Bug 1101651 - Part 2, Enable WebRTC unit tests to be built using standalone WebRTC library r=jesup
☠☠ backed out by 2fb78f64b625 ☠ ☠
authorRandall Barker <rbarker@mozilla.com>
Thu, 02 Apr 2015 12:14:46 -0700
changeset 267199 d02fb013d5b764812576a606391620a887121007
parent 267198 b84eb39d1b52d24607adbb88e57e61090b25ec7c
child 267200 af45e9fc2953180c712e49a2d5ecb56df7700afe
push id4830
push userjlund@mozilla.com
push dateMon, 29 Jun 2015 20:18:48 +0000
treeherdermozilla-beta@4c2175bb0420 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjesup
bugs1101651
milestone40.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1101651 - Part 2, Enable WebRTC unit tests to be built using standalone WebRTC library r=jesup
media/mtransport/build/moz.build
media/mtransport/common.build
media/mtransport/moz.build
media/mtransport/objs.mozbuild
media/mtransport/standalone/moz.build
media/mtransport/stun_udp_socket_filter.cpp
media/mtransport/test/moz.build
media/mtransport/test/mtransport_test_utils.h
media/mtransport/testlib/moz.build
media/webrtc/moz.build
media/webrtc/signaling/signaling.gyp
media/webrtc/signaling/src/common/browser_logging/WebRtcLog.cpp
media/webrtc/signaling/src/media-conduit/AudioConduit.cpp
media/webrtc/signaling/src/media-conduit/AudioConduit.h
media/webrtc/signaling/src/media-conduit/CodecStatistics.cpp
media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
media/webrtc/signaling/src/mediapipeline/MediaPipeline.h
media/webrtc/signaling/src/peerconnection/MediaPipelineFactory.cpp
media/webrtc/signaling/src/peerconnection/PeerConnectionCtx.cpp
media/webrtc/signaling/src/peerconnection/PeerConnectionCtx.h
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
media/webrtc/signaling/test/FakeMediaStreams.h
media/webrtc/signaling/test/FakePCObserver.h
media/webrtc/signaling/test/common.build
media/webrtc/signaling/test/jsep_session_unittest.cpp
media/webrtc/signaling/test/moz.build
media/webrtc/signaling/test/signaling_unittests.cpp
media/webrtc/signaling/test/standalone/jsep_session_unittest_standalone.cpp
media/webrtc/signaling/test/standalone/mediaconduit_unittests_standalone.cpp
media/webrtc/signaling/test/standalone/mediapipeline_unittest_standalone.cpp
media/webrtc/signaling/test/standalone/moz.build
media/webrtc/signaling/test/standalone/sdp_unittests_standalone.cpp
media/webrtc/signaling/test/standalone/signaling_unittests_standalone.cpp
toolkit/toolkit.mozbuild
xpcom/components/nsComponentManager.cpp
xpcom/components/nsComponentManager.h
--- a/media/mtransport/build/moz.build
+++ b/media/mtransport/build/moz.build
@@ -20,81 +20,21 @@ EXPORTS.mtransport += [
     '../transportlayer.h',
     '../transportlayerdtls.h',
     '../transportlayerice.h',
     '../transportlayerlog.h',
     '../transportlayerloopback.h',
     '../transportlayerprsock.h',
 ]
 
-include('../objs.mozbuild')
+include('../common.build')
 
 # These files cannot be built in unified mode because of the redefinition of
 # getLogModule, UNIMPLEMENTED, nr_socket_long_term_violation_time,
 # nr_socket_short_term_violation_time.
 SOURCES += mtransport_cppsrcs
 
 FAIL_ON_WARNINGS = True
 
-LOCAL_INCLUDES += [
-    '/media/mtransport/',
-    '/media/mtransport/third_party/',
-    '/media/mtransport/third_party/nICEr/src/crypto',
-    '/media/mtransport/third_party/nICEr/src/ice',
-    '/media/mtransport/third_party/nICEr/src/net',
-    '/media/mtransport/third_party/nICEr/src/stun',
-    '/media/mtransport/third_party/nICEr/src/util',
-    '/media/mtransport/third_party/nrappkit/src/event',
-    '/media/mtransport/third_party/nrappkit/src/log',
-    '/media/mtransport/third_party/nrappkit/src/plugin',
-    '/media/mtransport/third_party/nrappkit/src/port/generic/include',
-    '/media/mtransport/third_party/nrappkit/src/registry',
-    '/media/mtransport/third_party/nrappkit/src/share',
-    '/media/mtransport/third_party/nrappkit/src/stats',
-    '/media/mtransport/third_party/nrappkit/src/util/libekr',
-]
-
-if CONFIG['OS_TARGET'] in ['Darwin', 'DragonFly', 'FreeBSD', 'NetBSD', 'OpenBSD']:
-    if CONFIG['OS_TARGET'] == 'Darwin':
-        DEFINES['DARWIN'] = True
-    else:
-        DEFINES['BSD'] = True
-    LOCAL_INCLUDES += [
-        '/media/mtransport/third_party/nrappkit/src/port/darwin/include',
-    ]
-elif CONFIG['OS_TARGET'] == 'Linux':
-    DEFINES['LINUX'] = True
-    DEFINES['USE_INTERFACE_PRIORITIZER'] = True
-    LOCAL_INCLUDES += [
-        '/media/mtransport/third_party/nrappkit/src/port/linux/include',
-    ]
-elif CONFIG['OS_TARGET'] == 'Android':
-    DEFINES['LINUX'] = True
-    DEFINES['ANDROID'] = True
-    LOCAL_INCLUDES += [
-        '/media/mtransport/third_party/nrappkit/src/port/android/include',
-    ]
-elif CONFIG['OS_TARGET'] == 'WINNT':
-    DEFINES['WIN'] = True
-    # for stun.h
-    DEFINES['WIN32'] = True
-    DEFINES['NOMINMAX'] = True
-    LOCAL_INCLUDES += [
-        '/media/mtransport/third_party/nrappkit/src/port/win32/include',
-    ]
-
 if CONFIG['GKMEDIAS_SHARED_LIBRARY']:
     NO_VISIBILITY_FLAGS = True
 
 FINAL_LIBRARY = 'xul'
-
-if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
-    DEFINES['USE_INTERFACE_PRIORITIZER'] = True
-
-for var in ('HAVE_STRDUP', 'NR_SOCKET_IS_VOID_PTR'):
-    DEFINES[var] = True
-
-DEFINES['R_DEFINED_INT2'] = 'int16_t'
-DEFINES['R_DEFINED_UINT2'] = 'uint16_t'
-DEFINES['R_DEFINED_INT4'] = 'int32_t'
-DEFINES['R_DEFINED_UINT4'] = 'uint32_t'
-DEFINES['R_DEFINED_INT8'] = 'int64_t'
-DEFINES['R_DEFINED_UINT8'] = 'uint64_t'
new file mode 100644
--- /dev/null
+++ b/media/mtransport/common.build
@@ -0,0 +1,95 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+mtransport_lcppsrcs = [
+    'dtlsidentity.cpp',
+    'nr_socket_prsock.cpp',
+    'nr_timer.cpp',
+    'nricectx.cpp',
+    'nricemediastream.cpp',
+    'nriceresolver.cpp',
+    'nriceresolverfake.cpp',
+    'nrinterfaceprioritizer.cpp',
+    'rlogringbuffer.cpp',
+    'simpletokenbucket.cpp',
+    'stun_udp_socket_filter.cpp',
+    'transportflow.cpp',
+    'transportlayer.cpp',
+    'transportlayerdtls.cpp',
+    'transportlayerice.cpp',
+    'transportlayerlog.cpp',
+    'transportlayerloopback.cpp',
+    'transportlayerprsock.cpp',
+]
+
+if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
+    mtransport_lcppsrcs += [
+        'gonk_addrs.cpp',
+    ]
+
+mtransport_cppsrcs = [ 
+    '%s/media/mtransport/%s' % (TOPSRCDIR, s) for s in sorted(mtransport_lcppsrcs)
+]
+
+LOCAL_INCLUDES += [
+    '/media/mtransport/',
+    '/media/mtransport/third_party/',
+    '/media/mtransport/third_party/nICEr/src/crypto',
+    '/media/mtransport/third_party/nICEr/src/ice',
+    '/media/mtransport/third_party/nICEr/src/net',
+    '/media/mtransport/third_party/nICEr/src/stun',
+    '/media/mtransport/third_party/nICEr/src/util',
+    '/media/mtransport/third_party/nrappkit/src/event',
+    '/media/mtransport/third_party/nrappkit/src/log',
+    '/media/mtransport/third_party/nrappkit/src/plugin',
+    '/media/mtransport/third_party/nrappkit/src/port/generic/include',
+    '/media/mtransport/third_party/nrappkit/src/registry',
+    '/media/mtransport/third_party/nrappkit/src/share',
+    '/media/mtransport/third_party/nrappkit/src/stats',
+    '/media/mtransport/third_party/nrappkit/src/util/libekr',
+]
+
+if CONFIG['OS_TARGET'] in ['Darwin', 'DragonFly', 'FreeBSD', 'NetBSD', 'OpenBSD']:
+    if CONFIG['OS_TARGET'] == 'Darwin':
+        DEFINES['DARWIN'] = True
+    else:
+        DEFINES['BSD'] = True
+    LOCAL_INCLUDES += [
+        '/media/mtransport/third_party/nrappkit/src/port/darwin/include',
+    ]
+elif CONFIG['OS_TARGET'] == 'Linux':
+    DEFINES['LINUX'] = True
+    DEFINES['USE_INTERFACE_PRIORITIZER'] = True
+    LOCAL_INCLUDES += [
+        '/media/mtransport/third_party/nrappkit/src/port/linux/include',
+    ]
+elif CONFIG['OS_TARGET'] == 'Android':
+    DEFINES['LINUX'] = True
+    DEFINES['ANDROID'] = True
+    LOCAL_INCLUDES += [
+        '/media/mtransport/third_party/nrappkit/src/port/android/include',
+    ]
+elif CONFIG['OS_TARGET'] == 'WINNT':
+    DEFINES['WIN'] = True
+    # for stun.h
+    DEFINES['WIN32'] = True
+    DEFINES['NOMINMAX'] = True
+    LOCAL_INCLUDES += [
+        '/media/mtransport/third_party/nrappkit/src/port/win32/include',
+    ]
+
+if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
+    DEFINES['USE_INTERFACE_PRIORITIZER'] = True
+
+for var in ('HAVE_STRDUP', 'NR_SOCKET_IS_VOID_PTR'):
+    DEFINES[var] = True
+
+DEFINES['R_DEFINED_INT2'] = 'int16_t'
+DEFINES['R_DEFINED_UINT2'] = 'uint16_t'
+DEFINES['R_DEFINED_INT4'] = 'int32_t'
+DEFINES['R_DEFINED_UINT4'] = 'uint32_t'
+DEFINES['R_DEFINED_INT8'] = 'int64_t'
+DEFINES['R_DEFINED_UINT8'] = 'uint64_t'
new file mode 100644
--- /dev/null
+++ b/media/mtransport/moz.build
@@ -0,0 +1,11 @@
+DIRS += [
+    '/media/mtransport/third_party',
+    '/media/mtransport/build',
+    '/media/mtransport/testlib',
+]
+if CONFIG['OS_TARGET'] != 'WINNT' and CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
+    DIRS += [
+        '/media/mtransport/standalone',
+    ]
+
+
deleted file mode 100644
--- a/media/mtransport/objs.mozbuild
+++ /dev/null
@@ -1,35 +0,0 @@
-# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# 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/.
-
-mtransport_lcppsrcs = [
-    'dtlsidentity.cpp',
-    'nr_socket_prsock.cpp',
-    'nr_timer.cpp',
-    'nricectx.cpp',
-    'nricemediastream.cpp',
-    'nriceresolver.cpp',
-    'nriceresolverfake.cpp',
-    'nrinterfaceprioritizer.cpp',
-    'rlogringbuffer.cpp',
-    'simpletokenbucket.cpp',
-    'stun_udp_socket_filter.cpp',
-    'transportflow.cpp',
-    'transportlayer.cpp',
-    'transportlayerdtls.cpp',
-    'transportlayerice.cpp',
-    'transportlayerlog.cpp',
-    'transportlayerloopback.cpp',
-    'transportlayerprsock.cpp',
-]
-
-if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
-    mtransport_lcppsrcs += [
-        'gonk_addrs.cpp',
-    ]
-
-mtransport_cppsrcs = [ 
-    '%s/media/mtransport/%s' % (TOPSRCDIR, s) for s in sorted(mtransport_lcppsrcs)
-]
--- a/media/mtransport/standalone/moz.build
+++ b/media/mtransport/standalone/moz.build
@@ -1,76 +1,20 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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('../objs.mozbuild')
+Library('mtransport_standalone')
+
+include('../common.build')
 
 # These files cannot be built in unified mode because of the redefinition of
 # getLogModule, UNIMPLEMENTED, nr_socket_long_term_violation_time,
 # nr_socket_short_term_violation_time.
 SOURCES += mtransport_cppsrcs
 
-Library('mtransport_s')
-
-LOCAL_INCLUDES += [
-    '/media/mtransport/',
-    '/media/mtransport/third_party/',
-    '/media/mtransport/third_party/nICEr/src/crypto',
-    '/media/mtransport/third_party/nICEr/src/ice',
-    '/media/mtransport/third_party/nICEr/src/net',
-    '/media/mtransport/third_party/nICEr/src/stun',
-    '/media/mtransport/third_party/nICEr/src/util',
-    '/media/mtransport/third_party/nrappkit/src/event',
-    '/media/mtransport/third_party/nrappkit/src/log',
-    '/media/mtransport/third_party/nrappkit/src/plugin',
-    '/media/mtransport/third_party/nrappkit/src/port/generic/include',
-    '/media/mtransport/third_party/nrappkit/src/registry',
-    '/media/mtransport/third_party/nrappkit/src/share',
-    '/media/mtransport/third_party/nrappkit/src/stats',
-    '/media/mtransport/third_party/nrappkit/src/util/libekr',
-]
-
-if CONFIG['OS_TARGET'] in ['Darwin', 'DragonFly', 'FreeBSD', 'NetBSD', 'OpenBSD']:
-    if CONFIG['OS_TARGET'] == 'Darwin':
-        DEFINES['DARWIN'] = True
-    else:
-        DEFINES['BSD'] = True
-    LOCAL_INCLUDES += [
-        '/media/mtransport/third_party/nrappkit/src/port/darwin/include',
-    ]
-elif CONFIG['OS_TARGET'] == 'Linux':
-    DEFINES['LINUX'] = True
-    DEFINES['USE_INTERFACE_PRIORITIZER'] = True
-    LOCAL_INCLUDES += [
-        '/media/mtransport/third_party/nrappkit/src/port/linux/include',
-    ]
-elif CONFIG['OS_TARGET'] == 'Android':
-    DEFINES['LINUX'] = True
-    DEFINES['ANDROID'] = True
-    LOCAL_INCLUDES += [
-        '/media/mtransport/third_party/nrappkit/src/port/android/include',
-    ]
-elif CONFIG['OS_TARGET'] == 'WINNT':
-    DEFINES['WIN'] = True
-    # for stun.h
-    DEFINES['WIN32'] = True
-    DEFINES['NOMINMAX'] = True
-    LOCAL_INCLUDES += [
-        '/media/mtransport/third_party/nrappkit/src/port/win32/include',
-    ]
-
 FORCE_STATIC_LIB = True
 
-if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
-    DEFINES['USE_INTERFACE_PRIORITIZER'] = True
-
-for var in ('HAVE_STRDUP', 'NR_SOCKET_IS_VOID_PTR'):
+for var in ('MOZILLA_INTERNAL_API', 'MOZILLA_XPCOMRT_API', 'MOZILLA_EXTERNAL_LINKAGE'):
     DEFINES[var] = True
 
-DEFINES['R_DEFINED_INT2'] = 'int16_t'
-DEFINES['R_DEFINED_UINT2'] = 'uint16_t'
-DEFINES['R_DEFINED_INT4'] = 'int32_t'
-DEFINES['R_DEFINED_UINT4'] = 'uint32_t'
-DEFINES['R_DEFINED_INT8'] = 'int64_t'
-DEFINES['R_DEFINED_UINT8'] = 'uint64_t'
--- a/media/mtransport/stun_udp_socket_filter.cpp
+++ b/media/mtransport/stun_udp_socket_filter.cpp
@@ -9,16 +9,20 @@ extern "C" {
 #include "transport_addr.h"
 #include "stun.h"
 }
 
 #include "mozilla/Attributes.h"
 #include "mozilla/net/DNS.h"
 #include "stun_udp_socket_filter.h"
 #include "nr_socket_prsock.h"
