Merge m-c to inbound. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Fri, 21 Oct 2016 11:08:45 -0400
changeset 364040 806054dd12bdcbdee81dbd75f1583156cef9b649
parent 364039 f6811b39af13400c4d987bf0fd3669e24fc56c5e (current diff)
parent 363926 28681d252003e3110105473754da2f4097cb83a6 (diff)
child 364063 5639a9f476d08f300c079117e61697f5026b6367
child 364105 37cff35583fe1405d6466280aa70681df8aff3a4
push id1369
push userjlorenzo@mozilla.com
push dateMon, 27 Feb 2017 14:59:41 +0000
treeherdermozilla-release@d75a1dba431f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone52.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
Merge m-c to inbound. a=merge
dom/html/HTMLMediaElement.cpp
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
dom/media/MediaStreamTrack.cpp
dom/media/MediaStreamTrack.h
dom/media/tests/mochitest/mediaStreamPlayback.js
dom/media/tests/mochitest/mochitest.ini
dom/media/tests/mochitest/test_getUserMedia_addTrackRemoveTrack.html
dom/media/tests/mochitest/test_getUserMedia_addtrack_removetrack_events.html
dom/media/tests/mochitest/test_getUserMedia_basicScreenshare.html
dom/media/tests/mochitest/test_getUserMedia_basicTabshare.html
dom/media/tests/mochitest/test_getUserMedia_basicVideo_playAfterLoadedmetadata.html
dom/media/tests/mochitest/test_getUserMedia_bug1223696.html
dom/media/tests/mochitest/test_getUserMedia_constraints.html
dom/media/tests/mochitest/test_getUserMedia_getTrackById.html
dom/media/tests/mochitest/test_getUserMedia_loadedmetadata.html
dom/media/tests/mochitest/test_getUserMedia_mediaElementCapture_audio.html
dom/media/tests/mochitest/test_getUserMedia_mediaElementCapture_video.html
dom/media/tests/mochitest/test_getUserMedia_mediaStreamClone.html
dom/media/tests/mochitest/test_getUserMedia_mediaStreamTrackClone.html
dom/media/tests/mochitest/test_getUserMedia_peerIdentity.html
dom/media/tests/mochitest/test_getUserMedia_playAudioTwice.html
dom/media/tests/mochitest/test_getUserMedia_playVideoAudioTwice.html
dom/media/tests/mochitest/test_getUserMedia_playVideoTwice.html
dom/media/tests/mochitest/test_getUserMedia_spinEventLoop.html
dom/media/tests/mochitest/test_getUserMedia_trackCloneCleanup.html
dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
dom/media/webrtc/MediaEngineTabVideoSource.cpp
dom/media/webrtc/MediaEngineTabVideoSource.h
dom/mobilemessage/Assertions.cpp
dom/mobilemessage/Constants.cpp
dom/mobilemessage/Constants.h
dom/mobilemessage/DOMMobileMessageError.cpp
dom/mobilemessage/DOMMobileMessageError.h
dom/mobilemessage/DeletedMessageInfo.cpp
dom/mobilemessage/DeletedMessageInfo.h
dom/mobilemessage/MmsMessage.cpp
dom/mobilemessage/MmsMessage.h
dom/mobilemessage/MmsMessageInternal.cpp
dom/mobilemessage/MmsMessageInternal.h
dom/mobilemessage/MobileMessageCallback.cpp
dom/mobilemessage/MobileMessageCallback.h
dom/mobilemessage/MobileMessageCursorCallback.cpp
dom/mobilemessage/MobileMessageCursorCallback.h
dom/mobilemessage/MobileMessageManager.cpp
dom/mobilemessage/MobileMessageManager.h
dom/mobilemessage/MobileMessageService.cpp
dom/mobilemessage/MobileMessageService.h
dom/mobilemessage/MobileMessageThread.cpp
dom/mobilemessage/MobileMessageThread.h
dom/mobilemessage/MobileMessageThreadInternal.cpp
dom/mobilemessage/MobileMessageThreadInternal.h
dom/mobilemessage/SmsMessage.cpp
dom/mobilemessage/SmsMessage.h
dom/mobilemessage/SmsMessageInternal.cpp
dom/mobilemessage/SmsMessageInternal.h
dom/mobilemessage/Types.h
dom/mobilemessage/android/MobileMessageDatabaseService.cpp
dom/mobilemessage/android/MobileMessageDatabaseService.h
dom/mobilemessage/android/SmsManager.cpp
dom/mobilemessage/android/SmsManager.h
dom/mobilemessage/android/SmsService.cpp
dom/mobilemessage/android/SmsService.h
dom/mobilemessage/gonk/MmsPduHelper.jsm
dom/mobilemessage/gonk/MmsService.js
dom/mobilemessage/gonk/MmsService.manifest
dom/mobilemessage/gonk/MobileMessageDB.jsm
dom/mobilemessage/gonk/MobileMessageDatabaseService.js
dom/mobilemessage/gonk/MobileMessageDatabaseService.manifest
dom/mobilemessage/gonk/SmsSegmentHelper.jsm
dom/mobilemessage/gonk/SmsService.js
dom/mobilemessage/gonk/SmsService.manifest
dom/mobilemessage/gonk/WspPduHelper.jsm
dom/mobilemessage/gonk/mms_consts.js
dom/mobilemessage/gonk/wap_consts.js
dom/mobilemessage/interfaces/moz.build
dom/mobilemessage/interfaces/nsIDeletedMessageInfo.idl
dom/mobilemessage/interfaces/nsIGonkMobileMessageDatabaseService.idl
dom/mobilemessage/interfaces/nsIGonkSmsService.idl
dom/mobilemessage/interfaces/nsIMmsMessage.idl
dom/mobilemessage/interfaces/nsIMmsService.idl
dom/mobilemessage/interfaces/nsIMobileMessageCallback.idl
dom/mobilemessage/interfaces/nsIMobileMessageCursorCallback.idl
dom/mobilemessage/interfaces/nsIMobileMessageDatabaseService.idl
dom/mobilemessage/interfaces/nsIMobileMessageService.idl
dom/mobilemessage/interfaces/nsIMobileMessageThread.idl
dom/mobilemessage/interfaces/nsISmsMessage.idl
dom/mobilemessage/interfaces/nsISmsMessenger.idl
dom/mobilemessage/interfaces/nsISmsService.idl
dom/mobilemessage/interfaces/nsIWapPushApplication.idl
dom/mobilemessage/ipc/PMobileMessageCursor.ipdl
dom/mobilemessage/ipc/PSms.ipdl
dom/mobilemessage/ipc/PSmsRequest.ipdl
dom/mobilemessage/ipc/SmsChild.cpp
dom/mobilemessage/ipc/SmsChild.h
dom/mobilemessage/ipc/SmsIPCService.cpp
dom/mobilemessage/ipc/SmsIPCService.h
dom/mobilemessage/ipc/SmsParent.cpp
dom/mobilemessage/ipc/SmsParent.h
dom/mobilemessage/ipc/SmsTypes.ipdlh
dom/mobilemessage/moz.build
dom/mobilemessage/tests/marionette/head.js
dom/mobilemessage/tests/marionette/manifest.ini
dom/mobilemessage/tests/marionette/mmdb_head.js
dom/mobilemessage/tests/marionette/test_between_emulators.py
dom/mobilemessage/tests/marionette/test_bug814761.js
dom/mobilemessage/tests/marionette/test_decode_spanish_fallback.js
dom/mobilemessage/tests/marionette/test_emulator_loopback.js
dom/mobilemessage/tests/marionette/test_error_of_mms_manual_retrieval.js
dom/mobilemessage/tests/marionette/test_error_of_mms_send.js
dom/mobilemessage/tests/marionette/test_error_of_sms_send.js
dom/mobilemessage/tests/marionette/test_filter_date.js
dom/mobilemessage/tests/marionette/test_filter_mixed.js
dom/mobilemessage/tests/marionette/test_filter_number.js
dom/mobilemessage/tests/marionette/test_filter_read.js
dom/mobilemessage/tests/marionette/test_filter_received.js
dom/mobilemessage/tests/marionette/test_filter_sent.js
dom/mobilemessage/tests/marionette/test_filter_unread.js
dom/mobilemessage/tests/marionette/test_getmessage.js
dom/mobilemessage/tests/marionette/test_getmessage_notfound.js
dom/mobilemessage/tests/marionette/test_getmessages.js
dom/mobilemessage/tests/marionette/test_getsegmentinfofortext.js
dom/mobilemessage/tests/marionette/test_getthreads.js
dom/mobilemessage/tests/marionette/test_incoming.js
dom/mobilemessage/tests/marionette/test_incoming_delete.js
dom/mobilemessage/tests/marionette/test_incoming_max_segments.js
dom/mobilemessage/tests/marionette/test_invalid_address.js
dom/mobilemessage/tests/marionette/test_mark_msg_read.js
dom/mobilemessage/tests/marionette/test_mark_msg_read_error.js
dom/mobilemessage/tests/marionette/test_massive_incoming_delete.js
dom/mobilemessage/tests/marionette/test_message_classes.js
dom/mobilemessage/tests/marionette/test_mmdb_foreachmatchedmmsdeliveryinfo.js
dom/mobilemessage/tests/marionette/test_mmdb_full_storage.js
dom/mobilemessage/tests/marionette/test_mmdb_new.js
dom/mobilemessage/tests/marionette/test_mmdb_ports_in_cdma_wappush.js
dom/mobilemessage/tests/marionette/test_mmdb_setmessagedeliverybyid_sms.js
dom/mobilemessage/tests/marionette/test_mmdb_upgradeSchema_22.js
dom/mobilemessage/tests/marionette/test_mmdb_upgradeSchema_current_structure.js
dom/mobilemessage/tests/marionette/test_mmsmessage_attachments.js
dom/mobilemessage/tests/marionette/test_mobilemessage_dsds_default_service_id.js
dom/mobilemessage/tests/marionette/test_mt_sms_concatenation.js
dom/mobilemessage/tests/marionette/test_ondeleted_event.js
dom/mobilemessage/tests/marionette/test_outgoing.js
dom/mobilemessage/tests/marionette/test_outgoing_delete.js
dom/mobilemessage/tests/marionette/test_outgoing_max_segments.js
dom/mobilemessage/tests/marionette/test_outgoing_unstable_voice_connection.js
dom/mobilemessage/tests/marionette/test_phone_number_normalization.js
dom/mobilemessage/tests/marionette/test_replace_short_message_type.js
dom/mobilemessage/tests/marionette/test_segment_info.js
dom/mobilemessage/tests/marionette/test_smsc_address.js
dom/mobilemessage/tests/marionette/test_strict_7bit_encoding.js
dom/mobilemessage/tests/marionette/test_thread_subject.js
dom/mobilemessage/tests/marionette/test_update_gsm_nl_on_mcc_chanages.js
dom/mobilemessage/tests/marionette/test_update_thread_record_in_delete.js
dom/mobilemessage/tests/mochitest/chrome.ini
dom/mobilemessage/tests/mochitest/test_sms_basics.html
dom/mobilemessage/tests/xpcshell/header_helpers.js
dom/mobilemessage/tests/xpcshell/test_mms_pdu_helper.js
dom/mobilemessage/tests/xpcshell/test_mms_service.js
dom/mobilemessage/tests/xpcshell/test_sms_segment_helper.js
dom/mobilemessage/tests/xpcshell/test_smsservice_createsmsmessage.js
dom/mobilemessage/tests/xpcshell/test_wsp_pdu_helper.js
dom/mobilemessage/tests/xpcshell/test_wsp_pdu_helper_header.js
dom/mobilemessage/tests/xpcshell/test_wsp_pdu_helper_numeric.js
dom/mobilemessage/tests/xpcshell/test_wsp_pdu_helper_parameter.js
dom/mobilemessage/tests/xpcshell/test_wsp_pdu_helper_text.js
dom/mobilemessage/tests/xpcshell/xpcshell.ini
dom/permission/tests/mochitest-websms.ini
dom/permission/tests/test_sms.html
dom/webidl/DOMMobileMessageError.webidl
dom/webidl/MmsMessage.webidl
dom/webidl/MobileMessageThread.webidl
dom/webidl/MozMessageDeletedEvent.webidl
dom/webidl/MozMmsEvent.webidl
dom/webidl/MozMobileMessageManager.webidl
dom/webidl/MozSmsEvent.webidl
dom/webidl/SmsMessage.webidl
gfx/vr/VRDisplayHost.cpp
gfx/vr/VRDisplayHost.h
gfx/vr/gfxVR.h
js/src/vm/NativeObject.cpp
layout/base/nsCSSFrameConstructor.cpp
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoSmsManager.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/SmsManager.java
taskcluster/ci/b2g-device/kind.yml
taskcluster/ci/build/mulet.yml
taskcluster/scripts/builder/build-emulator-x86.sh
taskcluster/scripts/builder/build-emulator.sh
taskcluster/scripts/builder/build-mulet-haz-linux.sh
taskcluster/scripts/builder/build-mulet-linux.sh
taskcluster/scripts/builder/build-simulator.sh
taskcluster/scripts/builder/gaia_props.py
taskcluster/scripts/builder/pull-gaia.sh
taskcluster/scripts/phone-builder/build-dolphin.sh
taskcluster/scripts/phone-builder/build-phone-ota.sh
taskcluster/scripts/phone-builder/build-phone.sh
taskcluster/scripts/phone-builder/post-build.sh
taskcluster/scripts/phone-builder/pre-build.sh
taskcluster/taskgraph/transforms/job/mulet.py
taskcluster/taskgraph/transforms/job/phone_builder.py
testing/docker/README.md
testing/docker/REGISTRY
testing/docker/android-gradle-build/Dockerfile
testing/docker/android-gradle-build/README.md
testing/docker/android-gradle-build/VERSION
testing/docker/android-gradle-build/bin/after.sh
testing/docker/android-gradle-build/bin/before.sh
testing/docker/android-gradle-build/bin/build.sh
testing/docker/android-gradle-build/bin/checkout-sources.sh
testing/docker/b2g-build/Dockerfile
testing/docker/b2g-build/VERSION
testing/docker/b2g-build/bin/repository-url.py
testing/docker/b2g-build/releng.repo
testing/docker/base-build/Dockerfile
testing/docker/base-build/VERSION
testing/docker/base-build/system-setup.sh
testing/docker/base-test/Dockerfile
testing/docker/base-test/VERSION
testing/docker/base-test/sources.list
testing/docker/builder/Dockerfile
testing/docker/builder/REGISTRY
testing/docker/builder/VERSION
testing/docker/builder/bin/checkout-gecko
testing/docker/builder/git.env
testing/docker/builder/mulet.env
testing/docker/centos6-build-upd/Dockerfile
testing/docker/centos6-build-upd/VERSION
testing/docker/centos6-build/Dockerfile
testing/docker/centos6-build/VERSION
testing/docker/centos6-build/hgrc
testing/docker/centos6-build/system-setup.sh
testing/docker/decision/README.md
testing/docker/decision/VERSION
testing/docker/decision/system-setup.sh
testing/docker/desktop-build/bin/build.sh
testing/docker/desktop-build/bin/checkout-script.sh
testing/docker/desktop-build/bin/checkout-sources.sh
testing/docker/desktop-build/buildprops.json
testing/docker/desktop-build/oauth.txt
testing/docker/desktop-test/apport
testing/docker/desktop-test/buildprops.json
testing/docker/desktop-test/dot-files/config/pip/pip.conf
testing/docker/desktop-test/dot-files/config/user-dirs.dirs
testing/docker/desktop-test/dot-files/config/user-dirs.locale
testing/docker/desktop-test/dot-files/pulse/default.pa
testing/docker/desktop-test/jockey-gtk.desktop
testing/docker/desktop-test/motd
testing/docker/desktop-test/release-upgrades
testing/docker/desktop-test/taskcluster-interactive-shell
testing/docker/desktop-test/tc-vcs-config.yml
testing/docker/desktop1604-test/bin/run-wizard
testing/docker/desktop1604-test/deja-dup-monitor.desktop
testing/docker/desktop1604-test/fonts.conf
testing/docker/desktop1604-test/taskcluster-interactive-shell
testing/docker/desktop1604-test/tc-vcs-config.yml
testing/docker/image_builder/Dockerfile
testing/docker/image_builder/REGISTRY
testing/docker/image_builder/VERSION
testing/docker/image_builder/bin/build_image.sh
testing/docker/lint/system-setup.sh
testing/docker/phone-builder/Dockerfile
testing/docker/phone-builder/bin/validate_task.py
testing/docker/phone-builder/hgrc
testing/docker/phone-builder/tc-vcs-config.yml
testing/docker/phone-builder/tests/invalid_base_repo.yml
testing/docker/phone-builder/tests/invalid_head_repo.yml
testing/docker/phone-builder/tests/public.yml
testing/docker/phone-builder/tests/test_validation.py
testing/docker/phone-builder/tests/valid.yml
testing/docker/recipes/centos6-build-system-setup.sh
testing/docker/recipes/common.sh
testing/docker/recipes/install-mercurial.sh
testing/docker/recipes/run-task
testing/docker/recipes/tooltool.py
testing/docker/recipes/ubuntu1204-test-system-setup.sh
testing/docker/recipes/ubuntu1604-test-system-setup.sh
testing/docker/recipes/xvfb.sh
testing/docker/rust-build/Dockerfile
testing/docker/rust-build/README.md
testing/docker/rust-build/REGISTRY
testing/docker/rust-build/VERSION
testing/docker/rust-build/build_cargo.sh
testing/docker/rust-build/build_rust.sh
testing/docker/rust-build/build_rust_mac.sh
testing/docker/rust-build/fetch_cargo.sh
testing/docker/rust-build/fetch_rust.sh
testing/docker/rust-build/package_rust.sh
testing/docker/rust-build/repack_rust.py
testing/docker/rust-build/task.json
testing/docker/rust-build/tcbuild.py
testing/docker/rust-build/upload_rust.sh
testing/docker/tester/Dockerfile
testing/docker/tester/VERSION
testing/docker/tester/bin/test.sh
testing/docker/tester/dot-config/user-dirs.dirs
testing/docker/tester/dot-config/user-dirs.locale
testing/docker/tester/dot-pulse/default.pa
testing/docker/tester/tc-vcs-config.yml
testing/docker/tester/tester.env
testing/web-platform/meta/MANIFEST.json
toolkit/components/extensions/jar.mn
xpcom/base/ErrorList.h
--- a/.eslintignore
+++ b/.eslintignore
@@ -1,11 +1,8 @@
-# Allow linting of .eslintrc.js files.
-!**/.eslintrc.js
-
 # Always ignore node_modules.
 **/node_modules/**/*.*
 
 # Exclude expected objdirs.
 obj*/**
 
 # We ignore all these directories by default, until we get them enabled.
 # If you are enabling a directory, please add directory specific exclusions
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -385,19 +385,16 @@ pref("dom.mozBrowserFramesEnabled", true
 pref("dom.ipc.processCount", 100000);
 
 pref("dom.ipc.browser_frames.oop_by_default", false);
 
 #if !defined(MOZ_MULET) && !defined(MOZ_GRAPHENE)
 pref("dom.meta-viewport.enabled", true);
 #endif
 
-// SMS/MMS
-pref("dom.sms.enabled", true);
-
 //The waiting time in network manager.
 pref("network.gonk.ms-release-mms-connection", 30000);
 
 // Shortnumber matching needed for e.g. Brazil:
 // 03187654321 can be found with 87654321
 pref("dom.phonenumber.substringmatching.BR", 8);
 pref("dom.phonenumber.substringmatching.CO", 10);
 pref("dom.phonenumber.substringmatching.VE", 7);
--- a/browser/base/content/aboutNetError.xhtml
+++ b/browser/base/content/aboutNetError.xhtml
@@ -96,17 +96,17 @@
 
       function doOverride(buttonEl) {
         var event = new CustomEvent("AboutNetErrorOverride", {bubbles:true});
         document.dispatchEvent(event);
         retryThis(buttonEl);
       }
 
       function toggleDisplay(node) {
-        toggle = {
+        const toggle = {
           "": "block",
           "none": "block",
           "block": "none"
         };
         return (node.style.display = toggle[node.style.display]);
       }
 
       function showCertificateErrorReporting() {
--- a/browser/base/content/abouthome/aboutHome.js
+++ b/browser/base/content/abouthome/aboutHome.js
@@ -1,14 +1,16 @@
 /* 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/. */
 
 "use strict";
 
