Merge m-c to inbound. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Fri, 21 Oct 2016 11:08:45 -0400
changeset 348983 806054dd12bdcbdee81dbd75f1583156cef9b649
parent 348982 f6811b39af13400c4d987bf0fd3669e24fc56c5e (current diff)
parent 348869 28681d252003e3110105473754da2f4097cb83a6 (diff)
child 349006 5639a9f476d08f300c079117e61697f5026b6367
child 349048 37cff35583fe1405d6466280aa70681df8aff3a4
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone52.0a1
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,
-                                    aReadReportRequested,
-                                    aCx,
-                                    aMessage);
-}
-
-NS_IMETHODIMP
-MobileMessageService::CreateThread(uint64_t aId,
-                                   JS::Handle<JS::Value> aParticipants,
-                                   uint64_t aTimestamp,
-                                   const nsAString& aLastMessageSubject,
-                                   const nsAString& aBody,
-                                   uint64_t aUnreadCount,
-                                   const nsAString& aLastMessageType,
-                                   JSContext* aCx,
-                                   nsIMobileMessageThread** aThread)
-{
-  return MobileMessageThreadInternal::Create(aId,
-                                             aParticipants,
-                                             aTimestamp,
-                                             aLastMessageSubject,
-                                             aBody,
-                                             aUnreadCount,
-                                             aLastMessageType,
-                                             aCx,
-                                             aThread);
-}
-
-NS_IMETHODIMP
-MobileMessageService::CreateDeletedMessageInfo(int32_t* aMessageIds,
-                                               uint32_t aMsgCount,
-                                               uint64_t* aThreadIds,
-                                               uint32_t  aThreadCount,
-                                               nsIDeletedMessageInfo** aDeletedInfo)
-{
-  return DeletedMessageInfo::Create(aMessageIds,
-                                    aMsgCount,
-                                    aThreadIds,
-                                    aThreadCount,
-                                    aDeletedInfo);
-}
-
-} // namespace mobilemessage
-} // namespace dom
-} // namespace mozilla
deleted file mode 100644
--- a/dom/mobilemessage/MobileMessageService.h
+++ /dev/null
@@ -1,34 +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_MobileMessageService_h
-#define mozilla_dom_mobilemessage_MobileMessageService_h
-
-#include "mozilla/Attributes.h" // For final
-#include "nsIMobileMessageService.h"
-
-namespace mozilla {
-namespace dom {