+#if defined(MOZILLA_XPCOMRT_API)
+#include "mozilla/Module.h"
+#include "mozilla/ModuleUtils.h"
+#endif
 
 namespace {
 
 class NetAddressAdapter {
  public:
   MOZ_IMPLICIT NetAddressAdapter(const mozilla::net::NetAddr& netaddr)
     : addr_(ntohl(netaddr.inet.ip)),
       port_(ntohs(netaddr.inet.port)) {
@@ -201,8 +205,31 @@ NS_IMETHODIMP nsStunUDPSocketFilterHandl
 {
   nsIUDPSocketFilter *ret = new STUNUDPSocketFilter();
   if (!ret) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
   NS_ADDREF(*result = ret);
   return NS_OK;
 }
+
+#if defined(MOZILLA_XPCOMRT_API)
+NS_DEFINE_NAMED_CID(NS_STUN_UDP_SOCKET_FILTER_HANDLER_CID)
+
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsStunUDPSocketFilterHandler)
+
+static const mozilla::Module::CIDEntry kCIDs[] = {
+  { &kNS_STUN_UDP_SOCKET_FILTER_HANDLER_CID, false, nullptr, nsStunUDPSocketFilterHandlerConstructor },
+  { nullptr }
+};
+
+static const mozilla::Module::ContractIDEntry kContracts[] = {
+  { NS_STUN_UDP_SOCKET_FILTER_HANDLER_CONTRACTID, &kNS_STUN_UDP_SOCKET_FILTER_HANDLER_CID },
+  { nullptr }
+};
+
+extern const mozilla::Module kStunUDPSocketFilterHandlerModule;
+const mozilla::Module kStunUDPSocketFilterHandlerModule = {
+  mozilla::Module::kVersion,
+  kCIDs,
+  kContracts
+};
+#endif
--- a/media/mtransport/test/moz.build
+++ b/media/mtransport/test/moz.build
@@ -1,50 +1,56 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 if CONFIG['OS_TARGET'] != 'WINNT' and CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
-    GeckoCppUnitTests([
+    CppUnitTests([
         'buffered_stun_socket_unittest',
         'ice_unittest',
         'nrappkit_unittest',
         'proxy_tunnel_socket_unittest',
         'rlogringbuffer_unittest',
         'runnable_utils_unittest',
         'simpletokenbucket_unittest',
         'sockettransportservice_unittest',
         'TestSyncRunnable',
         'transport_unittests',
         'turn_unittest',
     ])
 
     if CONFIG['MOZ_SCTP']:
-        GeckoCppUnitTests([
+        CppUnitTests([
             'sctp_unittest',
         ])
 
 FAIL_ON_WARNINGS = True
 
-for var in ('HAVE_STRDUP', 'NR_SOCKET_IS_VOID_PTR', 'SCTP_DEBUG', 'INET'):
+for var in ('MOZILLA_INTERNAL_API', 'MOZILLA_XPCOMRT_API', 'MOZILLA_EXTERNAL_LINKAGE', 'HAVE_STRDUP', 'NR_SOCKET_IS_VOID_PTR', 'SCTP_DEBUG', 'INET'):
     DEFINES[var] = True
 
 if CONFIG['OS_TARGET'] == 'Android':
     LOCAL_INCLUDES += [
         '/media/mtransport/third_party/nrappkit/src/port/android/include',
     ]
 else:
     DEFINES['INET6'] = True
 
 if CONFIG['OS_TARGET'] == 'Linux':
     LOCAL_INCLUDES += [
         '/media/mtransport/third_party/nrappkit/src/port/linux/include',
     ]
+    USE_LIBS += [
+        'static:/nsprpub/lib/libc/src/plc4',
+    ]
+    OS_LIBS += [
+        '-lrt',
+    ]
 
 if CONFIG['OS_TARGET'] == 'Darwin':
     LOCAL_INCLUDES += [
         '/media/mtransport/third_party/nrappkit/src/port/darwin/include',
     ]
 
 if CONFIG['OS_TARGET'] in ('DragonFly', 'FreeBSD', 'NetBSD', 'OpenBSD'):
     LOCAL_INCLUDES += [
@@ -75,28 +81,38 @@ LOCAL_INCLUDES += [
     '/media/mtransport/third_party/nrappkit/src/plugin',
     '/media/mtransport/third_party/nrappkit/src/registry',
     '/media/mtransport/third_party/nrappkit/src/share',
     '/media/mtransport/third_party/nrappkit/src/stats',
     '/media/mtransport/third_party/nrappkit/src/util/',
     '/media/mtransport/third_party/nrappkit/src/util/libekr',
     '/media/webrtc/trunk/testing/gtest/include/',
     '/netwerk/sctp/src/',
+    '/xpcom/libxpcomrt',
 ]
 
 USE_LIBS += [
     '/media/webrtc/trunk/testing/gtest_gtest/gtest',
-    'mtransport_s',
+    'fallible',
+    'mfbt',
+    'mozglue',
+    'mtransport_standalone',
+    'necko_standalone',
     'nicer',
     'nrappkit',
+    'nspr',
     'nss',
+    'unicharutil_standalone',
+    'xpcomrt',
 ]
 
 if not CONFIG['MOZ_NATIVE_NSS'] and not CONFIG['MOZ_FOLD_LIBS']:
     USE_LIBS += [
         # Statically linking NSS libssl ensures that we can debug NSS too
         'static:/security/nss/lib/ssl/ssl',
     ]
 
 if CONFIG['MOZ_SCTP']:
     USE_LIBS += [
         'nksctp_s',
     ]
+
+USE_LIBS += ['mozglue']
--- a/media/mtransport/test/mtransport_test_utils.h
+++ b/media/mtransport/test/mtransport_test_utils.h
@@ -14,45 +14,58 @@
 #include "nspr.h"
 #include "nsCOMPtr.h"
 #include "nsNetCID.h"
 #include "nsXPCOMGlue.h"
 #include "nsXPCOM.h"
 
 #include "nsIComponentManager.h"
 #include "nsIComponentRegistrar.h"
-#include "nsNetUtil.h"
+#include "nsIEventTarget.h"
 #include "nsIIOService.h"
 #include "nsIServiceManager.h"
 #include "nsISocketTransportService.h"
 #include "nsDirectoryServiceUtils.h"
 #include "nsDirectoryServiceDefs.h"
 #ifdef MOZ_CRASHREPORTER
 #include "nsICrashReporter.h"
 #endif
 #include "nsPISocketTransportService.h"
 #include "nsServiceManagerUtils.h"
+#if !defined(MOZILLA_XPCOMRT_API)
 #include "TestHarness.h"
+#else
+#include "XPCOMRTInit.h"
+class ScopedXPCOM {
+public:
+  ScopedXPCOM(const char*)
+  {
+    NS_InitXPCOMRT();
+  }
+  ~ScopedXPCOM()
+  {
+    NS_ShutdownXPCOMRT();
+  }
+};
+#endif
 
 class MtransportTestUtils {
  public:
   MtransportTestUtils() : xpcom_("") {
     if (!sts_) {
       InitServices();
     }
   }
 
   ~MtransportTestUtils() {
     sts_->Shutdown();
   }
 
   void InitServices() {
     nsresult rv;
-    ioservice_ = do_GetIOService(&rv);
-    MOZ_ASSERT(NS_SUCCEEDED(rv));
     sts_target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
     MOZ_ASSERT(NS_SUCCEEDED(rv));
     sts_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
     MOZ_ASSERT(NS_SUCCEEDED(rv));
 
 #ifdef MOZ_CRASHREPORTER
     char *crashreporter = PR_GetEnv("MOZ_CRASHREPORTER");
     if (crashreporter && !strcmp(crashreporter, "1")) {
@@ -75,17 +88,16 @@ class MtransportTestUtils {
     }
 #endif
   }
 
   nsCOMPtr<nsIEventTarget> sts_target() { return sts_target_; }
 
  private:
   ScopedXPCOM xpcom_;
-  nsCOMPtr<nsIIOService> ioservice_;
   nsCOMPtr<nsIEventTarget> sts_target_;
   nsCOMPtr<nsPISocketTransportService> sts_;
 #ifdef MOZ_CRASHREPORTER
   nsCOMPtr<nsICrashReporter> crashreporter_;
 #endif
 };
 
 
new file mode 100644
--- /dev/null
+++ b/media/mtransport/testlib/moz.build
@@ -0,0 +1,16 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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('../common.build')
+
+# These files cannot be built in unified mode because of the redefinition of
+# getLogModule, UNIMPLEMENTED, nr_socket_long_term_violation_time,
+# nr_socket_short_term_violation_time.
+SOURCES += mtransport_cppsrcs
+
+Library('mtransport_s')
+
+FORCE_STATIC_LIB = True
--- a/media/webrtc/moz.build
+++ b/media/webrtc/moz.build
@@ -45,16 +45,19 @@ GYP_DIRS['trunk'].non_unified_sources +=
 
 if CONFIG['MOZ_WEBRTC_SIGNALING']:
     GYP_DIRS += ['signaling']
     GYP_DIRS['signaling'].input = 'signaling/signaling.gyp'
     GYP_DIRS['signaling'].variables = gyp_vars.copy()
     GYP_DIRS['signaling'].variables.update(
         build_for_test=0
     )
+    GYP_DIRS['signaling'].variables.update(
+        build_for_standalone=0
+    )
     GYP_DIRS['signaling'].sandbox_vars['FINAL_LIBRARY'] = 'xul'
     # Excluded for various symbol conflicts
     signaling_non_unified_sources = [
         'signaling/src/common/browser_logging/CSFLog.cpp',
         'signaling/src/jsep/JsepSessionImpl.cpp',
         'signaling/src/media-conduit/AudioConduit.cpp',
         'signaling/src/media-conduit/CodecStatistics.cpp',
         'signaling/src/media-conduit/VideoConduit.cpp',
@@ -87,12 +90,21 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk
     GYP_DIRS['trunk/testing'].variables = gyp_vars
     GYP_DIRS['trunk/testing'].non_unified_sources += webrtc_non_unified_sources
 
     if CONFIG['MOZ_WEBRTC_SIGNALING']:
         GYP_DIRS += ['signalingtest']
         GYP_DIRS['signalingtest'].input = 'signaling/signaling.gyp'
         GYP_DIRS['signalingtest'].variables = gyp_vars.copy()
         GYP_DIRS['signalingtest'].variables.update(
-            build_for_test=1
+            build_for_test=1,
+            build_for_standalone=0
         )
         GYP_DIRS['signalingtest'].non_unified_sources += signaling_non_unified_sources
+        GYP_DIRS += ['signalingstandalone']
+        GYP_DIRS['signalingstandalone'].input = 'signaling/signaling.gyp'
+        GYP_DIRS['signalingstandalone'].variables = gyp_vars.copy()
+        GYP_DIRS['signalingstandalone'].variables.update(
+            build_for_test=0,
+            build_for_standalone=1
+        )
+        GYP_DIRS['signalingstandalone'].non_unified_sources += signaling_non_unified_sources
 
--- a/media/webrtc/signaling/signaling.gyp
+++ b/media/webrtc/signaling/signaling.gyp
@@ -72,18 +72,16 @@
         # Media Conduit
         './src/media-conduit/AudioConduit.h',
         './src/media-conduit/AudioConduit.cpp',
         './src/media-conduit/VideoConduit.h',
         './src/media-conduit/VideoConduit.cpp',
         './src/media-conduit/CodecStatistics.h',
         './src/media-conduit/CodecStatistics.cpp',
         './src/media-conduit/RunningStat.h',
-        './src/media-conduit/GmpVideoCodec.cpp',
-        './src/media-conduit/WebrtcGmpVideoCodec.cpp',
         # Common
         './src/common/CommonTypes.h',
         './src/common/csf_common.h',
         './src/common/NullDeleter.h',
         './src/common/PtrVector.h',
         './src/common/Wrapper.h',
         './src/common/NullTransport.h',
         './src/common/YuvStamper.cpp',
@@ -93,18 +91,16 @@
         './src/common/browser_logging/WebRtcLog.cpp',
         './src/common/browser_logging/WebRtcLog.h',
         # Browser Logging
         './src/common/time_profiling/timecard.c',
         './src/common/time_profiling/timecard.h',
         # PeerConnection
         './src/peerconnection/MediaPipelineFactory.cpp',
         './src/peerconnection/MediaPipelineFactory.h',
-        './src/peerconnection/MediaStreamList.cpp',
-        './src/peerconnection/MediaStreamList.h',
         './src/peerconnection/PeerConnectionCtx.cpp',
         './src/peerconnection/PeerConnectionCtx.h',
         './src/peerconnection/PeerConnectionImpl.cpp',
         './src/peerconnection/PeerConnectionImpl.h',
         './src/peerconnection/PeerConnectionMedia.cpp',
         './src/peerconnection/PeerConnectionMedia.h',
         # Media pipeline
         './src/mediapipeline/MediaPipeline.h',
@@ -215,33 +211,55 @@
             '-I$(ANDROID_SOURCE)/frameworks/native/include/media/openmax',
             '-I$(ANDROID_SOURCE)/frameworks/native/include',
             '-I$(ANDROID_SOURCE)/frameworks/native/opengl/include',
           ],
           'defines' : [
             'MOZ_WEBRTC_OMX'
           ],
         }],
-        ['build_for_test==0', {
+        ['(build_for_test==0) and (build_for_standalone==0)', {
           'defines' : [
-            'MOZILLA_INTERNAL_API'
+            'MOZILLA_INTERNAL_API',
           ],
           'sources': [
+            './src/peerconnection/MediaStreamList.cpp',
+            './src/peerconnection/MediaStreamList.h',
             './src/peerconnection/WebrtcGlobalInformation.cpp',
             './src/peerconnection/WebrtcGlobalInformation.h',
           ],
         }],
         ['build_for_test!=0', {
           'include_dirs': [
             './test'
           ],
           'defines' : [
             'NO_CHROMIUM_LOGGING',
             'USE_FAKE_MEDIA_STREAMS',
-            'USE_FAKE_PCOBSERVER'
+            'USE_FAKE_PCOBSERVER',
+            'MOZILLA_EXTERNAL_LINKAGE',
+          ],
+        }],
+        ['build_for_standalone==0', {
+          'sources': [
+            './src/media-conduit/GmpVideoCodec.cpp',
+            './src/media-conduit/WebrtcGmpVideoCodec.cpp',
+          ],
+        }],
+        ['build_for_standalone!=0', {
+          'include_dirs': [
+            './test'
+          ],
+          'defines' : [
+            'MOZILLA_INTERNAL_API',
+            'MOZILLA_XPCOMRT_API',
+            'MOZILLA_EXTERNAL_LINKAGE',
+            'NO_CHROMIUM_LOGGING',
+            'USE_FAKE_MEDIA_STREAMS',
+            'USE_FAKE_PCOBSERVER',
           ],
         }],
         ['(OS=="linux") or (OS=="android")', {
           'include_dirs': [
           ],
 
           'defines': [
             'OS_LINUX',
--- a/media/webrtc/signaling/src/common/browser_logging/WebRtcLog.cpp
+++ b/media/webrtc/signaling/src/common/browser_logging/WebRtcLog.cpp
@@ -6,17 +6,19 @@
 
 #include "prlog.h"
 #include "prenv.h"
 #include "webrtc/system_wrappers/interface/trace.h"
 
 #include "nscore.h"
 #ifdef MOZILLA_INTERNAL_API
 #include "nsString.h"
+#if !defined(MOZILLA_XPCOMRT_API)
 #include "mozilla/Preferences.h"
+#endif // !defined(MOZILLA_XPCOMRT_API)
 #else
 #include "nsStringAPI.h"
 #endif
 
 static int gWebRtcTraceLoggingOn = 0;
 
 #ifndef ANDROID
 static const char *default_log = "WebRTC.log";
@@ -52,21 +54,23 @@ public:
   }
 };
 
 static WebRtcTraceCallback gWebRtcCallback;
 
 #ifdef MOZILLA_INTERNAL_API
 void GetWebRtcLogPrefs(uint32_t *aTraceMask, nsACString* aLogFile, nsACString *aAECLogDir, bool *aMultiLog)
 {
+#if !defined(MOZILLA_XPCOMRT_API)
   *aMultiLog = mozilla::Preferences::GetBool("media.webrtc.debug.multi_log");
   *aTraceMask = mozilla::Preferences::GetUint("media.webrtc.debug.trace_mask");
   mozilla::Preferences::GetCString("media.webrtc.debug.log_file", aLogFile);
   mozilla::Preferences::GetCString("media.webrtc.debug.aec_log_dir", aAECLogDir);
   webrtc::Trace::set_aec_debug_size(mozilla::Preferences::GetUint("media.webrtc.debug.aec_dump_max_size"));
+#endif // !defined(MOZILLA_XPCOMRT_API)
 }
 #endif
 
 void CheckOverrides(uint32_t *aTraceMask, nsACString *aLogFile, bool *aMultiLog)
 {
   if (!aTraceMask || !aLogFile || !aMultiLog) {
     return;
   }
@@ -136,17 +140,17 @@ void ConfigWebRtcLog(uint32_t trace_mask
   webrtc::Trace::set_aec_debug_filename(aAECLogDir.get());
   if (trace_mask != 0) {
     if (aLogFile.EqualsLiteral("nspr")) {
       webrtc::Trace::SetTraceCallback(&gWebRtcCallback);
     } else {
       webrtc::Trace::SetTraceFile(aLogFile.get(), multi_log);
     }
   }
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   // Capture the final choices for the trace settings.
   mozilla::Preferences::SetCString("media.webrtc.debug.log_file", aLogFile);
   mozilla::Preferences::SetUint("media.webrtc.debug.trace_mask", trace_mask);
   mozilla::Preferences::SetCString("media.webrtc.debug.aec_log_dir", aAECLogDir);
 #endif
   return;
 }
 
--- a/media/webrtc/signaling/src/media-conduit/AudioConduit.cpp
+++ b/media/webrtc/signaling/src/media-conduit/AudioConduit.cpp
@@ -13,17 +13,17 @@
 
 #include "AudioConduit.h"
 #include "nsCOMPtr.h"
 #include "mozilla/Services.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 #include "nsThreadUtils.h"
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 #include "Latency.h"
 #include "mozilla/Telemetry.h"
 #endif
 
 #include "webrtc/voice_engine/include/voe_errors.h"
 #include "webrtc/system_wrappers/interface/clock.h"
 #include "browser_logging/WebRtcLog.h"
 
@@ -364,17 +364,17 @@ WebrtcAudioConduit::ConfigureSendMediaCo
       CSFLogError(logTag, "%s Invalid Send Codec", __FUNCTION__);
       return kMediaConduitInvalidSendCodec;
     }
     CSFLogError(logTag, "%s SetSendCodec Failed %d ", __FUNCTION__,
                                          mPtrVoEBase->LastError());
     return kMediaConduitUnknownError;
   }
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   // TEMPORARY - see bug 694814 comment 2
   nsresult rv;
   nsCOMPtr<nsIPrefService> prefs = do_GetService("@mozilla.org/preferences-service;1", &rv);
   if (NS_SUCCEEDED(rv)) {
     nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs);
 
     if (branch) {
       branch->GetIntPref("media.peerconnection.capture_delay", &mCaptureDelay);
@@ -525,17 +525,17 @@ WebrtcAudioConduit::SendAudioFrame(const
 
   // if transmission is not started .. conduit cannot insert frames
   if(!mEngineTransmitting)
   {
     CSFLogError(logTag, "%s Engine not transmitting ", __FUNCTION__);
     return kMediaConduitSessionNotInited;
   }
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
     if (PR_LOG_TEST(GetLatencyLog(), PR_LOG_DEBUG)) {
       struct Processing insert = { TimeStamp::Now(), 0 };
       mProcessing.AppendElement(insert);
     }
 #endif
 
   capture_delay = mCaptureDelay;
   //Insert the samples
@@ -619,17 +619,17 @@ WebrtcAudioConduit::GetAudioFrame(int16_
   mSamples += lengthSamples;
   if (mSamples >= mLastSyncLog + samplingFreqHz) {
     int jitter_buffer_delay_ms;
     int playout_buffer_delay_ms;
     int avsync_offset_ms;
     if (GetAVStats(&jitter_buffer_delay_ms,
                    &playout_buffer_delay_ms,
                    &avsync_offset_ms)) {
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
       if (avsync_offset_ms < 0) {
         Telemetry::Accumulate(Telemetry::WEBRTC_AVSYNC_WHEN_VIDEO_LAGS_AUDIO_MS,
                               -avsync_offset_ms);
       } else {
         Telemetry::Accumulate(Telemetry::WEBRTC_AVSYNC_WHEN_AUDIO_LAGS_VIDEO_MS,
                               avsync_offset_ms);
       }
 #endif
@@ -637,17 +637,17 @@ WebrtcAudioConduit::GetAudioFrame(int16_
                   "A/V sync: sync delta: %dms, audio jitter delay %dms, playout delay %dms",
                   avsync_offset_ms, jitter_buffer_delay_ms, playout_buffer_delay_ms);
     } else {
       CSFLogError(logTag, "A/V sync: GetAVStats failed");
     }
     mLastSyncLog = mSamples;
   }
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   if (PR_LOG_TEST(GetLatencyLog(), PR_LOG_DEBUG)) {
     if (mProcessing.Length() > 0) {
       unsigned int now;
       mPtrVoEVideoSync->GetPlayoutTimestamp(mChannel, now);
       if (static_cast<uint32_t>(now) != mLastTimestamp) {
         mLastTimestamp = static_cast<uint32_t>(now);
         // Find the block that includes this timestamp in the network input
         while (mProcessing.Length() > 0) {
@@ -674,17 +674,17 @@ WebrtcAudioConduit::GetAudioFrame(int16_
 // Transport Layer Callbacks
 MediaConduitErrorCode
 WebrtcAudioConduit::ReceivedRTPPacket(const void *data, int len)
 {
   CSFLogDebug(logTag,  "%s : channel %d", __FUNCTION__, mChannel);
 
   if(mEngineReceiving)
   {
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
     if (PR_LOG_TEST(GetLatencyLog(), PR_LOG_DEBUG)) {
       // timestamp is at 32 bits in ([1])
       struct Processing insert = { TimeStamp::Now(),
                                    ntohl(static_cast<const uint32_t *>(data)[1]) };
       mProcessing.AppendElement(insert);
     }
 #endif
 
@@ -812,17 +812,17 @@ WebrtcAudioConduit::StartReceiving()
 }
 
 //WebRTC::RTP Callback Implementation
 // Called on AudioGUM or MSG thread
 int WebrtcAudioConduit::SendPacket(int channel, const void* data, int len)
 {
   CSFLogDebug(logTag,  "%s : channel %d", __FUNCTION__, channel);
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   if (PR_LOG_TEST(GetLatencyLog(), PR_LOG_DEBUG)) {
     if (mProcessing.Length() > 0) {
       TimeStamp started = mProcessing[0].mTimeStamp;
       mProcessing.RemoveElementAt(0);
       mProcessing.RemoveElementAt(0); // 20ms packetization!  Could automate this by watching sizes
       TimeDuration t = TimeStamp::Now() - started;
       int64_t delta = t.ToMilliseconds();
       LogTime(AsyncLatencyLogger::AudioSendRTP, ((uint64_t) this), delta);
--- a/media/webrtc/signaling/src/media-conduit/AudioConduit.h
+++ b/media/webrtc/signaling/src/media-conduit/AudioConduit.h
@@ -166,17 +166,17 @@ public:
                       mTransportMonitor("WebrtcAudioConduit"),
                       mTransmitterTransport(nullptr),
                       mReceiverTransport(nullptr),
                       mEngineTransmitting(false),
                       mEngineReceiving(false),
                       mChannel(-1),
                       mCurSendCodecConfig(nullptr),
                       mCaptureDelay(150),
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
                       mLastTimestamp(0),
 #endif // MOZILLA_INTERNAL_API
                       mSamples(0),
                       mLastSyncLog(0)
   {
   }
 
   virtual ~WebrtcAudioConduit();
@@ -277,17 +277,17 @@ private:
 
   int mChannel;
   RecvCodecList    mRecvCodecList;
   AudioCodecConfig* mCurSendCodecConfig;
 
   // Current "capture" delay (really output plus input delay)
   int32_t mCaptureDelay;
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   uint32_t mLastTimestamp;
 #endif // MOZILLA_INTERNAL_API
 
   uint32_t mSamples;
   uint32_t mLastSyncLog;
 };
 
 } // end namespace
--- a/media/webrtc/signaling/src/media-conduit/CodecStatistics.cpp
+++ b/media/webrtc/signaling/src/media-conduit/CodecStatistics.cpp
@@ -1,16 +1,18 @@
 /* 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 "CodecStatistics.h"
 
 #include "CSFLog.h"
+#if !defined(MOZILLA_XPCOMRT_API)
 #include "mozilla/Telemetry.h"
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
 using namespace mozilla;
 using namespace webrtc;
 
 // use the same tag as VideoConduit
 static const char* logTag ="WebrtcVideoSessionConduit";
 
 VideoCodecStatistics::VideoCodecStatistics(int channel,
@@ -112,18 +114,20 @@ void VideoCodecStatistics::ReceiveStateC
 
         if (mReceiveState == kReceiveStatePreemptiveNACK) {
           mRecoveredBeforeLoss++;
           CSFLogError(logTag, "Video error avoided by NACK recovery");
         } else if (!mReceiveFailureTime.IsNull()) { // safety
           TimeDuration timeDelta = TimeStamp::Now() - mReceiveFailureTime;
           CSFLogError(logTag, "Video error duration: %u ms",
                       static_cast<uint32_t>(timeDelta.ToMilliseconds()));
+#if !defined(MOZILLA_XPCOMRT_API)
           Telemetry::Accumulate(Telemetry::WEBRTC_VIDEO_ERROR_RECOVERY_MS,
                                 static_cast<uint32_t>(timeDelta.ToMilliseconds()));
+#endif //
 
           mRecoveredLosses++; // to calculate losses per minute
           mTotalLossTime += timeDelta;  // To calculate % time in recovery
         }
       } // else non-Normal to different non-normal transition
       break;
   }
 
@@ -135,26 +139,32 @@ void VideoCodecStatistics::ReceiveStateC
 void VideoCodecStatistics::EndOfCallStats()
 {
 #ifdef MOZILLA_INTERNAL_API
   if (!mFirstDecodeTime.IsNull()) {
     TimeDuration callDelta = TimeStamp::Now() - mFirstDecodeTime;
     if (callDelta.ToSeconds() != 0) {
       uint32_t recovered_per_min = mRecoveredBeforeLoss/(callDelta.ToSeconds()/60);
       CSFLogError(logTag, "Video recovery before error per min %u", recovered_per_min);
+#if !defined(MOZILLA_XPCOMRT_API)
       Telemetry::Accumulate(Telemetry::WEBRTC_VIDEO_RECOVERY_BEFORE_ERROR_PER_MIN,
                             recovered_per_min);
+#endif // !defined(MOZILLA_XPCOMRT_API)
       uint32_t err_per_min = mRecoveredLosses/(callDelta.ToSeconds()/60);
       CSFLogError(logTag, "Video recovery after error per min %u", err_per_min);
+#if !defined(MOZILLA_XPCOMRT_API)
       Telemetry::Accumulate(Telemetry::WEBRTC_VIDEO_RECOVERY_AFTER_ERROR_PER_MIN,
                             err_per_min);
+#endif // !defined(MOZILLA_XPCOMRT_API)
       float percent = (mTotalLossTime.ToSeconds()*100)/callDelta.ToSeconds();
       CSFLogError(logTag, "Video error time percentage %f%%", percent);
+#if !defined(MOZILLA_XPCOMRT_API)
       Telemetry::Accumulate(Telemetry::WEBRTC_VIDEO_DECODE_ERROR_TIME_PERMILLE,
                             static_cast<uint32_t>(percent*10));
+#endif // !defined(MOZILLA_XPCOMRT_API)
     }
   }
 #endif
 }
 
 void VideoCodecStatistics::SentFrame()
 {
   mSentRawFrames++;
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
@@ -273,17 +273,17 @@ bool WebrtcVideoConduit::GetRTCPSenderRe
 /**
  * Performs initialization of the MANDATORY components of the Video Engine
  */
 MediaConduitErrorCode
 WebrtcVideoConduit::Init()
 {
   CSFLogDebug(logTag,  "%s this=%p", __FUNCTION__, this);
 
-#ifdef MOZILLA_INTERNAL_API
+#if defined(MOZILLA_INTERNAL_API) && !defined(MOZILLA_INTERNAL_API)
   // already know we must be on MainThread barring unit test weirdness
   MOZ_ASSERT(NS_IsMainThread());
 
   nsresult rv;
   nsCOMPtr<nsIPrefService> prefs = do_GetService("@mozilla.org/preferences-service;1", &rv);
   if (!NS_WARN_IF(NS_FAILED(rv)))
   {
     nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs);
--- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
+++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
@@ -11,17 +11,17 @@
 #include "MediaStreamGraphImpl.h"
 #endif
 
 #include <math.h>
 
 #include "nspr.h"
 #include "srtp.h"
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 #include "VideoSegment.h"
 #include "Layers.h"
 #include "ImageTypes.h"
 #include "ImageContainer.h"
 #include "VideoUtils.h"
 #ifdef WEBRTC_GONK
 #include "GrallocImages.h"
 #include "mozilla/layers/GrallocTextureClient.h"
@@ -33,17 +33,17 @@
 #include "MediaSegment.h"
 #include "databuffer.h"
 #include "transportflow.h"
 #include "transportlayer.h"
 #include "transportlayerdtls.h"
 #include "transportlayerice.h"
 #include "runnable_utils.h"
 #include "libyuv/convert.h"
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 #include "mozilla/PeerIdentity.h"
 #endif
 #include "mozilla/gfx/Point.h"
 #include "mozilla/gfx/Types.h"
 
 #include "logging.h"
 
 using namespace mozilla;
@@ -638,17 +638,17 @@ void MediaPipelineTransmit::AttachToTrac
  // }
 
 #ifndef MOZILLA_INTERNAL_API
   // this enables the unit tests that can't fiddle with principals and the like
   listener_->SetEnabled(true);
 #endif
 }
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 void MediaPipelineTransmit::UpdateSinkIdentity_m(nsIPrincipal* principal,
                                                  const PeerIdentity* sinkIdentity) {
   ASSERT_ON_THREAD(main_thread_);
   bool enableStream = principal->Subsumes(domstream_->GetPrincipal());
   if (!enableStream) {
     // first try didn't work, but there's a chance that this is still available
     // if our stream is bound to a peerIdentity, and the peer connection (our
     // sink) is bound to the same identity, then we can enable the stream
@@ -926,17 +926,17 @@ NewData(MediaStreamGraph* graph, TrackID
 #else
       rate = graph->GraphRate();
 #endif
       ProcessAudioChunk(static_cast<AudioSessionConduit*>(conduit_.get()),
                         rate, *iter);
       iter.Next();
     }
   } else if (media.GetType() == MediaSegment::VIDEO) {
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
     VideoSegment* video = const_cast<VideoSegment *>(
         static_cast<const VideoSegment *>(&media));
 
     VideoSegment::ChunkIterator iter(*video);
     while(!iter.IsEnded()) {
       ProcessVideoChunk(static_cast<VideoSessionConduit*>(conduit_.get()),
                         *iter);
       iter.Next();
@@ -1039,17 +1039,17 @@ void MediaPipelineTransmit::PipelineList
 
   if (chunk_remaining) {
     memcpy(samples_10ms_buffer_, samples_tmp, chunk_remaining * sizeof(int16_t));
     buffer_current_ = chunk_remaining;
   }
 
 }
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 void MediaPipelineTransmit::PipelineListener::ProcessVideoChunk(
     VideoSessionConduit* conduit,
     VideoChunk& chunk) {
   layers::Image *img = chunk.mFrame.GetImage();
 
   // We now need to send the video frame to the other side
   if (!img) {
     // segment.AppendFrame() allows null images, which show up here as null
@@ -1229,17 +1229,17 @@ nsresult MediaPipelineReceiveAudio::Init
 
 // Add a track and listener on the MSG thread using the MSG command queue
 static void AddTrackAndListener(MediaStream* source,
                                 TrackID track_id, TrackRate track_rate,
                                 MediaStreamListener* listener, MediaSegment* segment,
                                 const RefPtr<TrackAddedCallback>& completed,
                                 bool queue_track) {
   // This both adds the listener and the track
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   class Message : public ControlMessage {
    public:
     Message(MediaStream* stream, TrackID track, TrackRate rate,
             MediaSegment* segment, MediaStreamListener* listener,
             const RefPtr<TrackAddedCallback>& completed)
       : ControlMessage(stream),
         track_id_(track),
         track_rate_(rate),
@@ -1391,51 +1391,57 @@ NotifyPull(MediaStreamGraph* graph, Stre
 nsresult MediaPipelineReceiveVideo::Init() {
   ASSERT_ON_THREAD(main_thread_);
   MOZ_MTLOG(ML_DEBUG, __FUNCTION__);
 
   description_ = pc_ + "| Receive video[";
   description_ += track_id_;
   description_ += "]";
 
-#ifdef MOZILLA_INTERNAL_API
+#if defined(MOZILLA_INTERNAL_API)
   listener_->AddSelf(new VideoSegment());
 #endif
 
   // Always happens before we can DetachMediaStream()
   static_cast<VideoSessionConduit *>(conduit_.get())->
       AttachRenderer(renderer_);
 
   return MediaPipelineReceive::Init();
 }
 
 MediaPipelineReceiveVideo::PipelineListener::PipelineListener(
   SourceMediaStream* source, TrackID track_id, bool queue_track)
   : GenericReceiveListener(source, track_id, source->GraphRate(), queue_track),
     width_(640),
     height_(480),
-#ifdef MOZILLA_INTERNAL_API
+#if defined(MOZILLA_XPCOMRT_API)
+    image_(new mozilla::SimpleImageBuffer),
+#elif defined(MOZILLA_INTERNAL_API)
     image_container_(),
     image_(),
 #endif
     monitor_("Video PipelineListener") {
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   image_container_ = layers::LayerManager::CreateImageContainer();
 #endif
 }
 
 void MediaPipelineReceiveVideo::PipelineListener::RenderVideoFrame(
     const unsigned char* buffer,
     unsigned int buffer_size,
     uint32_t time_stamp,
     int64_t render_time,
     const RefPtr<layers::Image>& video_image) {
-#ifdef MOZILLA_INTERNAL_API
   ReentrantMonitorAutoEnter enter(monitor_);
 
+#if defined(MOZILLA_XPCOMRT_API)
+  if (buffer) {
+    image_->SetImage(buffer, buffer_size, width_, height_);
+  }
+#elif defined(MOZILLA_INTERNAL_API)
   if (buffer) {
     // Create a video frame using |buffer|.
 #ifdef MOZ_WIDGET_GONK
     ImageFormat format = ImageFormat::GRALLOC_PLANAR_YCBCR;
 #else
     ImageFormat format = ImageFormat::PLANAR_YCBCR;
 #endif
     nsRefPtr<layers::Image> image = image_container_->CreateImage(format);
@@ -1468,20 +1474,25 @@ void MediaPipelineReceiveVideo::Pipeline
 #endif // WEBRTC_GONK
 #endif // MOZILLA_INTERNAL_API
 }
 
 void MediaPipelineReceiveVideo::PipelineListener::
 NotifyPull(MediaStreamGraph* graph, StreamTime desired_time) {
   ReentrantMonitorAutoEnter enter(monitor_);
 
-#ifdef MOZILLA_INTERNAL_API
+#if defined(MOZILLA_XPCOMRT_API)
+  nsRefPtr<SimpleImageBuffer> image = image_;
+#elif defined(MOZILLA_INTERNAL_API)
   nsRefPtr<layers::Image> image = image_;
   // our constructor sets track_rate_ to the graph rate
   MOZ_ASSERT(track_rate_ == source_->GraphRate());
+#endif
+
+#if defined(MOZILLA_INTERNAL_API)
   StreamTime delta = desired_time - played_ticks_;
 
   // Don't append if we've already provided a frame that supposedly
   // goes past the current aDesiredTime Doing so means a negative
   // delta and thus messes up handling of the graph
   if (delta > 0) {
     VideoSegment segment;
     segment.AppendFrame(image.forget(), delta, IntSize(width_, height_));
@@ -1489,12 +1500,18 @@ NotifyPull(MediaStreamGraph* graph, Stre
     if (source_->AppendToTrack(track_id_, &segment)) {
       played_ticks_ = desired_time;
     } else {
       MOZ_MTLOG(ML_ERROR, "AppendToTrack failed");
       return;
     }
   }
 #endif
+#if defined(MOZILLA_XPCOMRT_API)
+  // Clear the image without deleting the memory.
+  // This prevents image_ from being used if it
+  // does not have new content during the next NotifyPull.
+  image_->SetImage(nullptr, 0, 0, 0);
+#endif
 }
 
 
 }  // end namespace
--- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.h
+++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.h
@@ -22,17 +22,17 @@
 #include "AudioSegment.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "mozilla/Atomics.h"
 #include "SrtpFlow.h"
 #include "databuffer.h"
 #include "runnable_utils.h"
 #include "transportflow.h"
 
-#ifdef MOZILLA_INTERNAL_API
+#if defined(MOZILLA_INTERNAL_API)
 #include "VideoSegment.h"
 #endif
 
 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
 
 namespace mozilla {
 
 class PeerIdentity;
@@ -401,17 +401,17 @@ public:
 
   // Index used to refer to this before we know the TrackID
   // Note: unlike MediaPipeline::trackid(), this is threadsafe
   // Not set until first media is received
   virtual TrackID const trackid_locked() { return listener_->trackid(); }
   // written and used from MainThread
   virtual bool IsVideo() const override { return is_video_; }
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   // when the principal of the PeerConnection changes, it calls through to here
   // so that we can determine whether to enable stream transmission
   virtual void UpdateSinkIdentity_m(nsIPrincipal* principal,
                                     const PeerIdentity* sinkIdentity);
 #endif
 
   // Called on the main thread.
   virtual void DetachMediaStream() override {
@@ -444,17 +444,17 @@ public:
         mMutex("MediaPipelineTransmit::PipelineListener"),
         track_id_external_(TRACK_INVALID),
         active_(false),
         enabled_(false),
         direct_connect_(false),
         samples_10ms_buffer_(nullptr),
         buffer_current_(0),
         samplenum_10ms_(0)
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
         , last_img_(-1)
 #endif // MOZILLA_INTERNAL_API
     {
     }
 
     ~PipelineListener()
     {
       // release conduit on mainthread.  Must use forget()!
@@ -489,17 +489,17 @@ public:
    private:
     void NewData(MediaStreamGraph* graph, TrackID tid,
                  StreamTime offset,
                  uint32_t events,
                  const MediaSegment& media);
 
     virtual void ProcessAudioChunk(AudioSessionConduit *conduit,
                                    TrackRate rate, AudioChunk& chunk);
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
     virtual void ProcessVideoChunk(VideoSessionConduit *conduit,
                                    VideoChunk& chunk);
 #endif
     RefPtr<MediaSessionConduit> conduit_;
 
     // May be TRACK_INVALID until we see data from the track
     TrackID track_id_; // this is the current TrackID this listener is attached to
     Mutex mMutex;
@@ -520,17 +520,17 @@ public:
     // The buffer of 10ms audio samples that we will send once full
     // (can be carried over from one call to another).
     nsAutoArrayPtr<int16_t> samples_10ms_buffer_;
     // The location of the pointer within that buffer (in units of samples).
     int64_t buffer_current_;
     // The number of samples in a 10ms audio chunk.
     int64_t samplenum_10ms_;
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
     int32_t last_img_; // serial number of last Image
 #endif // MOZILLA_INTERNAL_API
   };
 
  private:
   RefPtr<PipelineListener> listener_;
   DOMMediaStream *domstream_;
   bool is_video_;
@@ -741,17 +741,19 @@ class MediaPipelineReceiveVideo : public
                           unsigned int buffer_size,
                           uint32_t time_stamp,
                           int64_t render_time,
                           const RefPtr<layers::Image>& video_image);
 
    private:
     int width_;
     int height_;
-#ifdef MOZILLA_INTERNAL_API
+#if defined(MOZILLA_XPCOMRT_API)
+    nsRefPtr<mozilla::SimpleImageBuffer> image_;
+#elif defined(MOZILLA_INTERNAL_API)
     nsRefPtr<layers::ImageContainer> image_container_;
     nsRefPtr<layers::Image> image_;
 #endif
     mozilla::ReentrantMonitor monitor_; // Monitor for processing WebRTC frames.
                                         // Protects image_ against:
                                         // - Writing from the GIPS thread
                                         // - Reading from the MSG thread
   };
--- a/media/webrtc/signaling/src/peerconnection/MediaPipelineFactory.cpp
+++ b/media/webrtc/signaling/src/peerconnection/MediaPipelineFactory.cpp
@@ -11,17 +11,17 @@
 #include "transportlayer.h"
 #include "transportlayerdtls.h"
 #include "transportlayerice.h"
 
 #include "signaling/src/jsep/JsepTrack.h"
 #include "signaling/src/jsep/JsepTransport.h"
 #include "signaling/src/common/PtrVector.h"
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 #include "MediaStreamTrack.h"
 #include "nsIPrincipal.h"
 #include "nsIDocument.h"
 #include "mozilla/Preferences.h"
 #include "MediaEngine.h"
 #endif
 
 #include "GmpVideoCodec.h"
@@ -498,17 +498,17 @@ MediaPipelineFactory::CreateMediaPipelin
       aTrack.GetTrackId(),
       aLevel,
       aTrack.GetMediaType() == SdpMediaSection::kVideo,
       aConduit,
       aRtpFlow,
       aRtcpFlow,
       aFilter);
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   // implement checking for peerIdentity (where failure == black/silence)
   nsIDocument* doc = mPC->GetWindow()->GetExtantDoc();
   if (doc) {
     pipeline->UpdateSinkIdentity_m(doc->NodePrincipal(),
                                    mPC->GetPeerIdentity());
   } else {
     MOZ_MTLOG(ML_ERROR, "Cannot initialize pipeline without attached doc");
     return NS_ERROR_FAILURE; // Don't remove this till we know it's safe.
@@ -766,17 +766,17 @@ MediaPipelineFactory::GetOrCreateVideoCo
 
   return NS_OK;
 }
 
 nsresult
 MediaPipelineFactory::ConfigureVideoCodecMode(const JsepTrack& aTrack,
                                               VideoSessionConduit& aConduit)
 {
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   nsRefPtr<LocalSourceStreamInfo> stream =
     mPCMedia->GetLocalStreamById(aTrack.GetStreamId());
 
   //get video track
   nsRefPtr<mozilla::dom::VideoStreamTrack> videotrack =
     stream->GetVideoTrackByTrackId(aTrack.GetTrackId());
 
   if (!videotrack) {
@@ -837,30 +837,30 @@ MediaPipelineFactory::EnsureExternalCode
       return kMediaConduitNoError;
     }
     // Register H.264 codec.
     if (aIsSend) {
       VideoEncoder* encoder = nullptr;
 #ifdef MOZ_WEBRTC_OMX
       encoder =
           OMXVideoCodec::CreateEncoder(OMXVideoCodec::CodecType::CODEC_H264);
-#else
+#elif !defined(MOZILLA_XPCOMRT_API)
       encoder = GmpVideoCodec::CreateEncoder();
 #endif
       if (encoder) {
         return aConduit.SetExternalSendCodec(aConfig, encoder);
       } else {
         return kMediaConduitInvalidSendCodec;
       }
     } else {
-      VideoDecoder* decoder;
+      VideoDecoder* decoder = nullptr;
 #ifdef MOZ_WEBRTC_OMX
       decoder =
           OMXVideoCodec::CreateDecoder(OMXVideoCodec::CodecType::CODEC_H264);
-#else
+#elif !defined(MOZILLA_XPCOMRT_API)
       decoder = GmpVideoCodec::CreateDecoder();
 #endif
       if (decoder) {
         return aConduit.SetExternalRecvCodec(aConfig, decoder);
       } else {
         return kMediaConduitInvalidReceiveCodec;
       }
     }
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionCtx.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionCtx.cpp
@@ -7,17 +7,17 @@
 #include "base/histogram.h"
 #include "PeerConnectionImpl.h"
 #include "PeerConnectionCtx.h"
 #include "runnable_utils.h"
 #include "prcvar.h"
 
 #include "mozilla/Telemetry.h"
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 #include "mozilla/dom/RTCPeerConnectionBinding.h"
 #include "mozilla/Preferences.h"
 #include <mozilla/Types.h>
 #endif
 
 #include "nsNetCID.h" // NS_SOCKETTRANSPORTSERVICE_CONTRACTID
 #include "nsServiceManagerUtils.h" // do_GetService
 #include "nsIObserverService.h"
@@ -146,17 +146,17 @@ void PeerConnectionCtx::Destroy() {
 
   if (gInstance) {
     gInstance->Cleanup();
     delete gInstance;
     gInstance = nullptr;
   }
 }
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 typedef Vector<nsAutoPtr<RTCStatsQuery>> RTCStatsQueries;
 
 // Telemetry reporting every second after start of first call.
 // The threading model around the media pipelines is weird:
 // - The pipelines are containers,
 // - containers that are only safe on main thread, with members only safe on STS,
 // - hence the there and back again approach.
 
@@ -304,17 +304,17 @@ PeerConnectionCtx::EverySecondTelemetryC
     NS_ENSURE_SUCCESS_VOID(rv);
   }
 }
 #endif
 
 nsresult PeerConnectionCtx::Initialize() {
   initGMP();
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   mConnectionCounter = 0;
   Telemetry::GetHistogramById(Telemetry::WEBRTC_CALL_COUNT)->Add(0);
 
   mTelemetryTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
   MOZ_ASSERT(mTelemetryTimer);
   nsresult rv = mTelemetryTimer->SetTarget(gMainThread);
   NS_ENSURE_SUCCESS(rv, rv);
   mTelemetryTimer->InitWithFuncCallback(EverySecondTelemetryCallback_m, this, 1000,
@@ -367,17 +367,17 @@ nsresult PeerConnectionCtx::Cleanup() {
   mQueuedJSEPOperations.Clear();
   mGMPService = nullptr;
   return NS_OK;
 }
 
 PeerConnectionCtx::~PeerConnectionCtx() {
     // ensure mTelemetryTimer ends on main thread
   MOZ_ASSERT(NS_IsMainThread());
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   if (mTelemetryTimer) {
     mTelemetryTimer->Cancel();
   }
 #endif
 };
 
 void PeerConnectionCtx::queueJSEPOperation(nsIRunnable* aOperation) {
   mQueuedJSEPOperations.AppendElement(aOperation);
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionCtx.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionCtx.h
@@ -44,17 +44,17 @@ class PeerConnectionCtx {
 
   bool gmpHasH264();
 
   // Make these classes friend so that they can access mPeerconnections.
   friend class PeerConnectionImpl;
   friend class PeerConnectionWrapper;
   friend class mozilla::dom::WebrtcGlobalInformation;
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   // WebrtcGlobalInformation uses this; we put it here so we don't need to
   // create another shutdown observer class.
   mozilla::dom::Sequence<mozilla::dom::RTCStatsReportInternal>
     mStatsForClosedPeerConnections;
 #endif
 
  private:
   // We could make these available only via accessors but it's too much trouble.
@@ -69,17 +69,17 @@ class PeerConnectionCtx {
   nsresult Initialize();
   nsresult Cleanup();
 
   void initGMP();
 
   static void
   EverySecondTelemetryCallback_m(nsITimer* timer, void *);
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   // Telemetry Peer conection counter
   int mConnectionCounter;
 
   nsCOMPtr<nsITimer> mTelemetryTimer;
 
 public:
   // TODO(jib): If we ever enable move semantics on std::map...
   //std::map<nsString,nsAutoPtr<mozilla::dom::RTCStatsReportInternal>> mLastReports;
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -41,27 +41,25 @@
 #include "nsDOMDataChannelDeclarations.h"
 #include "dtlsidentity.h"
 #include "signaling/src/sdp/SdpAttribute.h"
 
 #include "signaling/src/jsep/JsepTrack.h"
 #include "signaling/src/jsep/JsepSession.h"
 #include "signaling/src/jsep/JsepSessionImpl.h"
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 #ifdef XP_WIN
 // We need to undef the MS macro for nsIDocument::CreateEvent
 #ifdef CreateEvent
 #undef CreateEvent
 #endif
 #endif // XP_WIN
 
-#ifdef MOZILLA_INTERNAL_API
 #include "nsIDocument.h"
-#endif
 #include "nsPerformance.h"
 #include "nsGlobalWindow.h"
 #include "nsDOMDataChannel.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/PublicSSL.h"
 #include "nsXULAppAPI.h"
@@ -131,17 +129,17 @@ static const char* logTag = "PeerConnect
 
 // Getting exceptions back down from PCObserver is generally not harmful.
 namespace {
 class JSErrorResult : public ErrorResult
 {
 public:
   ~JSErrorResult()
   {
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
     WouldReportJSException();
     if (IsJSException()) {
       MOZ_ASSERT(NS_IsMainThread());
       AutoJSContext cx;
       Optional<JS::Handle<JS::Value> > value(cx);
       StealJSException(cx, &value.Value());
     }
 #endif
@@ -169,17 +167,17 @@ public:
   }
   operator JSErrorResult &() { return mRv; }
 private:
   JSErrorResult mRv;
   bool isCopy;
 };
 }
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 class TracksAvailableCallback : public DOMMediaStream::OnTracksAvailableCallback
 {
 public:
   TracksAvailableCallback(size_t numNewAudioTracks,
                           size_t numNewVideoTracks,
                           const std::string& pcHandle,
                           nsRefPtr<PeerConnectionObserver> aObserver)
   : DOMMediaStream::OnTracksAvailableCallback()
@@ -259,17 +257,17 @@ public:
   }
 
 private:
   nsRefPtr<PeerConnectionObserver> mObserver;
   const std::string mPcHandle;
 };
 #endif
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 static nsresult InitNSSInContent()
 {
   NS_ENSURE_TRUE(NS_IsMainThread(), NS_ERROR_NOT_SAME_THREAD);
 
   if (XRE_GetProcessType() != GeckoProcessType_Content) {
     MOZ_ASSERT_UNREACHABLE("Must be called in content process");
     return NS_ERROR_FAILURE;
   }
@@ -315,31 +313,31 @@ PRLogModuleInfo *signalingLogInfo() {
 template<>
 struct nsISupportsWeakReference::COMTypeInfo<nsSupportsWeakReference, void> {
   static const nsIID kIID;
 };
 const nsIID nsISupportsWeakReference::COMTypeInfo<nsSupportsWeakReference, void>::kIID = NS_ISUPPORTSWEAKREFERENCE_IID;
 
 namespace mozilla {
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 RTCStatsQuery::RTCStatsQuery(bool internal) :
   failed(false),
   internalStats(internal) {
 }
 
 RTCStatsQuery::~RTCStatsQuery() {
   MOZ_ASSERT(NS_IsMainThread());
 }
 
 #endif
 
 NS_IMPL_ISUPPORTS0(PeerConnectionImpl)
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 bool
 PeerConnectionImpl::WrapObject(JSContext* aCx,
                                JS::Handle<JSObject*> aGivenProto,
                                JS::MutableHandle<JSObject*> aReflector)
 {
   return PeerConnectionImplBinding::Wrap(aCx, this, aGivenProto, aReflector);
 }
 #endif
@@ -386,26 +384,26 @@ PeerConnectionImpl::PeerConnectionImpl(c
   , mUuidGen(MakeUnique<PCUuidGenerator>())
   , mNumAudioStreams(0)
   , mNumVideoStreams(0)
   , mHaveDataStream(false)
   , mAddCandidateErrorCount(0)
   , mTrickle(true) // TODO(ekr@rtfm.com): Use pref
   , mShouldSuppressNegotiationNeeded(true)
 {
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   MOZ_ASSERT(NS_IsMainThread());
   if (aGlobal) {
     mWindow = do_QueryInterface(aGlobal->GetAsSupports());
   }
 #endif
   CSFLogInfo(logTag, "%s: PeerConnectionImpl constructor for %s",
              __FUNCTION__, mHandle.c_str());
   STAMP_TIMECARD(mTimeCard, "Constructor Completed");
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   mAllowIceLoopback = Preferences::GetBool(
     "media.peerconnection.ice.loopback", false);
 #endif
 }
 
 PeerConnectionImpl::~PeerConnectionImpl()
 {
   if (mTimeCard) {
@@ -422,17 +420,17 @@ PeerConnectionImpl::~PeerConnectionImpl(
     CSFLogError(logTag, "PeerConnectionCtx is already gone. Ignoring...");
   }
 
   CSFLogInfo(logTag, "%s: PeerConnectionImpl destructor invoked for %s",
              __FUNCTION__, mHandle.c_str());
 
   Close();
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   {
     // Deregister as an NSS Shutdown Object
     nsNSSShutDownPreventionLock locker;
     if (!isAlreadyShutDown()) {
       destructorSafeDestroyNSSReference();
       shutdown(calledFromObject);
     }
   }
@@ -448,17 +446,17 @@ PeerConnectionImpl::~PeerConnectionImpl(
 }
 
 already_AddRefed<DOMMediaStream>
 PeerConnectionImpl::MakeMediaStream()
 {
   nsRefPtr<DOMMediaStream> stream =
     DOMMediaStream::CreateSourceStream(GetWindow());
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   // Make the stream data (audio/video samples) accessible to the receiving page.
   // We're only certain that privacy hasn't been requested if we're connected.
   if (mDtlsConnected && !PrivacyRequested()) {
     nsIDocument* doc = GetWindow()->GetExtantDoc();
     if (!doc) {
       return nullptr;
     }
     stream->CombineWithPrincipal(doc->NodePrincipal());
@@ -504,32 +502,32 @@ PeerConnectionImpl::CreateRemoteSourceSt
  *                     username: "jib", credential:"mypass"} ] }
  *
  * This function converts that into an internal IceConfiguration object.
  */
 nsresult
 PeerConnectionImpl::ConvertRTCConfiguration(const RTCConfiguration& aSrc,
                                             IceConfiguration *aDst)
 {
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   if (aSrc.mIceServers.WasPassed()) {
     for (size_t i = 0; i < aSrc.mIceServers.Value().Length(); i++) {
       nsresult rv = AddIceServer(aSrc.mIceServers.Value()[i], aDst);
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
 #endif
   return NS_OK;
 }
 
 nsresult
 PeerConnectionImpl::AddIceServer(const RTCIceServer &aServer,
                                  IceConfiguration *aDst)
 {
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   NS_ENSURE_STATE(aServer.mUrls.WasPassed());
   NS_ENSURE_STATE(aServer.mUrls.Value().IsStringSequence());
   auto &urls = aServer.mUrls.Value().GetAsStringSequence();
   for (size_t i = 0; i < urls.Length(); i++) {
     // Without STUN/TURN handlers, NS_NewURI returns nsSimpleURI rather than
     // nsStandardURL. To parse STUN/TURN URI's to spec
     // http://tools.ietf.org/html/draft-nandakumar-rtcweb-stun-uri-02#section-3
     // http://tools.ietf.org/html/draft-petithuguenin-behave-turn-uri-03#section-3
@@ -639,17 +637,17 @@ PeerConnectionImpl::Initialize(PeerConne
   CheckThread();
 
   mPCObserver = do_GetWeakReference(&aObserver);
 
   // Find the STS thread
 
   mSTSThread = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &res);
   MOZ_ASSERT(mSTSThread);
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 
   // Initialize NSS if we are in content process. For chrome process, NSS should already
   // been initialized.
   if (XRE_GetProcessType() == GeckoProcessType_Default) {
     // This code interferes with the C++ unit test startup code.
     nsCOMPtr<nsISupports> nssDummy = do_GetService("@mozilla.org/psm;1", &res);
     NS_ENSURE_SUCCESS(res, res);
   } else {
@@ -667,17 +665,17 @@ PeerConnectionImpl::Initialize(PeerConne
     mPrivacyRequested = true;
   }
 #endif // MOZILLA_INTERNAL_API
 
   PRTime timestamp = PR_Now();
   // Ok if we truncate this.
   char temp[128];
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   nsAutoCString locationCStr;
   nsIDOMLocation* location;
   res = mWindow->GetLocation(&location);
 
   if (location && NS_SUCCEEDED(res)) {
     nsAutoString locationAStr;
     location->ToString(locationAStr);
     location->Release();
@@ -834,16 +832,17 @@ class CompareCodecPriority {
     }
 
   private:
     std::string mPreferredCodec;
 };
 
 nsresult
 PeerConnectionImpl::ConfigureJsepSessionCodecs() {
+#if !defined(MOZILLA_XPCOMRT_API)
   nsresult res;
   nsCOMPtr<nsIPrefService> prefs =
     do_GetService("@mozilla.org/preferences-service;1", &res);
 
   if (NS_FAILED(res)) {
     CSFLogError(logTag, "%s: Couldn't get prefs service, res=%u",
                         __FUNCTION__,
                         static_cast<unsigned>(res));
@@ -884,17 +883,17 @@ PeerConnectionImpl::ConfigureJsepSession
     if (encode->ReserveOMXCodec() && decode->ReserveOMXCodec()) {
       CSFLogDebug( logTag, "%s: H264 hardware codec available", __FUNCTION__);
       hardwareH264Supported = true;
     }
   }
 
 #endif // MOZ_WEBRTC_OMX
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   bool softwareH264Enabled = PeerConnectionCtx::GetInstance()->gmpHasH264();
 #else
   // For unit-tests
   bool softwareH264Enabled = true;
 #endif
 
   bool h264Enabled = hardwareH264Supported || softwareH264Enabled;
 
@@ -985,17 +984,17 @@ PeerConnectionImpl::ConfigureJsepSession
   branch->GetIntPref("media.navigator.video.preferred_codec",
                      &preferredCodec);
 
   if (preferredCodec) {
     comparator.SetPreferredCodec(preferredCodec);
   }
 
   std::stable_sort(codecs.begin(), codecs.end(), comparator);
-
+#endif // !defined(MOZILLA_XPCOMRT_API)
   return NS_OK;
 }
 
 RefPtr<DtlsIdentity> const
 PeerConnectionImpl::GetIdentity() const
 {
   PC_AUTO_ENTER_API_CALL_NO_CHECK();
   return mIdentity;
@@ -1004,17 +1003,17 @@ PeerConnectionImpl::GetIdentity() const
 // Data channels won't work without a window, so in order for the C++ unit
 // tests to work (it doesn't have a window available) we ifdef the following
 // two implementations.
 NS_IMETHODIMP
 PeerConnectionImpl::EnsureDataConnection(uint16_t aNumstreams)
 {
   PC_AUTO_ENTER_API_CALL_NO_CHECK();
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   if (mDataConnection) {
     CSFLogDebug(logTag,"%s DataConnection already connected",__FUNCTION__);
     // Ignore the request to connect when already connected.  This entire
     // implementation is temporary.  Ignore aNumstreams as it's merely advisory
     // and we increase the number of streams dynamically as needed.
     return NS_OK;
   }
   mDataConnection = new DataChannelConnection(this);
@@ -1114,17 +1113,17 @@ PeerConnectionImpl::InitializeDataChanne
 
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!codec) {
     CSFLogDebug(logTag, "%s: We did not negotiate datachannel", __FUNCTION__);
     return NS_OK;
   }
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   uint32_t channels = codec->mChannels;
   if (channels > MAX_NUM_STREAMS) {
     channels = MAX_NUM_STREAMS;
   }
 
   rv = EnsureDataConnection(codec->mChannels);
   if (NS_SUCCEEDED(rv)) {
     uint16_t localport = 5000;
@@ -1160,17 +1159,17 @@ PeerConnectionImpl::CreateDataChannel(co
                                       uint16_t aType,
                                       bool outOfOrderAllowed,
                                       uint16_t aMaxTime,
                                       uint16_t aMaxNum,
                                       bool aExternalNegotiated,
                                       uint16_t aStream,
                                       ErrorResult &rv)
 {
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   nsRefPtr<nsDOMDataChannel> result;
   rv = CreateDataChannel(aLabel, aProtocol, aType, outOfOrderAllowed,
                          aMaxTime, aMaxNum, aExternalNegotiated,
                          aStream, getter_AddRefs(result));
   return result.forget();
 #else
   return nullptr;
 #endif
@@ -1185,17 +1184,17 @@ PeerConnectionImpl::CreateDataChannel(co
                                       uint16_t aMaxNum,
                                       bool aExternalNegotiated,
                                       uint16_t aStream,
                                       nsDOMDataChannel** aRetval)
 {
   PC_AUTO_ENTER_API_CALL_NO_CHECK();
   MOZ_ASSERT(aRetval);
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   nsRefPtr<DataChannel> dataChannel;
   DataChannelConnection::Type theType =
     static_cast<DataChannelConnection::Type>(aType);
 
   nsresult rv = EnsureDataConnection(WEBRTC_DATACHANNEL_STREAMS_DEFAULT);
   if (NS_FAILED(rv)) {
     return rv;
   }
@@ -1269,17 +1268,17 @@ do_QueryObjectReferent(nsIWeakReference*
     return nullptr;
   }
   nsRefPtr<nsSupportsWeakReference> tmp2 = do_QueryObject(tmp);
   nsRefPtr<PeerConnectionObserver> tmp3 = static_cast<PeerConnectionObserver*>(&*tmp2);
   return tmp3.forget();
 }
 
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 // Not a member function so that we don't need to keep the PC live.
 static void NotifyDataChannel_m(nsRefPtr<nsIDOMDataChannel> aChannel,
                                 nsRefPtr<PeerConnectionObserver> aObserver)
 {
   MOZ_ASSERT(NS_IsMainThread());
   JSErrorResult rv;
   nsRefPtr<nsDOMDataChannel> channel = static_cast<nsDOMDataChannel*>(&*aChannel);
   aObserver->NotifyDataChannel(*channel, rv);
@@ -1297,17 +1296,17 @@ PeerConnectionImpl::NotifyDataChannel(al
   // if !MOZILLA_INTERNAL_API, but this function leaks the DataChannel if
   // !MOZILLA_INTERNAL_API because it never transfers the ref to
   // NS_NewDOMDataChannel.
   DataChannel* channel = aChannel.take();
   MOZ_ASSERT(channel);
 
   CSFLogDebug(logTag, "%s: channel: %p", __FUNCTION__, channel);
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   nsCOMPtr<nsIDOMDataChannel> domchannel;
   nsresult rv = NS_NewDOMDataChannel(already_AddRefed<DataChannel>(channel),
                                      mWindow, getter_AddRefs(domchannel));
   NS_ENSURE_SUCCESS_VOID(rv);
 
   mHaveDataStream = true;
 
   nsRefPtr<PeerConnectionObserver> pco = do_QueryObjectReferent(mPCObserver);
@@ -1322,17 +1321,17 @@ PeerConnectionImpl::NotifyDataChannel(al
                 NS_DISPATCH_NORMAL);
 #endif
 }
 
 NS_IMETHODIMP
 PeerConnectionImpl::CreateOffer(const RTCOfferOptions& aOptions)
 {
   JsepOfferOptions options;
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   if (aOptions.mOfferToReceiveAudio.WasPassed()) {
     options.mOfferToReceiveAudio =
       mozilla::Some(size_t(aOptions.mOfferToReceiveAudio.Value()));
   }
 
   if (aOptions.mOfferToReceiveVideo.WasPassed()) {
     options.mOfferToReceiveVideo =
         mozilla::Some(size_t(aOptions.mOfferToReceiveVideo.Value()));
@@ -1469,17 +1468,17 @@ PeerConnectionImpl::SetLocalDescription(
   JSErrorResult rv;
   nsRefPtr<PeerConnectionObserver> pco = do_QueryObjectReferent(mPCObserver);
   if (!pco) {
     return NS_OK;
   }
 
   STAMP_TIMECARD(mTimeCard, "Set Local Description");
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   bool isolated = mMedia->AnyLocalStreamHasPeerIdentity();
   mPrivacyRequested = mPrivacyRequested || isolated;
 #endif
 
   mLocalRequestedSDP = aSDP;
 
   JsepSdpType sdpType;
   switch (aAction) {
@@ -1650,17 +1649,17 @@ PeerConnectionImpl::SetRemoteDescription
           pco->OnSetRemoteDescriptionError(
               kInternalError,
               ObString("AddRemoteStream failed"),
               jrv);
           return NS_OK;
         }
         CSFLogDebug(logTag, "Added remote stream %s", info->GetId().c_str());
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
         info->GetMediaStream()->AssignId(NS_ConvertUTF8toUTF16(streamId.c_str()));
 #else
         info->GetMediaStream()->AssignId((streamId));
 #endif
       }
 
       size_t numNewAudioTracks = 0;
       size_t numNewVideoTracks = 0;
@@ -1681,17 +1680,17 @@ PeerConnectionImpl::SetRemoteDescription
           CSFLogDebug(logTag, "Added remote track %s/%s",
                       info->GetId().c_str(), track->GetTrackId().c_str());
         } else {
           ++numPreexistingTrackIds;
         }
       }
 
       // Now that the streams are all set up, notify about track availability.
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
       TracksAvailableCallback* tracksAvailableCallback =
         new TracksAvailableCallback(numNewAudioTracks,
                                     numNewVideoTracks,
                                     mHandle,
                                     pco);
       info->GetMediaStream()->OnTracksAvailable(tracksAvailableCallback);
 #else
       if (!numPreexistingTrackIds) {
@@ -1716,28 +1715,28 @@ PeerConnectionImpl::SetRemoteDescription
 
       // We might be holding the last ref, but that's ok.
       if (!info->GetTrackCount()) {
         pco->OnRemoveStream(*info->GetMediaStream(), jrv);
       }
     }
 
     pco->OnSetRemoteDescriptionSuccess(jrv);
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
     startCallTelem();
 #endif
   }
 
   UpdateSignalingState();
   return NS_OK;
 }
 
 // WebRTC uses highres time relative to the UNIX epoch (Jan 1, 1970, UTC).
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 nsresult
 PeerConnectionImpl::GetTimeSinceEpoch(DOMHighResTimeStamp *result) {
   MOZ_ASSERT(NS_IsMainThread());
   nsPerformance *perf = mWindow->GetPerformance();
   NS_ENSURE_TRUE(perf && perf->Timing(), NS_ERROR_UNEXPECTED);
   *result = perf->Now() + perf->Timing()->NavigationStart();
   return NS_OK;
 }
@@ -1759,17 +1758,17 @@ public:
   }
 };
 #endif
 
 NS_IMETHODIMP
 PeerConnectionImpl::GetStats(MediaStreamTrack *aSelector) {
   PC_AUTO_ENTER_API_CALL(true);
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   if (!mMedia) {
     // Since we zero this out before the d'tor, we should check.
     return NS_ERROR_UNEXPECTED;
   }
 
   nsAutoPtr<RTCStatsQuery> query(new RTCStatsQuery(false));
 
   nsresult rv = BuildStatsQuery_m(aSelector, query.get());
@@ -1794,17 +1793,17 @@ PeerConnectionImpl::AddIceCandidate(cons
   if (!pco) {
     return NS_OK;
   }
 
   STAMP_TIMECARD(mTimeCard, "Add Ice Candidate");
 
   CSFLogDebug(logTag, "AddIceCandidate: %s", aCandidate);
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   // When remote candidates are added before our ICE ctx is up and running
   // (the transition to New is async through STS, so this is not impossible),
   // we won't record them as trickle candidates. Is this what we want?
   if(!mIceStartTime.IsNull()) {
     TimeDuration timeDelta = TimeStamp::Now() - mIceStartTime;
     if (mIceConnectionState == PCImplIceConnectionState::Failed) {
       Telemetry::Accumulate(Telemetry::WEBRTC_ICE_LATE_TRICKLE_ARRIVAL_TIME,
                             timeDelta.ToMilliseconds());
@@ -1857,17 +1856,17 @@ PeerConnectionImpl::AddIceCandidate(cons
 
 NS_IMETHODIMP
 PeerConnectionImpl::CloseStreams() {
   PC_AUTO_ENTER_API_CALL(false);
 
   return NS_OK;
 }
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 nsresult
 PeerConnectionImpl::SetPeerIdentity(const nsAString& aPeerIdentity)
 {
   PC_AUTO_ENTER_API_CALL(true);
   MOZ_ASSERT(!aPeerIdentity.IsEmpty());
 
   // once set, this can't be changed
   if (mPeerIdentity) {
@@ -1891,74 +1890,74 @@ nsresult
 PeerConnectionImpl::SetDtlsConnected(bool aPrivacyRequested)
 {
   PC_AUTO_ENTER_API_CALL(false);
 
   // For this, as with mPrivacyRequested, once we've connected to a peer, we
   // fixate on that peer.  Dealing with multiple peers or connections is more
   // than this run-down wreck of an object can handle.
   // Besides, this is only used to say if we have been connected ever.
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   if (!mPrivacyRequested && !aPrivacyRequested && !mDtlsConnected) {
     // now we know that privacy isn't needed for sure
     nsIDocument* doc = GetWindow()->GetExtantDoc();
     if (!doc) {
       CSFLogInfo(logTag, "Can't update principal on streams; document gone");
       return NS_ERROR_FAILURE;
     }
     mMedia->UpdateRemoteStreamPrincipals_m(doc->NodePrincipal());
   }
 #endif
   mDtlsConnected = true;
   mPrivacyRequested = mPrivacyRequested || aPrivacyRequested;
   return NS_OK;
 }
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 void
 PeerConnectionImpl::PrincipalChanged(DOMMediaStream* aMediaStream) {
   nsIDocument* doc = GetWindow()->GetExtantDoc();
   if (doc) {
     mMedia->UpdateSinkIdentity_m(doc->NodePrincipal(), mPeerIdentity);
   } else {
     CSFLogInfo(logTag, "Can't update sink principal; document gone");
   }
 }
 #endif
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 nsresult
 PeerConnectionImpl::GetRemoteTrackId(const std::string streamId,
                                      TrackID numericTrackId,
                                      std::string* trackId) const
 {
   if (IsClosed()) {
     return NS_ERROR_UNEXPECTED;
   }
 
   return mMedia->GetRemoteTrackId(streamId, numericTrackId, trackId);
 }
 #endif
 
 std::string
 PeerConnectionImpl::GetTrackId(const MediaStreamTrack& aTrack)
 {
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   nsString wideTrackId;
   aTrack.GetId(wideTrackId);
   return NS_ConvertUTF16toUTF8(wideTrackId).get();
 #else
   return aTrack.GetId();
 #endif
 }
 
 std::string
 PeerConnectionImpl::GetStreamId(const DOMMediaStream& aStream)
 {
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   nsString wideStreamId;
   aStream.GetId(wideStreamId);
   return NS_ConvertUTF16toUTF8(wideStreamId).get();
 #else
   return aStream.GetId();
 #endif
 }
 
@@ -2010,17 +2009,17 @@ PeerConnectionImpl::AddTrack(MediaStream
       CSFLogError(logTag, "%s (audio) : pc = %s, error = %s",
                   __FUNCTION__, mHandle.c_str(), errorString.c_str());
       return NS_ERROR_FAILURE;
     }
     mNumAudioStreams++;
   }
 
   if (aTrack.AsVideoStreamTrack()) {
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
     if (!Preferences::GetBool("media.peerconnection.video.enabled", true)) {
       // Before this code was moved, this would silently ignore just like it
       // does now. Is this actually what we want to do?
       return NS_OK;
     }
 #endif
 
     res = mJsepSession->AddTrack(new JsepTrack(
@@ -2085,17 +2084,17 @@ PeerConnectionImpl::ReplaceTrack(MediaSt
   PC_AUTO_ENTER_API_CALL(true);
 
   nsRefPtr<PeerConnectionObserver> pco = do_QueryObjectReferent(mPCObserver);
   if (!pco) {
     return NS_ERROR_UNEXPECTED;
   }
   JSErrorResult jrv;
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   if (&aThisTrack == &aWithTrack) {
     pco->OnReplaceTrackSuccess(jrv);
     if (jrv.Failed()) {
       CSFLogError(logTag, "Error firing replaceTrack success callback");
       return NS_ERROR_UNEXPECTED;
     }
     return NS_OK;
   }
@@ -2302,17 +2301,17 @@ PeerConnectionImpl::PluginCrash(uint64_t
   // fire an event to the DOM window if this is "ours"
   bool result = mMedia ? mMedia->AnyCodecHasPluginID(aPluginID) : false;
   if (!result) {
     return false;
   }
 
   CSFLogError(logTag, "%s: Our plugin %llu crashed", __FUNCTION__, static_cast<unsigned long long>(aPluginID));
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   nsCOMPtr<nsIDocument> doc = mWindow->GetExtantDoc();
   if (!doc) {
     NS_WARNING("Couldn't get document for PluginCrashed event!");
     return true;
   }
 
   PluginCrashedEventInit init;
   init.mPluginDumpID = aPluginDumpID;
@@ -2344,17 +2343,17 @@ PeerConnectionImpl::CloseInt()
   // transitioned to connected. As a bonus, this allows us to detect race
   // conditions where a stats dispatch happens right as the PC closes.
   RecordLongtermICEStatistics();
   CSFLogInfo(logTag, "%s: Closing PeerConnectionImpl %s; "
              "ending call", __FUNCTION__, mHandle.c_str());
   if (mJsepSession) {
     mJsepSession->Close();
   }
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   if (mDataConnection) {
     CSFLogInfo(logTag, "%s: Destroying DataChannelConnection %p for %s",
                __FUNCTION__, (void *) mDataConnection.get(), mHandle.c_str());
     mDataConnection->Destroy();
     mDataConnection = nullptr; // it may not go away until the runnables are dead
   }
 #endif
   ShutdownMedia();
@@ -2367,17 +2366,17 @@ PeerConnectionImpl::CloseInt()
 void
 PeerConnectionImpl::ShutdownMedia()
 {
   PC_AUTO_ENTER_API_CALL_NO_CHECK();
 
   if (!mMedia)
     return;
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   // before we destroy references to local streams, detach from them
   for(uint32_t i = 0; i < media()->LocalStreamsLength(); ++i) {
     LocalSourceStreamInfo *info = media()->GetLocalStreamByIndex(i);
     info->GetMediaStream()->RemovePrincipalChangeObserver(this);
   }
 
   // End of call to be recorded in Telemetry
   if (!mStartTime.IsNull()){
@@ -2386,17 +2385,17 @@ PeerConnectionImpl::ShutdownMedia()
   }
 #endif
 
   // Forget the reference so that we can transfer it to
   // SelfDestruct().
   mMedia.forget().take()->SelfDestruct();
 }
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 // If NSS is shutting down, then we need to get rid of the DTLS
 // identity right now; otherwise, we'll cause wreckage when we do
 // finally deallocate it in our destructor.
 void
 PeerConnectionImpl::virtualDestroyNSSReference()
 {
   destructorSafeDestroyNSSReference();
 }
@@ -2642,17 +2641,17 @@ PeerConnectionImpl::SendLocalIceCandidat
       WrapRunnableNM(&SendLocalIceCandidateToContentImpl,
                      mPCObserver,
                      level,
                      mid,
                      candidate),
       NS_DISPATCH_NORMAL);
 }
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 static bool isDone(PCImplIceConnectionState state) {
   return state != PCImplIceConnectionState::Checking &&
          state != PCImplIceConnectionState::New;
 }
 
 static bool isSucceeded(PCImplIceConnectionState state) {
   return state == PCImplIceConnectionState::Connected ||
          state == PCImplIceConnectionState::Completed;
@@ -2668,17 +2667,17 @@ void PeerConnectionImpl::IceConnectionSt
     NrIceCtx* ctx,
     NrIceCtx::ConnectionState state) {
   PC_AUTO_ENTER_API_CALL_VOID_RETURN(false);
 
   CSFLogDebug(logTag, "%s", __FUNCTION__);
 
   auto domState = toDomIceConnectionState(state);
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   if (!isDone(mIceConnectionState) && isDone(domState)) {
     // mIceStartTime can be null if going directly from New to Closed, in which
     // case we don't count it as a success or a failure.
     if (!mIceStartTime.IsNull()){
       TimeDuration timeDelta = TimeStamp::Now() - mIceStartTime;
       if (isSucceeded(domState)) {
         Telemetry::Accumulate(Telemetry::WEBRTC_ICE_SUCCESS_TIME,
                               timeDelta.ToMilliseconds());
@@ -2704,17 +2703,17 @@ void PeerConnectionImpl::IceConnectionSt
 
   // Would be nice if we had a means of converting one of these dom enums
   // to a string that wasn't almost as much text as this switch statement...
   switch (mIceConnectionState) {
     case PCImplIceConnectionState::New:
       STAMP_TIMECARD(mTimeCard, "Ice state: new");
       break;
     case PCImplIceConnectionState::Checking:
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
       // For telemetry
       mIceStartTime = TimeStamp::Now();
 #endif
       STAMP_TIMECARD(mTimeCard, "Ice state: checking");
       break;
     case PCImplIceConnectionState::Connected:
       STAMP_TIMECARD(mTimeCard, "Ice state: connected");
       break;
@@ -2794,17 +2793,17 @@ PeerConnectionImpl::IceGatheringStateCha
 void
 PeerConnectionImpl::EndOfLocalCandidates(const std::string& defaultAddr,
                                          uint16_t defaultPort,
                                          uint16_t level) {
   CSFLogDebug(logTag, "%s", __FUNCTION__);
   mJsepSession->EndOfLocalCandidates(defaultAddr, defaultPort, level);
 }
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 nsresult
 PeerConnectionImpl::BuildStatsQuery_m(
     mozilla::dom::MediaStreamTrack *aSelector,
     RTCStatsQuery *query) {
 
   if (!HasMedia()) {
     return NS_ERROR_UNEXPECTED;
   }
@@ -3253,17 +3252,17 @@ void PeerConnectionImpl::DeliverStatsRep
     }
   }
 }
 
 #endif
 
 void
 PeerConnectionImpl::RecordLongtermICEStatistics() {
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   WebrtcGlobalInformation::StoreLongTermICEStatistics(*this);
 #endif
 }
 
 void
 PeerConnectionImpl::OnNegotiationNeeded()
 {
   if (mShouldSuppressNegotiationNeeded) {
@@ -3285,17 +3284,17 @@ void
 PeerConnectionImpl::IceStreamReady(NrIceMediaStream *aStream)
 {
   PC_AUTO_ENTER_API_CALL_NO_CHECK();
   MOZ_ASSERT(aStream);
 
   CSFLogDebug(logTag, "%s: %s", __FUNCTION__, aStream->name().c_str());
 }
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 //Telemetry for when calls start
 void
 PeerConnectionImpl::startCallTelem() {
   // Start time for calls
   mStartTime = TimeStamp::Now();
 
   // Increment session call counter
   int &cnt = PeerConnectionCtx::GetInstance()->mConnectionCounter;
@@ -3304,33 +3303,33 @@ PeerConnectionImpl::startCallTelem() {
   Telemetry::GetHistogramById(Telemetry::WEBRTC_CALL_COUNT)->Add(cnt);
 }
 #endif
 
 NS_IMETHODIMP
 PeerConnectionImpl::GetLocalStreams(nsTArray<nsRefPtr<DOMMediaStream > >& result)
 {
   PC_AUTO_ENTER_API_CALL_NO_CHECK();
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   for(uint32_t i=0; i < media()->LocalStreamsLength(); i++) {
     LocalSourceStreamInfo *info = media()->GetLocalStreamByIndex(i);
     NS_ENSURE_TRUE(info, NS_ERROR_UNEXPECTED);
     result.AppendElement(info->GetMediaStream());
   }
   return NS_OK;
 #else
   return NS_ERROR_FAILURE;
 #endif
 }
 
 NS_IMETHODIMP
 PeerConnectionImpl::GetRemoteStreams(nsTArray<nsRefPtr<DOMMediaStream > >& result)
 {
   PC_AUTO_ENTER_API_CALL_NO_CHECK();
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   for(uint32_t i=0; i < media()->RemoteStreamsLength(); i++) {
     RemoteSourceStreamInfo *info = media()->GetRemoteStreamByIndex(i);
     NS_ENSURE_TRUE(info, NS_ERROR_UNEXPECTED);
     result.AppendElement(info->GetMediaStream());
   }
   return NS_OK;
 #else
   return NS_ERROR_FAILURE;
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
@@ -28,17 +28,17 @@
 #include "signaling/src/jsep/JsepSession.h"
 #include "signaling/src/jsep/JsepSessionImpl.h"
 #include "signaling/src/sdp/SdpMediaSection.h"
 
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/PeerConnectionImplEnumsBinding.h"
 #include "StreamBuffer.h"
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 #include "mozilla/TimeStamp.h"
 #include "mozilla/net/DataChannel.h"
 #include "VideoUtils.h"
 #include "VideoSegment.h"
 #include "nsNSSShutDown.h"
 #include "mozilla/dom/RTCStatsReportBinding.h"
 #include "nsIPrincipal.h"
 #include "mozilla/PeerIdentity.h"
@@ -124,17 +124,17 @@ using mozilla::dom::RTCIceServer;
 using mozilla::dom::RTCOfferOptions;
 using mozilla::DOMMediaStream;
 using mozilla::NrIceCtx;
 using mozilla::NrIceMediaStream;
 using mozilla::DtlsIdentity;
 using mozilla::ErrorResult;
 using mozilla::NrIceStunServer;
 using mozilla::NrIceTurnServer;
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 using mozilla::PeerIdentity;
 #endif
 
 class PeerConnectionWrapper;
 class PeerConnectionMedia;
 class RemoteSourceStreamInfo;
 
 // Uuid Generator
@@ -181,17 +181,17 @@ public:
   void addTurnServer(const NrIceTurnServer& server) { mTurnServers.push_back (server); }
   const std::vector<NrIceStunServer>& getStunServers() const { return mStunServers; }
   const std::vector<NrIceTurnServer>& getTurnServers() const { return mTurnServers; }
 private:
   std::vector<NrIceStunServer> mStunServers;
   std::vector<NrIceTurnServer> mTurnServers;
 };
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 // Not an inner class so we can forward declare.
 class RTCStatsQuery {
   public:
     explicit RTCStatsQuery(bool internalStats);
     ~RTCStatsQuery();
 
     nsAutoPtr<mozilla::dom::RTCStatsReportInternal> report;
     std::string error;
@@ -223,17 +223,17 @@ class RTCStatsQuery {
     do { \
       /* do/while prevents res from conflicting with locals */    \
       nsresult res = CheckApiState(assert_ice_ready);             \
       if (NS_FAILED(res)) return; \
     } while(0)
 #define PC_AUTO_ENTER_API_CALL_NO_CHECK() CheckThread()
 
 class PeerConnectionImpl final : public nsISupports,
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
                                  public mozilla::DataChannelConnection::DataConnectionListener,
                                  public nsNSSShutDownObject,
                                  public DOMMediaStream::PrincipalChangeObserver,
 #endif
                                  public sigslot::has_slots<>
 {
   struct Internal; // Avoid exposing c includes to bindings
 
@@ -248,17 +248,17 @@ public:
     kInvalidSessionDescription        = 5,
     kIncompatibleSessionDescription   = 6,
     kIncompatibleMediaStreamTrack     = 8,
     kInternalError                    = 9
   };
 
   NS_DECL_THREADSAFE_ISUPPORTS
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
 #endif
 
   static already_AddRefed<PeerConnectionImpl>
       Constructor(const mozilla::dom::GlobalObject& aGlobal, ErrorResult& rv);
   static PeerConnectionImpl* CreatePeerConnection();
   static nsresult ConvertRTCConfiguration(const RTCConfiguration& aSrc,
                                           IceConfiguration *aDst);
@@ -266,17 +266,17 @@ public:
                                IceConfiguration* aDst);
   already_AddRefed<DOMMediaStream> MakeMediaStream();
 
   nsresult CreateRemoteSourceStreamInfo(nsRefPtr<RemoteSourceStreamInfo>* aInfo,
                                         const std::string& aId);
 
   // DataConnection observers
   void NotifyDataChannel(already_AddRefed<mozilla::DataChannel> aChannel)
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
     // PeerConnectionImpl only inherits from mozilla::DataChannelConnection
     // inside libxul.
     override
 #endif
     ;
 
   // Get the media object
   const nsRefPtr<PeerConnectionMedia>& media() const {
@@ -420,28 +420,28 @@ public:
                                mozilla::dom::MediaStreamTrack& aThisTrack,
                                mozilla::dom::MediaStreamTrack& aWithTrack)
   {
     rv = ReplaceTrack(aThisTrack, aWithTrack);
   }
 
   nsresult GetPeerIdentity(nsAString& peerIdentity)
   {
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
     if (mPeerIdentity) {
       peerIdentity = mPeerIdentity->ToString();
       return NS_OK;
     }
 #endif
 
     peerIdentity.SetIsVoid(true);
     return NS_OK;
   }
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   const PeerIdentity* GetPeerIdentity() const { return mPeerIdentity; }
   nsresult SetPeerIdentity(const nsAString& peerIdentity);
 
   const std::string& GetIdAsAscii() const
   {
     return mName;
   }
 
@@ -578,17 +578,17 @@ public:
   void UpdateSignalingState();
 
   bool IsClosed() const;
   // called when DTLS connects; we only need this once
   nsresult SetDtlsConnected(bool aPrivacyRequested);
 
   bool HasMedia() const;
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   // initialize telemetry for when calls start
   void startCallTelem();
 
   nsresult BuildStatsQuery_m(
       mozilla::dom::MediaStreamTrack *aSelector,
       RTCStatsQuery *query);
 
   static nsresult ExecuteStatsQuery_s(RTCStatsQuery *query);
@@ -621,28 +621,30 @@ private:
   NS_IMETHODIMP EnsureDataConnection(uint16_t aNumstreams);
 
   nsresult CloseInt();
   nsresult CheckApiState(bool assert_ice_ready) const;
   void CheckThread() const {
     MOZ_ASSERT(CheckThreadInt(), "Wrong thread");
   }
   bool CheckThreadInt() const {
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
     // Thread assertions are disabled in the C++ unit tests because those
     // make API calls off the main thread.
+    // This affects the standalone version of WebRTC since it is also used
+    // for an alternate build of the unit tests.
     // TODO(ekr@rtfm.com): Fix the unit tests so they don't do that.
     bool on;
     NS_ENSURE_SUCCESS(mThread->IsOnCurrentThread(&on), false);
     NS_ENSURE_TRUE(on, false);
 #endif
     return true;
   }
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   void virtualDestroyNSSReference() final;
   void destructorSafeDestroyNSSReference();
   nsresult GetTimeSinceEpoch(DOMHighResTimeStamp *result);
 #endif
 
   // Shut down media - called on main thread only
   void ShutdownMedia();
 
@@ -650,17 +652,17 @@ private:
   void SendLocalIceCandidateToContent(uint16_t level,
                                       const std::string& mid,
                                       const std::string& candidate);
 
   nsresult GetDatachannelParameters(
       const mozilla::JsepApplicationCodecDescription** codec,
       uint16_t* level) const;
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   static void GetStatsForPCObserver_s(
       const std::string& pcHandle,
       nsAutoPtr<RTCStatsQuery> query);
 
   // Sends an RTCStatsReport to JS. Must run on main thread.
   static void DeliverStatsReportToPCObserver_m(
       const std::string& pcHandle,
       nsresult result,
@@ -702,17 +704,17 @@ private:
   std::string mRemoteRequestedSDP;
 
   // DTLS fingerprint
   std::string mFingerprint;
   std::string mRemoteFingerprint;
 
   // identity-related fields
   mozilla::RefPtr<DtlsIdentity> mIdentity;
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   // The entity on the other end of the peer-to-peer connection;
   // void if they are not yet identified, and no identity setting has been set
   nsAutoPtr<PeerIdentity> mPeerIdentity;
 #endif
   // Whether an app should be prevented from accessing media produced by the PC
   // If this is true, then media will not be sent until mPeerIdentity matches
   // local streams PeerIdentity; and remote streams are protected from content
   //
@@ -724,29 +726,29 @@ private:
   std::string mHandle;
 
   // A name for this PC that we are willing to expose to content.
   std::string mName;
 
   // The target to run stuff on
   nsCOMPtr<nsIEventTarget> mSTSThread;
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   // DataConnection that's used to get all the DataChannels
   nsRefPtr<mozilla::DataChannelConnection> mDataConnection;
 #endif
 
   bool mAllowIceLoopback;
   nsRefPtr<PeerConnectionMedia> mMedia;
 
   // The JSEP negotiation session.
   mozilla::UniquePtr<PCUuidGenerator> mUuidGen;
   mozilla::UniquePtr<mozilla::JsepSession> mJsepSession;
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   // Start time of ICE, used for telemetry
   mozilla::TimeStamp mIceStartTime;
   // Start time of call used for Telemetry
   mozilla::TimeStamp mStartTime;
 #endif
 
   // Temporary: used to prevent multiple audio streams or multiple video streams
   // in a single PC. This is tied up in the IETF discussion around proper
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
@@ -18,27 +18,30 @@
 #include "AudioConduit.h"
 #include "VideoConduit.h"
 #include "runnable_utils.h"
 #include "transportlayerice.h"
 #include "transportlayerdtls.h"
 #include "signaling/src/jsep/JsepSession.h"
 #include "signaling/src/jsep/JsepTransport.h"
 
+#if !defined(MOZILLA_XPCOMRT_API)
 #include "nsNetCID.h"
 #include "nsNetUtil.h"
 #include "nsICancelable.h"
 #include "nsIDocument.h"
 #include "nsILoadInfo.h"
 #include "nsIContentPolicy.h"
 #include "nsIProxyInfo.h"
 #include "nsIProtocolProxyService.h"
+#endif // !defined(MOZILLA_XPCOMRT_API)
+
 #include "nsProxyRelease.h"
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 #include "MediaStreamList.h"
 #include "nsIScriptGlobalObject.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/RTCStatsReportBinding.h"
 #include "MediaStreamTrack.h"
 #include "VideoStreamTrack.h"
 #endif
 
@@ -148,16 +151,17 @@ PeerConnectionImpl* PeerConnectionImpl::
 {
   PeerConnectionImpl *pc = new PeerConnectionImpl();
 
   CSFLogDebug(logTag, "Created PeerConnection: %p", pc);
 
   return pc;
 }
 
+#if !defined(MOZILLA_XPCOMRT_API)
 NS_IMETHODIMP PeerConnectionMedia::ProtocolProxyQueryHandler::
 OnProxyAvailable(nsICancelable *request,
                  nsIChannel *aChannel,
                  nsIProxyInfo *proxyinfo,
                  nsresult result) {
   CSFLogInfo(logTag, "%s: Proxy Available: %d", __FUNCTION__, (int)result);
 
   if (NS_SUCCEEDED(result) && proxyinfo) {
@@ -194,16 +198,17 @@ OnProxyAvailable(nsICancelable *request,
     pcm_->mProxyResolveCompleted = true;
     pcm_->FlushIceCtxOperationQueueIfReady();
   }
 
   return NS_OK;
 }
 
 NS_IMPL_ISUPPORTS(PeerConnectionMedia::ProtocolProxyQueryHandler, nsIProtocolProxyCallback)
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
 PeerConnectionMedia::PeerConnectionMedia(PeerConnectionImpl *parent)
     : mParent(parent),
       mParentHandle(parent->GetHandle()),
       mParentName(parent->GetName()),
       mAllowIceLoopback(false),
       mIceCtx(nullptr),
       mDNSResolver(new NrIceResolver()),
@@ -212,16 +217,20 @@ PeerConnectionMedia::PeerConnectionMedia
       mSTSThread(mParent->GetSTSThread()),
       mProxyResolveCompleted(false) {
 }
 
 nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_servers,
                                    const std::vector<NrIceTurnServer>& turn_servers)
 {
   nsresult rv;
+#if defined(MOZILLA_XPCOMRT_API)
+  // TODO(Bug 1126039) Standalone XPCOMRT does not currently support nsIProtocolProxyService or nsIIOService
+  mProxyResolveCompleted = true;
+#else
 
   nsCOMPtr<nsIProtocolProxyService> pps =
     do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &rv);
   if (NS_FAILED(rv)) {
     CSFLogError(logTag, "%s: Failed to get proxy service: %d", __FUNCTION__, (int)rv);
     return NS_ERROR_FAILURE;
   }
 
@@ -232,17 +241,17 @@ nsresult PeerConnectionMedia::Init(const
   rv = NS_NewURI(getter_AddRefs(fakeHttpsLocation), "https://example.com");
   if (NS_FAILED(rv)) {
     CSFLogError(logTag, "%s: Failed to set URI: %d", __FUNCTION__, (int)rv);
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsIChannel> channel;
 
-#ifdef MOZILLA_INTERNAL_API
+#if defined(MOZILLA_INTERNAL_API)
   nsCOMPtr<nsIDocument> principal = mParent->GetWindow()->GetExtantDoc();
 #else
   // For unit-tests
   nsCOMPtr<nsIScriptSecurityManager> secMan(
       do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv));
   if (NS_FAILED(rv)) {
     CSFLogError(logTag, "%s: Failed to get IOService: %d",
         __FUNCTION__, (int)rv);
@@ -251,17 +260,16 @@ nsresult PeerConnectionMedia::Init(const
   }
 
   nsCOMPtr<nsIPrincipal> principal;
   rv = secMan->GetSystemPrincipal(getter_AddRefs(principal));
   if (NS_FAILED(rv)) {
     CSFLogError(logTag, "%s: Failed to get systemPrincipal: %d", __FUNCTION__, (int)rv);
     return NS_ERROR_FAILURE;
   }
-#endif
 
   rv = NS_NewChannel(getter_AddRefs(channel),
                      fakeHttpsLocation,
                      principal,
                      nsILoadInfo::SEC_NORMAL,
                      nsIContentPolicy::TYPE_OTHER);
 
   if (NS_FAILED(rv)) {
@@ -274,16 +282,18 @@ nsresult PeerConnectionMedia::Init(const
   rv = pps->AsyncResolve(channel,
                          nsIProtocolProxyService::RESOLVE_PREFER_HTTPS_PROXY |
                          nsIProtocolProxyService::RESOLVE_ALWAYS_TUNNEL,
                          handler, getter_AddRefs(mProxyRequest));
   if (NS_FAILED(rv)) {
     CSFLogError(logTag, "%s: Failed to resolve protocol proxy: %d", __FUNCTION__, (int)rv);
     return NS_ERROR_FAILURE;
   }
+#endif // defined(MOZILLA_INTERNAL_API)
+#endif // defined(MOZILLA_XPCOMRT_API)
 
   // TODO(ekr@rtfm.com): need some way to set not offerer later
   // Looks like a bug in the NrIceCtx API.
   mIceCtx = NrIceCtx::Create("PC:" + mParentName,
                              true, // Offerer
                              true, // Trickle
                              mAllowIceLoopback);
   if(!mIceCtx) {
@@ -291,17 +301,17 @@ nsresult PeerConnectionMedia::Init(const
     return NS_ERROR_FAILURE;
   }
 
   if (NS_FAILED(rv = mIceCtx->SetStunServers(stun_servers))) {
     CSFLogError(logTag, "%s: Failed to set stun servers", __FUNCTION__);
     return rv;
   }
   // Give us a way to globally turn off TURN support
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   bool disabled = Preferences::GetBool("media.peerconnection.turn.disable", false);
 #else
   bool disabled = false;
 #endif
   if (!disabled) {
     if (NS_FAILED(rv = mIceCtx->SetTurnServers(turn_servers))) {
       CSFLogError(logTag, "%s: Failed to set turn servers", __FUNCTION__);
       return rv;
@@ -1040,17 +1050,17 @@ LocalSourceStreamInfo::TakePipelineFrom(
         mMediaStream, newTrackId);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mPipelines[newTrackId] = pipeline;
 
   return NS_OK;
 }
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 /**
  * Tells you if any local streams is isolated to a specific peer identity.
  * Obviously, we want all the streams to be isolated equally so that they can
  * all be sent or not.  We check once when we are setting a local description
  * and that determines if we flip the "privacy requested" bit on.  Once the bit
  * is on, all media originating from this peer connection is isolated.
  *
  * @returns true if any stream has a peerIdentity set on it
@@ -1134,17 +1144,17 @@ SourceStreamInfo::AnyCodecHasPluginID(ui
   for (auto it = mPipelines.begin(); it != mPipelines.end(); ++it) {
     if (it->second->Conduit()->CodecPluginID() == aPluginID) {
       return true;
     }
   }
   return false;
 }
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 nsRefPtr<mozilla::dom::VideoStreamTrack>
 SourceStreamInfo::GetVideoTrackByTrackId(const std::string& trackId)
 {
   nsTArray<nsRefPtr<mozilla::dom::VideoStreamTrack>> videoTracks;
 
   mMediaStream->GetVideoTracks(videoTracks);
 
   for (size_t i = 0; i < videoTracks.Length(); ++i) {
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
@@ -10,29 +10,31 @@
 #include <map>
 
 #include "nspr.h"
 #include "prlock.h"
 
 #include "mozilla/RefPtr.h"
 #include "mozilla/UniquePtr.h"
 #include "nsComponentManagerUtils.h"
+#if !defined(MOZILLA_XPCOMRT_API)
 #include "nsIProtocolProxyCallback.h"
+#endif
 
 #ifdef USE_FAKE_MEDIA_STREAMS
 #include "FakeMediaStreams.h"
 #else
 #include "DOMMediaStream.h"
 #include "MediaSegment.h"
 #endif
 
 #include "signaling/src/jsep/JsepSession.h"
 #include "AudioSegment.h"
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
 #include "Layers.h"
 #include "VideoUtils.h"
 #include "ImageLayers.h"
 #include "VideoSegment.h"
 #include "MediaStreamTrack.h"
 #endif
 
 class nsIPrincipal;
@@ -100,17 +102,17 @@ public:
   const std::map<std::string, RefPtr<MediaPipeline>>&
   GetPipelines() const { return mPipelines; }
   RefPtr<MediaPipeline> GetPipelineByTrackId_m(const std::string& trackId);
   const std::string& GetId() const { return mId; }
 
   void DetachTransport_s();
   void DetachMedia_m();
   bool AnyCodecHasPluginID(uint64_t aPluginID);
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   nsRefPtr<mozilla::dom::VideoStreamTrack> GetVideoTrackByTrackId(const std::string& trackId);
 #endif
 protected:
   nsRefPtr<DOMMediaStream> mMediaStream;
   PeerConnectionMedia *mParent;
   const std::string mId;
   // These get set up before we generate our local description, the pipelines
   // and conduits are set up once offer/answer completes.
@@ -129,17 +131,17 @@ public:
                         PeerConnectionMedia *aParent,
                         const std::string& aId)
      : SourceStreamInfo(aMediaStream, aParent, aId) {}
 
   nsresult TakePipelineFrom(RefPtr<LocalSourceStreamInfo>& info,
                             const std::string& oldTrackId,
                             const std::string& newTrackId);
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   void UpdateSinkIdentity_m(nsIPrincipal* aPrincipal,
                             const PeerIdentity* aSinkIdentity);
 #endif
 
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(LocalSourceStreamInfo)
 
 private:
   TemporaryRef<MediaPipeline> ForgetPipelineByTrackId_m(
@@ -154,17 +156,17 @@ class RemoteSourceStreamInfo : public So
                          const std::string& aId)
     : SourceStreamInfo(aMediaStream, aParent, aId),
       mReceiving(false)
   {
   }
 
   void SyncPipeline(RefPtr<MediaPipelineReceive> aPipeline);
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   void UpdatePrincipal_m(nsIPrincipal* aPrincipal);
 #endif
 
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteSourceStreamInfo)
 
   virtual void AddTrack(const std::string& track) override
   {
     mTrackIdMap.push_back(track);
@@ -291,17 +293,17 @@ class PeerConnectionMedia : public sigsl
   nsresult AddRemoteStream(nsRefPtr<RemoteSourceStreamInfo> aInfo);
 
   nsresult ReplaceTrack(const std::string& oldStreamId,
                         const std::string& oldTrackId,
                         DOMMediaStream* aNewStream,
                         const std::string& newStreamId,
                         const std::string& aNewTrack);
 
-#ifdef MOZILLA_INTERNAL_API
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
   // In cases where the peer isn't yet identified, we disable the pipeline (not
   // the stream, that would potentially affect others), so that it sends
   // black/silence.  Once the peer is identified, re-enable those streams.
   void UpdateSinkIdentity_m(nsIPrincipal* aPrincipal,
                             const PeerIdentity* aSinkIdentity);
   // this determines if any stream is peerIdentity constrained
   bool AnyLocalStreamHasPeerIdentity() const;
   // When we finally learn who is on the other end, we need to change the ownership
@@ -386,31 +388,33 @@ class PeerConnectionMedia : public sigsl
       SignalIceConnectionStateChange;
   // This passes a candidate:... attribute  and level
   sigslot::signal2<const std::string&, uint16_t> SignalCandidate;
   // This passes address, port, level of the default candidate.
   sigslot::signal3<const std::string&, uint16_t, uint16_t>
       SignalEndOfLocalCandidates;
 
  private:
+#if !defined(MOZILLA_XPCOMRT_API)
   class ProtocolProxyQueryHandler : public nsIProtocolProxyCallback {
    public:
     explicit ProtocolProxyQueryHandler(PeerConnectionMedia *pcm) :
       pcm_(pcm) {}
 
     NS_IMETHODIMP OnProxyAvailable(nsICancelable *request,
                                    nsIChannel *aChannel,
                                    nsIProxyInfo *proxyinfo,
                                    nsresult result) override;
     NS_DECL_ISUPPORTS
 
    private:
       RefPtr<PeerConnectionMedia> pcm_;
       virtual ~ProtocolProxyQueryHandler() {}
   };
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
   // Shutdown media transport. Must be called on STS thread.
   void ShutdownMediaTransport_s();
 
   // Final destruction of the media stream. Must be called on the main
   // thread.
   void SelfDestruct_m();
 
--- a/media/webrtc/signaling/test/FakeMediaStreams.h
+++ b/media/webrtc/signaling/test/FakeMediaStreams.h
@@ -28,16 +28,25 @@
 
 class nsIDOMWindow;
 
 namespace mozilla {
    class MediaStreamGraph;
    class MediaSegment;
 };
 
+class Fake_VideoSink {
+public:
+  Fake_VideoSink() {}
+  virtual void SegmentReady(mozilla::MediaSegment* aSegment) = 0;
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Fake_VideoSink)
+protected:
+  virtual ~Fake_VideoSink() {}
+};
+
 class Fake_SourceMediaStream;
 
 class Fake_MediaStreamListener
 {
 protected:
   virtual ~Fake_MediaStreamListener() {}
 
 public:
@@ -77,16 +86,26 @@ class Fake_MediaStream {
     mListeners.insert(aListener);
   }
 
   void RemoveListener(Fake_MediaStreamListener *aListener) {
     mozilla::MutexAutoLock lock(mMutex);
     mListeners.erase(aListener);
   }
 
+  void NotifyPull(mozilla::MediaStreamGraph* graph,
+                  mozilla::StreamTime aDesiredTime) {
+
+    mozilla::MutexAutoLock lock(mMutex);
+    std::set<Fake_MediaStreamListener *>::iterator it;
+    for (it = mListeners.begin(); it != mListeners.end(); ++it) {
+      (*it)->NotifyPull(graph, aDesiredTime);
+    }
+  }
+
   virtual Fake_SourceMediaStream *AsSourceStream() { return nullptr; }
 
   virtual nsresult Start() { return NS_OK; }
   virtual nsresult Stop() { return NS_OK; }
   virtual void StopStream() {}
 
   virtual void Periodic() {}
 
@@ -129,16 +148,21 @@ class Fake_SourceMediaStream : public Fa
                              mDesiredTime(0),
                              mPullEnabled(false),
                              mStop(false),
                              mPeriodic(new Fake_MediaPeriodic(this)) {}
 
   enum {
     ADDTRACK_QUEUED    = 0x01 // Queue track add until FinishAddTracks()
   };
+
+  void AddVideoSink(const nsRefPtr<Fake_VideoSink>& aSink) {
+    mSink  = aSink;
+  }
+
   void AddTrack(mozilla::TrackID aID, mozilla::StreamTime aStart,
                 mozilla::MediaSegment* aSegment, uint32_t aFlags = 0) {
     delete aSegment;
   }
   void AddAudioTrack(mozilla::TrackID aID, mozilla::TrackRate aRate, mozilla::StreamTime aStart,
                      mozilla::AudioSegment* aSegment, uint32_t aFlags = 0) {
     delete aSegment;
   }
@@ -177,16 +201,19 @@ class Fake_SourceMediaStream : public Fa
       if(nonZeroSample) {
           //we increment segments count if
           //atleast one non-zero samples was found.
           ++mSegmentsAdded;
       }
     } else {
       //in the case of video segment appended, we just increase the
       //segment count.
+      if (mSink.get()) {
+        mSink->SegmentReady(aSegment);
+      }
       ++mSegmentsAdded;
     }
     return true;
   }
 
   void AdvanceKnownTracksTime(mozilla::StreamTime aKnownTime) {}
 
   void SetPullEnabled(bool aEnabled) {
@@ -212,16 +239,17 @@ class Fake_SourceMediaStream : public Fa
   }
 
  protected:
   int mSegmentsAdded;
   uint64_t mDesiredTime;
   bool mPullEnabled;
   bool mStop;
   nsRefPtr<Fake_MediaPeriodic> mPeriodic;
+  nsRefPtr<Fake_VideoSink> mSink;
   nsCOMPtr<nsITimer> mTimer;
 };
 
 class Fake_DOMMediaStream;
 
 class Fake_MediaStreamTrack
 {
 public:
@@ -244,16 +272,24 @@ public:
   const Fake_MediaStreamTrack* AsVideoStreamTrack() const
   {
     return mIsVideo? this : nullptr;
   }
   const Fake_MediaStreamTrack* AsAudioStreamTrack() const
   {
     return mIsVideo? nullptr : this;
   }
+  const uint32_t typeSize () const
+  {
+    return sizeof(Fake_MediaStreamTrack);
+  }
+  const char* typeName () const
+  {
+    return "Fake_MediaStreamTrack";
+  }
 private:
   ~Fake_MediaStreamTrack() {}
 
   const bool mIsVideo;
   Fake_DOMMediaStream* mStream;
   std::string mID;
 };
 
--- a/media/webrtc/signaling/test/FakePCObserver.h
+++ b/media/webrtc/signaling/test/FakePCObserver.h
@@ -50,16 +50,23 @@ public:
   AFakePCObserver(mozilla::PeerConnectionImpl *peerConnection,
                   const std::string &aName) :
     state(stateNoResponse), addIceSuccessCount(0),
     onAddStreamCalled(false),
     name(aName),
     pc(peerConnection) {
   }
 
+  AFakePCObserver() :
+    state(stateNoResponse), addIceSuccessCount(0),
+    onAddStreamCalled(false),
+    name(""),
+    pc(nullptr) {
+  }
+
   virtual ~AFakePCObserver() {}
 
   std::vector<mozilla::DOMMediaStream *> GetStreams() { return streams; }
 
   ResponseState state;
   std::string lastString;
   mozilla::PeerConnectionImpl::Error lastStatusCode;
   mozilla::dom::PCObserverStateType lastStateType;
new file mode 100644
--- /dev/null
+++ b/media/webrtc/signaling/test/common.build
@@ -0,0 +1,143 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+if CONFIG['OS_TARGET'] in ('Darwin', 'Android'):
+    DEFINES['GTEST_USE_OWN_TR1_TUPLE'] = 1
+
+for var in ('MOZILLA_EXTERNAL_LINKAGE', 'USE_FAKE_MEDIA_STREAMS', 'USE_FAKE_PCOBSERVER',
+            'NR_SOCKET_IS_VOID_PTR', 'HAVE_STRDUP'):
+    DEFINES[var] = True
+
+GENERATED_INCLUDES += [
+  '/dom/bindings',
+]
+LOCAL_INCLUDES += [
+    '/dom/media/',
+    '/ipc/chromium/src',
+    '/media/mtransport',
+    '/media/mtransport/test',
+    '/media/mtransport/third_party/nICEr/src/ice',
+    '/media/mtransport/third_party/nICEr/src/net',
+    '/media/mtransport/third_party/nICEr/src/stun',
+    '/media/mtransport/third_party/nrappkit/src/event',
+    '/media/mtransport/third_party/nrappkit/src/log',
+    '/media/mtransport/third_party/nrappkit/src/plugin',
+    '/media/mtransport/third_party/nrappkit/src/registry',
+    '/media/mtransport/third_party/nrappkit/src/share',
+    '/media/mtransport/third_party/nrappkit/src/stats',
+    '/media/mtransport/third_party/nrappkit/src/util/libekr',
+    '/media/webrtc',
+    '/media/webrtc/signaling/src/common/browser_logging',
+    '/media/webrtc/signaling/src/common/time_profiling',
+    '/media/webrtc/signaling/src/media',
+    '/media/webrtc/signaling/src/media-conduit',
+    '/media/webrtc/signaling/src/mediapipeline',
+    '/media/webrtc/signaling/src/peerconnection',
+    '/media/webrtc/signaling/src/sdp/sipcc',
+    '/media/webrtc/trunk',
+    '/media/webrtc/trunk/testing/gtest/include',
+    '/xpcom/base',
+]
+
+if CONFIG['OS_TARGET'] == 'Android':
+    LOCAL_INCLUDES += [
+        '/media/mtransport/third_party/nrappkit/src/port/android/include',
+    ]
+
+if CONFIG['OS_TARGET'] == 'Linux':
+    LOCAL_INCLUDES += [
+        '/media/mtransport/third_party/nrappkit/src/port/linux/include',
+    ]
+
+if CONFIG['OS_TARGET'] == 'Darwin':
+    LOCAL_INCLUDES += [
+        '/media/mtransport/third_party/nrappkit/src/port/darwin/include',
+    ]
+    OS_LIBS += [
+        '-framework AudioToolbox',
+        '-framework AudioUnit',
+        '-framework Carbon',
+        '-framework CoreAudio',
+        '-framework OpenGL',
+        '-framework QTKit',
+        '-framework QuartzCore',
+        '-framework Security',
+        '-framework SystemConfiguration',
+        '-framework IOKit',
+        '-F%s' % CONFIG['MACOS_PRIVATE_FRAMEWORKS_DIR'],
+        '-framework CoreUI',
+    ]
+
+if CONFIG['OS_TARGET'] in ('DragonFly', 'FreeBSD', 'NetBSD', 'OpenBSD'):
+    LOCAL_INCLUDES += [
+        '/media/mtransport/third_party/nrappkit/src/port/darwin/include',
+        '/media/mtransport/third_party/nrappkit/src/port/generic/include',
+    ]
+
+USE_LIBS += [
+    '/media/webrtc/trunk/testing/gtest_gtest/gtest',
+    'gkmedias',
+    'nksrtp_s',
+    'nss',
+    'webrtc',
+    'yuv',
+    'zlib',
+]
+
+if CONFIG['BUILD_ARM_NEON']:
+    USE_LIBS += [
+        'yuv_neon',
+    ]
+
+if CONFIG['JS_SHARED_LIBRARY']:
+    USE_LIBS += [
+        'js',
+    ]
+
+USE_LIBS += ['mozglue']
+
+OS_LIBS += CONFIG['MOZ_WEBRTC_X11_LIBS']
+OS_LIBS += CONFIG['REALTIME_LIBS']
+
+if CONFIG['MOZ_ALSA']:
+    OS_LIBS += CONFIG['MOZ_ALSA_LIBS']
+
+if CONFIG['MOZ_NATIVE_JPEG']:
+    OS_LIBS += CONFIG['MOZ_JPEG_LIBS']
+
+if CONFIG['MOZ_NATIVE_LIBVPX']:
+    OS_LIBS += CONFIG['MOZ_LIBVPX_LIBS']
+
+if not CONFIG['MOZ_TREE_PIXMAN']:
+    OS_LIBS += CONFIG['MOZ_PIXMAN_LIBS']
+
+if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk2':
+    OS_LIBS += CONFIG['XLIBS']
+    OS_LIBS += CONFIG['MOZ_GTK2_LIBS']
+    OS_LIBS += [
+        'gmodule-2.0',
+        'gthread-2.0',
+    ]
+
+if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk3':
+    OS_LIBS += CONFIG['MOZ_GTK3_LIBS']
+    USE_LIBS += [
+        'freetype',
+    ]
+
+if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
+    OS_LIBS += CONFIG['XLIBS']
+    OS_LIBS += CONFIG['TK_LIBS']
+    OS_LIBS += CONFIG['MOZ_PANGO_LIBS']
+
+if CONFIG['OS_TARGET'] in ('Linux', 'DragonFly', 'FreeBSD', 'NetBSD',
+        'OpenBSD'):
+    OS_LIBS += CONFIG['MOZ_CAIRO_OSLIBS']
+
+if CONFIG['OS_TARGET'] == 'Darwin':
+    OS_LIBS += CONFIG['TK_LIBS']
+
+FAIL_ON_WARNINGS = True
--- a/media/webrtc/signaling/test/jsep_session_unittest.cpp
+++ b/media/webrtc/signaling/test/jsep_session_unittest.cpp
@@ -23,17 +23,17 @@
 #include "signaling/src/sdp/SdpMediaSection.h"
 #include "signaling/src/sdp/SipccSdpParser.h"
 #include "signaling/src/jsep/JsepCodecDescription.h"
 #include "signaling/src/jsep/JsepTrack.h"
 #include "signaling/src/jsep/JsepSession.h"
 #include "signaling/src/jsep/JsepSessionImpl.h"
 #include "signaling/src/jsep/JsepTrack.h"
 
-#include "TestHarness.h"
+#include "mtransport_test_utils.h"
 
 namespace mozilla {
 static const char* kCandidates[] = {
   "0 1 UDP 9999 192.168.0.1 2000 typ host",
   "0 1 UDP 9999 192.168.0.1 2001 typ host",
   "0 1 UDP 9999 192.168.0.2 2002 typ srflx raddr 10.252.34.97 rport 53594",
   // Mix up order
   "0 1 UDP 9999 192.168.1.2 2012 typ srflx raddr 10.252.34.97 rport 53594",
--- a/media/webrtc/signaling/test/moz.build
+++ b/media/webrtc/signaling/test/moz.build
@@ -4,150 +4,20 @@
 # 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/.
 
 if CONFIG['OS_TARGET'] != 'WINNT' and CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
     GeckoCppUnitTests([
         'jsep_session_unittest',
         'mediaconduit_unittests',
         'mediapipeline_unittest',
-       'sdp_unittests',
-       'signaling_unittests',
+        'sdp_unittests',
+        'signaling_unittests',
     ])
 
 include('/ipc/chromium/chromium-config.mozbuild')
-
-if CONFIG['OS_TARGET'] in ('Darwin', 'Android'):
-    DEFINES['GTEST_USE_OWN_TR1_TUPLE'] = 1
-
-for var in ('USE_FAKE_MEDIA_STREAMS', 'USE_FAKE_PCOBSERVER',
-            'NR_SOCKET_IS_VOID_PTR', 'HAVE_STRDUP'):
-    DEFINES[var] = True
-
-GENERATED_INCLUDES += [
-  '/dom/bindings',
-]
-LOCAL_INCLUDES += [
-    '/ipc/chromium/src',
-    '/media/mtransport',
-    '/media/mtransport/test',
-    '/media/mtransport/third_party/nICEr/src/ice',
-    '/media/mtransport/third_party/nICEr/src/net',
-    '/media/mtransport/third_party/nICEr/src/stun',
-    '/media/mtransport/third_party/nrappkit/src/event',
-    '/media/mtransport/third_party/nrappkit/src/log',
-    '/media/mtransport/third_party/nrappkit/src/plugin',
-    '/media/mtransport/third_party/nrappkit/src/registry',
-    '/media/mtransport/third_party/nrappkit/src/share',
-    '/media/mtransport/third_party/nrappkit/src/stats',
-    '/media/mtransport/third_party/nrappkit/src/util/libekr',
-    '/media/webrtc',
-    '/media/webrtc/signaling/src/common/browser_logging',
-    '/media/webrtc/signaling/src/common/time_profiling',
-    '/media/webrtc/signaling/src/media',
-    '/media/webrtc/signaling/src/media-conduit',
-    '/media/webrtc/signaling/src/mediapipeline',
-    '/media/webrtc/signaling/src/peerconnection',
-    '/media/webrtc/signaling/src/sdp/sipcc',
-    '/media/webrtc/trunk',
-    '/media/webrtc/trunk/testing/gtest/include',
-    '/xpcom/base',
-]
-
-if CONFIG['OS_TARGET'] == 'Android':
-    LOCAL_INCLUDES += [
-        '/media/mtransport/third_party/nrappkit/src/port/android/include',
-    ]
-
-if CONFIG['OS_TARGET'] == 'Linux':
-    LOCAL_INCLUDES += [
-        '/media/mtransport/third_party/nrappkit/src/port/linux/include',
-    ]
-
-if CONFIG['OS_TARGET'] == 'Darwin':
-    LOCAL_INCLUDES += [
-        '/media/mtransport/third_party/nrappkit/src/port/darwin/include',
-    ]
-    OS_LIBS += [
-        '-framework AudioToolbox',
-        '-framework AudioUnit',
-        '-framework Carbon',
-        '-framework CoreAudio',
-        '-framework OpenGL',
-        '-framework QTKit',
-        '-framework QuartzCore',
-        '-framework Security',
-        '-framework SystemConfiguration',
-        '-framework IOKit',
-        '-F%s' % CONFIG['MACOS_PRIVATE_FRAMEWORKS_DIR'],
-        '-framework CoreUI',
-    ]
-
-if CONFIG['OS_TARGET'] in ('DragonFly', 'FreeBSD', 'NetBSD', 'OpenBSD'):
-    LOCAL_INCLUDES += [
-        '/media/mtransport/third_party/nrappkit/src/port/darwin/include',
-        '/media/mtransport/third_party/nrappkit/src/port/generic/include',
-    ]
+include('common.build')
 
 USE_LIBS += [
     '/media/webrtc/signalingtest/signaling_ecc/ecc',
-    '/media/webrtc/trunk/testing/gtest_gtest/gtest',
-    'gkmedias',
     'mtransport_s',
-    'nksrtp_s',
-    'nss',
-    'webrtc',
-    'yuv',
-    'zlib',
 ]
 
-if CONFIG['BUILD_ARM_NEON']:
-    USE_LIBS += [
-        'yuv_neon',
-    ]
-
-if CONFIG['JS_SHARED_LIBRARY']:
-    USE_LIBS += [
-        'js',
-    ]
-
-OS_LIBS += CONFIG['MOZ_WEBRTC_X11_LIBS']
-OS_LIBS += CONFIG['REALTIME_LIBS']
-
-if CONFIG['MOZ_ALSA']:
-    OS_LIBS += CONFIG['MOZ_ALSA_LIBS']
-
-if CONFIG['MOZ_NATIVE_JPEG']:
-    OS_LIBS += CONFIG['MOZ_JPEG_LIBS']
-
-if CONFIG['MOZ_NATIVE_LIBVPX']:
-    OS_LIBS += CONFIG['MOZ_LIBVPX_LIBS']
-
-if not CONFIG['MOZ_TREE_PIXMAN']:
-    OS_LIBS += CONFIG['MOZ_PIXMAN_LIBS']
-
-if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk2':
-    OS_LIBS += CONFIG['XLIBS']
-    OS_LIBS += CONFIG['MOZ_GTK2_LIBS']
-    OS_LIBS += [
-        'gmodule-2.0',
-        'gthread-2.0',
-    ]
-
-if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk3':
-    OS_LIBS += CONFIG['MOZ_GTK3_LIBS']
-    USE_LIBS += [
-        'freetype',
-    ]
-
-if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
-    OS_LIBS += CONFIG['XLIBS']
-    OS_LIBS += CONFIG['TK_LIBS']
-    OS_LIBS += CONFIG['MOZ_PANGO_LIBS']
-
-if CONFIG['OS_TARGET'] in ('Linux', 'DragonFly', 'FreeBSD', 'NetBSD',
-        'OpenBSD'):
-    OS_LIBS += CONFIG['MOZ_CAIRO_OSLIBS']
-
-if CONFIG['OS_TARGET'] == 'Darwin':
-    OS_LIBS += CONFIG['TK_LIBS']
-
-FAIL_ON_WARNINGS = True
--- a/media/webrtc/signaling/test/signaling_unittests.cpp
+++ b/media/webrtc/signaling/test/signaling_unittests.cpp
@@ -26,18 +26,16 @@
 #include "PeerConnectionCtx.h"
 #include "PeerConnectionMedia.h"
 #include "MediaPipeline.h"
 #include "runnable_utils.h"
 #include "nsServiceManagerUtils.h"
 #include "mozilla/Services.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
-#include "nsNetUtil.h"
-#include "nsIIOService.h"
 #include "nsIDNSService.h"
 #include "nsWeakReference.h"
 #include "nricectx.h"
 #include "rlogringbuffer.h"
 #include "mozilla/SyncRunnable.h"
 #include "logging.h"
 #include "stunserver.h"
 #include "stunserver.cpp"
@@ -2107,16 +2105,19 @@ public:
  protected:
   bool init_;
   ScopedDeletePtr<SignalingAgent> a1_;  // Canonically "caller"
   ScopedDeletePtr<SignalingAgent> a2_;  // Canonically "callee"
   std::string stun_addr_;
   uint16_t stun_port_;
 };
 
+#if !defined(MOZILLA_XPCOMRT_API)
+// FIXME XPCOMRT doesn't support nsPrefService
+// See Bug 1129188 - Create standalone libpref for use in standalone WebRTC
 static void SetIntPrefOnMainThread(nsCOMPtr<nsIPrefBranch> prefs,
   const char *pref_name,
   int new_value) {
   MOZ_ASSERT(NS_IsMainThread());
   prefs->SetIntPref(pref_name, new_value);
 }
 
 static void SetMaxFsFr(nsCOMPtr<nsIPrefBranch> prefs,
@@ -2156,16 +2157,17 @@ class FsFrPrefClearer {
     static void ClearUserPrefOnMainThread(nsCOMPtr<nsIPrefBranch> prefs,
       const char *pref_name) {
       MOZ_ASSERT(NS_IsMainThread());
       prefs->ClearUserPref(pref_name);
     }
   private:
     nsCOMPtr<nsIPrefBranch> mPrefs;
 };
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
 TEST_P(SignalingTest, JustInit)
 {
 }
 
 TEST_P(SignalingTest, CreateSetOffer)
 {
   OfferOptions options;
@@ -3903,16 +3905,20 @@ TEST_P(SignalingTest, hugeSdp)
   a1_->CreateOffer(options, OFFER_AV);
   a1_->SetLocal(TestObserver::OFFER, a1_->offer(), true);
 
   a2_->SetRemote(TestObserver::OFFER, offer, true);
   ASSERT_GE(a2_->getRemoteDescription().length(), 4096U);
   a2_->CreateAnswer(OFFER_AV);
 }
 
+#if !defined(MOZILLA_XPCOMRT_API)
+// FIXME XPCOMRT doesn't support nsPrefService
+// See Bug 1129188 - Create standalone libpref for use in standalone WebRTC
+
 // Test max_fs and max_fr prefs have proper impact on SDP offer
 TEST_P(SignalingTest, MaxFsFrInOffer)
 {
   EnsureInit();
 
   OfferOptions options;
 
   nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
@@ -4037,16 +4043,17 @@ TEST_P(SignalingTest, MaxFsFrCallerCodec
   ASSERT_TRUE(conduit);
   ASSERT_EQ(conduit->type(), mozilla::MediaSessionConduit::VIDEO);
   mozilla::VideoSessionConduit *video_conduit =
     static_cast<mozilla::VideoSessionConduit*>(conduit);
 
   ASSERT_EQ(video_conduit->SendingMaxFs(), (unsigned short) 600);
   ASSERT_EQ(video_conduit->SendingMaxFr(), (unsigned short) 60);
 }
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
 // Validate offer with multiple video codecs
 TEST_P(SignalingTest, ValidateMultipleVideoCodecsInOffer)
 {
   EnsureInit();
   OfferOptions options;
 
   a1_->CreateOffer(options, OFFER_AV);
new file mode 100644
--- /dev/null
+++ b/media/webrtc/signaling/test/standalone/jsep_session_unittest_standalone.cpp
@@ -0,0 +1,7 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 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/. */
+
+#include "../jsep_session_unittest.cpp"
new file mode 100644
--- /dev/null
+++ b/media/webrtc/signaling/test/standalone/mediaconduit_unittests_standalone.cpp
@@ -0,0 +1,5 @@
+/* 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 "../mediaconduit_unittests.cpp"
new file mode 100644
--- /dev/null
+++ b/media/webrtc/signaling/test/standalone/mediapipeline_unittest_standalone.cpp
@@ -0,0 +1,7 @@
+/* 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/. */
+
+// Original author: ekr@rtfm.com
+
+#include "../mediapipeline_unittest.cpp"
new file mode 100644
--- /dev/null
+++ b/media/webrtc/signaling/test/standalone/moz.build
@@ -0,0 +1,58 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+# Standalone WebRTC does not link on Android.
+# See Bug 1127510 - Standalone WebRTC unit tests fail to link on Android
+if CONFIG['OS_TARGET'] != 'WINNT' and CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk' and CONFIG['OS_TARGET'] != 'Android':
+    CppUnitTests([
+        'jsep_session_unittest_standalone',
+#       mediaconduit_unittests disabled for standalone build until GMP support added.
+#       See Bug 1121677 - Enable GMP for WebRTC standalone.
+#        'mediaconduit_unittests_standalone',
+        'mediapipeline_unittest_standalone',
+        'sdp_unittests_standalone',
+        'signaling_unittests_standalone',
+    ])
+
+include('/ipc/chromium/chromium-config.mozbuild')
+include('../common.build')
+
+for var in ('MOZILLA_INTERNAL_API', 'MOZILLA_XPCOMRT_API'):
+    DEFINES[var] = True
+
+if CONFIG['OS_TARGET'] == 'Linux':
+    USE_LIBS += [
+        'static:/nsprpub/lib/libc/src/plc4',
+    ]
+    OS_LIBS += [
+        '-lrt',
+    ]
+
+LOCAL_INCLUDES += [
+    '..',
+    '/xpcom/libxpcomrt',
+]
+
+USE_LIBS += [
+    '/media/webrtc/signalingstandalone/signaling_ecc/ecc',
+    'fallible',
+    'media_standalone',
+    'mfbt',
+    'mozglue',
+    'mtransport_standalone',
+    'necko_standalone',
+    'nspr',
+    'nss',
+    'unicharutil_standalone',
+    'xpcomrt',
+]
+
+if CONFIG['OS_TARGET'] == 'Android':
+    USE_LIBS += [
+        'freetype',
+    ]
+
+USE_LIBS += ['mozglue']
new file mode 100644
--- /dev/null
+++ b/media/webrtc/signaling/test/standalone/sdp_unittests_standalone.cpp
@@ -0,0 +1,7 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 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/. */
+
+#include "../sdp_unittests.cpp"
new file mode 100644
--- /dev/null
+++ b/media/webrtc/signaling/test/standalone/signaling_unittests_standalone.cpp
@@ -0,0 +1,5 @@
+/* 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 "../signaling_unittests.cpp"
--- a/toolkit/toolkit.mozbuild
+++ b/toolkit/toolkit.mozbuild
@@ -56,19 +56,17 @@ if CONFIG['MOZ_PERMISSIONS']:
 
 DIRS += [
     '/rdf',
 ]
 
 if CONFIG['MOZ_WEBRTC']:
     DIRS += [
         '/media/webrtc',
-        '/media/mtransport/third_party',
-        '/media/mtransport/build',
-        '/media/mtransport/standalone',
+        '/media/mtransport',
     ]
 
 if CONFIG['MOZ_OMX_PLUGIN']:
     DIRS += [
         '/media/omx-plugin/lib/ics/libutils',
         '/media/omx-plugin/lib/ics/libstagefright',
         '/media/omx-plugin/lib/ics/libvideoeditorplayer',
         '/media/omx-plugin/lib/gb/libutils',
@@ -187,10 +185,11 @@ if CONFIG['ENABLE_TESTS']:
         '/testing/modules',
         '/testing/runtimes',
         '/testing/web-platform',
     ]
 
     if CONFIG['MOZ_WEBRTC'] and CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
             DIRS += [
                 '/media/webrtc/signaling/test',
+                '/media/webrtc/signaling/test/standalone',
                 '/media/mtransport/test',
             ]
--- a/xpcom/components/nsComponentManager.cpp
+++ b/xpcom/components/nsComponentManager.cpp
@@ -392,16 +392,17 @@ nsComponentManagerImpl::Init()
   }
 
   nsCategoryManager::GetSingleton()->SuppressNotifications(true);
 #endif
 
 #if defined(MOZILLA_XPCOMRT_API)
   RegisterModule(&kXPCOMRTModule, nullptr);
   RegisterModule(&kNeckoStandaloneModule, nullptr);
+  RegisterModule(&kStunUDPSocketFilterHandlerModule, nullptr);
 #else
   RegisterModule(&kXPCOMModule, nullptr);
 #endif // defined(MOZILLA_XPCOMRT_API)
 
   for (uint32_t i = 0; i < sStaticModules->Length(); ++i) {
     RegisterModule((*sStaticModules)[i], nullptr);
   }
 
--- a/xpcom/components/nsComponentManager.h
+++ b/xpcom/components/nsComponentManager.h
@@ -65,16 +65,17 @@ extern const char staticComponentType[];
 #ifdef DEBUG
 #define XPCOM_CHECK_PENDING_CIDS
 #endif
 ////////////////////////////////////////////////////////////////////////////////
 
 #if defined(MOZILLA_XPCOMRT_API)
 extern const mozilla::Module kXPCOMRTModule;
 extern const mozilla::Module kNeckoStandaloneModule;
+extern const mozilla::Module kStunUDPSocketFilterHandlerModule;
 #else
 extern const mozilla::Module kXPCOMModule;
 #endif
 
 /**
  * This is a wrapper around mozilla::Mutex which provides runtime
  * checking for a deadlock where the same thread tries to lock a mutex while
  * it is already locked. This checking is present in both debug and release