+/* import-globals-from ../contentSearchUI.js */
+
 // The process of adding a new default snippet involves:
 //   * add a new entity to aboutHome.dtd
 //   * add a <span/> for it in aboutHome.xhtml
 //   * add an entry here in the proper ordering (based on spans)
 // The <a/> part of the snippet will be linked to the corresponding url.
 const DEFAULT_SNIPPETS_URLS = [
   "https://www.mozilla.org/firefox/features/?utm_source=snippet&utm_medium=snippet&utm_campaign=default+feature+snippet"
 , "https://addons.mozilla.org/firefox/?utm_source=snippet&utm_medium=snippet&utm_campaign=addons"
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -5670,17 +5670,17 @@
 
       <field name="_animateElement">
         this.mTabstrip._scrollButtonDown;
       </field>
 
       <method name="_notifyBackgroundTab">
         <parameter name="aTab"/>
         <body><![CDATA[
-          if (aTab.pinned)
+          if (aTab.pinned || aTab.hidden)
             return;
 
           var scrollRect = this.mTabstrip.scrollClientRect;
           var tab = aTab.getBoundingClientRect();
           this.mTabstrip._calcTabMargins(aTab);
 
           // DOMRect left/right properties are immutable.
           tab = {left: tab.left, right: tab.right};
--- a/browser/components/contextualidentity/test/browser/.eslintrc.js
+++ b/browser/components/contextualidentity/test/browser/.eslintrc.js
@@ -1,7 +1,11 @@
 "use strict";
 
 module.exports = {
   "extends": [
     "../../../../../testing/mochitest/browser.eslintrc.js"
-  ]
+  ],
+
+  "rules": {
+    "no-undef": 2
+  }
 };
--- a/browser/components/contextualidentity/test/browser/browser_windowName.js
+++ b/browser/components/contextualidentity/test/browser/browser_windowName.js
@@ -35,17 +35,17 @@ add_task(function* test() {
   let browser2 = gBrowser.getBrowserForTab(tab2);
   yield BrowserTestUtils.browserLoaded(browser2);
   yield ContentTask.spawn(browser2, null, function(opts) {
     content.window.name = 'tab-2';
   });
 
   // Let's try to open a window from tab1 with a name 'tab-2'.
   info("Opening a window from the first tab...");
-  yield ContentTask.spawn(browser1, { url: BASE_URI + '?new' }, function(opts) {
+  yield ContentTask.spawn(browser1, { url: BASE_URI + '?new' }, function* (opts) {
     yield (new content.window.wrappedJSObject.Promise(resolve => {
       let w = content.window.wrappedJSObject.open(opts.url, 'tab-2');
       w.onload = function() { resolve(); }
     }));
   });
 
   is(browser1.contentTitle, '?old', "Tab1 title must be 'old'");
   is(browser1.contentPrincipal.userContextId, 1, "Tab1 UCI must be 1");
--- a/browser/components/customizableui/CustomizableWidgets.jsm
+++ b/browser/components/customizableui/CustomizableWidgets.jsm
@@ -1254,18 +1254,19 @@ if (Services.prefs.getBoolPref("privacy.
 }
 
 if (AppConstants.E10S_TESTING_ONLY) {
   if (Services.appinfo.browserTabsRemoteAutostart) {
     CustomizableWidgets.push({
       id: "e10s-button",
       defaultArea: CustomizableUI.AREA_PANEL,
       onBuild: function(aDocument) {
-          node.setAttribute("label", CustomizableUI.getLocalizedProperty(this, "label"));
-          node.setAttribute("tooltiptext", CustomizableUI.getLocalizedProperty(this, "tooltiptext"));
+        let node = aDocument.createElementNS(kNSXUL, "toolbarbutton");
+        node.setAttribute("label", CustomizableUI.getLocalizedProperty(this, "label"));
+        node.setAttribute("tooltiptext", CustomizableUI.getLocalizedProperty(this, "tooltiptext"));
       },
       onCommand: function(aEvent) {
         let win = aEvent.view;
         win.OpenBrowserWindow({remote: false});
       },
     });
   }
 }
--- a/browser/components/customizableui/test/browser_988072_sidebar_events.js
+++ b/browser/components/customizableui/test/browser_988072_sidebar_events.js
@@ -132,261 +132,261 @@ function add_sidebar_task(description, s
     gTestSidebarItem.remove();
     removeWidget();
   });
 }
 
 add_sidebar_task(
   "Check that a sidebar that uses a command event listener works",
 function*() {
-  gTestSidebarItem.addEventListener("command", sawEvent);
+  gTestSidebarItem.addEventListener("command", window.sawEvent);
 }, function*() {
   checkExpectedEvents({ command: 1 });
 });
 
 add_sidebar_task(
   "Check that a sidebar that uses a click event listener works",
 function*() {
-  gTestSidebarItem.addEventListener("click", sawEvent);
+  gTestSidebarItem.addEventListener("click", window.sawEvent);
 }, function*() {
   checkExpectedEvents({ click: 1 });
 });
 
 add_sidebar_task(
   "Check that a sidebar that uses both click and command event listeners works",
 function*() {
-  gTestSidebarItem.addEventListener("command", sawEvent);
-  gTestSidebarItem.addEventListener("click", sawEvent);
+  gTestSidebarItem.addEventListener("command", window.sawEvent);
+  gTestSidebarItem.addEventListener("click", window.sawEvent);
 }, function*() {
   checkExpectedEvents({ command: 1, click: 1 });
 });
 
 add_sidebar_task(
   "Check that a sidebar that uses an oncommand attribute works",
 function*() {
-  gTestSidebarItem.setAttribute("oncommand", "sawEvent(event, true)");
+  gTestSidebarItem.setAttribute("oncommand", "window.sawEvent(event, true)");
 }, function*() {
   checkExpectedEvents({ oncommand: 1 });
 });
 
 add_sidebar_task(
   "Check that a sidebar that uses an onclick attribute works",
 function*() {
-  gTestSidebarItem.setAttribute("onclick", "sawEvent(event, true)");
+  gTestSidebarItem.setAttribute("onclick", "window.sawEvent(event, true)");
 }, function*() {
   checkExpectedEvents({ onclick: 1 });
 });
 
 add_sidebar_task(
   "Check that a sidebar that uses both onclick and oncommand attributes works",
 function*() {
-  gTestSidebarItem.setAttribute("onclick", "sawEvent(event, true)");
-  gTestSidebarItem.setAttribute("oncommand", "sawEvent(event, true)");
+  gTestSidebarItem.setAttribute("onclick", "window.sawEvent(event, true)");
+  gTestSidebarItem.setAttribute("oncommand", "window.sawEvent(event, true)");
 }, function*() {
   checkExpectedEvents({ onclick: 1, oncommand: 1 });
 });
 
 add_sidebar_task(
   "Check that a sidebar that uses an onclick attribute and a command listener works",
 function*() {
-  gTestSidebarItem.setAttribute("onclick", "sawEvent(event, true)");
-  gTestSidebarItem.addEventListener("command", sawEvent);
+  gTestSidebarItem.setAttribute("onclick", "window.sawEvent(event, true)");
+  gTestSidebarItem.addEventListener("command", window.sawEvent);
 }, function*() {
   checkExpectedEvents({ onclick: 1, command: 1 });
 });
 
 add_sidebar_task(
   "Check that a sidebar that uses an oncommand attribute and a click listener works",
 function*() {
-  gTestSidebarItem.setAttribute("oncommand", "sawEvent(event, true)");
-  gTestSidebarItem.addEventListener("click", sawEvent);
+  gTestSidebarItem.setAttribute("oncommand", "window.sawEvent(event, true)");
+  gTestSidebarItem.addEventListener("click", window.sawEvent);
 }, function*() {
   checkExpectedEvents({ click: 1, oncommand: 1 });
 });
 
 add_sidebar_task(
   "A sidebar with both onclick attribute and click listener sees only one event :(",
 function*() {
-  gTestSidebarItem.setAttribute("onclick", "sawEvent(event, true)");
-  gTestSidebarItem.addEventListener("click", sawEvent);
+  gTestSidebarItem.setAttribute("onclick", "window.sawEvent(event, true)");
+  gTestSidebarItem.addEventListener("click", window.sawEvent);
 }, function*() {
   checkExpectedEvents({ onclick: 1 });
 });
 
 add_sidebar_task(
   "A sidebar with both oncommand attribute and command listener sees only one event :(",
 function*() {
-  gTestSidebarItem.setAttribute("oncommand", "sawEvent(event, true)");
-  gTestSidebarItem.addEventListener("command", sawEvent);
+  gTestSidebarItem.setAttribute("oncommand", "window.sawEvent(event, true)");
+  gTestSidebarItem.addEventListener("command", window.sawEvent);
 }, function*() {
   checkExpectedEvents({ oncommand: 1 });
 });
 
 add_sidebar_task(
   "Check that a sidebar that uses a broadcaster with an oncommand attribute works",
 function*() {
   let broadcaster = document.createElement("broadcaster");
   broadcaster.setAttribute("id", "testbroadcaster");
-  broadcaster.setAttribute("oncommand", "sawEvent(event, true)");
+  broadcaster.setAttribute("oncommand", "window.sawEvent(event, true)");
   broadcaster.setAttribute("label", "Test Sidebar");
   document.getElementById("mainBroadcasterSet").appendChild(broadcaster);
 
   gTestSidebarItem.setAttribute("observes", "testbroadcaster");
 }, function*() {
   checkExpectedEvents({ oncommand: 1 });
   document.getElementById("testbroadcaster").remove();
 });
 
 add_sidebar_task(
   "Check that a sidebar that uses a broadcaster with an onclick attribute works",
 function*() {
   let broadcaster = document.createElement("broadcaster");
   broadcaster.setAttribute("id", "testbroadcaster");
-  broadcaster.setAttribute("onclick", "sawEvent(event, true)");
+  broadcaster.setAttribute("onclick", "window.sawEvent(event, true)");
   broadcaster.setAttribute("label", "Test Sidebar");
   document.getElementById("mainBroadcasterSet").appendChild(broadcaster);
 
   gTestSidebarItem.setAttribute("observes", "testbroadcaster");
 }, function*() {
   checkExpectedEvents({ onclick: 1 });
   document.getElementById("testbroadcaster").remove();
 });
 
 add_sidebar_task(
   "Check that a sidebar that uses a broadcaster with both onclick and oncommand attributes works",
 function*() {
   let broadcaster = document.createElement("broadcaster");
   broadcaster.setAttribute("id", "testbroadcaster");
-  broadcaster.setAttribute("onclick", "sawEvent(event, true)");
-  broadcaster.setAttribute("oncommand", "sawEvent(event, true)");
+  broadcaster.setAttribute("onclick", "window.sawEvent(event, true)");
+  broadcaster.setAttribute("oncommand", "window.sawEvent(event, true)");
   broadcaster.setAttribute("label", "Test Sidebar");
   document.getElementById("mainBroadcasterSet").appendChild(broadcaster);
 
   gTestSidebarItem.setAttribute("observes", "testbroadcaster");
 }, function*() {
   checkExpectedEvents({ onclick: 1, oncommand: 1 });
   document.getElementById("testbroadcaster").remove();
 });
 
 add_sidebar_task(
   "Check that a sidebar with a click listener and a broadcaster with an oncommand attribute works",
 function*() {
   let broadcaster = document.createElement("broadcaster");
   broadcaster.setAttribute("id", "testbroadcaster");
-  broadcaster.setAttribute("oncommand", "sawEvent(event, true)");
+  broadcaster.setAttribute("oncommand", "window.sawEvent(event, true)");
   broadcaster.setAttribute("label", "Test Sidebar");
   document.getElementById("mainBroadcasterSet").appendChild(broadcaster);
 
   gTestSidebarItem.setAttribute("observes", "testbroadcaster");
-  gTestSidebarItem.addEventListener("click", sawEvent);
+  gTestSidebarItem.addEventListener("click", window.sawEvent);
 }, function*() {
   checkExpectedEvents({ click: 1, oncommand: 1 });
   document.getElementById("testbroadcaster").remove();
 });
 
 add_sidebar_task(
   "Check that a sidebar with a command listener and a broadcaster with an onclick attribute works",
 function*() {
   let broadcaster = document.createElement("broadcaster");
   broadcaster.setAttribute("id", "testbroadcaster");
-  broadcaster.setAttribute("onclick", "sawEvent(event, true)");
+  broadcaster.setAttribute("onclick", "window.sawEvent(event, true)");
   broadcaster.setAttribute("label", "Test Sidebar");
   document.getElementById("mainBroadcasterSet").appendChild(broadcaster);
 
   gTestSidebarItem.setAttribute("observes", "testbroadcaster");
-  gTestSidebarItem.addEventListener("command", sawEvent);
+  gTestSidebarItem.addEventListener("command", window.sawEvent);
 }, function*() {
   checkExpectedEvents({ onclick: 1, command: 1 });
   document.getElementById("testbroadcaster").remove();
 });
 
 add_sidebar_task(
   "Check that a sidebar with a click listener and a broadcaster with an onclick " +
   "attribute only sees one event :(",
 function*() {
   let broadcaster = document.createElement("broadcaster");
   broadcaster.setAttribute("id", "testbroadcaster");
-  broadcaster.setAttribute("onclick", "sawEvent(event, true)");
+  broadcaster.setAttribute("onclick", "window.sawEvent(event, true)");
   broadcaster.setAttribute("label", "Test Sidebar");
   document.getElementById("mainBroadcasterSet").appendChild(broadcaster);
 
   gTestSidebarItem.setAttribute("observes", "testbroadcaster");
-  gTestSidebarItem.addEventListener("click", sawEvent);
+  gTestSidebarItem.addEventListener("click", window.sawEvent);
 }, function*() {
   checkExpectedEvents({ onclick: 1 });
   document.getElementById("testbroadcaster").remove();
 });
 
 add_sidebar_task(
   "Check that a sidebar with a command listener and a broadcaster with an oncommand " +
   "attribute only sees one event :(",
 function*() {
   let broadcaster = document.createElement("broadcaster");
   broadcaster.setAttribute("id", "testbroadcaster");
-  broadcaster.setAttribute("oncommand", "sawEvent(event, true)");
+  broadcaster.setAttribute("oncommand", "window.sawEvent(event, true)");
   broadcaster.setAttribute("label", "Test Sidebar");
   document.getElementById("mainBroadcasterSet").appendChild(broadcaster);
 
   gTestSidebarItem.setAttribute("observes", "testbroadcaster");
-  gTestSidebarItem.addEventListener("command", sawEvent);
+  gTestSidebarItem.addEventListener("command", window.sawEvent);
 }, function*() {
   checkExpectedEvents({ oncommand: 1 });
   document.getElementById("testbroadcaster").remove();
 });
 
 add_sidebar_task(
   "Check that a sidebar that uses a command element with a command event listener works",
 function*() {
   let command = document.createElement("command");
   command.setAttribute("id", "testcommand");
   document.getElementById("mainCommandSet").appendChild(command);
-  command.addEventListener("command", sawEvent);
+  command.addEventListener("command", window.sawEvent);
 
   gTestSidebarItem.setAttribute("command", "testcommand");
 }, function*() {
   checkExpectedEvents({ command: 1 });
   document.getElementById("testcommand").remove();
 });
 
 add_sidebar_task(
   "Check that a sidebar that uses a command element with an oncommand attribute works",
 function*() {
   let command = document.createElement("command");
   command.setAttribute("id", "testcommand");
-  command.setAttribute("oncommand", "sawEvent(event, true)");
+  command.setAttribute("oncommand", "window.sawEvent(event, true)");
   document.getElementById("mainCommandSet").appendChild(command);
 
   gTestSidebarItem.setAttribute("command", "testcommand");
 }, function*() {
   checkExpectedEvents({ oncommand: 1 });
   document.getElementById("testcommand").remove();
 });
 
 add_sidebar_task("Check that a sidebar that uses a command element with a " +
   "command event listener and oncommand attribute works",
 function*() {
   let command = document.createElement("command");
   command.setAttribute("id", "testcommand");
-  command.setAttribute("oncommand", "sawEvent(event, true)");
+  command.setAttribute("oncommand", "window.sawEvent(event, true)");
   document.getElementById("mainCommandSet").appendChild(command);
-  command.addEventListener("command", sawEvent);
+  command.addEventListener("command", window.sawEvent);
 
   gTestSidebarItem.setAttribute("command", "testcommand");
 }, function*() {
   checkExpectedEvents({ command: 1, oncommand: 1 });
   document.getElementById("testcommand").remove();
 });
 
 add_sidebar_task(
   "A sidebar with a command element will still see click events",
 function*() {
   let command = document.createElement("command");
   command.setAttribute("id", "testcommand");
-  command.setAttribute("oncommand", "sawEvent(event, true)");
+  command.setAttribute("oncommand", "window.sawEvent(event, true)");
   document.getElementById("mainCommandSet").appendChild(command);
-  command.addEventListener("command", sawEvent);
+  command.addEventListener("command", window.sawEvent);
 
   gTestSidebarItem.setAttribute("command", "testcommand");
-  gTestSidebarItem.addEventListener("click", sawEvent);
+  gTestSidebarItem.addEventListener("click", window.sawEvent);
 }, function*() {
   checkExpectedEvents({ click: 1, command: 1, oncommand: 1 });
   document.getElementById("testcommand").remove();
 });
--- a/browser/components/originattributes/test/browser/file_sharedworker.js
+++ b/browser/components/originattributes/test/browser/file_sharedworker.js
@@ -1,7 +1,9 @@
 self.randomValue = Math.random();
 
+/* global onconnect:true */
+
 onconnect = function (e) {
   let port = e.ports[0];
   port.postMessage(self.randomValue);
   port.start();
 };
--- a/browser/components/preferences/applicationManager.js
+++ b/browser/components/preferences/applicationManager.js
@@ -1,12 +1,14 @@
 // 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/.
 
+/* import-globals-from in-content/applications.js */
+
 var Cc = Components.classes;
 var Ci = Components.interfaces;
 
 var gAppManagerDialog = {
   _removed: [],
 
   init: function appManager_init() {
     this.handlerInfo = window.arguments[0];
--- a/browser/components/preferences/fonts.js
+++ b/browser/components/preferences/fonts.js
@@ -1,13 +1,15 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
 /* 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/. */
 
+/* import-globals-from ../../../toolkit/mozapps/preferences/fontbuilder.js */
+
 // browser.display.languageList LOCK ALL when LOCKED
 
 const kDefaultFontType          = "font.default.%LANG%";
 const kFontNameFmtSerif         = "font.name.serif.%LANG%";
 const kFontNameFmtSansSerif     = "font.name.sans-serif.%LANG%";
 const kFontNameFmtMonospace     = "font.name.monospace.%LANG%";
 const kFontNameListFmtSerif     = "font.name-list.serif.%LANG%";
 const kFontNameListFmtSansSerif = "font.name-list.sans-serif.%LANG%";
@@ -96,9 +98,8 @@ var gFontsDialog = {
     let {Services} = Components.utils.import("resource://gre/modules/Services.jsm", {});
     let flags = Services.prompt.BUTTON_POS_1 * Services.prompt.BUTTON_TITLE_CANCEL |
                 Services.prompt.BUTTON_POS_0 * Services.prompt.BUTTON_TITLE_IS_STRING |
                 Services.prompt.BUTTON_POS_1_DEFAULT;
     let buttonChosen = Services.prompt.confirmEx(window, title, warningMessage, flags, confirmLabel, null, "", "", {});
     return buttonChosen == 0;
   },
 };
-
--- a/browser/components/preferences/handlers.xml
+++ b/browser/components/preferences/handlers.xml
@@ -1,13 +1,14 @@
 <?xml version="1.0"?>
 
 <!-- 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/. -->
+<!-- import-globals-from in-content/applications.js -->
 
 <!DOCTYPE overlay [
   <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
   <!ENTITY % applicationsDTD SYSTEM "chrome://browser/locale/preferences/applications.dtd">
   %brandDTD;
   %applicationsDTD;
 ]>
 
--- a/browser/components/preferences/in-content/preferences.js
+++ b/browser/components/preferences/in-content/preferences.js
@@ -1,12 +1,24 @@
 /* - 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/. */
 
+// Import globals from the files imported by the .xul files.
+/* import-globals-from subdialogs.js */
+/* import-globals-from advanced.js */
+/* import-globals-from main.js */
+/* import-globals-from search.js */
+/* import-globals-from content.js */
+/* import-globals-from privacy.js */
+/* import-globals-from applications.js */
+/* import-globals-from security.js */
+/* import-globals-from sync.js */
+/* import-globals-from ../../../base/content/utilityOverlay.js */
+
 "use strict";
 
 var Cc = Components.classes;
 var Ci = Components.interfaces;
 var Cu = Components.utils;
 var Cr = Components.results;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
--- a/browser/components/preferences/in-content/privacy.js
+++ b/browser/components/preferences/in-content/privacy.js
@@ -646,32 +646,32 @@ var gPrivacyPane = {
     gSubDialog.open("chrome://browser/content/preferences/sanitize.xul", "resizable=no");
   },
 
 
   /**
    * Displays a dialog from which individual parts of private data may be
    * cleared.
    */
-  clearPrivateDataNow: function (aClearEverything)
-  {
+  clearPrivateDataNow: function (aClearEverything) {
     var ts = document.getElementById("privacy.sanitize.timeSpan");
     var timeSpanOrig = ts.value;
-    if (aClearEverything)
+
+    if (aClearEverything) {
       ts.value = 0;
+    }
 
-    const Cc = Components.classes, Ci = Components.interfaces;
-    var glue = Cc["@mozilla.org/browser/browserglue;1"]
-                 .getService(Ci.nsIBrowserGlue);
-    glue.sanitize(window);
+    gSubDialog.open("chrome://browser/content/sanitize.xul", "resizable=no", null, () => {
+      // reset the timeSpan pref
+      if (aClearEverything) {
+        ts.value = timeSpanOrig;
+      }
 
-    // reset the timeSpan pref
-    if (aClearEverything)
-      ts.value = timeSpanOrig;
-    Services.obs.notifyObservers(null, "clear-private-data", null);
+      Services.obs.notifyObservers(null, "clear-private-data", null);
+    });
   },
 
   /**
    * Enables or disables the "Settings..." button depending
    * on the privacy.sanitize.sanitizeOnShutdown preference value
    */
   _updateSanitizeSettingsButton: function () {
     var settingsButton = document.getElementById("clearDataSettings");
--- a/browser/components/preferences/in-content/subdialogs.js
+++ b/browser/components/preferences/in-content/subdialogs.js
@@ -168,16 +168,28 @@ var gSubDialog = {
       this.injectXMLStylesheet(styleSheetURL);
     }
 
     // Provide the ability for the dialog to know that it is being loaded "in-content".
     this._frame.contentDocument.documentElement.setAttribute("subdialog", "true");
 
     this._frame.contentWindow.addEventListener("dialogclosing", this);
 
+    let oldResizeBy = this._frame.contentWindow.resizeBy;
+    this._frame.contentWindow.resizeBy = function(resizeByWidth, resizeByHeight) {
+      // Only handle resizeByHeight currently.
+      let frameHeight = gSubDialog._frame.clientHeight;
+      let boxMinHeight = parseFloat(getComputedStyle(gSubDialog._box).minHeight, 10);
+
+      gSubDialog._frame.style.height = (frameHeight + resizeByHeight) + "px";
+      gSubDialog._box.style.minHeight = (boxMinHeight + resizeByHeight) + "px";
+
+      oldResizeBy.call(gSubDialog._frame.contentWindow, resizeByWidth, resizeByHeight);
+    };
+
     // Make window.close calls work like dialog closing.
     let oldClose = this._frame.contentWindow.close;
     this._frame.contentWindow.close = function() {
       var closingEvent = gSubDialog._closingEvent;
       if (!closingEvent) {
         closingEvent = new CustomEvent("dialogclosing", {
           bubbles: true,
           detail: { button: null },
@@ -268,18 +280,20 @@ var gSubDialog = {
     this._frame.style.height = frameHeight;
     this._box.style.minHeight = "calc(" +
                                 (boxVerticalBorder + groupBoxTitleHeight + boxVerticalPadding) +
                                 "px + " + frameMinHeight + ")";
 
     this._overlay.style.visibility = "visible";
     this._overlay.style.opacity = ""; // XXX: focus hack continued from _onContentLoaded
 
-    this._resizeObserver = new MutationObserver(this._onResize);
-    this._resizeObserver.observe(this._box, {attributes: true});
+    if (this._box.getAttribute("resizable") == "true") {
+      this._resizeObserver = new MutationObserver(this._onResize);
+      this._resizeObserver.observe(this._box, {attributes: true});
+    }
 
     this._trapFocus();
   },
 
   _onResize: function(mutations) {
     let frame = gSubDialog._frame;
     // The width and height styles are needed for the initial
     // layout of the frame, but afterward they need to be removed
copy from browser/components/contextualidentity/test/browser/.eslintrc.js
copy to browser/components/syncedtabs/test/browser/.eslintrc.js
new file mode 100644
--- /dev/null
+++ b/browser/components/syncedtabs/test/xpcshell/.eslintrc.js
@@ -0,0 +1,7 @@
+"use strict";
+
+module.exports = {
+  "extends": [
+    "../../../../../testing/xpcshell/xpcshell.eslintrc.js"
+  ]
+};
new file mode 100644
--- /dev/null
+++ b/browser/components/tests/unit/.eslintrc.js
@@ -0,0 +1,7 @@
+"use strict";
+
+module.exports = {
+  "extends": [
+    "../../../../testing/xpcshell/xpcshell.eslintrc.js"
+  ]
+};
--- a/browser/components/tests/unit/test_distribution.js
+++ b/browser/components/tests/unit/test_distribution.js
@@ -4,16 +4,17 @@
 /**
  * Tests that preferences are properly set by distribution.ini
  */
 
 Cu.import("resource://gre/modules/LoadContextInfo.jsm");
 
 // Import common head.
 var commonFile = do_get_file("../../../../toolkit/components/places/tests/head_common.js", false);
+/* import-globals-from ../../../../toolkit/components/places/tests/head_common.js */
 if (commonFile) {
   let uri = Services.io.newFileURI(commonFile);
   Services.scriptloader.loadSubScript(uri.spec, this);
 }
 
 const TOPICDATA_DISTRIBUTION_CUSTOMIZATION = "force-distribution-customization";
 const TOPIC_BROWSERGLUE_TEST = "browser-glue-test";
 
--- a/browser/extensions/e10srollout/bootstrap.js
+++ b/browser/extensions/e10srollout/bootstrap.js
@@ -237,17 +237,17 @@ let performLongSpinnerCheck = Task.async
         // The Histogram might not be defined in this ping if no data was recorded for it.
         // In this case, we still add the session length because that was a valid session
         // without a long spinner.
         continue;
       }
 
       let histogram = ping.payload.histograms[LONG_SPINNER_HISTOGRAM];
 
-      for (spinnerTime of Object.keys(histogram.values)) {
+      for (let spinnerTime of Object.keys(histogram.values)) {
         // Only consider spinners that took more than 2 seconds.
         // Note: the first bucket size that fits this criteria is
         // 2297ms. And the largest bucket is 64000ms, meaning that
         // any pause larger than that is only counted as a 64s pause.
         // For reference, the bucket sizes are:
         // 0, 1000, 2297, 5277, 12124, 27856, 64000
         if (spinnerTime >= 2000) {
           totalSpinnerTime += spinnerTime * histogram.values[spinnerTime];
--- a/browser/extensions/formautofill/test/unit/.eslintrc
+++ b/browser/extensions/formautofill/test/unit/.eslintrc
@@ -1,5 +1,5 @@
 {
   "extends": [
-    "../../../../../testing/xpcshell/xpcshell.eslintrc"
+    "../../../../../testing/xpcshell/xpcshell.eslintrc.js"
   ],
 }
new file mode 100644
--- /dev/null
+++ b/browser/extensions/pocket/test/.eslintrc.js
@@ -0,0 +1,7 @@
+"use strict";
+
+module.exports = {
+  "extends": [
+    "../../../../testing/mochitest/browser.eslintrc.js"
+  ]
+};
copy from browser/components/contextualidentity/test/browser/.eslintrc.js
copy to browser/extensions/webcompat/test/browser/.eslintrc.js
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -203,17 +203,16 @@
 @RESPATH@/components/dom_power.xpt
 @RESPATH@/components/dom_push.xpt
 @RESPATH@/components/dom_quota.xpt
 @RESPATH@/components/dom_range.xpt
 @RESPATH@/components/dom_security.xpt
 @RESPATH@/components/dom_settings.xpt
 @RESPATH@/components/dom_permissionsettings.xpt
 @RESPATH@/components/dom_sidebar.xpt
-@RESPATH@/components/dom_mobilemessage.xpt
 @RESPATH@/components/dom_storage.xpt
 @RESPATH@/components/dom_stylesheets.xpt
 @RESPATH@/components/dom_telephony.xpt
 @RESPATH@/components/dom_traversal.xpt
 #ifdef MOZ_WEBSPEECH
 @RESPATH@/components/dom_webspeechrecognition.xpt
 #endif
 @RESPATH@/components/dom_workers.xpt
--- a/browser/modules/WindowsPreviewPerTab.jsm
+++ b/browser/modules/WindowsPreviewPerTab.jsm
@@ -601,17 +601,17 @@ TabWindow.prototype = {
   directRequestProtocols: new Set([
     "file", "chrome", "resource", "about"
   ]),
   onLinkIconAvailable: function (aBrowser, aIconURL) {
     let requestURL = null;
     if (aIconURL) {
       let shouldRequestFaviconURL = true;
       try {
-        urlObject = NetUtil.newURI(aIconURL);
+        let urlObject = NetUtil.newURI(aIconURL);
         shouldRequestFaviconURL =
           !this.directRequestProtocols.has(urlObject.scheme);
       } catch (ex) {}
 
       requestURL = shouldRequestFaviconURL ?
         "moz-anno:favicon:" + aIconURL :
         aIconURL;
     }
--- a/browser/modules/test/head.js
+++ b/browser/modules/test/head.js
@@ -24,11 +24,11 @@ function waitForConditionPromise(conditi
     return undefined;
   }
   setTimeout(checkCondition, SINGLE_TRY_TIMEOUT);
   return defer.promise;
 }
 
 function waitForCondition(condition, nextTest, errorMsg) {
   waitForConditionPromise(condition, errorMsg).then(nextTest, (reason) => {
-    ok(false, reason + (reason.stack ? "\n" + e.stack : ""));
+    ok(false, reason + (reason.stack ? "\n" + reason.stack : ""));
   });
 }
--- a/browser/themes/linux/sanitizeDialog.css
+++ b/browser/themes/linux/sanitizeDialog.css
@@ -51,17 +51,17 @@
 }
 
 
 /* Progressive disclosure button */
 #detailsExpanderWrapper {
   padding: 0;
   margin-top: 6px;
   margin-bottom: 6px;
-  margin-inline-start: -6px;
+  margin-inline-start: -4px;
   margin-inline-end: 0;
 }
 
 .expander-up,
 .expander-down {
   min-width: 0;
   padding: 2px 0;
   padding-inline-start: 2px;
--- a/browser/themes/shared/devedition.inc.css
+++ b/browser/themes/shared/devedition.inc.css
@@ -209,16 +209,24 @@ toolbar[brighttext] #downloads-indicator
 }
 
 window:not([chromehidden~="toolbar"]) #urlbar-wrapper {
   overflow: -moz-hidden-unscrollable;
   clip-path: none;
   margin-inline-start: 0;
 }
 
+:root[devtoolstheme="dark"] #urlbar-zoom-button:hover {
+  background-color: rgba(255,255,255,.2);
+}
+
+:root[devtoolstheme="dark"] #urlbar-zoom-button:hover:active {
+  background-color: rgba(255,255,255,.3);
+}
+
 /* Nav bar specific stuff */
 #nav-bar {
   margin-top: 0 !important;
   border-top: none !important;
   border-bottom: none !important;
   border-radius: 0 !important;
   box-shadow: 0 -1px var(--chrome-nav-bar-separator-color) !important;
 }
--- a/browser/themes/shared/incontentprefs/preferences.inc.css
+++ b/browser/themes/shared/incontentprefs/preferences.inc.css
@@ -364,17 +364,16 @@ description > html|a {
 #dialogBox > .groupbox-body {
   -moz-appearance: none;
   padding: 20px;
 }
 
 #dialogFrame {
   -moz-box-flex: 1;
   /* Default dialog dimensions */
-  height: 20em;
   width: 66ch;
 }
 
 .largeDialogContainer.doScroll {
   overflow-y: auto;
   -moz-box-flex: 1;
 }
 
new file mode 100644
--- /dev/null
+++ b/browser/tools/mozscreenshots/.eslintrc.js
@@ -0,0 +1,7 @@
+"use strict";
+
+module.exports = { // eslint-disable-line no-undef
+  "extends": [
+    "../../../testing/mochitest/browser.eslintrc.js"
+  ],
+};
--- a/browser/tools/mozscreenshots/controlCenter/browser_controlCenter.js
+++ b/browser/tools/mozscreenshots/controlCenter/browser_controlCenter.js
@@ -1,12 +1,14 @@
 /* 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/. */
 
+/* import-globals-from ../head.js */
+
 "use strict";
 
 add_task(function* capture() {
   if (!shouldCapture()) {
     return;
   }
   let sets = ["LightweightThemes", "ControlCenter"];
 
--- a/browser/tools/mozscreenshots/devtools/browser_devtools.js
+++ b/browser/tools/mozscreenshots/devtools/browser_devtools.js
@@ -1,12 +1,14 @@
 /* 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/. */
 
+/* import-globals-from ../head.js */
+
 "use strict";
 
 add_task(function* capture() {
   if (!shouldCapture()) {
     return;
   }
   let sets = ["DevTools"];
 
--- a/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Preferences.jsm
+++ b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Preferences.jsm
@@ -18,16 +18,17 @@ this.Preferences = {
   init(libDir) {
     let panes = [
       ["paneGeneral", null],
       ["paneSearch", null],
       ["paneContent", null],
       ["paneApplications", null],
       ["panePrivacy", null],
       ["panePrivacy", null, DNTDialog],
+      ["panePrivacy", null, clearRecentHistoryDialog],
       ["paneSecurity", null],
       ["paneSync", null],
       ["paneAdvanced", "generalTab"],
       ["paneAdvanced", "dataChoicesTab"],
       ["paneAdvanced", "networkTab"],
       ["paneAdvanced", "networkTab", connectionDialog],
       ["paneAdvanced", "updateTab"],
       ["paneAdvanced", "encryptionTab"],
@@ -102,16 +103,22 @@ function* DNTDialog(aBrowser) {
 }
 
 function* connectionDialog(aBrowser) {
   yield ContentTask.spawn(aBrowser, null, function* () {
     content.document.getElementById("connectionSettings").click();
   });
 }
 
+function* clearRecentHistoryDialog(aBrowser) {
+  yield ContentTask.spawn(aBrowser, null, function* () {
+    content.document.getElementById("historyRememberClear").click();
+  });
+}
+
 function* certManager(aBrowser) {
   yield ContentTask.spawn(aBrowser, null, function* () {
     content.document.getElementById("viewCertificatesButton").click();
   });
 }
 
 function* deviceManager(aBrowser) {
   yield ContentTask.spawn(aBrowser, null, function* () {
--- a/browser/tools/mozscreenshots/permissionPrompts/browser_permissionPrompts.js
+++ b/browser/tools/mozscreenshots/permissionPrompts/browser_permissionPrompts.js
@@ -1,12 +1,14 @@
 /* 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/. */
 
+/* import-globals-from ../head.js */
+
 "use strict";
 
 add_task(function* capture() {
   if (!shouldCapture()) {
     return;
   }
   let sets = ["LightweightThemes", "PermissionPrompts"];
 
--- a/browser/tools/mozscreenshots/preferences/browser_preferences.js
+++ b/browser/tools/mozscreenshots/preferences/browser_preferences.js
@@ -1,12 +1,14 @@
 /* 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/. */
 
+/* import-globals-from ../head.js */
+
 "use strict";
 
 add_task(function* capture() {
   if (!shouldCapture()) {
     return;
   }
   let sets = ["Preferences"];
 
--- a/browser/tools/mozscreenshots/primaryUI/browser_primaryUI.js
+++ b/browser/tools/mozscreenshots/primaryUI/browser_primaryUI.js
@@ -1,12 +1,14 @@
 /* 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/. */
 
+/* import-globals-from ../head.js */
+
 "use strict";
 
 add_task(function* capture() {
   if (!shouldCapture()) {
     return;
   }
 
   requestLongerTimeout(20);
--- a/build/moz.configure/init.configure
+++ b/build/moz.configure/init.configure
@@ -768,17 +768,17 @@ def all_configure_options(_):
         # interesting.
         if option == previous or option.env in ('OLD_CONFIGURE', 'MOZCONFIG'):
             continue
         previous = option
         value = __sandbox__._value_for(option)
         # We only want options that were explicitly given on the command
         # line, the environment, or mozconfig, and that differ from the
         # defaults.
-        if (value.origin not in ('default', 'implied') and
+        if (value is not None and value.origin not in ('default', 'implied') and
                 value != option.default):
             result.append(__sandbox__._raw_options[option])
         # We however always include options that are sent to old configure
         # because we don't know their actual defaults. (Keep the conditions
         # separate for ease of understanding and ease of removal)
         elif (option.help == 'Help missing for old configure options' and
                 option in __sandbox__._raw_options):
             result.append(__sandbox__._raw_options[option])
--- a/devtools/client/framework/toolbox-options.xhtml
+++ b/devtools/client/framework/toolbox-options.xhtml
@@ -79,16 +79,26 @@
         <label title="&options.timestampMessages.tooltip;">
           <input type="checkbox"
                  id="webconsole-timestamp-messages"
                  data-pref="devtools.webconsole.timestampMessages"/>
           <span>&options.timestampMessages.label;</span>
         </label>
       </fieldset>
 
+      <fieldset id="debugger-options" class="options-groupbox">
+        <legend>&options.debugger.label;</legend>
+        <label title="&options.sourceMaps.tooltip;">
+          <input type="checkbox"
+                 id="debugger-sourcemaps"
+                 data-pref="devtools.debugger.client-source-maps-enabled"/>
+          <span>&options.sourceMaps.label;</span>
+        </label>
+      </fieldset>
+
       <fieldset id="styleeditor-options" class="options-groupbox">
         <legend>&options.styleeditor.label;</legend>
         <label title="&options.stylesheetSourceMaps.tooltip;">
           <input type="checkbox"
                  data-pref="devtools.styleeditor.source-maps-enabled"/>
           <span>&options.stylesheetSourceMaps.label;</span>
         </label>
         <label title="&options.stylesheetAutocompletion.tooltip;">
--- a/devtools/client/framework/toolbox-process-window.js
+++ b/devtools/client/framework/toolbox-process-window.js
@@ -66,16 +66,17 @@ function setPrefDefaults() {
   Services.prefs.setBoolPref("devtools.performance.ui.show-platform-data", true);
   Services.prefs.setBoolPref("devtools.inspector.showAllAnonymousContent", true);
   Services.prefs.setBoolPref("browser.dom.window.dump.enabled", true);
   Services.prefs.setBoolPref("devtools.command-button-noautohide.enabled", true);
   Services.prefs.setBoolPref("devtools.scratchpad.enabled", true);
   // Bug 1225160 - Using source maps with browser debugging can lead to a crash
   Services.prefs.setBoolPref("devtools.debugger.source-maps-enabled", false);
   Services.prefs.setBoolPref("devtools.debugger.new-debugger-frontend", false);
+  Services.prefs.setBoolPref("devtools.debugger.client-source-maps-enabled", true);
 }
 
 window.addEventListener("load", function() {
   let cmdClose = document.getElementById("toolbox-cmd-close");
   cmdClose.addEventListener("command", onCloseCommand);
   setPrefDefaults();
   connect().catch(e => {
     let errorMessageContainer = document.getElementById("error-message-container");
--- a/devtools/client/locales/en-US/toolbox.dtd
+++ b/devtools/client/locales/en-US/toolbox.dtd
@@ -154,16 +154,25 @@
   -  heading of the group of Web Console preferences in the options panel. -->
 <!ENTITY options.webconsole.label            "Web Console">
 
 <!-- LOCALIZATION NOTE (options.timestampMessages.label): This is the
    - label for the checkbox that toggles timestamps in the Web Console -->
 <!ENTITY options.timestampMessages.label      "Enable timestamps">
 <!ENTITY options.timestampMessages.tooltip    "If you enable this option commands and output in the Web Console will display a timestamp">
 
+<!-- LOCALIZATION NOTE (options.debugger.label): This is the label for the
+  -  heading of the group of Debugger preferences in the options panel. -->
+<!ENTITY options.debugger.label            "Debugger">
+
+<!-- LOCALIZATION NOTE (options.sourceMap.label): This is the
+   - label for the checkbox that toggles source maps in the Debugger -->
+<!ENTITY options.sourceMaps.label      "Enable Source Maps">
+<!ENTITY options.sourceMaps.tooltip    "If you enable this option sources will be mapped in the Debugger and Console.">
+
 <!-- LOCALIZATION NOTE (options.styleeditor.label): This is the label for the
   -  heading of the group of Style Editor preferences in the options
   -  panel. -->
 <!ENTITY options.styleeditor.label            "Style Editor">
 
 <!-- LOCALIZATION NOTE (options.stylesheetSourceMaps.label): This is the
    - label for the checkbox that toggles showing original sources in the Style Editor -->
 <!ENTITY options.stylesheetSourceMaps.label      "Show original sources">
--- a/devtools/client/preferences/devtools.js
+++ b/devtools/client/preferences/devtools.js
@@ -90,16 +90,17 @@ pref("devtools.debugger.enabled", true);
 pref("devtools.debugger.chrome-debugging-host", "localhost");
 pref("devtools.debugger.chrome-debugging-port", 6080);
 pref("devtools.debugger.chrome-debugging-websocket", false);
 pref("devtools.debugger.remote-host", "localhost");
 pref("devtools.debugger.remote-timeout", 20000);
 pref("devtools.debugger.pause-on-exceptions", false);
 pref("devtools.debugger.ignore-caught-exceptions", true);
 pref("devtools.debugger.source-maps-enabled", true);
+pref("devtools.debugger.client-source-maps-enabled", true);
 pref("devtools.debugger.pretty-print-enabled", true);
 pref("devtools.debugger.auto-pretty-print", false);
 pref("devtools.debugger.auto-black-box", true);
 pref("devtools.debugger.workers", false);
 pref("devtools.debugger.promise", false);
 
 #if defined(NIGHTLY_BUILD)
 pref("devtools.debugger.new-debugger-frontend", true);
--- a/devtools/client/responsive.html/browser/tunnel.js
+++ b/devtools/client/responsive.html/browser/tunnel.js
@@ -176,27 +176,67 @@ function tunnelToInnerBrowser(outer, inn
       });
 
       // Wants to access the content's `frameLoader`, so we'll redirect it to
       // inner browser.
       outer.preserveLayers = value => {
         inner.frameLoader.tabParent.preserveLayers(value);
       };
 
-      // Make the PopupNotifications object available on the iframe's owner
-      // This is used for permission doorhangers
+      // Expose `PopupNotifications` on the content's owner global.
+      // This is used by PermissionUI.jsm for permission doorhangers.
+      // Note: This pollutes the responsive.html tool UI's global.
       Object.defineProperty(inner.ownerGlobal, "PopupNotifications", {
         get() {
           return outer.ownerGlobal.PopupNotifications;
         },
         configurable: true,
         enumerable: true,
       });
+
+      // Expose `whereToOpenLink` on the content's owner global.
+      // This is used by ContentClick.jsm when opening links in ways other than just
+      // navigating the viewport.
+      // Note: This pollutes the responsive.html tool UI's global.
+      Object.defineProperty(inner.ownerGlobal, "whereToOpenLink", {
+        get() {
+          return outer.ownerGlobal.whereToOpenLink;
+        },
+        configurable: true,
+        enumerable: true,
+      });
+
+      // Add mozbrowser event handlers
+      inner.addEventListener("mozbrowseropenwindow", this);
     }),
 
+    handleEvent(event) {
+      if (event.type != "mozbrowseropenwindow") {
+        return;
+      }
+
+      // Minimal support for <a target/> and window.open() which just ensures we at
+      // least open them somewhere (in a new tab).  The following things are ignored:
+      //   * Specific target names (everything treated as _blank)
+      //   * Window features
+      //   * window.opener
+      // These things are deferred for now, since content which does depend on them seems
+      // outside the main focus of RDM.
+      let { detail } = event;
+      event.preventDefault();
+      let uri = Services.io.newURI(detail.url, null, null);
+      // This API is used mainly because it's near the path used for <a target/> with
+      // regular browser tabs (which calls `openURIInFrame`).  The more elaborate APIs
+      // that support openers, window features, etc. didn't seem callable from JS and / or
+      // this event doesn't give enough info to use them.
+      browserWindow.browserDOMWindow
+                   .openURI(uri, null, Ci.nsIBrowserDOMWindow.OPEN_NEWTAB,
+                            Ci.nsIBrowserDOMWindow.OPEN_NEWTAB);
+    },
+
     stop() {
       let tab = gBrowser.getTabForBrowser(outer);
       let filteredProgressListener = gBrowser._tabFilters.get(tab);
 
       // The browser's state has changed over time while the tunnel was active.  Push the
       // the current state down to the inner browser, so that it follows the content in
       // case that browser will be swapped elsewhere.
       for (let property of SWAPPED_BROWSER_STATE) {
@@ -218,18 +258,22 @@ function tunnelToInnerBrowser(outer, inn
       // are on the prototype.
       delete outer.hasContentOpener;
       delete outer.docShellIsActive;
       delete outer.preserveLayers;
 
       // Reset @remote since this is now back to a regular, non-remote browser
       outer.setAttribute("remote", "false");
 
-      // Delete the PopupNotifications getter added for permission doorhangers
+      // Delete browser window properties exposed on content's owner global
       delete inner.ownerGlobal.PopupNotifications;
+      delete inner.ownerGlobal.whereToOpenLink;
+
+      // Remove mozbrowser event handlers
+      inner.removeEventListener("mozbrowseropenwindow", this);
 
       mmTunnel.destroy();
       mmTunnel = null;
 
       // Invalidate outer's permanentKey so that SessionStore stops associating
       // things that happen to the outer browser with the content inside in the
       // inner browser.
       outer.permanentKey = { id: "zombie" };
--- a/devtools/server/actors/highlighters/box-model.js
+++ b/devtools/server/actors/highlighters/box-model.js
@@ -1,43 +1,38 @@
  /* 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/. */
 
 "use strict";
 
-const { Cu } = require("chrome");
 const { extend } = require("sdk/core/heritage");
 const { AutoRefreshHighlighter } = require("./auto-refresh");
-const { CssGridHighlighter } = require("./css-grid");
 const {
   CanvasFrameAnonymousContentHelper,
   createNode,
   createSVGNode,
   getBindingElementAndPseudo,
   hasPseudoClassLock,
   isNodeValid,
   moveInfobar,
 } = require("./utils/markup");
 const { setIgnoreLayoutChanges } = require("devtools/shared/layout/utils");
 const inspector = require("devtools/server/actors/inspector");
 const nodeConstants = require("devtools/shared/dom-node-constants");
-const Services = require("Services");
 
 // Note that the order of items in this array is important because it is used
 // for drawing the BoxModelHighlighter's path elements correctly.
 const BOX_MODEL_REGIONS = ["margin", "border", "padding", "content"];
 const BOX_MODEL_SIDES = ["top", "right", "bottom", "left"];
 // Width of boxmodelhighlighter guides
 const GUIDE_STROKE_WIDTH = 1;
 // FIXME: add ":visited" and ":link" after bug 713106 is fixed
 const PSEUDO_CLASSES = [":hover", ":active", ":focus"];
 
-const GRID_ENABLED_PREF = "layout.css.grid.enabled";
-
 /**
  * The BoxModelHighlighter draws the box model regions on top of a node.
  * If the node is a block box, then each region will be displayed as 1 polygon.
  * If the node is an inline box though, each region may be represented by 1 or
  * more polygons, depending on how many line boxes the inline element has.
  *
  * Usage example:
  *
@@ -92,20 +87,16 @@ const GRID_ENABLED_PREF = "layout.css.gr
  *       <div class="box-model-infobar-arrow box-model-infobar-arrow-bottom"/>
  *     </div>
  *   </div>
  * </div>
  */
 function BoxModelHighlighter(highlighterEnv) {
   AutoRefreshHighlighter.call(this, highlighterEnv);
 
-  if (Services.prefs.getBoolPref(GRID_ENABLED_PREF)) {
-    this.cssGridHighlighter = new CssGridHighlighter(this.highlighterEnv);
-  }
-
   this.markup = new CanvasFrameAnonymousContentHelper(this.highlighterEnv,
     this._buildMarkup.bind(this));
 
   /**
    * Optionally customize each region's fill color by adding an entry to the
    * regionFill property: `highlighter.regionFill.margin = "red";
    */
   this.regionFill = {};
@@ -258,21 +249,16 @@ BoxModelHighlighter.prototype = extend(A
   },
 
   /**
    * Destroy the nodes. Remove listeners.
    */
   destroy: function () {
     AutoRefreshHighlighter.prototype.destroy.call(this);
     this.markup.destroy();
-
-    if (this.cssGridHighlighter) {
-      this.cssGridHighlighter.destroy();
-      this.cssGridHighlighter = null;
-    }
   },
 
   getElement: function (id) {
     return this.markup.getElement(this.ID_CLASS_PREFIX + id);
   },
 
   /**
    * Override the AutoRefreshHighlighter's _isNodeValid method to also return true for
@@ -287,38 +273,16 @@ BoxModelHighlighter.prototype = extend(A
   /**
    * Show the highlighter on a given node
    */
   _show: function () {
     if (BOX_MODEL_REGIONS.indexOf(this.options.region) == -1) {
       this.options.region = "content";
     }
 
-    // Show the CSS grid highlighter if the current node is a grid container or grid item.
-    if (this.cssGridHighlighter) {
-      this.cssGridHighlighter.hide();
-      let gridNode;
-      if (this.currentNode &&
-          this.currentNode.getGridFragments &&
-          this.currentNode.getGridFragments().length) {
-        gridNode = this.currentNode;
-      } else if (this.currentNode.parentNode &&
-                 this.currentNode.parentNode.getGridFragments &&
-                 this.currentNode.parentNode.getGridFragments().length) {
-        gridNode = this.currentNode.parentNode;
-      }
-
-      if (gridNode) {
-        // Display the grid highlighter for the grid container and
-        // hide the box model guides.
-        this.cssGridHighlighter.show(gridNode);
-        this.options.hideGuides = true;
-      }
-    }
-
     let shown = this._update();
     this._trackMutations();
     this.emit("ready");
     return shown;
   },
 
   /**
    * Track the current node markup mutations so that the node info bar can be
@@ -375,20 +339,16 @@ BoxModelHighlighter.prototype = extend(A
    */
   _hide: function () {
     setIgnoreLayoutChanges(true);
 
     this._untrackMutations();
     this._hideBoxModel();
     this._hideInfobar();
 
-    if (this.cssGridHighlighter) {
-      this.cssGridHighlighter.hide();
-    }
-
     setIgnoreLayoutChanges(false, this.currentNode.ownerDocument.documentElement);
   },
 
   /**
    * Hide the infobar
    */
   _hideInfobar: function () {
     this.getElement("infobar-container").setAttribute("hidden", "true");
--- a/devtools/server/actors/highlighters/css-grid.js
+++ b/devtools/server/actors/highlighters/css-grid.js
@@ -1,15 +1,14 @@
 /* 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/. */
 
 "use strict";
 
-const { Cu } = require("chrome");
 const { extend } = require("sdk/core/heritage");
 const { AutoRefreshHighlighter } = require("./auto-refresh");
 const {
   CanvasFrameAnonymousContentHelper,
   createNode,
   createSVGNode,
   moveInfobar,
 } = require("./utils/markup");
@@ -41,21 +40,17 @@ const GRID_LINES_PROPERTIES = {
 const GRID_GAP_PATTERN_WIDTH = 14;
 const GRID_GAP_PATTERN_HEIGHT = 14;
 const GRID_GAP_PATTERN_LINE_DASH = [5, 3];
 const GRID_GAP_PATTERN_STROKE_STYLE = "#9370DB";
 
 /**
  * Cached used by `CssGridHighlighter.getGridGapPattern`.
  */
-const gCachedGridPattern = new WeakMap();
-// WeakMap key for the Row grid pattern.
-const ROW_KEY = {};
-// WeakMap key for the Column grid pattern.
-const COLUMN_KEY = {};
+const gCachedGridPattern = new Map();
 
 /**
  * The CssGridHighlighter is the class that overlays a visual grid on top of
  * display:grid elements.
  *
  * Usage example:
  * let h = new CssGridHighlighter(env);
  * h.show(node, options);
@@ -93,19 +88,16 @@ const COLUMN_KEY = {};
  *   </div>
  * </div>
  */
 function CssGridHighlighter(highlighterEnv) {
   AutoRefreshHighlighter.call(this, highlighterEnv);
 
   this.markup = new CanvasFrameAnonymousContentHelper(this.highlighterEnv,
     this._buildMarkup.bind(this));
-
-  this.onNavigate = this.onNavigate.bind(this);
-  this.highlighterEnv.on("navigate", this.onNavigate);
 }
 
 CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
   typeName: "CssGridHighlighter",
 
   ID_CLASS_PREFIX: "css-grid-",
 
   _buildMarkup() {
@@ -206,19 +198,19 @@ CssGridHighlighter.prototype = extend(Au
       },
       prefix: this.ID_CLASS_PREFIX
     });
 
     return container;
   },
 
   destroy() {
-    this.highlighterEnv.off("navigate", this.onNavigate);
+    AutoRefreshHighlighter.prototype.destroy.call(this);
     this.markup.destroy();
-    AutoRefreshHighlighter.prototype.destroy.call(this);
+    gCachedGridPattern.clear();
   },
 
   getElement(id) {
     return this.markup.getElement(this.ID_CLASS_PREFIX + id);
   },
 
   get ctx() {
     return this.canvas.getCanvasContext("2d");
@@ -226,61 +218,51 @@ CssGridHighlighter.prototype = extend(Au
 
   get canvas() {
     return this.getElement("canvas");
   },
 
   /**
    * Gets the grid gap pattern used to render the gap regions.
    *
-   * @param  {Object} dimension
-   *         Refers to the WeakMap key for the grid dimension type which is either the
-   *         constant COLUMN or ROW.
+   * @param  {String} dimensionType
+   *         The grid dimension type which is either the constant COLUMNS or ROWS.
    * @return {CanvasPattern} grid gap pattern.
    */
-  getGridGapPattern(dimension) {
-    if (gCachedGridPattern.has(dimension)) {
-      return gCachedGridPattern.get(dimension);
+  getGridGapPattern(dimensionType) {
+    if (gCachedGridPattern.has(dimensionType)) {
+      return gCachedGridPattern.get(dimensionType);
     }
 
     // Create the diagonal lines pattern for the rendering the grid gaps.
     let canvas = createNode(this.win, { nodeType: "canvas" });
     canvas.width = GRID_GAP_PATTERN_WIDTH;
     canvas.height = GRID_GAP_PATTERN_HEIGHT;
 
     let ctx = canvas.getContext("2d");
     ctx.setLineDash(GRID_GAP_PATTERN_LINE_DASH);
     ctx.beginPath();
     ctx.translate(.5, .5);
 
-    if (dimension === COLUMN_KEY) {
+    if (dimensionType === COLUMNS) {
       ctx.moveTo(0, 0);
       ctx.lineTo(GRID_GAP_PATTERN_WIDTH, GRID_GAP_PATTERN_HEIGHT);
     } else {
       ctx.moveTo(GRID_GAP_PATTERN_WIDTH, 0);
       ctx.lineTo(0, GRID_GAP_PATTERN_HEIGHT);
     }
 
     ctx.strokeStyle = GRID_GAP_PATTERN_STROKE_STYLE;
     ctx.stroke();
 
     let pattern = ctx.createPattern(canvas, "repeat");
-    gCachedGridPattern.set(dimension, pattern);
+    gCachedGridPattern.set(dimensionType, pattern);
     return pattern;
   },
 
-  /**
-   * Called when the page navigates. Used to clear the cached gap patterns and avoid
-   * using DeadWrapper objects as gap patterns the next time.
-   */
-  onNavigate() {
-    gCachedGridPattern.delete(ROW_KEY);
-    gCachedGridPattern.delete(COLUMN_KEY);
-  },
-
   _show() {
     if (Services.prefs.getBoolPref(CSS_GRID_ENABLED_PREF) && !this.isGrid()) {
       this.hide();
       return false;
     }
 
     return this._update();
   },
@@ -615,22 +597,21 @@ CssGridHighlighter.prototype = extend(Au
    *         The end position of the cross side of the grid line.
    * @param  {Number} breadth
    *         The grid line breadth value.
    * @param  {String} dimensionType
    *         The grid dimension type which is either the constant COLUMNS or ROWS.
    */
   renderGridGap(linePos, startPos, endPos, breadth, dimensionType) {
     this.ctx.save();
+    this.ctx.fillStyle = this.getGridGapPattern(dimensionType);
 
     if (dimensionType === COLUMNS) {
-      this.ctx.fillStyle = this.getGridGapPattern(COLUMN_KEY);
       this.ctx.fillRect(linePos, startPos, breadth, endPos - startPos);
     } else {
-      this.ctx.fillStyle = this.getGridGapPattern(ROW_KEY);
       this.ctx.fillRect(startPos, linePos, endPos - startPos, breadth);
     }
 
     this.ctx.restore();
   },
 
   /**
    * Render the grid area highlight for the given area name or for all the grid areas.
@@ -724,20 +705,16 @@ exports.CssGridHighlighter = CssGridHigh
  * Stringify CSS Grid data as returned by node.getGridFragments.
  * This is useful to compare grid state at each update and redraw the highlighter if
  * needed.
  *
  * @param  {Object} Grid Fragments
  * @return {String} representation of the CSS grid fragment data.
  */
 function stringifyGridFragments(fragments = []) {
-  if (fragments[0] && Cu.isDeadWrapper(fragments[0])) {
-    return {};
-  }
-
   return JSON.stringify(fragments.map(getStringifiableFragment));
 }
 
 function getStringifiableFragment(fragment) {
   return {
     cols: getStringifiableDimension(fragment.cols),
     rows: getStringifiableDimension(fragment.rows)
   };
--- a/docshell/shistory/nsSHistory.cpp
+++ b/docshell/shistory/nsSHistory.cpp
@@ -1531,17 +1531,20 @@ nsSHistory::LoadNextPossibleEntry(int32_
     return LoadEntry(aNewIndex + 1, aLoadType, aHistCmd);
   }
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsSHistory::LoadEntry(int32_t aIndex, long aLoadType, uint32_t aHistCmd)
 {
-  nsCOMPtr<nsIDocShell> docShell;
+  if (!mRootDocShell) {
+    return NS_ERROR_FAILURE;
+  }
+
   // Keep note of requested history index in mRequestedIndex.
   mRequestedIndex = aIndex;
 
   nsCOMPtr<nsISHEntry> prevEntry;
   GetEntryAtIndex(mIndex, false, getter_AddRefs(prevEntry));
 
   nsCOMPtr<nsISHEntry> nextEntry;
   GetEntryAtIndex(mRequestedIndex, false, getter_AddRefs(nextEntry));
@@ -1579,112 +1582,65 @@ nsSHistory::LoadEntry(int32_t aIndex, lo
 
   if (!canNavigate) {
     // If the listener asked us not to proceed with
     // the operation, simply return.
     mRequestedIndex = -1;
     return NS_OK;  // XXX Maybe I can return some other error code?
   }
 
-  int32_t pCount = 0;
-  int32_t nCount = 0;
-  nsCOMPtr<nsISHContainer> prevAsContainer(do_QueryInterface(prevEntry));
-  nsCOMPtr<nsISHContainer> nextAsContainer(do_QueryInterface(nextEntry));
-  if (prevAsContainer && nextAsContainer) {
-    prevAsContainer->GetChildCount(&pCount);
-    nextAsContainer->GetChildCount(&nCount);
-  }
-
   if (mRequestedIndex == mIndex) {
     // Possibly a reload case
-    docShell = mRootDocShell;
-  } else {
-    // Going back or forward.
-    if (pCount > 0 && nCount > 0) {
-      /* THis is a subframe navigation. Go find
-       * the docshell in which load should happen
-       */
-      bool frameFound = false;
-      nsresult rv = CompareFrames(prevEntry, nextEntry, mRootDocShell,
-                                  aLoadType, &frameFound);
-      if (!frameFound) {
-        // We did not successfully find the subframe in which
-        // the new url was to be loaded. Go further in the history.
-        return LoadNextPossibleEntry(aIndex, aLoadType, aHistCmd);
-      }
-      return rv;
-    } else {
-      // Loading top level page.
-      uint32_t prevID = 0;
-      uint32_t nextID = 0;
-      prevEntry->GetID(&prevID);
-      nextEntry->GetID(&nextID);
-      if (prevID == nextID) {
-        // Try harder to find something new to load.
-        // This may happen for example if some page removed iframes dynamically.
-        return LoadNextPossibleEntry(aIndex, aLoadType, aHistCmd);
-      }
-      docShell = mRootDocShell;
-    }
+    return InitiateLoad(nextEntry, mRootDocShell, aLoadType);
   }
 
-  if (!docShell) {
-    // we did not successfully go to the proper index.
-    // return error.
-    mRequestedIndex = -1;
-    return NS_ERROR_FAILURE;
+  // Going back or forward.
+  bool differenceFound = false;
+  nsresult rv = LoadDifferingEntries(prevEntry, nextEntry, mRootDocShell,
+                                     aLoadType, differenceFound);
+  if (!differenceFound) {
+    // We did not find any differences. Go further in the history.
+    return LoadNextPossibleEntry(aIndex, aLoadType, aHistCmd);
   }
 
-  // Start the load on the appropriate docshell
-  return InitiateLoad(nextEntry, docShell, aLoadType);
+  return rv;
 }
 
 nsresult
-nsSHistory::CompareFrames(nsISHEntry* aPrevEntry, nsISHEntry* aNextEntry,
-                          nsIDocShell* aParent, long aLoadType,
-                          bool* aIsFrameFound)
+nsSHistory::LoadDifferingEntries(nsISHEntry* aPrevEntry, nsISHEntry* aNextEntry,
+                                 nsIDocShell* aParent, long aLoadType,
+                                 bool& aDifferenceFound)
 {
   if (!aPrevEntry || !aNextEntry || !aParent) {
     return NS_ERROR_FAILURE;
   }
 
-  // We should be comparing only entries which were created for the
-  // same docshell. This is here to just prevent anything strange happening.
-  // This check could be possibly an assertion.
-  uint64_t prevdID, nextdID;
-  aPrevEntry->GetDocshellID(&prevdID);
-  aNextEntry->GetDocshellID(&nextdID);
-  NS_ENSURE_STATE(prevdID == nextdID);
-
   nsresult result = NS_OK;
   uint32_t prevID, nextID;
 
   aPrevEntry->GetID(&prevID);
   aNextEntry->GetID(&nextID);
 
   // Check the IDs to verify if the pages are different.
   if (prevID != nextID) {
-    if (aIsFrameFound) {
-      *aIsFrameFound = true;
-    }
-    // Set the Subframe flag of the entry to indicate that
-    // it is subframe navigation
-    aNextEntry->SetIsSubFrame(true);
-    InitiateLoad(aNextEntry, aParent, aLoadType);
-    return NS_OK;
+    aDifferenceFound = true;
+
+    // Set the Subframe flag if not navigating the root docshell.
+    aNextEntry->SetIsSubFrame(aParent != mRootDocShell);
+    return InitiateLoad(aNextEntry, aParent, aLoadType);
   }
 
-  // The root entries are the same, so compare any child frames
+  // The entries are the same, so compare any child frames
   int32_t pcnt = 0;
   int32_t ncnt = 0;
   int32_t dsCount = 0;
   nsCOMPtr<nsISHContainer> prevContainer(do_QueryInterface(aPrevEntry));
   nsCOMPtr<nsISHContainer> nextContainer(do_QueryInterface(aNextEntry));
 
-  if (!aParent || !prevContainer || !nextContainer) {
+  if (!prevContainer || !nextContainer) {
     return NS_ERROR_FAILURE;
   }
 
   prevContainer->GetChildCount(&pcnt);
   nextContainer->GetChildCount(&ncnt);
   aParent->GetChildCount(&dsCount);
 
   // Create an array for child docshells.
@@ -1739,17 +1695,17 @@ nsSHistory::CompareFrames(nsISHEntry* aP
           break;
         }
       }
     }
 
     // Finally recursively call this method.
     // This will either load a new page to shell or some subshell or
     // do nothing.
-    CompareFrames(pChild, nChild, dsChild, aLoadType, aIsFrameFound);
+    LoadDifferingEntries(pChild, nChild, dsChild, aLoadType, aDifferenceFound);
   }
   return result;
 }
 
 nsresult
 nsSHistory::InitiateLoad(nsISHEntry* aFrameEntry, nsIDocShell* aFrameDS,
                          long aLoadType)
 {
--- a/docshell/shistory/nsSHistory.h
+++ b/docshell/shistory/nsSHistory.h
@@ -48,19 +48,19 @@ public:
 
 protected:
   virtual ~nsSHistory();
   friend class nsSHEnumerator;
   friend class nsSHistoryObserver;
 
   // Could become part of nsIWebNavigation
   NS_IMETHOD GetTransactionAtIndex(int32_t aIndex, nsISHTransaction** aResult);
-  nsresult CompareFrames(nsISHEntry* aPrevEntry, nsISHEntry* aNextEntry,
-                         nsIDocShell* aRootDocShell, long aLoadType,
-                         bool* aIsFrameFound);
+  nsresult LoadDifferingEntries(nsISHEntry* aPrevEntry, nsISHEntry* aNextEntry,
+                                nsIDocShell* aRootDocShell, long aLoadType,
+                                bool& aDifferenceFound);
   nsresult InitiateLoad(nsISHEntry* aFrameEntry, nsIDocShell* aFrameDS,
                         long aLoadType);
 
   NS_IMETHOD LoadEntry(int32_t aIndex, long aLoadType, uint32_t aHistCmd);
 
 #ifdef DEBUG
   nsresult PrintHistory();
 #endif
--- a/docshell/test/browser/browser.ini
+++ b/docshell/test/browser/browser.ini
@@ -42,16 +42,17 @@ support-files =
   browser_timelineMarkers-frame-02.js
   browser_timelineMarkers-frame-03.js
   browser_timelineMarkers-frame-04.js
   browser_timelineMarkers-frame-05.js
   head.js
   frame-head.js
 
 [browser_bug1206879.js]
+[browser_bug1309900_crossProcessHistoryNavigation.js]
 [browser_bug134911.js]
 [browser_bug234628-1.js]
 [browser_bug234628-10.js]
 [browser_bug234628-11.js]
 [browser_bug234628-2.js]
 [browser_bug234628-3.js]
 [browser_bug234628-4.js]
 [browser_bug234628-5.js]
new file mode 100644
--- /dev/null
+++ b/docshell/test/browser/browser_bug1309900_crossProcessHistoryNavigation.js
@@ -0,0 +1,35 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=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/. */
+
+add_task(function* runTests() {
+  let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:about");
+
+  registerCleanupFunction(function* () {
+    gBrowser.removeTab(tab);
+  });
+
+  let browser = tab.linkedBrowser;
+
+  browser.loadURI("about:accounts");
+  let href = yield BrowserTestUtils.browserLoaded(browser);
+  is(href, "about:accounts", "Check about:accounts loaded");
+
+  // Using a dummy onunload listener to disable the bfcache as that can prevent
+  // the test browser load detection mechanism from working.
+  browser.loadURI("data:text/html,<body%20onunload=''><iframe></iframe></body>");
+  href = yield BrowserTestUtils.browserLoaded(browser);
+  is(href, "data:text/html,<body%20onunload=''><iframe></iframe></body>",
+    "Check data URL loaded");
+
+  browser.goBack();
+  href = yield BrowserTestUtils.browserLoaded(browser);
+  is(href, "about:accounts", "Check we've gone back to about:accounts");
+
+  browser.goForward();
+  href = yield BrowserTestUtils.browserLoaded(browser);
+  is(href, "data:text/html,<body%20onunload=''><iframe></iframe></body>",
+     "Check we've gone forward to data URL");
+});
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -37,17 +37,16 @@
 #endif
 #include "mozilla/dom/PowerManager.h"
 #include "mozilla/dom/WakeLock.h"
 #include "mozilla/dom/power/PowerManagerService.h"
 #include "mozilla/dom/FlyWebPublishedServer.h"
 #include "mozilla/dom/FlyWebService.h"
 #include "mozilla/dom/IccManager.h"
 #include "mozilla/dom/InputPortManager.h"
-#include "mozilla/dom/MobileMessageManager.h"
 #include "mozilla/dom/Permissions.h"
 #include "mozilla/dom/Presentation.h"
 #include "mozilla/dom/ServiceWorkerContainer.h"
 #include "mozilla/dom/StorageManager.h"
 #include "mozilla/dom/TCPSocket.h"
 #include "mozilla/dom/Telephony.h"
 #include "mozilla/dom/VRDisplay.h"
 #include "mozilla/dom/workers/RuntimeService.h"
@@ -211,17 +210,16 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPlugins)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPermissions)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGeolocation)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNotification)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBatteryManager)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBatteryPromise)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPowerManager)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIccManager)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMobileMessageManager)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTelephony)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mInputPortManager)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConnection)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStorageManager)
 #ifdef MOZ_B2G_RIL
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMobileConnections)
 #endif
 #ifdef MOZ_B2G_BT
@@ -287,21 +285,16 @@ Navigator::Invalidate()
     mPowerManager = nullptr;
   }
 
   if (mIccManager) {
     mIccManager->Shutdown();
     mIccManager = nullptr;
   }
 
-  if (mMobileMessageManager) {
-    mMobileMessageManager->Shutdown();
-    mMobileMessageManager = nullptr;
-  }
-
   if (mTelephony) {
     mTelephony = nullptr;
   }
 
   if (mInputPortManager) {
     mInputPortManager = nullptr;
   }
 
@@ -1619,31 +1612,16 @@ Navigator::RequestWakeLock(const nsAStri
   if (!pmService) {
     aRv.Throw(NS_ERROR_UNEXPECTED);
     return nullptr;
   }
 
   return pmService->NewWakeLock(aTopic, mWindow, aRv);
 }
 
-MobileMessageManager*
-Navigator::GetMozMobileMessage()
-{
-  if (!mMobileMessageManager) {
-    // Check that our window has not gone away
-    NS_ENSURE_TRUE(mWindow, nullptr);
-    NS_ENSURE_TRUE(mWindow->GetDocShell(), nullptr);
-
-    mMobileMessageManager = new MobileMessageManager(mWindow);
-    mMobileMessageManager->Init();
-  }
-
-  return mMobileMessageManager;
-}
-
 Telephony*
 Navigator::GetMozTelephony(ErrorResult& aRv)
 {
   if (!mTelephony) {
     if (!mWindow) {
       aRv.Throw(NS_ERROR_UNEXPECTED);
       return nullptr;
     }
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -54,17 +54,16 @@ class Permissions;
 
 namespace battery {
 class BatteryManager;
 } // namespace battery
 
 class Promise;
 
 class DesktopNotificationCenter;
-class MobileMessageManager;
 class MozIdleObserver;
 #ifdef MOZ_GAMEPAD
 class Gamepad;
 class GamepadServiceTest;
 #endif // MOZ_GAMEPAD
 class NavigatorUserMediaSuccessCallback;
 class NavigatorUserMediaErrorCallback;
 class MozGetUserMediaDevicesSuccessCallback;
@@ -217,17 +216,16 @@ public:
                          ErrorResult& aRv);
 
   already_AddRefed<nsDOMDeviceStorage>
   GetDeviceStorageByNameAndType(const nsAString& aName, const nsAString& aType,
                                 ErrorResult& aRv);
 
   DesktopNotificationCenter* GetMozNotification(ErrorResult& aRv);
   IccManager* GetMozIccManager(ErrorResult& aRv);
-  MobileMessageManager* GetMozMobileMessage();
   Telephony* GetMozTelephony(ErrorResult& aRv);
   InputPortManager* GetInputPortManager(ErrorResult& aRv);
   already_AddRefed<LegacyMozTCPSocket> MozTCPSocket();
   network::Connection* GetConnection(ErrorResult& aRv);
   MediaDevices* GetMediaDevices(ErrorResult& aRv);
 
 #ifdef MOZ_B2G_RIL
   MobileConnectionArray* GetMozMobileConnections(ErrorResult& aRv);
@@ -322,17 +320,16 @@ private:
   RefPtr<nsPluginArray> mPlugins;
   RefPtr<Permissions> mPermissions;
   RefPtr<Geolocation> mGeolocation;
   RefPtr<DesktopNotificationCenter> mNotification;
   RefPtr<battery::BatteryManager> mBatteryManager;
   RefPtr<Promise> mBatteryPromise;
   RefPtr<PowerManager> mPowerManager;
   RefPtr<IccManager> mIccManager;
-  RefPtr<MobileMessageManager> mMobileMessageManager;
   RefPtr<Telephony> mTelephony;
   RefPtr<InputPortManager> mInputPortManager;
   RefPtr<network::Connection> mConnection;
 #ifdef MOZ_B2G_RIL
   RefPtr<MobileConnectionArray> mMobileConnections;
 #endif
 #ifdef MOZ_B2G_BT
   RefPtr<bluetooth::BluetoothManager> mBluetooth;
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -681,20 +681,16 @@ DOMInterfaces = {
 'MozMobileConnectionArray': {
     'nativeType': 'mozilla::dom::MobileConnectionArray',
 },
 
 'MozMobileConnectionInfo': {
     'nativeType': 'mozilla::dom::MobileConnectionInfo',
 },
 
-'MozMobileMessageManager': {
-    'nativeType': 'mozilla::dom::MobileMessageManager',
-},
-
 'MozMobileNetworkInfo': {
     'nativeType': 'mozilla::dom::MobileNetworkInfo',
 },
 
 'MozSpeakerManager': {
     'nativeType': 'mozilla::dom::SpeakerManager',
     'headerFile': 'SpeakerManager.h'
 },
--- a/dom/gamepad/GamepadManager.cpp
+++ b/dom/gamepad/GamepadManager.cpp
@@ -257,24 +257,26 @@ GamepadManager::RemoveGamepad(uint32_t a
     return;
   }
   gamepad->SetConnected(false);
   NewConnectionEvent(newIndex, false);
   mGamepads.Remove(newIndex);
 }
 
 void
-GamepadManager::NewButtonEvent(uint32_t aIndex, uint32_t aButton, bool aPressed,
-                               double aValue)
+GamepadManager::NewButtonEvent(uint32_t aIndex, GamepadServiceType aServiceType,
+                               uint32_t aButton, bool aPressed, double aValue)
 {
   if (mShuttingDown) {
     return;
   }
 
-  RefPtr<Gamepad> gamepad = GetGamepad(aIndex);
+  uint32_t newIndex = GetGamepadIndexWithServiceType(aIndex, aServiceType);
+
+  RefPtr<Gamepad> gamepad = GetGamepad(newIndex);
   if (!gamepad) {
     return;
   }
 
   gamepad->SetButton(aButton, aPressed, aValue);
 
   // Hold on to listeners in a separate array because firing events
   // can mutate the mListeners array.
@@ -286,19 +288,19 @@ GamepadManager::NewButtonEvent(uint32_t 
     MOZ_ASSERT(listeners[i]->IsInnerWindow());
 
     // Only send events to non-background windows
     if (!listeners[i]->AsInner()->IsCurrentInnerWindow() ||
         listeners[i]->GetOuterWindow()->IsBackground()) {
       continue;
     }
 
-    bool firstTime = MaybeWindowHasSeenGamepad(listeners[i], aIndex);
+    bool firstTime = MaybeWindowHasSeenGamepad(listeners[i], newIndex);
 
-    RefPtr<Gamepad> listenerGamepad = listeners[i]->GetGamepad(aIndex);
+    RefPtr<Gamepad> listenerGamepad = listeners[i]->GetGamepad(newIndex);
     if (listenerGamepad) {
       listenerGamepad->SetButton(aButton, aPressed, aValue);
       if (firstTime) {
         FireConnectionEvent(listeners[i], listenerGamepad, true);
       }
       if (mNonstandardEventsEnabled) {
         // Fire event
         FireButtonEvent(listeners[i], listenerGamepad, aButton, aValue);
@@ -325,23 +327,26 @@ GamepadManager::FireButtonEvent(EventTar
 
   event->SetTrusted(true);
 
   bool defaultActionEnabled = true;
   aTarget->DispatchEvent(event, &defaultActionEnabled);
 }
 
 void
-GamepadManager::NewAxisMoveEvent(uint32_t aIndex, uint32_t aAxis, double aValue)
+GamepadManager::NewAxisMoveEvent(uint32_t aIndex, GamepadServiceType aServiceType,
+                                 uint32_t aAxis, double aValue)
 {
   if (mShuttingDown) {
     return;
   }
 
-  RefPtr<Gamepad> gamepad = GetGamepad(aIndex);
+  uint32_t newIndex = GetGamepadIndexWithServiceType(aIndex, aServiceType);
+
+  RefPtr<Gamepad> gamepad = GetGamepad(newIndex);
   if (!gamepad) {
     return;
   }
   gamepad->SetAxis(aAxis, aValue);
 
   // Hold on to listeners in a separate array because firing events
   // can mutate the mListeners array.
   nsTArray<RefPtr<nsGlobalWindow>> listeners(mListeners);
@@ -352,19 +357,19 @@ GamepadManager::NewAxisMoveEvent(uint32_
     MOZ_ASSERT(listeners[i]->IsInnerWindow());
 
     // Only send events to non-background windows
     if (!listeners[i]->AsInner()->IsCurrentInnerWindow() ||
         listeners[i]->GetOuterWindow()->IsBackground()) {
       continue;
     }
 
-    bool firstTime = MaybeWindowHasSeenGamepad(listeners[i], aIndex);
+    bool firstTime = MaybeWindowHasSeenGamepad(listeners[i], newIndex);
 
-    RefPtr<Gamepad> listenerGamepad = listeners[i]->GetGamepad(aIndex);
+    RefPtr<Gamepad> listenerGamepad = listeners[i]->GetGamepad(newIndex);
     if (listenerGamepad) {
       listenerGamepad->SetAxis(aAxis, aValue);
       if (firstTime) {
         FireConnectionEvent(listeners[i], listenerGamepad, true);
       }
       if (mNonstandardEventsEnabled) {
         // Fire event
         FireAxisMoveEvent(listeners[i], listenerGamepad, aAxis, aValue);
@@ -587,22 +592,23 @@ GamepadManager::Update(const GamepadChan
   }
   if (aEvent.type() == GamepadChangeEvent::TGamepadRemoved) {
     const GamepadRemoved& a = aEvent.get_GamepadRemoved();
     RemoveGamepad(a.index(), a.service_type());
     return;
   }
   if (aEvent.type() == GamepadChangeEvent::TGamepadButtonInformation) {
     const GamepadButtonInformation& a = aEvent.get_GamepadButtonInformation();
-    NewButtonEvent(a.index(), a.button(), a.pressed(), a.value());
+    NewButtonEvent(a.index(), a.service_type(), a.button(),
+                   a.pressed(), a.value());
     return;
   }
   if (aEvent.type() == GamepadChangeEvent::TGamepadAxisInformation) {
     const GamepadAxisInformation& a = aEvent.get_GamepadAxisInformation();
-    NewAxisMoveEvent(a.index(), a.axis(), a.value());
+    NewAxisMoveEvent(a.index(), a.service_type(), a.axis(), a.value());
     return;
   }
 
   MOZ_CRASH("We shouldn't be here!");
 
 }
 
 //Override nsIIPCBackgroundChildCreateCallback
--- a/dom/gamepad/GamepadManager.h
+++ b/dom/gamepad/GamepadManager.h
@@ -54,23 +54,24 @@ class GamepadManager final : public nsIO
 
   // Remove the gamepad at |aIndex| from the list of known gamepads.
   void RemoveGamepad(uint32_t aIndex, GamepadServiceType aServiceType);
 
   // Update the state of |aButton| for the gamepad at |aIndex| for all
   // windows that are listening and visible, and fire one of
   // a gamepadbutton{up,down} event at them as well.
   // aPressed is used for digital buttons, aValue is for analog buttons.
-  void NewButtonEvent(uint32_t aIndex, uint32_t aButton, bool aPressed,
-                      double aValue);
+  void NewButtonEvent(uint32_t aIndex, GamepadServiceType aServiceType, uint32_t aButton,
+                      bool aPressed, double aValue);
 
   // Update the state of |aAxis| for the gamepad at |aIndex| for all
   // windows that are listening and visible, and fire a gamepadaxismove
   // event at them as well.
-  void NewAxisMoveEvent(uint32_t aIndex, uint32_t aAxis, double aValue);
+  void NewAxisMoveEvent(uint32_t aIndex, GamepadServiceType aServiceType,
+                        uint32_t aAxis, double aValue);
 
   // Synchronize the state of |aGamepad| to match the gamepad stored at |aIndex|
   void SyncGamepadState(uint32_t aIndex, Gamepad* aGamepad);
 
   // Returns gamepad object if index exists, null otherwise
   already_AddRefed<Gamepad> GetGamepad(uint32_t aIndex) const;
 
   // Receive GamepadChangeEvent messages from parent process to fire DOM events
--- a/dom/gamepad/GamepadPlatformService.cpp
+++ b/dom/gamepad/GamepadPlatformService.cpp
@@ -106,17 +106,18 @@ GamepadPlatformService::RemoveGamepad(ui
 void
 GamepadPlatformService::NewButtonEvent(uint32_t aIndex, uint32_t aButton,
                                        bool aPressed, double aValue)
 {
   // This method is called by monitor thread populated in
   // platform-dependent backends
   MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(!NS_IsMainThread());
-  GamepadButtonInformation a(aIndex, aButton, aPressed, aValue);
+  GamepadButtonInformation a(aIndex, GamepadServiceType::Standard,
+                             aButton, aPressed, aValue);
   NotifyGamepadChange<GamepadButtonInformation>(a);
 }
 
 void
 GamepadPlatformService::NewButtonEvent(uint32_t aIndex, uint32_t aButton,
                                        bool aPressed)
 {
   // This method is called by monitor thread populated in
@@ -130,17 +131,18 @@ GamepadPlatformService::NewButtonEvent(u
 void
 GamepadPlatformService::NewAxisMoveEvent(uint32_t aIndex, uint32_t aAxis,
                                          double aValue)
 {
   // This method is called by monitor thread populated in
   // platform-dependent backends
   MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(!NS_IsMainThread());
-  GamepadAxisInformation a(aIndex, aAxis, aValue);
+  GamepadAxisInformation a(aIndex, GamepadServiceType::Standard,
+                           aAxis, aValue);
   NotifyGamepadChange<GamepadAxisInformation>(a);
 }
 
 void
 GamepadPlatformService::ResetGamepadIndexes()
 {
   // This method is called by monitor thread populated in
   // platform-dependent backends
--- a/dom/gamepad/GamepadServiceTest.cpp
+++ b/dom/gamepad/GamepadServiceTest.cpp
@@ -170,17 +170,18 @@ void
 GamepadServiceTest::NewButtonEvent(uint32_t aIndex,
                                    uint32_t aButton,
                                    bool aPressed)
 {
   if (mShuttingDown) {
     return;
   }
 
-  GamepadButtonInformation a(aIndex, aButton, aPressed, aPressed ? 1.0 : 0);
+  GamepadButtonInformation a(aIndex, GamepadServiceType::Standard,
+                             aButton, aPressed, aPressed ? 1.0 : 0);
   GamepadChangeEvent e(a);
 
   uint32_t id = ++mEventNumber;
   if (mChild) {
     mChild->SendGamepadTestEvent(id, e);
   } else {
     PendingOperation op(id, e);
     mPendingOperations.AppendElement(op);
@@ -192,17 +193,18 @@ GamepadServiceTest::NewButtonValueEvent(
                                         uint32_t aButton,
                                         bool aPressed,
                                         double aValue)
 {
   if (mShuttingDown) {
     return;
   }
 
-  GamepadButtonInformation a(aIndex, aButton, aPressed, aValue);
+  GamepadButtonInformation a(aIndex, GamepadServiceType::Standard,
+                             aButton, aPressed, aValue);
   GamepadChangeEvent e(a);
 
   uint32_t id = ++mEventNumber;
   if (mChild) {
     mChild->SendGamepadTestEvent(id, e);
   } else {
     PendingOperation op(id, e);
     mPendingOperations.AppendElement(op);
@@ -213,17 +215,18 @@ void
 GamepadServiceTest::NewAxisMoveEvent(uint32_t aIndex,
                                      uint32_t aAxis,
                                      double aValue)
 {
   if (mShuttingDown) {
     return;
   }
 
-  GamepadAxisInformation a(aIndex, aAxis, aValue);
+  GamepadAxisInformation a(aIndex, GamepadServiceType::Standard,
+                           aAxis, aValue);
   GamepadChangeEvent e(a);
 
   uint32_t id = ++mEventNumber;
   if (mChild) {
     mChild->SendGamepadTestEvent(id, e);
   } else {
     PendingOperation op(id, e);
     mPendingOperations.AppendElement(op);
--- a/dom/gamepad/ipc/GamepadEventTypes.ipdlh
+++ b/dom/gamepad/ipc/GamepadEventTypes.ipdlh
@@ -20,22 +20,24 @@ struct GamepadAdded {
 
 struct GamepadRemoved {
   uint32_t index;
   GamepadServiceType service_type;
 };
 
 struct GamepadAxisInformation {
   uint32_t index;
+  GamepadServiceType service_type;
   uint32_t axis;
   double value;
 };
 
 struct GamepadButtonInformation {
   uint32_t index;
+  GamepadServiceType service_type;
   uint32_t button;
   bool pressed;
   double value;
 };
 
 union GamepadChangeEvent {
   GamepadAdded;
   GamepadRemoved;
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -973,17 +973,17 @@ void HTMLMediaElement::AbortExistingLoad
   mSuspendedAfterFirstFrame = false;
   mAllowSuspendAfterFirstFrame = true;
   mHaveQueuedSelectResource = false;
   mSuspendedForPreloadNone = false;
   mDownloadSuspendedByCache = false;
   mMediaInfo = MediaInfo();
   mIsEncrypted = false;
   mPendingEncryptedInitData.mInitDatas.Clear();
-  mWaitingForKey = false;
+  mWaitingForKey = NOT_WAITING_FOR_KEY;
   mSourcePointer = nullptr;
 
   mTags = nullptr;
 
   if (mNetworkState != nsIDOMHTMLMediaElement::NETWORK_EMPTY) {
     NS_ASSERTION(!mDecoder && !mSrcStream, "How did someone setup a new stream/decoder already?");
     // ChangeNetworkState() will call UpdateAudioChannelPlayingState()
     // indirectly which depends on mPaused. So we need to update mPaused first.
@@ -2205,21 +2205,25 @@ public:
                                            MediaStreamTrackSource)
 
   explicit StreamCaptureTrackSource(MediaStreamTrackSource* aCapturedTrackSource)
     : MediaStreamTrackSource(aCapturedTrackSource->GetPrincipal(),
                              true,
                              nsString())
     , mCapturedTrackSource(aCapturedTrackSource)
   {
+    mCapturedTrackSource->RegisterSink(this);
   }
 
   void Destroy() override
   {
     MOZ_ASSERT(mCapturedTrackSource);
+    if (mCapturedTrackSource) {
+      mCapturedTrackSource->UnregisterSink(this);
+    }
   }
 
   MediaSourceEnum GetMediaSource() const override
   {
     return MediaSourceEnum::Other;
   }
 
   CORSMode GetCORSMode() const override
@@ -2882,17 +2886,17 @@ HTMLMediaElement::HTMLMediaElement(alrea
     mHasPlayedOrSeeked(false),
     mHasSelfReference(false),
     mShuttingDown(false),
     mSuspendedForPreloadNone(false),
     mSrcStreamIsPlaying(false),
     mMediaSecurityVerified(false),
     mCORSMode(CORS_NONE),
     mIsEncrypted(false),
-    mWaitingForKey(false),
+    mWaitingForKey(NOT_WAITING_FOR_KEY),
     mDownloadSuspendedByCache(false, "HTMLMediaElement::mDownloadSuspendedByCache"),
     mAudioChannelVolume(1.0),
     mPlayingThroughTheAudioChannel(false),
     mDisableVideo(false),
     mHasUserInteraction(false),
     mFirstFrameLoaded(false),
     mDefaultPlaybackStartPosition(0.0),
     mIsAudioTrackAudible(false),
@@ -4345,16 +4349,19 @@ void HTMLMediaElement::MetadataLoaded(co
         }
       }
     }
   }
 }
 
 void HTMLMediaElement::FirstFrameLoaded()
 {
+  LOG(LogLevel::Debug, ("%p, FirstFrameLoaded() mFirstFrameLoaded=%d mWaitingForKey=%d",
+      this, mFirstFrameLoaded, mWaitingForKey));
+
   NS_ASSERTION(!mSuspendedAfterFirstFrame, "Should not have already suspended");
 
   if (!mFirstFrameLoaded) {
     mFirstFrameLoaded = true;
     UpdateReadyStateInternal();
   }
 
   ChangeDelayLoadStatus(false);
@@ -4700,18 +4707,36 @@ HTMLMediaElement::UpdateReadyStateIntern
     }
     if (hasVideoTracks) {
       mediaInfo.EnableVideo();
     }
     MetadataLoaded(&mediaInfo, nsAutoPtr<const MetadataTags>(nullptr));
   }
 
   enum NextFrameStatus nextFrameStatus = NextFrameStatus();
-  if (mDecoder && nextFrameStatus == NEXT_FRAME_UNAVAILABLE) {
-    nextFrameStatus = mDecoder->NextFrameBufferedStatus();
+  if (nextFrameStatus == NEXT_FRAME_UNAVAILABLE) {
+    if (mWaitingForKey != NOT_WAITING_FOR_KEY) {
+      // http://w3c.github.io/encrypted-media/#wait-for-key
+      // Continuing 7.3.4 Queue a "waitingforkey" Event
+      // 4. Queue a task to fire a simple event named waitingforkey
+      // at the media element.
+      if (mWaitingForKey == WAITING_FOR_KEY) {
+        mWaitingForKey = WAITING_FOR_KEY_DISPATCHED;
+        DispatchAsyncEvent(NS_LITERAL_STRING("waitingforkey"));
+      }
+      // 5. Set the readyState of media element to HAVE_METADATA.
+      // NOTE: We'll change to HAVE_CURRENT_DATA or HAVE_METADATA
+      // depending on whether we've loaded the first frame or not
+      // below.
+      // 6. Suspend playback.
+      // Note: Playback will already be stalled, as the next frame is
+      // unavailable.
+    } else if (mDecoder) {
+      nextFrameStatus = mDecoder->NextFrameBufferedStatus();
+    }
   }
 
   if (nextFrameStatus == MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_SEEKING) {
     LOG(LogLevel::Debug, ("MediaElement %p UpdateReadyStateInternal() "
                           "NEXT_FRAME_UNAVAILABLE_SEEKING; Forcing HAVE_METADATA", this));
     ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA);
     return;
   }
@@ -4836,17 +4861,17 @@ void HTMLMediaElement::ChangeReadyState(
     DispatchAsyncEvent(NS_LITERAL_STRING("loadeddata"));
     mLoadedDataFired = true;
   }
 
   if (oldState < nsIDOMHTMLMediaElement::HAVE_FUTURE_DATA &&
       mReadyState >= nsIDOMHTMLMediaElement::HAVE_FUTURE_DATA) {
     DispatchAsyncEvent(NS_LITERAL_STRING("canplay"));
     if (!mPaused) {
-      mWaitingForKey = false;
+      mWaitingForKey = NOT_WAITING_FOR_KEY;
       DispatchAsyncEvent(NS_LITERAL_STRING("playing"));
     }
   }
 
   CheckAutoplayDataReady();
 
   if (oldState < nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA &&
       mReadyState >= nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA) {
@@ -6229,31 +6254,28 @@ HTMLMediaElement::GetTopLevelPrincipal()
   }
   principal = doc->NodePrincipal();
   return principal.forget();
 }
 
 void
 HTMLMediaElement::CannotDecryptWaitingForKey()
 {
-  // See: http://w3c.github.io/encrypted-media/#dom-evt-waitingforkey
-  // Spec: 7.5.4 Queue a "waitingforkey" Event
-  // Spec: 1. Let the media element be the specified HTMLMediaElement object.
-
-  // Note, existing code will handle the ready state of this element, as
-  // such this function does not handle changing or checking mReadyState.
-
-  // Spec: 2. If the media element's waiting for key value is true, abort these steps.
-  if (!mWaitingForKey) {
-    // Spec: 3. Set the media element's waiting for key value to true.
-    // Spec: 4. Queue a task to fire a simple event named waitingforkey at the media element.
-    DispatchAsyncEvent(NS_LITERAL_STRING("waitingforkey"));
-    mWaitingForKey = true;
-    // No need to explicitly suspend playback, it happens automatically when
-    // it's starving for decoded frames.
+  LOG(LogLevel::Debug, ("%p, CannotDecryptWaitingForKey()", this));
+
+  // http://w3c.github.io/encrypted-media/#wait-for-key
+  // 7.3.4 Queue a "waitingforkey" Event
+  // 1. Let the media element be the specified HTMLMediaElement object.
+  // 2. If the media element's waiting for key value is true, abort these steps.
+  if (mWaitingForKey == NOT_WAITING_FOR_KEY) {
+    // 3. Set the media element's waiting for key value to true.
+    // Note: algorithm continues in UpdateReadyStateInternal() when all decoded
+    // data enqueued in the MDSM is consumed.
+    mWaitingForKey = WAITING_FOR_KEY;
+    UpdateReadyStateInternal();
   }
 }
 
 NS_IMETHODIMP HTMLMediaElement::WindowAudioCaptureChanged(bool aCapture)
 {
   MOZ_ASSERT(mAudioChannelAgent);
 
   if (mAudioCapturedByWindow != aCapture) {
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -1584,20 +1584,26 @@ protected:
   CORSMode mCORSMode;
 
   // Info about the played media.
   MediaInfo mMediaInfo;
 
   // True if the media has encryption information.
   bool mIsEncrypted;
 
-  // True when the CDM cannot decrypt the current block, and the
-  // waitingforkey event has been fired. Back to false when keys have become
-  // available and we can advance the current playback position.
-  bool mWaitingForKey;
+  enum WaitingForKeyState {
+    NOT_WAITING_FOR_KEY = 0,
+    WAITING_FOR_KEY = 1,
+    WAITING_FOR_KEY_DISPATCHED = 2
+  };
+
+  // True when the CDM cannot decrypt the current block due to lacking a key.
+  // Note: the "waitingforkey" event is not dispatched until all decoded data
+  // has been rendered.
+  WaitingForKeyState mWaitingForKey;
 
   // Listens for waitingForKey events from the owned decoder.
   MediaEventListener mWaitingForKeyListener;
 
   // Init Data that needs to be sent in 'encrypted' events in MetadataLoaded().
   EncryptionInfo mPendingEncryptedInitData;
 
   // True if the media's channel's download has been suspended.
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -167,17 +167,16 @@
 
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/icc/IccChild.h"
 #include "mozilla/dom/mobileconnection/MobileConnectionChild.h"
-#include "mozilla/dom/mobilemessage/SmsChild.h"
 #include "mozilla/dom/devicestorage/DeviceStorageRequestChild.h"
 #include "mozilla/dom/bluetooth/PBluetoothChild.h"
 #include "mozilla/dom/PPresentationChild.h"
 #include "mozilla/dom/PresentationIPCService.h"
 #include "mozilla/ipc/InputStreamUtils.h"
 
 #ifdef MOZ_WEBSPEECH
 #include "mozilla/dom/PSpeechSynthesisChild.h"
@@ -203,17 +202,16 @@
 
 using namespace mozilla;
 using namespace mozilla::docshell;
 using namespace mozilla::dom::bluetooth;
 using namespace mozilla::dom::devicestorage;
 using namespace mozilla::dom::icc;
 using namespace mozilla::dom::ipc;
 using namespace mozilla::dom::mobileconnection;
-using namespace mozilla::dom::mobilemessage;
 using namespace mozilla::dom::telephony;
 using namespace mozilla::dom::workers;
 using namespace mozilla::media;
 using namespace mozilla::embedding;
 using namespace mozilla::gmp;
 using namespace mozilla::hal_sandbox;
 using namespace mozilla::ipc;
 using namespace mozilla::layers;
@@ -1972,29 +1970,16 @@ ContentChild::AllocPHandlerServiceChild(
 }
 
 bool ContentChild::DeallocPHandlerServiceChild(PHandlerServiceChild* aHandlerServiceChild)
 {
   static_cast<HandlerServiceChild*>(aHandlerServiceChild)->Release();
   return true;
 }
 
-PSmsChild*
-ContentChild::AllocPSmsChild()
-{
-  return new SmsChild();
-}
-
-bool
-ContentChild::DeallocPSmsChild(PSmsChild* aSms)
-{
-  delete aSms;
-  return true;
-}
-
 PTelephonyChild*
 ContentChild::AllocPTelephonyChild()
 {
   MOZ_CRASH("No one should be allocating PTelephonyChild actors");
 }
 
 bool
 ContentChild::DeallocPTelephonyChild(PTelephonyChild* aActor)
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -330,20 +330,16 @@ public:
 
   virtual bool
   DeallocPExternalHelperAppChild(PExternalHelperAppChild *aService) override;
 
   virtual PHandlerServiceChild* AllocPHandlerServiceChild() override;
 
   virtual bool DeallocPHandlerServiceChild(PHandlerServiceChild*) override;
 
-  virtual PSmsChild* AllocPSmsChild() override;
-
-  virtual bool DeallocPSmsChild(PSmsChild*) override;
-
   virtual PTelephonyChild* AllocPTelephonyChild() override;
 
   virtual bool DeallocPTelephonyChild(PTelephonyChild*) override;
 
   virtual PMediaChild* AllocPMediaChild() override;
 
   virtual bool DeallocPMediaChild(PMediaChild* aActor) override;
 
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -56,17 +56,16 @@
 #include "mozilla/dom/PContentPermissionRequestParent.h"
 #include "mozilla/dom/PCycleCollectWithLogsParent.h"
 #include "mozilla/dom/PMemoryReportRequestParent.h"
 #include "mozilla/dom/ServiceWorkerRegistrar.h"
 #include "mozilla/dom/bluetooth/PBluetoothParent.h"
 #include "mozilla/dom/devicestorage/DeviceStorageRequestParent.h"
 #include "mozilla/dom/icc/IccParent.h"
 #include "mozilla/dom/mobileconnection/MobileConnectionParent.h"
-#include "mozilla/dom/mobilemessage/SmsParent.h"
 #include "mozilla/dom/power/PowerManagerService.h"
 #include "mozilla/dom/Permissions.h"
 #include "mozilla/dom/PresentationParent.h"
 #include "mozilla/dom/PPresentationParent.h"
 #include "mozilla/dom/PushNotifier.h"
 #include "mozilla/dom/FlyWebPublishedServerIPC.h"
 #include "mozilla/dom/quota/QuotaManagerService.h"
 #include "mozilla/dom/telephony/TelephonyParent.h"
@@ -287,17 +286,16 @@ using mozilla::ProfileGatherer;
 #ifdef MOZ_CRASHREPORTER
 using namespace CrashReporter;
 #endif
 using namespace mozilla::dom::bluetooth;
 using namespace mozilla::dom::devicestorage;
 using namespace mozilla::dom::icc;
 using namespace mozilla::dom::power;
 using namespace mozilla::dom::mobileconnection;
-using namespace mozilla::dom::mobilemessage;
 using namespace mozilla::dom::telephony;
 using namespace mozilla::media;
 using namespace mozilla::embedding;
 using namespace mozilla::gfx;
 using namespace mozilla::gmp;
 using namespace mozilla::hal;
 using namespace mozilla::ipc;
 using namespace mozilla::layers;
@@ -3427,35 +3425,16 @@ ContentParent::AllocPHandlerServiceParen
 
 bool
 ContentParent::DeallocPHandlerServiceParent(PHandlerServiceParent* aHandlerServiceParent)
 {
   static_cast<HandlerServiceParent*>(aHandlerServiceParent)->Release();
   return true;
 }
 
-PSmsParent*
-ContentParent::AllocPSmsParent()
-{
-  if (!AssertAppProcessPermission(this, "sms")) {
-    return nullptr;
-  }
-
-  SmsParent* parent = new SmsParent();
-  parent->AddRef();
-  return parent;
-}
-
-bool
-ContentParent::DeallocPSmsParent(PSmsParent* aSms)
-{
-  static_cast<SmsParent*>(aSms)->Release();
-  return true;
-}
-
 PTelephonyParent*
 ContentParent::AllocPTelephonyParent()
 {
   if (!AssertAppProcessPermission(this, "telephony")) {
     return nullptr;
   }
 
   TelephonyParent* actor = new TelephonyParent();
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -838,20 +838,16 @@ private:
 
   virtual bool
   DeallocPExternalHelperAppParent(PExternalHelperAppParent* aService) override;
 
   virtual PHandlerServiceParent* AllocPHandlerServiceParent() override;
 
   virtual bool DeallocPHandlerServiceParent(PHandlerServiceParent*) override;
 
-  virtual PSmsParent* AllocPSmsParent() override;
-
-  virtual bool DeallocPSmsParent(PSmsParent*) override;
-
   virtual PTelephonyParent* AllocPTelephonyParent() override;
 
   virtual bool DeallocPTelephonyParent(PTelephonyParent*) override;
 
   virtual PMediaParent* AllocPMediaParent() override;
 
   virtual bool DeallocPMediaParent(PMediaParent* aActor) override;
 
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -37,17 +37,16 @@ include protocol PGMPService;
 include protocol PPluginModule;
 include protocol PGMP;
 include protocol PPrinting;
 include protocol PSendStream;
 include protocol POfflineCacheUpdate;
 include protocol PRenderFrame;
 include protocol PScreenManager;
 include protocol PSharedBufferManager;
-include protocol PSms;
 include protocol PSpeechSynthesis;
 include protocol PStorage;
 include protocol PTelephony;
 include protocol PTestShell;
 include protocol PJavaScript;
 include protocol PRemoteSpellcheckEngine;
 include protocol PWebBrowserPersistDocument;
 include protocol PWebrtcGlobal;
@@ -366,17 +365,16 @@ nested(upto inside_cpow) sync protocol P
     manages PMedia;
     manages PMemoryReportRequest;
     manages PMobileConnection;
     manages PNecko;
     manages POfflineCacheUpdate;
     manages PPrinting;
     manages PSendStream;
     manages PScreenManager;
-    manages PSms;
     manages PSpeechSynthesis;
     manages PStorage;
     manages PTelephony;
     manages PTestShell;
     manages PJavaScript;
     manages PRemoteSpellcheckEngine;
     manages PWebBrowserPersistDocument;
     manages PWebrtcGlobal;
@@ -812,18 +810,16 @@ parent:
 
     async PSendStream();
 
     nested(inside_sync) sync PScreenManager()
         returns (uint32_t numberOfScreens,
                  float systemDefaultScale,
                  bool success);
 
-    async PSms();
-
     async PSpeechSynthesis();
 
     nested(inside_cpow) async PStorage();
 
     async PTelephony();
 
     async PMedia();
 
--- a/dom/ipc/moz.build
+++ b/dom/ipc/moz.build
@@ -127,17 +127,16 @@ LOCAL_INCLUDES += [
     '/dom/base',
     '/dom/bluetooth/common',
     '/dom/bluetooth/ipc',
     '/dom/devicestorage',
     '/dom/events',
     '/dom/filesystem',
     '/dom/geolocation',
     '/dom/media/webspeech/synth/ipc',
-    '/dom/mobilemessage/ipc',
     '/dom/security',
     '/dom/storage',
     '/dom/workers',
     '/embedding/components/printingui/ipc',
     '/extensions/cookie',
     '/extensions/spellcheck/src',
     '/gfx/2d',
     '/hal/sandbox',
--- a/dom/media/MediaStreamTrack.cpp
+++ b/dom/media/MediaStreamTrack.cpp
@@ -383,49 +383,26 @@ MediaStreamTrack::Clone()
   MediaStreamGraph* graph = Graph();
   newStream->InitOwnedStreamCommon(graph);
   newStream->InitPlaybackStreamCommon(graph);
 
   return newStream->CloneDOMTrack(*this, mTrackID);
 }
 
 void
-MediaStreamTrack::SetReadyState(MediaStreamTrackState aState)
-{
-  MOZ_ASSERT(!(mReadyState == MediaStreamTrackState::Ended &&
-               aState == MediaStreamTrackState::Live),
-             "We don't support overriding the ready state from ended to live");
-
-  if (mReadyState == MediaStreamTrackState::Live &&
-      aState == MediaStreamTrackState::Ended &&
-      mSource) {
-    mSource->UnregisterSink(this);
-  }
-
-  mReadyState = aState;
-}
-
-void
 MediaStreamTrack::NotifyEnded()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (Ended()) {
     return;
   }
 
   LOG(LogLevel::Info, ("MediaStreamTrack %p ended", this));
 
-  if (!mSource) {
-    MOZ_ASSERT(false);
-    return;
-  }
-
-  mSource->UnregisterSink(this);
-
   mReadyState = MediaStreamTrackState::Ended;
 
   DispatchTrustedEvent(NS_LITERAL_STRING("ended"));
 }
 
 DOMMediaStream*
 MediaStreamTrack::GetInputDOMStream()
 {
--- a/dom/media/MediaStreamTrack.h
+++ b/dom/media/MediaStreamTrack.h
@@ -292,17 +292,17 @@ public:
    * Convenience (and legacy) method for when ready state is "ended".
    */
   bool Ended() const { return mReadyState == MediaStreamTrackState::Ended; }
 
   /**
    * Forces the ready state to a particular value, for instance when we're
    * cloning an already ended track.
    */
-  void SetReadyState(MediaStreamTrackState aState);
+  void SetReadyState(MediaStreamTrackState aState) { mReadyState = aState; }
 
   /**
    * Notified by the MediaStreamGraph, through our owning MediaStream on the
    * main thread.
    *
    * Note that this sets the track to ended and raises the "ended" event
    * synchronously.
    */
--- a/dom/media/eme/MediaKeySession.cpp
+++ b/dom/media/eme/MediaKeySession.cpp
@@ -377,26 +377,39 @@ MediaKeySession::Load(const nsAString& a
   if (aSessionId.IsEmpty()) {
     promise->MaybeReject(NS_ERROR_DOM_TYPE_ERR,
                          NS_LITERAL_CSTRING("Trying to load a session with empty session ID"));
     // "The sessionId parameter is empty."
     EME_LOG("MediaKeySession[%p,''] Load() failed, no sessionId", this);
     return promise.forget();
   }
 
+  // 5. If the result of running the Is persistent session type? algorithm
+  // on this object's session type is false, return a promise rejected with
+  // a newly created TypeError.
+  if (mSessionType == MediaKeySessionType::Temporary) {
+    promise->MaybeReject(NS_ERROR_DOM_TYPE_ERR,
+                         NS_LITERAL_CSTRING("Trying to load() into a non-persistent session"));
+    EME_LOG("MediaKeySession[%p,''] Load() failed, can't load in a non-persistent session", this);
+    return promise.forget();
+  }
+
+  // Note: We don't support persistent sessions in any keysystem, so all calls
+  // to Load() should reject with a TypeError in the preceding check. Omitting
+  // implementing the rest of the specified MediaKeySession::Load() algorithm.
+
   // We now know the sessionId being loaded into this session. Remove the
   // session from its owning MediaKey's set of sessions awaiting a sessionId.
   RefPtr<MediaKeySession> session(mKeys->GetPendingSession(Token()));
   MOZ_ASSERT(session == this, "Session should be awaiting id on its own token");
 
   // Associate with the known sessionId.
   SetSessionId(aSessionId);
 
   PromiseId pid = mKeys->StorePromise(promise);
-  mKeys->ConnectPendingPromiseIdWithToken(pid, Token());
   mKeys->GetCDMProxy()->LoadSession(pid, aSessionId);
 
   EME_LOG("MediaKeySession[%p,'%s'] Load() sent to CDM, promiseId=%d",
     this, NS_ConvertUTF16toUTF8(mSessionId).get(), pid);
 
   return promise.forget();
 }
 
--- a/dom/media/eme/MediaKeys.cpp
+++ b/dom/media/eme/MediaKeys.cpp
@@ -194,18 +194,17 @@ MediaKeys::StorePromise(DetailedPromise*
 
   mPromises.Put(id, aPromise);
   return id;
 }
 
 void
 MediaKeys::ConnectPendingPromiseIdWithToken(PromiseId aId, uint32_t aToken)
 {
-  // Should only be called from MediaKeySession::GenerateRequest and
-  // MediaKeySession::Load.
+  // Should only be called from MediaKeySession::GenerateRequest.
   mPromiseIdToken.Put(aId, aToken);
   EME_LOG("MediaKeys[%p]::ConnectPendingPromiseIdWithToken() id=%u => token(%u)",
           this, aId, aToken);
 }
 
 already_AddRefed<DetailedPromise>
 MediaKeys::RetrievePromise(PromiseId aId)
 {
--- a/dom/media/eme/MediaKeys.h
+++ b/dom/media/eme/MediaKeys.h
@@ -103,19 +103,21 @@ public:
   // Makes a new promise, or nullptr on failure.
   already_AddRefed<DetailedPromise> MakePromise(ErrorResult& aRv,
                                                 const nsACString& aName);
   // Stores promise in mPromises, returning an ID that can be used to retrieve
   // it later. The ID is passed to the CDM, so that it can signal specific
   // promises to be resolved.
   PromiseId StorePromise(DetailedPromise* aPromise);
 
-  // Stores a map for promise id and session token, and it will be used to
-  // remove the pending sessions by promise id while creating/loading various
-  // sessions in the same time.
+  // Stores a map from promise id to pending session token. Using this
+  // mapping, when a promise is rejected via its ID, we can check if the
+  // promise corresponds to a pending session and retrieve that session
+  // via the mapped-to token, and remove the pending session from the
+  // list of sessions awaiting a session id.
   void ConnectPendingPromiseIdWithToken(PromiseId aId, uint32_t aToken);
 
   // Reject promise with DOMException corresponding to aExceptionCode.
   void RejectPromise(PromiseId aId, nsresult aExceptionCode,
                      const nsCString& aReason);
   // Resolves promise with "undefined".
   void ResolvePromise(PromiseId aId);
 
--- a/dom/media/tests/mochitest/mediaStreamPlayback.js
+++ b/dom/media/tests/mochitest/mediaStreamPlayback.js
@@ -27,21 +27,21 @@ MediaStreamPlayback.prototype = {
 
    /**
    * Starts media element with a media stream, runs it until a canplaythrough
    * and timeupdate event fires, and calls stop() on all its tracks.
    *
    * @param {Boolean} isResume specifies if this media element is being resumed
    *                           from a previous run
    */
-  playMedia : function(isResume) {
+  playMediaWithMediaStreamTracksStop : function(isResume) {
     this.startMedia(isResume);
     return this.verifyPlaying()
       .then(() => this.stopTracksForStreamInMediaPlayback())
-      .then(() => this.detachFromMediaElement());
+      .then(() => this.stopMediaElement());
   },
 
   /**
    * Stops the local media stream's tracks while it's currently in playback in
    * a media element.
    *
    * Precondition: The media stream and element should both be actively
    *               being played. All the stream's tracks must be local.
@@ -75,25 +75,25 @@ MediaStreamPlayback.prototype = {
     this.mediaStream.stop();
     return timeout(waitForEnded(), ENDED_TIMEOUT_LENGTH, "ended event never fired")
              .then(() => ok(true, "ended event successfully fired"))
              .then(() => noTrackEnded);
   },
 
   /**
    * Starts media with a media stream, runs it until a canplaythrough and
-   * timeupdate event fires, and detaches from the element without stopping media.
+   * timeupdate event fires, and stops the media.
    *
    * @param {Boolean} isResume specifies if this media element is being resumed
    *                           from a previous run
    */
-  playMediaWithoutStoppingTracks : function(isResume) {
+  playMedia : function(isResume) {
     this.startMedia(isResume);
     return this.verifyPlaying()
-      .then(() => this.detachFromMediaElement());
+      .then(() => this.stopMediaElement());
   },
 
   /**
    * Starts the media with the associated stream.
    *
    * @param {Boolean} isResume specifies if the media element playback
    *                           is being resumed from a previous run
    */
@@ -151,22 +151,22 @@ MediaStreamPlayback.prototype = {
         is(this.mediaElement.preload, "", "Preload should not exist");
         is(this.mediaElement.src, "", "No src should be defined");
         is(this.mediaElement.currentSrc, "",
            "Current src should still be an empty string");
       });
   },
 
   /**
-   * Detaches from the element without stopping the media.
+   * Stops the media with the associated stream.
    *
    * Precondition: The media stream and element should both be actively
    *               being played.
    */
-  detachFromMediaElement : function() {
+  stopMediaElement : function() {
     this.mediaElement.pause();
     this.mediaElement.srcObject = null;
   }
 }
 
 
 /**
  * This class is basically the same as MediaStreamPlayback except
@@ -193,17 +193,17 @@ LocalMediaStreamPlayback.prototype = Obj
    * @param {Boolean} isResume specifies if this media element is being resumed
    *                           from a previous run
    */
   playMediaWithDeprecatedStreamStop : {
     value: function(isResume) {
       this.startMedia(isResume);
       return this.verifyPlaying()
         .then(() => this.deprecatedStopStreamInMediaPlayback())
-        .then(() => this.detachFromMediaElement());
+        .then(() => this.stopMediaElement());
     }
   },
 
   /**
    * DEPRECATED - MediaStream.stop() is going away. Use MediaStreamTrack.stop()!
    *
    * Stops the local media stream while it's currently in playback in
    * a media element.
@@ -249,28 +249,11 @@ var scriptsReady = Promise.all([
   document.head.appendChild(el);
   return new Promise(r => el.onload = r);
 }));
 
 function createHTML(options) {
   return scriptsReady.then(() => realCreateHTML(options));
 }
 
-var pushPrefs = (...p) => new Promise(r => SpecialPowers.pushPrefEnv({set: p}, r));
-
-// noGum - Helper to detect whether active guM tracks still exist.
-//
-// It relies on the fact that, by spec, device labels from enumerateDevices are
-// only visible during active gum calls. They're also visible when persistent
-// permissions are granted, so turn off media.navigator.permission.disabled
-// (which is normally on otherwise in our tests). Lastly, we must turn on
-// media.navigator.permission.fake otherwise fake devices don't count as active.
-
-var noGum = () => pushPrefs(["media.navigator.permission.disabled", false],
-                            ["media.navigator.permission.fake", true])
-  .then(() => navigator.mediaDevices.enumerateDevices())
-  .then(([device]) => device &&
-      is(device.label, "", "Test must leave no active gUM streams behind."));
-
 var runTest = testFunction => scriptsReady
   .then(() => runTestWhenReady(testFunction))
-  .then(() => noGum())
   .then(() => finish());
--- a/dom/media/tests/mochitest/mochitest.ini
+++ b/dom/media/tests/mochitest/mochitest.ini
@@ -75,17 +75,16 @@ skip-if = android_version == '18' # andr
 [test_getUserMedia_playVideoTwice.html]
 [test_getUserMedia_spinEventLoop.html]
 [test_getUserMedia_stopAudioStream.html]
 [test_getUserMedia_stopAudioStreamWithFollowupAudio.html]
 [test_getUserMedia_stopVideoAudioStream.html]
 [test_getUserMedia_stopVideoAudioStreamWithFollowupVideoAudio.html]
 [test_getUserMedia_stopVideoStream.html]
 [test_getUserMedia_stopVideoStreamWithFollowupVideo.html]
-[test_getUserMedia_trackCloneCleanup.html]
 [test_getUserMedia_trackEnded.html]
 [test_getUserMedia_peerIdentity.html]
 [test_peerConnection_addIceCandidate.html]
 [test_peerConnection_addtrack_removetrack_events.html]
 skip-if = android_version == '18' # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_peerConnection_basicAudio.html]
 skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_peerConnection_basicAudioNATSrflx.html]
--- a/dom/media/tests/mochitest/test_getUserMedia_addTrackRemoveTrack.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_addTrackRemoveTrack.html
@@ -23,33 +23,33 @@
         stream.addTrack(track);
         checkMediaStreamContains(stream, [track], "Re-added audio");
 
         stream.addTrack(otherTrack);
         checkMediaStreamContains(stream, [track, otherTrack], "Added video");
 
         var testElem = createMediaElement('video', 'testAddTrackAudioVideo');
         var playback = new LocalMediaStreamPlayback(testElem, stream);
-        return playback.playMedia(false);
+        return playback.playMediaWithMediaStreamTracksStop(false);
     }))
     .then(() => getUserMedia({video: true})).then(stream =>
       getUserMedia({video: true}).then(otherStream => {
         info("Test addTrack()ing a video track to a video-only gUM stream");
         var track = stream.getTracks()[0];
         var otherTrack = otherStream.getTracks()[0];
 
         stream.addTrack(track);
         checkMediaStreamContains(stream, [track], "Re-added video");
 
         stream.addTrack(otherTrack);
         checkMediaStreamContains(stream, [track, otherTrack], "Added video");
 
         var test = createMediaElement('video', 'testAddTrackDoubleVideo');
         var playback = new LocalMediaStreamPlayback(test, stream);
-        return playback.playMedia(false);
+        return playback.playMediaWithMediaStreamTracksStop(false);
     }))
     .then(() => getUserMedia({video: true})).then(stream =>
       getUserMedia({video: true}).then(otherStream => {
         info("Test removeTrack() existing and added video tracks from a video-only gUM stream");
         var track = stream.getTracks()[0];
         var otherTrack = otherStream.getTracks()[0];
 
         stream.removeTrack(otherTrack);
@@ -76,17 +76,17 @@
           ok(!loadeddata, "Stream without tracks shall not raise 'loadeddata' on media element");
           elem.pause();
           elem.srcObject = null;
         })
         .then(() => {
           stream.addTrack(track);
           checkMediaStreamContains(stream, [track], "Re-added added-then-removed track");
           var playback = new LocalMediaStreamPlayback(elem, stream);
-          return playback.playMedia(false);
+          return playback.playMediaWithMediaStreamTracksStop(false);
         })
         .then(() => otherTrack.stop());
     }))
     .then(() => getUserMedia({ audio: true })).then(audioStream =>
       getUserMedia({ video: true }).then(videoStream => {
         info("Test adding track and removing the original");
         var audioTrack = audioStream.getTracks()[0];
         var videoTrack = videoStream.getTracks()[0];
@@ -94,17 +94,17 @@
         audioStream.addTrack(videoTrack);
 
         checkMediaStreamContains(videoStream, [], "1, Removed original track");
         checkMediaStreamContains(audioStream, [audioTrack, videoTrack],
                                  "2, Added external track");
 
         var elem = createMediaElement('video', 'testAddRemoveOriginalTrackVideo');
         var playback = new LocalMediaStreamPlayback(elem, audioStream);
-        return playback.playMedia(false);
+        return playback.playMediaWithMediaStreamTracksStop(false);
       }))
     .then(() => {
       var ac = new AudioContext();
 
       var osc1k = createOscillatorStream(ac, 1000);
       var audioTrack1k = osc1k.getTracks()[0];
 
       var osc5k = createOscillatorStream(ac, 5000);
--- a/dom/media/tests/mochitest/test_getUserMedia_addtrack_removetrack_events.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_addtrack_removetrack_events.html
@@ -13,17 +13,16 @@ createHTML({
   bug: "1208328"
 });
 
 var spinEventLoop = () => new Promise(r => setTimeout(r, 0));
 
 var stream;
 var clone;
 var newStream;
-var tracks = [];
 
 var addTrack = track => {
   info("Adding track " + track.id);
   stream.addTrack(track);
 };
 var removeTrack = track => {
   info("Removing track " + track.id);
   stream.removeTrack(track);
@@ -45,24 +44,25 @@ runTest(() => getUserMedia({audio: true,
     stream.addEventListener("removetrack", function onRemovetrack(event) {
       ok(false, "removetrack fired unexpectedly for track " + event.track.id);
     });
 
     return getUserMedia({audio: true, video: true});
   })
   .then(s => {
     newStream = s;
+
     info("Stopping an original track");
     stopTrack(stream.getTracks()[0]);
 
     return spinEventLoop();
   })
   .then(() => {
     info("Removing original tracks");
-    stream.getTracks().forEach(t => (stream.removeTrack(t), tracks.push(t)));
+    stream.getTracks().forEach(t => stream.removeTrack(t));
 
     return spinEventLoop();
   })
   .then(() => {
     info("Adding other gUM tracks");
     newStream.getTracks().forEach(t => addTrack(t))
 
     return spinEventLoop();
@@ -84,17 +84,16 @@ runTest(() => getUserMedia({audio: true,
     info("Stopping clones");
     clone.getTracks().forEach(t => stopTrack(t));
 
     return spinEventLoop();
   })
   .then(() => {
     info("Stopping originals");
     stream.getTracks().forEach(t => stopTrack(t));
-    tracks.forEach(t => stopTrack(t));
 
     return spinEventLoop();
   })
   .then(() => {
     info("Removing remaining tracks");
     stream.getTracks().forEach(t => removeTrack(t));
 
     return spinEventLoop();
--- a/dom/media/tests/mochitest/test_getUserMedia_basicScreenshare.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_basicScreenshare.html
@@ -82,16 +82,16 @@
         playback.startMedia(false);
         return playback.verifyPlaying()
           .then(() => Promise.all([
             () => testVideo.srcObject.getVideoTracks()[0].applyConstraints(videoConstraints[1]),
             () => listenUntil(testVideo, "resize", () => true)
           ]))
           .then(() => playback.verifyPlaying()) // still playing
           .then(() => playback.deprecatedStopStreamInMediaPlayback())
-          .then(() => playback.detachFromMediaElement());
+          .then(() => playback.stopMediaElement());
       });
   });
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/tests/mochitest/test_getUserMedia_basicTabshare.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_basicTabshare.html
@@ -55,16 +55,16 @@
               viewportOffsetY: 50,
               viewportWidth: 90,
               viewportHeight: 50
             }),
             () => listenUntil(testVideo, "resize", () => true)
           ]))
           .then(() => playback.verifyPlaying()) // still playing
           .then(() => playback.deprecatedStopStreamInMediaPlayback())
-          .then(() => playback.detachFromMediaElement());
+          .then(() => playback.stopMediaElement());
       });
   });
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/tests/mochitest/test_getUserMedia_basicVideo_playAfterLoadedmetadata.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_basicVideo_playAfterLoadedmetadata.html
@@ -26,17 +26,16 @@
       return new Promise(resolve => {
         ok(playback.mediaElement.paused,
            "Media element should be paused before play()ing");
         video.addEventListener('loadedmetadata', function() {
           ok(video.videoWidth > 0, "Expected nonzero video width");
           ok(video.videoHeight > 0, "Expected nonzero video width");
           resolve();
         });
-      })
-      .then(() => stream.getTracks().forEach(t => t.stop()));
+      });
     });
   });
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/tests/mochitest/test_getUserMedia_bug1223696.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_bug1223696.html
@@ -11,42 +11,38 @@
 
   createHTML({
     title: "Testing that removeTrack+addTrack of video tracks still render the correct track in a media element",
     bug: "1223696",
     visible: true
   });
 
   runTest(() => Promise.resolve()
-    .then(() => getUserMedia({audio:true, video: true})).then(stream => {
+      .then(() => getUserMedia({audio:true, video: true})).then(stream => {
       info("Test addTrack()ing a video track to an audio-only gUM stream");
 
       var video = createMediaElement("video", "test_video_track");
       video.srcObject = stream;
       video.play();
 
       var h = new CaptureStreamTestHelper2D();
-      var removedTrack = stream.getVideoTracks()[0];
-      stream.removeTrack(removedTrack);
+      stream.removeTrack(stream.getVideoTracks()[0]);
       video.onloadeddata = () => {
         info("loadeddata");
         var canvas = document.createElement("canvas");
         canvas.getContext("2d");
         var canvasStream = canvas.captureStream();
         setInterval(() => h.drawColor(canvas, h.grey), 1000);
 
         stream.addTrack(canvasStream.getVideoTracks()[0]);
 
         checkMediaStreamContains(stream, [stream.getAudioTracks()[0],
                                           canvasStream.getVideoTracks()[0]]);
       };
 
       return listenUntil(video, "loadeddata", () => true)
         .then(() => h.waitForPixelColor(video, h.grey, 5,
-            "The canvas track should be rendered by the media element"))
-        .then(() => {
-          [removedTrack, ...stream.getAudioTracks()].forEach(t => t.stop());
-        });
+                                        "The canvas track should be rendered by the media element"));
     }));
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/tests/mochitest/test_getUserMedia_constraints.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_constraints.html
@@ -97,57 +97,60 @@ var mustFailWith = (msg, reason, constra
     }
   });
 
 /**
  * Starts the test run by running through each constraint
  * test by verifying that the right resolution and rejection is fired.
  */
 
-runTest(() => Promise.resolve()
-  .then(() => {
-    // Check supported constraints first.
-    var dict = navigator.mediaDevices.getSupportedConstraints();
-    var supported = Object.keys(dict);
+runTest(function() {
 
-    mustSupport.forEach(key => ok(supported.indexOf(key) != -1 && dict[key],
-                                  "Supports " + key));
+  // Check supported constraints first.
+  var dict = navigator.mediaDevices.getSupportedConstraints();
+  var supported = Object.keys(dict);
+
+  mustSupport.forEach(key => ok(supported.indexOf(key) != -1 && dict[key],
+                                "Supports " + key));
 
-    var unexpected = supported.filter(key => mustSupport.indexOf(key) == -1);
-    is(unexpected.length, 0,
-       "Unanticipated support (please update test): " + unexpected);
-  })
-  .then(() => pushPrefs(["media.getusermedia.browser.enabled", false],
-                        ["media.getusermedia.screensharing.enabled", false]))
-  .then(() => tests.reduce((p, test) => p.then(() => getUserMedia(test.constraints))
-    .then(stream => {
-      is(null, test.error, test.message);
-      stream.getTracks().forEach(t => t.stop());
-    }, e => {
+  var unexpected = supported.filter(key => mustSupport.indexOf(key) == -1);
+  is(unexpected.length, 0,
+     "Unanticipated support (please update test): " + unexpected);
+
+  // Run constraint tests
+
+  var p = new Promise(resolve => SpecialPowers.pushPrefEnv({
+      set : [ ['media.getusermedia.browser.enabled', false],
+              ['media.getusermedia.screensharing.enabled', false] ]
+    }, resolve));
+
+  return tests.reduce((p, test) =>
+    p.then(() => navigator.mediaDevices.getUserMedia(test.constraints))
+    .then(() => is(null, test.error, test.message), e => {
       is(e.name, test.error, test.message + ": " + e.message);
       if (test.constraint) {
         is(e.constraint, test.constraint,
            test.message + " w/correct constraint.");
       }
-    }), Promise.resolve()))
-  .then(() => getUserMedia({video: true, audio: true}))
-  .then(stream => stream.getVideoTracks()[0].applyConstraints({ width: 320 })
-    .then(() => stream.getAudioTracks()[0].applyConstraints({ }))
-    .then(() => {
-      stream.getTracks().forEach(track => track.stop());
-      ok(true, "applyConstraints code exercised");
-    }))
-  // TODO: Test outcome once fake devices support constraints (Bug 1088621)
-  .then(() => mustFailWith("applyConstraints fails on non-Gum tracks",
-                           "OverconstrainedError", "",
-                           () => (new AudioContext())
-                               .createMediaStreamDestination().stream
-                               .getAudioTracks()[0].applyConstraints()))
-  .then(() => mustFailWith(
-      "getUserMedia with unsatisfied required constraint",
-      "OverconstrainedError", "deviceId",
-      () => getUserMedia({ audio: true,
-                           video: { deviceId: { exact: "unheardof" } } }))));
+    }), p)
+    .then(() => navigator.mediaDevices.getUserMedia({video: true, audio: true}))
+    .then(stream => stream.getVideoTracks()[0].applyConstraints({ width: 320 })
+      .then(() => stream.getAudioTracks()[0].applyConstraints({ })))
+    .then(() => ok(true, "applyConstraints code exercised"))
+    // TODO: Test outcome once fake devices support constraints (Bug 1088621)
+    .then(() => mustFailWith("applyConstraints fails on non-Gum tracks",
+                             "OverconstrainedError", "",
+                             () => (new AudioContext())
+                                 .createMediaStreamDestination().stream
+                                 .getAudioTracks()[0].applyConstraints()))
+    .then(() => mustFailWith(
+        "getUserMedia with unsatisfied required constraint",
+        "OverconstrainedError", "deviceId",
+        () => navigator.mediaDevices.getUserMedia({
+          audio: true,
+          video: { deviceId: { exact: "unheardof" } },
+        })));
+});
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/tests/mochitest/test_getUserMedia_getTrackById.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_getTrackById.html
@@ -35,16 +35,15 @@
 
       newStream.addTrack(audioTrack);
       is(newStream.getTrackById(audioTrack.id), audioTrack,
          "getTrackByid with matching id should return the track");
 
       newStream.addTrack(videoTrack);
       is(newStream.getTrackById(videoTrack.id), videoTrack,
          "getTrackByid with matching id should return the track");
-      [audioTrack, videoTrack].forEach(t => t.stop());
     });
   });
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/tests/mochitest/test_getUserMedia_loadedmetadata.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_loadedmetadata.html
@@ -19,21 +19,19 @@
   runTest(function () {
     var v = document.createElement("video");
     document.body.appendChild(v);
     v.preload = "metadata";
 
     var constraints = {video: true, audio: true};
     return getUserMedia(constraints).then(stream => new Promise(resolve => {
       v.srcObject = stream;
-      v.onloadedmetadata = () => {
-        isnot(v.videoWidth, 0, "videoWidth shall be set on 'loadedmetadata'");
-        isnot(v.videoHeight, 0, "videoHeight shall be set on 'loadedmetadata'");
-        resolve();
-      };
-    })
-    .then(() => stream.getTracks().forEach(t => t.stop())));
+      v.onloadedmetadata = resolve;
+    })).then(() => {
+      isnot(v.videoWidth, 0, "videoWidth shall be set on 'loadedmetadata'");
+      isnot(v.videoHeight, 0, "videoHeight shall be set on 'loadedmetadata'");
+    });
   });
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/tests/mochitest/test_getUserMedia_mediaElementCapture_audio.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_mediaElementCapture_audio.html
@@ -99,19 +99,17 @@ runTest(() => getUserMedia({audio: true}
     is(gUMAudioElement.srcObject.getTracks().length, 1,
        "A track should have been removed");
 
     return analyser.waitForAnalysisSuccess(array =>
       array[analyser.binIndexForFrequency(50)]              < 50 &&
       array[analyser.binIndexForFrequency(TEST_AUDIO_FREQ)] < 50 &&
       array[analyser.binIndexForFrequency(1500)]            < 50 &&
       array[analyser.binIndexForFrequency(2000)]            > 200 &&
-      array[analyser.binIndexForFrequency(2500)]            < 50)
-        .then(() => [gUMTrack, ...gUMAudioElement.srcObject.getTracks()]
-            .forEach(t => t.stop()));
+      array[analyser.binIndexForFrequency(2500)]            < 50);
   })
   .then(() => ok(true, "Test passed."))
   .catch(e => ok(false, "Test failed: " + e + (e.stack ? "\n" + e.stack : ""))));
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/tests/mochitest/test_getUserMedia_mediaElementCapture_video.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_mediaElementCapture_video.html
@@ -105,18 +105,15 @@ runTest(() => getUserMedia({video: true,
     return checkVideoPaused(captureStreamElement).then(() => track);
   })
   .then(track => {
     info("Video paused. Changing source by track manipulation. Add first.");
     gUMVideoElement.srcObject.addTrack(track);
     gUMVideoElement.play();
     return checkVideoPlaying(captureStreamElement);
   })
-  .then(() => {
-    gUMVideoElement.srcObject.getTracks().forEach(t => t.stop());
-    ok(true, "Test passed.");
-  })
+  .then(() => ok(true, "Test passed."))
   .catch(e => ok(false, "Test failed: " + e + (e.stack ? "\n" + e.stack : ""))));
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/tests/mochitest/test_getUserMedia_mediaStreamClone.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_mediaStreamClone.html
@@ -31,17 +31,17 @@
             "Audio track clone should have an id string");
 
       info("Stopping original tracks");
       stream.getTracks().forEach(t => t.stop());
 
       info("Playing from track clones");
       var test = createMediaElement('video', 'testClonePlayback');
       var playback = new MediaStreamPlayback(test, clone);
-      return playback.playMedia(false);
+      return playback.playMediaWithMediaStreamTracksStop(false);
     })
     .then(() => getUserMedia({video: true})).then(stream =>
       getUserMedia({video: true}).then(otherStream => {
         info("Test addTrack()ing a video track to a stream without affecting its clone");
         var track = stream.getTracks()[0];
         var otherTrack = otherStream.getTracks()[0];
 
         var streamClone = stream.clone();
@@ -62,37 +62,35 @@
                                  "Original not affected");
 
         // Not part of streamClone. Does not get stopped by the playback test.
         otherTrack.stop();
         otherStream.stop();
 
         var test = createMediaElement('video', 'testClonePlayback');
         var playback = new MediaStreamPlayback(test, streamClone);
-        return playback.playMedia(false)
+        return playback.playMediaWithMediaStreamTracksStop(false)
           .then(() => stream.getTracks().forEach(t => t.stop()))
           .then(() => stream.stop());
     }))
     .then(() => getUserMedia({audio: true, video: true})).then(stream => {
       info("Test cloning a stream into inception");
-      var clone = stream;
-      var clones = Array(10).fill().map(() => clone = clone.clone());
-      var inceptionClone = clones.pop();
+      var inceptionClone = stream.clone().clone().clone().clone().clone()
+                                 .clone().clone().clone().clone().clone();
       checkMediaStreamCloneAgainstOriginal(inceptionClone, stream);
       stream.getTracks().forEach(t => (stream.removeTrack(t),
                                        inceptionClone.addTrack(t)));
       is(inceptionClone.getAudioTracks().length, 2,
          "The inception clone should contain the original audio track and a track clone");
       is(inceptionClone.getVideoTracks().length, 2,
          "The inception clone should contain the original video track and a track clone");
 
       var test = createMediaElement('video', 'testClonePlayback');
       var playback = new MediaStreamPlayback(test, inceptionClone);
-      return playback.playMedia(false)
-        .then(() => clones.forEach(c => c.getTracks().forEach(t => t.stop())));
+      return playback.playMediaWithMediaStreamTracksStop(false);
     })
     .then(() => getUserMedia({audio: true, video: true})).then(stream => {
       info("Test adding tracks from many stream clones to the original stream");
 
       const LOOPS = 3;
       for (var i = 0; i < LOOPS; i++) {
         stream.clone().getTracks().forEach(t => stream.addTrack(t));
       }
@@ -102,17 +100,17 @@
          "The original track should contain the original video track and all the video clones");
       stream.getTracks().forEach(t1 => is(stream.getTracks()
                                                 .filter(t2 => t1.id == t2.id)
                                                 .length,
                                           1, "Each track should be unique"));
 
       var test = createMediaElement('video', 'testClonePlayback');
       var playback = new MediaStreamPlayback(test, stream);
-      return playback.playMedia(false);
+      return playback.playMediaWithMediaStreamTracksStop(false);
     })
     .then(() => {
       info("Testing audio content routing with MediaStream.clone()");
       var ac = new AudioContext();
 
       var osc1kOriginal = createOscillatorStream(ac, 1000);
       var audioTrack1kOriginal = osc1kOriginal.getTracks()[0];
       var audioTrack1kClone = osc1kOriginal.clone().getTracks()[0];
--- a/dom/media/tests/mochitest/test_getUserMedia_mediaStreamTrackClone.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_mediaStreamTrackClone.html
@@ -26,47 +26,41 @@
 
     info("Creating new stream for clone");
     var cloneStream = new MediaStream([clone]);
     checkMediaStreamContains(cloneStream, [clone]);
 
     info("Testing playback of track clone");
     var test = createMediaElement('video', 'testClonePlayback');
     var playback = new MediaStreamPlayback(test, cloneStream);
-    return playback.playMedia(false);
+    return playback.playMediaWithMediaStreamTracksStop(false);
   });
 
   runTest(() => Promise.resolve()
     .then(() => testSingleTrackClonePlayback({audio: true}))
     .then(() => testSingleTrackClonePlayback({video: true}))
     .then(() => getUserMedia({video: true})).then(stream => {
       info("Test cloning a track into inception");
       var track = stream.getTracks()[0];
-      var clone = track;
-      var clones = Array(10).fill().map(() => clone = clone.clone());
-      var inceptionClone = clones.pop();
+      var inceptionClone = track.clone().clone().clone().clone().clone()
+                                .clone().clone().clone().clone().clone();
       checkMediaStreamTrackCloneAgainstOriginal(inceptionClone, track);
 
       var cloneStream = new MediaStream();
       cloneStream.addTrack(inceptionClone);
 
       // cloneStream is now essentially the same as stream.clone();
       checkMediaStreamCloneAgainstOriginal(cloneStream, stream);
 
       var test = createMediaElement('video', 'testClonePlayback');
       var playback = new MediaStreamPlayback(test, cloneStream);
-      return playback.playMedia(false).then(() => {
-          info("Testing that clones of ended tracks are ended");
-          cloneStream.clone().getTracks().forEach(t =>
-            is(t.readyState, "ended", "Track " + t.id + " should be ended"));
-        })
-        .then(() => {
-          clones.forEach(t => t.stop());
-          track.stop();
-        });
+      return playback.playMediaWithMediaStreamTracksStop(false)
+        .then(() => info("Testing that clones of ended tracks are ended"))
+        .then(() => cloneStream.clone().getTracks().forEach(t =>
+          is(t.readyState, "ended", "Track " + t.id + " should be ended")));
     })
     .then(() => getUserMedia({audio: true, video: true})).then(stream => {
       info("Test adding many track clones to the original stream");
 
       const LOOPS = 3;
       for (var i = 0; i < LOOPS; i++) {
         stream.getTracks().forEach(t => stream.addTrack(t.clone()));
       }
@@ -74,17 +68,17 @@
          "The original track should contain the original video track and all the video clones");
       stream.getTracks().forEach(t1 => is(stream.getTracks()
                                                 .filter(t2 => t1.id == t2.id)
                                                 .length,
                                           1, "Each track should be unique"));
 
       var test = createMediaElement('video', 'testClonePlayback');
       var playback = new MediaStreamPlayback(test, stream);
-      return playback.playMedia(false);
+      return playback.playMediaWithMediaStreamTracksStop(false);
     })
     .then(() => {
       info("Testing audio content routing with MediaStreamTrack.clone()");
       var ac = new AudioContext();
 
       var osc1kOriginal = createOscillatorStream(ac, 1000);
       var audioTrack1kOriginal = osc1kOriginal.getTracks()[0];
       var audioTrack1kClone = audioTrack1kOriginal.clone();
--- a/dom/media/tests/mochitest/test_getUserMedia_peerIdentity.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_peerIdentity.html
@@ -17,17 +17,17 @@ function theTest() {
     if (withConstraint) {
       config.peerIdentity = 'user@example.com';
     }
     info('getting media with constraints: ' + JSON.stringify(config));
     return getUserMedia(config)
       .then(stream => Promise.all([
         audioIsSilence(withConstraint, stream),
         videoIsBlack(withConstraint, stream)
-      ]).then(() => stream.getTracks().forEach(t => t.stop())));
+      ]));
   };
 
   // both without and with the constraint
   return testPeerIdentityConstraint(false)
     .then(() => testPeerIdentityConstraint(true));
 }
 
 runTest(theTest);
--- a/dom/media/tests/mochitest/test_getUserMedia_playAudioTwice.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_playAudioTwice.html
@@ -10,16 +10,17 @@
   /**
    * Run a test that we can complete an audio playback cycle twice in a row.
    */
   runTest(function () {
     return getUserMedia({audio: true}).then(audioStream => {
       var testAudio = createMediaElement('audio', 'testAudio');
       var playback = new LocalMediaStreamPlayback(testAudio, audioStream);
 
-      return playback.playMediaWithoutStoppingTracks(false)
-        .then(() => playback.playMedia(true));
+      return playback.playMedia(false)
+        .then(() => playback.playMedia(true))
+        .then(() => audioStream.stop());
     });
   });
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/tests/mochitest/test_getUserMedia_playVideoAudioTwice.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_playVideoAudioTwice.html
@@ -10,17 +10,18 @@
   /**
    * Run a test that we can complete a video playback cycle twice in a row.
    */
   runTest(function () {
     return getUserMedia({video: true, audio: true}).then(stream => {
       var testVideo = createMediaElement('video', 'testVideo');
       var playback = new LocalMediaStreamPlayback(testVideo, stream);
 
-      return playback.playMediaWithoutStoppingTracks(false)
-        .then(() => playback.playMedia(true));
+      return playback.playMedia(false)
+        .then(() => playback.playMedia(true))
+        .then(() => stream.stop());
     });
   });
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/tests/mochitest/test_getUserMedia_playVideoTwice.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_playVideoTwice.html
@@ -10,17 +10,18 @@
   /**
    * Run a test that we can complete a video playback cycle twice in a row.
    */
   runTest(function () {
     return getUserMedia({video: true}).then(stream => {
       var testVideo = createMediaElement('video', 'testVideo');
       var streamPlayback = new LocalMediaStreamPlayback(testVideo, stream);
 
-      return streamPlayback.playMediaWithoutStoppingTracks(false)
-        .then(() => streamPlayback.playMedia(true));
+      return streamPlayback.playMedia(false)
+        .then(() => streamPlayback.playMedia(true))
+        .then(() => stream.stop());
     });
   });
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/tests/mochitest/test_getUserMedia_spinEventLoop.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_spinEventLoop.html
@@ -8,21 +8,20 @@
 <script type="application/javascript">
   createHTML({ title: "getUserMedia Basic Audio Test", bug: "1208656" });
   /**
    * Run a test to verify that we can spin the event loop from within a mozGUM callback.
    */
   runTest(() => {
     var testAudio = createMediaElement('audio', 'testAudio');
     return new Promise((resolve, reject) => {
-      navigator.mozGetUserMedia({ audio: true }, stream => {
+      navigator.mozGetUserMedia({ audio: true }, () => {
         SpecialPowers.spinEventLoop(window);
-        ok(true, "Didn't crash");
-        stream.getTracks().forEach(t => t.stop());
-        resolve();
+               ok(true, "Didn't crash");
+               resolve();
       }, () => {});
     });
   });
 
 </script>
 </pre>
 </body>
 </html>
deleted file mode 100644
--- a/dom/media/tests/mochitest/test_getUserMedia_trackCloneCleanup.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <script type="application/javascript" src="mediaStreamPlayback.js"></script>
-</head>
-<body>
-<pre id="test">
-<script type="application/javascript">
-  "use strict";
-
-  createHTML({
-    title: "Stopping a MediaStreamTrack and its clones should deallocate the device",
-    bug: "1294605"
-  });
-
-  runTest(() => getUserMedia({audio: true, video: true}).then(stream => {
-    let clone = stream.clone();
-    stream.getTracks().forEach(t => t.stop());
-    stream.clone().getTracks().forEach(t => stream.addTrack(t));
-    is(stream.getTracks().filter(t => t.readyState == "live").length, 0,
-       "Cloning ended tracks should make them ended");
-    [...stream.getTracks(), ...clone.getTracks()].forEach(t => t.stop());
-
-    // Bug 1295352: better to be explicit about noGum here wrt future refactoring.
-    return noGum();
-  }));
-</script>
-</pre>
-</body>
-</html>
--- a/dom/media/webaudio/AudioContext.cpp
+++ b/dom/media/webaudio/AudioContext.cpp
@@ -21,16 +21,17 @@
 #include "AudioBufferSourceNode.h"
 #include "AudioChannelService.h"
 #include "AudioDestinationNode.h"
 #include "AudioListener.h"
 #include "AudioStream.h"
 #include "BiquadFilterNode.h"
 #include "ChannelMergerNode.h"
 #include "ChannelSplitterNode.h"
+#include "ConstantSourceNode.h"
 #include "ConvolverNode.h"
 #include "DelayNode.h"
 #include "DynamicsCompressorNode.h"
 #include "GainNode.h"
 #include "IIRFilterNode.h"
 #include "MediaElementAudioSourceNode.h"
 #include "MediaStreamAudioDestinationNode.h"
 #include "MediaStreamAudioSourceNode.h"
@@ -244,16 +245,28 @@ AudioContext::CreateBufferSource(ErrorRe
     return nullptr;
   }
 
   RefPtr<AudioBufferSourceNode> bufferNode =
     new AudioBufferSourceNode(this);
   return bufferNode.forget();
 }
 
+already_AddRefed<ConstantSourceNode>
+AudioContext::CreateConstantSource(ErrorResult& aRv)
+{
+  if (CheckClosed(aRv)) {
+    return nullptr;
+  }
+
+  RefPtr<ConstantSourceNode> constantSourceNode =
+    new ConstantSourceNode(this);
+  return constantSourceNode.forget();
+}
+
 already_AddRefed<AudioBuffer>
 AudioContext::CreateBuffer(uint32_t aNumberOfChannels, uint32_t aLength,
                            float aSampleRate,
                            ErrorResult& aRv)
 {
   if (!aNumberOfChannels) {
     aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
     return nullptr;
--- a/dom/media/webaudio/AudioContext.h
+++ b/dom/media/webaudio/AudioContext.h
@@ -47,16 +47,17 @@ class AnalyserNode;
 class AudioBuffer;
 class AudioBufferSourceNode;
 class AudioDestinationNode;
 class AudioListener;
 class AudioNode;
 class BiquadFilterNode;
 class ChannelMergerNode;
 class ChannelSplitterNode;
+class ConstantSourceNode;
 class ConvolverNode;
 class DelayNode;
 class DynamicsCompressorNode;
 class GainNode;
 class GlobalObject;
 class HTMLMediaElement;
 class IIRFilterNode;
 class MediaElementAudioSourceNode;
@@ -195,16 +196,18 @@ public:
   // thread and removing the reference we added.
   already_AddRefed<Promise> Suspend(ErrorResult& aRv);
   already_AddRefed<Promise> Resume(ErrorResult& aRv);
   already_AddRefed<Promise> Close(ErrorResult& aRv);
   IMPL_EVENT_HANDLER(statechange)
 
   already_AddRefed<AudioBufferSourceNode> CreateBufferSource(ErrorResult& aRv);
 
+  already_AddRefed<ConstantSourceNode> CreateConstantSource(ErrorResult& aRv);
+
   already_AddRefed<AudioBuffer>
   CreateBuffer(uint32_t aNumberOfChannels, uint32_t aLength, float aSampleRate,
                ErrorResult& aRv);
 
   already_AddRefed<MediaStreamAudioDestinationNode>
   CreateMediaStreamDestination(ErrorResult& aRv);
 
   already_AddRefed<ScriptProcessorNode>
new file mode 100644
--- /dev/null
+++ b/dom/media/webaudio/ConstantSourceNode.cpp
@@ -0,0 +1,286 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* 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 "ConstantSourceNode.h"
+
+#include "AudioDestinationNode.h"
+#include "nsContentUtils.h"
+
+namespace mozilla {
+namespace dom {
+
+NS_IMPL_CYCLE_COLLECTION_INHERITED(ConstantSourceNode, AudioNode,
+                                   mOffset)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ConstantSourceNode)
+NS_INTERFACE_MAP_END_INHERITING(AudioNode)
+
+NS_IMPL_ADDREF_INHERITED(ConstantSourceNode, AudioNode)
+NS_IMPL_RELEASE_INHERITED(ConstantSourceNode, AudioNode)
+
+class ConstantSourceNodeEngine final : public AudioNodeEngine
+{
+public:
+  ConstantSourceNodeEngine(AudioNode* aNode, AudioDestinationNode* aDestination)
+    : AudioNodeEngine(aNode)
+    , mSource(nullptr)
+    , mDestination(aDestination->Stream())
+    , mStart(-1)
+    , mStop(STREAM_TIME_MAX)
+    // Keep the default values in sync with ConstantSourceNode::ConstantSourceNode.
+    , mOffset(1.0f)
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+  }
+
+  void SetSourceStream(AudioNodeStream* aSource)
+  {
+    mSource = aSource;
+  }
+
+  enum Parameters {
+    OFFSET,
+    START,
+    STOP,
+  };
+  void RecvTimelineEvent(uint32_t aIndex,
+                         AudioTimelineEvent& aEvent) override
+  {
+    MOZ_ASSERT(mDestination);
+
+    WebAudioUtils::ConvertAudioTimelineEventToTicks(aEvent,
+                                                    mDestination);
+
+    switch (aIndex) {
+    case OFFSET:
+      mOffset.InsertEvent<int64_t>(aEvent);
+      break;
+    default:
+      NS_ERROR("Bad ConstantSourceNodeEngine TimelineParameter");
+    }
+  }
+
+  void SetStreamTimeParameter(uint32_t aIndex, StreamTime aParam) override
+  {
+    switch (aIndex) {
+    case START:
+      mStart = aParam;
+      mSource->SetActive();
+      break;
+    case STOP: mStop = aParam; break;
+    default:
+      NS_ERROR("Bad ConstantSourceNodeEngine StreamTimeParameter");
+    }
+  }
+
+  void ProcessBlock(AudioNodeStream* aStream,
+                    GraphTime aFrom,
+                    const AudioBlock& aInput,
+                    AudioBlock* aOutput,
+                    bool* aFinished) override
+  {
+    MOZ_ASSERT(mSource == aStream, "Invalid source stream");
+
+    StreamTime ticks = mDestination->GraphTimeToStreamTime(aFrom);
+    if (mStart == -1) {
+      aOutput->SetNull(WEBAUDIO_BLOCK_SIZE);
+      return;
+    }
+
+    if (ticks + WEBAUDIO_BLOCK_SIZE <= mStart || ticks >= mStop) {
+      aOutput->SetNull(WEBAUDIO_BLOCK_SIZE);
+    } else {
+      aOutput->AllocateChannels(1);
+      float* output = aOutput->ChannelFloatsForWrite(0);
+
+      if (mOffset.HasSimpleValue()) {
+        for (uint32_t i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
+          output[i] = mOffset.GetValueAtTime(aFrom, 0);
+        }
+      } else {
+        mOffset.GetValuesAtTime(ticks, output, WEBAUDIO_BLOCK_SIZE);
+      }
+    }
+
+    if (ticks + WEBAUDIO_BLOCK_SIZE >= mStop) {
+      // We've finished playing.
+      *aFinished = true;
+    }
+  }
+
+  bool IsActive() const override
+  {
+    // start() has been called.
+    return mStart != -1;
+  }
+
+  size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override
+  {
+    size_t amount = AudioNodeEngine::SizeOfExcludingThis(aMallocSizeOf);
+
+    // Not owned:
+    // - mSource
+    // - mDestination
+    // - mOffset (internal ref owned by node)
+
+    return amount;
+  }
+
+  size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override
+  {
+    return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
+  }
+
+  AudioNodeStream* mSource;
+  AudioNodeStream* mDestination;
+  StreamTime mStart;
+  StreamTime mStop;
+  AudioParamTimeline mOffset;
+};
+
+ConstantSourceNode::ConstantSourceNode(AudioContext* aContext)
+  : AudioNode(aContext,
+              1,
+              ChannelCountMode::Max,
+              ChannelInterpretation::Speakers)
+  , mOffset(new AudioParam(this, ConstantSourceNodeEngine::OFFSET,
+                           1.0, "offset"))
+  , mStartCalled(false)
+{
+  ConstantSourceNodeEngine* engine = new ConstantSourceNodeEngine(this, aContext->Destination());
+  mStream = AudioNodeStream::Create(aContext, engine,
+                                    AudioNodeStream::NEED_MAIN_THREAD_FINISHED,
+                                    aContext->Graph());
+  engine->SetSourceStream(mStream);
+  mStream->AddMainThreadListener(this);
+}
+
+ConstantSourceNode::~ConstantSourceNode()
+{
+}
+
+size_t
+ConstantSourceNode::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
+{
+  size_t amount = AudioNode::SizeOfExcludingThis(aMallocSizeOf);
+
+  amount += mOffset->SizeOfIncludingThis(aMallocSizeOf);
+  return amount;
+}
+
+size_t
+ConstantSourceNode::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
+{
+  return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
+}
+
+JSObject*
+ConstantSourceNode::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+{
+  return ConstantSourceNodeBinding::Wrap(aCx, this, aGivenProto);
+}
+
+already_AddRefed<ConstantSourceNode>
+ConstantSourceNode::Constructor(const GlobalObject& aGlobal,
+                                AudioContext& aContext,
+                                const ConstantSourceOptions& aOptions,
+                                ErrorResult& aRv)
+{
+  RefPtr<ConstantSourceNode> object = new ConstantSourceNode(&aContext);
+  object->mOffset->SetValue(aOptions.mOffset);
+  return object.forget();
+}
+
+void
+ConstantSourceNode::DestroyMediaStream()
+{
+  if (mStream) {
+    mStream->RemoveMainThreadListener(this);
+  }
+  AudioNode::DestroyMediaStream();
+}
+
+void
+ConstantSourceNode::Start(double aWhen, ErrorResult& aRv)
+{
+  if (!WebAudioUtils::IsTimeValid(aWhen)) {
+    aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
+    return;
+  }
+
+  if (mStartCalled) {
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+    return;
+  }
+  mStartCalled = true;
+
+  if (!mStream) {
+    return;
+  }
+
+  mStream->SetStreamTimeParameter(ConstantSourceNodeEngine::START,
+                                  Context(), aWhen);
+
+  MarkActive();
+}
+
+void
+ConstantSourceNode::Stop(double aWhen, ErrorResult& aRv)
+{
+  if (!WebAudioUtils::IsTimeValid(aWhen)) {
+    aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
+    return;
+  }
+
+  if (!mStartCalled) {
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+    return;
+  }
+
+  if (!mStream || !Context()) {
+    return;
+  }
+
+  mStream->SetStreamTimeParameter(ConstantSourceNodeEngine::STOP,
+                                  Context(), std::max(0.0, aWhen));
+}
+
+void
+ConstantSourceNode::NotifyMainThreadStreamFinished()
+{
+  MOZ_ASSERT(mStream->IsFinished());
+
+  class EndedEventDispatcher final : public Runnable
+  {
+  public:
+    explicit EndedEventDispatcher(ConstantSourceNode* aNode)
+      : mNode(aNode) {}
+    NS_IMETHOD Run() override
+    {
+      // If it's not safe to run scripts right now, schedule this to run later
+      if (!nsContentUtils::IsSafeToRunScript()) {
+        nsContentUtils::AddScriptRunner(this);
+        return NS_OK;
+      }
+
+      mNode->DispatchTrustedEvent(NS_LITERAL_STRING("ended"));
+      // Release stream resources.
+      mNode->DestroyMediaStream();
+      return NS_OK;
+    }
+  private:
+    RefPtr<ConstantSourceNode> mNode;
+  };
+
+  NS_DispatchToMainThread(new EndedEventDispatcher(this));
+
+  // Drop the playing reference
+  // Warning: The below line might delete this.
+  MarkInactive();
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/media/webaudio/ConstantSourceNode.h
@@ -0,0 +1,76 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef ConstantSourceNode_h_
+#define ConstantSourceNode_h_
+
+#include "AudioNode.h"
+#include "AudioParam.h"
+#include "mozilla/dom/ConstantSourceNodeBinding.h"
+
+namespace mozilla {
+namespace dom {
+
+class AudioContext;
+
+class ConstantSourceNode final : public AudioNode,
+                                 public MainThreadMediaStreamListener
+{
+public:
+  explicit ConstantSourceNode(AudioContext* aContext);
+
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ConstantSourceNode, AudioNode)
+
+  JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
+
+  static already_AddRefed<ConstantSourceNode>
+  Constructor(const GlobalObject& aGlobal,
+              AudioContext& aContext,
+              const ConstantSourceOptions& aOptions,
+              ErrorResult& aRv);
+
+  void DestroyMediaStream() override;
+
+  uint16_t NumberOfInputs() const final override
+  {
+    return 0;
+  }
+
+  AudioParam* Offset() const
+  {
+    return mOffset;
+  }
+
+  void Start(double aWhen, ErrorResult& rv);
+  void Stop(double aWhen, ErrorResult& rv);
+
+  IMPL_EVENT_HANDLER(ended)
+
+  void NotifyMainThreadStreamFinished() override;
+
+  const char* NodeType() const override
+  {
+    return "ConstantSourceNode";
+  }
+
+  size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
+  size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
+
+protected:
+  virtual ~ConstantSourceNode();
+
+private:
+  RefPtr<AudioParam> mOffset;
+  bool mStartCalled;
+
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif
+
--- a/dom/media/webaudio/PannerNode.cpp
+++ b/dom/media/webaudio/PannerNode.cpp
@@ -1,15 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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 "PannerNode.h"
+#include "AlignmentUtils.h"
+#include "AudioDestinationNode.h"
 #include "AudioNodeEngine.h"
 #include "AudioNodeStream.h"
 #include "AudioListener.h"
 #include "PanningUtils.h"
 #include "AudioBufferSourceNode.h"
 #include "PlayingRefChangeHandler.h"
 #include "blink/HRTFPanner.h"
 #include "blink/HRTFDatabaseLoader.h"
--- a/dom/media/webaudio/PannerNode.h
+++ b/dom/media/webaudio/PannerNode.h
@@ -3,20 +3,20 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef PannerNode_h_
 #define PannerNode_h_
 
 #include "AudioNode.h"
+#include "AudioParam.h"
 #include "mozilla/dom/PannerNodeBinding.h"
 #include "ThreeDPoint.h"
 #include "mozilla/WeakPtr.h"
-#include "WebAudioUtils.h"
 #include <limits>
 #include <set>
 
 namespace mozilla {
 namespace dom {
 
 class AudioContext;
 class AudioBufferSourceNode;
--- a/dom/media/webaudio/moz.build
+++ b/dom/media/webaudio/moz.build
@@ -52,16 +52,17 @@ EXPORTS.mozilla.dom += [
     'AudioDestinationNode.h',
     'AudioListener.h',
     'AudioNode.h',
     'AudioParam.h',
     'AudioProcessingEvent.h',
     'BiquadFilterNode.h',
     'ChannelMergerNode.h',
     'ChannelSplitterNode.h',
+    'ConstantSourceNode.h',
     'ConvolverNode.h',
     'DelayNode.h',
     'DynamicsCompressorNode.h',
     'GainNode.h',
     'IIRFilterNode.h',
     'MediaElementAudioSourceNode.h',
     'MediaStreamAudioDestinationNode.h',
     'MediaStreamAudioSourceNode.h',
@@ -88,16 +89,17 @@ UNIFIED_SOURCES += [
     'AudioNodeExternalInputStream.cpp',
     'AudioNodeStream.cpp',
     'AudioParam.cpp',
     'AudioProcessingEvent.cpp',
     'BiquadFilterNode.cpp',
     'BufferDecoder.cpp',
     'ChannelMergerNode.cpp',
     'ChannelSplitterNode.cpp',
+    'ConstantSourceNode.cpp',
     'ConvolverNode.cpp',
     'DelayBuffer.cpp',
     'DelayNode.cpp',
     'DynamicsCompressorNode.cpp',
     'FFTBlock.cpp',
     'GainNode.cpp',
     'IIRFilterNode.cpp',
     'MediaBufferDecoder.cpp',
--- a/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineRemoteVideoSource.cpp
@@ -330,20 +330,16 @@ void
 MediaEngineRemoteVideoSource::NotifyPull(MediaStreamGraph* aGraph,
                                          SourceMediaStream* aSource,
                                          TrackID aID, StreamTime aDesiredTime,
                                          const PrincipalHandle& aPrincipalHandle)
 {
   VideoSegment segment;
 
   MonitorAutoLock lock(mMonitor);
-  if (mState != kStarted) {
-    return;
-  }
-
   StreamTime delta = aDesiredTime - aSource->GetEndOfAppendedData(aID);
 
   if (delta > 0) {
     // nullptr images are allowed
     AppendToTrack(aSource, mImage, aID, delta, aPrincipalHandle);
   }
 }
 
--- a/dom/media/webrtc/MediaEngineTabVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineTabVideoSource.cpp
@@ -114,27 +114,16 @@ MediaEngineTabVideoSource::InitRunnable:
     mVideoSource->mWindow = nsPIDOMWindowOuter::From(win);
     MOZ_ASSERT(mVideoSource->mWindow);
   }
   nsCOMPtr<nsIRunnable> start(new StartRunnable(mVideoSource));
   start->Run();
   return NS_OK;
 }
 
-nsresult
-MediaEngineTabVideoSource::DestroyRunnable::Run()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  mVideoSource->mWindow = nullptr;
-  mVideoSource->mTabSource = nullptr;
-
-  return NS_OK;
-}
-
 void
 MediaEngineTabVideoSource::GetName(nsAString_internal& aName) const
 {
   aName.AssignLiteral(u"&getUserMedia.videoSource.tabShare;");
 }
 
 void
 MediaEngineTabVideoSource::GetUUID(nsACString_internal& aUuid) const
@@ -155,22 +144,16 @@ MediaEngineTabVideoSource::Allocate(cons
                                     const char** aOutBadConstraint)
 {
   // windowId is not a proper constraint, so just read it.
   // It has no well-defined behavior in advanced, so ignore it there.
 
   mWindowId = aConstraints.mBrowserWindow.WasPassed() ?
               aConstraints.mBrowserWindow.Value() : -1;
   *aOutHandle = nullptr;
-
-  {
-    MonitorAutoLock mon(mMonitor);
-    mState = kAllocated;
-  }
-
   return Restart(nullptr, aConstraints, aPrefs, aDeviceId, aOutBadConstraint);
 }
 
 nsresult
 MediaEngineTabVideoSource::Restart(AllocationHandle* aHandle,
                                    const dom::MediaTrackConstraints& aConstraints,
                                    const mozilla::MediaEnginePrefs& aPrefs,
                                    const nsString& aDeviceId,
@@ -199,56 +182,42 @@ MediaEngineTabVideoSource::Restart(Alloc
   }
   return NS_OK;
 }
 
 nsresult
 MediaEngineTabVideoSource::Deallocate(AllocationHandle* aHandle)
 {
   MOZ_ASSERT(!aHandle);
-  NS_DispatchToMainThread(do_AddRef(new DestroyRunnable(this)));
-
-  {
-    MonitorAutoLock mon(mMonitor);
-    mState = kReleased;
-  }
   return NS_OK;
 }
 
 nsresult
 MediaEngineTabVideoSource::Start(SourceMediaStream* aStream, TrackID aID,
                                  const PrincipalHandle& aPrincipalHandle)
 {
   nsCOMPtr<nsIRunnable> runnable;
   if (!mWindow)
     runnable = new InitRunnable(this);
   else
     runnable = new StartRunnable(this);
   NS_DispatchToMainThread(runnable);
   aStream->AddTrack(aID, 0, new VideoSegment());
 
-  {
-    MonitorAutoLock mon(mMonitor);
-    mState = kStarted;
-  }
-
   return NS_OK;
 }
 
 void
 MediaEngineTabVideoSource::NotifyPull(MediaStreamGraph*,
                                       SourceMediaStream* aSource,
                                       TrackID aID, StreamTime aDesiredTime,
                                       const PrincipalHandle& aPrincipalHandle)
 {
   VideoSegment segment;
   MonitorAutoLock mon(mMonitor);
-  if (mState != kStarted) {
-    return;
-  }
 
   // Note: we're not giving up mImage here
   RefPtr<layers::SourceSurfaceImage> image = mImage;
   StreamTime delta = aDesiredTime - aSource->GetEndOfAppendedData(aID);
   if (delta > 0) {
     // nullptr images are allowed
     gfx::IntSize size = image ? image->GetSize() : IntSize(0, 0);
     segment.AppendFrame(image.forget().downcast<layers::Image>(), delta, size,
@@ -361,32 +330,25 @@ MediaEngineTabVideoSource::Draw() {
 
   RefPtr<layers::SourceSurfaceImage> image = new layers::SourceSurfaceImage(size, surface);
 
   MonitorAutoLock mon(mMonitor);
   mImage = image;
 }
 
 nsresult
-MediaEngineTabVideoSource::Stop(mozilla::SourceMediaStream* aSource,
-                                mozilla::TrackID aID)
+MediaEngineTabVideoSource::Stop(mozilla::SourceMediaStream*, mozilla::TrackID)
 {
   // If mBlackedoutWindow is true, we may be running
   // despite mWindow == nullptr.
   if (!mWindow && !mBlackedoutWindow) {
     return NS_OK;
   }
 
   NS_DispatchToMainThread(new StopRunnable(this));
-
-  {
-    MonitorAutoLock mon(mMonitor);
-    mState = kStopped;
-    aSource->EndTrack(aID);
-  }
   return NS_OK;
 }
 
 bool
 MediaEngineTabVideoSource::IsFake()
 {
   return false;
 }
--- a/dom/media/webrtc/MediaEngineTabVideoSource.h
+++ b/dom/media/webrtc/MediaEngineTabVideoSource.h
@@ -76,23 +76,16 @@ class MediaEngineTabVideoSource : public
 
     class InitRunnable : public Runnable {
     public:
       explicit InitRunnable(MediaEngineTabVideoSource *videoSource) : mVideoSource(videoSource) {}
       NS_IMETHOD Run();
       RefPtr<MediaEngineTabVideoSource> mVideoSource;
     };
 
-    class DestroyRunnable : public Runnable {
-    public:
-      explicit DestroyRunnable(MediaEngineTabVideoSource* videoSource) : mVideoSource(videoSource) {}
-      NS_IMETHOD Run();
-      RefPtr<MediaEngineTabVideoSource> mVideoSource;
-    };
-
 protected:
     ~MediaEngineTabVideoSource() {}
 
 private:
     int32_t mBufWidthMax;
     int32_t mBufHeightMax;
     int64_t mWindowId;
     bool mScrollWithPage;
deleted file mode 100644
--- a/dom/mobilemessage/Assertions.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/* 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 "mozilla/dom/MozMobileMessageManagerBinding.h"
-#include "nsISmsService.h"
-
-namespace mozilla {
-namespace dom {
-namespace mobilemessage {
-
-#define ASSERT_SMS_EQUALITY(webidlType, webidlState, xpidlState) \
-  static_assert(static_cast<uint32_t>(webidlType::webidlState) == nsISmsService::xpidlState, \
-  #webidlType "::" #webidlState " should equal to nsISmsService::" #xpidlState)
-
-/**
- * Enum TypeOfNumber
- */
-#define ASSERT_SMS_TYPE_OF_NUMBER_EQUALITY(webidlState, xpidlState) \
-  ASSERT_SMS_EQUALITY(TypeOfNumber, webidlState, xpidlState)
-
-ASSERT_SMS_TYPE_OF_NUMBER_EQUALITY(Unknown, TYPE_OF_NUMBER_UNKNOWN);
-ASSERT_SMS_TYPE_OF_NUMBER_EQUALITY(International, TYPE_OF_NUMBER_INTERNATIONAL);
-ASSERT_SMS_TYPE_OF_NUMBER_EQUALITY(National, TYPE_OF_NUMBER_NATIONAL);
-ASSERT_SMS_TYPE_OF_NUMBER_EQUALITY(Network_specific, TYPE_OF_NUMBER_NETWORK_SPECIFIC);
-ASSERT_SMS_TYPE_OF_NUMBER_EQUALITY(Dedicated_access_short_code, TYPE_OF_NUMBER_DEDICATED_ACCESS_SHORT_CODE);
-
-#undef ASSERT_SMS_TYPE_OF_NUMBER_EQUALITY
-
-/**
- * Enum NumberPlanIdentification
- */
-#define ASSERT_SMS_NUMBER_PLAN_IDENTIFICATION_EQUALITY(webidlState, xpidlState) \
-  ASSERT_SMS_EQUALITY(NumberPlanIdentification, webidlState, xpidlState)
-
-ASSERT_SMS_NUMBER_PLAN_IDENTIFICATION_EQUALITY(Unknown, NUMBER_PLAN_IDENTIFICATION_UNKNOWN);
-ASSERT_SMS_NUMBER_PLAN_IDENTIFICATION_EQUALITY(Isdn, NUMBER_PLAN_IDENTIFICATION_ISDN);
-ASSERT_SMS_NUMBER_PLAN_IDENTIFICATION_EQUALITY(Data, NUMBER_PLAN_IDENTIFICATION_DATA);
-ASSERT_SMS_NUMBER_PLAN_IDENTIFICATION_EQUALITY(Telex, NUMBER_PLAN_IDENTIFICATION_TELEX);
-ASSERT_SMS_NUMBER_PLAN_IDENTIFICATION_EQUALITY(National, NUMBER_PLAN_IDENTIFICATION_NATIONAL);
-ASSERT_SMS_NUMBER_PLAN_IDENTIFICATION_EQUALITY(Private, NUMBER_PLAN_IDENTIFICATION_PRIVATE);
-
-#undef ASSERT_SMS_EQUALITY
-
-} // namespace mobilemessage
-} // namespace dom
-} // namespace mozilla
deleted file mode 100644
--- a/dom/mobilemessage/Constants.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=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/. */
-
-namespace mozilla {
-namespace dom {
-namespace mobilemessage {
-
-const char* kSmsReceivedObserverTopic        = "sms-received";
-const char* kSmsRetrievingObserverTopic      = "sms-retrieving";
-const char* kSmsSendingObserverTopic         = "sms-sending";
-const char* kSmsSentObserverTopic            = "sms-sent";
-const char* kSmsFailedObserverTopic          = "sms-failed";
-const char* kSmsDeliverySuccessObserverTopic = "sms-delivery-success";
-const char* kSmsDeliveryErrorObserverTopic   = "sms-delivery-error";
-const char* kSilentSmsReceivedObserverTopic  = "silent-sms-received";
-const char* kSmsReadSuccessObserverTopic     = "sms-read-success";
-const char* kSmsReadErrorObserverTopic       = "sms-read-error";
-const char* kSmsDeletedObserverTopic         = "sms-deleted";
-
-} // namespace mobilemessage
-} // namespace dom
-} // namespace mozilla
deleted file mode 100644
--- a/dom/mobilemessage/Constants.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=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/. */
-
-#ifndef mozilla_dom_mobilemessage_Constants_h
-#define mozilla_dom_mobilemessage_Constants_h
-
-namespace mozilla {
-namespace dom {
-namespace mobilemessage {
-
-// Defined in the .cpp.
-extern const char* kSmsReceivedObserverTopic;
-extern const char* kSmsRetrievingObserverTopic;
-extern const char* kSmsSendingObserverTopic;
-extern const char* kSmsSentObserverTopic;
-extern const char* kSmsFailedObserverTopic;
-extern const char* kSmsDeliverySuccessObserverTopic;
-extern const char* kSmsDeliveryErrorObserverTopic;
-extern const char* kSilentSmsReceivedObserverTopic;
-extern const char* kSmsReadSuccessObserverTopic;
-extern const char* kSmsReadErrorObserverTopic;
-extern const char* kSmsDeletedObserverTopic;
-
-#define DELIVERY_RECEIVED       NS_LITERAL_STRING("received")
-#define DELIVERY_SENDING        NS_LITERAL_STRING("sending")
-#define DELIVERY_SENT           NS_LITERAL_STRING("sent")
-#define DELIVERY_ERROR          NS_LITERAL_STRING("error")
-#define DELIVERY_NOT_DOWNLOADED NS_LITERAL_STRING("not-downloaded")
-
-#define DELIVERY_STATUS_NOT_APPLICABLE NS_LITERAL_STRING("not-applicable")
-#define DELIVERY_STATUS_SUCCESS        NS_LITERAL_STRING("success")
-#define DELIVERY_STATUS_PENDING        NS_LITERAL_STRING("pending")
-#define DELIVERY_STATUS_ERROR          NS_LITERAL_STRING("error")
-#define DELIVERY_STATUS_REJECTED       NS_LITERAL_STRING("rejected")
-#define DELIVERY_STATUS_MANUAL         NS_LITERAL_STRING("manual")
-
-#define READ_STATUS_NOT_APPLICABLE NS_LITERAL_STRING("not-applicable")
-#define READ_STATUS_SUCCESS        NS_LITERAL_STRING("success")
-#define READ_STATUS_PENDING        NS_LITERAL_STRING("pending")
-#define READ_STATUS_ERROR          NS_LITERAL_STRING("error")
-
-#define MESSAGE_CLASS_NORMAL  NS_LITERAL_STRING("normal")
-#define MESSAGE_CLASS_CLASS_0 NS_LITERAL_STRING("class-0")
-#define MESSAGE_CLASS_CLASS_1 NS_LITERAL_STRING("class-1")
-#define MESSAGE_CLASS_CLASS_2 NS_LITERAL_STRING("class-2")
-#define MESSAGE_CLASS_CLASS_3 NS_LITERAL_STRING("class-3")
-
-#define MESSAGE_TYPE_SMS NS_LITERAL_STRING("sms")
-#define MESSAGE_TYPE_MMS NS_LITERAL_STRING("mms")
-
-} // namespace mobilemessage
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_mobilemessage_Constants_h
deleted file mode 100644
--- a/dom/mobilemessage/DOMMobileMessageError.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=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 "DOMMobileMessageError.h"
-#include "mozilla/dom/DOMMobileMessageErrorBinding.h"
-#include "MmsMessage.h"
-#include "SmsMessage.h"
-
-namespace mozilla {
-namespace dom {
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(DOMMobileMessageError)
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(DOMMobileMessageError, DOMError)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mSms)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mMms)
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(DOMMobileMessageError, DOMError)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSms)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMms)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DOMMobileMessageError)
-NS_INTERFACE_MAP_END_INHERITING(DOMError)
-
-NS_IMPL_ADDREF_INHERITED(DOMMobileMessageError, DOMError)
-NS_IMPL_RELEASE_INHERITED(DOMMobileMessageError, DOMError)
-
-DOMMobileMessageError::DOMMobileMessageError(nsPIDOMWindowInner* aWindow,
-                                             const nsAString& aName,
-                                             SmsMessage* aSms)
-  : DOMError(aWindow, aName)
-  , mSms(aSms)
-  , mMms(nullptr)
-{
-}
-
-DOMMobileMessageError::DOMMobileMessageError(nsPIDOMWindowInner* aWindow,
-                                             const nsAString& aName,
-                                             MmsMessage* aMms)
-  : DOMError(aWindow, aName)
-  , mSms(nullptr)
-  , mMms(aMms)
-{
-}
-
-void
-DOMMobileMessageError::GetData(OwningSmsMessageOrMmsMessage& aRetVal) const
-{
-  if (mSms) {
-    aRetVal.SetAsSmsMessage() = mSms;
-    return;
-  }
-
-  if (mMms) {
-    aRetVal.SetAsMmsMessage() = mMms;
-    return;
-  }
-
-  MOZ_CRASH("Bad object with invalid mSms and mMms.");
-}
-
-JSObject*
-DOMMobileMessageError::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
-  return DOMMobileMessageErrorBinding::Wrap(aCx, this, aGivenProto);
-}
-
-} // namespace dom
-} // namespace mozilla
deleted file mode 100644
--- a/dom/mobilemessage/DOMMobileMessageError.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=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/. */
-
-#ifndef mozilla_dom_MobileMessageError_h
-#define mozilla_dom_MobileMessageError_h
-
-#include "mozilla/dom/DOMError.h"
-
-namespace mozilla {
-namespace dom {
-
-class MmsMessage;
-class OwningSmsMessageOrMmsMessage;
-class SmsMessage;
-
-class DOMMobileMessageError final : public DOMError
-{
-public:
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DOMMobileMessageError, DOMError)
-
-  DOMMobileMessageError(nsPIDOMWindowInner* aWindow, const nsAString& aName,
-                        SmsMessage* aSms);
-
-  DOMMobileMessageError(nsPIDOMWindowInner* aWindow, const nsAString& aName,
-                        MmsMessage* aMms);
-
-  virtual JSObject*
-  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
-  void GetData(OwningSmsMessageOrMmsMessage& aRetVal) const;
-
-private:
-  ~DOMMobileMessageError() {}
-
-  RefPtr<SmsMessage> mSms;
-  RefPtr<MmsMessage> mMms;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_MobileMessageError_h
deleted file mode 100644
--- a/dom/mobilemessage/DeletedMessageInfo.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=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 "DeletedMessageInfo.h"
-#include "nsComponentManagerUtils.h"    // for do_CreateInstance
-#include "nsVariant.h"
-
-namespace mozilla {
-namespace dom {
-namespace mobilemessage {
-
-NS_IMPL_ISUPPORTS(DeletedMessageInfo, nsIDeletedMessageInfo)
-
-DeletedMessageInfo::DeletedMessageInfo(const DeletedMessageInfoData& aData)
-  : mData(aData)
-{
-}
-
-DeletedMessageInfo::DeletedMessageInfo(int32_t* aMessageIds,
-                                       uint32_t aMsgCount,
-                                       uint64_t* aThreadIds,
-                                       uint32_t  aThreadCount)
-{
-  mData.deletedMessageIds().AppendElements(aMessageIds, aMsgCount);
-  mData.deletedThreadIds().AppendElements(aThreadIds, aThreadCount);
-}
-
-DeletedMessageInfo::~DeletedMessageInfo()
-{
-}
-
-/* static */ nsresult
-DeletedMessageInfo::Create(int32_t* aMessageIds,
-                           uint32_t aMsgCount,
-                           uint64_t* aThreadIds,
-                           uint32_t  aThreadCount,
-                           nsIDeletedMessageInfo** aDeletedInfo)
-{
-  NS_ENSURE_ARG_POINTER(aDeletedInfo);
-  NS_ENSURE_TRUE(aMsgCount || aThreadCount, NS_ERROR_INVALID_ARG);
-
-  nsCOMPtr<nsIDeletedMessageInfo> deletedInfo =
-    new DeletedMessageInfo(aMessageIds,
-                           aMsgCount,
-                           aThreadIds,
-                           aThreadCount);
-  deletedInfo.forget(aDeletedInfo);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-DeletedMessageInfo::GetDeletedMessageIds(nsIVariant** aDeletedMessageIds)
-{
-  NS_ENSURE_ARG_POINTER(aDeletedMessageIds);
-
-  if (mDeletedMessageIds) {
-    NS_ADDREF(*aDeletedMessageIds = mDeletedMessageIds);
-    return NS_OK;
-  }
-
-  uint32_t length = mData.deletedMessageIds().Length();
-
-  if (length == 0) {
-    *aDeletedMessageIds = nullptr;
-    return NS_OK;
-  }
-
-  mDeletedMessageIds = new nsVariant();
-
-  nsresult rv;
-  rv = mDeletedMessageIds->SetAsArray(nsIDataType::VTYPE_INT32,
-                                      nullptr,
-                                      length,
-                                      mData.deletedMessageIds().Elements());
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  mDeletedMessageIds->SetWritable(false);
-
-  NS_ADDREF(*aDeletedMessageIds = mDeletedMessageIds);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-DeletedMessageInfo::GetDeletedThreadIds(nsIVariant** aDeletedThreadIds)
-{
-  NS_ENSURE_ARG_POINTER(aDeletedThreadIds);
-
-  if (mDeletedThreadIds) {
-    NS_ADDREF(*aDeletedThreadIds = mDeletedThreadIds);
-    return NS_OK;
-  }
-
-  uint32_t length = mData.deletedThreadIds().Length();
-
-  if (length == 0) {
-    *aDeletedThreadIds = nullptr;
-    return NS_OK;
-  }
-
-  mDeletedThreadIds = new nsVariant();
-
-  nsresult rv;
-  rv = mDeletedThreadIds->SetAsArray(nsIDataType::VTYPE_UINT64,
-                                     nullptr,
-                                     length,
-                                     mData.deletedThreadIds().Elements());
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  mDeletedThreadIds->SetWritable(false);
-
-  NS_ADDREF(*aDeletedThreadIds = mDeletedThreadIds);
-
-  return NS_OK;
-}
-
-} // namespace mobilemessage
-} // namespace dom
-} // namespace mozilla
deleted file mode 100644
--- a/dom/mobilemessage/DeletedMessageInfo.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=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/. */
-
-#ifndef mozilla_dom_mobilemessage_DeletedMessageInfo_h
-#define mozilla_dom_mobilemessage_DeletedMessageInfo_h
-
-#include "mozilla/dom/mobilemessage/SmsTypes.h"
-#include "nsIDeletedMessageInfo.h"
-
-class nsIWritableVariant;
-
-namespace mozilla {
-namespace dom {
-namespace mobilemessage {
-
-class DeletedMessageInfo final : public nsIDeletedMessageInfo
-{
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIDELETEDMESSAGEINFO
-
-  explicit DeletedMessageInfo(const DeletedMessageInfoData& aData);
-
-  DeletedMessageInfo(int32_t* aMessageIds,
-                     uint32_t aMsgCount,
-                     uint64_t* aThreadIds,
-                     uint32_t  aThreadCount);
-
-  static nsresult Create(int32_t* aMessageIds,
-                         uint32_t aMsgCount,
-                         uint64_t* aThreadIds,
-                         uint32_t  aThreadCount,
-                         nsIDeletedMessageInfo** aDeletedInfo);
-
-  const DeletedMessageInfoData& GetData() const { return mData; }
-
-private:
-  // Don't try to use the default constructor.
-  DeletedMessageInfo();
-
-  ~DeletedMessageInfo();
-
-  DeletedMessageInfoData mData;
-
-  nsCOMPtr<nsIWritableVariant> mDeletedMessageIds;
-  nsCOMPtr<nsIWritableVariant> mDeletedThreadIds;
-
-protected:
-  /* additional members */
-};
-
-} // namespace mobilemessage
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_mobilemessage_DeletedMessageInfo_h
deleted file mode 100644
--- a/dom/mobilemessage/MmsMessage.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* 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 "MmsMessage.h"
-
-#include "MmsMessageInternal.h"
-#include "mozilla/dom/MmsMessageBinding.h"
-#include "nsPIDOMWindow.h"
-
-using namespace mozilla::dom::mobilemessage;
-
-namespace mozilla {
-namespace dom {
-
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(MmsMessage, mWindow, mMessage)
-NS_IMPL_CYCLE_COLLECTING_ADDREF(MmsMessage)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(MmsMessage)
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MmsMessage)
-  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-MmsMessage::MmsMessage(nsPIDOMWindowInner* aWindow, MmsMessageInternal* aMessage)
-  : mWindow(aWindow)
-  , mMessage(aMessage)
-{
-}
-
-MmsMessage::~MmsMessage()
-{
-}
-
-JSObject*
-MmsMessage::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
-  return MmsMessageBinding::Wrap(aCx, this, aGivenProto);
-}
-
-void
-MmsMessage::GetType(nsString& aRetVal) const
-{
-  mMessage->GetType(aRetVal);
-}
-
-int32_t
-MmsMessage::Id() const
-{
-  int32_t id;
-  mMessage->GetId(&id);
-  return id;
-}
-
-uint64_t
-MmsMessage::ThreadId() const
-{
-  uint64_t id;
-  mMessage->GetThreadId(&id);
-  return id;
-}
-
-void
-MmsMessage::GetIccId(nsString& aRetVal) const
-{
-  mMessage->GetIccId(aRetVal);
-}
-
-void
-MmsMessage::GetDelivery(nsString& aRetVal) const
-{
-  mMessage->GetDelivery(aRetVal);
-}
-
-void
-MmsMessage::GetDeliveryInfo(nsTArray<MmsDeliveryInfo>& aRetVal) const
-{
-  aRetVal = mMessage->mDeliveryInfo;
-}
-
-void
-MmsMessage::GetSender(nsString& aRetVal) const
-{
-  mMessage->GetSender(aRetVal);
-}
-
-void
-MmsMessage::GetReceivers(nsTArray<nsString>& aRetVal) const
-{
-  aRetVal = mMessage->mReceivers;
-}
-
-uint64_t
-MmsMessage::Timestamp() const
-{
-  uint64_t timestamp;
-  mMessage->GetTimestamp(&timestamp);
-  return timestamp;
-}
-
-uint64_t
-MmsMessage::SentTimestamp() const
-{
-  uint64_t timestamp;
-  mMessage->GetSentTimestamp(&timestamp);
-  return timestamp;
-}
-
-bool
-MmsMessage::Read() const
-{
-  bool read;
-  mMessage->GetRead(&read);
-  return read;
-}
-
-void
-MmsMessage::GetSubject(nsString& aRetVal) const
-{
-  mMessage->GetSubject(aRetVal);
-}
-
-void
-MmsMessage::GetSmil(nsString& aRetVal) const
-{
-  mMessage->GetSmil(aRetVal);
-}
-
-void
-MmsMessage::GetAttachments(nsTArray<MmsAttachment>& aRetVal) const
-{
-  uint32_t length = mMessage->mAttachments.Length();
-
-  // Duplicating the Blob with the correct parent object.
-  for (uint32_t i = 0; i < length; i++) {
-    MmsAttachment attachment;
-    const MmsAttachment &element = mMessage->mAttachments[i];
-    attachment.mId = element.mId;
-    attachment.mLocation = element.mLocation;
-    attachment.mContent = Blob::Create(mWindow, element.mContent->Impl());
-    aRetVal.AppendElement(attachment);
-  }
-}
-
-uint64_t
-MmsMessage::ExpiryDate() const
-{
-  uint64_t date;
-  mMessage->GetExpiryDate(&date);
-  return date;
-}
-
-bool
-MmsMessage::ReadReportRequested() const
-{
-  bool reportRequested;
-  mMessage->GetReadReportRequested(&reportRequested);
-  return reportRequested;
-}
-
-} // namespace dom
-} // namespace mozilla
deleted file mode 100644
--- a/dom/mobilemessage/MmsMessage.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_MmsMessage_h
-#define mozilla_dom_MmsMessage_h
-
-#include "mozilla/dom/BindingDeclarations.h"
-#include "nsWrapperCache.h"
-
-class nsPIDOMWindowInner;
-
-namespace mozilla {
-namespace dom {
-
-namespace mobilemessage {
-class MmsMessageInternal;
-} // namespace mobilemessage
-
-struct MmsAttachment;
-struct MmsDeliveryInfo;
-
-class MmsMessage final : public nsISupports,
-                         public nsWrapperCache
-{
-public:
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MmsMessage)
-
-  MmsMessage(nsPIDOMWindowInner* aWindow,
-             mobilemessage::MmsMessageInternal* aMessage);
-
-  nsPIDOMWindowInner*
-  GetParentObject() const
-  {
-    return mWindow;
-  }
-
-  virtual JSObject*
-  WrapObject(JSContext* aCx,
-             JS::Handle<JSObject*> aGivenProto) override;
-
-  void
-  GetType(nsString& aRetVal) const;
-
-  int32_t
-  Id() const;
-
-  uint64_t
-  ThreadId() const;
-
-  void
-  GetIccId(nsString& aRetVal) const;
-
-  void
-  GetDelivery(nsString& aRetVal) const;
-
-  void
-  GetDeliveryInfo(nsTArray<MmsDeliveryInfo>& aRetVal) const;
-
-  void
-  GetSender(nsString& aRetVal) const;
-
-  void
-  GetReceivers(nsTArray<nsString>& aRetVal) const;
-
-  uint64_t
-  Timestamp() const;
-
-  uint64_t
-  SentTimestamp() const;
-
-  bool
-  Read() const;
-
-  void
-  GetSubject(nsString& aRetVal) const;
-
-  void
-  GetSmil(nsString& aRetVal) const;
-
-  void
-  GetAttachments(nsTArray<MmsAttachment>& aRetVal) const;
-
-  uint64_t
-  ExpiryDate() const;
-
-  bool
-  ReadReportRequested() const;
-
-private:
-  // Don't try to use the default constructor.
-  MmsMessage() = delete;
-
-  ~MmsMessage();
-
-  nsCOMPtr<nsPIDOMWindowInner> mWindow;
-  RefPtr<mobilemessage::MmsMessageInternal> mMessage;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_MmsMessage_h
deleted file mode 100644
--- a/dom/mobilemessage/MmsMessageInternal.cpp
+++ /dev/null
@@ -1,614 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=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 "MmsMessageInternal.h"
-
-#include "nsIDOMClassInfo.h"
-#include "jsapi.h" // For JS_IsArrayObject, JS_GetElement, etc.
-#include "nsJSUtils.h"
-#include "nsContentUtils.h"
-#include "nsTArrayHelpers.h"
-#include "mozilla/dom/ContentParent.h"
-#include "mozilla/dom/File.h"
-#include "mozilla/dom/mobilemessage/Constants.h" // For MessageType
-#include "mozilla/dom/mobilemessage/SmsTypes.h"
-#include "mozilla/dom/ScriptSettings.h"
-#include "mozilla/dom/ToJSValue.h"
-#include "mozilla/dom/ipc/BlobChild.h"
-#include "mozilla/dom/ipc/BlobParent.h"
-
-
-namespace mozilla {
-namespace dom {
-namespace mobilemessage {
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(MmsMessageInternal)
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(MmsMessageInternal)
-  for (uint32_t i = 0; i < tmp->mAttachments.Length(); i++) {
-    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAttachments[i].mContent)
-  }
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(MmsMessageInternal)
-  for (uint32_t i = 0; i < tmp->mAttachments.Length(); i++) {
-    NS_IMPL_CYCLE_COLLECTION_UNLINK(mAttachments[i].mContent)
-  }
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MmsMessageInternal)
-  NS_INTERFACE_MAP_ENTRY(nsIMmsMessage)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(MmsMessageInternal)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(MmsMessageInternal)
-
-MmsMessageInternal::MmsMessageInternal(int32_t                          aId,
-                                       uint64_t                         aThreadId,
-                                       const nsAString&                 aIccId,
-                                       DeliveryState                    aDelivery,
-                                       const nsTArray<MmsDeliveryInfo>& aDeliveryInfo,
-                                       const nsAString&                 aSender,
-                                       const nsTArray<nsString>&        aReceivers,
-                                       uint64_t                         aTimestamp,
-                                       uint64_t                         aSentTimestamp,
-                                       bool                             aRead,
-                                       const nsAString&                 aSubject,
-                                       const nsAString&                 aSmil,
-                                       const nsTArray<MmsAttachment>&   aAttachments,
-                                       uint64_t                         aExpiryDate,
-                                       bool                             aReadReportRequested)
-  : mId(aId),
-    mThreadId(aThreadId),
-    mIccId(aIccId),
-    mDelivery(aDelivery),
-    mDeliveryInfo(aDeliveryInfo),
-    mSender(aSender),
-    mReceivers(aReceivers),
-    mTimestamp(aTimestamp),
-    mSentTimestamp(aSentTimestamp),
-    mRead(aRead),
-    mSubject(aSubject),
-    mSmil(aSmil),
-    mAttachments(aAttachments),
-    mExpiryDate(aExpiryDate),
-    mReadReportRequested(aReadReportRequested)
-{
-}
-
-MmsMessageInternal::MmsMessageInternal(const MmsMessageData& aData)
-  : mId(aData.id())
-  , mThreadId(aData.threadId())
-  , mIccId(aData.iccId())
-  , mDelivery(aData.delivery())
-  , mSender(aData.sender())
-  , mReceivers(aData.receivers())
-  , mTimestamp(aData.timestamp())
-  , mSentTimestamp(aData.sentTimestamp())
-  , mRead(aData.read())
-  , mSubject(aData.subject())
-  , mSmil(aData.smil())
-  , mExpiryDate(aData.expiryDate())
-  , mReadReportRequested(aData.readReportRequested())
-{
-  uint32_t len = aData.attachments().Length();
-  mAttachments.SetCapacity(len);
-  for (uint32_t i = 0; i < len; i++) {
-    MmsAttachment att;
-    const MmsAttachmentData &element = aData.attachments()[i];
-    att.mId = element.id();
-    att.mLocation = element.location();
-
-    // mContent is not going to be exposed to JS directly so we can use
-    // nullptr as parent.
-    if (element.contentParent()) {
-      RefPtr<BlobImpl> impl = static_cast<BlobParent*>(element.contentParent())->GetBlobImpl();
-      att.mContent = Blob::Create(nullptr, impl);
-    } else if (element.contentChild()) {
-      RefPtr<BlobImpl> impl = static_cast<BlobChild*>(element.contentChild())->GetBlobImpl();
-      att.mContent = Blob::Create(nullptr, impl);
-    } else {
-      NS_WARNING("MmsMessage: Unable to get attachment content.");
-    }
-    mAttachments.AppendElement(att);
-  }
-
-  len = aData.deliveryInfo().Length();
-  mDeliveryInfo.SetCapacity(len);
-  for (uint32_t i = 0; i < len; i++) {
-    MmsDeliveryInfo info;
-    const MmsDeliveryInfoData &infoData = aData.deliveryInfo()[i];
-
-    // Prepare |info.mReceiver|.
-    info.mReceiver = infoData.receiver();
-
-    // Prepare |info.mDeliveryStatus|.
-    nsString statusStr;
-    switch (infoData.deliveryStatus()) {
-      case eDeliveryStatus_NotApplicable:
-        statusStr = DELIVERY_STATUS_NOT_APPLICABLE;
-        break;
-      case eDeliveryStatus_Success:
-        statusStr = DELIVERY_STATUS_SUCCESS;
-        break;
-      case eDeliveryStatus_Pending:
-        statusStr = DELIVERY_STATUS_PENDING;
-        break;
-      case eDeliveryStatus_Error:
-        statusStr = DELIVERY_STATUS_ERROR;
-        break;
-      case eDeliveryStatus_Reject:
-        statusStr = DELIVERY_STATUS_REJECTED;
-        break;
-      case eDeliveryStatus_Manual:
-        statusStr = DELIVERY_STATUS_MANUAL;
-        break;
-      case eDeliveryStatus_EndGuard:
-      default:
-        MOZ_CRASH("We shouldn't get any other delivery status!");
-    }
-    info.mDeliveryStatus = statusStr;
-
-    // Prepare |info.mDeliveryTimestamp|.
-    info.mDeliveryTimestamp = infoData.deliveryTimestamp();
-
-    // Prepare |info.mReadStatus|.
-    nsString statusReadString;
-    switch(infoData.readStatus()) {
-      case eReadStatus_NotApplicable:
-        statusReadString = READ_STATUS_NOT_APPLICABLE;
-        break;
-      case eReadStatus_Success:
-        statusReadString = READ_STATUS_SUCCESS;
-        break;
-      case eReadStatus_Pending:
-        statusReadString = READ_STATUS_PENDING;
-        break;
-      case eReadStatus_Error:
-        statusReadString = READ_STATUS_ERROR;
-        break;
-      case eReadStatus_EndGuard:
-      default:
-        MOZ_CRASH("We shouldn't get any other read status!");
-    }
-    info.mReadStatus = statusReadString;
-
-    // Prepare |info.mReadTimestamp|.
-    info.mReadTimestamp = infoData.readTimestamp();
-
-    mDeliveryInfo.AppendElement(info);
-  }
-}
-
-/* static */ nsresult
-MmsMessageInternal::Create(int32_t aId,
-                           uint64_t aThreadId,
-                           const nsAString& aIccId,
-                           const nsAString& aDelivery,
-                           const JS::Value& aDeliveryInfo,
-                           const nsAString& aSender,
-                           const JS::Value& aReceivers,
-                           uint64_t aTimestamp,
-                           uint64_t aSentTimestamp,
-                           bool aRead,
-                           const nsAString& aSubject,
-                           const nsAString& aSmil,
-                           const JS::Value& aAttachments,
-                           uint64_t aExpiryDate,
-                           bool aIsReadReportRequested,
-                           JSContext* aCx,
-                           nsIMmsMessage** aMessage)
-{
-  *aMessage = nullptr;
-
-  // Set |delivery|.
-  DeliveryState delivery;
-  if (aDelivery.Equals(DELIVERY_SENT)) {
-    delivery = eDeliveryState_Sent;
-  } else if (aDelivery.Equals(DELIVERY_RECEIVED)) {
-    delivery = eDeliveryState_Received;
-  } else if (aDelivery.Equals(DELIVERY_SENDING)) {
-    delivery = eDeliveryState_Sending;
-  } else if (aDelivery.Equals(DELIVERY_NOT_DOWNLOADED)) {
-    delivery = eDeliveryState_NotDownloaded;
-  } else if (aDelivery.Equals(DELIVERY_ERROR)) {
-    delivery = eDeliveryState_Error;
-  } else {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  // Set |deliveryInfo|.
-  if (!aDeliveryInfo.isObject()) {
-    return NS_ERROR_INVALID_ARG;
-  }
-  JS::Rooted<JSObject*> deliveryInfoObj(aCx, &aDeliveryInfo.toObject());
-  bool isArray;
-  if (!JS_IsArrayObject(aCx, deliveryInfoObj, &isArray)) {
-    return NS_ERROR_FAILURE;
-  }
-  if (!isArray) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  uint32_t length;
-  MOZ_ALWAYS_TRUE(JS_GetArrayLength(aCx, deliveryInfoObj, &length));
-
-  nsTArray<MmsDeliveryInfo> deliveryInfo;
-  JS::Rooted<JS::Value> infoJsVal(aCx);
-  for (uint32_t i = 0; i < length; ++i) {
-    if (!JS_GetElement(aCx, deliveryInfoObj, i, &infoJsVal) ||
-        !infoJsVal.isObject()) {
-      return NS_ERROR_INVALID_ARG;
-    }
-
-    MmsDeliveryInfo info;
-    if (!info.Init(aCx, infoJsVal)) {
-      return NS_ERROR_TYPE_ERR;
-    }
-
-    deliveryInfo.AppendElement(info);
-  }
-
-  // Set |receivers|.
-  if (!aReceivers.isObject()) {
-    return NS_ERROR_INVALID_ARG;
-  }
-  JS::Rooted<JSObject*> receiversObj(aCx, &aReceivers.toObject());
-  if (!JS_IsArrayObject(aCx, receiversObj, &isArray)) {
-    return NS_ERROR_FAILURE;
-  }
-  if (!isArray) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  MOZ_ALWAYS_TRUE(JS_GetArrayLength(aCx, receiversObj, &length));
-
-  nsTArray<nsString> receivers;
-  JS::Rooted<JS::Value> receiverJsVal(aCx);
-  for (uint32_t i = 0; i < length; ++i) {
-    if (!JS_GetElement(aCx, receiversObj, i, &receiverJsVal) ||
-        !receiverJsVal.isString()) {
-      return NS_ERROR_INVALID_ARG;
-    }
-
-    nsAutoJSString receiverStr;
-    if (!receiverStr.init(aCx, receiverJsVal.toString())) {
-      return NS_ERROR_FAILURE;
-    }
-
-    receivers.AppendElement(receiverStr);
-  }
-
-  // Set |attachments|.
-  if (!aAttachments.isObject()) {
-    return NS_ERROR_INVALID_ARG;
-  }
-  JS::Rooted<JSObject*> attachmentsObj(aCx, &aAttachments.toObject());
-  if (!JS_IsArrayObject(aCx, attachmentsObj, &isArray)) {
-    return NS_ERROR_FAILURE;
-  }
-  if (!isArray) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  nsTArray<MmsAttachment> attachments;
-  MOZ_ALWAYS_TRUE(JS_GetArrayLength(aCx, attachmentsObj, &length));
-
-  JS::Rooted<JS::Value> attachmentJsVal(aCx);
-  for (uint32_t i = 0; i < length; ++i) {
-    if (!JS_GetElement(aCx, attachmentsObj, i, &attachmentJsVal)) {
-      return NS_ERROR_INVALID_ARG;
-    }
-
-    MmsAttachment attachment;
-    if (!attachment.Init(aCx, attachmentJsVal)) {
-      return NS_ERROR_TYPE_ERR;
-    }
-
-    NS_ENSURE_TRUE(attachment.mContent, NS_ERROR_TYPE_ERR);
-
-    attachments.AppendElement(attachment);
-  }
-
-  nsCOMPtr<nsIMmsMessage> message =
-    new MmsMessageInternal(aId,
-                           aThreadId,
-                           aIccId,
-                           delivery,
-                           deliveryInfo,
-                           aSender,
-                           receivers,
-                           aTimestamp,
-                           aSentTimestamp,
-                           aRead,
-                           aSubject,
-                           aSmil,
-                           attachments,
-                           aExpiryDate,
-                           aIsReadReportRequested);
-  message.forget(aMessage);
-  return NS_OK;
-}
-
-bool
-MmsMessageInternal::GetData(ContentParent* aParent,
-                            MmsMessageData& aData)
-{
-  NS_ASSERTION(aParent, "aParent is null");
-
-  aData.id() = mId;
-  aData.threadId() = mThreadId;
-  aData.iccId() = mIccId;
-  aData.delivery() = mDelivery;
-  aData.sender().Assign(mSender);
-  aData.receivers() = mReceivers;
-  aData.timestamp() = mTimestamp;
-  aData.sentTimestamp() = mSentTimestamp;
-  aData.read() = mRead;
-  aData.subject() = mSubject;
-  aData.smil() = mSmil;
-  aData.expiryDate() = mExpiryDate;
-  aData.readReportRequested() = mReadReportRequested;
-
-  aData.deliveryInfo().SetCapacity(mDeliveryInfo.Length());
-  for (uint32_t i = 0; i < mDeliveryInfo.Length(); i++) {
-    MmsDeliveryInfoData infoData;
-    const MmsDeliveryInfo &info = mDeliveryInfo[i];
-
-    // Prepare |infoData.mReceiver|.
-    infoData.receiver().Assign(info.mReceiver);
-
-    // Prepare |infoData.mDeliveryStatus|.
-    DeliveryStatus status;
-    if (info.mDeliveryStatus.Equals(DELIVERY_STATUS_NOT_APPLICABLE)) {
-      status = eDeliveryStatus_NotApplicable;
-    } else if (info.mDeliveryStatus.Equals(DELIVERY_STATUS_SUCCESS)) {
-      status = eDeliveryStatus_Success;
-    } else if (info.mDeliveryStatus.Equals(DELIVERY_STATUS_PENDING)) {
-      status = eDeliveryStatus_Pending;
-    } else if (info.mDeliveryStatus.Equals(DELIVERY_STATUS_ERROR)) {
-      status = eDeliveryStatus_Error;
-    } else if (info.mDeliveryStatus.Equals(DELIVERY_STATUS_REJECTED)) {
-      status = eDeliveryStatus_Reject;
-    } else if (info.mDeliveryStatus.Equals(DELIVERY_STATUS_MANUAL)) {
-      status = eDeliveryStatus_Manual;
-    } else {
-      return false;
-    }
-    infoData.deliveryStatus() = status;
-
-    // Prepare |infoData.mDeliveryTimestamp|.
-    infoData.deliveryTimestamp() = info.mDeliveryTimestamp;
-
-    // Prepare |infoData.mReadStatus|.
-    ReadStatus readStatus;
-    if (info.mReadStatus.Equals(READ_STATUS_NOT_APPLICABLE)) {
-      readStatus = eReadStatus_NotApplicable;
-    } else if (info.mReadStatus.Equals(READ_STATUS_SUCCESS)) {
-      readStatus = eReadStatus_Success;
-    } else if (info.mReadStatus.Equals(READ_STATUS_PENDING)) {
-      readStatus = eReadStatus_Pending;
-    } else if (info.mReadStatus.Equals(READ_STATUS_ERROR)) {
-      readStatus = eReadStatus_Error;
-    } else {
-      return false;
-    }
-    infoData.readStatus() = readStatus;
-
-    // Prepare |infoData.mReadTimestamp|.
-    infoData.readTimestamp() = info.mReadTimestamp;
-
-    aData.deliveryInfo().AppendElement(infoData);
-  }
-
-  aData.attachments().SetCapacity(mAttachments.Length());
-  for (uint32_t i = 0; i < mAttachments.Length(); i++) {
-    MmsAttachmentData mma;
-    const MmsAttachment &element = mAttachments[i];
-    mma.id().Assign(element.mId);
-    mma.location().Assign(element.mLocation);
-
-    // This is a workaround. Sometimes the blob we get from the database
-    // doesn't have a valid last modified date, making the ContentParent
-    // send a "Mystery Blob" to the ContentChild. Attempting to get the
-    // last modified date of blob can force that value to be initialized.
-    RefPtr<BlobImpl> impl = element.mContent->Impl();
-    if (impl && impl->IsDateUnknown()) {
-      ErrorResult rv;
-      impl->GetLastModified(rv);
-      if (rv.Failed()) {
-        NS_WARNING("Failed to get last modified date!");
-        rv.SuppressException();
-      }
-    }
-
-    mma.contentParent() = aParent->GetOrCreateActorForBlob(element.mContent);
-    if (!mma.contentParent()) {
-      return false;
-    }
-    aData.attachments().AppendElement(mma);
-  }
-
-  return true;
-}
-
-NS_IMETHODIMP
-MmsMessageInternal::GetType(nsAString& aType)
-{
-  aType = NS_LITERAL_STRING("mms");
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-MmsMessageInternal::GetId(int32_t* aId)
-{
-  *aId = mId;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-MmsMessageInternal::GetThreadId(uint64_t* aThreadId)
-{
-  *aThreadId = mThreadId;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-MmsMessageInternal::GetIccId(nsAString& aIccId)
-{
-  aIccId = mIccId;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-MmsMessageInternal::GetDelivery(nsAString& aDelivery)
-{
-  switch (mDelivery) {
-    case eDeliveryState_Received:
-      aDelivery = DELIVERY_RECEIVED;
-      break;
-    case eDeliveryState_Sending:
-      aDelivery = DELIVERY_SENDING;
-      break;
-    case eDeliveryState_Sent:
-      aDelivery = DELIVERY_SENT;
-      break;
-    case eDeliveryState_Error:
-      aDelivery = DELIVERY_ERROR;
-      break;
-    case eDeliveryState_NotDownloaded:
-      aDelivery = DELIVERY_NOT_DOWNLOADED;
-      break;
-    case eDeliveryState_Unknown:
-    case eDeliveryState_EndGuard:
-    default:
-      MOZ_CRASH("We shouldn't get any other delivery state!");
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-MmsMessageInternal::GetDeliveryInfo(JSContext* aCx, JS::MutableHandle<JS::Value> aDeliveryInfo)
-{
-  // TODO Bug 850525 It'd be better to depend on the delivery of MmsMessage
-  // to return a more correct value. Ex, if .delivery = 'received', we should
-  // also make .deliveryInfo = null, since the .deliveryInfo is useless.
-  uint32_t length = mDeliveryInfo.Length();
-  if (length == 0) {
-    aDeliveryInfo.setNull();
-    return NS_OK;
-  }
-
-  if (!ToJSValue(aCx, mDeliveryInfo, aDeliveryInfo)) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-MmsMessageInternal::GetSender(nsAString& aSender)
-{
-  aSender = mSender;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-MmsMessageInternal::GetReceivers(JSContext* aCx, JS::MutableHandle<JS::Value> aReceivers)
-{
-  JS::Rooted<JSObject*> receiversObj(aCx);
-  nsresult rv = nsTArrayToJSArray(aCx, mReceivers, &receiversObj);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  aReceivers.setObject(*receiversObj);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-MmsMessageInternal::GetTimestamp(DOMTimeStamp* aTimestamp)
-{
-  *aTimestamp = mTimestamp;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-MmsMessageInternal::GetSentTimestamp(DOMTimeStamp* aSentTimestamp)
-{
-  *aSentTimestamp = mSentTimestamp;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-MmsMessageInternal::GetRead(bool* aRead)
-{
-  *aRead = mRead;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-MmsMessageInternal::GetSubject(nsAString& aSubject)
-{
-  aSubject = mSubject;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-MmsMessageInternal::GetSmil(nsAString& aSmil)
-{
-  aSmil = mSmil;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-MmsMessageInternal::GetAttachments(JSContext* aCx, JS::MutableHandle<JS::Value> aAttachments)
-{
-  uint32_t length = mAttachments.Length();
-
-  if (length == 0) {
-    aAttachments.setNull();
-    return NS_OK;
-  }
-
-  // Duplicating the Blob with the correct parent object.
-  nsIGlobalObject* global = xpc::NativeGlobal(JS::CurrentGlobalOrNull(aCx));
-  MOZ_ASSERT(global);
-  nsTArray<MmsAttachment> result;
-  for (uint32_t i = 0; i < length; i++) {
-    MmsAttachment attachment;
-    const MmsAttachment &element = mAttachments[i];
-    attachment.mId = element.mId;
-    attachment.mLocation = element.mLocation;
-    attachment.mContent = Blob::Create(global, element.mContent->Impl());
-    result.AppendElement(attachment);
-  }
-
- if (!ToJSValue(aCx, result, aAttachments)) {
-    JS_ClearPendingException(aCx);
-    return NS_ERROR_TYPE_ERR;
- }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-MmsMessageInternal::GetExpiryDate(DOMTimeStamp* aExpiryDate)
-{
-  *aExpiryDate = mExpiryDate;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-MmsMessageInternal::GetReadReportRequested(bool* aReadReportRequested)
-{
-  *aReadReportRequested = mReadReportRequested;
-  return NS_OK;
-}
-
-} // namespace mobilemessage
-} // namespace dom
-} // namespace mozilla
deleted file mode 100644
--- a/dom/mobilemessage/MmsMessageInternal.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=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/. */
-
-#ifndef mozilla_dom_mobilemessage_MmsMessageInternal_h
-#define mozilla_dom_mobilemessage_MmsMessageInternal_h
-
-#include "nsIMmsMessage.h"
-#include "nsString.h"
-#include "mozilla/dom/mobilemessage/Types.h"
-#include "mozilla/dom/MmsMessageBinding.h"
-#include "mozilla/dom/MozMobileMessageManagerBinding.h"
-#include "mozilla/Attributes.h"
-
-namespace mozilla {
-namespace dom {
-
-class ContentParent;
-class Blob;
-struct MmsAttachment;
-class MmsMessage;
-
-namespace mobilemessage {
-
-class MmsMessageData;
-
-class MmsMessageInternal final : public nsIMmsMessage
-{
-  // This allows the MmsMessage class to access jsval data members
-  // like |deliveryInfo|, |receivers|, and |attachments| without JS API.
-  friend class mozilla::dom::MmsMessage;
-
-public:
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_CLASS(MmsMessageInternal)
-  NS_DECL_NSIMMSMESSAGE
-
-  MmsMessageInternal(int32_t aId,
-                     uint64_t aThreadId,
-                     const nsAString& aIccId,
-                     mobilemessage::DeliveryState aDelivery,
-                     const nsTArray<MmsDeliveryInfo>& aDeliveryInfo,
-                     const nsAString& aSender,
-                     const nsTArray<nsString>& aReceivers,
-                     uint64_t aTimestamp,
-                     uint64_t aSentTimestamp,
-                     bool aRead,
-                     const nsAString& aSubject,
-                     const nsAString& aSmil,
-                     const nsTArray<MmsAttachment>& aAttachments,
-                     uint64_t aExpiryDate,
-                     bool aReadReportRequested);
-
-  explicit MmsMessageInternal(const MmsMessageData& aData);
-
-  static nsresult Create(int32_t aId,
-                         uint64_t aThreadId,
-                         const nsAString& aIccId,
-                         const nsAString& aDelivery,
-                         const JS::Value& aDeliveryInfo,
-                         const nsAString& aSender,
-                         const JS::Value& aReceivers,
-                         uint64_t aTimestamp,
-                         uint64_t aSentTimestamp,
-                         bool aRead,
-                         const nsAString& aSubject,
-                         const nsAString& aSmil,
-                         const JS::Value& aAttachments,
-                         uint64_t aExpiryDate,
-                         bool aReadReportRequested,
-                         JSContext* aCx,
-                         nsIMmsMessage** aMessage);
-
-  bool GetData(ContentParent* aParent,
-               MmsMessageData& aData);
-
-private:
-
-  ~MmsMessageInternal() {}
-
-  int32_t mId;
-  uint64_t mThreadId;
-  nsString mIccId;
-  mobilemessage::DeliveryState mDelivery;
-  nsTArray<MmsDeliveryInfo> mDeliveryInfo;
-  nsString mSender;
-  nsTArray<nsString> mReceivers;
-  uint64_t mTimestamp;
-  uint64_t mSentTimestamp;
-  bool mRead;
-  nsString mSubject;
-  nsString mSmil;
-  nsTArray<MmsAttachment> mAttachments;
-  uint64_t mExpiryDate;
-  bool mReadReportRequested;
-};
-
-} // namespace mobilemessage
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_mobilemessage_MmsMessageInternal_h
deleted file mode 100644
--- a/dom/mobilemessage/MobileMessageCallback.cpp
+++ /dev/null
@@ -1,381 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=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 "MobileMessageCallback.h"
-#include "mozilla/dom/ToJSValue.h"
-#include "nsContentUtils.h"
-#include "nsIScriptGlobalObject.h"
-#include "nsPIDOMWindow.h"
-#include "MmsMessage.h"
-#include "MmsMessageInternal.h"
-#include "SmsMessage.h"
-#include "SmsMessageInternal.h"
-#include "mozilla/dom/ScriptSettings.h"
-#include "jsapi.h"
-#include "xpcpublic.h"
-#include "nsServiceManagerUtils.h"
-#include "nsTArrayHelpers.h"
-#include "DOMMobileMessageError.h"
-#include "mozilla/dom/Promise.h"
-
-namespace mozilla {
-namespace dom {
-namespace mobilemessage {
-
-static nsAutoString
-ConvertErrorCodeToErrorString(int32_t aError)
-{
-  nsAutoString errorStr;
-  switch (aError) {
-    case nsIMobileMessageCallback::NO_SIGNAL_ERROR:
-      errorStr = NS_LITERAL_STRING("NoSignalError");
-      break;
-    case nsIMobileMessageCallback::NOT_FOUND_ERROR:
-      errorStr = NS_LITERAL_STRING("NotFoundError");
-      break;
-    case nsIMobileMessageCallback::UNKNOWN_ERROR:
-      errorStr = NS_LITERAL_STRING("UnknownError");
-      break;
-    case nsIMobileMessageCallback::INTERNAL_ERROR:
-      errorStr = NS_LITERAL_STRING("InternalError");
-      break;
-    case nsIMobileMessageCallback::NO_SIM_CARD_ERROR:
-      errorStr = NS_LITERAL_STRING("NoSimCardError");
-      break;
-    case nsIMobileMessageCallback::RADIO_DISABLED_ERROR:
-      errorStr = NS_LITERAL_STRING("RadioDisabledError");
-      break;
-    case nsIMobileMessageCallback::INVALID_ADDRESS_ERROR:
-      errorStr = NS_LITERAL_STRING("InvalidAddressError");
-      break;
-    case nsIMobileMessageCallback::FDN_CHECK_ERROR:
-      errorStr = NS_LITERAL_STRING("FdnCheckError");
-      break;
-    case nsIMobileMessageCallback::NON_ACTIVE_SIM_CARD_ERROR:
-      errorStr = NS_LITERAL_STRING("NonActiveSimCardError");
-      break;
-    case nsIMobileMessageCallback::STORAGE_FULL_ERROR:
-      errorStr = NS_LITERAL_STRING("StorageFullError");
-      break;
-    case nsIMobileMessageCallback::SIM_NOT_MATCHED_ERROR:
-      errorStr = NS_LITERAL_STRING("SimNotMatchedError");
-      break;
-    case nsIMobileMessageCallback::NETWORK_PROBLEMS_ERROR:
-      errorStr = NS_LITERAL_STRING("NetworkProblemsError");
-      break;
-    case nsIMobileMessageCallback::GENERAL_PROBLEMS_ERROR:
-      errorStr = NS_LITERAL_STRING("GeneralProblemsError");
-      break;
-    case nsIMobileMessageCallback::SERVICE_NOT_AVAILABLE_ERROR:
-      errorStr = NS_LITERAL_STRING("ServiceNotAvailableError");
-      break;
-    case nsIMobileMessageCallback::MESSAGE_TOO_LONG_FOR_NETWORK_ERROR:
-      errorStr = NS_LITERAL_STRING("MessageTooLongForNetworkError");
-      break;
-    case nsIMobileMessageCallback::SERVICE_NOT_SUPPORTED_ERROR:
-      errorStr = NS_LITERAL_STRING("ServiceNotSupportedError");
-      break;
-    case nsIMobileMessageCallback::RETRY_REQUIRED_ERROR:
-      errorStr = NS_LITERAL_STRING("RetryRequiredError");
-      break;
-    default: // SUCCESS_NO_ERROR is handled above.
-      MOZ_CRASH("Should never get here!");
-  }
-
-  return errorStr;
-}
-
-NS_IMPL_ADDREF(MobileMessageCallback)
-NS_IMPL_RELEASE(MobileMessageCallback)
-
-NS_INTERFACE_MAP_BEGIN(MobileMessageCallback)
-  NS_INTERFACE_MAP_ENTRY(nsIMobileMessageCallback)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-MobileMessageCallback::MobileMessageCallback(DOMRequest* aDOMRequest)
-  : mDOMRequest(aDOMRequest)
-{
-}
-
-MobileMessageCallback::MobileMessageCallback(Promise* aPromise)
-  : mPromise(aPromise)
-{
-}
-
-MobileMessageCallback::~MobileMessageCallback()
-{
-}
-
-
-nsresult
-MobileMessageCallback::NotifySuccess(JS::Handle<JS::Value> aResult, bool aAsync)
-{
-  if (NS_WARN_IF(!mDOMRequest->GetOwner())) {
-    return NS_ERROR_FAILURE;
-  }
-
-  if (aAsync) {
-    nsCOMPtr<nsIDOMRequestService> rs =
-      do_GetService(DOMREQUEST_SERVICE_CONTRACTID);
-    NS_ENSURE_TRUE(rs, NS_ERROR_FAILURE);
-
-    return rs->FireSuccessAsync(mDOMRequest, aResult);
-  }
-
-  mDOMRequest->FireSuccess(aResult);
-  return NS_OK;
-}
-
-nsresult
-MobileMessageCallback::NotifySuccess(nsISupports *aMessage, bool aAsync)
-{
-  nsCOMPtr<nsPIDOMWindowInner> window = mDOMRequest->GetOwner();
-  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
-
-  nsCOMPtr<nsISupports> result;
-
-  nsCOMPtr<nsISmsMessage> internalSms =
-    do_QueryInterface(aMessage);
-  if (internalSms) {
-    SmsMessageInternal* smsMsg = static_cast<SmsMessageInternal*>(internalSms.get());
-    result = new SmsMessage(window, smsMsg);
-  }
-
-  if (!result) {
-    nsCOMPtr<nsIMmsMessage> internalMms =
-      do_QueryInterface(aMessage);
-    if (internalMms) {
-      MmsMessageInternal* mmsMsg = static_cast<MmsMessageInternal*>(internalMms.get());
-      result = new MmsMessage(window, mmsMsg);
-    }
-  }
-
-  AutoJSAPI jsapi;
-  if (NS_WARN_IF(!jsapi.Init(window))) {
-    return NS_ERROR_FAILURE;
-  }
-  JSContext* cx = jsapi.cx();
-
-  JS::Rooted<JS::Value> wrappedMessage(cx);
-  nsresult rv =
-    nsContentUtils::WrapNative(cx, result, &wrappedMessage);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return NotifySuccess(wrappedMessage, aAsync);
-}
-
-nsresult
-MobileMessageCallback::NotifyError(int32_t aError, DOMError *aDetailedError, bool aAsync)
-{
-  if (NS_WARN_IF(!mDOMRequest->GetOwner())) {
-    return NS_ERROR_FAILURE;
-  }
-
-  if (aAsync) {
-    NS_ASSERTION(!aDetailedError,
-      "No Support to FireDetailedErrorAsync() in nsIDOMRequestService!");
-
-    nsCOMPtr<nsIDOMRequestService> rs =
-      do_GetService(DOMREQUEST_SERVICE_CONTRACTID);
-    NS_ENSURE_TRUE(rs, NS_ERROR_FAILURE);
-
-    return rs->FireErrorAsync(mDOMRequest,
-                              ConvertErrorCodeToErrorString(aError));
-  }
-
-  if (aDetailedError) {
-    mDOMRequest->FireDetailedError(aDetailedError);
-  } else {
-    mDOMRequest->FireError(ConvertErrorCodeToErrorString(aError));
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-MobileMessageCallback::NotifyMessageSent(nsISupports *aMessage)
-{
-  return NotifySuccess(aMessage);
-}
-
-NS_IMETHODIMP
-MobileMessageCallback::NotifySendMessageFailed(int32_t aError, nsISupports *aMessage)
-{
-  nsCOMPtr<nsPIDOMWindowInner> window = mDOMRequest->GetOwner();
-  if (NS_WARN_IF(!window)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  RefPtr<DOMMobileMessageError> domMobileMessageError;
-  if (aMessage) {
-    nsAutoString errorStr = ConvertErrorCodeToErrorString(aError);
-    nsCOMPtr<nsISmsMessage> internalSms = do_QueryInterface(aMessage);
-    if (internalSms) {
-      domMobileMessageError =
-        new DOMMobileMessageError(window, errorStr,
-                                  new SmsMessage(window,
-                                  static_cast<SmsMessageInternal*>(internalSms.get())));
-    }
-    else {
-      nsCOMPtr<nsIMmsMessage> internalMms = do_QueryInterface(aMessage);
-      domMobileMessageError =
-        new DOMMobileMessageError(window, errorStr,
-                                  new MmsMessage(window,
-                                  static_cast<MmsMessageInternal*>(internalMms.get())));
-    }
-    NS_ASSERTION(domMobileMessageError, "Invalid DOMMobileMessageError!");
-  }
-
-  return NotifyError(aError, domMobileMessageError);
-}
-
-NS_IMETHODIMP
-MobileMessageCallback::NotifyMessageGot(nsISupports *aMessage)
-{
-  return NotifySuccess(aMessage);
-}
-
-NS_IMETHODIMP
-MobileMessageCallback::NotifyGetMessageFailed(int32_t aError)
-{
-  return NotifyError(aError);
-}
-
-NS_IMETHODIMP
-MobileMessageCallback::NotifyMessageDeleted(bool *aDeleted, uint32_t aSize)
-{
-  if (aSize == 1) {
-    AutoJSContext cx;
-    JS::Rooted<JS::Value> val(cx, JS::BooleanValue(*aDeleted));
-    return NotifySuccess(val);
-  }
-
-  AutoJSAPI jsapi;
-  if (NS_WARN_IF(!jsapi.Init(mDOMRequest->GetOwner()))) {
-    return NS_ERROR_FAILURE;
-  }
-  JSContext* cx = jsapi.cx();
-
-  JS::Rooted<JSObject*> deleteArrayObj(cx, JS_NewArrayObject(cx, aSize));
-  if (!deleteArrayObj) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-  for (uint32_t i = 0; i < aSize; i++) {
-    if (!JS_DefineElement(cx, deleteArrayObj, i, aDeleted[i],
-                          JSPROP_ENUMERATE)) {
-      return NS_ERROR_UNEXPECTED;
-    }
-  }
-
-  JS::Rooted<JS::Value> deleteArrayVal(cx, JS::ObjectValue(*deleteArrayObj));
-  return NotifySuccess(deleteArrayVal);
-}
-
-NS_IMETHODIMP
-MobileMessageCallback::NotifyDeleteMessageFailed(int32_t aError)
-{
-  return NotifyError(aError);
-}
-
-NS_IMETHODIMP
-MobileMessageCallback::NotifyMessageMarkedRead(bool aRead)
-{
-  AutoJSContext cx;
-  JS::Rooted<JS::Value> val(cx, JS::BooleanValue(aRead));
-  return NotifySuccess(val);
-}
-
-NS_IMETHODIMP
-MobileMessageCallback::NotifyMarkMessageReadFailed(int32_t aError)
-{
-  return NotifyError(aError);
-}
-
-NS_IMETHODIMP
-MobileMessageCallback::NotifySegmentInfoForTextGot(int32_t aSegments,
-                                                   int32_t aCharsPerSegment,
-                                                   int32_t aCharsAvailableInLastSegment)
-{
-  AutoJSAPI jsapi;
-  if (NS_WARN_IF(!jsapi.Init(mDOMRequest->GetOwner()))) {
-    return NotifyError(nsIMobileMessageCallback::INTERNAL_ERROR);
-  }
-
-  SmsSegmentInfo info;
-  info.mSegments = aSegments;
-  info.mCharsPerSegment = aCharsPerSegment;
-  info.mCharsAvailableInLastSegment = aCharsAvailableInLastSegment;
-
-  JSContext* cx = jsapi.cx();
-  JS::Rooted<JS::Value> val(cx);
-  if (!ToJSValue(cx, info, &val)) {
-    jsapi.ClearException();
-    return NotifyError(nsIMobileMessageCallback::INTERNAL_ERROR);
-  }
-
-  return NotifySuccess(val, true);
-}
-
-NS_IMETHODIMP
-MobileMessageCallback::NotifyGetSegmentInfoForTextFailed(int32_t aError)
-{
-  return NotifyError(aError, nullptr, true);
-}
-
-NS_IMETHODIMP
-MobileMessageCallback::NotifyGetSmscAddress(const nsAString& aSmscAddress,
-                                            uint32_t aTypeOfNumber,
-                                            uint32_t aNumberPlanIdentification)
-{
-  TypeOfAddress toa;
-
-  // Check the value is valid and set TON accordingly.
-  bool isTonValid = aTypeOfNumber < uint32_t(TypeOfNumber::EndGuard_);
-  toa.mTypeOfNumber = (isTonValid) ?
-    static_cast<TypeOfNumber>(aTypeOfNumber) : TypeOfNumber::Unknown;
-
-  // Check the value is valid and set NPI accordingly.
-  bool isNpiValid =
-    aNumberPlanIdentification < uint32_t(NumberPlanIdentification::EndGuard_);
-  toa.mNumberPlanIdentification = (isNpiValid) ?
-    static_cast<NumberPlanIdentification>(aNumberPlanIdentification) :
-    NumberPlanIdentification::Unknown;
-
-  SmscAddress smsc;
-  smsc.mTypeOfAddress = toa;
-  smsc.mAddress.Construct(nsString(aSmscAddress));
-
-  mPromise->MaybeResolve(smsc);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-MobileMessageCallback::NotifyGetSmscAddressFailed(int32_t aError)
-{
-  const nsAString& errorStr = ConvertErrorCodeToErrorString(aError);
-  mPromise->MaybeRejectBrokenly(errorStr);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-MobileMessageCallback::NotifySetSmscAddress()
-{
-  mPromise->MaybeResolveWithUndefined();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-MobileMessageCallback::NotifySetSmscAddressFailed(int32_t aError)
-{
-  const nsAString& errorStr = ConvertErrorCodeToErrorString(aError);
-  mPromise->MaybeRejectBrokenly(errorStr);
-  return NS_OK;
-}
-
-} // namespace mobilemessage
-} // namespace dom
-} // namespace mozilla
deleted file mode 100644
--- a/dom/mobilemessage/MobileMessageCallback.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=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/. */
-
-#ifndef mozilla_dom_mobilemessage_MobileMessageCallback_h
-#define mozilla_dom_mobilemessage_MobileMessageCallback_h
-
-#include "nsIMobileMessageCallback.h"
-#include "nsCOMPtr.h"
-#include "DOMRequest.h"
-
-class Promise;
-
-namespace mozilla {
-namespace dom {
-namespace mobilemessage {
-
-class MobileMessageCallback final : public nsIMobileMessageCallback
-{
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIMOBILEMESSAGECALLBACK
-
-  explicit MobileMessageCallback(DOMRequest* aDOMRequest);
-  explicit MobileMessageCallback(Promise* aPromise);
-
-private:
-  ~MobileMessageCallback();
-
-  RefPtr<DOMRequest> mDOMRequest;
-  RefPtr<Promise> mPromise;
-
-  nsresult NotifySuccess(JS::Handle<JS::Value> aResult, bool aAsync = false);
-  nsresult NotifySuccess(nsISupports *aMessage, bool aAsync = false);
-  nsresult NotifyError(int32_t aError, DOMError *aDetailedError = nullptr, bool aAsync = false);
-};
-
-} // namespace mobilemessage
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_mobilemessage_MobileMessageCallback_h
deleted file mode 100644
--- a/dom/mobilemessage/MobileMessageCursorCallback.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=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 "MobileMessageCursorCallback.h"
-#include "MmsMessage.h"
-#include "MmsMessageInternal.h"
-#include "MobileMessageThread.h"
-#include "MobileMessageThreadInternal.h"
-#include "mozilla/dom/ScriptSettings.h"
-#include "nsIDOMDOMRequest.h"
-#include "SmsMessage.h"
-#include "SmsMessageInternal.h"
-#include "nsIMobileMessageCallback.h"
-#include "nsServiceManagerUtils.h"      // for do_GetService
-
-namespace mozilla {
-namespace dom {
-
-NS_IMPL_CYCLE_COLLECTION_INHERITED(MobileMessageCursor, DOMCursor,
-                                   mPendingResults)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MobileMessageCursor)
-NS_INTERFACE_MAP_END_INHERITING(DOMCursor)
-
-NS_IMPL_ADDREF_INHERITED(MobileMessageCursor, DOMCursor)
-NS_IMPL_RELEASE_INHERITED(MobileMessageCursor, DOMCursor)
-
-MobileMessageCursor::MobileMessageCursor(nsPIDOMWindowInner* aWindow,
-                                         nsICursorContinueCallback* aCallback)
-  : DOMCursor(aWindow, aCallback)
-{
-}
-
-NS_IMETHODIMP
-MobileMessageCursor::Continue()
-{
-  // We have originally:
-  //
-  //   DOMCursor::Continue()
-  //   +-> DOMCursor::Continue(ErrorResult& aRv)
-  //
-  // Now it becomes:
-  //
-  //   MobileMessageCursor::Continue()
-  //   +-> DOMCursor::Continue()
-  //       +-> MobileMessageCursor::Continue(ErrorResult& aRv)
-  //           o-> DOMCursor::Continue(ErrorResult& aRv)
-  return DOMCursor::Continue();
-}
-
-void
-MobileMessageCursor::Continue(ErrorResult& aRv)
-{
-  // An ordinary DOMCursor works in following flow:
-  //
-  //   DOMCursor::Continue()
-  //   +-> DOMCursor::Reset()
-  //   +-> nsICursorContinueCallback::HandleContinue()
-  //       +-> nsIMobileMessageCursorCallback::NotifyCursorResult()
-  //           +-> DOMCursor::FireSuccess()
-  //
-  // With no pending result, we call to |DOMCursor::Continue()| as usual.
-  if (!mPendingResults.Length()) {
-    DOMCursor::Continue(aRv);
-    return;
-  }
-
-  // Otherwise, reset current result and fire a success event with the last
-  // pending one.
-  Reset();
-
-  nsresult rv = FireSuccessWithNextPendingResult();
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-  }
-}
-
-nsresult
-MobileMessageCursor::FireSuccessWithNextPendingResult()
-{
-  // We're going to pop the last element from mPendingResults, so it must not
-  // be empty.
-  MOZ_ASSERT(mPendingResults.Length());
-
-  nsCOMPtr<nsISupports> result;
-
-  nsCOMPtr<nsIMobileMessageThread> internalThread =
-    do_QueryInterface(mPendingResults.LastElement());
-  if (internalThread) {
-    MobileMessageThreadInternal* thread =
-      static_cast<MobileMessageThreadInternal*>(internalThread.get());
-    result = new MobileMessageThread(GetOwner(), thread);
-  }
-
-  if (!result) {
-    nsCOMPtr<nsISmsMessage> internalSms =
-      do_QueryInterface(mPendingResults.LastElement());
-    if (internalSms) {
-      SmsMessageInternal* sms = static_cast<SmsMessageInternal*>(internalSms.get());
-      result = new SmsMessage(GetOwner(), sms);
-    }
-  }
-
-  if (!result) {
-    nsCOMPtr<nsIMmsMessage> internalMms =
-      do_QueryInterface(mPendingResults.LastElement());
-    if (internalMms) {
-      MmsMessageInternal* mms = static_cast<MmsMessageInternal*>(internalMms.get());
-      result = new MmsMessage(GetOwner(), mms);
-    }
-  }
-
-  MOZ_ASSERT(result);
-
-  AutoJSAPI jsapi;
-  if (NS_WARN_IF(!jsapi.Init(GetOwner()))) {
-    return NS_ERROR_FAILURE;
-  }
-
-  JSContext* cx = jsapi.cx();
-  JS::Rooted<JS::Value> val(cx);
-  nsresult rv =
-    nsContentUtils::WrapNative(cx, result, &val);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  mPendingResults.RemoveElementAt(mPendingResults.Length() - 1);
-
-  FireSuccess(val);
-  return NS_OK;
-}
-
-namespace mobilemessage {
-
-NS_IMPL_CYCLE_COLLECTION(MobileMessageCursorCallback, mDOMCursor)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MobileMessageCursorCallback)
-  NS_INTERFACE_MAP_ENTRY(nsIMobileMessageCursorCallback)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(MobileMessageCursorCallback)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(MobileMessageCursorCallback)
-
-// nsIMobileMessageCursorCallback
-
-NS_IMETHODIMP
-MobileMessageCursorCallback::NotifyCursorError(int32_t aError)
-{
-  MOZ_ASSERT(mDOMCursor);
-
-  RefPtr<DOMCursor> cursor = mDOMCursor.forget();
-
-  switch (aError) {
-    case nsIMobileMessageCallback::NO_SIGNAL_ERROR:
-      cursor->FireError(NS_LITERAL_STRING("NoSignalError"));
-      break;
-    case nsIMobileMessageCallback::NOT_FOUND_ERROR:
-      cursor->FireError(NS_LITERAL_STRING("NotFoundError"));
-      break;
-    case nsIMobileMessageCallback::UNKNOWN_ERROR:
-      cursor->FireError(NS_LITERAL_STRING("UnknownError"));
-      break;
-    case nsIMobileMessageCallback::INTERNAL_ERROR:
-      cursor->FireError(NS_LITERAL_STRING("InternalError"));
-      break;
-    default: // SUCCESS_NO_ERROR is handled above.
-      MOZ_CRASH("Should never get here!");
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-MobileMessageCursorCallback::NotifyCursorResult(nsISupports** aResults,
-                                                uint32_t aSize)
-{
-  MOZ_ASSERT(mDOMCursor);
-  // We should only be notified with valid results. Or, either
-  // |NotifyCursorDone()| or |NotifyCursorError()| should be called instead.
-  MOZ_ASSERT(aResults && *aResults && aSize);
-  // There shouldn't be unexpected notifications before |Continue()| is called.
-  nsTArray<nsCOMPtr<nsISupports>>& pending = mDOMCursor->mPendingResults;
-  MOZ_ASSERT(pending.Length() == 0);
-
-  // Push pending results in reversed order.
-  pending.SetCapacity(pending.Length() + aSize);
-  while (aSize) {
-    --aSize;
-    pending.AppendElement(aResults[aSize]);
-  }
-
-  nsresult rv = mDOMCursor->FireSuccessWithNextPendingResult();
-  if (NS_FAILED(rv)) {
-    NotifyCursorError(nsIMobileMessageCallback::INTERNAL_ERROR);
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-MobileMessageCursorCallback::NotifyCursorDone()
-{
-  MOZ_ASSERT(mDOMCursor);
-
-  RefPtr<DOMCursor> cursor = mDOMCursor.forget();
-  cursor->FireDone();
-
-  return NS_OK;
-}
-
-} // namespace mobilemessage
-} // namespace dom
-} // namespace mozilla
deleted file mode 100644
--- a/dom/mobilemessage/MobileMessageCursorCallback.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=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/. */
-
-#ifndef mozilla_dom_mobilemessage_MobileMessageCursorCallback_h
-#define mozilla_dom_mobilemessage_MobileMessageCursorCallback_h
-
-#include "mozilla/Attributes.h"
-#include "mozilla/dom/DOMCursor.h"
-#include "nsIMobileMessageCursorCallback.h"
-#include "nsCycleCollectionParticipant.h"
-#include "nsCOMPtr.h"
-
-class nsICursorContinueCallback;
-
-namespace mozilla {
-namespace dom {
-
-class MobileMessageManager;
-
-namespace mobilemessage {
-class MobileMessageCursorCallback;
-} // namespace mobilemessage
-
-class MobileMessageCursor final : public DOMCursor
-{
-  friend class mobilemessage::MobileMessageCursorCallback;
-
-public:
-  NS_DECL_ISUPPORTS_INHERITED
-
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MobileMessageCursor, DOMCursor)
-
-  MobileMessageCursor(nsPIDOMWindowInner* aWindow,
-                      nsICursorContinueCallback* aCallback);
-
-  // Override XPIDL continue function to suppress -Werror,-Woverloaded-virtual.
-  NS_IMETHOD
-  Continue(void) override;
-
-  virtual void
-  Continue(ErrorResult& aRv) override;
-
-private:
-  // final suppresses -Werror,-Wdelete-non-virtual-dtor
-  ~MobileMessageCursor() {}
-
-private:
-  // List of read-ahead results in reversed order.
-  nsTArray<nsCOMPtr<nsISupports>> mPendingResults;
-
-  nsresult
-  FireSuccessWithNextPendingResult();
-};
-
-namespace mobilemessage {
-
-class MobileMessageCursorCallback final : public nsIMobileMessageCursorCallback
-{
-  friend class mozilla::dom::MobileMessageManager;
-
-public:
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_NSIMOBILEMESSAGECURSORCALLBACK
-
-  NS_DECL_CYCLE_COLLECTION_CLASS(MobileMessageCursorCallback)
-
-  MobileMessageCursorCallback()
-  {
-    MOZ_COUNT_CTOR(MobileMessageCursorCallback);
-  }
-
-private:
-  // final suppresses -Werror,-Wdelete-non-virtual-dtor
-  ~MobileMessageCursorCallback()
-  {
-    MOZ_COUNT_DTOR(MobileMessageCursorCallback);
-  }
-
-  RefPtr<MobileMessageCursor> mDOMCursor;
-};
-
-} // namespace mobilemessage
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_mobilemessage_MobileMessageCursorCallback_h
-
deleted file mode 100644
--- a/dom/mobilemessage/MobileMessageManager.cpp
+++ /dev/null
@@ -1,905 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=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 "MobileMessageManager.h"
-
-#include "DeletedMessageInfo.h"
-#include "DOMCursor.h"
-#include "DOMRequest.h"
-#include "MmsMessage.h"
-#include "MmsMessageInternal.h"
-#include "MobileMessageCallback.h"
-#include "MobileMessageCursorCallback.h"
-#include "SmsMessage.h"
-#include "SmsMessageInternal.h"
-#include "mozilla/dom/mobilemessage/Constants.h" // For kSms*ObserverTopic
-#include "mozilla/dom/MozMessageDeletedEvent.h"
-#include "mozilla/dom/MozMmsEvent.h"
-#include "mozilla/dom/MozMobileMessageManagerBinding.h"
-#include "mozilla/dom/MozSmsEvent.h"
-#include "mozilla/dom/Promise.h"
-#include "mozilla/dom/ToJSValue.h"
-#include "mozilla/Preferences.h"
-#include "mozilla/Services.h"
-#include "mozilla/UniquePtr.h"
-#include "nsIMmsService.h"
-#include "nsIMobileMessageCallback.h"
-#include "nsIMobileMessageDatabaseService.h"
-#include "nsIMobileMessageService.h"
-#include "nsIObserverService.h"
-#include "nsISmsService.h"
-#include "nsServiceManagerUtils.h" // For do_GetService()
-
-// Service instantiation
-#include "ipc/SmsIPCService.h"
-#include "MobileMessageService.h"
-#if defined(MOZ_WIDGET_ANDROID) && defined(MOZ_WEBSMS_BACKEND)
-#include "android/MobileMessageDatabaseService.h"
-#include "android/SmsService.h"
-#elif defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
-#include "nsIGonkMobileMessageDatabaseService.h"
-#include "nsIGonkSmsService.h"
-#endif
-#include "nsXULAppAPI.h" // For XRE_GetProcessType()
-
-#define RECEIVED_EVENT_NAME         NS_LITERAL_STRING("received")
-#define RETRIEVING_EVENT_NAME       NS_LITERAL_STRING("retrieving")
-#define SENDING_EVENT_NAME          NS_LITERAL_STRING("sending")
-#define SENT_EVENT_NAME             NS_LITERAL_STRING("sent")
-#define FAILED_EVENT_NAME           NS_LITERAL_STRING("failed")
-#define DELIVERY_SUCCESS_EVENT_NAME NS_LITERAL_STRING("deliverysuccess")
-#define DELIVERY_ERROR_EVENT_NAME   NS_LITERAL_STRING("deliveryerror")
-#define READ_SUCCESS_EVENT_NAME     NS_LITERAL_STRING("readsuccess")
-#define READ_ERROR_EVENT_NAME       NS_LITERAL_STRING("readerror")
-#define DELETED_EVENT_NAME          NS_LITERAL_STRING("deleted")
-
-using namespace mozilla::dom::mobilemessage;
-
-namespace mozilla {
-namespace dom {
-
-NS_INTERFACE_MAP_BEGIN(MobileMessageManager)
-  NS_INTERFACE_MAP_ENTRY(nsIObserver)
-NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
-
-NS_IMPL_ADDREF_INHERITED(MobileMessageManager, DOMEventTargetHelper)
-NS_IMPL_RELEASE_INHERITED(MobileMessageManager, DOMEventTargetHelper)
-
-MobileMessageManager::MobileMessageManager(nsPIDOMWindowInner* aWindow)
-  : DOMEventTargetHelper(aWindow)
-{
-}
-
-void
-MobileMessageManager::Init()
-{
-  nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
-  // GetObserverService() can return null is some situations like shutdown.
-  if (!obs) {
-    return;
-  }
-
-  obs->AddObserver(this, kSmsReceivedObserverTopic, false);
-  obs->AddObserver(this, kSmsRetrievingObserverTopic, false);
-  obs->AddObserver(this, kSmsSendingObserverTopic, false);
-  obs->AddObserver(this, kSmsSentObserverTopic, false);
-  obs->AddObserver(this, kSmsFailedObserverTopic, false);
-  obs->AddObserver(this, kSmsDeliverySuccessObserverTopic, false);
-  obs->AddObserver(this, kSmsDeliveryErrorObserverTopic, false);
-  obs->AddObserver(this, kSmsReadSuccessObserverTopic, false);
-  obs->AddObserver(this, kSmsReadErrorObserverTopic, false);
-  obs->AddObserver(this, kSmsDeletedObserverTopic, false);
-}
-
-void
-MobileMessageManager::Shutdown()
-{
-  nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
-  // GetObserverService() can return null is some situations like shutdown.
-  if (!obs) {
-    return;
-  }
-
-  obs->RemoveObserver(this, kSmsReceivedObserverTopic);
-  obs->RemoveObserver(this, kSmsRetrievingObserverTopic);
-  obs->RemoveObserver(this, kSmsSendingObserverTopic);
-  obs->RemoveObserver(this, kSmsSentObserverTopic);
-  obs->RemoveObserver(this, kSmsFailedObserverTopic);
-  obs->RemoveObserver(this, kSmsDeliverySuccessObserverTopic);
-  obs->RemoveObserver(this, kSmsDeliveryErrorObserverTopic);
-  obs->RemoveObserver(this, kSmsReadSuccessObserverTopic);
-  obs->RemoveObserver(this, kSmsReadErrorObserverTopic);
-  obs->RemoveObserver(this, kSmsDeletedObserverTopic);
-}
-
-JSObject*
-MobileMessageManager::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
-  return MozMobileMessageManagerBinding::Wrap(aCx, this, aGivenProto);
-}
-
-already_AddRefed<DOMRequest>
-MobileMessageManager::GetSegmentInfoForText(const nsAString& aText,
-                                            ErrorResult& aRv)
-{
-  nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
-  if (!smsService) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
-  if (!window) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  RefPtr<DOMRequest> request = new DOMRequest(window);
-  nsCOMPtr<nsIMobileMessageCallback> msgCallback =
-    new MobileMessageCallback(request);
-  nsresult rv = smsService->GetSegmentInfoForText(aText, msgCallback);
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-    return nullptr;
-  }
-
-  return request.forget();
-}
-
-already_AddRefed<DOMRequest>
-MobileMessageManager::Send(nsISmsService* aSmsService,
-                           uint32_t aServiceId,
-                           const nsAString& aNumber,
-                           const nsAString& aText,
-                           ErrorResult& aRv)
-{
-  nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
-  if (!window) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  RefPtr<DOMRequest> request = new DOMRequest(window);
-  nsCOMPtr<nsIMobileMessageCallback> msgCallback =
-    new MobileMessageCallback(request);
-
-  // By default, we don't send silent messages via MobileMessageManager.
-  nsresult rv = aSmsService->Send(aServiceId, aNumber, aText,
-                                  false, msgCallback);
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-    return nullptr;
-  }
-
-  return request.forget();
-}
-
-already_AddRefed<DOMRequest>
-MobileMessageManager::Send(const nsAString& aNumber,
-                           const nsAString& aText,
-                           const SmsSendParameters& aSendParams,
-                           ErrorResult& aRv)
-{
-  nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
-  if (!smsService) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  // Use the default one unless |aSendParams.serviceId| is available.
-  uint32_t serviceId;
-  if (aSendParams.mServiceId.WasPassed()) {
-    serviceId = aSendParams.mServiceId.Value();
-  } else {
-    nsresult rv = smsService->GetSmsDefaultServiceId(&serviceId);
-    if (NS_FAILED(rv)) {
-      aRv.Throw(rv);
-      return nullptr;
-    }
-  }
-
-  return Send(smsService, serviceId, aNumber, aText, aRv);
-}
-
-void
-MobileMessageManager::Send(const Sequence<nsString>& aNumbers,
-                           const nsAString& aText,
-                           const SmsSendParameters& aSendParams,
-                           nsTArray<RefPtr<DOMRequest>>& aReturn,
-                           ErrorResult& aRv)
-{
-  nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
-  if (!smsService) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return;
-  }
-
-  // Use the default one unless |aSendParams.serviceId| is available.
-  uint32_t serviceId;
-  if (aSendParams.mServiceId.WasPassed()) {
-    serviceId = aSendParams.mServiceId.Value();
-  } else {
-    nsresult rv = smsService->GetSmsDefaultServiceId(&serviceId);
-    if (NS_FAILED(rv)) {
-      aRv.Throw(rv);
-      return;
-    }
-  }
-
-  const uint32_t size = aNumbers.Length();
-  for (uint32_t i = 0; i < size; ++i) {
-    RefPtr<DOMRequest> request = Send(smsService, serviceId, aNumbers[i], aText, aRv);
-    if (aRv.Failed()) {
-      return;
-    }
-    aReturn.AppendElement(request);
-  }
-}
-
-already_AddRefed<DOMRequest>
-MobileMessageManager::SendMMS(const MmsParameters& aParams,
-                              const MmsSendParameters& aSendParams,
-                              ErrorResult& aRv)
-{
-  nsCOMPtr<nsIMmsService> mmsService = do_GetService(MMS_SERVICE_CONTRACTID);
-  if (!mmsService) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  // Use the default one unless |aSendParams.serviceId| is available.
-  uint32_t serviceId;
-  nsresult rv;
-  if (aSendParams.mServiceId.WasPassed()) {
-    serviceId = aSendParams.mServiceId.Value();
-  } else {
-    rv = mmsService->GetMmsDefaultServiceId(&serviceId);
-    if (NS_FAILED(rv)) {
-      aRv.Throw(rv);
-      return nullptr;
-    }
-  }
-
-  nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
-  if (!window) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  AutoJSAPI jsapi;
-  if (NS_WARN_IF(!jsapi.Init(window))) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  JSContext *cx = jsapi.cx();
-  JS::Rooted<JS::Value> val(cx);
-  aRv.MightThrowJSException();
-  if (!ToJSValue(cx, aParams, &val)) {
-    aRv.StealExceptionFromJSContext(cx);
-    return nullptr;
-  }
-
-  RefPtr<DOMRequest> request = new DOMRequest(window);
-  nsCOMPtr<nsIMobileMessageCallback> msgCallback = new MobileMessageCallback(request);
-  rv = mmsService->Send(serviceId, val, msgCallback);
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-    return nullptr;
-  }
-
-  return request.forget();
-}
-
-already_AddRefed<DOMRequest>
-MobileMessageManager::GetMessage(int32_t aId,
-                                 ErrorResult& aRv)
-{
-  nsCOMPtr<nsIMobileMessageDatabaseService> dbService =
-    do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID);
-  if (!dbService) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
-  if (!window) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  RefPtr<DOMRequest> request = new DOMRequest(window);
-  nsCOMPtr<nsIMobileMessageCallback> msgCallback = new MobileMessageCallback(request);
-  nsresult rv = dbService->GetMessageMoz(aId, msgCallback);
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-    return nullptr;
-  }
-
-  return request.forget();
-}
-
-already_AddRefed<DOMRequest>
-MobileMessageManager::Delete(int32_t* aIdArray,
-                             uint32_t aSize,
-                             ErrorResult& aRv)
-{
-  nsCOMPtr<nsIMobileMessageDatabaseService> dbService =
-    do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID);
-  if (!dbService) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
-  if (!window) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  RefPtr<DOMRequest> request = new DOMRequest(window);
-  nsCOMPtr<nsIMobileMessageCallback> msgCallback =
-    new MobileMessageCallback(request);
-
-  nsresult rv = dbService->DeleteMessage(aIdArray, aSize, msgCallback);
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-    return nullptr;
-  }
-
-  return request.forget();
-}
-
-already_AddRefed<DOMRequest>
-MobileMessageManager::Delete(int32_t aId,
-                             ErrorResult& aRv)
-{
-  return Delete(&aId, 1, aRv);
-}
-
-already_AddRefed<DOMRequest>
-MobileMessageManager::Delete(SmsMessage& aMessage,
-                             ErrorResult& aRv)
-{
-  return Delete(aMessage.Id(), aRv);
-}
-
-already_AddRefed<DOMRequest>
-MobileMessageManager::Delete(MmsMessage& aMessage,
-                             ErrorResult& aRv)
-{
-  return Delete(aMessage.Id(), aRv);
-}
-
-already_AddRefed<DOMRequest>
-MobileMessageManager::Delete(const Sequence<OwningLongOrSmsMessageOrMmsMessage>& aParams,
-                             ErrorResult& aRv)
-{
-  const uint32_t size = aParams.Length();
-  FallibleTArray<int32_t> idArray;
-  if (!idArray.SetLength(size, fallible)) {
-    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
-    return nullptr;
-  }
-
-  DebugOnly<nsresult> rv;
-  for (uint32_t i = 0; i < size; i++) {
-    const OwningLongOrSmsMessageOrMmsMessage& element = aParams[i];
-    int32_t &id = idArray[i];
-
-    if (element.IsLong()) {
-      id = element.GetAsLong();
-    } else if (element.IsMmsMessage()) {
-      id = element.GetAsMmsMessage()->Id();
-    } else /*if (element.IsSmsMessage())*/ {
-      id = element.GetAsSmsMessage()->Id();
-    }
-  }
-
-  return Delete(idArray.Elements(), size, aRv);
-}
-
-already_AddRefed<DOMCursor>
-MobileMessageManager::GetMessages(const MobileMessageFilter& aFilter,
-                                  bool aReverse,
-                                  ErrorResult& aRv)
-{
-  nsCOMPtr<nsIMobileMessageDatabaseService> dbService =
-    do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID);
-  if (!dbService) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  bool hasStartDate = !aFilter.mStartDate.IsNull();
-  uint64_t startDate = 0;
-  if (hasStartDate) {
-    startDate = aFilter.mStartDate.Value();
-  }
-
-  bool hasEndDate = !aFilter.mEndDate.IsNull();
-  uint64_t endDate = 0;
-  if (hasEndDate) {
-    endDate = aFilter.mEndDate.Value();
-  }
-
-  UniquePtr<const char16_t*[]> ptrNumbers;
-  uint32_t numbersCount = 0;
-  if (!aFilter.mNumbers.IsNull() &&
-      aFilter.mNumbers.Value().Length()) {
-    const FallibleTArray<nsString>& numbers = aFilter.mNumbers.Value();
-    uint32_t index;
-
-    numbersCount = numbers.Length();
-    ptrNumbers = MakeUnique<const char16_t*[]>(numbersCount);
-    for (index = 0; index < numbersCount; index++) {
-      ptrNumbers[index] = numbers[index].get();
-    }
-  }
-
-  nsString delivery;
-  delivery.SetIsVoid(true);
-  if (!aFilter.mDelivery.IsNull()) {
-    const uint32_t index = static_cast<uint32_t>(aFilter.mDelivery.Value());
-    const EnumEntry& entry =
-      MobileMessageFilterDeliveryValues::strings[index];
-    delivery.AssignASCII(entry.value, entry.length);
-  }
-
-  bool hasRead = !aFilter.mRead.IsNull();
-  bool read = false;
-  if (hasRead) {
-    read = aFilter.mRead.Value();
-  }
-
-  bool hasThreadId = !aFilter.mThreadId.IsNull();
-  uint64_t threadId = 0;
-  if (hasThreadId) {
-    threadId = aFilter.mThreadId.Value();
-  }
-
-  RefPtr<MobileMessageCursorCallback> cursorCallback =
-    new MobileMessageCursorCallback();
-  nsCOMPtr<nsICursorContinueCallback> continueCallback;
-  nsresult rv = dbService->CreateMessageCursor(hasStartDate, startDate,
-                                               hasEndDate, endDate,
-                                               ptrNumbers.get(), numbersCount,
-                                               delivery,
-                                               hasRead, read,
-                                               hasThreadId, threadId,
-                                               aReverse, cursorCallback,
-                                               getter_AddRefs(continueCallback));
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-    return nullptr;
-  }
-
-  nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
-  if (!window) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  cursorCallback->mDOMCursor =
-    new MobileMessageCursor(window, continueCallback);
-
-  RefPtr<DOMCursor> cursor(cursorCallback->mDOMCursor);
-  return cursor.forget();
-}
-
-already_AddRefed<DOMRequest>
-MobileMessageManager::MarkMessageRead(int32_t aId,
-                                      bool aValue,
-                                      bool aSendReadReport,
-                                      ErrorResult& aRv)
-{
-  nsCOMPtr<nsIMobileMessageDatabaseService> dbService =
-    do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID);
-  if (!dbService) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
-  if (!window) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  RefPtr<DOMRequest> request = new DOMRequest(window);
-  nsCOMPtr<nsIMobileMessageCallback> msgCallback = new MobileMessageCallback(request);
-  nsresult rv = dbService->MarkMessageRead(aId, aValue, aSendReadReport,
-                                           msgCallback);
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-    return nullptr;
-  }
-
-  return request.forget();
-}
-
-already_AddRefed<DOMCursor>
-MobileMessageManager::GetThreads(ErrorResult& aRv)
-{
-  nsCOMPtr<nsIMobileMessageDatabaseService> dbService =
-    do_GetService(MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID);
-  if (!dbService) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  RefPtr<MobileMessageCursorCallback> cursorCallback =
-    new MobileMessageCursorCallback();
-
-  nsCOMPtr<nsICursorContinueCallback> continueCallback;
-  nsresult rv = dbService->CreateThreadCursor(cursorCallback,
-                                              getter_AddRefs(continueCallback));
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-    return nullptr;
-  }
-
-  nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
-  if (!window) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  cursorCallback->mDOMCursor =
-    new MobileMessageCursor(window, continueCallback);
-
-  RefPtr<DOMCursor> cursor(cursorCallback->mDOMCursor);
-  return cursor.forget();
-}
-
-already_AddRefed<DOMRequest>
-MobileMessageManager::RetrieveMMS(int32_t aId,
-                                  ErrorResult& aRv)
-{
-  nsCOMPtr<nsIMmsService> mmsService = do_GetService(MMS_SERVICE_CONTRACTID);
-  if (!mmsService) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
-  if (!window) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  RefPtr<DOMRequest> request = new DOMRequest(window);
-  nsCOMPtr<nsIMobileMessageCallback> msgCallback = new MobileMessageCallback(request);
-
-  nsresult rv = mmsService->Retrieve(aId, msgCallback);
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-    return nullptr;
-  }
-
-  return request.forget();
-}
-
-already_AddRefed<DOMRequest>
-MobileMessageManager::RetrieveMMS(MmsMessage& aMessage,
-                                  ErrorResult& aRv)
-{
-  return RetrieveMMS(aMessage.Id(), aRv);
-}
-
-nsresult
-MobileMessageManager::DispatchTrustedSmsEventToSelf(const char* aTopic,
-                                                    const nsAString& aEventName,
-                                                    nsISupports* aMsg)
-{
-  nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
-  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
-
-  nsCOMPtr<nsISmsMessage> sms = do_QueryInterface(aMsg);
-  if (sms) {
-    MozSmsEventInit init;
-    init.mBubbles = false;
-    init.mCancelable = false;
-    init.mMessage =
-      new SmsMessage(window, static_cast<SmsMessageInternal*>(sms.get()));
-
-    RefPtr<MozSmsEvent> event =
-      MozSmsEvent::Constructor(this, aEventName, init);
-    return DispatchTrustedEvent(event);
-  }
-
-  nsCOMPtr<nsIMmsMessage> mms = do_QueryInterface(aMsg);
-  if (mms) {
-    MozMmsEventInit init;
-    init.mBubbles = false;
-    init.mCancelable = false;
-    init.mMessage =
-      new MmsMessage(window, static_cast<MmsMessageInternal*>(mms.get()));
-
-    RefPtr<MozMmsEvent> event =
-      MozMmsEvent::Constructor(this, aEventName, init);
-    return DispatchTrustedEvent(event);
-  }
-
-  nsAutoCString errorMsg;
-  errorMsg.AssignLiteral("Got a '");
-  errorMsg.Append(aTopic);
-  errorMsg.AppendLiteral("' topic without a valid message!");
-  NS_ERROR(errorMsg.get());
-  return NS_OK;
-}
-
-nsresult
-MobileMessageManager::DispatchTrustedDeletedEventToSelf(nsISupports* aDeletedInfo)
-{
-  nsCOMPtr<nsIDeletedMessageInfo> deletedInfo = do_QueryInterface(aDeletedInfo);
-  if (deletedInfo) {
-    MozMessageDeletedEventInit init;
-    init.mBubbles = false;
-    init.mCancelable = false;
-    DeletedMessageInfo* info =
-      static_cast<DeletedMessageInfo*>(deletedInfo.get());
-
-    uint32_t msgIdLength = info->GetData().deletedMessageIds().Length();
-    if (msgIdLength) {
-      Sequence<int32_t>& deletedMsgIds = init.mDeletedMessageIds.SetValue();
-      if (!deletedMsgIds.AppendElements(info->GetData().deletedMessageIds(),
-                                        fallible)) {
-        return NS_ERROR_OUT_OF_MEMORY;
-      }
-    }
-
-    uint32_t threadIdLength = info->GetData().deletedThreadIds().Length();
-    if (threadIdLength) {
-      Sequence<uint64_t>& deletedThreadIds = init.mDeletedThreadIds.SetValue();
-      if (!deletedThreadIds.AppendElements(info->GetData().deletedThreadIds(),
-                                           fallible)) {
-        return NS_ERROR_OUT_OF_MEMORY;
-      }
-    }
-
-    RefPtr<MozMessageDeletedEvent> event =
-      MozMessageDeletedEvent::Constructor(this, DELETED_EVENT_NAME, init);
-    return DispatchTrustedEvent(event);
-  }
-
-  NS_ERROR("Got a 'deleted' topic without a valid message!");
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-MobileMessageManager::Observe(nsISupports* aSubject, const char* aTopic,
-                              const char16_t* aData)
-{
-  if (!strcmp(aTopic, kSmsReceivedObserverTopic)) {
-    return DispatchTrustedSmsEventToSelf(aTopic, RECEIVED_EVENT_NAME, aSubject);
-  }
-
-  if (!strcmp(aTopic, kSmsRetrievingObserverTopic)) {
-    return DispatchTrustedSmsEventToSelf(aTopic, RETRIEVING_EVENT_NAME, aSubject);
-  }
-
-  if (!strcmp(aTopic, kSmsSendingObserverTopic)) {
-    return DispatchTrustedSmsEventToSelf(aTopic, SENDING_EVENT_NAME, aSubject);
-  }
-
-  if (!strcmp(aTopic, kSmsSentObserverTopic)) {
-    return DispatchTrustedSmsEventToSelf(aTopic, SENT_EVENT_NAME, aSubject);
-  }
-
-  if (!strcmp(aTopic, kSmsFailedObserverTopic)) {
-    return DispatchTrustedSmsEventToSelf(aTopic, FAILED_EVENT_NAME, aSubject);
-  }
-
-  if (!strcmp(aTopic, kSmsDeliverySuccessObserverTopic)) {
-    return DispatchTrustedSmsEventToSelf(aTopic, DELIVERY_SUCCESS_EVENT_NAME, aSubject);
-  }
-
-  if (!strcmp(aTopic, kSmsDeliveryErrorObserverTopic)) {
-    return DispatchTrustedSmsEventToSelf(aTopic, DELIVERY_ERROR_EVENT_NAME, aSubject);
-  }
-
-  if (!strcmp(aTopic, kSmsReadSuccessObserverTopic)) {
-    return DispatchTrustedSmsEventToSelf(aTopic, READ_SUCCESS_EVENT_NAME, aSubject);
-  }
-
-  if (!strcmp(aTopic, kSmsReadErrorObserverTopic)) {
-    return DispatchTrustedSmsEventToSelf(aTopic, READ_ERROR_EVENT_NAME, aSubject);
-  }
-
-  if (!strcmp(aTopic, kSmsDeletedObserverTopic)) {
-    return DispatchTrustedDeletedEventToSelf(aSubject);
-  }
-
-  return NS_OK;
-}
-
-already_AddRefed<Promise>
-MobileMessageManager::GetSmscAddress(const Optional<uint32_t>& aServiceId,
-                                     ErrorResult& aRv)
-{
-  nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
-  if (!smsService) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  // Use the default one unless |aSendParams.serviceId| is available.
-  uint32_t serviceId;
-  nsresult rv;
-  if (aServiceId.WasPassed()) {
-    serviceId = aServiceId.Value();
-  } else {
-    rv = smsService->GetSmsDefaultServiceId(&serviceId);
-    if (NS_FAILED(rv)) {
-      aRv.Throw(rv);
-      return nullptr;
-    }
-  }
-
-  nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
-  if (!window) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(window);
-  if (!global) {
-    aRv.Throw(NS_ERROR_UNEXPECTED);
-    return nullptr;
-  }
-
-  RefPtr<Promise> promise = Promise::Create(global, aRv);
-  if (aRv.Failed()) {
-    return nullptr;
-  }
-
-  nsCOMPtr<nsIMobileMessageCallback> msgCallback =
-    new MobileMessageCallback(promise);
-
-  rv = smsService->GetSmscAddress(serviceId, msgCallback);
-  if (NS_FAILED(rv)) {
-    promise->MaybeReject(rv);
-    return promise.forget();
-  }
-
-  return promise.forget();
-}
-
-already_AddRefed<Promise>
-MobileMessageManager::SetSmscAddress(const SmscAddress& aSmscAddress,
-                                     const Optional<uint32_t>& aServiceId,
-                                     ErrorResult& aRv)
-{
-  nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
-  if (!smsService) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  // Use the default one unless |serviceId| is available.
-  uint32_t serviceId;
-  nsresult rv;
-  if (aServiceId.WasPassed()) {
-    serviceId = aServiceId.Value();
-  } else {
-    rv = smsService->GetSmsDefaultServiceId(&serviceId);
-    if (NS_FAILED(rv)) {
-      aRv.Throw(rv);
-      return nullptr;
-    }
-  }
-
-  nsCOMPtr<nsPIDOMWindowInner> window = GetOwner();
-  if (!window) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(window);
-  if (!global) {
-    aRv.Throw(NS_ERROR_UNEXPECTED);
-    return nullptr;
-  }
-
-  RefPtr<Promise> promise = Promise::Create(global, aRv);
-  if (aRv.Failed()) {
-    return nullptr;
-  }
-
-  if (!aSmscAddress.mAddress.WasPassed()) {
-    NS_WARNING("SmscAddress.address is a mandatory field and can not be omitted.");
-    promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
-    return promise.forget();
-  }
-
-  nsString address = aSmscAddress.mAddress.Value();
-  TypeOfNumber ton = aSmscAddress.mTypeOfAddress.mTypeOfNumber;
-  NumberPlanIdentification npi =
-    aSmscAddress.mTypeOfAddress.mNumberPlanIdentification;
-
-  // If the address begins with +, set TON to international no matter what has
-  // passed in.
-  if (!address.IsEmpty() && address[0] == '+') {
-    ton = TypeOfNumber::International;
-  }
-
-  nsCOMPtr<nsIMobileMessageCallback> msgCallback =
-    new MobileMessageCallback(promise);
-
-  rv = smsService->SetSmscAddress(serviceId, address,
-    static_cast<uint32_t>(ton), static_cast<uint32_t>(npi), msgCallback);
-  if (NS_FAILED(rv)) {
-    promise->MaybeReject(rv);
-    return promise.forget();
-  }
-
-  return promise.forget();
-}
-
-
-} // namespace dom
-} // namespace mozilla
-
-already_AddRefed<nsISmsService>
-NS_CreateSmsService()
-{
-  nsCOMPtr<nsISmsService> smsService;
-
-  if (XRE_IsContentProcess()) {
-    smsService = SmsIPCService::GetSingleton();
-  } else {
-#if defined(MOZ_WIDGET_ANDROID) && defined(MOZ_WEBSMS_BACKEND)
-    smsService = new SmsService();
-#elif defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
-    smsService = do_GetService(GONK_SMSSERVICE_CONTRACTID);
-#endif
-  }
-
-  return smsService.forget();
-}
-
-already_AddRefed<nsIMobileMessageDatabaseService>
-NS_CreateMobileMessageDatabaseService()
-{
-  nsCOMPtr<nsIMobileMessageDatabaseService> mobileMessageDBService;
-  if (XRE_IsContentProcess()) {
-    mobileMessageDBService = SmsIPCService::GetSingleton();
-  } else {
-#if defined(MOZ_WIDGET_ANDROID) && defined(MOZ_WEBSMS_BACKEND)
-    mobileMessageDBService = new MobileMessageDatabaseService();
-#elif defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
-    mobileMessageDBService =
-      do_CreateInstance(GONK_MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID);
-#endif
-  }
-
-  return mobileMessageDBService.forget();
-}
-
-already_AddRefed<nsIMmsService>
-NS_CreateMmsService()
-{
-  nsCOMPtr<nsIMmsService> mmsService;
-
-  if (XRE_IsContentProcess()) {
-    mmsService = SmsIPCService::GetSingleton();
-  } else {
-#if defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
-    mmsService = do_CreateInstance("@mozilla.org/mms/gonkmmsservice;1");
-#endif
-  }
-
-  return mmsService.forget();
-}
-
-already_AddRefed<nsIMobileMessageService>
-NS_CreateMobileMessageService()
-{
-  nsCOMPtr<nsIMobileMessageService> service = new MobileMessageService();
-  return service.forget();
-}
deleted file mode 100644
--- a/dom/mobilemessage/MobileMessageManager.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=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/. */
-
-#ifndef mozilla_dom_mobilemessage_MobileMessageManager_h
-#define mozilla_dom_mobilemessage_MobileMessageManager_h
-
-#include "mozilla/Attributes.h"
-#include "mozilla/DOMEventTargetHelper.h"
-#include "nsIObserver.h"
-
-class nsISmsService;
-
-namespace mozilla {
-namespace dom {
-
-class Promise;
-class DOMRequest;
-class DOMCursor;
-class MmsMessage;
-struct MmsParameters;
-struct MmsSendParameters;
-struct MobileMessageFilter;
-class OwningLongOrSmsMessageOrMmsMessage;
-class SmsMessage;
-struct SmsSendParameters;
-struct SmscAddress;
-
-class MobileMessageManager final : public DOMEventTargetHelper
-                                 , public nsIObserver
-{
-public:
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_NSIOBSERVER
-
-  NS_REALLY_FORWARD_NSIDOMEVENTTARGET(DOMEventTargetHelper)
-
-  explicit MobileMessageManager(nsPIDOMWindowInner* aWindow);
-
-  void Init();
-  void Shutdown();
-
-  nsPIDOMWindowInner*
-  GetParentObject() const { return GetOwner(); }
-
-  // WrapperCache
-  virtual JSObject*
-  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
-  // WebIDL Interface
-  already_AddRefed<DOMRequest>
-  GetSegmentInfoForText(const nsAString& aText,
-                        ErrorResult& aRv);
-
-  already_AddRefed<DOMRequest>
-  Send(const nsAString& aNumber,
-       const nsAString& aText,
-       const SmsSendParameters& aSendParams,
-       ErrorResult& aRv);
-
-  void
-  Send(const Sequence<nsString>& aNumbers,
-       const nsAString& aText,
-       const SmsSendParameters& aSendParams,
-       nsTArray<RefPtr<DOMRequest>>& aReturn,
-       ErrorResult& aRv);
-
-  already_AddRefed<DOMRequest>
-  SendMMS(const MmsParameters& aParameters,
-          const MmsSendParameters& aSendParams,
-          ErrorResult& aRv);
-
-  already_AddRefed<DOMRequest>
-  GetMessage(int32_t aId,
-             ErrorResult& aRv);
-
-  already_AddRefed<DOMRequest>
-  Delete(int32_t aId,
-         ErrorResult& aRv);
-
-  already_AddRefed<DOMRequest>
-  Delete(SmsMessage& aMessage,
-         ErrorResult& aRv);
-
-  already_AddRefed<DOMRequest>
-  Delete(MmsMessage& aMessage,
-         ErrorResult& aRv);
-
-  already_AddRefed<DOMRequest>
-  Delete(const Sequence<OwningLongOrSmsMessageOrMmsMessage>& aParams,
-         ErrorResult& aRv);
-
-  already_AddRefed<DOMCursor>
-  GetMessages(const MobileMessageFilter& aFilter,
-              bool aReverse,
-              ErrorResult& aRv);
-
-  already_AddRefed<DOMRequest>
-  MarkMessageRead(int32_t aId,
-                  bool aRead,
-                  bool aSendReadReport,
-                  ErrorResult& aRv);
-
-  already_AddRefed<DOMCursor>
-  GetThreads(ErrorResult& aRv);
-
-  already_AddRefed<DOMRequest>
-  RetrieveMMS(int32_t aId,
-              ErrorResult& aRv);
-
-  already_AddRefed<DOMRequest>
-  RetrieveMMS(MmsMessage& aMessage,
-              ErrorResult& aRv);
-
-  already_AddRefed<Promise>
-  GetSmscAddress(const Optional<uint32_t>& aServiceId,
-                 ErrorResult& aRv);
-
-  already_AddRefed<Promise>
-  SetSmscAddress(const SmscAddress& aSmscAddress,
-                 const Optional<uint32_t>& aServiceId,
-                 ErrorResult& aRv);
-
-  IMPL_EVENT_HANDLER(received)
-  IMPL_EVENT_HANDLER(retrieving)
-  IMPL_EVENT_HANDLER(sending)
-  IMPL_EVENT_HANDLER(sent)
-  IMPL_EVENT_HANDLER(failed)
-  IMPL_EVENT_HANDLER(deliverysuccess)
-  IMPL_EVENT_HANDLER(deliveryerror)
-  IMPL_EVENT_HANDLER(readsuccess)
-  IMPL_EVENT_HANDLER(readerror)
-  IMPL_EVENT_HANDLER(deleted)
-
-private:
-  ~MobileMessageManager() {}
-
-  /**
-   * Internal Send() method used to send one message.
-   */
-  already_AddRefed<DOMRequest>
-  Send(nsISmsService* aSmsService,
-       uint32_t aServiceId,
-       const nsAString& aNumber,
-       const nsAString& aText,
-       ErrorResult& aRv);
-
-  already_AddRefed<DOMRequest>
-  Delete(int32_t* aIdArray,
-         uint32_t aSize,
-         ErrorResult& aRv);
-
-  nsresult
-  DispatchTrustedSmsEventToSelf(const char* aTopic,
-                                const nsAString& aEventName,
-                                nsISupports* aMsg);
-
-  nsresult
-  DispatchTrustedDeletedEventToSelf(nsISupports* aDeletedInfo);
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_mobilemessage_MobileMessageManager_h
deleted file mode 100644
--- a/dom/mobilemessage/MobileMessageService.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=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 "SmsMessageInternal.h"
-#include "MmsMessageInternal.h"
-#include "MobileMessageThreadInternal.h"
-#include "MobileMessageService.h"
-#include "DeletedMessageInfo.h"
-
-namespace mozilla {
-namespace dom {
-namespace mobilemessage {
-
-NS_IMPL_ISUPPORTS(MobileMessageService, nsIMobileMessageService)
-
-NS_IMETHODIMP
-MobileMessageService::CreateSmsMessage(int32_t aId,
-                                       uint64_t aThreadId,
-                                       const nsAString& aIccId,
-                                       const nsAString& aDelivery,
-                                       const nsAString& aDeliveryStatus,
-                                       const nsAString& aSender,
-                                       const nsAString& aReceiver,
-                                       const nsAString& aBody,
-                                       const nsAString& aMessageClass,
-                                       uint64_t aTimestamp,
-                                       uint64_t aSentTimestamp,
-                                       uint64_t aDeliveryTimestamp,
-                                       bool aRead,
-                                       JSContext* aCx,
-                                       nsISmsMessage** aMessage)
-{
-  return SmsMessageInternal::Create(aId,
-                                    aThreadId,
-                                    aIccId,
-                                    aDelivery,
-                                    aDeliveryStatus,
-                                    aSender,
-                                    aReceiver,
-                                    aBody,
-                                    aMessageClass,
-                                    aTimestamp,
-                                    aSentTimestamp,
-                                    aDeliveryTimestamp,
-                                    aRead,
-                                    aCx,
-                                    aMessage);
-}
-
-NS_IMETHODIMP
-MobileMessageService::CreateMmsMessage(int32_t aId,
-                                       uint64_t aThreadId,
-                                       const nsAString& aIccId,
-                                       const nsAString& aDelivery,
-                                       JS::Handle<JS::Value> aDeliveryInfo,
-                                       const nsAString& aSender,
-                                       JS::Handle<JS::Value> aReceivers,
-                                       uint64_t aTimestamp,
-                                       uint64_t aSentTimestamp,
-                                       bool aRead,
-                                       const nsAString& aSubject,
-                                       const nsAString& aSmil,
-                                       JS::Handle<JS::Value> aAttachments,
-                                       uint64_t aExpiryDate,
-                                       bool aReadReportRequested,
-                                       JSContext* aCx,
-                                       nsIMmsMessage** aMessage)
-{
-  return MmsMessageInternal::Create(aId,
-                                    aThreadId,
-                                    aIccId,
-                                    aDelivery,
-                                    aDeliveryInfo,
-                                    aSender,
-                                    aReceivers,
-                                    aTimestamp,
-                                    aSentTimestamp,
-                                    aRead,
-                                    aSubject,
-                                    aSmil,
-                                    aAttachments,
-                                    aExpiryDate,