Merge m-c to fx-team. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Fri, 22 May 2015 14:21:30 -0400
changeset 276073 1a7bb3dee2439964796599a4d8ee70d7bd55e9dc
parent 276072 b317389acc043f56102b97b25ae13ad42873c677 (current diff)
parent 275940 a69094e0f2a47486a85c9d65a6ef3cd7693c1789 (diff)
child 276074 411adbfe0ea2e815b51c569fbcc190e20a63ccd4
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to fx-team. a=merge
browser/base/jar.mn
configure.in
docshell/base/nsDocShell.cpp
dom/ipc/post-fork-preload.js
dom/manifest/manifestValueExtractor.js
gfx/thebes/gfxFcPlatformFontList.cpp
toolkit/mozapps/extensions/test/xpcshell/data/test_gfxBlacklist_AllOS.xml
toolkit/xre/nsAppRunner.cpp
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -1129,8 +1129,11 @@ pref("gfx.touch.resample", true);
 
 // Comma separated list of activity names that can only be provided by
 // the system app in dev mode.
 pref("dom.activities.developer_mode_only", "import-app");
 
 // mulet apparently loads firefox.js as well as b2g.js, so we have to explicitly
 // disable serviceworkers here to get them disabled in mulet.
 pref("dom.serviceWorkers.enabled", false);
+
+// Retain at most 10 processes' layers buffers
+pref("layers.compositor-lru-size", 10);
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -636,29 +636,31 @@ var shell = {
       }
       delete shell.pendingChromeEvents;
     });
 
     shell.handleCmdLine();
   },
 
   handleCmdLine: function shell_handleCmdLine() {
+#ifndef MOZ_WIDGET_GONK
     let b2gcmds = Cc["@mozilla.org/commandlinehandler/general-startup;1?type=b2gcmds"]
                     .getService(Ci.nsISupports);
     let args = b2gcmds.wrappedJSObject.cmdLine;
     try {
       // Returns null if -url is not present
       let url = args.handleFlagWithParam("url", false);
       if (url) {
         this.sendChromeEvent({type: "mozbrowseropenwindow", url});
         args.preventDefault = true;
       }
     } catch(e) {
       // Throws if -url is present with no params
     }
+#endif
   },
 };
 
 Services.obs.addObserver(function onFullscreenOriginChange(subject, topic, data) {
   shell.sendChromeEvent({ type: "fullscreenoriginchange",
                           fullscreenorigin: data });
 }, "fullscreen-origin-change", false);
 
--- a/b2g/config/aries/sources.xml
+++ b/b2g/config/aries/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1126d8bee559f7cde675df2fcc6c196da9cfeba1"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="f4486f7c7785b66e8dbfc775677d1b6386718e96"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="53517af1f57810bef745f03602f407161a475d76"/>
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1126d8bee559f7cde675df2fcc6c196da9cfeba1"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="f4486f7c7785b66e8dbfc775677d1b6386718e96"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="53517af1f57810bef745f03602f407161a475d76"/>
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="173b3104bfcbd23fc9dccd4b0035fc49aae3d444">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="1126d8bee559f7cde675df2fcc6c196da9cfeba1"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="f4486f7c7785b66e8dbfc775677d1b6386718e96"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="22664edc4c73e5fe8f5095ff1d5549db78a2bc10"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="218a5637399d023f4326e12c8a486dad95403b6c"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="4efd19d199ae52656604f794c5a77518400220fd">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1126d8bee559f7cde675df2fcc6c196da9cfeba1"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="f4486f7c7785b66e8dbfc775677d1b6386718e96"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="53517af1f57810bef745f03602f407161a475d76"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1126d8bee559f7cde675df2fcc6c196da9cfeba1"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="f4486f7c7785b66e8dbfc775677d1b6386718e96"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="53517af1f57810bef745f03602f407161a475d76"/>
--- a/b2g/config/emulator-l/sources.xml
+++ b/b2g/config/emulator-l/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1126d8bee559f7cde675df2fcc6c196da9cfeba1"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="f4486f7c7785b66e8dbfc775677d1b6386718e96"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="53517af1f57810bef745f03602f407161a475d76"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="173b3104bfcbd23fc9dccd4b0035fc49aae3d444">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="1126d8bee559f7cde675df2fcc6c196da9cfeba1"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="f4486f7c7785b66e8dbfc775677d1b6386718e96"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="22664edc4c73e5fe8f5095ff1d5549db78a2bc10"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="218a5637399d023f4326e12c8a486dad95403b6c"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1126d8bee559f7cde675df2fcc6c196da9cfeba1"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="f4486f7c7785b66e8dbfc775677d1b6386718e96"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="53517af1f57810bef745f03602f407161a475d76"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
-        "git_revision": "1126d8bee559f7cde675df2fcc6c196da9cfeba1", 
+        "git_revision": "f4486f7c7785b66e8dbfc775677d1b6386718e96", 
         "remote": "https://git.mozilla.org/releases/gaia.git", 
         "branch": ""
     }, 
-    "revision": "d61a9645397139d188f61d977b5c677399a35518", 
+    "revision": "667627b8fc148996b1a51155b4c123d63cf27c59", 
     "repo_path": "integration/gaia-central"
 }
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="4efd19d199ae52656604f794c5a77518400220fd">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1126d8bee559f7cde675df2fcc6c196da9cfeba1"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="f4486f7c7785b66e8dbfc775677d1b6386718e96"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="53517af1f57810bef745f03602f407161a475d76"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1126d8bee559f7cde675df2fcc6c196da9cfeba1"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="f4486f7c7785b66e8dbfc775677d1b6386718e96"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="53517af1f57810bef745f03602f407161a475d76"/>
--- a/browser/base/content/browser-pocket-de.properties
+++ b/browser/base/content/browser-pocket-de.properties
@@ -6,11 +6,11 @@
 # browser.properties in the usual L10N location.
 
 pocket-button.label = Pocket
 pocket-button.tooltiptext = Bei Pocket speichern
 
 # From browser-pocket.dtd
 saveToPocketCmd.label = Seite bei Pocket speichern
 saveToPocketCmd.accesskey = k
-saveLinkToPocketCmd.label = Link in Pocket speichern
+saveLinkToPocketCmd.label = Link bei Pocket speichern
 saveLinkToPocketCmd.accesskey = o
 pocketMenuitem.label = Pocket-Liste anzeigen
--- a/browser/base/content/browser-pocket-ru.properties
+++ b/browser/base/content/browser-pocket-ru.properties
@@ -7,10 +7,10 @@
 
 pocket-button.label = Pocket
 pocket-button.tooltiptext = Сохранить в Pocket
 
 # From browser-pocket.dtd
 saveToPocketCmd.label = Сохранить страницу в Pocket
 saveToPocketCmd.accesskey = х
 saveLinkToPocketCmd.label = Сохранить ссылку в Pocket
-saveLinkToPocketCmd.accesskey = P
+saveLinkToPocketCmd.accesskey = а
 pocketMenuitem.label = Показать список Pocket
new file mode 100644
--- /dev/null
+++ b/browser/base/content/gcli_sec_bad.svg
@@ -0,0 +1,7 @@
+<svg width="30" height="30" xmlns="http://www.w3.org/2000/svg">
+  <circle cx="15" cy="15" r="15" fill="#e74c3c"/>
+  <g stroke="white" stroke-width="3">
+    <line x1="9" y1="9" x2="21" y2="21"/>
+    <line x1="21" y1="9" x2="9" y2="21"/>
+  </g>
+</svg>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/browser/base/content/gcli_sec_good.svg
@@ -0,0 +1,4 @@
+<svg width="30" height="30" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60">
+  <circle cx="30" cy="30" r="30" fill="#2CBB0F"/>
+  <polygon points="17,32 25,39 26,39 44,18 45,18 48,21 27,46 25,46 14,36 13,36 16,33 16,32" fill="white"/>
+</svg>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/browser/base/content/gcli_sec_moderate.svg
@@ -0,0 +1,4 @@
+<svg width="30" height="30" xmlns="http://www.w3.org/2000/svg">
+  <circle cx="15" cy="15" r="15" fill="#F5B400"/>
+  <rect x="7.5" y="13" width="15" height="4" fill="white"/>
+</svg>
\ No newline at end of file
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -103,16 +103,19 @@ browser.jar:
         content/browser/defaultthemes/4.icon.png      (content/defaultthemes/4.icon.png)
         content/browser/defaultthemes/4.preview.png   (content/defaultthemes/4.preview.png)
         content/browser/defaultthemes/5.footer.png    (content/defaultthemes/5.footer.png)
         content/browser/defaultthemes/5.header.png    (content/defaultthemes/5.header.png)
         content/browser/defaultthemes/5.icon.jpg      (content/defaultthemes/5.icon.jpg)
         content/browser/defaultthemes/5.preview.jpg   (content/defaultthemes/5.preview.jpg)
         content/browser/defaultthemes/devedition.header.png   (content/defaultthemes/devedition.header.png)
         content/browser/defaultthemes/devedition.icon.png     (content/defaultthemes/devedition.icon.png)
+        content/browser/gcli_sec_bad.svg              (content/gcli_sec_bad.svg)
+        content/browser/gcli_sec_good.svg             (content/gcli_sec_good.svg)
+        content/browser/gcli_sec_moderate.svg         (content/gcli_sec_moderate.svg)
         content/browser/newtab/newTab.xul             (content/newtab/newTab.xul)
 *       content/browser/newtab/newTab.js              (content/newtab/newTab.js)
         content/browser/newtab/newTab.css             (content/newtab/newTab.css)
         content/browser/newtab/newTab.inadjacent.json         (content/newtab/newTab.inadjacent.json)
 *       content/browser/pageinfo/pageInfo.xul         (content/pageinfo/pageInfo.xul)
         content/browser/pageinfo/pageInfo.js          (content/pageinfo/pageInfo.js)
         content/browser/pageinfo/pageInfo.css         (content/pageinfo/pageInfo.css)
         content/browser/pageinfo/pageInfo.xml         (content/pageinfo/pageInfo.xml)
--- a/browser/components/pocket/panels/js/dictionary.js
+++ b/browser/components/pocket/panels/js/dictionary.js
@@ -30,30 +30,30 @@ Translations.en =
 	viewlist: "View List"
 };
 
 Translations.de =
 {
   addtags: "Tags hinzufügen",
   alreadyhaveacct: "Sind Sie bereits Pocket-Nutzer?",
   continueff: "Mit Firefox fortfahren",
-  errorgeneric: "Beim Speichern des Links in Pocket ist ein Problem aufgetreten.",
+  errorgeneric: "Beim Speichern des Links bei Pocket ist ein Fehler aufgetreten.",
   learnmore: "Mehr erfahren",
   loginnow: "Anmelden",
   maxtaglength: "Tags dürfen höchsten 25 Zeichen lang sein.",
-  mustbeconnected: "Bitte versichere dich, dass du mit dem Internet verbunden bist.",
+  mustbeconnected: "Bitte überprüfen Sie, ob Sie mit dem Internet verbunden sind.",
   onlylinkssaved: "Es können nur Links gespeichert werden",
   pagenotsaved: "Seite nicht gespeichert",
   pageremoved: "Seite entfernt",
   pagesaved: "Bei Pocket gespeichert",
   processingremove: "Seite wird entfernt…",
   processingtags: "Tags werden hinzugefügt…",
   removepage: "Seite entfernen",
   save: "Speichern",
-  saving: "Speichern...",
+  saving: "Speichern…",
   signupemail: "Mit E-Mail registrieren",
   signuptosave: "Registrieren Sie sich bei Pocket. Das ist kostenlos.",
   suggestedtags: "Vorgeschlagene Tags",
   tagline: "Speichern Sie Artikel und Videos aus Firefox bei Pocket, um sie jederzeit und auf jedem Gerät ansehen zu können.",
   taglinestory_one: "Klicken Sie auf die Pocket-Schaltfläche, um beliebige Artikel, Videos und Seiten aus Firefox zu speichern.",
   taglinestory_two: "Lesen Sie diese mit Pocket, jederzeit und auf jedem Gerät.",
   tagssaved: "Tags hinzugefügt",
   signinfirefox: "Mit Firefox anmelden",
@@ -65,17 +65,17 @@ Translations.es =
 {
   addtags: "Añadir etiquetas",
   alreadyhaveacct: "¿Ya tiene cuenta Pocket?",
   continueff: "Continuar con Firefox",
   errorgeneric: "Se ha producido un error al guardar el enlace en Pocket.",
   learnmore: "Saber más",
   loginnow: "Iniciar sesión",
   maxtaglength: "Las etiquetas están limitadas a 25 caracteres.",
-  mustbeconnected: "Comprueba que tienes conexión a Internet.",
+  mustbeconnected: "Compruebe que tiene conexión a Internet.",
   onlylinkssaved: "Solo se pueden guardar enlaces",
   pagenotsaved: "Página no guardada",
   pageremoved: "Página eliminada",
   pagesaved: "Guardada en Pocket",
   processingremove: "Eliminando página…",
   processingtags: "Añadiendo etiquetas…",
   removepage: "Eliminar página",
   save: "Guardar",
@@ -96,32 +96,32 @@ Translations.ja =
 {
   addtags: "タグを追加",
   alreadyhaveacct: "アカウントをお持ちですか?",
   continueff: "Firefox で続行",
   errorgeneric: "Pocket にリンクを保存中に問題が発生しました。",
   learnmore: "詳細",
   loginnow: "ログイン",
   maxtaglength: "タグは 25 文字までです。",
-  mustbeconnected: "インターネットに接続されていることをご確認ください。",
+  mustbeconnected: "インターネットに接続されていることを確認してください。",
   onlylinkssaved: "リンクのみ保存できます",
   pagenotsaved: "ページを保存できませんでした",
   pageremoved: "ページを削除しました",
   pagesaved: "Pocket に保存しました",
   processingremove: "ページを削除中...",
   processingtags: "タグを追加中...",
   removepage: "ページを削除",
   save: "保存",
   saving: "保存中...",
   signupemail: "メールでアカウント登録",
   signuptosave: "Pocket にアカウント登録してください。無料です。",
   suggestedtags: "タグ候補",
-  tagline: "Pocket でいつでもどこでも見れるよう、Firefox から記事や動画を保存できます。",
+  tagline: "Pocket でいつでもどこでも見られるよう、Firefox から記事や動画を保存できます。",
   taglinestory_one: "Firefox から記事や動画やページを保存するには、Pocket ボタンをクリックしてください。",
-  taglinestory_two: "Pocket でいつでもどこでも見れます。",
+  taglinestory_two: "Pocket でいつでもどこでも見られます。",
   tagssaved: "タグを追加しました",
   signinfirefox: "Firefox でログイン",
   signupfirefox: "Firefox でアカウント登録",
   viewlist: "マイリストを表示"
 };
 
 Translations.ru =
 {
@@ -147,9 +147,9 @@ Translations.ru =
   suggestedtags: "Рекомендуемые теги",
   tagline: "Сохраняйте статьи и видео из Firefox для просмотра в Pocket на любом устройстве, в любой момент.",
   taglinestory_one: "Щёлкните по кнопке Pocket, чтобы сохранить любую статью, видео или страницу из Firefox.",
   taglinestory_two: "Просматривайте их в Pocket на любом устройстве, в любой момент.",
   tagssaved: "Теги добавлены",
   signinfirefox: "Войти через Firefox",
   signupfirefox: "Регистрация через Firefox",
   viewlist: "Просмотреть список"
-};
\ No newline at end of file
+};
--- a/caps/BasePrincipal.cpp
+++ b/caps/BasePrincipal.cpp
@@ -1,24 +1,26 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 sw=2 et tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/BasePrincipal.h"
 
+#include "nsIContentSecurityPolicy.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 
 #include "nsPrincipal.h"
 #include "nsNetUtil.h"
 #include "nsNullPrincipal.h"
 #include "nsScriptSecurityManager.h"
 
+#include "mozilla/dom/CSPDictionariesBinding.h"
 #include "mozilla/dom/ToJSValue.h"
 
 namespace mozilla {
 
 void
 OriginAttributes::CreateSuffix(nsACString& aStr)
 {
   aStr.Truncate();
@@ -124,16 +126,29 @@ BasePrincipal::SetCsp(nsIContentSecurity
   if (mCSP)
     return NS_ERROR_ALREADY_INITIALIZED;
 
   mCSP = aCsp;
   return NS_OK;
 }
 
 NS_IMETHODIMP
+BasePrincipal::GetCspJSON(nsAString& outCSPinJSON)
+{
+  outCSPinJSON.Truncate();
+  dom::CSPPolicies jsonPolicies;
+
+  if (!mCSP) {
+    jsonPolicies.ToJSON(outCSPinJSON);
+    return NS_OK;
+  }
+  return mCSP->ToJSON(outCSPinJSON);
+}
+
+NS_IMETHODIMP
 BasePrincipal::GetIsNullPrincipal(bool* aIsNullPrincipal)
 {
   *aIsNullPrincipal = false;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 BasePrincipal::GetJarPrefix(nsACString& aJarPrefix)
--- a/caps/BasePrincipal.h
+++ b/caps/BasePrincipal.h
@@ -65,16 +65,17 @@ public:
   NS_IMETHOD GetOrigin(nsACString& aOrigin) final;
   NS_IMETHOD GetOriginNoSuffix(nsACString& aOrigin) final;
   NS_IMETHOD Equals(nsIPrincipal* other, bool* _retval) final;
   NS_IMETHOD EqualsConsideringDomain(nsIPrincipal* other, bool* _retval) final;
   NS_IMETHOD Subsumes(nsIPrincipal* other, bool* _retval) final;
   NS_IMETHOD SubsumesConsideringDomain(nsIPrincipal* other, bool* _retval) final;
   NS_IMETHOD GetCsp(nsIContentSecurityPolicy** aCsp) override;
   NS_IMETHOD SetCsp(nsIContentSecurityPolicy* aCsp) override;
+  NS_IMETHOD GetCspJSON(nsAString& outCSPinJSON) override;
   NS_IMETHOD GetIsNullPrincipal(bool* aIsNullPrincipal) override;
   NS_IMETHOD GetJarPrefix(nsACString& aJarPrefix) final;
   NS_IMETHOD GetOriginAttributes(JSContext* aCx, JS::MutableHandle<JS::Value> aVal) final;
   NS_IMETHOD GetOriginSuffix(nsACString& aOriginSuffix) final;
   NS_IMETHOD GetCookieJar(nsACString& aCookieJar) final;
   NS_IMETHOD GetAppStatus(uint16_t* aAppStatus) final;
   NS_IMETHOD GetAppId(uint32_t* aAppStatus) final;
   NS_IMETHOD GetIsInBrowserElement(bool* aIsInBrowserElement) final;
--- a/caps/nsIPrincipal.idl
+++ b/caps/nsIPrincipal.idl
@@ -15,17 +15,17 @@ struct JSPrincipals;
 
 interface nsIURI;
 interface nsIContentSecurityPolicy;
 
 [ptr] native JSContext(JSContext);
 [ptr] native JSPrincipals(JSPrincipals);
 [ptr] native PrincipalArray(nsTArray<nsCOMPtr<nsIPrincipal> >);
 
-[scriptable, builtinclass, uuid(749f21f5-8ade-4d0b-a590-2b1d18e890d5)]
+[scriptable, builtinclass, uuid(49c2faf0-b6de-4640-8d0f-e0217baa8627)]
 interface nsIPrincipal : nsISerializable
 {
     /**
      * Returns whether the other principal is equivalent to this principal.
      * Principals are considered equal if they are the same principal, or
      * they have the same origin.
      */
     boolean equals(in nsIPrincipal other);
@@ -129,16 +129,23 @@ interface nsIPrincipal : nsISerializable
                       in boolean allowIfInheritsPrincipal);
 
     /**
      * A Content Security Policy associated with this principal.
      */
     [noscript] attribute nsIContentSecurityPolicy csp;
 
     /**
+     * The CSP of the principal in JSON notation.
+     * Note, that the CSP itself is not exposed to JS, but script
+     * should be able to obtain a JSON representation of the CSP.
+     */
+    readonly attribute AString cspJSON;
+
+    /**
      * Returns the jar prefix of the principal.
      * The jar prefix is a string that can be used to isolate data or
      * permissions between different principals while taking into account
      * parameters like the app id or the fact that the principal is embedded in
      * a mozbrowser.
      * Some principals will return an empty string.
      * Some principals will assert if you try to access the jarPrefix.
      *
--- a/configure.in
+++ b/configure.in
@@ -2654,17 +2654,17 @@ AC_LANG_C
 dnl Check for .hidden assembler directive and visibility attribute.
 dnl Borrowed from glibc configure.in
 dnl ===============================================================
 if test "$GNU_CC" -a "$OS_TARGET" != WINNT; then
   AC_DEFINE(HAVE_VISIBILITY_HIDDEN_ATTRIBUTE)
   AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE)
   case "$OS_TARGET" in
   Darwin)
-    VISIBILITY_FLAGS='-fvisibility=hidden'
+    VISIBILITY_FLAGS='-fvisibility=hidden -fvisibility-inlines-hidden'
     ;;
   *)
     VISIBILITY_FLAGS='-I$(DIST)/system_wrappers -include $(MOZILLA_DIR)/config/gcc_hidden.h'
     WRAP_SYSTEM_INCLUDES=1
     ;;
   esac
 fi         # GNU_CC
 
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -921,17 +921,17 @@ nsDocShell::nsDocShell()
   if (!gDocShellLog) {
     gDocShellLog = PR_NewLogModule("nsDocShell");
   }
 #endif
   if (!gDocShellLeakLog) {
     gDocShellLeakLog = PR_NewLogModule("nsDocShellLeak");
   }
   if (gDocShellLeakLog) {
-    PR_LOG(gDocShellLeakLog, PR_LOG_DEBUG, ("DOCSHELL %p created\n", this));
+    MOZ_LOG(gDocShellLeakLog, PR_LOG_DEBUG, ("DOCSHELL %p created\n", this));
   }
 
 #ifdef DEBUG
   // We're counting the number of |nsDocShells| to help find leaks
   ++gNumberOfDocShells;
   if (!PR_GetEnv("MOZ_QUIET")) {
     printf_stderr("++DOCSHELL %p == %ld [pid = %d] [id = %llu]\n",
                   (void*)this,
@@ -953,17 +953,17 @@ nsDocShell::~nsDocShell()
     shPrivate->SetRootDocShell(nullptr);
   }
 
   if (--gDocShellCount == 0) {
     NS_IF_RELEASE(sURIFixup);
   }
 
   if (gDocShellLeakLog) {
-    PR_LOG(gDocShellLeakLog, PR_LOG_DEBUG, ("DOCSHELL %p destroyed\n", this));
+    MOZ_LOG(gDocShellLeakLog, PR_LOG_DEBUG, ("DOCSHELL %p destroyed\n", this));
   }
 
 #ifdef DEBUG
   // We're counting the number of |nsDocShells| to help find leaks
   --gNumberOfDocShells;
   if (!PR_GetEnv("MOZ_QUIET")) {
     printf_stderr("--DOCSHELL %p == %ld [pid = %d] [id = %llu]\n",
                   (void*)this,
@@ -1090,17 +1090,17 @@ nsDocShell::GetInterface(const nsIID& aI
     nsCOMPtr<nsIDOMDocument> domDoc;
     contentViewer->GetDOMDocument(getter_AddRefs(domDoc));
     NS_ASSERTION(domDoc, "Should have a document.");
     if (!domDoc) {
       return NS_ERROR_NO_INTERFACE;
     }
 
 #if defined(DEBUG)
-    PR_LOG(gDocShellLog, PR_LOG_DEBUG,
+    MOZ_LOG(gDocShellLog, PR_LOG_DEBUG,
            ("nsDocShell[%p]: returning app cache container %p",
             this, domDoc.get()));
 #endif
     return domDoc->QueryInterface(aIID, aSink);
   } else if (aIID.Equals(NS_GET_IID(nsIPrompt)) &&
              NS_SUCCEEDED(EnsureScriptEnvironment())) {
     nsresult rv;
     nsCOMPtr<nsIWindowWatcher> wwatch =
@@ -1416,17 +1416,17 @@ nsDocShell::LoadURI(nsIURI* aURI,
     aLoadInfo->GetSourceDocShell(getter_AddRefs(sourceDocShell));
     aLoadInfo->GetBaseURI(getter_AddRefs(baseURI));
   }
 
 #if defined(DEBUG)
   if (PR_LOG_TEST(gDocShellLog, PR_LOG_DEBUG)) {
     nsAutoCString uristr;
     aURI->GetAsciiSpec(uristr);
-    PR_LOG(gDocShellLog, PR_LOG_DEBUG,
+    MOZ_LOG(gDocShellLog, PR_LOG_DEBUG,
            ("nsDocShell[%p]: loading %s with flags 0x%08x",
             this, uristr.get(), aLoadFlags));
   }
 #endif
 
   if (!shEntry &&
       !LOAD_TYPE_HAS_FLAGS(loadType, LOAD_FLAGS_REPLACE_HISTORY)) {
     // First verify if this is a subframe.
@@ -1535,17 +1535,17 @@ nsDocShell::LoadURI(nsIURI* aURI,
       if (inOnLoadHandler) {
         loadType = LOAD_NORMAL_REPLACE;
       }
     }
   } // !shEntry
 
   if (shEntry) {
 #ifdef DEBUG
-    PR_LOG(gDocShellLog, PR_LOG_DEBUG,
+    MOZ_LOG(gDocShellLog, PR_LOG_DEBUG,
            ("nsDocShell[%p]: loading from session history", this));
 #endif
 
     return LoadHistoryEntry(shEntry, loadType);
   }
 
   // On history navigation via Back/Forward buttons, don't execute
   // automatic JavaScript redirection such as |location.href = ...| or
@@ -5308,17 +5308,17 @@ nsDocShell::LoadErrorPage(nsIURI* aURI, 
 
     nsAutoCString chanName;
     if (aFailedChannel) {
       aFailedChannel->GetName(chanName);
     } else {
       chanName.AssignLiteral("<no channel>");
     }
 
-    PR_LOG(gDocShellLog, PR_LOG_DEBUG,
+    MOZ_LOG(gDocShellLog, PR_LOG_DEBUG,
            ("nsDocShell[%p]::LoadErrorPage(\"%s\", \"%s\", {...}, [%s])\n", this,
             spec.get(), NS_ConvertUTF16toUTF8(aURL).get(), chanName.get()));
   }
 #endif
   mFailedChannel = aFailedChannel;
   mFailedURI = aURI;
   mFailedLoadType = mLoadType;
 
@@ -11159,17 +11159,17 @@ nsDocShell::OnNewURI(nsIURI* aURI, nsICh
 
     nsAutoCString chanName;
     if (aChannel) {
       aChannel->GetName(chanName);
     } else {
       chanName.AssignLiteral("<no channel>");
     }
 
-    PR_LOG(gDocShellLog, PR_LOG_DEBUG,
+    MOZ_LOG(gDocShellLog, PR_LOG_DEBUG,
            ("nsDocShell[%p]::OnNewURI(\"%s\", [%s], 0x%x)\n", this, spec.get(),
             chanName.get(), aLoadType));
   }
 #endif
 
   bool equalUri = false;
 
   // Get the post data and the HTTP response code from the channel.
@@ -11224,17 +11224,17 @@ nsDocShell::OnNewURI(nsIURI* aURI, nsICh
   }
 
 #ifdef DEBUG
   bool shAvailable = (rootSH != nullptr);
 
   // XXX This log message is almost useless because |updateSHistory|
   //     and |updateGHistory| are not correct at this point.
 
-  PR_LOG(gDocShellLog, PR_LOG_DEBUG,
+  MOZ_LOG(gDocShellLog, PR_LOG_DEBUG,
          ("  shAvailable=%i updateSHistory=%i updateGHistory=%i"
           " equalURI=%i\n",
           shAvailable, updateSHistory, updateGHistory, equalUri));
 
   if (shAvailable && mCurrentURI && !mOSHE && aLoadType != LOAD_ERROR_PAGE) {
     NS_ASSERTION(NS_IsAboutBlank(mCurrentURI),
                  "no SHEntry for a non-transient viewer?");
   }
@@ -11779,17 +11779,17 @@ nsDocShell::AddToSessionHistory(nsIURI* 
 
     nsAutoCString chanName;
     if (aChannel) {
       aChannel->GetName(chanName);
     } else {
       chanName.AssignLiteral("<no channel>");
     }
 
-    PR_LOG(gDocShellLog, PR_LOG_DEBUG,
+    MOZ_LOG(gDocShellLog, PR_LOG_DEBUG,
            ("nsDocShell[%p]::AddToSessionHistory(\"%s\", [%s])\n",
             this, spec.get(), chanName.get()));
   }
 #endif
 
   nsresult rv = NS_OK;
   nsCOMPtr<nsISHEntry> entry;
   bool shouldPersist;
--- a/docshell/shistory/nsSHistory.cpp
+++ b/docshell/shistory/nsSHistory.cpp
@@ -63,17 +63,17 @@ static PRLogModuleInfo*
 GetSHistoryLog()
 {
   static PRLogModuleInfo* sLog;
   if (!sLog) {
     sLog = PR_NewLogModule("nsSHistory");
   }
   return sLog;
 }
-#define LOG(format) PR_LOG(GetSHistoryLog(), PR_LOG_DEBUG, format)
+#define LOG(format) MOZ_LOG(GetSHistoryLog(), PR_LOG_DEBUG, format)
 
 // This macro makes it easier to print a log message which includes a URI's
 // spec.  Example use:
 //
 //  nsIURI *uri = [...];
 //  LOG_SPEC(("The URI is %s.", _spec), uri);
 //
 #define LOG_SPEC(format, uri)                              \
--- a/dom/apps/AppsServiceChild.jsm
+++ b/dom/apps/AppsServiceChild.jsm
@@ -98,38 +98,33 @@ this.DOMApplicationRegistry = {
   init: function init() {
     this.cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
                   .getService(Ci.nsISyncMessageSender);
 
     APPS_IPC_MSG_NAMES.forEach((function(aMsgName) {
       this.cpmm.addMessageListener(aMsgName, this);
     }).bind(this));
 
-    this.resetList();
-
-    Services.obs.addObserver(this, "xpcom-shutdown", false);
-  },
-
-  resetList: function() {
     this.cpmm.sendAsyncMessage("Webapps:RegisterForMessages", {
       messages: APPS_IPC_MSG_NAMES
     });
 
     // We need to prime the cache with the list of apps.
     let list = this.cpmm.sendSyncMessage("Webapps:GetList", { })[0];
     this.webapps = list.webapps;
-
     // We need a fast mapping from localId -> app, so we add an index.
     // We also add the manifest to the app object.
     this.localIdIndex = { };
     for (let id in this.webapps) {
       let app = this.webapps[id];
       this.localIdIndex[app.localId] = app;
       app.manifest = list.manifests[id];
     }
+
+    Services.obs.addObserver(this, "xpcom-shutdown", false);
   },
 
   observe: function(aSubject, aTopic, aData) {
     // cpmm.addMessageListener causes the DOMApplicationRegistry object to
     // live forever if we don't clean up properly.
     this.webapps = null;
     this.DOMApps = null;
 
--- a/dom/base/ImageEncoder.cpp
+++ b/dom/base/ImageEncoder.cpp
@@ -387,17 +387,18 @@ ImageEncoder::ExtractDataInternal(const 
                                   aSize.width * aSize.height * 4,
                                   aSize.width,
                                   aSize.height,
                                   aSize.width * 4,
                                   imgIEncoder::INPUT_FORMAT_HOSTARGB,
                                   aOptions);
     } else {
       RefPtr<gfx::DataSourceSurface> dataSurface;
-      dataSurface = GetBRGADataSourceSurfaceSync(aImage);
+      RefPtr<layers::Image> image(aImage);
+      dataSurface = GetBRGADataSourceSurfaceSync(image.forget());
 
       DataSourceSurface::MappedSurface map;
       if (!dataSurface->Map(gfx::DataSourceSurface::MapType::READ, &map)) {
         return NS_ERROR_INVALID_ARG;
       }
       rv = aEncoder->InitFromData(map.mData,
                                   aSize.width * aSize.height * 4,
                                   aSize.width,
--- a/dom/base/ThirdPartyUtil.cpp
+++ b/dom/base/ThirdPartyUtil.cpp
@@ -18,17 +18,17 @@
 
 NS_IMPL_ISUPPORTS(ThirdPartyUtil, mozIThirdPartyUtil)
 
 //
 // NSPR_LOG_MODULES=thirdPartyUtil:5
 //
 static PRLogModuleInfo *gThirdPartyLog;
 #undef LOG
-#define LOG(args)     PR_LOG(gThirdPartyLog, PR_LOG_DEBUG, args)
+#define LOG(args)     MOZ_LOG(gThirdPartyLog, PR_LOG_DEBUG, args)
 
 nsresult
 ThirdPartyUtil::Init()
 {
   NS_ENSURE_TRUE(NS_IsMainThread(), NS_ERROR_NOT_AVAILABLE);
 
   nsresult rv;
   mTLDService = do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID, &rv);
--- a/dom/base/nsContentPolicy.cpp
+++ b/dom/base/nsContentPolicy.cpp
@@ -198,17 +198,17 @@ nsContentPolicy::CheckPolicy(CPMethod   
       nsAutoCString spec("None");                                             \
       if (contentLocation) {                                                  \
           contentLocation->GetSpec(spec);                                     \
       }                                                                       \
       nsAutoCString refSpec("None");                                          \
       if (requestingLocation) {                                               \
           requestingLocation->GetSpec(refSpec);                               \
       }                                                                       \
-      PR_LOG(gConPolLog, PR_LOG_DEBUG,                                        \
+      MOZ_LOG(gConPolLog, PR_LOG_DEBUG,                                        \
              ("Content Policy: " logType ": <%s> <Ref:%s> result=%s",         \
               spec.get(), refSpec.get(), resultName)                          \
              );                                                               \
     }                                                                         \
   PR_END_MACRO
 
 NS_IMETHODIMP
 nsContentPolicy::ShouldLoad(uint32_t          contentType,
--- a/dom/base/nsContentSink.cpp
+++ b/dom/base/nsContentSink.cpp
@@ -28,17 +28,16 @@
 #include "nsIAtom.h"
 #include "nsGkAtoms.h"
 #include "nsNetCID.h"
 #include "nsIOfflineCacheUpdate.h"
 #include "nsIApplicationCache.h"
 #include "nsIApplicationCacheContainer.h"
 #include "nsIApplicationCacheChannel.h"
 #include "nsIScriptSecurityManager.h"
-#include "nsISpeculativeConnect.h"
 #include "nsICookieService.h"
 #include "nsContentUtils.h"
 #include "nsNodeInfoManager.h"
 #include "nsIAppShell.h"
 #include "nsIWidget.h"
 #include "nsWidgetsCID.h"
 #include "nsIDOMNode.h"
 #include "mozAutoDocUpdate.h"
@@ -873,30 +872,25 @@ nsContentSink::PrefetchDNS(const nsAStri
   if (!hostname.IsEmpty() && nsHTMLDNSPrefetch::IsAllowed(mDocument)) {
     nsHTMLDNSPrefetch::PrefetchLow(hostname);
   }
 }
 
 void
 nsContentSink::Preconnect(const nsAString &aHref)
 {
-  nsCOMPtr<nsISpeculativeConnect>
-    speculator(do_QueryInterface(nsContentUtils::GetIOService()));
-  if (!speculator) {
-    return;
-  }
-
   // construct URI using document charset
   const nsACString& charset = mDocument->GetDocumentCharacterSet();
   nsCOMPtr<nsIURI> uri;
   NS_NewURI(getter_AddRefs(uri), aHref,
             charset.IsEmpty() ? nullptr : PromiseFlatCString(charset).get(),
             mDocument->GetDocBaseURI());
-  if (uri) {
-    speculator->SpeculativeConnect(uri, nullptr);
+
+  if (uri && mDocument) {
+    mDocument->MaybePreconnect(uri);
   }
 }
 
 nsresult
 nsContentSink::SelectDocAppCache(nsIApplicationCache *aLoadApplicationCache,
                                  nsIURI *aManifestURI,
                                  bool aFetchedWithHTTPGetOrEquiv,
                                  CacheSelectionAction *aAction)
--- a/dom/base/nsContentSink.h
+++ b/dom/base/nsContentSink.h
@@ -158,20 +158,19 @@ protected:
                                     bool aAlternate,
                                     const nsSubstring& aTitle,
                                     const nsSubstring& aType,
                                     const nsSubstring& aMedia);
 
   void PrefetchHref(const nsAString &aHref, nsINode *aSource,
                     bool aExplicit);
 
-  // For both PrefetchDNS() and Preconnect() aHref can either be the usual
+  // For PrefetchDNS() aHref can either be the usual
   // URI format or of the form "//www.hostname.com" without a scheme.
   void PrefetchDNS(const nsAString &aHref);
-  void Preconnect(const nsAString &aHref);
 
   // Gets the cache key (used to identify items in a cache) of the channel.
   nsresult GetChannelCacheKey(nsIChannel* aChannel, nsACString& aCacheKey);
 
   // There is an offline cache manifest attribute specified and the
   // document is allowed to use the offline cache.  Process the cache
   // selection algorithm for this document and the manifest. Result is
   // an action that must be taken on the manifest, see
@@ -219,16 +218,20 @@ public:
   // This method MUST be called with the empty string as the argument
   // when there is no manifest attribute!
   void ProcessOfflineManifest(const nsAString& aManifestSpec);
 
   // Extracts the manifest attribute from the element if it is the root 
   // element and calls the above method.
   void ProcessOfflineManifest(nsIContent *aElement);
 
+  // For Preconnect() aHref can either be the usual
+  // URI format or of the form "//www.hostname.com" without a scheme.
+  void Preconnect(const nsAString &aHref);
+
 protected:
   // Tries to scroll to the URI's named anchor. Once we've successfully
   // done that, further calls to this method will be ignored.
   void ScrollToRef();
 
   // Start layout.  If aIgnorePendingSheets is true, this will happen even if
   // we still have stylesheet loads pending.  Otherwise, we'll wait until the
   // stylesheets are all done loading.
--- a/dom/base/nsDOMDataChannel.cpp
+++ b/dom/base/nsDOMDataChannel.cpp
@@ -6,17 +6,17 @@
 
 #include "nsDOMDataChannel.h"
 
 #include "base/basictypes.h"
 #include "mozilla/Logging.h"
 
 extern PRLogModuleInfo* GetDataChannelLog();
 #undef LOG
-#define LOG(args) PR_LOG(GetDataChannelLog(), PR_LOG_DEBUG, args)
+#define LOG(args) MOZ_LOG(GetDataChannelLog(), PR_LOG_DEBUG, args)
 
 
 #include "nsDOMDataChannelDeclarations.h"
 #include "nsDOMDataChannel.h"
 #include "nsIDOMDataChannel.h"
 #include "nsIDOMMessageEvent.h"
 #include "mozilla/DOMEventTargetHelper.h"
 #include "mozilla/dom/File.h"
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -224,16 +224,18 @@
 #include "nsContentPermissionHelper.h"
 #include "mozilla/dom/DOMStringList.h"
 #include "nsWindowMemoryReporter.h"
 #include "nsLocation.h"
 #include "mozilla/dom/FontFaceSet.h"
 #include "mozilla/dom/BoxObject.h"
 #include "gfxVR.h"
 
+#include "nsISpeculativeConnect.h"
+
 #ifdef MOZ_MEDIA_NAVIGATOR
 #include "mozilla/MediaManager.h"
 #endif // MOZ_MEDIA_NAVIGATOR
 #ifdef MOZ_WEBRTC
 #include "IPeerConnection.h"
 #endif // MOZ_WEBRTC
 
 using namespace mozilla;
@@ -1588,17 +1590,17 @@ nsDocument::nsDocument(const char* aCont
   , mViewportType(Unknown)
 {
   SetContentTypeInternal(nsDependentCString(aContentType));
 
   if (!gDocumentLeakPRLog)
     gDocumentLeakPRLog = PR_NewLogModule("DocumentLeak");
 
   if (gDocumentLeakPRLog)
-    PR_LOG(gDocumentLeakPRLog, PR_LOG_DEBUG,
+    MOZ_LOG(gDocumentLeakPRLog, PR_LOG_DEBUG,
            ("DOCUMENT %p created", this));
 
   if (!gCspPRLog)
     gCspPRLog = PR_NewLogModule("CSP");
 
   // Start out mLastStyleSheetSet as null, per spec
   SetDOMStringToNull(mLastStyleSheetSet);
 
@@ -1632,17 +1634,17 @@ nsIDocument::~nsIDocument()
 
   UnlinkOriginalDocumentIfStatic();
 }
 
 
 nsDocument::~nsDocument()
 {
   if (gDocumentLeakPRLog)
-    PR_LOG(gDocumentLeakPRLog, PR_LOG_DEBUG,
+    MOZ_LOG(gDocumentLeakPRLog, PR_LOG_DEBUG,
            ("DOCUMENT %p destroyed", this));
 
   NS_ASSERTION(!mIsShowing, "Destroying a currently-showing document");
 
   // Note: This assert is only non-fatal because mochitest-bc triggers
   // it... as well as the preceding assert about !mIsShowing.
   NS_ASSERTION(!mObservingAppThemeChanged,
                "Document leaked to shutdown, then the observer service dropped "
@@ -2766,17 +2768,17 @@ AppendCSPFromHeader(nsIContentSecurityPo
   // See RFC2616 section 4.2 (last paragraph)
   nsresult rv = NS_OK;
   nsCharSeparatedTokenizer tokenizer(aHeaderValue, ',');
   while (tokenizer.hasMoreTokens()) {
       const nsSubstring& policy = tokenizer.nextToken();
       rv = csp->AppendPolicy(policy, aReportOnly);
       NS_ENSURE_SUCCESS(rv, rv);
       {
-        PR_LOG(gCspPRLog, PR_LOG_DEBUG,
+        MOZ_LOG(gCspPRLog, PR_LOG_DEBUG,
                 ("CSP refined with policy: \"%s\"",
                 NS_ConvertUTF16toUTF8(policy).get()));
       }
   }
   return NS_OK;
 }
 
 bool
@@ -2806,17 +2808,17 @@ nsDocument::IsLoopDocument(nsIChannel *a
   return isLoop;
 }
 
 nsresult
 nsDocument::InitCSP(nsIChannel* aChannel)
 {
   nsCOMPtr<nsIContentSecurityPolicy> csp;
   if (!CSPService::sCSPEnabled) {
-    PR_LOG(gCspPRLog, PR_LOG_DEBUG,
+    MOZ_LOG(gCspPRLog, PR_LOG_DEBUG,
            ("CSP is disabled, skipping CSP init for document %p", this));
     return NS_OK;
   }
 
   nsAutoCString tCspHeaderValue, tCspROHeaderValue;
 
   nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
   if (httpChannel) {
@@ -2864,26 +2866,26 @@ nsDocument::InitCSP(nsIChannel* aChannel
       !applyLoopCSP &&
       cspHeaderValue.IsEmpty() &&
       cspROHeaderValue.IsEmpty()) {
     if (PR_LOG_TEST(gCspPRLog, PR_LOG_DEBUG)) {
       nsCOMPtr<nsIURI> chanURI;
       aChannel->GetURI(getter_AddRefs(chanURI));
       nsAutoCString aspec;
       chanURI->GetAsciiSpec(aspec);
-      PR_LOG(gCspPRLog, PR_LOG_DEBUG,
+      MOZ_LOG(gCspPRLog, PR_LOG_DEBUG,
              ("no CSP for document, %s, %s",
               aspec.get(),
               applyAppDefaultCSP ? "is app" : "not an app"));
     }
 
     return NS_OK;
   }
 
-  PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("Document is an app or CSP header specified %p", this));
+  MOZ_LOG(gCspPRLog, PR_LOG_DEBUG, ("Document is an app or CSP header specified %p", this));
 
   nsresult rv;
 
   // If Document is an app check to see if we already set CSP and return early
   // if that is indeed the case.
   //
   // In general (see bug 947831), we should not be setting CSP on a principal
   // that aliases another document. For non-app code this is not a problem
@@ -2892,28 +2894,28 @@ nsDocument::InitCSP(nsIChannel* aChannel
   // about:srcodoc iframes) and thus won't try to set the CSP again. This
   // check ensures that we do not try to set CSP for an app.
   if (applyAppDefaultCSP || applyAppManifestCSP) {
     nsCOMPtr<nsIContentSecurityPolicy> csp;
     rv = principal->GetCsp(getter_AddRefs(csp));
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (csp) {
-      PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("%s %s %s",
+      MOZ_LOG(gCspPRLog, PR_LOG_DEBUG, ("%s %s %s",
            "This document is sharing principal with another document.",
            "Since the document is an app, CSP was already set.",
            "Skipping attempt to set CSP."));
       return NS_OK;
     }
   }
 
   csp = do_CreateInstance("@mozilla.org/cspcontext;1", &rv);
 
   if (NS_FAILED(rv)) {
-    PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("Failed to create CSP object: %x", rv));
+    MOZ_LOG(gCspPRLog, PR_LOG_DEBUG, ("Failed to create CSP object: %x", rv));
     return rv;
   }
 
   // used as a "self" identifier for the CSP.
   nsCOMPtr<nsIURI> selfURI;
   aChannel->GetURI(getter_AddRefs(selfURI));
 
   // Store the request context for violation reports
@@ -2956,17 +2958,17 @@ nsDocument::InitCSP(nsIChannel* aChannel
   nsCOMPtr<nsIDocShell> docShell(mDocumentContainer);
   if (docShell) {
     bool safeAncestry = false;
 
     // PermitsAncestry sends violation reports when necessary
     rv = csp->PermitsAncestry(docShell, &safeAncestry);
 
     if (NS_FAILED(rv) || !safeAncestry) {
-      PR_LOG(gCspPRLog, PR_LOG_DEBUG,
+      MOZ_LOG(gCspPRLog, PR_LOG_DEBUG,
               ("CSP doesn't like frame's ancestry, not loading."));
       // stop!  ERROR page!
       aChannel->Cancel(NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION);
     }
   }
 
   // ----- Set up any Referrer Policy specified by CSP
   bool hasReferrerPolicy = false;
@@ -2977,30 +2979,30 @@ nsDocument::InitCSP(nsIChannel* aChannel
     // Referrer policy spec (section 6.1) says that once the referrer policy
     // is set, any future attempts to change it result in No-Referrer.
     if (!mReferrerPolicySet) {
       mReferrerPolicy = static_cast<ReferrerPolicy>(referrerPolicy);
       mReferrerPolicySet = true;
     } else if (mReferrerPolicy != referrerPolicy) {
       mReferrerPolicy = mozilla::net::RP_No_Referrer;
       {
-        PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("%s %s",
+        MOZ_LOG(gCspPRLog, PR_LOG_DEBUG, ("%s %s",
                 "CSP wants to set referrer, but nsDocument"
                 "already has it set. No referrers will be sent"));
       }
     }
 
     // Referrer Policy is set separately for the speculative parser in
     // nsHTMLDocument::StartDocumentLoad() so there's nothing to do here for
     // speculative loads.
   }
 
   rv = principal->SetCsp(csp);
   NS_ENSURE_SUCCESS(rv, rv);
-  PR_LOG(gCspPRLog, PR_LOG_DEBUG,
+  MOZ_LOG(gCspPRLog, PR_LOG_DEBUG,
          ("Inserted CSP into principal %p", principal));
 
   return NS_OK;
 }
 
 void
 nsDocument::StopDocumentLoad()
 {
@@ -5091,16 +5093,20 @@ void
 nsDocument::DispatchContentLoadedEvents()
 {
   // If you add early returns from this method, make sure you're
   // calling UnblockOnload properly.
 
   // Unpin references to preloaded images
   mPreloadingImages.Clear();
 
+  // DOM manipulation after content loaded should not care if the element
+  // came from the preloader.
+  mPreloadedPreconnects.Clear();
+
   if (mTiming) {
     mTiming->NotifyDOMContentLoadedStart(nsIDocument::GetDocumentURI());
   }
 
   // Dispatch observer notification to notify observers document is interactive.
   nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
   nsIPrincipal *principal = GetPrincipal();
   os->NotifyObservers(static_cast<nsIDocument*>(this),
@@ -9806,16 +9812,33 @@ nsDocument::MaybePreLoadImage(nsIURI* ur
   // the "real" load occurs. Unpinned in DispatchContentLoadedEvents and
   // unlink
   if (NS_SUCCEEDED(rv)) {
     mPreloadingImages.Put(uri, request.forget());
   }
 }
 
 void
+nsDocument::MaybePreconnect(nsIURI* uri)
+{
+  if (mPreloadedPreconnects.Contains(uri)) {
+    return;
+  }
+  mPreloadedPreconnects.Put(uri, true);
+
+  nsCOMPtr<nsISpeculativeConnect>
+    speculator(do_QueryInterface(nsContentUtils::GetIOService()));
+  if (!speculator) {
+    return;
+  }
+
+  speculator->SpeculativeConnect(uri, nullptr);
+}
+
+void
 nsDocument::ForgetImagePreload(nsIURI* aURI)
 {
   // Checking count is faster than hashing the URI in the common
   // case of empty table.
   if (mPreloadingImages.Count() != 0) {
     nsCOMPtr<imgIRequest> req;
     mPreloadingImages.Remove(aURI, getter_AddRefs(req));
     if (req) {
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -1110,16 +1110,18 @@ public:
                         const nsAString& aSrcsetAttr,
                         const nsAString& aSizesAttr) override;
 
   virtual void MaybePreLoadImage(nsIURI* uri,
                                  const nsAString &aCrossOriginAttr,
                                  ReferrerPolicy aReferrerPolicy) override;
   virtual void ForgetImagePreload(nsIURI* aURI) override;
 
+  virtual void MaybePreconnect(nsIURI* uri) override;
+
   virtual void PreloadStyle(nsIURI* uri, const nsAString& charset,
                             const nsAString& aCrossOriginAttr,
                             ReferrerPolicy aReferrerPolicy) override;
 
   virtual nsresult LoadChromeSheetSync(nsIURI* uri, bool isAgentSheet,
                                        mozilla::CSSStyleSheet** sheet) override;
 
   virtual nsISupports* GetCurrentContentSink() override;
@@ -1780,16 +1782,21 @@ private:
   nsExternalResourceMap mExternalResourceMap;
 
   // All images in process of being preloaded.  This is a hashtable so
   // we can remove them as the real image loads start; that way we
   // make sure to not keep the image load going when no one cares
   // about it anymore.
   nsRefPtrHashtable<nsURIHashKey, imgIRequest> mPreloadingImages;
 
+  // A list of preconnects initiated by the preloader. This prevents
+  // the same uri from being used more than once, and allows the dom
+  // builder to not repeat the work of the preloader.
+  nsDataHashtable< nsURIHashKey, bool> mPreloadedPreconnects;
+
   // Current depth of picture elements from parser
   int32_t mPreloadPictureDepth;
 
   // Set if we've found a URL for the current picture
   nsString mPreloadPictureFoundSource;
 
   nsRefPtr<mozilla::dom::DOMImplementation> mDOMImplementation;
 
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -72,26 +72,26 @@ using namespace mozilla::dom;
 using namespace mozilla::widget;
 
 // Two types of focus pr logging are available:
 //   'Focus' for normal focus manager calls
 //   'FocusNavigation' for tab and document navigation
 PRLogModuleInfo* gFocusLog;
 PRLogModuleInfo* gFocusNavigationLog;
 
-#define LOGFOCUS(args) PR_LOG(gFocusLog, PR_LOG_DEBUG, args)
-#define LOGFOCUSNAVIGATION(args) PR_LOG(gFocusNavigationLog, PR_LOG_DEBUG, args)
+#define LOGFOCUS(args) MOZ_LOG(gFocusLog, PR_LOG_DEBUG, args)
+#define LOGFOCUSNAVIGATION(args) MOZ_LOG(gFocusNavigationLog, PR_LOG_DEBUG, args)
 
 #define LOGTAG(log, format, content)                            \
   if (PR_LOG_TEST(log, PR_LOG_DEBUG)) {                         \
     nsAutoCString tag(NS_LITERAL_CSTRING("(none)"));            \
     if (content) {                                              \
       content->NodeInfo()->NameAtom()->ToUTF8String(tag);       \
     }                                                           \
-    PR_LOG(log, PR_LOG_DEBUG, (format, tag.get()));             \
+    MOZ_LOG(log, PR_LOG_DEBUG, (format, tag.get()));             \
   }
 
 #define LOGCONTENT(format, content) LOGTAG(gFocusLog, format, content)
 #define LOGCONTENTNAVIGATION(format, content) LOGTAG(gFocusNavigationLog, format, content)
 
 struct nsDelayedBlurOrFocusEvent
 {
   nsDelayedBlurOrFocusEvent(uint32_t aType,
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1206,17 +1206,17 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalW
                   static_cast<void*>(ToCanonicalSupports(this)),
                   getpid(),
                   gSerialCounter,
                   static_cast<void*>(ToCanonicalSupports(aOuterWindow)));
   }
 #endif
 
   if (gDOMLeakPRLog)
-    PR_LOG(gDOMLeakPRLog, PR_LOG_DEBUG,
+    MOZ_LOG(gDOMLeakPRLog, PR_LOG_DEBUG,
            ("DOMWINDOW %p created outer=%p", this, aOuterWindow));
 
   NS_ASSERTION(sWindowsById, "Windows hash table must be created!");
   NS_ASSERTION(!sWindowsById->Get(mWindowID),
                "This window shouldn't be in the hash table yet!");
   // We seem to see crashes in release builds because of null |sWindowsById|.
   if (sWindowsById) {
     sWindowsById->Put(mWindowID, this);
@@ -1296,17 +1296,17 @@ nsGlobalWindow::~nsGlobalWindow()
                   getpid(),
                   mSerial,
                   static_cast<void*>(ToCanonicalSupports(outer)),
                   url.get());
   }
 #endif
 
   if (gDOMLeakPRLog)
-    PR_LOG(gDOMLeakPRLog, PR_LOG_DEBUG,
+    MOZ_LOG(gDOMLeakPRLog, PR_LOG_DEBUG,
            ("DOMWINDOW %p destroyed", this));
 
   if (IsOuterWindow()) {
     JSObject *proxy = GetWrapperPreserveColor();
     if (proxy) {
       js::SetProxyExtra(proxy, 0, js::PrivateValue(nullptr));
     }
 
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -2012,16 +2012,21 @@ public:
    * Returns true if the locale used for the document specifies a direction of
    * right to left. For chrome documents, this comes from the chrome registry.
    * This is used to determine the current state for the :-moz-locale-dir pseudoclass
    * so once can know whether a document is expected to be rendered left-to-right
    * or right-to-left.
    */
   virtual bool IsDocumentRightToLeft() { return false; }
 
+  /**
+   * Called by Parser for link rel=preconnect
+   */
+  virtual void MaybePreconnect(nsIURI* uri) = 0;
+
   enum DocumentTheme {
     Doc_Theme_Uninitialized, // not determined yet
     Doc_Theme_None,
     Doc_Theme_Neutral,
     Doc_Theme_Dark,
     Doc_Theme_Bright
   };
 
--- a/dom/base/nsNodeInfoManager.cpp
+++ b/dom/base/nsNodeInfoManager.cpp
@@ -114,17 +114,17 @@ nsNodeInfoManager::nsNodeInfoManager()
     mDocumentNodeInfo(nullptr)
 {
   nsLayoutStatics::AddRef();
 
   if (!gNodeInfoManagerLeakPRLog)
     gNodeInfoManagerLeakPRLog = PR_NewLogModule("NodeInfoManagerLeak");
 
   if (gNodeInfoManagerLeakPRLog)
-    PR_LOG(gNodeInfoManagerLeakPRLog, PR_LOG_DEBUG,
+    MOZ_LOG(gNodeInfoManagerLeakPRLog, PR_LOG_DEBUG,
            ("NODEINFOMANAGER %p created", this));
 
   mNodeInfoHash = PL_NewHashTable(32, GetNodeInfoInnerHashValue,
                                   NodeInfoInnerKeyCompare,
                                   PL_CompareValues, &allocOps, nullptr);
 }
 
 
@@ -134,17 +134,17 @@ nsNodeInfoManager::~nsNodeInfoManager()
     PL_HashTableDestroy(mNodeInfoHash);
 
   // Note: mPrincipal may be null here if we never got inited correctly
   mPrincipal = nullptr;
 
   mBindingManager = nullptr;
 
   if (gNodeInfoManagerLeakPRLog)
-    PR_LOG(gNodeInfoManagerLeakPRLog, PR_LOG_DEBUG,
+    MOZ_LOG(gNodeInfoManagerLeakPRLog, PR_LOG_DEBUG,
            ("NODEINFOMANAGER %p destroyed", this));
 
   nsLayoutStatics::Release();
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsNodeInfoManager)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsNodeInfoManager)
@@ -191,17 +191,17 @@ nsNodeInfoManager::Init(nsIDocument *aDo
     mBindingManager = new nsBindingManager(aDocument);
   }
 
   mDefaultPrincipal = mPrincipal;
 
   mDocument = aDocument;
 
   if (gNodeInfoManagerLeakPRLog)
-    PR_LOG(gNodeInfoManagerLeakPRLog, PR_LOG_DEBUG,
+    MOZ_LOG(gNodeInfoManagerLeakPRLog, PR_LOG_DEBUG,
            ("NODEINFOMANAGER %p Init document=%p", this, aDocument));
 
   return NS_OK;
 }
 
 // static
 int
 nsNodeInfoManager::DropNodeInfoDocument(PLHashEntry *he, int hashIndex, void *arg)
--- a/dom/base/nsObjectLoadingContent.cpp
+++ b/dom/base/nsObjectLoadingContent.cpp
@@ -110,17 +110,17 @@ static PRLogModuleInfo*
 GetObjectLog()
 {
   static PRLogModuleInfo *sLog;
   if (!sLog)
     sLog = PR_NewLogModule("objlc");
   return sLog;
 }
 
-#define LOG(args) PR_LOG(GetObjectLog(), PR_LOG_DEBUG, args)
+#define LOG(args) MOZ_LOG(GetObjectLog(), PR_LOG_DEBUG, args)
 #define LOG_ENABLED() PR_LOG_TEST(GetObjectLog(), PR_LOG_DEBUG)
 
 static bool
 IsJavaMIME(const nsACString & aMIMEType)
 {
   return
     nsPluginHost::GetSpecialType(aMIMEType) == nsPluginHost::eSpecialType_Java;
 }
--- a/dom/bluetooth/bluedroid/hfp-fallback/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluedroid/hfp-fallback/BluetoothHfpManager.cpp
@@ -196,16 +196,27 @@ BluetoothHfpManager::ConnectSco()
   /**
    * TODO:
    *   Implement ConnectSco() for applications that want to create SCO link
    *   without a HFP connection (e.g., VoIP).
    */
   return false;
 }
 
+void
+BluetoothHfpManager::HandleBackendError()
+{
+  /**
+   * TODO: 
+   *   Reset connection state and audio state to DISCONNECTED to handle backend
+   *   error. The state change triggers UI status bar update as ordinary
+   *   bluetooth turn-off sequence.
+   */
+}
+
 bool
 BluetoothHfpManager::DisconnectSco()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   /**
    * TODO:
    *   Implement DisconnectSco() for applications that want to destroy SCO link
--- a/dom/bluetooth/bluedroid/hfp-fallback/BluetoothHfpManager.h
+++ b/dom/bluetooth/bluedroid/hfp-fallback/BluetoothHfpManager.h
@@ -29,16 +29,18 @@ public:
   }
 
   static BluetoothHfpManager* Get();
   static void InitHfpInterface(BluetoothProfileResultHandler* aRes);
   static void DeinitHfpInterface(BluetoothProfileResultHandler* aRes);
 
   bool ConnectSco();
   bool DisconnectSco();
+  // Handle unexpected backend crash
+  void HandleBackendError();
 
 protected:
   virtual ~BluetoothHfpManager() { }
 
 private:
   BluetoothHfpManager() { }
   bool Init();
   void HandleShutdown();
--- a/dom/cache/DBSchema.cpp
+++ b/dom/cache/DBSchema.cpp
@@ -13,31 +13,32 @@
 #include "mozilla/dom/cache/Types.h"
 #include "mozilla/dom/cache/TypeUtils.h"
 #include "mozIStorageConnection.h"
 #include "mozIStorageStatement.h"
 #include "nsCOMPtr.h"
 #include "nsTArray.h"
 #include "nsCRT.h"
 #include "nsHttp.h"
+#include "nsICryptoHash.h"
 #include "mozilla/dom/HeadersBinding.h"
 #include "mozilla/dom/RequestBinding.h"
 #include "mozilla/dom/ResponseBinding.h"
 #include "nsIContentPolicy.h"
 
 namespace mozilla {
 namespace dom {
 namespace cache {
 namespace db {
 
-const int32_t kMaxWipeSchemaVersion = 8;
+const int32_t kMaxWipeSchemaVersion = 9;
 
 namespace {
 
-const int32_t kLatestSchemaVersion = 8;
+const int32_t kLatestSchemaVersion = 9;
 const int32_t kMaxEntriesPerStatement = 255;
 
 } // anonymous namespace
 
 // If any of the static_asserts below fail, it means that you have changed
 // the corresponding WebIDL enum in a way that may be incompatible with the
 // existing data stored in the DOM Cache.  You would need to update the Cache
 // database schema accordingly and adjust the failing static_assert.
@@ -146,30 +147,45 @@ static_assert(nsIContentPolicy::TYPE_INV
               nsIContentPolicy::TYPE_FETCH == 20 &&
               nsIContentPolicy::TYPE_IMAGESET == 21,
               "nsContentPolicytType values are as expected");
 
 namespace {
 
 typedef int32_t EntryId;
 
+struct IdCount
+{
+  IdCount() : mId(-1), mCount(0) { }
+  explicit IdCount(int32_t aId) : mId(aId), mCount(1) { }
+  int32_t mId;
+  int32_t mCount;
+};
+
 static nsresult QueryAll(mozIStorageConnection* aConn, CacheId aCacheId,
                          nsTArray<EntryId>& aEntryIdListOut);
 static nsresult QueryCache(mozIStorageConnection* aConn, CacheId aCacheId,
                            const CacheRequest& aRequest,
                            const CacheQueryParams& aParams,
                            nsTArray<EntryId>& aEntryIdListOut,
                            uint32_t aMaxResults = UINT32_MAX);
 static nsresult MatchByVaryHeader(mozIStorageConnection* aConn,
                                   const CacheRequest& aRequest,
                                   EntryId entryId, bool* aSuccessOut);
 static nsresult DeleteEntries(mozIStorageConnection* aConn,
                               const nsTArray<EntryId>& aEntryIdList,
                               nsTArray<nsID>& aDeletedBodyIdListOut,
+                              nsTArray<IdCount>& aDeletedSecurityIdListOut,
                               uint32_t aPos=0, int32_t aLen=-1);
+static nsresult InsertSecurity(mozIStorageConnection* aConn,
+                               const nsACString& aData, int32_t *aIdOut);
+static nsresult DeleteSecurityInfo(mozIStorageConnection* aConn, int32_t aId,
+                                   int32_t aCount);
+static nsresult DeleteSecurityInfoList(mozIStorageConnection* aConn,
+                                       const nsTArray<IdCount>& aDeletedStorageIdList);
 static nsresult InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
                             const CacheRequest& aRequest,
                             const nsID* aRequestBodyId,
                             const CacheResponse& aResponse,
                             const nsID* aResponseBodyId);
 static nsresult ReadResponse(mozIStorageConnection* aConn, EntryId aEntryId,
                              SavedResponse* aSavedResponseOut);
 static nsresult ReadRequest(mozIStorageConnection* aConn, EntryId aEntryId,
@@ -180,16 +196,20 @@ static void AppendListParamsToQuery(nsAC
                                     uint32_t aPos, int32_t aLen);
 static nsresult BindListParamsToQuery(mozIStorageStatement* aState,
                                       const nsTArray<EntryId>& aEntryIdList,
                                       uint32_t aPos, int32_t aLen);
 static nsresult BindId(mozIStorageStatement* aState, const nsACString& aName,
                        const nsID* aId);
 static nsresult ExtractId(mozIStorageStatement* aState, uint32_t aPos,
                           nsID* aIdOut);
+static nsresult CreateAndBindKeyStatement(mozIStorageConnection* aConn,
+                                          const char* aQueryFormat,
+                                          const nsAString& aKey,
+                                          mozIStorageStatement** aStateOut);
 } // anonymous namespace
 
 nsresult
 CreateSchema(mozIStorageConnection* aConn)
 {
   MOZ_ASSERT(!NS_IsMainThread());
   MOZ_ASSERT(aConn);
 
@@ -236,16 +256,34 @@ CreateSchema(mozIStorageConnection* aCon
     // AUTOINCREMENT is necessary to prevent CacheId values from being reused.
     rv = aConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
       "CREATE TABLE caches ("
         "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT "
       ");"
     ));
     if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
+    // Security blobs are quite large and duplicated for every Response from
+    // the same https origin.  This table is used to de-duplicate this data.
+    rv = aConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
+      "CREATE TABLE security_info ("
+        "id INTEGER NOT NULL PRIMARY KEY, "
+        "hash BLOB NOT NULL, "  // first 8-bytes of the sha1 hash of data column
+        "data BLOB NOT NULL, "  // full security info data, usually a few KB
+        "refcount INTEGER NOT NULL"
+      ");"
+    ));
+    if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+    // Index the smaller hash value instead of the large security data blob.
+    rv = aConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
+      "CREATE INDEX security_info_hash_index ON security_info (hash);"
+    ));
+    if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
     rv = aConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
       "CREATE TABLE entries ("
         "id INTEGER NOT NULL PRIMARY KEY, "
         "request_method TEXT NOT NULL, "
         "request_url TEXT NOT NULL, "
         "request_url_no_query TEXT NOT NULL, "
         "request_referrer TEXT NOT NULL, "
         "request_headers_guard INTEGER NOT NULL, "
@@ -256,17 +294,17 @@ CreateSchema(mozIStorageConnection* aCon
         "request_cache INTEGER NOT NULL, "
         "request_body_id TEXT NULL, "
         "response_type INTEGER NOT NULL, "
         "response_url TEXT NOT NULL, "
         "response_status INTEGER NOT NULL, "
         "response_status_text TEXT NOT NULL, "
         "response_headers_guard INTEGER NOT NULL, "
         "response_body_id TEXT NULL, "
-        "response_security_info BLOB NULL, "
+        "response_security_info_id INTEGER NULL REFERENCES security_info(id), "
         "cache_id INTEGER NOT NULL REFERENCES caches(id) ON DELETE CASCADE"
       ");"
     ));
     if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
     // TODO: see if we can remove these indices on TEXT columns (bug 1110458)
     rv = aConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
       "CREATE INDEX entries_request_url_index "
@@ -401,17 +439,22 @@ DeleteCacheId(mozIStorageConnection* aCo
 
   // Delete the bodies explicitly as we need to read out the body IDs
   // anyway.  These body IDs must be deleted one-by-one as content may
   // still be referencing them invidivually.
   nsAutoTArray<EntryId, 256> matches;
   nsresult rv = QueryAll(aConn, aCacheId, matches);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
-  rv = DeleteEntries(aConn, matches, aDeletedBodyIdListOut);
+  nsAutoTArray<IdCount, 16> deletedSecurityIdList;
+  rv = DeleteEntries(aConn, matches, aDeletedBodyIdListOut,
+                     deletedSecurityIdList);
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  rv = DeleteSecurityInfoList(aConn, deletedSecurityIdList);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   // Delete the remainder of the cache using cascade semantics.
   nsCOMPtr<mozIStorageStatement> state;
   rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
     "DELETE FROM caches WHERE id=:id;"
   ), getter_AddRefs(state));
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
@@ -533,23 +576,30 @@ CachePut(mozIStorageConnection* aConn, C
   MOZ_ASSERT(aConn);
 
   CacheQueryParams params(false, false, false, false,
                            NS_LITERAL_STRING(""));
   nsAutoTArray<EntryId, 256> matches;
   nsresult rv = QueryCache(aConn, aCacheId, aRequest, params, matches);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
-  rv = DeleteEntries(aConn, matches, aDeletedBodyIdListOut);
+  nsAutoTArray<IdCount, 16> deletedSecurityIdList;
+  rv = DeleteEntries(aConn, matches, aDeletedBodyIdListOut,
+                     deletedSecurityIdList);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   rv = InsertEntry(aConn, aCacheId, aRequest, aRequestBodyId, aResponse,
                    aResponseBodyId);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
+  // Delete the security values after doing the insert to avoid churning
+  // the security table when its not necessary.
+  rv = DeleteSecurityInfoList(aConn, deletedSecurityIdList);
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
   return rv;
 }
 
 nsresult
 CacheDelete(mozIStorageConnection* aConn, CacheId aCacheId,
             const CacheRequest& aRequest,
             const CacheQueryParams& aParams,
             nsTArray<nsID>& aDeletedBodyIdListOut, bool* aSuccessOut)
@@ -563,17 +613,22 @@ CacheDelete(mozIStorageConnection* aConn
   nsAutoTArray<EntryId, 256> matches;
   nsresult rv = QueryCache(aConn, aCacheId, aRequest, aParams, matches);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   if (matches.IsEmpty()) {
     return rv;
   }
 
-  rv = DeleteEntries(aConn, matches, aDeletedBodyIdListOut);
+  nsAutoTArray<IdCount, 16> deletedSecurityIdList;
+  rv = DeleteEntries(aConn, matches, aDeletedBodyIdListOut,
+                     deletedSecurityIdList);
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  rv = DeleteSecurityInfoList(aConn, deletedSecurityIdList);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   *aSuccessOut = true;
 
   return rv;
 }
 
 nsresult
@@ -685,30 +740,31 @@ StorageGetCacheId(mozIStorageConnection*
 {
   MOZ_ASSERT(!NS_IsMainThread());
   MOZ_ASSERT(aConn);
   MOZ_ASSERT(aFoundCacheOut);
   MOZ_ASSERT(aCacheIdOut);
 
   *aFoundCacheOut = false;
 
-  // Use IS for matching the key since an EmptryString() key maps to NULL.
+  // How we constrain the key column depends on the value of our key.  Use
+  // a format string for the query and let CreateAndBindKeyStatement() fill
+  // it in for us.
+  const char* query = "SELECT cache_id FROM storage "
+                      "WHERE namespace=:namespace AND %s "
+                      "ORDER BY rowid;";
+
   nsCOMPtr<mozIStorageStatement> state;
-  nsresult rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
-    "SELECT cache_id FROM storage WHERE namespace=:namespace AND key IS :key "
-                                 "ORDER BY rowid;"
-  ), getter_AddRefs(state));
+  nsresult rv = CreateAndBindKeyStatement(aConn, query, aKey,
+                                          getter_AddRefs(state));
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   rv = state->BindInt32ByName(NS_LITERAL_CSTRING("namespace"), aNamespace);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
-  rv = state->BindStringAsBlobByName(NS_LITERAL_CSTRING("key"), aKey);
-  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
-
   bool hasMoreData = false;
   rv = state->ExecuteStep(&hasMoreData);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   if (!hasMoreData) {
     return rv;
   }
 
@@ -750,29 +806,29 @@ StoragePutCache(mozIStorageConnection* a
 
 nsresult
 StorageForgetCache(mozIStorageConnection* aConn, Namespace aNamespace,
                    const nsAString& aKey)
 {
   MOZ_ASSERT(!NS_IsMainThread());
   MOZ_ASSERT(aConn);
 
-  // Use IS for matching the key since an EmptryString() key maps to NULL.
+  // How we constrain the key column depends on the value of our key.  Use
+  // a format string for the query and let CreateAndBindKeyStatement() fill
+  // it in for us.
+  const char *query = "DELETE FROM storage WHERE namespace=:namespace AND %s;";
+
   nsCOMPtr<mozIStorageStatement> state;
-  nsresult rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
-    "DELETE FROM storage WHERE namespace=:namespace AND key IS :key;"
-  ), getter_AddRefs(state));
+  nsresult rv = CreateAndBindKeyStatement(aConn, query, aKey,
+                                          getter_AddRefs(state));
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   rv = state->BindInt32ByName(NS_LITERAL_CSTRING("namespace"), aNamespace);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
-  rv = state->BindStringAsBlobByName(NS_LITERAL_CSTRING("key"), aKey);
-  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
-
   rv = state->Execute();
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   return rv;
 }
 
 nsresult
 StorageGetKeys(mozIStorageConnection* aConn, Namespace aNamespace,
@@ -1019,16 +1075,17 @@ MatchByVaryHeader(mozIStorageConnection*
   *aSuccessOut = varyHeadersMatch;
   return rv;
 }
 
 nsresult
 DeleteEntries(mozIStorageConnection* aConn,
               const nsTArray<EntryId>& aEntryIdList,
               nsTArray<nsID>& aDeletedBodyIdListOut,
+              nsTArray<IdCount>& aDeletedSecurityIdListOut,
               uint32_t aPos, int32_t aLen)
 {
   MOZ_ASSERT(!NS_IsMainThread());
   MOZ_ASSERT(aConn);
 
   if (aEntryIdList.IsEmpty()) {
     return NS_OK;
   }
@@ -1043,28 +1100,29 @@ DeleteEntries(mozIStorageConnection* aCo
   // so split up larger operations.
   if (aLen > kMaxEntriesPerStatement) {
     uint32_t curPos = aPos;
     int32_t remaining = aLen;
     while (remaining > 0) {
       int32_t max = kMaxEntriesPerStatement;
       int32_t curLen = std::min(max, remaining);
       nsresult rv = DeleteEntries(aConn, aEntryIdList, aDeletedBodyIdListOut,
-                                  curPos, curLen);
+                                  aDeletedSecurityIdListOut, curPos, curLen);
       if (NS_FAILED(rv)) { return rv; }
 
       curPos += curLen;
       remaining -= curLen;
     }
     return NS_OK;
   }
 
   nsCOMPtr<mozIStorageStatement> state;
   nsAutoCString query(
-    "SELECT request_body_id, response_body_id FROM entries WHERE id IN ("
+    "SELECT request_body_id, response_body_id, response_security_info_id "
+    "FROM entries WHERE id IN ("
   );
   AppendListParamsToQuery(query, aEntryIdList, aPos, aLen);
   query.AppendLiteral(")");
 
   nsresult rv = aConn->CreateStatement(query, getter_AddRefs(state));
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   rv = BindListParamsToQuery(state, aEntryIdList, aPos, aLen);
@@ -1081,16 +1139,43 @@ DeleteEntries(mozIStorageConnection* aCo
 
       if (!isNull) {
         nsID id;
         rv = ExtractId(state, i, &id);
         if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
         aDeletedBodyIdListOut.AppendElement(id);
       }
     }
+
+    // and then a possible third entry for the security id
+    bool isNull = false;
+    rv = state->GetIsNull(2, &isNull);
+    if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+    if (!isNull) {
+      int32_t securityId = -1;
+      rv = state->GetInt32(2, &securityId);
+      if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+      // First try to increment the count for this ID if we're already
+      // seen it
+      bool found = false;
+      for (uint32_t i = 0; i < aDeletedSecurityIdListOut.Length(); ++i) {
+        if (aDeletedSecurityIdListOut[i].mId == securityId) {
+          found = true;
+          aDeletedSecurityIdListOut[i].mCount += 1;
+          break;
+        }
+      }
+
+      // Otherwise add a new entry for this ID with a count of 1
+      if (!found) {
+        aDeletedSecurityIdListOut.AppendElement(IdCount(securityId));
+      }
+    }
   }
 
   // Dependent records removed via ON DELETE CASCADE
 
   query = NS_LITERAL_CSTRING(
     "DELETE FROM entries WHERE id IN ("
   );
   AppendListParamsToQuery(query, aEntryIdList, aPos, aLen);
@@ -1104,27 +1189,223 @@ DeleteEntries(mozIStorageConnection* aCo
 
   rv = state->Execute();
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   return rv;
 }
 
 nsresult
+InsertSecurity(mozIStorageConnection* aConn, const nsACString& aData,
+               int32_t *aIdOut)
+{
+  MOZ_ASSERT(aConn);
+  MOZ_ASSERT(aIdOut);
+  MOZ_ASSERT(!aData.IsEmpty());
+
+  // We want to use an index to find existing security blobs, but indexing
+  // the full blob would be quite expensive.  Instead, we index a small
+  // hash value.  Calculate this hash as the first 8 bytes of the SHA1 of
+  // the full data.
+  nsresult rv;
+  nsCOMPtr<nsICryptoHash> crypto =
+    do_CreateInstance(NS_CRYPTO_HASH_CONTRACTID, &rv);
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  rv = crypto->Init(nsICryptoHash::SHA1);
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  rv = crypto->Update(reinterpret_cast<const uint8_t*>(aData.BeginReading()),
+                      aData.Length());
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  nsAutoCString fullHash;
+  rv = crypto->Finish(false /* based64 result */, fullHash);
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  nsDependentCSubstring hash(fullHash, 0, 8);
+
+  // Next, search for an existing entry for this blob by comparing the hash
+  // value first and then the full data.  SQLite is smart enough to use
+  // the index on the hash to search the table before doing the expensive
+  // comparison of the large data column.  (This was verified with EXPLAIN.)
+  nsCOMPtr<mozIStorageStatement> state;
+  rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
+    // Note that hash and data are blobs, but we can use = here since the
+    // columns are NOT NULL.
+    "SELECT id, refcount FROM security_info WHERE hash=:hash AND data=:data;"
+  ), getter_AddRefs(state));
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  rv = state->BindUTF8StringAsBlobByName(NS_LITERAL_CSTRING("hash"), hash);
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  rv = state->BindUTF8StringAsBlobByName(NS_LITERAL_CSTRING("data"), aData);
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  bool hasMoreData = false;
+  rv = state->ExecuteStep(&hasMoreData);
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  // This security info blob is already in the database
+  if (hasMoreData) {
+    // get the existing security blob id to return
+    rv = state->GetInt32(0, aIdOut);
+    if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+    int32_t refcount = -1;
+    rv = state->GetInt32(1, &refcount);
+    if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+    // But first, update the refcount in the database.
+    refcount += 1;
+
+    rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
+      "UPDATE security_info SET refcount=:refcount WHERE id=:id;"
+    ), getter_AddRefs(state));
+    if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+    rv = state->BindInt32ByName(NS_LITERAL_CSTRING("refcount"), refcount);
+    if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+    rv = state->BindInt32ByName(NS_LITERAL_CSTRING("id"), *aIdOut);
+    if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+    rv = state->Execute();
+    if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+    return NS_OK;
+  }
+
+  // This is a new security info blob.  Create a new row in the security table
+  // with an initial refcount of 1.
+  rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
+    "INSERT INTO security_info (hash, data, refcount) VALUES (:hash, :data, 1);"
+  ), getter_AddRefs(state));
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  rv = state->BindUTF8StringAsBlobByName(NS_LITERAL_CSTRING("hash"), hash);
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  rv = state->BindUTF8StringAsBlobByName(NS_LITERAL_CSTRING("data"), aData);
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  rv = state->Execute();
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
+    "SELECT last_insert_rowid()"
+  ), getter_AddRefs(state));
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  hasMoreData = false;
+  rv = state->ExecuteStep(&hasMoreData);
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  rv = state->GetInt32(0, aIdOut);
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  return NS_OK;
+}
+
+nsresult
+DeleteSecurityInfo(mozIStorageConnection* aConn, int32_t aId, int32_t aCount)
+{
+  // First, we need to determine the current refcount for this security blob.
+  nsCOMPtr<mozIStorageStatement> state;
+  nsresult rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
+    "SELECT refcount FROM security_info WHERE id=:id;"
+  ), getter_AddRefs(state));
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  rv = state->BindInt32ByName(NS_LITERAL_CSTRING("id"), aId);
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  bool hasMoreData = false;
+  rv = state->ExecuteStep(&hasMoreData);
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  int32_t refcount = -1;
+  rv = state->GetInt32(0, &refcount);
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  MOZ_ASSERT(refcount >= aCount);
+
+  // Next, calculate the new refcount
+  int32_t newCount = refcount - aCount;
+
+  // If the last reference to this security blob was removed we can
+  // just remove the entire row.
+  if (newCount == 0) {
+    rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
+      "DELETE FROM security_info WHERE id=:id;"
+    ), getter_AddRefs(state));
+    if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+    rv = state->BindInt32ByName(NS_LITERAL_CSTRING("id"), aId);
+    if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+    rv = state->Execute();
+    if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+    return NS_OK;
+  }
+
+  // Otherwise update the refcount in the table to reflect the reduced
+  // number of references to the security blob.
+  rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
+    "UPDATE security_info SET refcount=:refcount WHERE id=:id;"
+  ), getter_AddRefs(state));
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  rv = state->BindInt32ByName(NS_LITERAL_CSTRING("refcount"), newCount);
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  rv = state->BindInt32ByName(NS_LITERAL_CSTRING("id"), aId);
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  rv = state->Execute();
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  return NS_OK;
+}
+
+nsresult
+DeleteSecurityInfoList(mozIStorageConnection* aConn,
+                        const nsTArray<IdCount>& aDeletedStorageIdList)
+{
+  for (uint32_t i = 0; i < aDeletedStorageIdList.Length(); ++i) {
+    nsresult rv = DeleteSecurityInfo(aConn, aDeletedStorageIdList[i].mId,
+                                     aDeletedStorageIdList[i].mCount);
+    if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+  }
+
+  return NS_OK;
+}
+
+nsresult
 InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
             const CacheRequest& aRequest,
             const nsID* aRequestBodyId,
             const CacheResponse& aResponse,
             const nsID* aResponseBodyId)
 {
   MOZ_ASSERT(!NS_IsMainThread());
   MOZ_ASSERT(aConn);
 
+  nsresult rv = NS_OK;
+  int32_t securityId = -1;
+
+  if (!aResponse.securityInfo().IsEmpty()) {
+    rv = InsertSecurity(aConn, aResponse.securityInfo(), &securityId);
+    if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+  }
+
   nsCOMPtr<mozIStorageStatement> state;
-  nsresult rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
+  rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
     "INSERT INTO entries ("
       "request_method, "
       "request_url, "
       "request_url_no_query, "
       "request_referrer, "
       "request_headers_guard, "
       "request_mode, "
       "request_credentials, "
@@ -1133,17 +1414,17 @@ InsertEntry(mozIStorageConnection* aConn
       "request_cache, "
       "request_body_id, "
       "response_type, "
       "response_url, "
       "response_status, "
       "response_status_text, "
       "response_headers_guard, "
       "response_body_id, "
-      "response_security_info, "
+      "response_security_info_id, "
       "cache_id "
     ") VALUES ("
       ":request_method, "
       ":request_url, "
       ":request_url_no_query, "
       ":request_referrer, "
       ":request_headers_guard, "
       ":request_mode, "
@@ -1153,17 +1434,17 @@ InsertEntry(mozIStorageConnection* aConn
       ":request_cache, "
       ":request_body_id, "
       ":response_type, "
       ":response_url, "
       ":response_status, "
       ":response_status_text, "
       ":response_headers_guard, "
       ":response_body_id, "
-      ":response_security_info, "
+      ":response_security_info_id, "
       ":cache_id "
     ");"
   ), getter_AddRefs(state));
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   rv = state->BindUTF8StringByName(NS_LITERAL_CSTRING("request_method"),
                                    aRequest.method());
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
@@ -1225,18 +1506,22 @@ InsertEntry(mozIStorageConnection* aConn
 
   rv = state->BindInt32ByName(NS_LITERAL_CSTRING("response_headers_guard"),
     static_cast<int32_t>(aResponse.headersGuard()));
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   rv = BindId(state, NS_LITERAL_CSTRING("response_body_id"), aResponseBodyId);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
-  rv = state->BindUTF8StringAsBlobByName(NS_LITERAL_CSTRING("response_security_info"),
-                                         aResponse.securityInfo());
+  if (aResponse.securityInfo().IsEmpty()) {
+    rv = state->BindNullByName(NS_LITERAL_CSTRING("response_security_info_id"));
+  } else {
+    rv = state->BindInt32ByName(NS_LITERAL_CSTRING("response_security_info_id"),
+                                securityId);
+  }
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   rv = state->BindInt64ByName(NS_LITERAL_CSTRING("cache_id"), aCacheId);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   rv = state->Execute();
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
@@ -1314,25 +1599,27 @@ ReadResponse(mozIStorageConnection* aCon
 {
   MOZ_ASSERT(!NS_IsMainThread());
   MOZ_ASSERT(aConn);
   MOZ_ASSERT(aSavedResponseOut);
 
   nsCOMPtr<mozIStorageStatement> state;
   nsresult rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
     "SELECT "
-      "response_type, "
-      "response_url, "
-      "response_status, "
-      "response_status_text, "
-      "response_headers_guard, "
-      "response_body_id, "
-      "response_security_info "
+      "entries.response_type, "
+      "entries.response_url, "
+      "entries.response_status, "
+      "entries.response_status_text, "
+      "entries.response_headers_guard, "
+      "entries.response_body_id, "
+      "security_info.data "
     "FROM entries "
-    "WHERE id=:id;"
+    "LEFT OUTER JOIN security_info "
+    "ON entries.response_security_info_id=security_info.id "
+    "WHERE entries.id=:id;"
   ), getter_AddRefs(state));
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   rv = state->BindInt32ByName(NS_LITERAL_CSTRING("id"), aEntryId);
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   bool hasMoreData = false;
   rv = state->ExecuteStep(&hasMoreData);
@@ -1581,14 +1868,53 @@ ExtractId(mozIStorageStatement* aState, 
   if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
 
   bool success = aIdOut->Parse(idString.get());
   if (NS_WARN_IF(!success)) { return NS_ERROR_UNEXPECTED; }
 
   return rv;
 }
 
+nsresult
+CreateAndBindKeyStatement(mozIStorageConnection* aConn,
+                          const char* aQueryFormat,
+                          const nsAString& aKey,
+                          mozIStorageStatement** aStateOut)
+{
+  MOZ_ASSERT(aConn);
+  MOZ_ASSERT(aQueryFormat);
+  MOZ_ASSERT(aStateOut);
+
+  // The key is stored as a blob to avoid encoding issues.  An empty string
+  // is mapped to NULL for blobs.  Normally we would just write the query
+  // as "key IS :key" to do the proper NULL checking, but that prevents
+  // sqlite from using the key index.  Therefore use "IS NULL" explicitly
+  // if the key is empty, otherwise use "=:key" so that sqlite uses the
+  // index.
+  const char* constraint = nullptr;
+  if (aKey.IsEmpty()) {
+    constraint = "key IS NULL";
+  } else {
+    constraint = "key=:key";
+  }
+
+  nsPrintfCString query(aQueryFormat, constraint);
+
+  nsCOMPtr<mozIStorageStatement> state;
+  nsresult rv = aConn->CreateStatement(query, getter_AddRefs(state));
+  if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+
+  if (!aKey.IsEmpty()) {
+    rv = state->BindStringAsBlobByName(NS_LITERAL_CSTRING("key"), aKey);
+    if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
+  }
+
+  state.forget(aStateOut);
+
+  return rv;
+}
+
 } // anonymouns namespace
 
 } // namespace db
 } // namespace cache
 } // namespace dom
 } // namespace mozilla
--- a/dom/cache/test/mochitest/mochitest.ini
+++ b/dom/cache/test/mochitest/mochitest.ini
@@ -15,22 +15,25 @@ support-files =
   test_cache_match_vary.js
   vary.sjs
   test_caches.js
   test_cache_keys.js
   test_cache_put.js
   test_cache_requestCache.js
   test_cache_delete.js
   test_cache_put_reorder.js
+  test_cache_https.js
 
 [test_cache.html]
 [test_cache_add.html]
 [test_cache_match_request.html]
 [test_cache_matchAll_request.html]
 [test_cache_overwrite.html]
 [test_cache_match_vary.html]
 [test_caches.html]
 [test_cache_keys.html]
 [test_cache_put.html]
 [test_cache_requestCache.html]
 [test_cache_delete.html]
 [test_cache_put_reorder.html]
+[test_cache_https.html]
+  skip-if = buildapp == 'b2g' # bug 1162353
 [test_cache_restart.html]
new file mode 100644
--- /dev/null
+++ b/dom/cache/test/mochitest/test_cache_https.html
@@ -0,0 +1,20 @@
+<!-- Any copyright is dedicated to the Public Domain.
+   - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Validate Interfaces Exposed to Workers</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="driver.js"></script>
+</head>
+<body>
+<iframe id="frame"></iframe>
+<script class="testbody" type="text/javascript">
+  runTests("test_cache_https.js")
+    .then(function() {
+      SimpleTest.finish();
+    });
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/cache/test/mochitest/test_cache_https.js
@@ -0,0 +1,23 @@
+var cache = null;
+var name = 'https_' + context;
+var urlBase = 'https://example.com/tests/dom/cache/test/mochitest';
+var url1 = urlBase + '/test_cache.js';
+var url2 = urlBase + '/test_cache_add.js';
+
+caches.open(name).then(function(c) {
+  cache = c;
+  return cache.addAll([new Request(url1, { mode: 'no-cors' }),
+                       new Request(url2, { mode: 'no-cors' })]);
+}).then(function() {
+  return cache.delete(url1);
+}).then(function(result) {
+  ok(result, 'Cache entry should be deleted');
+  return cache.delete(url2);
+}).then(function(result) {
+  ok(result, 'Cache entry should be deleted');
+  cache = null;
+  return caches.delete(name);
+}).then(function(result) {
+  ok(result, 'Cache should be deleted');
+  testDone();
+});
--- a/dom/camera/CameraCommon.h
+++ b/dom/camera/CameraCommon.h
@@ -13,17 +13,17 @@
 #else
 #define __func__ __FILE__
 #endif
 #endif
 
 #include "mozilla/Logging.h"
 
 extern PRLogModuleInfo* GetCameraLog();
-#define DOM_CAMERA_LOG( type, ... ) PR_LOG(GetCameraLog(), (PRLogModuleLevel)type, ( __VA_ARGS__ ))
+#define DOM_CAMERA_LOG( type, ... ) MOZ_LOG(GetCameraLog(), (PRLogModuleLevel)type, ( __VA_ARGS__ ))
 
 #define DOM_CAMERA_LOGA( ... )      DOM_CAMERA_LOG( 0, __VA_ARGS__ )
 
 /**
  * From the least to the most output.
  */
 enum {
   DOM_CAMERA_LOG_NOTHING,
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -4074,24 +4074,26 @@ bool CanvasRenderingContext2D::IsPointIn
 // relative to the returned surface.
 static TemporaryRef<SourceSurface>
 ExtractSubrect(SourceSurface* aSurface, mgfx::Rect* aSourceRect, DrawTarget* aTargetDT)
 {
   mgfx::Rect roundedOutSourceRect = *aSourceRect;
   roundedOutSourceRect.RoundOut();
   mgfx::IntRect roundedOutSourceRectInt;
   if (!roundedOutSourceRect.ToIntRect(&roundedOutSourceRectInt)) {
-    return aSurface;
+    RefPtr<SourceSurface> surface(aSurface);
+    return surface.forget();
   }
 
   RefPtr<DrawTarget> subrectDT =
     aTargetDT->CreateSimilarDrawTarget(roundedOutSourceRectInt.Size(), SurfaceFormat::B8G8R8A8);
 
   if (!subrectDT) {
-    return aSurface;
+    RefPtr<SourceSurface> surface(aSurface);
+    return surface.forget();
   }
 
   *aSourceRect -= roundedOutSourceRect.TopLeft();
 
   subrectDT->CopySurface(aSurface, roundedOutSourceRectInt, IntPoint());
   return subrectDT->Snapshot();
 }
 
@@ -5629,40 +5631,44 @@ CanvasPath::GetPath(const CanvasWindingR
   FillRule fillRule = FillRule::FILL_WINDING;
   if (winding == CanvasWindingRule::Evenodd) {
     fillRule = FillRule::FILL_EVEN_ODD;
   }
 
   if (mPath &&
       (mPath->GetBackendType() == aTarget->GetBackendType()) &&
       (mPath->GetFillRule() == fillRule)) {
-    return mPath;
+    RefPtr<gfx::Path> path(mPath);
+    return path.forget();
   }
 
   if (!mPath) {
     // if there is no path, there must be a pathbuilder
     MOZ_ASSERT(mPathBuilder);
     mPath = mPathBuilder->Finish();
-    if (!mPath)
-      return mPath;
+    if (!mPath) {
+      RefPtr<gfx::Path> path(mPath);
+      return path.forget();
+    }
 
     mPathBuilder = nullptr;
   }
 
   // retarget our backend if we're used with a different backend
   if (mPath->GetBackendType() != aTarget->GetBackendType()) {
     RefPtr<PathBuilder> tmpPathBuilder = aTarget->CreatePathBuilder(fillRule);
     mPath->StreamToSink(tmpPathBuilder);
     mPath = tmpPathBuilder->Finish();
   } else if (mPath->GetFillRule() != fillRule) {
     RefPtr<PathBuilder> tmpPathBuilder = mPath->CopyToBuilder(fillRule);
     mPath = tmpPathBuilder->Finish();
   }
 
-  return mPath;
+  RefPtr<gfx::Path> path(mPath);
+  return path.forget();
 }
 
 void
 CanvasPath::EnsurePathBuilder() const
 {
   if (mPathBuilder) {
     return;
   }
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -189,16 +189,17 @@ WebGLObserver::HandleEvent(nsIDOMEvent* 
 
 WebGLContextOptions::WebGLContextOptions()
     : alpha(true)
     , depth(true)
     , stencil(false)
     , premultipliedAlpha(true)
     , antialias(true)
     , preserveDrawingBuffer(false)
+    , failIfMajorPerformanceCaveat(false)
 {
     // Set default alpha state based on preference.
     if (Preferences::GetBool("webgl.default-no-alpha", false))
         alpha = false;
 }
 
 WebGLContext::WebGLContext()
     : WebGLContextUnchecked(nullptr)
@@ -426,16 +427,17 @@ WebGLContext::SetContextOptions(JSContex
 
     WebGLContextOptions newOpts;
 
     newOpts.stencil = attributes.mStencil;
     newOpts.depth = attributes.mDepth;
     newOpts.premultipliedAlpha = attributes.mPremultipliedAlpha;
     newOpts.antialias = attributes.mAntialias;
     newOpts.preserveDrawingBuffer = attributes.mPreserveDrawingBuffer;
+    newOpts.failIfMajorPerformanceCaveat = attributes.mFailIfMajorPerformanceCaveat;
 
     if (attributes.mAlpha.WasPassed())
         newOpts.alpha = attributes.mAlpha.Value();
 
     // Don't do antialiasing if we've disabled MSAA.
     if (!gfxPrefs::MSAALevel())
       newOpts.antialias = false;
 
@@ -495,16 +497,40 @@ IsFeatureInBlacklist(const nsCOMPtr<nsIG
 {
     int32_t status;
     if (!NS_SUCCEEDED(gfxInfo->GetFeatureStatus(feature, &status)))
         return false;
 
     return status != nsIGfxInfo::FEATURE_STATUS_OK;
 }
 
+static bool
+HasAcceleratedLayers(const nsCOMPtr<nsIGfxInfo>& gfxInfo)
+{
+    int32_t status;
+
+    gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_DIRECT3D_9_LAYERS, &status);
+    if (status)
+        return true;
+    gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_DIRECT3D_10_LAYERS, &status);
+    if (status)
+        return true;
+    gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_DIRECT3D_10_1_LAYERS, &status);
+    if (status)
+        return true;
+    gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_DIRECT3D_11_LAYERS, &status);
+    if (status)
+        return true;
+    gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_OPENGL_LAYERS, &status);
+    if (status)
+        return true;
+
+    return false;
+}
+
 static already_AddRefed<GLContext>
 CreateHeadlessNativeGL(bool forceEnabled, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
                        bool requireCompatProfile, WebGLContext* webgl)
 {
     if (!forceEnabled &&
         IsFeatureInBlacklist(gfxInfo, nsIGfxInfo::FEATURE_WEBGL_OPENGL))
     {
         webgl->GenerateWarning("Refused to create native OpenGL context"
@@ -564,17 +590,16 @@ CreateHeadlessEGL(bool forceEnabled, boo
         return nullptr;
     }
     MOZ_ASSERT(!gl->IsANGLE());
 #endif
 
     return gl.forget();
 }
 
-
 static already_AddRefed<GLContext>
 CreateHeadlessGL(bool forceEnabled, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
                  WebGLContext* webgl)
 {
     bool preferEGL = PR_GetEnv("MOZ_WEBGL_PREFER_EGL");
     bool disableANGLE = Preferences::GetBool("webgl.disable-angle", false);
 
     if (PR_GetEnv("MOZ_WEBGL_FORCE_OPENGL"))
@@ -868,16 +893,28 @@ WebGLContext::SetDimensions(int32_t sign
     NS_ENSURE_TRUE(Preferences::GetRootBranch(), NS_ERROR_FAILURE);
 
     bool disabled = Preferences::GetBool("webgl.disabled", false);
     if (disabled) {
         GenerateWarning("WebGL creation is disabled, and so disallowed here.");
         return NS_ERROR_FAILURE;
     }
 
+    nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
+    bool failIfMajorPerformanceCaveat =
+                    !gfxPrefs::WebGLDisableFailIfMajorPerformanceCaveat() &&
+                    !HasAcceleratedLayers(gfxInfo);
+    if (failIfMajorPerformanceCaveat) {
+        Nullable<dom::WebGLContextAttributes> contextAttributes;
+        this->GetContextAttributes(contextAttributes);
+        if (contextAttributes.Value().mFailIfMajorPerformanceCaveat) {
+            return NS_ERROR_FAILURE;
+        }
+    }
+
     // Alright, now let's start trying.
     bool forceEnabled = Preferences::GetBool("webgl.force-enabled", false);
     ScopedGfxFeatureReporter reporter("WebGL", forceEnabled);
 
     if (!CreateOffscreenGL(forceEnabled)) {
         GenerateWarning("WebGL creation failed.");
         return NS_ERROR_FAILURE;
     }
@@ -1250,16 +1287,17 @@ WebGLContext::GetContextAttributes(Nulla
     dom::WebGLContextAttributes& result = retval.SetValue();
 
     result.mAlpha.Construct(mOptions.alpha);
     result.mDepth = mOptions.depth;
     result.mStencil = mOptions.stencil;
     result.mAntialias = mOptions.antialias;
     result.mPremultipliedAlpha = mOptions.premultipliedAlpha;
     result.mPreserveDrawingBuffer = mOptions.preserveDrawingBuffer;
+    result.mFailIfMajorPerformanceCaveat = mOptions.failIfMajorPerformanceCaveat;
 }
 
 /* [noscript] DOMString mozGetUnderlyingParamString(in GLenum pname); */
 NS_IMETHODIMP
 WebGLContext::MozGetUnderlyingParamString(uint32_t pname, nsAString& retval)
 {
     if (IsContextLost())
         return NS_OK;
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -123,16 +123,17 @@ struct WebGLContextOptions
     }
 
     bool alpha;
     bool depth;
     bool stencil;
     bool premultipliedAlpha;
     bool antialias;
     bool preserveDrawingBuffer;
+    bool failIfMajorPerformanceCaveat;
 };
 
 // From WebGLContextUtils
 TexTarget TexImageTargetToTexTarget(TexImageTarget texImageTarget);
 
 class WebGLIntOrFloat {
     enum {
         Int,
--- a/dom/events/IMEStateManager.cpp
+++ b/dom/events/IMEStateManager.cpp
@@ -196,17 +196,17 @@ IMEStateManager::Init()
     sISMLog = PR_NewLogModule("IMEStateManager");
   }
 }
 
 // static
 void
 IMEStateManager::Shutdown()
 {
-  PR_LOG(sISMLog, PR_LOG_ALWAYS,
+  MOZ_LOG(sISMLog, PR_LOG_ALWAYS,
     ("ISM: IMEStateManager::Shutdown(), "
      "sTextCompositions=0x%p, sTextCompositions->Length()=%u",
      sTextCompositions, sTextCompositions ? sTextCompositions->Length() : 0));
 
   MOZ_ASSERT(!sTextCompositions || !sTextCompositions->Length());
   delete sTextCompositions;
   sTextCompositions = nullptr;
 }
@@ -217,37 +217,37 @@ IMEStateManager::OnDestroyPresContext(ns
 {
   NS_ENSURE_ARG_POINTER(aPresContext);
 
   // First, if there is a composition in the aPresContext, clean up it.
   if (sTextCompositions) {
     TextCompositionArray::index_type i =
       sTextCompositions->IndexOf(aPresContext);
     if (i != TextCompositionArray::NoIndex) {
-      PR_LOG(sISMLog, PR_LOG_DEBUG,
+      MOZ_LOG(sISMLog, PR_LOG_DEBUG,
         ("ISM:   IMEStateManager::OnDestroyPresContext(), "
          "removing TextComposition instance from the array (index=%u)", i));
       // there should be only one composition per presContext object.
       sTextCompositions->ElementAt(i)->Destroy();
       sTextCompositions->RemoveElementAt(i);
       if (sTextCompositions->IndexOf(aPresContext) !=
             TextCompositionArray::NoIndex) {
-        PR_LOG(sISMLog, PR_LOG_ERROR,
+        MOZ_LOG(sISMLog, PR_LOG_ERROR,
           ("ISM:   IMEStateManager::OnDestroyPresContext(), FAILED to remove "
            "TextComposition instance from the array"));
         MOZ_CRASH("Failed to remove TextComposition instance from the array");
       }
     }
   }
 
   if (aPresContext != sPresContext) {
     return NS_OK;
   }
 
-  PR_LOG(sISMLog, PR_LOG_ALWAYS,
+  MOZ_LOG(sISMLog, PR_LOG_ALWAYS,
     ("ISM: IMEStateManager::OnDestroyPresContext(aPresContext=0x%p), "
      "sPresContext=0x%p, sContent=0x%p, sTextCompositions=0x%p",
      aPresContext, sPresContext, sContent, sTextCompositions));
 
   DestroyIMEContentObserver();
 
   nsCOMPtr<nsIWidget> widget = sPresContext->GetRootWidget();
   if (widget) {
@@ -269,17 +269,17 @@ IMEStateManager::OnRemoveContent(nsPresC
   NS_ENSURE_ARG_POINTER(aPresContext);
 
   // First, if there is a composition in the aContent, clean up it.
   if (sTextCompositions) {
     nsRefPtr<TextComposition> compositionInContent =
       sTextCompositions->GetCompositionInContent(aPresContext, aContent);
 
     if (compositionInContent) {
-      PR_LOG(sISMLog, PR_LOG_DEBUG,
+      MOZ_LOG(sISMLog, PR_LOG_DEBUG,
         ("ISM:   IMEStateManager::OnRemoveContent(), "
          "composition is in the content"));
 
       // Try resetting the native IME state.  Be aware, typically, this method
       // is called during the content being removed.  Then, the native
       // composition events which are caused by following APIs are ignored due
       // to unsafe to run script (in PresShell::HandleEvent()).
       nsCOMPtr<nsIWidget> widget = aPresContext->GetRootWidget();
@@ -292,17 +292,17 @@ IMEStateManager::OnRemoveContent(nsPresC
     }
   }
 
   if (!sPresContext || !sContent ||
       !nsContentUtils::ContentIsDescendantOf(sContent, aContent)) {
     return NS_OK;
   }
 
-  PR_LOG(sISMLog, PR_LOG_ALWAYS,
+  MOZ_LOG(sISMLog, PR_LOG_ALWAYS,
     ("ISM: IMEStateManager::OnRemoveContent(aPresContext=0x%p, "
      "aContent=0x%p), sPresContext=0x%p, sContent=0x%p, sTextCompositions=0x%p",
      aPresContext, aContent, sPresContext, sContent, sTextCompositions));
 
   DestroyIMEContentObserver();
 
   // Current IME transaction should commit
   nsCOMPtr<nsIWidget> widget = sPresContext->GetRootWidget();
@@ -320,32 +320,32 @@ IMEStateManager::OnRemoveContent(nsPresC
 }
 
 // static
 nsresult
 IMEStateManager::OnChangeFocus(nsPresContext* aPresContext,
                                nsIContent* aContent,
                                InputContextAction::Cause aCause)
 {
-  PR_LOG(sISMLog, PR_LOG_ALWAYS,
+  MOZ_LOG(sISMLog, PR_LOG_ALWAYS,
     ("ISM: IMEStateManager::OnChangeFocus(aPresContext=0x%p, "
      "aContent=0x%p, aCause=%s)",
      aPresContext, aContent, GetActionCauseName(aCause)));
 
   InputContextAction action(aCause);
   return OnChangeFocusInternal(aPresContext, aContent, action);
 }
 
 // static
 nsresult
 IMEStateManager::OnChangeFocusInternal(nsPresContext* aPresContext,
                                        nsIContent* aContent,
                                        InputContextAction aAction)
 {
-  PR_LOG(sISMLog, PR_LOG_ALWAYS,
+  MOZ_LOG(sISMLog, PR_LOG_ALWAYS,
     ("ISM: IMEStateManager::OnChangeFocusInternal(aPresContext=0x%p, "
      "aContent=0x%p, aAction={ mCause=%s, mFocusChange=%s }), "
      "sPresContext=0x%p, sContent=0x%p, sActiveIMEContentObserver=0x%p",
      aPresContext, aContent, GetActionCauseName(aAction.mCause),
      GetActionFocusChangeName(aAction.mFocusChange),
      sPresContext, sContent, sActiveIMEContentObserver));
 
   bool focusActuallyChanging =
@@ -363,27 +363,27 @@ IMEStateManager::OnChangeFocusInternal(n
 
   if (sActiveIMEContentObserver &&
       (aPresContext || !sActiveIMEContentObserver->KeepAliveDuringDeactive()) &&
       !sActiveIMEContentObserver->IsManaging(aPresContext, aContent)) {
     DestroyIMEContentObserver();
   }
 
   if (!aPresContext) {
-    PR_LOG(sISMLog, PR_LOG_DEBUG,
+    MOZ_LOG(sISMLog, PR_LOG_DEBUG,
       ("ISM:   IMEStateManager::OnChangeFocusInternal(), "
        "no nsPresContext is being activated"));
     return NS_OK;
   }
 
   nsCOMPtr<nsIWidget> widget =
     (sPresContext == aPresContext) ? oldWidget.get() :
                                      aPresContext->GetRootWidget();
   if (NS_WARN_IF(!widget)) {
-    PR_LOG(sISMLog, PR_LOG_ERROR,
+    MOZ_LOG(sISMLog, PR_LOG_ERROR,
       ("ISM:   IMEStateManager::OnChangeFocusInternal(), FAILED due to "
        "no widget to manage its IME state"));
     return NS_OK;
   }
 
   IMEState newState = GetNewIMEState(aPresContext, aContent);
 
   // In e10s, remote content may have IME focus.  The main process (i.e. this process)
@@ -391,32 +391,32 @@ IMEStateManager::OnChangeFocusInternal(n
   // some other remote content.  The content process would later re-ENABLE IME, meaning
   // that all state-changes were unnecessary.
   // Here we filter the common case where the main process knows that the remote
   // process controls IME focus.  The DISABLED->re-ENABLED progression can
   // still happen since remote content may be concurrently communicating its claim
   // on focus to the main process... but this cannot cause bugs like missed keypresses.
   // (It just means a lot of needless IPC.)
   if ((newState.mEnabled == IMEState::DISABLED) && TabParent::GetIMETabParent()) {
-    PR_LOG(sISMLog, PR_LOG_DEBUG,
+    MOZ_LOG(sISMLog, PR_LOG_DEBUG,
       ("ISM:   IMEStateManager::OnChangeFocusInternal(), "
        "Parent process cancels to set DISABLED state because the content process "
        "has IME focus and has already sets IME state"));  
     MOZ_ASSERT(XRE_IsParentProcess(),
       "TabParent::GetIMETabParent() should never return non-null value "
       "in the content process");
     return NS_OK;
   }
 
   if (!focusActuallyChanging) {
     // actual focus isn't changing, but if IME enabled state is changing,
     // we should do it.
     InputContext context = widget->GetInputContext();
     if (context.mIMEState.mEnabled == newState.mEnabled) {
-      PR_LOG(sISMLog, PR_LOG_DEBUG,
+      MOZ_LOG(sISMLog, PR_LOG_DEBUG,
         ("ISM:   IMEStateManager::OnChangeFocusInternal(), "
          "neither focus nor IME state is changing"));
       return NS_OK;
     }
     aAction.mFocusChange = InputContextAction::FOCUS_NOT_CHANGED;
 
     // Even if focus isn't changing actually, we should commit current
     // composition here since the IME state is changing.
@@ -445,17 +445,17 @@ IMEStateManager::OnChangeFocusInternal(n
 
   return NS_OK;
 }
 
 // static
 void
 IMEStateManager::OnInstalledMenuKeyboardListener(bool aInstalling)
 {
-  PR_LOG(sISMLog, PR_LOG_ALWAYS,
+  MOZ_LOG(sISMLog, PR_LOG_ALWAYS,
     ("ISM: IMEStateManager::OnInstalledMenuKeyboardListener(aInstalling=%s), "
      "sInstalledMenuKeyboardListener=%s",
      GetBoolName(aInstalling), GetBoolName(sInstalledMenuKeyboardListener)));
 
   sInstalledMenuKeyboardListener = aInstalling;
 
   InputContextAction action(InputContextAction::CAUSE_UNKNOWN,
     aInstalling ? InputContextAction::MENU_GOT_PSEUDO_FOCUS :
@@ -464,113 +464,113 @@ IMEStateManager::OnInstalledMenuKeyboard
 }
 
 // static
 bool
 IMEStateManager::OnMouseButtonEventInEditor(nsPresContext* aPresContext,
                                             nsIContent* aContent,
                                             nsIDOMMouseEvent* aMouseEvent)
 {
-  PR_LOG(sISMLog, PR_LOG_ALWAYS,
+  MOZ_LOG(sISMLog, PR_LOG_ALWAYS,
     ("ISM: IMEStateManager::OnMouseButtonEventInEditor(aPresContext=0x%p, "
      "aContent=0x%p, aMouseEvent=0x%p), sPresContext=0x%p, sContent=0x%p",
      aPresContext, aContent, aMouseEvent, sPresContext, sContent));
 
   if (sPresContext != aPresContext || sContent != aContent) {
-    PR_LOG(sISMLog, PR_LOG_DEBUG,
+    MOZ_LOG(sISMLog, PR_LOG_DEBUG,
       ("ISM:   IMEStateManager::OnMouseButtonEventInEditor(), "
        "the mouse event isn't fired on the editor managed by ISM"));
     return false;
   }
 
   if (!sActiveIMEContentObserver) {
-    PR_LOG(sISMLog, PR_LOG_DEBUG,
+    MOZ_LOG(sISMLog, PR_LOG_DEBUG,
       ("ISM:   IMEStateManager::OnMouseButtonEventInEditor(), "
        "there is no active IMEContentObserver"));
     return false;
   }
 
   if (!sActiveIMEContentObserver->IsManaging(aPresContext, aContent)) {
-    PR_LOG(sISMLog, PR_LOG_DEBUG,
+    MOZ_LOG(sISMLog, PR_LOG_DEBUG,
       ("ISM:   IMEStateManager::OnMouseButtonEventInEditor(), "
        "the active IMEContentObserver isn't managing the editor"));
     return false;
   }
 
   WidgetMouseEvent* internalEvent =
     aMouseEvent->GetInternalNSEvent()->AsMouseEvent();
   if (NS_WARN_IF(!internalEvent)) {
-    PR_LOG(sISMLog, PR_LOG_DEBUG,
+    MOZ_LOG(sISMLog, PR_LOG_DEBUG,
       ("ISM:   IMEStateManager::OnMouseButtonEventInEditor(), "
        "the internal event of aMouseEvent isn't WidgetMouseEvent"));
     return false;
   }
 
   bool consumed =
     sActiveIMEContentObserver->OnMouseButtonEvent(aPresContext, internalEvent);
 
   if (PR_LOG_TEST(sISMLog, PR_LOG_ALWAYS)) {
     nsAutoString eventType;
     aMouseEvent->GetType(eventType);
-    PR_LOG(sISMLog, PR_LOG_ALWAYS,
+    MOZ_LOG(sISMLog, PR_LOG_ALWAYS,
       ("ISM:   IMEStateManager::OnMouseButtonEventInEditor(), "
        "mouse event (type=%s, button=%d) is %s",
        NS_ConvertUTF16toUTF8(eventType).get(), internalEvent->button,
        consumed ? "consumed" : "not consumed"));
   }
 
   return consumed;
 }
 
 // static
 void
 IMEStateManager::OnClickInEditor(nsPresContext* aPresContext,
                                  nsIContent* aContent,
                                  nsIDOMMouseEvent* aMouseEvent)
 {
-  PR_LOG(sISMLog, PR_LOG_ALWAYS,
+  MOZ_LOG(sISMLog, PR_LOG_ALWAYS,
     ("ISM: IMEStateManager::OnClickInEditor(aPresContext=0x%p, aContent=0x%p, "
      "aMouseEvent=0x%p), sPresContext=0x%p, sContent=0x%p",
      aPresContext, aContent, aMouseEvent, sPresContext, sContent));
 
   if (sPresContext != aPresContext || sContent != aContent) {
-    PR_LOG(sISMLog, PR_LOG_DEBUG,
+    MOZ_LOG(sISMLog, PR_LOG_DEBUG,
       ("ISM:   IMEStateManager::OnClickInEditor(), "
        "the mouse event isn't fired on the editor managed by ISM"));
     return;
   }
 
   nsCOMPtr<nsIWidget> widget = aPresContext->GetRootWidget();
   NS_ENSURE_TRUE_VOID(widget);
 
   bool isTrusted;
   nsresult rv = aMouseEvent->GetIsTrusted(&isTrusted);
   NS_ENSURE_SUCCESS_VOID(rv);
   if (!isTrusted) {
-    PR_LOG(sISMLog, PR_LOG_DEBUG,
+    MOZ_LOG(sISMLog, PR_LOG_DEBUG,
       ("ISM:   IMEStateManager::OnClickInEditor(), "
        "the mouse event isn't a trusted event"));
     return; // ignore untrusted event.
   }
 
   int16_t button;
   rv = aMouseEvent->GetButton(&button);
   NS_ENSURE_SUCCESS_VOID(rv);
   if (button != 0) {
-    PR_LOG(sISMLog, PR_LOG_DEBUG,
+    MOZ_LOG(sISMLog, PR_LOG_DEBUG,
       ("ISM:   IMEStateManager::OnClickInEditor(), "
        "the mouse event isn't a left mouse button event"));
     return; // not a left click event.
   }
 
   int32_t clickCount;
   rv = aMouseEvent->GetDetail(&clickCount);
   NS_ENSURE_SUCCESS_VOID(rv);
   if (clickCount != 1) {
-    PR_LOG(sISMLog, PR_LOG_DEBUG,
+    MOZ_LOG(sISMLog, PR_LOG_DEBUG,
       ("ISM:   IMEStateManager::OnClickInEditor(), "
        "the mouse event isn't a single click event"));
     return; // should notify only first click event.
   }
 
   InputContextAction action(InputContextAction::CAUSE_MOUSE,
                             InputContextAction::FOCUS_NOT_CHANGED);
   IMEState newState = GetNewIMEState(aPresContext, aContent);
@@ -578,77 +578,77 @@ IMEStateManager::OnClickInEditor(nsPresC
 }
 
 // static
 void
 IMEStateManager::OnFocusInEditor(nsPresContext* aPresContext,
                                  nsIContent* aContent,
                                  nsIEditor* aEditor)
 {
-  PR_LOG(sISMLog, PR_LOG_ALWAYS,
+  MOZ_LOG(sISMLog, PR_LOG_ALWAYS,
     ("ISM: IMEStateManager::OnFocusInEditor(aPresContext=0x%p, aContent=0x%p, "
      "aEditor=0x%p), sPresContext=0x%p, sContent=0x%p, "
      "sActiveIMEContentObserver=0x%p",
      aPresContext, aContent, aEditor, sPresContext, sContent,
      sActiveIMEContentObserver));
 
   if (sPresContext != aPresContext || sContent != aContent) {
-    PR_LOG(sISMLog, PR_LOG_DEBUG,
+    MOZ_LOG(sISMLog, PR_LOG_DEBUG,
       ("ISM:   IMEStateManager::OnFocusInEditor(), "
        "an editor not managed by ISM gets focus"));
     return;
   }
 
   // If the IMEContentObserver instance isn't managing the editor actually,
   // we need to recreate the instance.
   if (sActiveIMEContentObserver) {
     if (sActiveIMEContentObserver->IsManaging(aPresContext, aContent)) {
-      PR_LOG(sISMLog, PR_LOG_DEBUG,
+      MOZ_LOG(sISMLog, PR_LOG_DEBUG,
         ("ISM:   IMEStateManager::OnFocusInEditor(), "
          "the editor is already being managed by sActiveIMEContentObserver"));
       return;
     }
     DestroyIMEContentObserver();
   }
 
   CreateIMEContentObserver(aEditor);
 }
 
 // static
 void
 IMEStateManager::UpdateIMEState(const IMEState& aNewIMEState,
                                 nsIContent* aContent,
                                 nsIEditor* aEditor)
 {
-  PR_LOG(sISMLog, PR_LOG_ALWAYS,
+  MOZ_LOG(sISMLog, PR_LOG_ALWAYS,
     ("ISM: IMEStateManager::UpdateIMEState(aNewIMEState={ mEnabled=%s, "
      "mOpen=%s }, aContent=0x%p, aEditor=0x%p), "
      "sPresContext=0x%p, sContent=0x%p, sActiveIMEContentObserver=0x%p, "
      "sIsGettingNewIMEState=%s",
      GetIMEStateEnabledName(aNewIMEState.mEnabled),
      GetIMEStateSetOpenName(aNewIMEState.mOpen), aContent, aEditor,
      sPresContext, sContent, sActiveIMEContentObserver,
      GetBoolName(sIsGettingNewIMEState)));
 
   if (sIsGettingNewIMEState) {
-    PR_LOG(sISMLog, PR_LOG_DEBUG,
+    MOZ_LOG(sISMLog, PR_LOG_DEBUG,
       ("ISM:   IMEStateManager::UpdateIMEState(), "
        "does nothing because of called while getting new IME state"));
     return;
   }
 
   if (NS_WARN_IF(!sPresContext)) {
-    PR_LOG(sISMLog, PR_LOG_ERROR,
+    MOZ_LOG(sISMLog, PR_LOG_ERROR,
       ("ISM:   IMEStateManager::UpdateIMEState(), FAILED due to "
        "no managing nsPresContext"));
     return;
   }
   nsCOMPtr<nsIWidget> widget = sPresContext->GetRootWidget();
   if (NS_WARN_IF(!widget)) {
-    PR_LOG(sISMLog, PR_LOG_ERROR,
+    MOZ_LOG(sISMLog, PR_LOG_ERROR,
       ("ISM:   IMEStateManager::UpdateIMEState(), FAILED due to "
        "no widget for the managing nsPresContext"));
     return;
   }
 
   // If the IMEContentObserver instance isn't managing the editor's current
   // editable root content, the editor frame might be reframed.  We should
   // recreate the instance at that time.
@@ -679,62 +679,62 @@ IMEStateManager::UpdateIMEState(const IM
   }
 }
 
 // static
 IMEState
 IMEStateManager::GetNewIMEState(nsPresContext* aPresContext,
                                 nsIContent*    aContent)
 {
-  PR_LOG(sISMLog, PR_LOG_ALWAYS,
+  MOZ_LOG(sISMLog, PR_LOG_ALWAYS,
     ("ISM: IMEStateManager::GetNewIMEState(aPresContext=0x%p, aContent=0x%p), "
      "sInstalledMenuKeyboardListener=%s",
      aPresContext, aContent, GetBoolName(sInstalledMenuKeyboardListener)));
 
   // On Printing or Print Preview, we don't need IME.
   if (aPresContext->Type() == nsPresContext::eContext_PrintPreview ||
       aPresContext->Type() == nsPresContext::eContext_Print) {
-    PR_LOG(sISMLog, PR_LOG_DEBUG,
+    MOZ_LOG(sISMLog, PR_LOG_DEBUG,
       ("ISM:   IMEStateManager::GetNewIMEState() returns DISABLED because "
        "the nsPresContext is for print or print preview"));
     return IMEState(IMEState::DISABLED);
   }
 
   if (sInstalledMenuKeyboardListener) {
-    PR_LOG(sISMLog, PR_LOG_DEBUG,
+    MOZ_LOG(sISMLog, PR_LOG_DEBUG,
       ("ISM:   IMEStateManager::GetNewIMEState() returns DISABLED because "
        "menu keyboard listener was installed"));
     return IMEState(IMEState::DISABLED);
   }
 
   if (!aContent) {
     // Even if there are no focused content, the focused document might be
     // editable, such case is design mode.
     nsIDocument* doc = aPresContext->Document();
     if (doc && doc->HasFlag(NODE_IS_EDITABLE)) {
-      PR_LOG(sISMLog, PR_LOG_DEBUG,
+      MOZ_LOG(sISMLog, PR_LOG_DEBUG,
         ("ISM:   IMEStateManager::GetNewIMEState() returns ENABLED because "
          "design mode editor has focus"));
       return IMEState(IMEState::ENABLED);
     }
-    PR_LOG(sISMLog, PR_LOG_DEBUG,
+    MOZ_LOG(sISMLog, PR_LOG_DEBUG,
       ("ISM:   IMEStateManager::GetNewIMEState() returns DISABLED because "
        "no content has focus"));
     return IMEState(IMEState::DISABLED);
   }
 
   // nsIContent::GetDesiredIMEState() may cause a call of UpdateIMEState()
   // from nsEditor::PostCreate() because GetDesiredIMEState() needs to retrieve
   // an editor instance for the element if it's editable element.
   // For avoiding such nested IME state updates, we should set
   // sIsGettingNewIMEState here and UpdateIMEState() should check it.
   GettingNewIMEStateBlocker blocker;
 
   IMEState newIMEState = aContent->GetDesiredIMEState();
-  PR_LOG(sISMLog, PR_LOG_DEBUG,
+  MOZ_LOG(sISMLog, PR_LOG_DEBUG,
     ("ISM:   IMEStateManager::GetNewIMEState() returns { mEnabled=%s, "
      "mOpen=%s }",
      GetIMEStateEnabledName(newIMEState.mEnabled),
      GetIMEStateSetOpenName(newIMEState.mOpen)));
   return newIMEState;
 }
 
 // Helper class, used for IME enabled state change notification
@@ -745,17 +745,17 @@ public:
   {
   }
 
   NS_IMETHOD Run()
   {
     nsCOMPtr<nsIObserverService> observerService =
       services::GetObserverService();
     if (observerService) {
-      PR_LOG(sISMLog, PR_LOG_ALWAYS,
+      MOZ_LOG(sISMLog, PR_LOG_ALWAYS,
         ("ISM: IMEEnabledStateChangedEvent::Run(), notifies observers of "
          "\"ime-enabled-state-changed\""));
       nsAutoString state;
       state.AppendInt(mState);
       observerService->NotifyObservers(nullptr, "ime-enabled-state-changed",
                                        state.get());
     }
     return NS_OK;
@@ -767,17 +767,17 @@ private:
 
 // static
 void
 IMEStateManager::SetIMEState(const IMEState& aState,
                              nsIContent* aContent,
                              nsIWidget* aWidget,
                              InputContextAction aAction)
 {
-  PR_LOG(sISMLog, PR_LOG_ALWAYS,
+  MOZ_LOG(sISMLog, PR_LOG_ALWAYS,
     ("ISM: IMEStateManager::SetIMEState(aState={ mEnabled=%s, mOpen=%s }, "
      "aContent=0x%p, aWidget=0x%p, aAction={ mCause=%s, mFocusChange=%s })",
      GetIMEStateEnabledName(aState.mEnabled),
      GetIMEStateSetOpenName(aState.mOpen), aContent, aWidget,
      GetActionCauseName(aAction.mCause),
      GetActionFocusChangeName(aAction.mFocusChange)));
 
   NS_ENSURE_TRUE_VOID(aWidget);
@@ -853,17 +853,17 @@ IMEStateManager::SetIMEState(const IMESt
   // XXX I think that we should use nsContentUtils::IsCallerChrome() instead
   //     of the process type.
   if (aAction.mCause == InputContextAction::CAUSE_UNKNOWN &&
       XRE_GetProcessType() != GeckoProcessType_Content) {
     aAction.mCause = InputContextAction::CAUSE_UNKNOWN_CHROME;
   }
 
 
-  PR_LOG(sISMLog, PR_LOG_DEBUG,
+  MOZ_LOG(sISMLog, PR_LOG_DEBUG,
     ("ISM:   IMEStateManager::SetIMEState(), "
      "calling nsIWidget::SetInputContext(context={ mIMEState={ mEnabled=%s, "
      "mOpen=%s }, mHTMLInputType=\"%s\", mHTMLInputInputmode=\"%s\", "
      "mActionHint=\"%s\" }, aAction={ mCause=%s, mAction=%s })",
      GetIMEStateEnabledName(context.mIMEState.mEnabled),
      GetIMEStateSetOpenName(context.mIMEState.mOpen),
      NS_ConvertUTF16toUTF8(context.mHTMLInputType).get(),
      NS_ConvertUTF16toUTF8(context.mHTMLInputInputmode).get(),
@@ -895,17 +895,17 @@ void
 IMEStateManager::DispatchCompositionEvent(
                    nsINode* aEventTargetNode,
                    nsPresContext* aPresContext,
                    WidgetCompositionEvent* aCompositionEvent,
                    nsEventStatus* aStatus,
                    EventDispatchingCallback* aCallBack,
                    bool aIsSynthesized)
 {
-  PR_LOG(sISMLog, PR_LOG_ALWAYS,
+  MOZ_LOG(sISMLog, PR_LOG_ALWAYS,
     ("ISM: IMEStateManager::DispatchCompositionEvent(aNode=0x%p, "
      "aPresContext=0x%p, aCompositionEvent={ message=%s, "
      "mFlags={ mIsTrusted=%s, mPropagationStopped=%s } }, "
      "aIsSynthesized=%s)",
      aEventTargetNode, aPresContext,
      GetEventMessageName(aCompositionEvent->message),
      GetBoolName(aCompositionEvent->mFlags.mIsTrusted),
      GetBoolName(aCompositionEvent->mFlags.mPropagationStopped),
@@ -924,17 +924,17 @@ IMEStateManager::DispatchCompositionEven
   nsRefPtr<TextComposition> composition =
     sTextCompositions->GetCompositionFor(aCompositionEvent->widget);
   if (!composition) {
     // If synthesized event comes after delayed native composition events
     // for request of commit or cancel, we should ignore it.
     if (NS_WARN_IF(aIsSynthesized)) {
       return;
     }
-    PR_LOG(sISMLog, PR_LOG_DEBUG,
+    MOZ_LOG(sISMLog, PR_LOG_DEBUG,
       ("ISM:   IMEStateManager::DispatchCompositionEvent(), "
        "adding new TextComposition to the array"));
     MOZ_ASSERT(aCompositionEvent->message == NS_COMPOSITION_START);
     composition =
       new TextComposition(aPresContext, aEventTargetNode, aCompositionEvent);
     sTextCompositions->AppendElement(composition);
   }
 #ifdef DEBUG
@@ -960,17 +960,17 @@ IMEStateManager::DispatchCompositionEven
   //       the last event for the composition.  In this case, we need to
   //       destroy the TextComposition with synthesized compositionend event.
   if ((!aIsSynthesized ||
        composition->WasNativeCompositionEndEventDiscarded()) &&
       aCompositionEvent->CausesDOMCompositionEndEvent()) {
     TextCompositionArray::index_type i =
       sTextCompositions->IndexOf(aCompositionEvent->widget);
     if (i != TextCompositionArray::NoIndex) {
-      PR_LOG(sISMLog, PR_LOG_DEBUG,
+      MOZ_LOG(sISMLog, PR_LOG_DEBUG,
         ("ISM:   IMEStateManager::DispatchCompositionEvent(), "
          "removing TextComposition from the array since NS_COMPOSTION_END "
          "was dispatched"));
       sTextCompositions->ElementAt(i)->Destroy();
       sTextCompositions->RemoveElementAt(i);
     }
   }
 }
@@ -978,17 +978,17 @@ IMEStateManager::DispatchCompositionEven
 // static
 void
 IMEStateManager::OnCompositionEventDiscarded(
                    const WidgetCompositionEvent* aCompositionEvent)
 {
   // Note that this method is never called for synthesized events for emulating
   // commit or cancel composition.
 
-  PR_LOG(sISMLog, PR_LOG_ALWAYS,
+  MOZ_LOG(sISMLog, PR_LOG_ALWAYS,
     ("ISM: IMEStateManager::OnCompositionEventDiscarded(aCompositionEvent={ "
      "message=%s, mFlags={ mIsTrusted=%s } })",
      GetEventMessageName(aCompositionEvent->message),
      GetBoolName(aCompositionEvent->mFlags.mIsTrusted)));
 
   if (!aCompositionEvent->mFlags.mIsTrusted) {
     return;
   }
@@ -1001,17 +1001,17 @@ IMEStateManager::OnCompositionEventDisca
 
   nsRefPtr<TextComposition> composition =
     sTextCompositions->GetCompositionFor(aCompositionEvent->widget);
   if (!composition) {
     // If the PresShell has been being destroyed during composition,
     // a TextComposition instance for the composition was already removed from
     // the array and destroyed in OnDestroyPresContext().  Therefore, we may
     // fail to retrieve a TextComposition instance here.
-    PR_LOG(sISMLog, PR_LOG_ALWAYS,
+    MOZ_LOG(sISMLog, PR_LOG_ALWAYS,
       ("ISM:   IMEStateManager::OnCompositionEventDiscarded(), "
        "TextComposition instance for the widget has already gone"));
     return;
   }
   composition->OnCompositionEventDiscarded(aCompositionEvent);
 }
 
 // static
@@ -1022,24 +1022,24 @@ IMEStateManager::NotifyIME(IMEMessage aM
   nsRefPtr<TextComposition> composition;
   if (aWidget && sTextCompositions) {
     composition = sTextCompositions->GetCompositionFor(aWidget);
   }
 
   bool isSynthesizedForTests =
     composition && composition->IsSynthesizedForTests();
 
-  PR_LOG(sISMLog, PR_LOG_ALWAYS,
+  MOZ_LOG(sISMLog, PR_LOG_ALWAYS,
     ("ISM: IMEStateManager::NotifyIME(aMessage=%s, aWidget=0x%p), "
      "composition=0x%p, composition->IsSynthesizedForTests()=%s",
      GetNotifyIMEMessageName(aMessage), aWidget, composition.get(),
      GetBoolName(isSynthesizedForTests)));
 
   if (NS_WARN_IF(!aWidget)) {
-    PR_LOG(sISMLog, PR_LOG_ERROR,
+    MOZ_LOG(sISMLog, PR_LOG_ERROR,
       ("ISM:   IMEStateManager::NotifyIME(), FAILED due to no widget"));
     return NS_ERROR_INVALID_ARG;
   }
 
   switch (aMessage) {
     case REQUEST_TO_COMMIT_COMPOSITION:
       return composition ?
         composition->RequestToCommit(aWidget, false) : NS_OK;
@@ -1057,25 +1057,25 @@ IMEStateManager::NotifyIME(IMEMessage aM
   return NS_ERROR_FAILURE;
 }
 
 // static
 nsresult
 IMEStateManager::NotifyIME(IMEMessage aMessage,
                            nsPresContext* aPresContext)
 {
-  PR_LOG(sISMLog, PR_LOG_ALWAYS,
+  MOZ_LOG(sISMLog, PR_LOG_ALWAYS,
     ("ISM: IMEStateManager::NotifyIME(aMessage=%s, aPresContext=0x%p)",
      GetNotifyIMEMessageName(aMessage), aPresContext));
 
   NS_ENSURE_TRUE(aPresContext, NS_ERROR_INVALID_ARG);
 
   nsIWidget* widget = aPresContext->GetRootWidget();
   if (NS_WARN_IF(!widget)) {
-    PR_LOG(sISMLog, PR_LOG_ERROR,
+    MOZ_LOG(sISMLog, PR_LOG_ERROR,
       ("ISM:   IMEStateManager::NotifyIME(), FAILED due to no widget for the "
        "nsPresContext"));
     return NS_ERROR_NOT_AVAILABLE;
   }
   return NotifyIME(aMessage, widget);
 }
 
 // static
@@ -1141,78 +1141,78 @@ IMEStateManager::IsEditableIMEState(nsIW
       MOZ_CRASH("Unknown IME enable state");
   }
 }
 
 // static
 void
 IMEStateManager::DestroyIMEContentObserver()
 {
-  PR_LOG(sISMLog, PR_LOG_ALWAYS,
+  MOZ_LOG(sISMLog, PR_LOG_ALWAYS,
     ("ISM: IMEStateManager::DestroyIMEContentObserver(), "
      "sActiveIMEContentObserver=0x%p",
      sActiveIMEContentObserver));
 
   if (!sActiveIMEContentObserver) {
-    PR_LOG(sISMLog, PR_LOG_DEBUG,
+    MOZ_LOG(sISMLog, PR_LOG_DEBUG,
       ("ISM:   IMEStateManager::DestroyIMEContentObserver() does nothing"));
     return;
   }
 
-  PR_LOG(sISMLog, PR_LOG_DEBUG,
+  MOZ_LOG(sISMLog, PR_LOG_DEBUG,
     ("ISM:   IMEStateManager::DestroyIMEContentObserver(), destroying "
      "the active IMEContentObserver..."));
   nsRefPtr<IMEContentObserver> tsm;
   tsm.swap(sActiveIMEContentObserver);
   tsm->Destroy();
 }
 
 // static
 void
 IMEStateManager::CreateIMEContentObserver(nsIEditor* aEditor)
 {
-  PR_LOG(sISMLog, PR_LOG_ALWAYS,
+  MOZ_LOG(sISMLog, PR_LOG_ALWAYS,
     ("ISM: IMEStateManager::CreateIMEContentObserver(aEditor=0x%p), "
      "sPresContext=0x%p, sContent=0x%p, sActiveIMEContentObserver=0x%p, "
      "sActiveIMEContentObserver->IsManaging(sPresContext, sContent)=%s",
      aEditor, sPresContext, sContent, sActiveIMEContentObserver,
      GetBoolName(sActiveIMEContentObserver ?
        sActiveIMEContentObserver->IsManaging(sPresContext, sContent) : false)));
 
   if (NS_WARN_IF(sActiveIMEContentObserver)) {
-    PR_LOG(sISMLog, PR_LOG_ERROR,
+    MOZ_LOG(sISMLog, PR_LOG_ERROR,
       ("ISM:   IMEStateManager::CreateIMEContentObserver(), FAILED due to "
        "there is already an active IMEContentObserver"));
     MOZ_ASSERT(sActiveIMEContentObserver->IsManaging(sPresContext, sContent));
     return;
   }
 
   nsCOMPtr<nsIWidget> widget = sPresContext->GetRootWidget();
   if (!widget) {
-    PR_LOG(sISMLog, PR_LOG_ERROR,
+    MOZ_LOG(sISMLog, PR_LOG_ERROR,
       ("ISM:   IMEStateManager::CreateIMEContentObserver(), FAILED due to "
        "there is a root widget for the nsPresContext"));
     return; // Sometimes, there are no widgets.
   }
 
   // If it's not text ediable, we don't need to create IMEContentObserver.
   if (!IsEditableIMEState(widget)) {
-    PR_LOG(sISMLog, PR_LOG_DEBUG,
+    MOZ_LOG(sISMLog, PR_LOG_DEBUG,
       ("ISM:   IMEStateManager::CreateIMEContentObserver() doesn't create "
        "IMEContentObserver because of non-editable IME state"));
     return;
   }
 
   static bool sInitializeIsTestingIME = true;
   if (sInitializeIsTestingIME) {
     Preferences::AddBoolVarCache(&sIsTestingIME, "test.IME", false);
     sInitializeIsTestingIME = false;
   }
 
-  PR_LOG(sISMLog, PR_LOG_DEBUG,
+  MOZ_LOG(sISMLog, PR_LOG_DEBUG,
     ("ISM:   IMEStateManager::CreateIMEContentObserver() is creating an "
      "IMEContentObserver instance..."));
   sActiveIMEContentObserver = new IMEContentObserver();
   NS_ADDREF(sActiveIMEContentObserver);
 
   // IMEContentObserver::Init() might create another IMEContentObserver
   // instance.  So, sActiveIMEContentObserver would be replaced with new one.
   // We should hold the current instance here.
--- a/dom/html/HTMLLinkElement.cpp
+++ b/dom/html/HTMLLinkElement.cpp
@@ -16,17 +16,16 @@
 #include "nsContentUtils.h"
 #include "nsGenericHTMLElement.h"
 #include "nsGkAtoms.h"
 #include "nsDOMTokenList.h"
 #include "nsIDocument.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMStyleSheet.h"
 #include "nsINode.h"
-#include "nsISpeculativeConnect.h"
 #include "nsIStyleSheet.h"
 #include "nsIStyleSheetLinkingElement.h"
 #include "nsIURL.h"
 #include "nsNetUtil.h"
 #include "nsPIDOMWindow.h"
 #include "nsReadableUtils.h"
 #include "nsStyleConsts.h"
 #include "nsUnicharUtils.h"
@@ -177,16 +176,18 @@ HTMLLinkElement::LinkRemoved()
 
 void
 HTMLLinkElement::UnbindFromTree(bool aDeep, bool aNullParent)
 {
   // If this link is ever reinserted into a document, it might
   // be under a different xml:base, so forget the cached state now.
   Link::ResetLinkState(false, Link::ElementHasHref());
 
+  // If this is reinserted back into the document it will not be
+  // from the parser.
   nsCOMPtr<nsIDocument> oldDoc = GetUncomposedDoc();
 
   // Check for a ShadowRoot because link elements are inert in a
   // ShadowRoot.
   ShadowRoot* oldShadowRoot = GetBindingParent() ?
     GetBindingParent()->GetShadowRoot() : nullptr;
 
   OwnerDoc()->UnregisterPendingLinkUpdate(this);
@@ -306,22 +307,21 @@ HTMLLinkElement::UpdatePreconnect()
     return;
   }
 
   uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(rel, NodePrincipal());
   if (!(linkTypes & ePRECONNECT)) {
     return;
   }
 
-  nsCOMPtr<nsISpeculativeConnect>
-    speculator(do_QueryInterface(nsContentUtils::GetIOService()));
-  if (speculator) {
+  nsIDocument *owner = OwnerDoc();
+  if (owner) {
     nsCOMPtr<nsIURI> uri = GetHrefURI();
     if (uri) {
-      speculator->SpeculativeConnect(uri, nullptr);
+      owner->MaybePreconnect(uri);
     }
   }
 }
 
 nsresult
 HTMLLinkElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                          nsIAtom* aPrefix, const nsAString& aValue,
                          bool aNotify)
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -89,18 +89,18 @@
 #include "mozilla/Telemetry.h"
 
 #include "ImageContainer.h"
 #include "nsRange.h"
 #include <algorithm>
 
 static PRLogModuleInfo* gMediaElementLog;
 static PRLogModuleInfo* gMediaElementEventsLog;
-#define LOG(type, msg) PR_LOG(gMediaElementLog, type, msg)
-#define LOG_EVENT(type, msg) PR_LOG(gMediaElementEventsLog, type, msg)
+#define LOG(type, msg) MOZ_LOG(gMediaElementLog, type, msg)
+#define LOG_EVENT(type, msg) MOZ_LOG(gMediaElementEventsLog, type, msg)
 
 #include "nsIContentSecurityPolicy.h"
 
 #include "mozilla/Preferences.h"
 #include "mozilla/FloatingPoint.h"
 
 #include "nsIPermissionManager.h"
 #include "nsContentTypeParser.h"
--- a/dom/html/HTMLTrackElement.cpp
+++ b/dom/html/HTMLTrackElement.cpp
@@ -36,17 +36,17 @@
 #include "nsMappedAttributes.h"
 #include "nsNetUtil.h"
 #include "nsRuleData.h"
 #include "nsStyleConsts.h"
 #include "nsThreadUtils.h"
 #include "nsVideoFrame.h"
 
 static PRLogModuleInfo* gTrackElementLog;
-#define LOG(type, msg) PR_LOG(gTrackElementLog, type, msg)
+#define LOG(type, msg) MOZ_LOG(gTrackElementLog, type, msg)
 
 // Replace the usual NS_IMPL_NS_NEW_HTML_ELEMENT(Track) so
 // we can return an UnknownElement instead when pref'd off.
 nsGenericHTMLElement*
 NS_NewHTMLTrackElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                        mozilla::dom::FromParser aFromParser)
 {
   if (!mozilla::dom::HTMLTrackElement::IsWebVTTEnabled()) {
--- a/dom/imptests/editing/selecttest/test_collapse.html
+++ b/dom/imptests/editing/selecttest/test_collapse.html
@@ -3,17 +3,17 @@
 <div id=log></div>
 <script src=/resources/testharness.js></script>
 <script src=/resources/testharnessreport.js></script>
 <script src=common.js></script>
 <script>
 "use strict";
 
 if (W3CTest.runner) {
-  W3CTest.runner.requestLongerTimeout(2);
+  W3CTest.runner.requestLongerTimeout(5);
 }
 
 function testCollapse(range, point) {
 	selection.removeAllRanges();
 	var addedRange;
 	if (range) {
 		addedRange = range.cloneRange();
 		selection.addRange(addedRange);
--- a/dom/indexedDB/ActorsParent.cpp
+++ b/dom/indexedDB/ActorsParent.cpp
@@ -87,30 +87,26 @@
 #include "nsString.h"
 #include "nsThreadUtils.h"
 #include "nsXPCOMCID.h"
 #include "PermissionRequestBase.h"
 #include "ProfilerHelpers.h"
 #include "ReportInternalError.h"
 #include "snappy/snappy.h"
 
-#ifdef MOZ_NUWA_PROCESS
-#include "nsThread.h"
-#endif
-
 #define DISABLE_ASSERTS_FOR_FUZZING 0
 
 #if DISABLE_ASSERTS_FOR_FUZZING
 #define ASSERT_UNLESS_FUZZING(...) do { } while (0)
 #else
 #define ASSERT_UNLESS_FUZZING(...) MOZ_ASSERT(false, __VA_ARGS__)
 #endif
 
 #define IDB_DEBUG_LOG(_args)                                                   \
-  PR_LOG(IndexedDatabaseManager::GetLoggingModule(),                           \
+  MOZ_LOG(IndexedDatabaseManager::GetLoggingModule(),                           \
          PR_LOG_DEBUG,                                                         \
          _args )
 
 #if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
 #define IDB_MOBILE
 #endif
 
 namespace mozilla {
@@ -4817,37 +4813,23 @@ private:
 
   NS_DECL_NSIRUNNABLE
 };
 
 struct ConnectionPool::ThreadInfo
 {
   nsCOMPtr<nsIThread> mThread;
   nsRefPtr<ThreadRunnable> mRunnable;
-#ifdef MOZ_NUWA_PROCESS
-  bool mNuwaWorking;
-#endif
 
   ThreadInfo();
 
   explicit
   ThreadInfo(const ThreadInfo& aOther);
 
   ~ThreadInfo();
-
-  void
-  NuwaSetWorking(bool aWorking)
-#ifdef MOZ_NUWA_PROCESS
-    ;
-#else
-  {
-    AssertIsOnBackgroundThread();
-    MOZ_ASSERT(mThread);
-  }
-#endif
 };
 
 struct ConnectionPool::DatabaseInfo final
 {
   friend class nsAutoPtr<DatabaseInfo>;
 
   nsRefPtr<ConnectionPool> mConnectionPool;
   const nsCString mDatabaseId;
@@ -9960,18 +9942,16 @@ ConnectionPool::CancelIdleTimer()
 void
 ConnectionPool::ShutdownThread(ThreadInfo& aThreadInfo)
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aThreadInfo.mThread);
   MOZ_ASSERT(aThreadInfo.mRunnable);
   MOZ_ASSERT(mTotalThreadCount);
 
-  aThreadInfo.NuwaSetWorking(/* aWorking */ false);
-
   nsRefPtr<ThreadRunnable> runnable;
   aThreadInfo.mRunnable.swap(runnable);
 
   nsCOMPtr<nsIThread> thread;
   aThreadInfo.mThread.swap(thread);
 
   IDB_DEBUG_LOG(("ConnectionPool shutting down thread %lu",
                  runnable->SerialNumber()));
@@ -10090,18 +10070,16 @@ ConnectionPool::ScheduleTransaction(Tran
 
       dbInfo->mThreadInfo.mRunnable.swap(threadInfo.mRunnable);
       dbInfo->mThreadInfo.mThread.swap(threadInfo.mThread);
 
       mIdleThreads.RemoveElementAt(lastIndex);
 
       AdjustIdleTimer();
     }
-
-    dbInfo->mThreadInfo.NuwaSetWorking(/* aWorking */ true);
   }
 
   MOZ_ASSERT(dbInfo->mThreadInfo.mThread);
   MOZ_ASSERT(dbInfo->mThreadInfo.mRunnable);
 
   if (aTransactionInfo->mIsWriteTransaction) {
     if (dbInfo->mRunningWriteTransaction) {
       // SQLite only allows one write transaction at a time so queue this
@@ -10311,18 +10289,16 @@ ConnectionPool::NoteIdleDatabase(Databas
       // thread down immediately instead of going through the idle thread
       // mechanism.
       ShutdownThread(aDatabaseInfo->mThreadInfo);
     }
 
     return;
   }
 
-  aDatabaseInfo->mThreadInfo.NuwaSetWorking(/* aWorking */ false);
-
   mIdleDatabases.InsertElementSorted(aDatabaseInfo);
 
   AdjustIdleTimer();
 }
 
 void
 ConnectionPool::NoteClosedDatabase(DatabaseInfo* aDatabaseInfo)
 {
@@ -10356,18 +10332,16 @@ ConnectionPool::NoteClosedDatabase(Datab
       // Give the thread to another database.
       ScheduleQueuedTransactions(aDatabaseInfo->mThreadInfo);
     } else if (!aDatabaseInfo->TotalTransactionCount()) {
       if (mShutdownRequested) {
         ShutdownThread(aDatabaseInfo->mThreadInfo);
       } else {
         MOZ_ASSERT(!mIdleThreads.Contains(aDatabaseInfo->mThreadInfo));
 
-        aDatabaseInfo->mThreadInfo.NuwaSetWorking(/* aWorking */ false);
-
         mIdleThreads.InsertElementSorted(aDatabaseInfo->mThreadInfo);
 
         aDatabaseInfo->mThreadInfo.mRunnable = nullptr;
         aDatabaseInfo->mThreadInfo.mThread = nullptr;
 
         if (mIdleThreads.Length() > kMaxIdleConnectionThreadCount) {
           ShutdownThread(mIdleThreads[0].mThreadInfo);
           mIdleThreads.RemoveElementAt(0);
@@ -10490,18 +10464,16 @@ ConnectionPool::CloseDatabase(DatabaseIn
   MOZ_ASSERT(aDatabaseInfo->mThreadInfo.mRunnable);
   MOZ_ASSERT(!aDatabaseInfo->mClosing);
 
   aDatabaseInfo->mNeedsCheckpoint = false;
   aDatabaseInfo->mClosing = true;
 
   nsCOMPtr<nsIRunnable> runnable = new CloseConnectionRunnable(aDatabaseInfo);
 
-  aDatabaseInfo->mThreadInfo.NuwaSetWorking(/* aWorking */ true);
-
   MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
     aDatabaseInfo->mThreadInfo.mThread->Dispatch(runnable,
                                                  NS_DISPATCH_NORMAL)));
 }
 
 bool
 ConnectionPool::CloseDatabaseWhenIdleInternal(const nsACString& aDatabaseId)
 {
@@ -10840,91 +10812,42 @@ ThreadRunnable::Run()
   profiler_unregister_thread();
 #endif // MOZ_ENABLE_PROFILER_SPS
 
   return NS_OK;
 }
 
 ConnectionPool::
 ThreadInfo::ThreadInfo()
-#ifdef MOZ_NUWA_PROCESS
-  : mNuwaWorking(false)
-#endif
 {
   AssertIsOnBackgroundThread();
 
   MOZ_COUNT_CTOR(ConnectionPool::ThreadInfo);
 }
 
 ConnectionPool::
 ThreadInfo::ThreadInfo(const ThreadInfo& aOther)
   : mThread(aOther.mThread)
   , mRunnable(aOther.mRunnable)
-#ifdef MOZ_NUWA_PROCESS
-  , mNuwaWorking(false)
-#endif
 {
   AssertIsOnBackgroundThread();
   MOZ_ASSERT(aOther.mThread);
   MOZ_ASSERT(aOther.mRunnable);
 
   MOZ_COUNT_CTOR(ConnectionPool::ThreadInfo);
 }
 
 ConnectionPool::
 ThreadInfo::~ThreadInfo()
 {
   AssertIsOnBackgroundThread();
 
-#ifdef MOZ_NUWA_PROCESS
-  MOZ_ASSERT(!mNuwaWorking);
-#endif
-
   MOZ_COUNT_DTOR(ConnectionPool::ThreadInfo);
 }
 
-#ifdef MOZ_NUWA_PROCESS
-
-void
-ConnectionPool::
-ThreadInfo::NuwaSetWorking(bool aWorking)
-{
-  AssertIsOnBackgroundThread();
-  MOZ_ASSERT(mThread);
-
-  if (mNuwaWorking == aWorking) {
-    return;
-  }
-
-  nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction(
-    [aWorking]
-    {
-      MOZ_ASSERT(!IsOnBackgroundThread());
-      MOZ_ASSERT(!NS_IsMainThread());
-
-      auto* thread = static_cast<nsThread*>(NS_GetCurrentThread());
-      MOZ_ASSERT(thread);
-
-      if (aWorking) {
-        thread->SetWorking();
-      } else {
-        thread->SetIdle();
-      }
-    }
-  );
-  MOZ_ASSERT(runnable);
-
-  MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
-    mThread->Dispatch(runnable, NS_DISPATCH_NORMAL)));
-
-  mNuwaWorking = aWorking;
-}
-
-#endif // MOZ_NUWA_PROCESS
-
 ConnectionPool::
 IdleResource::IdleResource(const TimeStamp& aIdleTime)
   : mIdleTime(aIdleTime)
 {
   AssertIsOnBackgroundThread();
   MOZ_ASSERT(!aIdleTime.IsNull());
 
   MOZ_COUNT_CTOR(ConnectionPool::IdleResource);
--- a/dom/indexedDB/ProfilerHelpers.h
+++ b/dom/indexedDB/ProfilerHelpers.h
@@ -292,17 +292,17 @@ LoggingHelper(bool aUseProfiler, const c
       va_list args;
       va_start(args, aFmt);
 
       message.AppendPrintf(aFmt, args);
 
       va_end(args);
     }
 
-    PR_LOG(logModule, logLevel, ("%s", message.get()));
+    MOZ_LOG(logModule, logLevel, ("%s", message.get()));
 
     if (aUseProfiler) {
       PROFILER_MARKER(message.get());
     }
   }
 }
 
 } // namespace indexedDB
--- a/dom/interfaces/security/nsIContentSecurityPolicy.idl
+++ b/dom/interfaces/security/nsIContentSecurityPolicy.idl
@@ -15,17 +15,17 @@ interface nsIURI;
  * nsIContentSecurityPolicy
  * Describes an XPCOM component used to model and enforce CSPs.  Instances of
  * this class may have multiple policies within them, but there should only be
  * one of these per document/principal.
  */
 
 typedef unsigned short CSPDirective;
 
-[scriptable, uuid(68434447-b816-4473-a731-efc4f6d59902)]
+[scriptable, uuid(459fe61a-203e-4460-9ced-352a9bd3aa71)]
 interface nsIContentSecurityPolicy : nsISerializable
 {
   /**
    * Directives supported by Content Security Policy.  These are enums for
    * the CSPDirective type.
    * The NO_DIRECTIVE entry is  used for checking default permissions and
    * returning failure when asking CSP which directive to check.
    *
@@ -277,9 +277,14 @@ interface nsIContentSecurityPolicy : nsI
                    in ACString        aMimeTypeGuess,
                    in nsISupports     aExtra);
 
 %{ C++
 // nsIObserver topic to fire when the policy encounters a violation.
 #define CSP_VIOLATION_TOPIC "csp-on-violate-policy"
 %}
 
+  /**
+   * Returns the CSP in JSON notation.
+   */
+  AString toJSON();
+
 };
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -533,33 +533,26 @@ private:
         MOZ_CRASH("Failed to create a PBackgroundChild actor!");
     }
 };
 
 NS_IMPL_ISUPPORTS(BackgroundChildPrimer, nsIIPCBackgroundChildCreateCallback)
 
 ContentChild* ContentChild::sSingleton;
 
-static void
-PostForkPreload()
-{
-    TabChild::PostForkPreload();
-}
-
 // Performs initialization that is not fork-safe, i.e. that must be done after
 // forking from the Nuwa process.
 static void
 InitOnContentProcessCreated()
 {
 #ifdef MOZ_NUWA_PROCESS
     // Wait until we are forked from Nuwa
     if (IsNuwaProcess()) {
         return;
     }
-    PostForkPreload();
 
     nsCOMPtr<nsIPermissionManager> permManager =
         services::GetPermissionManager();
     MOZ_ASSERT(permManager, "Unable to get permission manager");
     nsresult rv = permManager->RefreshPermission();
     if (NS_FAILED(rv)) {
         MOZ_ASSERT(false, "Failed updating permission in child process");
     }
@@ -1351,16 +1344,17 @@ ContentChild::RecvPBrowserConstructor(PB
                                       const IPCTabContext& aContext,
                                       const uint32_t& aChromeFlags,
                                       const ContentParentId& aCpID,
                                       const bool& aIsForApp,
                                       const bool& aIsForBrowser)
 {
     // This runs after AllocPBrowserChild() returns and the IPC machinery for this
     // PBrowserChild has been set up.
+
     nsCOMPtr<nsIObserverService> os = services::GetObserverService();
     if (os) {
         nsITabChild* tc =
             static_cast<nsITabChild*>(static_cast<TabChild*>(aActor));
         os->NotifyObservers(tc, "tab-child-created", nullptr);
     }
 
     static bool hasRunOnce = false;
@@ -2196,21 +2190,18 @@ ContentChild::RecvScreenSizeChanged(cons
 #endif
     return true;
 }
 
 bool
 ContentChild::RecvFlushMemory(const nsString& reason)
 {
 #ifdef MOZ_NUWA_PROCESS
-    if (IsNuwaProcess() || ManagedPBrowserChild().Length() == 0) {
+    if (IsNuwaProcess()) {
         // Don't flush memory in the nuwa process: the GC thread could be frozen.
-        // If there's no PBrowser child, don't flush memory, either. GC writes
-        // to copy-on-write pages and makes preallocated process take more memory
-        // before it actually becomes an app.
         return true;
     }
 #endif
     nsCOMPtr<nsIObserverService> os =
         mozilla::services::GetObserverService();
     if (os)
         os->NotifyObservers(nullptr, "memory-pressure", reason.get());
     return true;
@@ -2294,45 +2285,30 @@ ContentChild::RecvAppInit()
 
     // If we're part of the mozbrowser machinery, go ahead and start
     // preloading things.  We can only do this for mozbrowser because
     // PreloadSlowThings() may set the docshell of the first TabChild
     // inactive, and we can only safely restore it to active from
     // BrowserElementChild.js.
     if ((mIsForApp || mIsForBrowser)
 #ifdef MOZ_NUWA_PROCESS
-        && IsNuwaProcess()
+        && !IsNuwaProcess()
 #endif
        ) {
         PreloadSlowThings();
-#ifndef MOZ_NUWA_PROCESS
-        PostForkPreload();
-#endif
     }
 
 #ifdef MOZ_NUWA_PROCESS
-    // Some modules are initialized in preloading. We need to wait until the
-    // tasks they dispatched to chrome process are done.
-    if (IsNuwaProcess()) {
-        SendNuwaWaitForFreeze();
-    }
-#endif
-    return true;
-}
-
-bool
-ContentChild::RecvNuwaFreeze()
-{
-#ifdef MOZ_NUWA_PROCESS
     if (IsNuwaProcess()) {
         ContentChild::GetSingleton()->RecvGarbageCollect();
         MessageLoop::current()->PostTask(
             FROM_HERE, NewRunnableFunction(OnFinishNuwaPreparation));
     }
 #endif
+
     return true;
 }
 
 bool
 ContentChild::RecvLastPrivateDocShellDestroyed()
 {
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     obs->NotifyObservers(nullptr, "last-pb-context-exited", nullptr);
@@ -2599,60 +2575,43 @@ DoNuwaFork()
  */
 static void
 RunNuwaFork()
 {
     if (NuwaCheckpointCurrentThread()) {
       DoNuwaFork();
     }
 }
-
-class NuwaForkCaller: public nsRunnable
-{
-public:
-    NS_IMETHODIMP
-    Run() {
-        // We want to ensure that the PBackground actor gets cloned in the Nuwa
-        // process before we freeze. Also, we have to do this to avoid deadlock.
-        // Protocols that are "opened" (e.g. PBackground, PCompositor) block the
-        // main thread to wait for the IPC thread during the open operation.
-        // NuwaSpawnWait() blocks the IPC thread to wait for the main thread when
-        // the Nuwa process is forked. Unless we ensure that the two cannot happen
-        // at the same time then we risk deadlock. Spinning the event loop here
-        // guarantees the ordering is safe for PBackground.
-        if (!BackgroundChild::GetForCurrentThread()) {
-            // Dispatch ourself again.
-            NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL);
-        } else {
-            MessageLoop* ioloop = XRE_GetIOMessageLoop();
-            ioloop->PostTask(FROM_HERE, NewRunnableFunction(RunNuwaFork));
-        }
-        return NS_OK;
-    }
-private:
-    virtual
-    ~NuwaForkCaller()
-    {
-    }
-};
-
 #endif
 
 bool
 ContentChild::RecvNuwaFork()
 {
 #ifdef MOZ_NUWA_PROCESS
     if (sNuwaForking) {           // No reentry.
         return true;
     }
     sNuwaForking = true;
 
-    nsRefPtr<NuwaForkCaller> runnable = new NuwaForkCaller();
-    NS_DispatchToMainThread(runnable, NS_DISPATCH_NORMAL);
-
+    // We want to ensure that the PBackground actor gets cloned in the Nuwa
+    // process before we freeze. Also, we have to do this to avoid deadlock.
+    // Protocols that are "opened" (e.g. PBackground, PCompositor) block the
+    // main thread to wait for the IPC thread during the open operation.
+    // NuwaSpawnWait() blocks the IPC thread to wait for the main thread when
+    // the Nuwa process is forked. Unless we ensure that the two cannot happen
+    // at the same time then we risk deadlock. Spinning the event loop here
+    // guarantees the ordering is safe for PBackground.
+    while (!BackgroundChild::GetForCurrentThread()) {
+        if (NS_WARN_IF(!NS_ProcessNextEvent())) {
+            return false;
+        }
+    }
+
+    MessageLoop* ioloop = XRE_GetIOMessageLoop();
+    ioloop->PostTask(FROM_HERE, NewRunnableFunction(RunNuwaFork));
     return true;
 #else
     return false; // Makes the underlying IPC channel abort.
 #endif
 }
 
 bool
 ContentChild::RecvOnAppThemeChanged()
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -374,18 +374,16 @@ public:
     virtual bool RecvMinimizeMemoryUsage() override;
 
     virtual bool RecvLoadAndRegisterSheet(const URIParams& aURI,
                                           const uint32_t& aType) override;
     virtual bool RecvUnregisterSheet(const URIParams& aURI, const uint32_t& aType) override;
 
     virtual bool RecvNotifyPhoneStateChange(const nsString& state) override;
 
-    virtual bool RecvNuwaFreeze() override;
-
     void AddIdleObserver(nsIObserver* aObserver, uint32_t aIdleTimeInS);
     void RemoveIdleObserver(nsIObserver* aObserver, uint32_t aIdleTimeInS);
     virtual bool RecvNotifyIdleObserver(const uint64_t& aObserver,
                                         const nsCString& aTopic,
                                         const nsString& aData) override;
 
     virtual bool RecvOnAppThemeChanged() override;
 
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -135,17 +135,16 @@
 #include "nsIXULRuntime.h"
 #include "gfxDrawable.h"
 #include "ImageOps.h"
 #include "nsMemoryInfoDumper.h"
 #include "nsMemoryReporterManager.h"
 #include "nsServiceManagerUtils.h"
 #include "nsStyleSheetService.h"
 #include "nsThreadUtils.h"
-#include "nsThreadManager.h"
 #include "nsToolkitCompsCID.h"
 #include "nsWidgetsCID.h"
 #include "PreallocatedProcessManager.h"
 #include "ProcessPriorityManager.h"
 #include "SandboxHal.h"
 #include "ScreenManagerParent.h"
 #include "SourceSurfaceRawData.h"
 #include "StructuredCloneUtils.h"
@@ -1558,38 +1557,16 @@ private:
 };
 
 StaticAutoPtr<LinkedList<SystemMessageHandledListener> >
     SystemMessageHandledListener::sListeners;
 
 NS_IMPL_ISUPPORTS(SystemMessageHandledListener,
                   nsITimerCallback)
 
-#ifdef MOZ_NUWA_PROCESS
-class NuwaFreezeListener : public nsThreadManager::AllThreadsWereIdleListener
-{
-public:
-    NuwaFreezeListener(ContentParent* parent)
-        : mParent(parent)
-    {
-    }
-
-    void OnAllThreadsWereIdle()
-    {
-        unused << mParent->SendNuwaFreeze();
-        nsThreadManager::get()->RemoveAllThreadsWereIdleListener(this);
-    }
-private:
-    nsRefPtr<ContentParent> mParent;
-    virtual ~NuwaFreezeListener()
-    {
-    }
-};
-#endif // MOZ_NUWA_PROCESS
-
 } // anonymous namespace
 
 void
 ContentParent::MaybeTakeCPUWakeLock(Element* aFrameElement)
 {
     // Take the CPU wake lock on behalf of this processs if it's expecting a
     // system message.  We'll release the CPU lock once the message is
     // delivered, or after some period of time, which ever comes first.
@@ -2357,18 +2334,16 @@ ContentParent::ContentParent(ContentPare
     // memory priority, which it has inherited from this process.
     ProcessPriority priority;
     if (IsPreallocated()) {
         priority = PROCESS_PRIORITY_PREALLOC;
     } else {
         priority = PROCESS_PRIORITY_FOREGROUND;
     }
 
-    mSendPermissionUpdates = aTemplate->mSendPermissionUpdates;
-
     InitInternal(priority,
                  false, /* Setup Off-main thread compositing */
                  false  /* Send registered chrome */);
 
     ContentProcessManager::GetSingleton()->AddContentProcess(this);
 }
 #endif  // MOZ_NUWA_PROCESS
 
@@ -2522,17 +2497,17 @@ ContentParent::IsAlive()
 bool
 ContentParent::IsForApp()
 {
     return !mAppManifestURL.IsEmpty();
 }
 
 #ifdef MOZ_NUWA_PROCESS
 bool
-ContentParent::IsNuwaProcess() const
+ContentParent::IsNuwaProcess()
 {
     return mIsNuwaProcess;
 }
 #endif
 
 int32_t
 ContentParent::Pid()
 {
@@ -2898,29 +2873,16 @@ ContentParent::RecvNuwaReady()
     return true;
 #else
     NS_ERROR("ContentParent::RecvNuwaReady() not implemented!");
     return false;
 #endif
 }
 
 bool
-ContentParent::RecvNuwaWaitForFreeze()
-{
-#ifdef MOZ_NUWA_PROCESS
-    nsRefPtr<NuwaFreezeListener> listener = new NuwaFreezeListener(this);
-    nsThreadManager::get()->AddAllThreadsWereIdleListener(listener);
-    return true;
-#else // MOZ_NUWA_PROCESS
-    NS_ERROR("ContentParent::RecvNuwaWaitForFreeze() not implemented!");
-    return false;
-#endif // MOZ_NUWA_PROCESS
-}
-
-bool
 ContentParent::RecvAddNewProcess(const uint32_t& aPid,
                                  InfallibleTArray<ProtocolFdMapping>&& aFds)
 {
 #ifdef MOZ_NUWA_PROCESS
     if (!IsNuwaProcess()) {
         NS_ERROR(
             nsPrintfCString(
                 "Terminating child process %d for unauthorized IPC message: "
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -228,35 +228,31 @@ public:
 
     bool IsAlive();
     virtual bool IsForApp() override;
     virtual bool IsForBrowser() override
     {
       return mIsForBrowser;
     }
 #ifdef MOZ_NUWA_PROCESS
-    bool IsNuwaProcess() const;
+    bool IsNuwaProcess();
 #endif
 
     GeckoChildProcessHost* Process() {
         return mSubprocess;
     }
 
     int32_t Pid();
 
     ContentParent* Opener() {
         return mOpener;
     }
 
     bool NeedsPermissionsUpdate() const {
-#ifdef MOZ_NUWA_PROCESS
-        return !IsNuwaProcess() && mSendPermissionUpdates;
-#else
         return mSendPermissionUpdates;
-#endif
     }
 
     bool NeedsDataStoreInfos() const {
         return mSendDataStoreInfos;
     }
 
     /**
      * Kill our subprocess and make sure it dies.  Should only be used
@@ -778,18 +774,16 @@ private:
     virtual bool RecvSpeakerManagerGetSpeakerStatus(bool* aValue) override;
 
     virtual bool RecvSpeakerManagerForceSpeaker(const bool& aEnable) override;
 
     virtual bool RecvSystemMessageHandled() override;
 
     virtual bool RecvNuwaReady() override;
 
-    virtual bool RecvNuwaWaitForFreeze() override;
-
     virtual bool RecvAddNewProcess(const uint32_t& aPid,
                                    InfallibleTArray<ProtocolFdMapping>&& aFds) override;
 
     virtual bool RecvCreateFakeVolume(const nsString& fsName, const nsString& mountPoint) override;
 
     virtual bool RecvSetFakeVolumeState(const nsString& fsName, const int32_t& fsState) override;
 
     virtual bool RecvRemoveFakeVolume(const nsString& fsName) override;
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -627,17 +627,16 @@ child:
                         nsCString[] aThreadNameFilters);
     async StopProfiler();
     prio(high) sync GetProfile()
       returns (nsCString aProfile);
 
     InvokeDragSession(IPCDataTransfer[] transfers, uint32_t action);
 
     EndDragSession(bool aDoneDrag, bool aUserCancelled);
-    NuwaFreeze();
 
     async DomainSetChanged(uint32_t aSetType, uint32_t aChangeType, OptionalURIParams aDomain);
 
     /**
      * Notify the child to shutdown. The child will in turn call FinishShutdown
      * and let the parent close the channel.
      */
     async Shutdown();
@@ -894,19 +893,16 @@ parent:
                                nsString aStorageName,
                                nsString aFilepath,
                                nsCString aReason);
 
     // Notify the parent that the child has finished handling a system message.
     async SystemMessageHandled();
 
     NuwaReady();
-    // Sent when nuwa finished its initialization process and is waiting for
-    // parent's signal to make it freeze.
-    NuwaWaitForFreeze();
 
     sync AddNewProcess(uint32_t pid, ProtocolFdMapping[] aFds);
 
     // called by the child (test code only) to propagate volume changes to the parent
     async CreateFakeVolume(nsString fsName, nsString mountPoint);
     async SetFakeVolumeState(nsString fsName, int32_t fsState);
     async RemoveFakeVolume(nsString fsName);
 
--- a/dom/ipc/ProcessPriorityManager.cpp
+++ b/dom/ipc/ProcessPriorityManager.cpp
@@ -72,20 +72,20 @@
   GetPPMLog()
   {
     static PRLogModuleInfo *sLog;
     if (!sLog)
       sLog = PR_NewLogModule("ProcessPriorityManager");
     return sLog;
   }
 #  define LOG(fmt, ...) \
-     PR_LOG(GetPPMLog(), PR_LOG_DEBUG, \
+     MOZ_LOG(GetPPMLog(), PR_LOG_DEBUG, \
             ("ProcessPriorityManager - " fmt, ##__VA_ARGS__))
 #  define LOGP(fmt, ...) \
-     PR_LOG(GetPPMLog(), PR_LOG_DEBUG, \
+     MOZ_LOG(GetPPMLog(), PR_LOG_DEBUG, \
             ("ProcessPriorityManager[%schild-id=%" PRIu64 ", pid=%d] - " fmt, \
             NameWithComma().get(), \
             static_cast<uint64_t>(ChildID()), Pid(), ##__VA_ARGS__))
 #endif
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::hal;
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -770,31 +770,16 @@ TabChild::PreloadSlowThings()
         // work.
         presShell->MakeZombie();
     }
 
     sPreallocatedTab = tab;
     ClearOnShutdown(&sPreallocatedTab);
 }
 
-/*static*/ void
-TabChild::PostForkPreload()
-{
-    // Preallocated Tab can be null if we are forked directly from b2g. In such
-    // case we don't need to preload anything, just return.
-    if (!sPreallocatedTab) {
-        return;
-    }
-
-    // Rebuild connections to parent.
-    sPreallocatedTab->RecvLoadRemoteScript(
-      NS_LITERAL_STRING("chrome://global/content/post-fork-preload.js"),
-      true);
-}
-
 /*static*/ already_AddRefed<TabChild>
 TabChild::Create(nsIContentChild* aManager,
                  const TabId& aTabId,
                  const TabContext &aContext,
                  uint32_t aChromeFlags)
 {
     if (sPreallocatedTab &&
         sPreallocatedTab->mChromeFlags == aChromeFlags &&
@@ -2982,27 +2967,33 @@ TabChild::NotifyPainted()
         mRemoteFrame->SendNotifyCompositorTransaction();
         mNotified = true;
     }
 }
 
 void
 TabChild::MakeVisible()
 {
-    if (mWidget) {
-        mWidget->Show(true);
-    }
+  CompositorChild* compositor = CompositorChild::Get();
+  compositor->SendNotifyVisible(mLayersId);
+
+  if (mWidget) {
+    mWidget->Show(true);
+  }
 }
 
 void
 TabChild::MakeHidden()
 {
-    if (mWidget) {
-        mWidget->Show(false);
-    }
+  CompositorChild* compositor = CompositorChild::Get();
+  compositor->SendNotifyHidden(mLayersId);
+
+  if (mWidget) {
+    mWidget->Show(false);
+  }
 }
 
 void
 TabChild::UpdateHitRegion(const nsRegion& aRegion)
 {
     mRemoteFrame->SendUpdateHitRegion(aRegion);
 }
 
@@ -3134,16 +3125,27 @@ TabChild::DidComposite(uint64_t aTransac
   MOZ_ASSERT(mWidget);
   MOZ_ASSERT(mWidget->GetLayerManager());
   MOZ_ASSERT(mWidget->GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_CLIENT);
 
   ClientLayerManager *manager = static_cast<ClientLayerManager*>(mWidget->GetLayerManager());
   manager->DidComposite(aTransactionId);
 }
 
+void
+TabChild::ClearCachedResources()
+{
+  MOZ_ASSERT(mWidget);
+  MOZ_ASSERT(mWidget->GetLayerManager());
+  MOZ_ASSERT(mWidget->GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_CLIENT);
+
+  ClientLayerManager *manager = static_cast<ClientLayerManager*>(mWidget->GetLayerManager());
+  manager->ClearCachedResources();
+}
+
 NS_IMETHODIMP
 TabChild::OnShowTooltip(int32_t aXCoords, int32_t aYCoords, const char16_t *aTipText)
 {
     nsString str(aTipText);
     SendShowTooltip(aXCoords, aYCoords, str);
     return NS_OK;
 }
 
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -258,17 +258,16 @@ public:
 
 public:
     /** 
      * This is expected to be called off the critical path to content
      * startup.  This is an opportunity to load things that are slow
      * on the critical path.
      */
     static void PreloadSlowThings();
-    static void PostForkPreload();
 
     /** Return a TabChild with the given attributes. */
     static already_AddRefed<TabChild>
     Create(nsIContentChild* aManager, const TabId& aTabId, const TabContext& aContext, uint32_t aChromeFlags);
 
     bool IsRootContentDocument();
     // Let managees query if it is safe to send messages.
     bool IsDestroyed() { return mDestroyed; }
@@ -471,16 +470,17 @@ public:
       nsCOMPtr<nsITabChild> tc = do_GetInterface(aDocShell);
       return static_cast<TabChild*>(tc.get());
     }
 
     static TabChild* GetFrom(nsIPresShell* aPresShell);
     static TabChild* GetFrom(uint64_t aLayersId);
 
     void DidComposite(uint64_t aTransactionId);
+    void ClearCachedResources();
 
     static inline TabChild*
     GetFrom(nsIDOMWindow* aWindow)
     {
       nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(aWindow);
       nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(webNav);
       return GetFrom(docShell);
     }
--- a/dom/ipc/jar.mn
+++ b/dom/ipc/jar.mn
@@ -7,9 +7,8 @@ toolkit.jar:
         content/global/remote-test-ipc.js (remote-test.js)
         content/global/BrowserElementChild.js (../browser-element/BrowserElementChild.js)
         content/global/BrowserElementChildPreload.js (../browser-element/BrowserElementChildPreload.js)
         content/global/BrowserElementPanning.js (../browser-element/BrowserElementPanning.js)
 *       content/global/BrowserElementPanningAPZDisabled.js (../browser-element/BrowserElementPanningAPZDisabled.js)
         content/global/manifestMessages.js (manifestMessages.js)
         content/global/PushServiceChildPreload.js (../push/PushServiceChildPreload.js)
         content/global/preload.js (preload.js)
-        content/global/post-fork-preload.js (post-fork-preload.js)
deleted file mode 100644
--- a/dom/ipc/post-fork-preload.js
+++ /dev/null
@@ -1,20 +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/. */
-
-// Preload some things, in an attempt to make app startup faster.
-//
-// This script is run when the preallocated process starts.  It is injected as
-// a frame script.
-// If Nuwa process is enabled, this script will run in preallocated process
-// forked by Nuwa.
-
-(function (global) {
-  "use strict";
-
-  Components.utils.import("resource://gre/modules/AppsServiceChild.jsm");
-  Components.classes["@mozilla.org/network/protocol-proxy-service;1"].
-    getService(Ci["nsIProtocolProxyService"]);
-
-  DOMApplicationRegistry.resetList();
-})(this);
--- a/dom/ipc/preload.js
+++ b/dom/ipc/preload.js
@@ -1,17 +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/. */
 
 // Preload some things, in an attempt to make app startup faster.
 //
 // This script is run when the preallocated process starts.  It is injected as
 // a frame script.
-// If nuwa is enabled, this script will run in Nuwa process before frozen.
 
 const BrowserElementIsPreloaded = true;
 
 (function (global) {
   "use strict";
 
   let Cu = Components.utils;
   let Cc = Components.classes;
@@ -54,16 +53,17 @@ const BrowserElementIsPreloaded = true;
   Cc["@mozilla.org/message-loop;1"].getService(Ci["nsIMessageLoop"]);
   Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci["mozIJSSubScriptLoader"]);
   Cc["@mozilla.org/network/application-cache-service;1"].getService(Ci["nsIApplicationCacheService"]);
   Cc["@mozilla.org/network/dns-service;1"].getService(Ci["nsIDNSService"]);
   Cc["@mozilla.org/network/effective-tld-service;1"].getService(Ci["nsIEffectiveTLDService"]);
   Cc["@mozilla.org/network/idn-service;1"].getService(Ci["nsIIDNService"]);
   Cc["@mozilla.org/network/io-service;1"].getService(Ci["nsIIOService2"]);
   Cc["@mozilla.org/network/mime-hdrparam;1"].getService(Ci["nsIMIMEHeaderParam"]);
+  Cc["@mozilla.org/network/protocol-proxy-service;1"].getService(Ci["nsIProtocolProxyService"]);
   Cc["@mozilla.org/network/socket-transport-service;1"].getService(Ci["nsISocketTransportService"]);
   Cc["@mozilla.org/network/stream-transport-service;1"].getService(Ci["nsIStreamTransportService"]);
   Cc["@mozilla.org/network/url-parser;1?auth=maybe"].getService(Ci["nsIURLParser"]);
   Cc["@mozilla.org/network/url-parser;1?auth=no"].getService(Ci["nsIURLParser"]);
   Cc["@mozilla.org/network/url-parser;1?auth=yes"].getService(Ci["nsIURLParser"]);
   Cc["@mozilla.org/observer-service;1"].getService(Ci["nsIObserverService"]);
   Cc["@mozilla.org/permissionmanager;1"].getService(Ci["nsIPermissionManager"]);
   Cc["@mozilla.org/preferences-service;1"].getService(Ci["nsIPrefBranch"]);
--- a/dom/manifest/ManifestImageObjectProcessor.jsm
+++ b/dom/manifest/ManifestImageObjectProcessor.jsm
@@ -9,69 +9,66 @@
  * This is intended to be used in conjunction with ManifestProcessor.jsm
  *
  * Creates an object to process Image Objects as defined by the
  * W3C specification. This is used to process things like the
  * icon member and the splash_screen member.
  *
  * Usage:
  *
- *   .process(aManifest, aBaseURL, aMemberName, console);
+ *   .process(aManifest, aBaseURL, aMemberName);
  *
  */
-/*exported EXPORTED_SYMBOLS */
-/*globals extractValue, Components*/
+/*exported EXPORTED_SYMBOLS*/
+/*globals Components*/
 'use strict';
 this.EXPORTED_SYMBOLS = ['ManifestImageObjectProcessor']; // jshint ignore:line
 const imports = {};
 const {
   utils: Cu,
   classes: Cc,
   interfaces: Ci
 } = Components;
-const scriptLoader = Cc['@mozilla.org/moz/jssubscript-loader;1']
-  .getService(Ci.mozIJSSubScriptLoader);
-scriptLoader.loadSubScript(
-  'resource://gre/modules/manifestValueExtractor.js',
-  this); // jshint ignore:line
 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 Cu.importGlobalProperties(['URL']);
 imports.netutil = Cc['@mozilla.org/network/util;1']
   .getService(Ci.nsINetUtil);
-imports.DOMUtils = Cc['@mozilla.org/inspector/dom-utils;1']
-  .getService(Ci.inIDOMUtils);
 
-function ManifestImageObjectProcessor() {}
+function ManifestImageObjectProcessor(aConsole, aExtractor) {
+  this.console = aConsole;
+  this.extractor = aExtractor;
+}
 
 // Static getters
 Object.defineProperties(ManifestImageObjectProcessor, {
   'decimals': {
     get: function() {
       return /^\d+$/;
     }
   },
   'anyRegEx': {
     get: function() {
       return new RegExp('any', 'i');
     }
   }
 });
 
-ManifestImageObjectProcessor.process = function(
-  aManifest, aBaseURL, aMemberName, console
+ManifestImageObjectProcessor.prototype.process = function(
+  aManifest, aBaseURL, aMemberName
 ) {
   const spec = {
     objectName: 'manifest',
     object: aManifest,
     property: aMemberName,
     expectedType: 'array',
     trim: false
   };
+  const extractor = this.extractor;
   const images = [];
-  const value = extractValue(spec, console);
+  const value = extractor.extractValue(spec);
   if (Array.isArray(value)) {
     // Filter out images whose "src" is not useful.
     value.filter(item => !!processSrcMember(item, aBaseURL))
       .map(toImageObject)
       .forEach(image => images.push(image));
   }
   return images;
 
@@ -90,17 +87,17 @@ ManifestImageObjectProcessor.process = f
     const hadCharset = {};
     const spec = {
       objectName: 'image',
       object: aImage,
       property: 'type',
       expectedType: 'string',
       trim: true
     };
-    let value = extractValue(spec, console);
+    let value = extractor.extractValue(spec);
     if (value) {
       value = imports.netutil.parseContentType(value, charset, hadCharset);
     }
     return value || undefined;
   }
 
   function processDensityMember(aImage) {
     const value = parseFloat(aImage.density);
@@ -112,17 +109,17 @@ ManifestImageObjectProcessor.process = f
   function processSrcMember(aImage, aBaseURL) {
     const spec = {
       objectName: 'image',
       object: aImage,
       property: 'src',
       expectedType: 'string',
       trim: false
     };
-    const value = extractValue(spec, console);
+    const value = extractor.extractValue(spec);
     let url;
     if (value && value.length) {
       try {
         url = new URL(value, aBaseURL).href;
       } catch (e) {}
     }
     return url;
   }
@@ -131,17 +128,17 @@ ManifestImageObjectProcessor.process = f
     const sizes = new Set();
     const spec = {
       objectName: 'image',
       object: aImage,
       property: 'sizes',
       expectedType: 'string',
       trim: true
     };
-    const value = extractValue(spec, console);
+    const value = extractor.extractValue(spec);
     if (value) {
       // Split on whitespace and filter out invalid values.
       value.split(/\s+/)
         .filter(isValidSizeValue)
         .forEach(size => sizes.add(size));
     }
     return sizes;
     // Implementation of HTML's link@size attribute checker.
@@ -166,20 +163,12 @@ ManifestImageObjectProcessor.process = f
   function processBackgroundColorMember(aImage) {
     const spec = {
       objectName: 'image',
       object: aImage,
       property: 'background_color',
       expectedType: 'string',
       trim: true
     };
-    const value = extractValue(spec, console);
-    let color;
-    if (imports.DOMUtils.isValidCSSColor(value)) {
-      color = value;
-    } else {
-      const msg = `background_color: ${value} is not a valid CSS color.`;
-      console.warn(msg);
-    }
-    return color;
+    return extractor.extractColorValue(spec);
   }
 };
 this.ManifestImageObjectProcessor = ManifestImageObjectProcessor; // jshint ignore:line
--- a/dom/manifest/ManifestProcessor.jsm
+++ b/dom/manifest/ManifestProcessor.jsm
@@ -16,49 +16,44 @@
  * icons and splash_screens.
  *
  * TODO: The constructor should accept the UA's supported orientations.
  * TODO: The constructor should accept the UA's supported display modes.
  * TODO: hook up developer tools to console. (1086997).
  */
 /*exported EXPORTED_SYMBOLS */
 /*JSLint options in comment below: */
-/*globals Components, XPCOMUtils, extractValue*/
+/*globals Components, XPCOMUtils*/
 'use strict';
 this.EXPORTED_SYMBOLS = ['ManifestProcessor']; // jshint ignore:line
 const imports = {};
 const {
-  utils: Cu,
-  classes: Cc,
-  interfaces: Ci
+  utils: Cu
 } = Components;
-const scriptLoader = Cc['@mozilla.org/moz/jssubscript-loader;1']
-  .getService(Ci.mozIJSSubScriptLoader);
-//Add extractValue() helper to this context.
-scriptLoader.loadSubScript(
-  'resource://gre/modules/manifestValueExtractor.js',
-  this); // jshint ignore:line
 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 Cu.importGlobalProperties(['URL']);
 XPCOMUtils.defineLazyModuleGetter(imports, 'Services',
   'resource://gre/modules/Services.jsm');
-XPCOMUtils.defineLazyModuleGetter(imports, 'ManifestImageObjectProcessor',
-  'resource://gre/modules/ManifestImageObjectProcessor.jsm');
-imports.netutil = Cc['@mozilla.org/network/util;1']
-  .getService(Ci.nsINetUtil);
 const displayModes = new Set(['fullscreen', 'standalone', 'minimal-ui',
   'browser'
 ]);
 const orientationTypes = new Set(['any', 'natural', 'landscape', 'portrait',
   'portrait-primary', 'portrait-secondary', 'landscape-primary',
   'landscape-secondary'
 ]);
 const {
   ConsoleAPI
 } = Cu.import('resource://gre/modules/devtools/Console.jsm');
+const {
+  ManifestImageObjectProcessor: ImgObjProcessor
+} = Cu.import('resource://gre/modules/ManifestImageObjectProcessor.jsm');
+
+const {
+  ManifestValueExtractor
+} = Cu.import('resource://gre/modules/ManifestValueExtractor.jsm');
 
 function ManifestProcessor() {}
 
 // Static getters
 Object.defineProperties(ManifestProcessor, {
   'defaultDisplayMode': {
     get: function() {
       return 'browser';
@@ -72,122 +67,125 @@ Object.defineProperties(ManifestProcesso
   'orientationTypes': {
     get: function() {
       return orientationTypes;
     }
   }
 });
 
 ManifestProcessor.prototype = {
-  // process method: processes JSON text into a clean manifest
+  // process() method processes JSON text into a clean manifest
   // that conforms with the W3C specification. Takes an object
   // expecting the following dictionary items:
   //  * aJsonText: the JSON string to be processed.
   //  * aManifestURL: the URL of the manifest, to resolve URLs.
-  //  * aDocURL: the URL of the owner doc, for security checks.
+  //  * aDocURL: the URL of the owner doc, for security checks
   process({
     jsonText: aJsonText,
     manifestURL: aManifestURL,
     docURL: aDocURL
   }) {
-    const manifestURL = new URL(aManifestURL);
-    const docURL = new URL(aDocURL);
     const console = new ConsoleAPI({
       prefix: 'Web Manifest: '
     });
+    const manifestURL = new URL(aManifestURL);
+    const docURL = new URL(aDocURL);
     let rawManifest = {};
     try {
       rawManifest = JSON.parse(aJsonText);
     } catch (e) {}
     if (typeof rawManifest !== 'object' || rawManifest === null) {
       let msg = 'Manifest needs to be an object.';
       console.warn(msg);
       rawManifest = {};
     }
+    const extractor = new ManifestValueExtractor(console);
+    const imgObjProcessor = new ImgObjProcessor(console, extractor);
     const processedManifest = {
       'start_url': processStartURLMember(rawManifest, manifestURL, docURL),
       'display': processDisplayMember(rawManifest),
       'orientation': processOrientationMember(rawManifest),
       'name': processNameMember(rawManifest),
-      'icons': imports.ManifestImageObjectProcessor.process(
-        rawManifest, manifestURL, 'icons', console
+      'icons': imgObjProcessor.process(
+        rawManifest, manifestURL, 'icons'
       ),
-      'splash_screens': imports.ManifestImageObjectProcessor.process(
-        rawManifest, manifestURL, 'splash_screens', console
+      'splash_screens': imgObjProcessor.process(
+        rawManifest, manifestURL, 'splash_screens'
       ),
       'short_name': processShortNameMember(rawManifest),
+      'theme_color': processThemeColorMember(rawManifest),
     };
     processedManifest.scope = processScopeMember(rawManifest, manifestURL,
       docURL, new URL(processedManifest['start_url'])); // jshint ignore:line
 
     return processedManifest;
 
     function processNameMember(aManifest) {
       const spec = {
         objectName: 'manifest',
         object: aManifest,
         property: 'name',
         expectedType: 'string',
         trim: true
       };
-      return extractValue(spec, console);
+      return extractor.extractValue(spec);
     }
 
     function processShortNameMember(aManifest) {
       const spec = {
         objectName: 'manifest',
         object: aManifest,
         property: 'short_name',
         expectedType: 'string',
         trim: true
       };
-      return extractValue(spec, console);
+      return extractor.extractValue(spec);
     }
 
     function processOrientationMember(aManifest) {
       const spec = {
         objectName: 'manifest',
         object: aManifest,
         property: 'orientation',
         expectedType: 'string',
         trim: true
       };
-      const value = extractValue(spec, console);
+      const value = extractor.extractValue(spec);
       if (ManifestProcessor.orientationTypes.has(value)) {
         return value;
       }
       // The spec special-cases orientation to return the empty string.
       return '';
     }
 
     function processDisplayMember(aManifest) {
       const spec = {
         objectName: 'manifest',
         object: aManifest,
         property: 'display',
         expectedType: 'string',
         trim: true
       };
-      const value = extractValue(spec, console);
+      const value = extractor.extractValue(spec);
       if (ManifestProcessor.displayModes.has(value)) {
         return value;
       }
       return ManifestProcessor.defaultDisplayMode;
     }
 
     function processScopeMember(aManifest, aManifestURL, aDocURL, aStartURL) {
       const spec = {
         objectName: 'manifest',
         object: aManifest,
         property: 'scope',
         expectedType: 'string',
         trim: false
       };
       let scopeURL;
-      const value = extractValue(spec, console);
+      const value = extractor.extractValue(spec);
       if (value === undefined || value === '') {
         return undefined;
       }
       try {
         scopeURL = new URL(value, aManifestURL);
       } catch (e) {
         let msg = 'The URL of scope is invalid.';
         console.warn(msg);
@@ -213,17 +211,17 @@ ManifestProcessor.prototype = {
       const spec = {
         objectName: 'manifest',
         object: aManifest,
         property: 'start_url',
         expectedType: 'string',
         trim: false
       };
       let result = new URL(aDocURL).href;
-      const value = extractValue(spec, console);
+      const value = extractor.extractValue(spec);
       if (value === undefined || value === '') {
         return result;
       }
       let potentialResult;
       try {
         potentialResult = new URL(value, aManifestURL);
       } catch (e) {
         console.warn('Invalid URL.');
@@ -232,11 +230,23 @@ ManifestProcessor.prototype = {
       if (potentialResult.origin !== aDocURL.origin) {
         let msg = 'start_url must be same origin as document.';
         console.warn(msg);
       } else {
         result = potentialResult.href;
       }
       return result;
     }
+
+    function processThemeColorMember(aManifest) {
+      const spec = {
+        objectName: 'manifest',
+        object: aManifest,
+        property: 'theme_color',
+        expectedType: 'string',
+        trim: true
+      };
+      return extractor.extractColorValue(spec);
+    }
   }
 };
+
 this.ManifestProcessor = ManifestProcessor; // jshint ignore:line
new file mode 100644
--- /dev/null
+++ b/dom/manifest/ManifestValueExtractor.jsm
@@ -0,0 +1,68 @@
+/* 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 https://www.mozilla.org/MPL/2.0/. */
+/*
+ * Helper functions extract values from manifest members
+ * and reports conformance violations.
+ */
+/*globals Components*/
+'use strict';
+const imports = {};
+const {
+  classes: Cc,
+  interfaces: Ci
+} = Components;
+imports.DOMUtils = Cc['@mozilla.org/inspector/dom-utils;1']
+  .getService(Ci.inIDOMUtils);
+
+this.EXPORTED_SYMBOLS = ['ManifestValueExtractor']; // jshint ignore:line
+
+function ManifestValueExtractor(aConsole) {
+  this.console = aConsole;
+}
+
+ManifestValueExtractor.prototype = {
+  // This function takes a 'spec' object and destructures
+  // it to extract a value. If the value is of th wrong type, it
+  // warns the developer and returns undefined.
+  //  expectType: is the type of a JS primitive (string, number, etc.)
+  //  object: is the object from which to extract the value.
+  //  objectName: string used to construct the developer warning.
+  //  property: the name of the property being extracted.
+  //  trim: boolean, if the value should be trimmed (used by string type).
+  extractValue({
+    expectedType, object, objectName, property, trim
+  }) {
+    const value = object[property];
+    const isArray = Array.isArray(value);
+    // We need to special-case "array", as it's not a JS primitive.
+    const type = (isArray) ? 'array' : typeof value;
+    if (type !== expectedType) {
+      if (type !== 'undefined') {
+        let msg = `Expected the ${objectName}'s ${property} `;
+        msg += `member to be a ${expectedType}.`;
+        this.console.log(msg);
+      }
+      return undefined;
+    }
+    // Trim string and returned undefined if the empty string.
+    const shouldTrim = expectedType === 'string' && value && trim;
+    if (shouldTrim) {
+      return value.trim() || undefined;
+    }
+    return value;
+  },
+  extractColorValue(spec) {
+    const value = this.extractValue(spec);
+    let color;
+    if (imports.DOMUtils.isValidCSSColor(value)) {
+      color = value;
+    } else {
+      const msg = `background_color: ${value} is not a valid CSS color.`;
+      this.console.warn(msg);
+    }
+    return color;
+  }
+};
+
+this.ManifestValueExtractor = ManifestValueExtractor; // jshint ignore:line
deleted file mode 100644
--- a/dom/manifest/manifestValueExtractor.js
+++ /dev/null
@@ -1,34 +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/. */
-/*
- * Helper function extracts values from manifest members
- * and reports conformance violations.
- */
-
-function extractValue({
-  objectName,
-  object,
-  property,
-  expectedType,
-  trim
-}, console) {
-  const value = object[property];
-  const isArray = Array.isArray(value);
-  // We need to special-case "array", as it's not a JS primitive.
-  const type = (isArray) ? 'array' : typeof value;
-  if (type !== expectedType) {
-    if (type !== 'undefined') {
-      let msg = `Expected the ${objectName}'s ${property} `;
-      msg += `member to be a ${expectedType}.`;
-      console.log(msg);
-    }
-    return undefined;
-  }
-  // Trim string and returned undefined if the empty string.
-  const shouldTrim = expectedType === 'string' && value && trim;
-  if (shouldTrim) {
-    return value.trim() || undefined;
-  }
-  return value;
-}
--- a/dom/manifest/moz.build
+++ b/dom/manifest/moz.build
@@ -3,13 +3,13 @@
 # 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/.
 
 EXTRA_JS_MODULES += [
     'ManifestImageObjectProcessor.jsm',
     'ManifestObtainer.jsm',
     'ManifestProcessor.jsm',
-    'manifestValueExtractor.js'
+    'ManifestValueExtractor.jsm'
 ]
 
 MOCHITEST_MANIFESTS += ['test/mochitest.ini']
 BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
--- a/dom/media/AudioSink.cpp
+++ b/dom/media/AudioSink.cpp
@@ -7,19 +7,19 @@
 #include "MediaDecoderStateMachine.h"
 #include "AudioStream.h"
 #include "prenv.h"
 
 namespace mozilla {
 
 extern PRLogModuleInfo* gMediaDecoderLog;
 #define SINK_LOG(msg, ...) \
-  PR_LOG(gMediaDecoderLog, PR_LOG_DEBUG, ("AudioSink=%p " msg, this, ##__VA_ARGS__))
+  MOZ_LOG(gMediaDecoderLog, PR_LOG_DEBUG, ("AudioSink=%p " msg, this, ##__VA_ARGS__))
 #define SINK_LOG_V(msg, ...) \
-  PR_LOG(gMediaDecoderLog, PR_LOG_DEBUG+1, ("AudioSink=%p " msg, this, ##__VA_ARGS__))
+  MOZ_LOG(gMediaDecoderLog, PR_LOG_DEBUG+1, ("AudioSink=%p " msg, this, ##__VA_ARGS__))
 
 AudioSink::OnAudioEndTimeUpdateTask::OnAudioEndTimeUpdateTask(
                                      MediaDecoderStateMachine* aStateMachine)
   : mMutex("OnAudioEndTimeUpdateTask")
   , mEndTime(0)
   , mStateMachine(aStateMachine)
 {
 }
@@ -33,17 +33,18 @@ AudioSink::OnAudioEndTimeUpdateTask::Run
   return NS_OK;
 }
 
 void
 AudioSink::OnAudioEndTimeUpdateTask::Dispatch(int64_t aEndTime) {
   MutexAutoLock lock(mMutex);
   if (mStateMachine) {
     mEndTime = aEndTime;
-    mStateMachine->TaskQueue()->Dispatch(this);
+    nsRefPtr<AudioSink::OnAudioEndTimeUpdateTask> runnable(this);
+    mStateMachine->TaskQueue()->Dispatch(runnable.forget());
   }
 }
 
 void
 AudioSink::OnAudioEndTimeUpdateTask::Cancel() {
   MutexAutoLock lock(mMutex);
   mStateMachine = nullptr;
 }
--- a/dom/media/AudioStream.cpp
+++ b/dom/media/AudioStream.cpp
@@ -25,17 +25,17 @@
 namespace mozilla {
 
 #ifdef LOG
 #undef LOG
 #endif
 
 PRLogModuleInfo* gAudioStreamLog = nullptr;
 // For simple logs
-#define LOG(x) PR_LOG(gAudioStreamLog, PR_LOG_DEBUG, x)
+#define LOG(x) MOZ_LOG(gAudioStreamLog, PR_LOG_DEBUG, x)
 
 /**
  * When MOZ_DUMP_AUDIO is set in the environment (to anything),
  * we'll drop a series of files in the current working directory named
  * dumped-audio-<nnn>.wav, one per AudioStream created, containing
  * the audio for the stream including any skips due to underruns.
  */
 static int gDumpedAudioCount = 0;
@@ -324,17 +324,17 @@ AudioStream::Init(int32_t aNumChannels, 
 {
   mStartTime = TimeStamp::Now();
   mIsFirst = CubebUtils::GetFirstStream();
 
   if (!CubebUtils::GetCubebContext() || aNumChannels < 0 || aRate < 0) {
     return NS_ERROR_FAILURE;
   }
 
-  PR_LOG(gAudioStreamLog, PR_LOG_DEBUG,
+  MOZ_LOG(gAudioStreamLog, PR_LOG_DEBUG,
     ("%s  channels: %d, rate: %d for %p", __FUNCTION__, aNumChannels, aRate, this));
   mInRate = mOutRate = aRate;
   mChannels = aNumChannels;
   mOutChannels = (aNumChannels > 2) ? 2 : aNumChannels;
   mLatencyRequest = aLatencyRequest;
 
   mDumpFile = OpenDumpFile(this);
 
@@ -541,22 +541,22 @@ AudioStream::CheckForStart()
   mMonitor.AssertCurrentThreadOwns();
   if (mState == INITIALIZED) {
     // Start the stream right away when low latency has been requested. This means
     // that the DataCallback will feed silence to cubeb, until the first frames
     // are written to this AudioStream.  Also start if a start has been queued.
     if (mLatencyRequest == LowLatency || mNeedsStart) {
       StartUnlocked(); // mState = STARTED or ERRORED
       mNeedsStart = false;
-      PR_LOG(gAudioStreamLog, PR_LOG_WARNING,
+      MOZ_LOG(gAudioStreamLog, PR_LOG_WARNING,
              ("Started waiting %s-latency stream",
               mLatencyRequest == LowLatency ? "low" : "high"));
     } else {
       // high latency, not full - OR Pause() was called before we got here
-      PR_LOG(gAudioStreamLog, PR_LOG_DEBUG,
+      MOZ_LOG(gAudioStreamLog, PR_LOG_DEBUG,
              ("Not starting waiting %s-latency stream",
               mLatencyRequest == LowLatency ? "low" : "high"));
     }
   }
 }
 
 NS_IMETHODIMP
 AudioInitTask::Run()
@@ -639,32 +639,32 @@ AudioStream::Write(const AudioDataValue*
       // Careful - the CubebInit thread may not have gotten to STARTED yet
       if ((mState == INITIALIZED || mState == STARTED) && mLatencyRequest == LowLatency) {
         // don't ever block MediaStreamGraph low-latency streams
         uint32_t remains = 0; // we presume the buffer is full
         if (mBuffer.Length() > bytesToCopy) {
           remains = mBuffer.Length() - bytesToCopy; // Free up just enough space
         }
         // account for dropping samples
-        PR_LOG(gAudioStreamLog, PR_LOG_WARNING, ("Stream %p dropping %u bytes (%u frames)in Write()",
+        MOZ_LOG(gAudioStreamLog, PR_LOG_WARNING, ("Stream %p dropping %u bytes (%u frames)in Write()",
             this, mBuffer.Length() - remains, BytesToFrames(mBuffer.Length() - remains)));
         mReadPoint += BytesToFrames(mBuffer.Length() - remains);
         mBuffer.ContractTo(remains);
       } else { // RUNNING or high latency
         // If we are not playing, but our buffer is full, start playing to make
         // room for soon-to-be-decoded data.
         if (mState != STARTED && mState != RUNNING) {
-          PR_LOG(gAudioStreamLog, PR_LOG_WARNING, ("Starting stream %p in Write (%u waiting)",
+          MOZ_LOG(gAudioStreamLog, PR_LOG_WARNING, ("Starting stream %p in Write (%u waiting)",
                                                  this, bytesToCopy));
           StartUnlocked();
           if (mState == ERRORED) {
             return NS_ERROR_FAILURE;
           }
         }
-        PR_LOG(gAudioStreamLog, PR_LOG_WARNING, ("Stream %p waiting in Write() (%u waiting)",
+        MOZ_LOG(gAudioStreamLog, PR_LOG_WARNING, ("Stream %p waiting in Write() (%u waiting)",
                                                  this, bytesToCopy));
         mon.Wait();
       }
     }
   }
 
   mWritten += aFrames;
   return NS_OK;
@@ -1067,26 +1067,26 @@ AudioStream::DataCallback(void* aBuffer,
     // we start getting callbacks.
     // Simple version - contract on first callback only.
     if (mLatencyRequest == LowLatency) {
       uint32_t old_len = mBuffer.Length();
       available = mBuffer.ContractTo(FramesToBytes(aFrames));
       TimeStamp now = TimeStamp::Now();
       if (!mStartTime.IsNull()) {
         int64_t timeMs = (now - mStartTime).ToMilliseconds();
-        PR_LOG(gAudioStreamLog, PR_LOG_WARNING,
+        MOZ_LOG(gAudioStreamLog, PR_LOG_WARNING,
                ("Stream took %lldms to start after first Write() @ %u", timeMs, mOutRate));
       } else {
-        PR_LOG(gAudioStreamLog, PR_LOG_WARNING,
+        MOZ_LOG(gAudioStreamLog, PR_LOG_WARNING,
           ("Stream started before Write() @ %u", mOutRate));
       }
 
       if (old_len != available) {
         // Note that we may have dropped samples in Write() as well!
-        PR_LOG(gAudioStreamLog, PR_LOG_WARNING,
+        MOZ_LOG(gAudioStreamLog, PR_LOG_WARNING,
                ("AudioStream %p dropped %u + %u initial frames @ %u", this,
                  mReadPoint, BytesToFrames(old_len - available), mOutRate));
         mReadPoint += BytesToFrames(old_len - available);
       }
     }
     mState = RUNNING;
   }
 
@@ -1117,17 +1117,17 @@ AudioStream::DataCallback(void* aBuffer,
 
   // Always send audible frames first, and silent frames later.
   // Otherwise it will break the assumption of FrameHistory.
   if (mState != DRAINING) {
     mAudioClock.UpdateFrameHistory(servicedFrames, underrunFrames);
     uint8_t* rpos = static_cast<uint8_t*>(aBuffer) + FramesToBytes(aFrames - underrunFrames);
     memset(rpos, 0, FramesToBytes(underrunFrames));
     if (underrunFrames) {
-      PR_LOG(gAudioStreamLog, PR_LOG_WARNING,
+      MOZ_LOG(gAudioStreamLog, PR_LOG_WARNING,
              ("AudioStream %p lost %d frames", this, underrunFrames));
     }
     servicedFrames += underrunFrames;
   } else {
     mAudioClock.UpdateFrameHistory(servicedFrames, 0);
   }
 
   WriteDumpFile(mDumpFile, this, aFrames, aBuffer);
--- a/dom/media/GraphDriver.cpp
+++ b/dom/media/GraphDriver.cpp
@@ -6,17 +6,17 @@
 #include <MediaStreamGraphImpl.h>
 #include "CubebUtils.h"
 
 #ifdef XP_MACOSX
 #include <sys/sysctl.h>
 #endif
 
 extern PRLogModuleInfo* gMediaStreamGraphLog;
-#define STREAM_LOG(type, msg) PR_LOG(gMediaStreamGraphLog, type, msg)
+#define STREAM_LOG(type, msg) MOZ_LOG(gMediaStreamGraphLog, type, msg)
 
 // We don't use NSPR log here because we want this interleaved with adb logcat
 // on Android/B2G
 // #define ENABLE_LIFECYCLE_LOG
 #ifdef ENABLE_LIFECYCLE_LOG
 #ifdef ANDROID
 #include "android/log.h"
 #define LIFECYCLE_LOG(...)  __android_log_print(ANDROID_LOG_INFO, "Gecko - MSG" , __VA_ARGS__); printf(__VA_ARGS__);printf("\n");
@@ -314,17 +314,17 @@ void
 SystemClockDriver::GetIntervalForIteration(GraphTime& aFrom, GraphTime& aTo)
 {
   TimeStamp now = TimeStamp::Now();
   aFrom = mIterationStart = IterationEnd();
   aTo = mIterationEnd = mGraphImpl->SecondsToMediaTime((now - mCurrentTimeStamp).ToSeconds()) + IterationEnd();
 
   mCurrentTimeStamp = now;
 
-  PR_LOG(gMediaStreamGraphLog, PR_LOG_DEBUG+1, ("Updating current time to %f (real %f, mStateComputedTime %f)",
+  MOZ_LOG(gMediaStreamGraphLog, PR_LOG_DEBUG+1, ("Updating current time to %f (real %f, mStateComputedTime %f)",
          mGraphImpl->MediaTimeToSeconds(aTo),
          (now - mInitialTimeStamp).ToSeconds(),
          mGraphImpl->MediaTimeToSeconds(StateComputedTime())));
 
   if (mStateComputedTime < aTo) {
     STREAM_LOG(PR_LOG_WARNING, ("Media graph global underrun detected"));
     aTo = mIterationEnd = mStateComputedTime;
   }
--- a/dom/media/Latency.cpp
+++ b/dom/media/Latency.cpp
@@ -186,21 +186,21 @@ AsyncLatencyLogger::Observe(nsISupports*
   return NS_OK;
 }
 
 // aID is a sub-identifier (in particular a specific MediaStramTrack)
 void AsyncLatencyLogger::WriteLog(LatencyLogIndex aIndex, uint64_t aID, int64_t aValue,
                                   TimeStamp aTimeStamp)
 {
   if (aTimeStamp.IsNull()) {
-    PR_LOG(GetLatencyLog(), PR_LOG_DEBUG,
+    MOZ_LOG(GetLatencyLog(), PR_LOG_DEBUG,
       ("Latency: %s,%llu,%lld,%lld",
        LatencyLogIndex2Strings[aIndex], aID, GetTimeStamp(), aValue));
   } else {
-    PR_LOG(GetLatencyLog(), PR_LOG_DEBUG,
+    MOZ_LOG(GetLatencyLog(), PR_LOG_DEBUG,
       ("Latency: %s,%llu,%lld,%lld,%lld",
        LatencyLogIndex2Strings[aIndex], aID, GetTimeStamp(), aValue,
        static_cast<int64_t>((aTimeStamp - gAsyncLogger->mStart).ToMilliseconds())));
   }
 }
 
 int64_t AsyncLatencyLogger::GetTimeStamp()
 {
--- a/dom/media/MediaCache.cpp
+++ b/dom/media/MediaCache.cpp
@@ -20,17 +20,17 @@
 #include "nsIPrincipal.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Services.h"
 #include <algorithm>
 
 namespace mozilla {
 
 PRLogModuleInfo* gMediaCacheLog;
-#define CACHE_LOG(type, msg) PR_LOG(gMediaCacheLog, type, msg)
+#define CACHE_LOG(type, msg) MOZ_LOG(gMediaCacheLog, type, msg)
 
 // Readahead blocks for non-seekable streams will be limited to this
 // fraction of the cache space. We don't normally evict such blocks
 // because replacing them requires a seek, but we need to make sure
 // they don't monopolize the cache.
 static const double NONSEEKABLE_READAHEAD_MAX = 0.5;
 
 // Data N seconds before the current playback position is given the same priority
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -48,17 +48,17 @@ namespace mozilla {
 // fluctuating bitrates.
 static const int64_t CAN_PLAY_THROUGH_MARGIN = 1;
 
 // avoid redefined macro in unified build
 #undef DECODER_LOG
 
 PRLogModuleInfo* gMediaDecoderLog;
 #define DECODER_LOG(x, ...) \
-  PR_LOG(gMediaDecoderLog, PR_LOG_DEBUG, ("Decoder=%p " x, this, ##__VA_ARGS__))
+  MOZ_LOG(gMediaDecoderLog, PR_LOG_DEBUG, ("Decoder=%p " x, this, ##__VA_ARGS__))
 
 static const char* const gPlayStateStr[] = {
   "START",
   "LOADING",
   "PAUSED",
   "PLAYING",
   "SEEKING",
   "ENDED",
@@ -204,33 +204,33 @@ void MediaDecoder::UpdateDormantState(bo
   if (mIsDormant) {
     DECODER_LOG("UpdateDormantState() entering DORMANT state");
     // enter dormant state
     RefPtr<nsRunnable> event =
       NS_NewRunnableMethodWithArg<bool>(
         mDecoderStateMachine,
         &MediaDecoderStateMachine::SetDormant,
         true);
-    mDecoderStateMachine->TaskQueue()->Dispatch(event);
+    mDecoderStateMachine->TaskQueue()->Dispatch(event.forget());
 
     if (IsEnded()) {
       mWasEndedWhenEnteredDormant = true;
     }
     mNextState = mPlayState;
     ChangeState(PLAY_STATE_LOADING);
   } else {
     DECODER_LOG("UpdateDormantState() leaving DORMANT state");
     // exit dormant state
     // trigger to state machine.
     RefPtr<nsRunnable> event =
       NS_NewRunnableMethodWithArg<bool>(
         mDecoderStateMachine,
         &MediaDecoderStateMachine::SetDormant,
         false);
-    mDecoderStateMachine->TaskQueue()->Dispatch(event);
+    mDecoderStateMachine->TaskQueue()->Dispatch(event.forget());
   }
 }
 
 void MediaDecoder::DormantTimerExpired(nsITimer* aTimer, void* aClosure)
 {
   MOZ_ASSERT(aClosure);
   MediaDecoder* decoder = static_cast<MediaDecoder*>(aClosure);
   ReentrantMonitorAutoEnter mon(decoder->GetReentrantMonitor());
--- a/dom/media/MediaDecoderReader.cpp
+++ b/dom/media/MediaDecoderReader.cpp
@@ -17,17 +17,17 @@
 
 namespace mozilla {
 
 // Un-comment to enable logging of seek bisections.
 //#define SEEK_LOGGING
 
 extern PRLogModuleInfo* gMediaDecoderLog;
 #define DECODER_LOG(x, ...) \
-  PR_LOG(gMediaDecoderLog, PR_LOG_DEBUG, ("Decoder=%p " x, mDecoder, ##__VA_ARGS__))
+  MOZ_LOG(gMediaDecoderLog, PR_LOG_DEBUG, ("Decoder=%p " x, mDecoder, ##__VA_ARGS__))
 
 // Same workaround as MediaDecoderStateMachine.cpp.
 #define DECODER_WARN_HELPER(a, b) NS_WARNING b
 #define DECODER_WARN(x, ...) \
   DECODER_WARN_HELPER(0, (nsPrintfCString("Decoder=%p " x, mDecoder, ##__VA_ARGS__).get()))
 
 class VideoQueueMemoryFunctor : public nsDequeFunctor {
 public:
@@ -272,17 +272,17 @@ MediaDecoderReader::RequestVideoData(boo
     if (!DecodeVideoFrame(skip, aTimeThreshold)) {
       VideoQueue().Finish();
     } else if (skip) {
       // We still need to decode more data in order to skip to the next
       // keyframe. Post another task to the decode task queue to decode
       // again. We don't just decode straight in a loop here, as that
       // would hog the decode task queue.
       RefPtr<nsIRunnable> task(new ReRequestVideoWithSkipTask(this, aTimeThreshold));
-      mTaskQueue->Dispatch(task);
+      mTaskQueue->Dispatch(task.forget());
       return p;
     }
   }
   if (VideoQueue().GetSize() > 0) {
     nsRefPtr<VideoData> v = VideoQueue().PopFront();
     if (v && mVideoDiscontinuity) {
       v->mDiscontinuity = true;
       mVideoDiscontinuity = false;
@@ -308,17 +308,17 @@ MediaDecoderReader::RequestAudioData()
       break;
     }
     // AudioQueue size is still zero, post a task to try again. Don't spin
     // waiting in this while loop since it somehow prevents audio EOS from
     // coming in gstreamer 1.x when there is still video buffer waiting to be
     // consumed. (|mVideoSinkBufferCount| > 0)
     if (AudioQueue().GetSize() == 0 && mTaskQueue) {
       RefPtr<nsIRunnable> task(new ReRequestAudioTask(this));
-      mTaskQueue->Dispatch(task);
+      mTaskQueue->Dispatch(task.forget());
       return p;
     }
   }
   if (AudioQueue().GetSize() > 0) {
     nsRefPtr<AudioData> a = AudioQueue().PopFront();
     if (mAudioDiscontinuity) {
       a->mDiscontinuity = true;
       mAudioDiscontinuity = false;
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -53,17 +53,17 @@ using namespace mozilla::gfx;
 // avoid redefined macro in unified build
 #undef LOG
 #undef DECODER_LOG
 #undef VERBOSE_LOG
 
 extern PRLogModuleInfo* gMediaDecoderLog;
 extern PRLogModuleInfo* gMediaSampleLog;
 #define LOG(m, l, x, ...) \
-  PR_LOG(m, l, ("Decoder=%p " x, mDecoder.get(), ##__VA_ARGS__))
+  MOZ_LOG(m, l, ("Decoder=%p " x, mDecoder.get(), ##__VA_ARGS__))
 #define DECODER_LOG(x, ...) \
   LOG(gMediaDecoderLog, PR_LOG_DEBUG, x, ##__VA_ARGS__)
 #define VERBOSE_LOG(x, ...) \
   LOG(gMediaDecoderLog, PR_LOG_DEBUG+1, x, ##__VA_ARGS__)
 #define SAMPLE_LOG(x, ...) \
   LOG(gMediaSampleLog, PR_LOG_DEBUG, x, ##__VA_ARGS__)
 
 // Somehow MSVC doesn't correctly delete the comma before ##__VA_ARGS__
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -171,17 +171,19 @@ private:
   // constructor immediately after the task queue is created.
   void InitializationTask();
 
   void Shutdown();
 public:
 
   void DispatchShutdown()
   {
-    TaskQueue()->Dispatch(NS_NewRunnableMethod(this, &MediaDecoderStateMachine::Shutdown));
+    nsCOMPtr<nsIRunnable> runnable =
+      NS_NewRunnableMethod(this, &MediaDecoderStateMachine::Shutdown);
+    TaskQueue()->Dispatch(runnable.forget());
   }
 
   void FinishShutdown();
 
   bool IsRealTime() const;
 
   // Called from the main thread to get the duration. The decoder monitor
   // must be obtained before calling this. It is in units of microseconds.
@@ -238,17 +240,19 @@ private:
   // Causes the state machine to switch to buffering state, and to
   // immediately stop playback and buffer downloaded data. Called on
   // the state machine thread.
   void StartBuffering();
 public:
 
   void DispatchStartBuffering()
   {
-    TaskQueue()->Dispatch(NS_NewRunnableMethod(this, &MediaDecoderStateMachine::StartBuffering));
+    nsCOMPtr<nsIRunnable> runnable =
+      NS_NewRunnableMethod(this, &MediaDecoderStateMachine::StartBuffering);
+    TaskQueue()->Dispatch(runnable.forget());
   }
 
   // This is called on the state machine thread and audio thread.
   // The decoder monitor must be obtained before calling this.
   bool HasAudio() const {
     AssertCurrentThreadInMonitor();
     return mInfo.HasAudio();
   }
@@ -740,25 +744,29 @@ public:
 
 private:
   // Called by the AudioSink to signal that all outstanding work is complete
   // and the sink is shutting down.
   void OnAudioSinkComplete();
 public:
   void DispatchOnAudioSinkComplete()
   {
-    TaskQueue()->Dispatch(NS_NewRunnableMethod(this, &MediaDecoderStateMachine::OnAudioSinkComplete));
+    nsCOMPtr<nsIRunnable> runnable =
+      NS_NewRunnableMethod(this, &MediaDecoderStateMachine::OnAudioSinkComplete);
+    TaskQueue()->Dispatch(runnable.forget());
   }
 
   // Called by the AudioSink to signal errors.
   void OnAudioSinkError();
 
   void DispatchOnAudioSinkError()
   {
-    TaskQueue()->Dispatch(NS_NewRunnableMethod(this, &MediaDecoderStateMachine::OnAudioSinkError));
+    nsCOMPtr<nsIRunnable> runnable =
+      NS_NewRunnableMethod(this, &MediaDecoderStateMachine::OnAudioSinkError);
+    TaskQueue()->Dispatch(runnable.forget());
   }
 
   // Return true if the video decoder's decode speed can not catch up the
   // play time.
   bool NeedToSkipToNextKeyframe();
 
   // The decoder object that created this state machine. The state machine
   // holds a strong reference to the decoder to ensure that the decoder stays
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -30,18 +30,18 @@ using mozilla::layers::LayersBackend;
 
 PRLogModuleInfo* GetFormatDecoderLog() {
   static PRLogModuleInfo* log = nullptr;
   if (!log) {
     log = PR_NewLogModule("MediaFormatReader");
   }
   return log;
 }
-#define LOG(arg, ...) PR_LOG(GetFormatDecoderLog(), PR_LOG_DEBUG, ("MediaFormatReader(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
-#define LOGV(arg, ...) PR_LOG(GetFormatDecoderLog(), PR_LOG_DEBUG+1, ("MediaFormatReader(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
+#define LOG(arg, ...) MOZ_LOG(GetFormatDecoderLog(), PR_LOG_DEBUG, ("MediaFormatReader(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
+#define LOGV(arg, ...) MOZ_LOG(GetFormatDecoderLog(), PR_LOG_DEBUG+1, ("MediaFormatReader(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
 
 namespace mozilla {
 
 static const char*
 TrackTypeToStr(TrackInfo::TrackType aTrack)
 {
   MOZ_ASSERT(aTrack == TrackInfo::kAudioTrack ||
              aTrack == TrackInfo::kVideoTrack ||
@@ -1012,44 +1012,44 @@ MediaFormatReader::Output(TrackType aTra
     NS_WARNING("MediaFormatReader::Output() passed a null sample");
     Error(aTrack);
     return;
   }
 
   RefPtr<nsIRunnable> task =
     NS_NewRunnableMethodWithArgs<TrackType, StorensRefPtrPassByPtr<MediaData>>(
       this, &MediaFormatReader::NotifyNewOutput, aTrack, aSample);
-  GetTaskQueue()->Dispatch(task);
+  GetTaskQueue()->Dispatch(task.forget());
 }
 
 void
 MediaFormatReader::DrainComplete(TrackType aTrack)
 {
   RefPtr<nsIRunnable> task =
     NS_NewRunnableMethodWithArg<TrackType>(
       this, &MediaFormatReader::NotifyDrainComplete, aTrack);
-  GetTaskQueue()->Dispatch(task);
+  GetTaskQueue()->Dispatch(task.forget());
 }
 
 void
 MediaFormatReader::InputExhausted(TrackType aTrack)
 {
   RefPtr<nsIRunnable> task =
     NS_NewRunnableMethodWithArg<TrackType>(
       this, &MediaFormatReader::NotifyInputExhausted, aTrack);
-  GetTaskQueue()->Dispatch(task);
+  GetTaskQueue()->Dispatch(task.forget());
 }
 
 void
 MediaFormatReader::Error(TrackType aTrack)
 {
   RefPtr<nsIRunnable> task =
     NS_NewRunnableMethodWithArg<TrackType>(
       this, &MediaFormatReader::NotifyError, aTrack);
-  GetTaskQueue()->Dispatch(task);
+  GetTaskQueue()->Dispatch(task.forget());
 }
 
 void
 MediaFormatReader::Flush(TrackType aTrack)
 {
   MOZ_ASSERT(OnTaskQueue());
   LOG("Flush(%s) BEGIN", TrackTypeToStr(aTrack));
 
@@ -1357,12 +1357,12 @@ MediaFormatReader::NotifyDataArrived(con
   MOZ_ASSERT(mMainThreadDemuxer);
   mMainThreadDemuxer->NotifyDataArrived(aLength, aOffset);
 
   // Queue a task to notify our main demuxer.
   RefPtr<nsIRunnable> task =
     NS_NewRunnableMethodWithArgs<int32_t, uint64_t>(
       this, &MediaFormatReader::NotifyDemuxer,
       aLength, aOffset);
-  GetTaskQueue()->Dispatch(task);
+  GetTaskQueue()->Dispatch(task.forget());
 }
 
 } // namespace mozilla
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -106,17 +106,17 @@ namespace mozilla {
 PRLogModuleInfo*
 GetMediaManagerLog()
 {
   static PRLogModuleInfo *sLog;
   if (!sLog)
     sLog = PR_NewLogModule("MediaManager");
   return sLog;
 }
-#define LOG(msg) PR_LOG(GetMediaManagerLog(), PR_LOG_DEBUG, msg)
+#define LOG(msg) MOZ_LOG(GetMediaManagerLog(), PR_LOG_DEBUG, msg)
 
 using dom::File;
 using dom::MediaStreamConstraints;
 using dom::MediaTrackConstraintSet;
 using dom::MediaTrackConstraints;
 using dom::MediaStreamError;
 using dom::GetUserMediaRequest;
 using dom::Sequence;
@@ -2237,17 +2237,17 @@ MediaManager::Observe(nsISupports* aSubj
     // Post ShutdownTask to execute on mMediaThread and pass in a lambda
     // callback to be executed back on this thread once it is done.
     //
     // The lambda callback "captures" the 'this' pointer for member access.
     // This is safe since this is guaranteed to be here since sSingleton isn't
     // cleared until the lambda function clears it.
 
     MediaManager::GetMessageLoop()->PostTask(FROM_HERE, new ShutdownTask(
-        media::CallbackRunnable::New([this]() mutable {
+        media::NewRunnableFrom([this]() mutable {
       // Close off any remaining active windows.
       MutexAutoLock lock(mMutex);
       GetActiveWindows()->Clear();
       mActiveCallbacks.Clear();
       mCallIds.Clear();
       LOG(("Releasing MediaManager singleton and thread"));
       // Note: won't be released immediately as the Observer has a ref to us
       sSingleton = nullptr;
--- a/dom/media/MediaManager.h
+++ b/dom/media/MediaManager.h
@@ -44,17 +44,17 @@
 
 namespace mozilla {
 namespace dom {
 struct MediaStreamConstraints;
 struct MediaTrackConstraintSet;
 }
 
 extern PRLogModuleInfo* GetMediaManagerLog();
-#define MM_LOG(msg) PR_LOG(GetMediaManagerLog(), PR_LOG_DEBUG, msg)
+#define MM_LOG(msg) MOZ_LOG(GetMediaManagerLog(), PR_LOG_DEBUG, msg)
 
 /**
  * This class is an implementation of MediaStreamListener. This is used
  * to Start() and Stop() the underlying MediaEngineSource when MediaStreams
  * are assigned and deassigned in content.
  */
 class GetUserMediaCallbackMediaStreamListener : public MediaStreamListener
 {
--- a/dom/media/MediaPromise.h
+++ b/dom/media/MediaPromise.h
@@ -26,17 +26,17 @@
 #endif
 
 namespace mozilla {
 
 extern PRLogModuleInfo* gMediaPromiseLog;
 
 #define PROMISE_LOG(x, ...) \
   MOZ_ASSERT(gMediaPromiseLog); \
-  PR_LOG(gMediaPromiseLog, PR_LOG_DEBUG, (x, ##__VA_ARGS__))
+  MOZ_LOG(gMediaPromiseLog, PR_LOG_DEBUG, (x, ##__VA_ARGS__))
 
 /*
  * A promise manages an asynchronous request that may or may not be able to be
  * fulfilled immediately. When an API returns a promise, the consumer may attach
  * callbacks to be invoked (asynchronously, on a specified thread) when the
  * request is either completed (resolved) or cannot be completed (rejected).
  *
  * When IsExclusive is true, the MediaPromise does a release-mode assertion that
--- a/dom/media/MediaRecorder.cpp
+++ b/dom/media/MediaRecorder.cpp
@@ -27,17 +27,17 @@
 #include "nsTArray.h"
 #include "GeckoProfiler.h"
 
 #ifdef LOG
 #undef LOG
 #endif
 
 PRLogModuleInfo* gMediaRecorderLog;
-#define LOG(type, msg) PR_LOG(gMediaRecorderLog, type, msg)
+#define LOG(type, msg) MOZ_LOG(gMediaRecorderLog, type, msg)
 
 namespace mozilla {
 
 namespace dom {
 
 /**
 + * MediaRecorderReporter measures memory being used by the Media Recorder.
 + *
--- a/dom/media/MediaResource.cpp
+++ b/dom/media/MediaResource.cpp
@@ -29,17 +29,17 @@
 #include "nsIAsyncVerifyRedirectCallback.h"
 #include "nsContentUtils.h"
 #include "nsHostObjectProtocolHandler.h"
 #include <algorithm>
 #include "nsProxyRelease.h"
 #include "nsIContentPolicy.h"
 
 PRLogModuleInfo* gMediaResourceLog;
-#define RESOURCE_LOG(msg, ...) PR_LOG(gMediaResourceLog, PR_LOG_DEBUG, \
+#define RESOURCE_LOG(msg, ...) MOZ_LOG(gMediaResourceLog, PR_LOG_DEBUG, \
                                       (msg, ##__VA_ARGS__))
 // Debug logging macro with object pointer and class name.
 #define CMLOG(msg, ...) \
         RESOURCE_LOG("%p [ChannelMediaResource]: " msg, this, ##__VA_ARGS__)
 
 static const uint32_t HTTP_OK_CODE = 200;
 static const uint32_t HTTP_PARTIAL_RESPONSE_CODE = 206;
 
--- a/dom/media/MediaShutdownManager.cpp
+++ b/dom/media/MediaShutdownManager.cpp
@@ -9,17 +9,17 @@
 #include "mozilla/StaticPtr.h"
 #include "MediaDecoder.h"
 #include "SharedThreadPool.h"
 #include "mozilla/Logging.h"
 
 namespace mozilla {
 
 extern PRLogModuleInfo* gMediaDecoderLog;
-#define DECODER_LOG(type, msg) PR_LOG(gMediaDecoderLog, type, msg)
+#define DECODER_LOG(type, msg) MOZ_LOG(gMediaDecoderLog, type, msg)
 
 NS_IMPL_ISUPPORTS(MediaShutdownManager, nsIObserver)
 
 MediaShutdownManager::MediaShutdownManager()
   : mIsObservingShutdown(false),
     mIsDoingXPCOMShutDown(false)
 {
   MOZ_ASSERT(NS_IsMainThread());
--- a/dom/media/MediaStreamGraph.cpp
+++ b/dom/media/MediaStreamGraph.cpp
@@ -37,17 +37,17 @@
 
 using namespace mozilla::layers;
 using namespace mozilla::dom;
 using namespace mozilla::gfx;
 
 namespace mozilla {
 
 PRLogModuleInfo* gMediaStreamGraphLog;
-#define STREAM_LOG(type, msg) PR_LOG(gMediaStreamGraphLog, type, msg)
+#define STREAM_LOG(type, msg) MOZ_LOG(gMediaStreamGraphLog, type, msg)
 
 // #define ENABLE_LIFECYCLE_LOG
 
 // We don't use NSPR log here because we want this interleaved with adb logcat
 // on Android/B2G
 #ifdef ENABLE_LIFECYCLE_LOG
 #  ifdef ANDROID
 #    include "android/log.h"
@@ -2518,17 +2518,17 @@ SourceMediaStream::ResampleAudioToGraphS
   // If this segment is just silence, we delay instanciating the resampler.
   if (channels) {
     if (aTrackData->mResampler) {
       MOZ_ASSERT(aTrackData->mResamplerChannelCount == segment->ChannelCount());
     } else {
       SpeexResamplerState* state = speex_resampler_init(channels,
                                                         aTrackData->mInputRate,
                                                         GraphImpl()->GraphRate(),
-                                                        SPEEX_RESAMPLER_QUALITY_DEFAULT,
+                                                        SPEEX_RESAMPLER_QUALITY_MIN,
                                                         nullptr);
       if (!state) {
         return;
       }
       aTrackData->mResampler.own(state);
 #ifdef DEBUG
       aTrackData->mResamplerChannelCount = channels;
 #endif
--- a/dom/media/MediaTimer.h
+++ b/dom/media/MediaTimer.h
@@ -18,17 +18,17 @@
 #include "mozilla/TimeStamp.h"
 
 namespace mozilla {
 
 extern PRLogModuleInfo* gMediaTimerLog;
 
 #define TIMER_LOG(x, ...) \
   MOZ_ASSERT(gMediaTimerLog); \
-  PR_LOG(gMediaTimerLog, PR_LOG_DEBUG, ("[MediaTimer=%p relative_t=%lld]" x, this, \
+  MOZ_LOG(gMediaTimerLog, PR_LOG_DEBUG, ("[MediaTimer=%p relative_t=%lld]" x, this, \
                                         RelativeMicroseconds(TimeStamp::Now()), ##__VA_ARGS__))
 
 // This promise type is only exclusive because so far there isn't a reason for
 // it not to be. Feel free to change that.
 typedef MediaPromise<bool, bool, /* IsExclusive = */ true> MediaTimerPromise;
 
 // Timers only know how to fire at a given thread, which creates an impedence
 // mismatch with code that operates with MediaTaskQueues. This class solves
--- a/dom/media/RtspMediaResource.cpp
+++ b/dom/media/RtspMediaResource.cpp
@@ -16,17 +16,17 @@
 #include "nsIStreamingProtocolService.h"
 #include "nsServiceManagerUtils.h"
 #ifdef NECKO_PROTOCOL_rtsp
 #include "mozilla/net/RtspChannelChild.h"
 #endif
 using namespace mozilla::net;
 
 PRLogModuleInfo* gRtspMediaResourceLog;
-#define RTSP_LOG(msg, ...) PR_LOG(gRtspMediaResourceLog, PR_LOG_DEBUG, \
+#define RTSP_LOG(msg, ...) MOZ_LOG(gRtspMediaResourceLog, PR_LOG_DEBUG, \
                                   (msg, ##__VA_ARGS__))
 // Debug logging macro with object pointer and class name.
 #define RTSPMLOG(msg, ...) \
         RTSP_LOG("%p [RtspMediaResource]: " msg, this, ##__VA_ARGS__)
 
 namespace mozilla {
 
 /* class RtspTrackBuffer: a ring buffer implementation for audio/video track
--- a/dom/media/StateMirroring.h
+++ b/dom/media/StateMirroring.h
@@ -45,17 +45,17 @@
 
 namespace mozilla {
 
 // Mirror<T> and Canonical<T> inherit WatchTarget, so we piggy-back on the
 // logging that WatchTarget already does. Given that, it makes sense to share
 // the same log module.
 #define MIRROR_LOG(x, ...) \
   MOZ_ASSERT(gStateWatchingLog); \
-  PR_LOG(gStateWatchingLog, PR_LOG_DEBUG, (x, ##__VA_ARGS__))
+  MOZ_LOG(gStateWatchingLog, PR_LOG_DEBUG, (x, ##__VA_ARGS__))
 
 template<typename T> class AbstractMirror;
 
 /*
  * AbstractCanonical is a superclass from which all Canonical values must
  * inherit. It serves as the interface of operations which may be performed (via
  * asynchronous dispatch) by other threads, in particular by the corresponding
  * Mirror value.
--- a/dom/media/StateWatching.h
+++ b/dom/media/StateWatching.h
@@ -55,17 +55,17 @@
  */
 
 namespace mozilla {
 
 extern PRLogModuleInfo* gStateWatchingLog;
 
 #define WATCH_LOG(x, ...) \
   MOZ_ASSERT(gStateWatchingLog); \
-  PR_LOG(gStateWatchingLog, PR_LOG_DEBUG, (x, ##__VA_ARGS__))
+  MOZ_LOG(gStateWatchingLog, PR_LOG_DEBUG, (x, ##__VA_ARGS__))
 
 /*
  * AbstractWatcher is a superclass from which all watchers must inherit.
  */
 class AbstractWatcher
 {
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AbstractWatcher)
--- a/dom/media/StreamBuffer.cpp
+++ b/dom/media/StreamBuffer.cpp
@@ -5,17 +5,17 @@
 
 #include "StreamBuffer.h"
 #include "mozilla/Logging.h"
 #include <algorithm>
 
 namespace mozilla {
 
 extern PRLogModuleInfo* gMediaStreamGraphLog;
-#define STREAM_LOG(type, msg) PR_LOG(gMediaStreamGraphLog, type, msg)
+#define STREAM_LOG(type, msg) MOZ_LOG(gMediaStreamGraphLog, type, msg)
 
 #ifdef DEBUG
 void
 StreamBuffer::DumpTrackInfo() const
 {
   STREAM_LOG(PR_LOG_ALWAYS, ("DumpTracks: mTracksKnownTime %lld", mTracksKnownTime));
   for (uint32_t i = 0; i < mTracks.Length(); ++i) {
     Track* track = mTracks[i];
--- a/dom/media/TrackUnionStream.cpp
+++ b/dom/media/TrackUnionStream.cpp
@@ -38,17 +38,17 @@ using namespace mozilla::gfx;
 
 namespace mozilla {
 
 #ifdef STREAM_LOG
 #undef STREAM_LOG
 #endif
 
 PRLogModuleInfo* gTrackUnionStreamLog;
-#define STREAM_LOG(type, msg) PR_LOG(gTrackUnionStreamLog, type, msg)
+#define STREAM_LOG(type, msg) MOZ_LOG(gTrackUnionStreamLog, type, msg)
 
 TrackUnionStream::TrackUnionStream(DOMMediaStream* aWrapper) :
   ProcessedMediaStream(aWrapper)
 {
   if (!gTrackUnionStreamLog) {
     gTrackUnionStreamLog = PR_NewLogModule("TrackUnionStream");
   }
 }
--- a/dom/media/WebVTTListener.cpp
+++ b/dom/media/WebVTTListener.cpp
@@ -24,17 +24,17 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebVTTListener)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(WebVTTListener)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(WebVTTListener)
 
 PRLogModuleInfo* gTextTrackLog;
-# define VTT_LOG(...) PR_LOG(gTextTrackLog, PR_LOG_DEBUG, (__VA_ARGS__))
+# define VTT_LOG(...) MOZ_LOG(gTextTrackLog, PR_LOG_DEBUG, (__VA_ARGS__))
 
 WebVTTListener::WebVTTListener(HTMLTrackElement* aElement)
   : mElement(aElement)
 {
   MOZ_ASSERT(mElement, "Must pass an element to the callback");
   if (!gTextTrackLog) {
     gTextTrackLog = PR_NewLogModule("TextTrack");
   }
--- a/dom/media/apple/AppleMP3Reader.cpp
+++ b/dom/media/apple/AppleMP3Reader.cpp
@@ -17,19 +17,19 @@
 // buffer we cannot use AudioCompactor without paying for an additional
 // allocation and copy.  Therefore, choosing a value that divides exactly into
 // 1152 is most memory efficient.
 #define MAX_AUDIO_FRAMES 128
 
 namespace mozilla {
 
 extern PRLogModuleInfo* gMediaDecoderLog;
-#define LOGE(...) PR_LOG(gMediaDecoderLog, PR_LOG_ERROR, (__VA_ARGS__))
-#define LOGW(...) PR_LOG(gMediaDecoderLog, PR_LOG_WARNING, (__VA_ARGS__))
-#define LOGD(...) PR_LOG(gMediaDecoderLog, PR_LOG_DEBUG, (__VA_ARGS__))
+#define LOGE(...) MOZ_LOG(gMediaDecoderLog, PR_LOG_ERROR, (__VA_ARGS__))
+#define LOGW(...) MOZ_LOG(gMediaDecoderLog, PR_LOG_WARNING, (__VA_ARGS__))
+#define LOGD(...) MOZ_LOG(gMediaDecoderLog, PR_LOG_DEBUG, (__VA_ARGS__))
 
 #define PROPERTY_ID_FORMAT "%c%c%c%c"
 #define PROPERTY_ID_PRINT(x) ((x) >> 24), \
                              ((x) >> 16) & 0xff, \
                              ((x) >> 8) & 0xff, \
                              (x) & 0xff
 
 AppleMP3Reader::AppleMP3Reader(AbstractMediaDecoder *aDecoder)
--- a/dom/media/directshow/AudioSinkFilter.cpp
+++ b/dom/media/directshow/AudioSinkFilter.cpp
@@ -19,17 +19,17 @@
 DEFINE_GUID(CLSID_MozAudioSinkFilter, 0x1872d8c8, 0xea8d, 0x4c34, 0xae, 0x96, 0x69, 0xde,
             0xf1, 0x33, 0x7b, 0x33);
 
 using namespace mozilla::media;
 
 namespace mozilla {
 
 PRLogModuleInfo* GetDirectShowLog();
-#define LOG(...) PR_LOG(GetDirectShowLog(), PR_LOG_DEBUG, (__VA_ARGS__))
+#define LOG(...) MOZ_LOG(GetDirectShowLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 
 AudioSinkFilter::AudioSinkFilter(const wchar_t* aObjectName, HRESULT* aOutResult)
   : BaseFilter(aObjectName, CLSID_MozAudioSinkFilter),
     mFilterCritSec("AudioSinkFilter::mFilterCritSec")
 {
   (*aOutResult) = S_OK;
   mInputPin = new AudioSinkInputPin(L"AudioSinkInputPin",
                                     this,
--- a/dom/media/directshow/AudioSinkInputPin.cpp
+++ b/dom/media/directshow/AudioSinkInputPin.cpp
@@ -11,17 +11,17 @@
 
 #include <wmsdkidl.h>
 
 using namespace mozilla::media;
 
 namespace mozilla {
 
 PRLogModuleInfo* GetDirectShowLog();
-#define LOG(...) PR_LOG(GetDirectShowLog(), PR_LOG_DEBUG, (__VA_ARGS__))
+#define LOG(...) MOZ_LOG(GetDirectShowLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 
 AudioSinkInputPin::AudioSinkInputPin(wchar_t* aObjectName,
                                      AudioSinkFilter* aFilter,
                                      mozilla::CriticalSection* aLock,
                                      HRESULT* aOutResult)
   : BaseInputPin(aObjectName, aFilter, aLock, aOutResult, aObjectName),
     mSegmentStartTime(0)
 {
@@ -134,17 +134,17 @@ AudioSinkInputPin::Receive(IMediaSample*
 TemporaryRef<IMediaSeeking>
 AudioSinkInputPin::GetConnectedPinSeeking()
 {
   RefPtr<IPin> peer = GetConnected();
   if (!peer)
     return nullptr;
   RefPtr<IMediaSeeking> seeking;
   peer->QueryInterface(static_cast<IMediaSeeking**>(byRef(seeking)));
-  return seeking;
+  return seeking.forget();
 }
 
 HRESULT
 AudioSinkInputPin::BeginFlush()
 {
   HRESULT hr = media::BaseInputPin::BeginFlush();
   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
 
--- a/dom/media/directshow/DirectShowReader.cpp
+++ b/dom/media/directshow/DirectShowReader.cpp
@@ -21,17 +21,17 @@ PRLogModuleInfo*
 GetDirectShowLog() {
   static PRLogModuleInfo* log = nullptr;
   if (!log) {
     log = PR_NewLogModule("DirectShowDecoder");
   }
   return log;
 }
 
-#define LOG(...) PR_LOG(GetDirectShowLog(), PR_LOG_DEBUG, (__VA_ARGS__))
+#define LOG(...) MOZ_LOG(GetDirectShowLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 
 DirectShowReader::DirectShowReader(AbstractMediaDecoder* aDecoder)
   : MediaDecoderReader(aDecoder),
     mMP3FrameParser(aDecoder->GetResource()->GetLength()),
 #ifdef DEBUG
     mRotRegister(0),
 #endif
     mNumChannels(0),
--- a/dom/media/directshow/DirectShowUtils.cpp
+++ b/dom/media/directshow/DirectShowUtils.cpp
@@ -293,17 +293,17 @@ GetUnconnectedPin(IBaseFilter* aFilter, 
   NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
 
   // Test each pin to see if it matches the direction we're looking for.
   RefPtr<IPin> pin;
   while (S_OK == enumPins->Next(1, byRef(pin), nullptr)) {
     bool matches = FALSE;
     if (SUCCEEDED(MatchUnconnectedPin(pin, aPinDir, &matches)) &&
         matches) {
-      return pin;
+      return pin.forget();
     }
   }
 
   return nullptr;
 }
 
 HRESULT
 ConnectFilters(IGraphBuilder* aGraph,
--- a/dom/media/directshow/SampleSink.cpp
+++ b/dom/media/directshow/SampleSink.cpp
@@ -10,17 +10,17 @@
 #include "VideoUtils.h"
 #include "mozilla/Logging.h"
 
 using namespace mozilla::media;
 
 namespace mozilla {
 
 PRLogModuleInfo* GetDirectShowLog();
-#define LOG(...) PR_LOG(GetDirectShowLog(), PR_LOG_DEBUG, (__VA_ARGS__))
+#define LOG(...) MOZ_LOG(GetDirectShowLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 
 SampleSink::SampleSink()
   : mMonitor("SampleSink"),
     mIsFlushing(false),
     mAtEOS(false)
 {
   MOZ_COUNT_CTOR(SampleSink);
 }
--- a/dom/media/directshow/SourceFilter.cpp
+++ b/dom/media/directshow/SourceFilter.cpp
@@ -16,17 +16,17 @@ using namespace mozilla::media;
 
 namespace mozilla {
 
 // Define to trace what's on...
 //#define DEBUG_SOURCE_TRACE 1
 
 #if defined (DEBUG_SOURCE_TRACE)
 PRLogModuleInfo* GetDirectShowLog();
-#define DIRECTSHOW_LOG(...) PR_LOG(GetDirectShowLog(), PR_LOG_DEBUG, (__VA_ARGS__))
+#define DIRECTSHOW_LOG(...) MOZ_LOG(GetDirectShowLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 #else
 #define DIRECTSHOW_LOG(...)
 #endif
 
 static HRESULT
 DoGetInterface(IUnknown* aUnknown, void** aInterface)
 {
   if (!aInterface)
--- a/dom/media/eme/EMEUtils.h
+++ b/dom/media/eme/EMEUtils.h
@@ -9,23 +9,23 @@
 
 #include "mozilla/Logging.h"
 #include "nsString.h"
 
 namespace mozilla {
 
 #ifndef EME_LOG
   PRLogModuleInfo* GetEMELog();
-  #define EME_LOG(...) PR_LOG(GetEMELog(), PR_LOG_DEBUG, (__VA_ARGS__))
+  #define EME_LOG(...) MOZ_LOG(GetEMELog(), PR_LOG_DEBUG, (__VA_ARGS__))
   #define EME_LOG_ENABLED() PR_LOG_TEST(GetEMELog(), PR_LOG_DEBUG)
 #endif
 
 #ifndef EME_VERBOSE_LOG
   PRLogModuleInfo* GetEMEVerboseLog();
-  #define EME_VERBOSE_LOG(...) PR_LOG(GetEMEVerboseLog(), PR_LOG_DEBUG, (__VA_ARGS__))
+  #define EME_VERBOSE_LOG(...) MOZ_LOG(GetEMEVerboseLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 #else
   #ifndef EME_LOG
     #define EME_LOG(...)
   #endif
 
   #ifndef EME_VERBOSE_LOG
     #define EME_VERBOSE_LOG(...)
   #endif
--- a/dom/media/encoder/MediaEncoder.cpp
+++ b/dom/media/encoder/MediaEncoder.cpp
@@ -27,17 +27,17 @@
 #include "ISOMediaWriter.h"
 #endif
 
 #ifdef LOG
 #undef LOG
 #endif
 
 PRLogModuleInfo* gMediaEncoderLog;
-#define LOG(type, msg) PR_LOG(gMediaEncoderLog, type, msg)
+#define LOG(type, msg) MOZ_LOG(gMediaEncoderLog, type, msg)
 
 namespace mozilla {
 
 void
 MediaEncoder::NotifyQueuedTrackChanges(MediaStreamGraph* aGraph,
                                        TrackID aID,
                                        StreamTime aTrackOffset,
                                        uint32_t aTrackEvents,
--- a/dom/media/encoder/TrackEncoder.cpp
+++ b/dom/media/encoder/TrackEncoder.cpp
@@ -14,17 +14,17 @@
 #define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "MediaEncoder", ## args);
 #else
 #define LOG(args, ...)
 #endif
 
 namespace mozilla {
 
 PRLogModuleInfo* gTrackEncoderLog;
-#define TRACK_LOG(type, msg) PR_LOG(gTrackEncoderLog, type, msg)
+#define TRACK_LOG(type, msg) MOZ_LOG(gTrackEncoderLog, type, msg)
 
 static const int DEFAULT_CHANNELS = 1;
 static const int DEFAULT_SAMPLING_RATE = 16000;
 static const int DEFAULT_FRAME_WIDTH = 640;
 static const int DEFAULT_FRAME_HEIGHT = 480;
 static const int DEFAULT_TRACK_RATE = USECS_PER_S;
 
 TrackEncoder::TrackEncoder()
--- a/dom/media/encoder/VP8TrackEncoder.cpp
+++ b/dom/media/encoder/VP8TrackEncoder.cpp
@@ -11,17 +11,17 @@
 #include "prsystem.h"
 #include "WebMWriter.h"
 #include "libyuv.h"
 #include "GeckoProfiler.h"
 
 namespace mozilla {
 
 PRLogModuleInfo* gVP8TrackEncoderLog;
-#define VP8LOG(msg, ...) PR_LOG(gVP8TrackEncoderLog, PR_LOG_DEBUG, \
+#define VP8LOG(msg, ...) MOZ_LOG(gVP8TrackEncoderLog, PR_LOG_DEBUG, \
                                   (msg, ##__VA_ARGS__))
 // Debug logging macro with object pointer and class name.
 
 #define DEFAULT_BITRATE 2500 // in kbit/s
 #define DEFAULT_ENCODE_FRAMERATE 30
 
 using namespace mozilla::layers;
 
--- a/dom/media/encoder/VorbisTrackEncoder.cpp
+++ b/dom/media/encoder/VorbisTrackEncoder.cpp
@@ -13,17 +13,17 @@
 // Example quality mode .4: 44kHz stereo coupled, roughly 128kbps VBR
 // ret = vorbis_encode_init_vbr(&vi,2,44100,.4);
 static const float BASE_QUALITY = 0.4f;
 
 namespace mozilla {
 
 #undef LOG
 PRLogModuleInfo* gVorbisTrackEncoderLog;
-#define VORBISLOG(msg, ...) PR_LOG(gVorbisTrackEncoderLog, PR_LOG_DEBUG, \
+#define VORBISLOG(msg, ...) MOZ_LOG(gVorbisTrackEncoderLog, PR_LOG_DEBUG, \
                              (msg, ##__VA_ARGS__))
 
 VorbisTrackEncoder::VorbisTrackEncoder()
   : AudioTrackEncoder()
 {
   MOZ_COUNT_CTOR(VorbisTrackEncoder);
   if (!gVorbisTrackEncoderLog) {
     gVorbisTrackEncoderLog = PR_NewLogModule("VorbisTrackEncoder");
--- a/dom/media/fmp4/MP4Reader.cpp
+++ b/dom/media/fmp4/MP4Reader.cpp
@@ -35,18 +35,18 @@ using mozilla::layers::LayersBackend;
 
 PRLogModuleInfo* GetDemuxerLog() {
   static PRLogModuleInfo* log = nullptr;
   if (!log) {
     log = PR_NewLogModule("MP4Demuxer");
   }
   return log;
 }
-#define LOG(arg, ...) PR_LOG(GetDemuxerLog(), PR_LOG_DEBUG, ("MP4Reader(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
-#define VLOG(arg, ...) PR_LOG(GetDemuxerLog(), PR_LOG_DEBUG, ("MP4Reader(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
+#define LOG(arg, ...) MOZ_LOG(GetDemuxerLog(), PR_LOG_DEBUG, ("MP4Reader(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
+#define VLOG(arg, ...) MOZ_LOG(GetDemuxerLog(), PR_LOG_DEBUG, ("MP4Reader(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
 
 using namespace mp4_demuxer;
 
 namespace mozilla {
 
 // Uncomment to enable verbose per-sample logging.
 //#define LOG_SAMPLE_DECODE 1
 
--- a/dom/media/gmp/GMPAudioDecoderParent.cpp
+++ b/dom/media/gmp/GMPAudioDecoderParent.cpp
@@ -14,18 +14,18 @@
 namespace mozilla {
 
 #ifdef LOG
 #undef LOG
 #endif
 
 extern PRLogModuleInfo* GetGMPLog();
 
-#define LOGD(msg) PR_LOG(GetGMPLog(), PR_LOG_DEBUG, msg)
-#define LOG(level, msg) PR_LOG(GetGMPLog(), (level), msg)
+#define LOGD(msg) MOZ_LOG(GetGMPLog(), PR_LOG_DEBUG, msg)
+#define LOG(level, msg) MOZ_LOG(GetGMPLog(), (level), msg)
 
 namespace gmp {
 
 GMPAudioDecoderParent::GMPAudioDecoderParent(GMPContentParent* aPlugin)
   : mIsOpen(false)
   , mShuttingDown(false)
   , mActorDestroyed(false)
   , mPlugin(aPlugin)
--- a/dom/media/gmp/GMPChild.cpp
+++ b/dom/media/gmp/GMPChild.cpp
@@ -41,17 +41,17 @@ static const int MAX_VOUCHER_LENGTH = 50
 #endif
 
 namespace mozilla {
 
 #undef LOG
 #undef LOGD
 
 extern PRLogModuleInfo* GetGMPLog();
-#define LOG(level, x, ...) PR_LOG(GetGMPLog(), (level), (x, ##__VA_ARGS__))
+#define LOG(level, x, ...) MOZ_LOG(GetGMPLog(), (level), (x, ##__VA_ARGS__))
 #define LOGD(x, ...) LOG(PR_LOG_DEBUG, "GMPChild[pid=%d] " x, (int)base::GetCurrentProcId(), ##__VA_ARGS__)
 
 namespace gmp {
 
 GMPChild::GMPChild()
   : mAsyncShutdown(nullptr)
   , mGMPMessageLoop(MessageLoop::current())
   , mGMPLoader(nullptr)
--- a/dom/media/gmp/GMPContentParent.cpp
+++ b/dom/media/gmp/GMPContentParent.cpp
@@ -16,18 +16,18 @@
 namespace mozilla {
 
 #ifdef LOG
 #undef LOG
 #endif
 
 extern PRLogModuleInfo* GetGMPLog();
 
-#define LOGD(msg) PR_LOG(GetGMPLog(), PR_LOG_DEBUG, msg)
-#define LOG(level, msg) PR_LOG(GetGMPLog(), (level), msg)
+#define LOGD(msg) MOZ_LOG(GetGMPLog(), PR_LOG_DEBUG, msg)
+#define LOG(level, msg) MOZ_LOG(GetGMPLog(), (level), msg)
 
 #ifdef __CLASS__
 #undef __CLASS__
 #endif
 #define __CLASS__ "GMPContentParent"
 
 namespace gmp {
 
--- a/dom/media/gmp/GMPParent.cpp
+++ b/dom/media/gmp/GMPParent.cpp
@@ -37,17 +37,17 @@ using CrashReporter::GetIDFromMinidump;
 #include "mozilla/Telemetry.h"
 
 namespace mozilla {
 
 #undef LOG
 #undef LOGD
 
 extern PRLogModuleInfo* GetGMPLog();
-#define LOG(level, x, ...) PR_LOG(GetGMPLog(), (level), (x, ##__VA_ARGS__))
+#define LOG(level, x, ...) MOZ_LOG(GetGMPLog(), (level), (x, ##__VA_ARGS__))
 #define LOGD(x, ...) LOG(PR_LOG_DEBUG, "GMPParent[%p|childPid=%d] " x, this, mChildPid, ##__VA_ARGS__)
 
 namespace gmp {
 
 GMPParent::GMPParent()
   : mState(GMPStateNotLoaded)
   , mProcess(nullptr)
   , mDeleteProcessOnlyOnUnload(false)
--- a/dom/media/gmp/GMPService.cpp
+++ b/dom/media/gmp/GMPService.cpp
@@ -45,18 +45,18 @@ PRLogModuleInfo*
 GetGMPLog()
 {
   static PRLogModuleInfo *sLog;
   if (!sLog)
     sLog = PR_NewLogModule("GMP");
   return sLog;
 }
 
-#define LOGD(msg) PR_LOG(GetGMPLog(), PR_LOG_DEBUG, msg)
-#define LOG(level, msg) PR_LOG(GetGMPLog(), (level), msg)
+#define LOGD(msg) MOZ_LOG(GetGMPLog(), PR_LOG_DEBUG, msg)
+#define LOG(level, msg) MOZ_LOG(GetGMPLog(), (level), msg)
 
 #ifdef __CLASS__
 #undef __CLASS__
 #endif
 #define __CLASS__ "GMPService"
 
 namespace gmp {
 
--- a/dom/media/gmp/GMPServiceChild.cpp
+++ b/dom/media/gmp/GMPServiceChild.cpp
@@ -7,18 +7,18 @@
 #include "mozilla/dom/ContentChild.h"
 
 namespace mozilla {
 
 #ifdef LOG
 #undef LOG
 #endif
 
-#define LOGD(msg) PR_LOG(GetGMPLog(), PR_LOG_DEBUG, msg)
-#define LOG(level, msg) PR_LOG(GetGMPLog(), (level), msg)
+#define LOGD(msg) MOZ_LOG(GetGMPLog(), PR_LOG_DEBUG, msg)
+#define LOG(level, msg) MOZ_LOG(GetGMPLog(), (level), msg)
 
 #ifdef __CLASS__
 #undef __CLASS__
 #endif
 #define __CLASS__ "GMPService"
 
 namespace gmp {
 
--- a/dom/media/gmp/GMPServiceParent.cpp
+++ b/dom/media/gmp/GMPServiceParent.cpp
@@ -35,18 +35,18 @@
 #include "nsISimpleEnumerator.h"
 
 namespace mozilla {
 
 #ifdef LOG
 #undef LOG
 #endif
 
-#define LOGD(msg) PR_LOG(GetGMPLog(), PR_LOG_DEBUG, msg)
-#define LOG(level, msg) PR_LOG(GetGMPLog(), (level), msg)
+#define LOGD(msg) MOZ_LOG(GetGMPLog(), PR_LOG_DEBUG, msg)
+#define LOG(level, msg) MOZ_LOG(GetGMPLog(), (level), msg)
 
 #ifdef __CLASS__
 #undef __CLASS__
 #endif
 #define __CLASS__ "GMPService"
 
 namespace gmp {
 
--- a/dom/media/gmp/GMPStorageParent.cpp
+++ b/dom/media/gmp/GMPStorageParent.cpp
@@ -23,18 +23,18 @@
 namespace mozilla {
 
 #ifdef LOG
 #undef LOG
 #endif
 
 extern PRLogModuleInfo* GetGMPLog();
 
-#define LOGD(msg) PR_LOG(GetGMPLog(), PR_LOG_DEBUG, msg)
-#define LOG(level, msg) PR_LOG(GetGMPLog(), (level), msg)
+#define LOGD(msg) MOZ_LOG(GetGMPLog(), PR_LOG_DEBUG, msg)
+#define LOG(level, msg) MOZ_LOG(GetGMPLog(), (level), msg)
 
 #ifdef __CLASS__
 #undef __CLASS__
 #endif
 #define __CLASS__ "GMPStorageParent"
 
 namespace gmp {
 
--- a/dom/media/gmp/GMPTimerParent.cpp
+++ b/dom/media/gmp/GMPTimerParent.cpp
@@ -10,18 +10,18 @@
 namespace mozilla {
 
 #ifdef LOG
 #undef LOG
 #endif
 
 extern PRLogModuleInfo* GetGMPLog();
 
-#define LOGD(msg) PR_LOG(GetGMPLog(), PR_LOG_DEBUG, msg)
-#define LOG(level, msg) PR_LOG(GetGMPLog(), (level), msg)
+#define LOGD(msg) MOZ_LOG(GetGMPLog(), PR_LOG_DEBUG, msg)
+#define LOG(level, msg) MOZ_LOG(GetGMPLog(), (level), msg)
 
 #ifdef __CLASS__
 #undef __CLASS__
 #endif
 #define __CLASS__ "GMPParent"
 
 namespace gmp {
 
--- a/dom/media/gmp/GMPVideoDecoderParent.cpp
+++ b/dom/media/gmp/GMPVideoDecoderParent.cpp
@@ -18,18 +18,18 @@
 namespace mozilla {
 
 #ifdef LOG
 #undef LOG
 #endif
 
 extern PRLogModuleInfo* GetGMPLog();
 
-#define LOGD(msg) PR_LOG(GetGMPLog(), PR_LOG_DEBUG, msg)
-#define LOG(level, msg) PR_LOG(GetGMPLog(), (level), msg)
+#define LOGD(msg) MOZ_LOG(GetGMPLog(), PR_LOG_DEBUG, msg)
+#define LOG(level, msg) MOZ_LOG(GetGMPLog(), (level), msg)
 
 namespace gmp {
 
 // States:
 // Initial: mIsOpen == false
 //    on InitDecode success -> Open
 //    on Shutdown -> Dead
 // Open: mIsOpen == true
--- a/dom/media/gmp/GMPVideoEncoderParent.cpp
+++ b/dom/media/gmp/GMPVideoEncoderParent.cpp
@@ -20,18 +20,18 @@
 namespace mozilla {
 
 #ifdef LOG
 #undef LOG
 #endif
 
 extern PRLogModuleInfo* GetGMPLog();
 
-#define LOGD(msg) PR_LOG(GetGMPLog(), PR_LOG_DEBUG, msg)
-#define LOG(level, msg) PR_LOG(GetGMPLog(), (level), msg)
+#define LOGD(msg) MOZ_LOG(GetGMPLog(), PR_LOG_DEBUG, msg)
+#define LOG(level, msg) MOZ_LOG(GetGMPLog(), (level), msg)
 
 #ifdef __CLASS__
 #undef __CLASS__
 #endif
 #define __CLASS__ "GMPVideoEncoderParent"
 
 namespace gmp {
 
--- a/dom/media/gstreamer/GStreamerReader.cpp
+++ b/dom/media/gstreamer/GStreamerReader.cpp
@@ -26,17 +26,17 @@ namespace mozilla {
 using namespace gfx;
 using namespace layers;
 
 // Un-comment to enable logging of seek bisections.
 //#define SEEK_LOGGING
 
 extern PRLogModuleInfo* gMediaDecoderLog;
 #define LOG(type, msg, ...) \
-  PR_LOG(gMediaDecoderLog, type, ("GStreamerReader(%p) " msg, this, ##__VA_ARGS__))
+  MOZ_LOG(gMediaDecoderLog, type, ("GStreamerReader(%p) " msg, this, ##__VA_ARGS__))
 
 #if DEBUG
 static const unsigned int MAX_CHANNELS = 4;
 #endif
 // Let the demuxer work in pull mode for short files. This used to be a micro
 // optimization to have more accurate durations for ogg files in mochitests.
 // Since as of today we aren't using gstreamer to demux ogg, and having demuxers
 // work in pull mode over http makes them slower (since they really assume
--- a/dom/media/imagecapture/ImageCapture.h
+++ b/dom/media/imagecapture/ImageCapture.h
@@ -10,17 +10,17 @@
 #include "mozilla/DOMEventTargetHelper.h"
 #include "mozilla/dom/ImageCaptureBinding.h"
 #include "mozilla/Logging.h"
 
 namespace mozilla {
 
 #ifndef IC_LOG
 PRLogModuleInfo* GetICLog();
-#define IC_LOG(...) PR_LOG(GetICLog(), PR_LOG_DEBUG, (__VA_ARGS__))
+#define IC_LOG(...) MOZ_LOG(GetICLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 #endif
 
 namespace dom {
 
 class Blob;
 class VideoStreamTrack;
 
 /**
--- a/dom/media/mediasource/ContainerParser.cpp
+++ b/dom/media/mediasource/ContainerParser.cpp
@@ -20,17 +20,17 @@ extern PRLogModuleInfo* GetMediaSourceLo
 
 /* Polyfill __func__ on MSVC to pass to the log. */
 #ifdef _MSC_VER
 #define __func__ __FUNCTION__
 #endif
 
 #define STRINGIFY(x) #x
 #define TOSTRING(x) STRINGIFY(x)
-#define MSE_DEBUG(name, arg, ...) PR_LOG(GetMediaSourceLog(), PR_LOG_DEBUG, (TOSTRING(name) "(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
+#define MSE_DEBUG(name, arg, ...) MOZ_LOG(GetMediaSourceLog(), PR_LOG_DEBUG, (TOSTRING(name) "(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
 
 namespace mozilla {
 
 ContainerParser::ContainerParser(const nsACString& aType)
   : mHasInitData(false)
   , mType(aType)
 {
 }
--- a/dom/media/mediasource/MediaSource.cpp
+++ b/dom/media/mediasource/MediaSource.cpp
@@ -52,18 +52,18 @@ PRLogModuleInfo* GetMediaSourceAPILog()
 {
   static PRLogModuleInfo* sLogModule;
   if (!sLogModule) {
     sLogModule = PR_NewLogModule("MediaSource");
   }
   return sLogModule;
 }
 
-#define MSE_DEBUG(arg, ...) PR_LOG(GetMediaSourceLog(), PR_LOG_DEBUG, ("MediaSource(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
-#define MSE_API(arg, ...) PR_LOG(GetMediaSourceAPILog(), PR_LOG_DEBUG, ("MediaSource(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
+#define MSE_DEBUG(arg, ...) MOZ_LOG(GetMediaSourceLog(), PR_LOG_DEBUG, ("MediaSource(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
+#define MSE_API(arg, ...) MOZ_LOG(GetMediaSourceAPILog(), PR_LOG_DEBUG, ("MediaSource(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
 
 // Arbitrary limit.
 static const unsigned int MAX_SOURCE_BUFFERS = 16;
 
 namespace mozilla {
 
 static const char* const gMediaSourceTypes[6] = {
   "video/mp4",
--- a/dom/media/mediasource/MediaSourceDecoder.cpp
+++ b/dom/media/mediasource/MediaSourceDecoder.cpp
@@ -12,18 +12,18 @@
 #include "MediaSourceReader.h"
 #include "MediaSourceResource.h"
 #include "MediaSourceUtils.h"
 #include "SourceBufferDecoder.h"
 #include "VideoUtils.h"
 
 extern PRLogModuleInfo* GetMediaSourceLog();
 
-#define MSE_DEBUG(arg, ...) PR_LOG(GetMediaSourceLog(), PR_LOG_DEBUG, ("MediaSourceDecoder(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
-#define MSE_DEBUGV(arg, ...) PR_LOG(GetMediaSourceLog(), PR_LOG_DEBUG + 1, ("MediaSourceDecoder(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
+#define MSE_DEBUG(arg, ...) MOZ_LOG(GetMediaSourceLog(), PR_LOG_DEBUG, ("MediaSourceDecoder(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
+#define MSE_DEBUGV(arg, ...) MOZ_LOG(GetMediaSourceLog(), PR_LOG_DEBUG + 1, ("MediaSourceDecoder(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
 
 namespace mozilla {
 
 class SourceBufferDecoder;
 
 MediaSourceDecoder::MediaSourceDecoder(dom::HTMLMediaElement* aElement)
   : mMediaSource(nullptr)
   , mMediaSourceDuration(UnspecifiedNaN<double>())
--- a/dom/media/mediasource/MediaSourceReader.cpp
+++ b/dom/media/mediasource/MediaSourceReader.cpp
@@ -20,18 +20,18 @@
 #include "SharedDecoderManager.h"
 #include "MP4Decoder.h"
 #include "MP4Demuxer.h"
 #include "MP4Reader.h"
 #endif
 
 extern PRLogModuleInfo* GetMediaSourceLog();
 
-#define MSE_DEBUG(arg, ...) PR_LOG(GetMediaSourceLog(), PR_LOG_DEBUG, ("MediaSourceReader(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
-#define MSE_DEBUGV(arg, ...) PR_LOG(GetMediaSourceLog(), PR_LOG_DEBUG + 1, ("MediaSourceReader(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
+#define MSE_DEBUG(arg, ...) MOZ_LOG(GetMediaSourceLog(), PR_LOG_DEBUG, ("MediaSourceReader(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
+#define MSE_DEBUGV(arg, ...) MOZ_LOG(GetMediaSourceLog(), PR_LOG_DEBUG + 1, ("MediaSourceReader(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
 
 // When a stream hits EOS it needs to decide what other stream to switch to. Due
 // to inaccuracies is determining buffer end frames (Bug 1065207) and rounding
 // issues we use a fuzz factor to determine the end time of this stream for
 // switching to the new stream. This value is based on the end of frame
 // default value used in Blink, kDefaultBufferDurationInMs.
 #define EOS_FUZZ_US 125000
 
--- a/dom/media/mediasource/MediaSourceResource.h
+++ b/dom/media/mediasource/MediaSourceResource.h
@@ -8,17 +8,17 @@
 #define MOZILLA_MEDIASOURCERESOURCE_H_
 
 #include "MediaResource.h"
 #include "mozilla/Monitor.h"
 #include "mozilla/Logging.h"
 
 extern PRLogModuleInfo* GetMediaSourceLog();
 
-#define MSE_DEBUG(arg, ...) PR_LOG(GetMediaSourceLog(), PR_LOG_DEBUG, ("MediaSourceResource(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
+#define MSE_DEBUG(arg, ...) MOZ_LOG(GetMediaSourceLog(), PR_LOG_DEBUG, ("MediaSourceResource(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
 
 #define UNIMPLEMENTED() MSE_DEBUG("UNIMPLEMENTED FUNCTION at %s:%d", __FILE__, __LINE__)
 
 namespace mozilla {
 
 class MediaSourceResource final : public MediaResource
 {
 public:
--- a/dom/media/mediasource/ResourceQueue.cpp
+++ b/dom/media/mediasource/ResourceQueue.cpp
@@ -10,18 +10,18 @@
 
 extern PRLogModuleInfo* GetSourceBufferResourceLog();
 
 /* Polyfill __func__ on MSVC to pass to the log. */
 #ifdef _MSC_VER
 #define __func__ __FUNCTION__
 #endif
 
-#define SBR_DEBUG(arg, ...) PR_LOG(GetSourceBufferResourceLog(), PR_LOG_DEBUG, ("ResourceQueue(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
-#define SBR_DEBUGV(arg, ...) PR_LOG(GetSourceBufferResourceLog(), PR_LOG_DEBUG+1, ("ResourceQueue(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
+#define SBR_DEBUG(arg, ...) MOZ_LOG(GetSourceBufferResourceLog(), PR_LOG_DEBUG, ("ResourceQueue(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
+#define SBR_DEBUGV(arg, ...) MOZ_LOG(GetSourceBufferResourceLog(), PR_LOG_DEBUG+1, ("ResourceQueue(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
 
 namespace mozilla {
 
 ResourceItem::ResourceItem(MediaLargeByteBuffer* aData)
   : mData(aData)
 {
 }
 
--- a/dom/media/mediasource/SourceBuffer.cpp
+++ b/dom/media/mediasource/SourceBuffer.cpp
@@ -24,19 +24,19 @@
 #include "TimeUnits.h"
 
 struct JSContext;
 class JSObject;
 
 extern PRLogModuleInfo* GetMediaSourceLog();
 extern PRLogModuleInfo* GetMediaSourceAPILog();
 
-#define MSE_DEBUG(arg, ...) PR_LOG(GetMediaSourceLog(), PR_LOG_DEBUG, ("SourceBuffer(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
-#define MSE_DEBUGV(arg, ...) PR_LOG(GetMediaSourceLog(), PR_LOG_DEBUG + 1, ("SourceBuffer(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
-#define MSE_API(arg, ...) PR_LOG(GetMediaSourceAPILog(), PR_LOG_DEBUG, ("SourceBuffer(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
+#define MSE_DEBUG(arg, ...) MOZ_LOG(GetMediaSourceLog(), PR_LOG_DEBUG, ("SourceBuffer(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
+#define MSE_DEBUGV(arg, ...) MOZ_LOG(GetMediaSourceLog(), PR_LOG_DEBUG + 1, ("SourceBuffer(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
+#define MSE_API(arg, ...) MOZ_LOG(GetMediaSourceAPILog(), PR_LOG_DEBUG, ("SourceBuffer(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
 
 namespace mozilla {
 
 namespace dom {
 
 class AppendDataRunnable : public nsRunnable {
 public:
   AppendDataRunnable(SourceBuffer* aSourceBuffer,
--- a/dom/media/mediasource/SourceBufferDecoder.cpp
+++ b/dom/media/mediasource/SourceBufferDecoder.cpp
@@ -11,17 +11,17 @@
 #include "MediaDecoderReader.h"
 
 extern PRLogModuleInfo* GetMediaSourceLog();
 /* Polyfill __func__ on MSVC to pass to the log. */
 #ifdef _MSC_VER
 #define __func__ __FUNCTION__
 #endif
 
-#define MSE_DEBUG(arg, ...) PR_LOG(GetMediaSourceLog(), PR_LOG_DEBUG, ("SourceBufferDecoder(%p:%s)::%s: " arg, this, mResource->GetContentType().get(), __func__, ##__VA_ARGS__))
+#define MSE_DEBUG(arg, ...) MOZ_LOG(GetMediaSourceLog(), PR_LOG_DEBUG, ("SourceBufferDecoder(%p:%s)::%s: " arg, this, mResource->GetContentType().get(), __func__, ##__VA_ARGS__))
 
 namespace mozilla {
 
 class ReentrantMonitor;
 
 namespace layers {
 
 class ImageContainer;
--- a/dom/media/mediasource/SourceBufferList.cpp
+++ b/dom/media/mediasource/SourceBufferList.cpp
@@ -14,18 +14,18 @@
 #include "nsIRunnable.h"
 #include "nsString.h"
 #include "nsThreadUtils.h"
 #include "mozilla/Logging.h"
 
 extern PRLogModuleInfo* GetMediaSourceLog();
 extern PRLogModuleInfo* GetMediaSourceAPILog();
 
-#define MSE_API(arg, ...) PR_LOG(GetMediaSourceAPILog(), PR_LOG_DEBUG, ("SourceBufferList(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
-#define MSE_DEBUG(arg, ...) PR_LOG(GetMediaSourceLog(), PR_LOG_DEBUG, ("SourceBufferList(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
+#define MSE_API(arg, ...) MOZ_LOG(GetMediaSourceAPILog(), PR_LOG_DEBUG, ("SourceBufferList(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
+#define MSE_DEBUG(arg, ...) MOZ_LOG(GetMediaSourceLog(), PR_LOG_DEBUG, ("SourceBufferList(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
 
 struct JSContext;
 class JSObject;
 
 namespace mozilla {
 
 namespace dom {
 
--- a/dom/media/mediasource/SourceBufferResource.cpp
+++ b/dom/media/mediasource/SourceBufferResource.cpp
@@ -17,18 +17,18 @@ PRLogModuleInfo* GetSourceBufferResource
 {
   static PRLogModuleInfo* sLogModule;
   if (!sLogModule) {
     sLogModule = PR_NewLogModule("SourceBufferResource");
   }
   return sLogModule;
 }
 
-#define SBR_DEBUG(arg, ...) PR_LOG(GetSourceBufferResourceLog(), PR_LOG_DEBUG, ("SourceBufferResource(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
-#define SBR_DEBUGV(arg, ...) PR_LOG(GetSourceBufferResourceLog(), PR_LOG_DEBUG+1, ("SourceBufferResource(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
+#define SBR_DEBUG(arg, ...) MOZ_LOG(GetSourceBufferResourceLog(), PR_LOG_DEBUG, ("SourceBufferResource(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
+#define SBR_DEBUGV(arg, ...) MOZ_LOG(GetSourceBufferResourceLog(), PR_LOG_DEBUG+1, ("SourceBufferResource(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
 
 namespace mozilla {
 
 nsresult
 SourceBufferResource::Close()
 {
   ReentrantMonitorAutoEnter mon(mMonitor);
   SBR_DEBUG("Close");
--- a/dom/media/mediasource/TrackBuffer.cpp
+++ b/dom/media/mediasource/TrackBuffer.cpp
@@ -19,17 +19,17 @@
 #include "mozilla/TypeTraits.h"
 #include "nsError.h"
 #include "nsIRunnable.h"
 #include "nsThreadUtils.h"
 #include "mozilla/Logging.h"
 
 extern PRLogModuleInfo* GetMediaSourceLog();
 
-#define MSE_DEBUG(arg, ...) PR_LOG(GetMediaSourceLog(), PR_LOG_DEBUG, ("TrackBuffer(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
+#define MSE_DEBUG(arg, ...) MOZ_LOG(GetMediaSourceLog(), PR_LOG_DEBUG, ("TrackBuffer(%p:%s)::%s: " arg, this, mType.get(), __func__, ##__VA_ARGS__))
 
 // Time in seconds to substract from the current time when deciding the
 // time point to evict data before in a decoder. This is used to help
 // prevent evicting the current playback point.
 #define MSE_EVICT_THRESHOLD_TIME 2.0
 
 // Time in microsecond under which a timestamp will be considered to be 0.
 #define FUZZ_TIMESTAMP_OFFSET 100000
@@ -546,17 +546,17 @@ TrackBuffer::QueueInitializeDecoder(Sour
   // to aDecoder.
   static_assert(mozilla::IsBaseOf<nsISupports, SourceBufferDecoder>::value,
                 "SourceBufferDecoder must be inheriting from nsISupports");
   RefPtr<nsIRunnable> task =
     NS_NewRunnableMethodWithArg<SourceBufferDecoder*>(this,
                                                       &TrackBuffer::InitializeDecoder,
                                                       aDecoder);
   // We need to initialize the reader on its own task queue
-  aDecoder->GetReader()->GetTaskQueue()->Dispatch(task);
+  aDecoder->GetReader()->GetTaskQueue()->Dispatch(task.forget());
   return true;
 }
 
 // MetadataRecipient is a is used to pass extra values required by the
 // MetadataPromise's target methods
 class MetadataRecipient {
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MetadataRecipient);
@@ -1036,17 +1036,17 @@ TrackBuffer::RemoveDecoder(SourceBufferD
   {
     ReentrantMonitorAutoEnter mon(mParentDecoder->GetReentrantMonitor());
     // There should be no other references to the decoder. Assert that
     // we aren't using it in the MediaSourceReader.
     MOZ_ASSERT(!mParentDecoder->IsActiveReader(aDecoder->GetReader()));
     mInitializedDecoders.RemoveElement(aDecoder);
     mDecoders.RemoveElement(aDecoder);
   }
-  aDecoder->GetReader()->GetTaskQueue()->Dispatch(task);
+  aDecoder->GetReader()->GetTaskQueue()->Dispatch(task.forget());
 }
 
 bool
 TrackBuffer::RangeRemoval(media::TimeUnit aStart,
                           media::TimeUnit aEnd)
 {
   MOZ_ASSERT(NS_IsMainThread());
   ReentrantMonitorAutoEnter mon(mParentDecoder->GetReentrantMonitor());
--- a/dom/media/ogg/OggCodecState.cpp
+++ b/dom/media/ogg/OggCodecState.cpp
@@ -28,17 +28,17 @@
 #ifdef version_minor
 #undef version_minor
 #endif
 #endif
 
 namespace mozilla {
 
 extern PRLogModuleInfo* gMediaDecoderLog;
-#define LOG(type, msg) PR_LOG(gMediaDecoderLog, type, msg)
+#define LOG(type, msg) MOZ_LOG(gMediaDecoderLog, type, msg)
 
 /** Decoder base class for Ogg-encapsulated streams. */
 OggCodecState*
 OggCodecState::Create(ogg_page* aPage)
 {
   NS_ASSERTION(ogg_page_bos(aPage), "Only call on BOS page!");
   nsAutoPtr<OggCodecState> codecState;
   if (aPage->body_len > 6 && memcmp(aPage->body+1, "theora", 6) == 0) {
--- a/dom/media/ogg/OggReader.cpp
+++ b/dom/media/ogg/OggReader.cpp
@@ -32,19 +32,19 @@ namespace mozilla {
 #ifdef MOZ_WIDGET_GONK
 #define OGG_ESTIMATE_BUFFERED 1
 #endif
 
 // Un-comment to enable logging of seek bisections.
 //#define SEEK_LOGGING
 
 extern PRLogModuleInfo* gMediaDecoderLog;
-#define LOG(type, msg) PR_LOG(gMediaDecoderLog, type, msg)
+#define LOG(type, msg) MOZ_LOG(gMediaDecoderLog, type, msg)
 #ifdef SEEK_LOGGING
-#define SEEK_LOG(type, msg) PR_LOG(gMediaDecoderLog, type, msg)
+#define SEEK_LOG(type, msg) MOZ_LOG(gMediaDecoderLog, type, msg)
 #else
 #define SEEK_LOG(type, msg)
 #endif
 
 // The number of microseconds of "fuzz" we use in a bisection search over
 // HTTP. When we're seeking with fuzz, we'll stop the search if a bisection
 // lands between the seek target and SEEK_FUZZ_USECS microseconds before the
 // seek target.  This is becaue it's usually quicker to just keep downloading
--- a/dom/media/ogg/OpusParser.cpp
+++ b/dom/media/ogg/OpusParser.cpp
@@ -20,17 +20,17 @@
 #include "opus/opus.h"
 extern "C" {
 #include "opus/opus_multistream.h"
 }
 
 namespace mozilla {
 
 extern PRLogModuleInfo* gMediaDecoderLog;
-#define OPUS_LOG(type, msg) PR_LOG(gMediaDecoderLog, type, msg)
+#define OPUS_LOG(type, msg) MOZ_LOG(gMediaDecoderLog, type, msg)
 
 OpusParser::OpusParser():
   mRate(0),
   mNominalRate(0),
   mChannels(0),
   mPreSkip(0),
 #ifdef MOZ_SAMPLE_TYPE_FLOAT32
   mGain(1.0f),
--- a/dom/media/omx/AudioOffloadPlayer.cpp
+++ b/dom/media/omx/AudioOffloadPlayer.cpp
@@ -39,17 +39,17 @@
 #include <hardware/audio.h>
 
 using namespace android;
 
 namespace mozilla {
 
 PRLogModuleInfo* gAudioOffloadPlayerLog;
 #define AUDIO_OFFLOAD_LOG(type, msg) \
-  PR_LOG(gAudioOffloadPlayerLog, type, msg)
+  MOZ_LOG(gAudioOffloadPlayerLog, type, msg)
 
 // maximum time in paused state when offloading audio decompression.
 // When elapsed, the GonkAudioSink is destroyed to allow the audio DSP to power down.
 static const uint64_t OFFLOAD_PAUSE_MAX_MSECS = 60000ll;
 
 AudioOffloadPlayer::AudioOffloadPlayer(MediaOmxCommonDecoder* aObserver) :
   mStarted(false),
   mPlaying(false),
--- a/dom/media/omx/AudioOutput.cpp
+++ b/dom/media/omx/AudioOutput.cpp
@@ -15,23 +15,23 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 #include <stagefright/foundation/ADebug.h>
 #include "AudioOutput.h"
 
-#include "prlog.h"
+#include "mozilla/Logging.h"
 
 namespace mozilla {
 
 extern PRLogModuleInfo* gAudioOffloadPlayerLog;
 #define AUDIO_OFFLOAD_LOG(type, msg) \
-  PR_LOG(gAudioOffloadPlayerLog, type, msg)
+  MOZ_LOG(gAudioOffloadPlayerLog, type, msg)
 
 using namespace android;
 
 AudioOutput::AudioOutput(int aSessionId, int aUid) :
   mCallbackCookie(nullptr),
   mCallback(nullptr),
   mCallbackData(nullptr),
   mUid(aUid),
--- a/dom/media/omx/I420ColorConverterHelper.cpp
+++ b/dom/media/omx/I420ColorConverterHelper.cpp
@@ -6,17 +6,17 @@
 
 #include "I420ColorConverterHelper.h"
 
 #include <dlfcn.h>
 
 #include "mozilla/Logging.h"
 
 PRLogModuleInfo *gI420ColorConverterHelperLog;
-#define LOG(msg...) PR_LOG(gI420ColorConverterHelperLog, PR_LOG_WARNING, (msg))
+#define LOG(msg...) MOZ_LOG(gI420ColorConverterHelperLog, PR_LOG_WARNING, (msg))
 
 namespace android {
 
 I420ColorConverterHelper::I420ColorConverterHelper()
   : mHandle(nullptr)
   , mConverter({nullptr, nullptr, nullptr, nullptr, nullptr})
 {
   if (!gI420ColorConverterHelperLog) {
--- a/dom/media/omx/MediaCodecReader.cpp
+++ b/dom/media/omx/MediaCodecReader.cpp
@@ -329,29 +329,29 @@ MediaCodecReader::Shutdown()
 
 void
 MediaCodecReader::DispatchAudioTask()
 {
   if (mAudioTrack.mTaskQueue) {
     RefPtr<nsIRunnable> task =
       NS_NewRunnableMethod(this,
                            &MediaCodecReader::DecodeAudioDataTask);
-    mAudioTrack.mTaskQueue->Dispatch(task);
+    mAudioTrack.mTaskQueue->Dispatch(task.forget());
   }
 }
 
 void
 MediaCodecReader::DispatchVideoTask(int64_t aTimeThreshold)
 {
   if (mVideoTrack.mTaskQueue) {
     RefPtr<nsIRunnable> task =
       NS_NewRunnableMethodWithArg<int64_t>(this,
                                            &MediaCodecReader::DecodeVideoFrameTask,
                                            aTimeThreshold);
-    mVideoTrack.mTaskQueue->Dispatch(task);
+    mVideoTrack.mTaskQueue->Dispatch(task.forget());
   }
 }
 
 nsRefPtr<MediaDecoderReader::AudioDataPromise>
 MediaCodecReader::RequestAudioData()
 {
   MOZ_ASSERT(GetTaskQueue()->IsCurrentThreadIn());
   MOZ_ASSERT(HasAudio());
@@ -792,17 +792,17 @@ MediaCodecReader::TextureClientRecycleCa
 
     mTextureClientIndexes.Remove(aClient);
   }
 
   if (mVideoTrack.mReleaseBufferTaskQueue->IsEmpty()) {
     RefPtr<nsIRunnable> task =
       NS_NewRunnableMethod(this,
                            &MediaCodecReader::WaitFenceAndReleaseOutputBuffer);
-    mVideoTrack.mReleaseBufferTaskQueue->Dispatch(task);
+    mVideoTrack.mReleaseBufferTaskQueue->Dispatch(task.forget());
   }
 }
 
 void
 MediaCodecReader::WaitFenceAndReleaseOutputBuffer()
 {
   nsTArray<ReleaseItem> releasingItems;
   {
@@ -1926,13 +1926,13 @@ MediaCodecReader::VideoCodecReserved()
 
 // Called on Binder thread.
 void
 MediaCodecReader::VideoCodecCanceled()
 {
   if (mVideoTrack.mTaskQueue) {
     RefPtr<nsIRunnable> task =
       NS_NewRunnableMethod(this, &MediaCodecReader::ReleaseCriticalResources);
-    mVideoTrack.mTaskQueue->Dispatch(task);
+    mVideoTrack.mTaskQueue->Dispatch(task.forget());
   }
 }
 
 } // namespace mozilla
--- a/dom/media/omx/MediaOmxCommonDecoder.cpp
+++ b/dom/media/omx/MediaOmxCommonDecoder.cpp
@@ -16,17 +16,17 @@
 #include "AudioOffloadPlayer.h"
 #endif
 
 using namespace android;
 
 namespace mozilla {
 
 extern PRLogModuleInfo* gMediaDecoderLog;
-#define DECODER_LOG(type, msg) PR_LOG(gMediaDecoderLog, type, msg)
+#define DECODER_LOG(type, msg) MOZ_LOG(gMediaDecoderLog, type, msg)
 
 MediaOmxCommonDecoder::MediaOmxCommonDecoder()
   : MediaDecoder()
   , mReader(nullptr)
   , mCanOffloadAudio(false)
   , mFallbackToStateMachine(false)
 {
   if (!gMediaDecoderLog) {
@@ -114,17 +114,17 @@ MediaOmxCommonDecoder::PauseStateMachine
     return;
   }
   // enter dormant state
   RefPtr<nsRunnable> event =
     NS_NewRunnableMethodWithArg<bool>(
       GetStateMachine(),
       &MediaDecoderStateMachine::SetDormant,
       true);
-  GetStateMachine()->TaskQueue()->Dispatch(event);
+  GetStateMachine()->TaskQueue()->Dispatch(event.forget());
 }
 
 void
 MediaOmxCommonDecoder::ResumeStateMachine()
 {
   MOZ_ASSERT(NS_IsMainThread());
   ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
   DECODER_LOG(PR_LOG_DEBUG, ("%s current time %f", __PRETTY_FUNCTION__, mLogicalPosition));
@@ -143,27 +143,27 @@ MediaOmxCommonDecoder::ResumeStateMachin
                                  SeekTarget::Accurate,
                                  MediaDecoderEventVisibility::Suppressed);
   // Call Seek of MediaDecoderStateMachine to suppress seek events.
   RefPtr<nsRunnable> event =
     NS_NewRunnableMethodWithArg<SeekTarget>(
       GetStateMachine(),
       &MediaDecoderStateMachine::Seek,
       target);
-  GetStateMachine()->TaskQueue()->Dispatch(event);
+  GetStateMachine()->TaskQueue()->Dispatch(event.forget());
 
   mNextState = mPlayState;
   ChangeState(PLAY_STATE_LOADING);
   // exit dormant state
   event =
     NS_NewRunnableMethodWithArg<bool>(
       GetStateMachine(),
       &MediaDecoderStateMachine::SetDormant,
       false);
-  GetStateMachine()->TaskQueue()->Dispatch(event);
+  GetStateMachine()->TaskQueue()->Dispatch(event.forget());
   UpdateLogicalPosition();
 }
 
 void
 MediaOmxCommonDecoder::AudioOffloadTearDown()
 {
   MOZ_ASSERT(NS_IsMainThread());
   DECODER_LOG(PR_LOG_DEBUG, ("%s", __PRETTY_FUNCTION__));
--- a/dom/media/omx/MediaOmxCommonReader.cpp
+++ b/dom/media/omx/MediaOmxCommonReader.cpp
@@ -18,17 +18,17 @@
 #include <stagefright/MetaData.h>
 #endif
 
 using namespace android;
 
 namespace mozilla {
 
 extern PRLogModuleInfo* gMediaDecoderLog;
-#define DECODER_LOG(type, msg) PR_LOG(gMediaDecoderLog, type, msg)
+#define DECODER_LOG(type, msg) MOZ_LOG(gMediaDecoderLog, type, msg)
 
 MediaOmxCommonReader::MediaOmxCommonReader(AbstractMediaDecoder *aDecoder)
   : MediaDecoderReader(aDecoder)
 {
   if (!gMediaDecoderLog) {
     gMediaDecoderLog = PR_NewLogModule("MediaDecoder");
   }
 
--- a/dom/media/omx/MediaOmxReader.cpp
+++ b/dom/media/omx/MediaOmxReader.cpp
@@ -23,17 +23,17 @@
 #define MAX_VIDEO_DECODE_SECONDS 0.1
 
 using namespace mozilla::gfx;
 using namespace android;
 
 namespace mozilla {
 
 extern PRLogModuleInfo* gMediaDecoderLog;
-#define DECODER_LOG(type, msg) PR_LOG(gMediaDecoderLog, type, msg)
+#define DECODER_LOG(type, msg) MOZ_LOG(gMediaDecoderLog, type, msg)
 
 class MediaOmxReader::ProcessCachedDataTask : public Task
 {
 public:
   ProcessCachedDataTask(MediaOmxReader* aOmxReader, int64_t aOffset)
   : mOmxReader(aOmxReader),
     mOffset(aOffset)
   { }
--- a/dom/media/omx/OmxDecoder.cpp
+++ b/dom/media/omx/OmxDecoder.cpp
@@ -33,17 +33,17 @@
 #include "OMXCodecProxy.h"
 #include "OmxDecoder.h"
 
 #include <android/log.h>
 #define OD_LOG(...) __android_log_print(ANDROID_LOG_DEBUG, "OmxDecoder", __VA_ARGS__)
 
 #undef LOG
 PRLogModuleInfo *gOmxDecoderLog;
-#define LOG(type, msg...) PR_LOG(gOmxDecoderLog, type, (msg))
+#define LOG(type, msg...) MOZ_LOG(gOmxDecoderLog, type, (msg))
 
 using namespace MPAPI;
 using namespace mozilla;
 using namespace mozilla::gfx;
 using namespace mozilla::layers;
 using namespace android;
 
 OmxDecoder::OmxDecoder(MediaResource *aResource,
--- a/dom/media/platforms/agnostic/BlankDecoderModule.cpp
+++ b/dom/media/platforms/agnostic/BlankDecoderModule.cpp
@@ -64,17 +64,17 @@ public:
   };
 
   virtual nsresult Input(MediaRawData* aSample) override
   {
     // The MediaDataDecoder must delete the sample when we're finished
     // with it, so the OutputEvent stores it in an nsAutoPtr and deletes
     // it once it's run.
     RefPtr<nsIRunnable> r(new OutputEvent(aSample, mCallback, mCreator));
-    mTaskQueue->Dispatch(r);
+    mTaskQueue->Dispatch(r.forget());
     return NS_OK;
   }
 
   virtual nsresult Flush() override {
     mTaskQueue->Flush();
     return NS_OK;
   }
 
--- a/dom/media/platforms/apple/AppleATDecoder.cpp
+++ b/dom/media/platforms/apple/AppleATDecoder.cpp
@@ -8,17 +8,17 @@
 #include "MP4Reader.h"
 #include "MP4Decoder.h"
 #include "mp4_demuxer/Adts.h"
 #include "MediaInfo.h"
 #include "AppleATDecoder.h"
 #include "mozilla/Logging.h"
 
 PRLogModuleInfo* GetAppleMediaLog();
-#define LOG(...) PR_LOG(GetAppleMediaLog(), PR_LOG_DEBUG, (__VA_ARGS__))
+#define LOG(...) MOZ_LOG(GetAppleMediaLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 #define FourCC2Str(n) ((char[5]){(char)(n >> 24), (char)(n >> 16), (char)(n >> 8), (char)(n), 0})
 
 namespace mozilla {
 
 AppleATDecoder::AppleATDecoder(const AudioInfo& aConfig,
                                FlushableMediaTaskQueue* aAudioTaskQueue,
                                MediaDataDecoderCallback* aCallback)
   : mConfig(aConfig)
@@ -67,21 +67,22 @@ AppleATDecoder::Input(MediaRawData* aSam
   LOG("mp4 input sample %p %lld us %lld pts%s %llu bytes audio",
       aSample,
       aSample->mDuration,
       aSample->mTime,
       aSample->mKeyframe ? " keyframe" : "",
       (unsigned long long)aSample->mSize);
 
   // Queue a task to perform the actual decoding on a separate thread.
-  mTaskQueue->Dispatch(
+  nsCOMPtr<nsIRunnable> runnable =
       NS_NewRunnableMethodWithArg<nsRefPtr<MediaRawData>>(
         this,
         &AppleATDecoder::SubmitSample,
-        nsRefPtr<MediaRawData>(aSample)));
+        nsRefPtr<MediaRawData>(aSample));
+  mTaskQueue->Dispatch(runnable.forget());
 
   return NS_OK;
 }
 
 nsresult
 AppleATDecoder::Flush()
 {
   LOG("Flushing AudioToolbox AAC decoder");
--- a/dom/media/platforms/apple/AppleCMLinker.cpp
+++ b/dom/media/platforms/apple/AppleCMLinker.cpp
@@ -8,17 +8,17 @@
 
 #include "AppleCMLinker.h"
 #include "MainThreadUtils.h"
 #include "mozilla/ArrayUtils.h"
 #include "nsCocoaFeatures.h"
 #include "nsDebug.h"
 
 PRLogModuleInfo* GetAppleMediaLog();
-#define LOG(...) PR_LOG(GetAppleMediaLog(), PR_LOG_DEBUG, (__VA_ARGS__))
+#define LOG(...) MOZ_LOG(GetAppleMediaLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 
 namespace mozilla {
 
 AppleCMLinker::LinkStatus
 AppleCMLinker::sLinkStatus = LinkStatus_INIT;
 
 void* AppleCMLinker::sLink = nullptr;
 nsrefcnt AppleCMLinker::sRefCount = 0;
--- a/dom/media/platforms/apple/AppleVDADecoder.cpp
+++ b/dom/media/platforms/apple/AppleVDADecoder.cpp
@@ -19,17 +19,17 @@
 #include "nsCocoaFeatures.h"
 #include "nsThreadUtils.h"
 #include "mozilla/Logging.h"
 #include "VideoUtils.h"
 #include <algorithm>
 #include "gfxPlatform.h"
 
 PRLogModuleInfo* GetAppleMediaLog();
-#define LOG(...) PR_LOG(GetAppleMediaLog(), PR_LOG_DEBUG, (__VA_ARGS__))
+#define LOG(...) MOZ_LOG(GetAppleMediaLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 //#define LOG_MEDIA_SHA1
 
 namespace mozilla {
 
 AppleVDADecoder::AppleVDADecoder(const VideoInfo& aConfig,
                                FlushableMediaTaskQueue* aVideoTaskQueue,
                                MediaDataDecoderCallback* aCallback,
                                layers::ImageContainer* aImageContainer)
@@ -103,21 +103,22 @@ AppleVDADecoder::Input(MediaRawData* aSa
 {
   LOG("mp4 input sample %p pts %lld duration %lld us%s %d bytes",
       aSample,
       aSample->mTime,
       aSample->mDuration,
       aSample->mKeyframe ? " keyframe" : "",
       aSample->mSize);
 
-  mTaskQueue->Dispatch(
+  nsCOMPtr<nsIRunnable> runnable =
       NS_NewRunnableMethodWithArg<nsRefPtr<MediaRawData>>(
           this,
           &AppleVDADecoder::SubmitFrame,
-          nsRefPtr<MediaRawData>(aSample)));
+          nsRefPtr<MediaRawData>(aSample));
+  mTaskQueue->Dispatch(runnable.forget());
   return NS_OK;
 }
 
 nsresult
 AppleVDADecoder::Flush()
 {
   mTaskQueue->Flush();
   OSStatus rv = VDADecoderFlush(mDecoder, 0 /*dont emit*/);
--- a/dom/media/platforms/apple/AppleVDALinker.cpp
+++ b/dom/media/platforms/apple/AppleVDALinker.cpp
@@ -6,17 +6,17 @@
 
 #include <dlfcn.h>
 
 #include "AppleVDALinker.h"
 #include "MainThreadUtils.h"
 #include "nsDebug.h"
 
 PRLogModuleInfo* GetAppleMediaLog();
-#define LOG(...) PR_LOG(GetAppleMediaLog(), PR_LOG_DEBUG, (__VA_ARGS__))
+#define LOG(...) MOZ_LOG(GetAppleMediaLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 
 namespace mozilla {
 
 AppleVDALinker::LinkStatus
 AppleVDALinker::sLinkStatus = LinkStatus_INIT;
 
 void* AppleVDALinker::sLink = nullptr;
 nsrefcnt AppleVDALinker::sRefCount = 0;
--- a/dom/media/platforms/apple/AppleVTDecoder.cpp
+++ b/dom/media/platforms/apple/AppleVTDecoder.cpp
@@ -16,17 +16,17 @@
 #include "mozilla/ArrayUtils.h"
 #include "nsAutoPtr.h"
 #include "nsThreadUtils.h"
 #include "mozilla/Logging.h"
 #include "VideoUtils.h"
 #include "gfxPlatform.h"
 
 PRLogModuleInfo* GetAppleMediaLog();
-#define LOG(...) PR_LOG(GetAppleMediaLog(), PR_LOG_DEBUG, (__VA_ARGS__))
+#define LOG(...) MOZ_LOG(GetAppleMediaLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 //#define LOG_MEDIA_SHA1
 
 #ifdef LOG_MEDIA_SHA1
 #include "mozilla/SHA1.h"
 #endif
 
 namespace mozilla {
 
@@ -93,21 +93,22 @@ AppleVTDecoder::Input(MediaRawData* aSam
   hash.finish(digest_buf);
   nsAutoCString digest;
   for (size_t i = 0; i < sizeof(digest_buf); i++) {
     digest.AppendPrintf("%02x", digest_buf[i]);
   }
   LOG("    sha1 %s", digest.get());
 #endif // LOG_MEDIA_SHA1
 
-  mTaskQueue->Dispatch(
+  nsCOMPtr<nsIRunnable> runnable =
       NS_NewRunnableMethodWithArg<nsRefPtr<MediaRawData>>(
           this,
           &AppleVTDecoder::SubmitFrame,
-          nsRefPtr<MediaRawData>(aSample)));
+          nsRefPtr<MediaRawData>(aSample));
+  mTaskQueue->Dispatch(runnable.forget());
   return NS_OK;
 }
 
 nsresult
 AppleVTDecoder::Flush()
 {
   mTaskQueue->Flush();
   nsresult rv = WaitForAsynchronousFrames();
--- a/dom/media/platforms/apple/AppleVTLinker.cpp
+++ b/dom/media/platforms/apple/AppleVTLinker.cpp
@@ -7,17 +7,17 @@
 #include <dlfcn.h>
 
 #include "AppleVTLinker.h"
 #include "MainThreadUtils.h"
 #include "mozilla/ArrayUtils.h"
 #include "nsDebug.h"
 
 PRLogModuleInfo* GetAppleMediaLog();
-#define LOG(...) PR_LOG(GetAppleMediaLog(), PR_LOG_DEBUG, (__VA_ARGS__))
+#define LOG(...) MOZ_LOG(GetAppleMediaLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 
 namespace mozilla {
 
 AppleVTLinker::LinkStatus
 AppleVTLinker::sLinkStatus = LinkStatus_INIT;
 
 void* AppleVTLinker::sLink = nullptr;
 nsrefcnt AppleVTLinker::sRefCount = 0;
--- a/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp
@@ -143,19 +143,19 @@ FFmpegAudioDecoder<LIBAV_VER>::DecodePac
   if (mTaskQueue->IsEmpty()) {
     mCallback->InputExhausted();
   }
 }
 
 nsresult
 FFmpegAudioDecoder<LIBAV_VER>::Input(MediaRawData* aSample)
 {
-  mTaskQueue->Dispatch(NS_NewRunnableMethodWithArg<nsRefPtr<MediaRawData> >(
+  nsCOMPtr<nsIRunnable> runnable(NS_NewRunnableMethodWithArg<nsRefPtr<MediaRawData>>(
     this, &FFmpegAudioDecoder::DecodePacket, nsRefPtr<MediaRawData>(aSample)));
-
+  mTaskQueue->Dispatch(runnable.forget());
   return NS_OK;
 }
 
 nsresult
 FFmpegAudioDecoder<LIBAV_VER>::Drain()
 {
   mTaskQueue->AwaitIdle();
   mCallback->DrainComplete();
--- a/dom/media/platforms/ffmpeg/FFmpegH264Decoder.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegH264Decoder.cpp
@@ -237,38 +237,40 @@ FFmpegH264Decoder<LIBAV_VER>::AllocateYU
   aFrame->opaque = static_cast<void*>(image.forget().take());
 
   return 0;
 }
 
 nsresult
 FFmpegH264Decoder<LIBAV_VER>::Input(MediaRawData* aSample)
 {
-  mTaskQueue->Dispatch(
+  nsCOMPtr<nsIRunnable> runnable(
     NS_NewRunnableMethodWithArg<nsRefPtr<MediaRawData>>(
       this, &FFmpegH264Decoder<LIBAV_VER>::DecodeFrame,
       nsRefPtr<MediaRawData>(aSample)));
+  mTaskQueue->Dispatch(runnable.forget());
 
   return NS_OK;
 }
 
 void
 FFmpegH264Decoder<LIBAV_VER>::DoDrain()
 {
   nsRefPtr<MediaRawData> empty(new MediaRawData());
   while (DoDecodeFrame(empty) == DecodeResult::DECODE_FRAME) {
   }
   mCallback->DrainComplete();
 }
 
 nsresult
 FFmpegH264Decoder<LIBAV_VER>::Drain()
 {
-  mTaskQueue->Dispatch(
+  nsCOMPtr<nsIRunnable> runnable(
     NS_NewRunnableMethod(this, &FFmpegH264Decoder<LIBAV_VER>::DoDrain));
+  mTaskQueue->Dispatch(runnable.forget());
 
   return NS_OK;
 }
 
 nsresult
 FFmpegH264Decoder<LIBAV_VER>::Flush()
 {
   nsresult rv = FFmpegDataDecoder::Flush();
--- a/dom/media/platforms/ffmpeg/FFmpegLog.h
+++ b/dom/media/platforms/ffmpeg/FFmpegLog.h
@@ -3,11 +3,11 @@
 /* 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 __FFmpegLog_h__
 #define __FFmpegLog_h__
 
 extern PRLogModuleInfo* GetFFmpegDecoderLog();
-#define FFMPEG_LOG(...) PR_LOG(GetFFmpegDecoderLog(), PR_LOG_DEBUG, (__VA_ARGS__))
+#define FFMPEG_LOG(...) MOZ_LOG(GetFFmpegDecoderLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 
 #endif // __FFmpegLog_h__
--- a/dom/media/platforms/gonk/GonkAudioDecoderManager.cpp
+++ b/dom/media/platforms/gonk/GonkAudioDecoderManager.cpp
@@ -21,17 +21,17 @@
 #include "media/openmax/OMX_Audio.h"
 #include "MediaData.h"
 #include "MediaInfo.h"
 
 #include <android/log.h>
 #define GADM_LOG(...) __android_log_print(ANDROID_LOG_DEBUG, "GonkAudioDecoderManager", __VA_ARGS__)
 
 PRLogModuleInfo* GetDemuxerLog();
-#define LOG(...) PR_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__))
+#define LOG(...) MOZ_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 #define READ_OUTPUT_BUFFER_TIMEOUT_US  3000
 
 using namespace android;
 typedef android::MediaCodecProxy MediaCodecProxy;
 
 namespace mozilla {
 
 GonkAudioDecoderManager::GonkAudioDecoderManager(const AudioInfo& aConfig)
--- a/dom/media/platforms/gonk/GonkMediaDataDecoder.cpp
+++ b/dom/media/platforms/gonk/GonkMediaDataDecoder.cpp
@@ -9,17 +9,17 @@
 #include "MediaCodecProxy.h"
 #include "MediaData.h"
 
 #include "mozilla/Logging.h"
 #include <android/log.h>
 #define GMDD_LOG(...) __android_log_print(ANDROID_LOG_DEBUG, "GonkMediaDataDecoder", __VA_ARGS__)
 
 PRLogModuleInfo* GetDemuxerLog();
-#define LOG(...) PR_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__))
+#define LOG(...) MOZ_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 
 using namespace android;
 
 namespace mozilla {
 
 GonkMediaDataDecoder::GonkMediaDataDecoder(GonkDecoderManager* aManager,
                                            FlushableMediaTaskQueue* aTaskQueue,
                                            MediaDataDecoderCallback* aCallback)
@@ -60,21 +60,22 @@ GonkMediaDataDecoder::Shutdown()
   mDecoder = nullptr;
   return NS_OK;
 }
 
 // Inserts data into the decoder's pipeline.
 nsresult
 GonkMediaDataDecoder::Input(MediaRawData* aSample)
 {
-  mTaskQueue->Dispatch(
+  nsCOMPtr<nsIRunnable> runnable(
     NS_NewRunnableMethodWithArg<nsRefPtr<MediaRawData>>(
       this,
       &GonkMediaDataDecoder::ProcessDecode,
       nsRefPtr<MediaRawData>(aSample)));
+  mTaskQueue->Dispatch(runnable.forget());
   return NS_OK;
 }
 
 void
 GonkMediaDataDecoder::ProcessDecode(MediaRawData* aSample)
 {
   nsresult rv = mManager->Input(aSample);
   if (rv != NS_OK) {
@@ -156,13 +157,15 @@ GonkMediaDataDecoder::ProcessDrain()
   ProcessDecode(nullptr);
   mSignaledEOS = true;
   ProcessOutput();
 }
 
 nsresult
 GonkMediaDataDecoder::Drain()
 {
-  mTaskQueue->Dispatch(NS_NewRunnableMethod(this, &GonkMediaDataDecoder::ProcessDrain));
+  nsCOMPtr<nsIRunnable> runnable =
+    NS_NewRunnableMethod(this, &GonkMediaDataDecoder::ProcessDrain);
+  mTaskQueue->Dispatch(runnable.forget());
   return NS_OK;
 }
 
 } // namespace mozilla
--- a/dom/media/platforms/gonk/GonkVideoDecoderManager.cpp
+++ b/dom/media/platforms/gonk/GonkVideoDecoderManager.cpp
@@ -27,17 +27,17 @@
 #include "mozilla/layers/TextureClient.h"
 
 #define READ_OUTPUT_BUFFER_TIMEOUT_US  3000
 
 #include <android/log.h>
 #define GVDM_LOG(...) __android_log_print(ANDROID_LOG_DEBUG, "GonkVideoDecoderManager", __VA_ARGS__)
 
 PRLogModuleInfo* GetDemuxerLog();
-#define LOG(...) PR_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__))
+#define LOG(...) MOZ_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 using namespace mozilla::layers;
 using namespace android;
 typedef android::MediaCodecProxy MediaCodecProxy;
 
 namespace mozilla {
 
 GonkVideoDecoderManager::GonkVideoDecoderManager(
   mozilla::layers::ImageContainer* aImageContainer,
--- a/dom/media/platforms/wmf/MFTDecoder.cpp
+++ b/dom/media/platforms/wmf/MFTDecoder.cpp
@@ -5,17 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "MFTDecoder.h"
 #include "nsThreadUtils.h"
 #include "WMFUtils.h"
 #include "mozilla/Logging.h"
 
 PRLogModuleInfo* GetDemuxerLog();
-#define LOG(...) PR_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__))
+#define LOG(...) MOZ_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 
 namespace mozilla {
 
 MFTDecoder::MFTDecoder()
   : mMFTProvidesOutputSamples(false)
   , mDiscontinuity(true)
 {
   memset(&mInputStreamInfo, 0, sizeof(MFT_INPUT_STREAM_INFO));
@@ -69,17 +69,17 @@ MFTDecoder::SetMediaTypes(IMFMediaType* 
 }
 
 TemporaryRef<IMFAttributes>
 MFTDecoder::GetAttributes()
 {
   RefPtr<IMFAttributes> attr;
   HRESULT hr = mDecoder->GetAttributes(byRef(attr));
   NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
-  return attr;
+  return attr.forget();
 }
 
 HRESULT
 MFTDecoder::SetDecoderOutputType(ConfigureOutputCallback aCallback, void* aData)
 {
   NS_ENSURE_TRUE(mDecoder != nullptr, E_POINTER);
 
   // Iterate the enumerate the output types, until we find one compatible
--- a/dom/media/platforms/wmf/WMFAudioMFTManager.cpp
+++ b/dom/media/platforms/wmf/WMFAudioMFTManager.cpp
@@ -8,17 +8,17 @@
 #include "MediaInfo.h"
 #include "VideoUtils.h"
 #include "WMFUtils.h"
 #include "nsTArray.h"
 
 #include "mozilla/Logging.h"
 
 PRLogModuleInfo* GetDemuxerLog();
-#define LOG(...) PR_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__))
+#define LOG(...) MOZ_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 
 namespace mozilla {
 
 static void
 AACAudioSpecificConfigToUserData(uint8_t aAACProfileLevelIndication,
                                  const uint8_t* aAudioSpecConfig,
                                  uint32_t aConfigLength,
                                  nsTArray<BYTE>& aOutUserData)
--- a/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp
+++ b/dom/media/platforms/wmf/WMFMediaDataDecoder.cpp
@@ -8,17 +8,17 @@
 #include "VideoUtils.h"
 #include "WMFUtils.h"
 #include "nsTArray.h"
 #include "mozilla/Telemetry.h"
 
 #include "mozilla/Logging.h"
 
 PRLogModuleInfo* GetDemuxerLog();
-#define LOG(...) PR_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__))
+#define LOG(...) MOZ_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 
 namespace mozilla {
 
 WMFMediaDataDecoder::WMFMediaDataDecoder(MFTManager* aMFTManager,
                                          FlushableMediaTaskQueue* aTaskQueue,
                                          MediaDataDecoderCallback* aCallback)
   : mTaskQueue(aTaskQueue)
   , mCallback(aCallback)
@@ -79,18 +79,19 @@ SendTelemetry(HRESULT hr)
 }
 
 nsresult
 WMFMediaDataDecoder::Shutdown()
 {
   MOZ_DIAGNOSTIC_ASSERT(!mIsShutDown);
 
   if (mTaskQueue) {
-    mTaskQueue->Dispatch(
-      NS_NewRunnableMethod(this, &WMFMediaDataDecoder::ProcessShutdown));
+    nsCOMPtr<nsIRunnable> runnable =
+      NS_NewRunnableMethod(this, &WMFMediaDataDecoder::ProcessShutdown);
+    mTaskQueue->Dispatch(runnable.forget());
   } else {
     ProcessShutdown();
   }
   mIsShutDown = true;
   return NS_OK;
 }
 
 void
@@ -221,17 +222,19 @@ WMFMediaDataDecoder::ProcessDrain()
 }
 
 nsresult
 WMFMediaDataDecoder::Drain()
 {
   MOZ_ASSERT(mCallback->OnReaderTaskQueue());
   MOZ_DIAGNOSTIC_ASSERT(!mIsShutDown);
 
-  mTaskQueue->Dispatch(NS_NewRunnableMethod(this, &WMFMediaDataDecoder::ProcessDrain));
+  nsCOMPtr<nsIRunnable> runnable =
+    NS_NewRunnableMethod(this, &WMFMediaDataDecoder::ProcessDrain);
+  mTaskQueue->Dispatch(runnable.forget());
   return NS_OK;
 }
 
 bool
 WMFMediaDataDecoder::IsHardwareAccelerated() const {
   MOZ_ASSERT(!mIsShutDown);
 
   return mMFTManager && mMFTManager->IsHardwareAccelerated();
--- a/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
+++ b/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
@@ -17,17 +17,17 @@
 #include "MediaInfo.h"
 #include "mozilla/Logging.h"
 #include "gfx2DGlue.h"
 #include "gfxWindowsPlatform.h"
 #include "IMFYCbCrImage.h"
 #include "mozilla/WindowsVersion.h"
 
 PRLogModuleInfo* GetDemuxerLog();
-#define LOG(...) PR_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__))
+#define LOG(...) MOZ_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 
 using mozilla::layers::Image;
 using mozilla::layers::IMFYCbCrImage;
 using mozilla::layers::LayerManager;
 using mozilla::layers::LayersBackend;
 
 const GUID MFVideoFormat_VP80 =
 {
--- a/dom/media/systemservices/LoadManager.cpp
+++ b/dom/media/systemservices/LoadManager.cpp
@@ -16,17 +16,17 @@
 #include "nsReadableUtils.h"
 #include "nsNetUtil.h"
 #include "nsIObserverService.h"
 
 // NSPR_LOG_MODULES=LoadManager:5
 PRLogModuleInfo *gLoadManagerLog = nullptr;
 #undef LOG
 #undef LOG_ENABLED
-#define LOG(args) PR_LOG(gLoadManagerLog, PR_LOG_DEBUG, args)
+#define LOG(args) MOZ_LOG(gLoadManagerLog, PR_LOG_DEBUG, args)
 #define LOG_ENABLED() PR_LOG_TEST(gLoadManagerLog, 5)
 
 namespace mozilla {
 
 /* static */ StaticRefPtr<LoadManagerSingleton> LoadManagerSingleton::sSingleton;
 
 NS_IMPL_ISUPPORTS(LoadManagerSingleton, nsIObserver)
 
--- a/dom/media/systemservices/LoadMonitor.cpp
+++ b/dom/media/systemservices/LoadMonitor.cpp
@@ -51,17 +51,17 @@
 #include <pdh.h>
 #include <tchar.h>
 #pragma comment(lib, "pdh.lib")
 #endif
 
 // NSPR_LOG_MODULES=LoadManager:5
 #undef LOG
 #undef LOG_ENABLED
-#define LOG(args) PR_LOG(gLoadManagerLog, PR_LOG_DEBUG, args)
+#define LOG(args) MOZ_LOG(gLoadManagerLog, PR_LOG_DEBUG, args)
 #define LOG_ENABLED() PR_LOG_TEST(gLoadManagerLog, 4)
 #define LOG_MANY_ENABLED() PR_LOG_TEST(gLoadManagerLog, 5)
 
 namespace mozilla {
 
 NS_IMPL_ISUPPORTS(LoadMonitor, nsIObserver)
 
 LoadMonitor::LoadMonitor(int aLoadUpdateInterval)
--- a/dom/media/systemservices/MediaChild.cpp
+++ b/dom/media/systemservices/MediaChild.cpp
@@ -10,17 +10,17 @@
 #include "mozilla/ipc/PBackgroundChild.h"
 #include "nsGlobalWindow.h"
 #include "mozilla/MediaManager.h"
 #include "mozilla/Logging.h"
 #include "nsQueryObject.h"
 
 #undef LOG
 PRLogModuleInfo *gMediaChildLog;
-#define LOG(args) PR_LOG(gMediaChildLog, PR_LOG_DEBUG, args)
+#define LOG(args) MOZ_LOG(gMediaChildLog, PR_LOG_DEBUG, args)
 
 namespace mozilla {
 namespace media {
 
 static Child* sChild;
 
 template<typename ValueType> void
 ChildPledge<ValueType>::ActorCreated(PBackgroundChild* aActor)
@@ -108,40 +108,26 @@ Child::Child()
 
 Child::~Child()
 {
   LOG(("~media::Child: %p", this));
   sChild = nullptr;
   MOZ_COUNT_DTOR(Child);
 }
 
-uint32_t Child::sRequestCounter = 0;
-
 uint32_t
 Child::AddRequestPledge(ChildPledge<nsCString>& aPledge)
 {
-  uint32_t id = ++sRequestCounter;
-  nsRefPtr<ChildPledge<nsCString>> ptr(&aPledge);
-  mRequestPledges.AppendElement(PledgeEntry(id, ptr));
-  return id;
+  return mRequestPledges.Append(aPledge);
 }
 
 already_AddRefed<ChildPledge<nsCString>>
 Child::RemoveRequestPledge(uint32_t aRequestId)
 {
-  for (PledgeEntry& entry : mRequestPledges) {
-    if (entry.first == aRequestId) {
-      nsRefPtr<ChildPledge<nsCString>> ref;
-      ref.swap(entry.second);
-      mRequestPledges.RemoveElement(entry);
-      return ref.forget();
-    }
-  }
-  MOZ_ASSERT_UNREACHABLE("Received response with no matching media::ChildPledge!");
-  return nullptr;
+  return mRequestPledges.Remove(aRequestId);
 }
 
 bool
 Child::RecvGetOriginKeyResponse(const uint32_t& aRequestId, const nsCString& aKey)
 {
   nsRefPtr<ChildPledge<nsCString>> pledge = RemoveRequestPledge(aRequestId);
   if (pledge) {
     pledge->Resolve(aKey);
--- a/dom/media/systemservices/MediaChild.h
+++ b/dom/media/systemservices/MediaChild.h
@@ -55,19 +55,17 @@ public:
 
   bool RecvGetOriginKeyResponse(const uint32_t& aRequestId, const nsCString& aKey);
 
   uint32_t AddRequestPledge(ChildPledge<nsCString>& aPledge);
   already_AddRefed<ChildPledge<nsCString>> RemoveRequestPledge(uint32_t aRequestId);
 private:
   virtual ~Child();
 
-  typedef std::pair<uint32_t,nsRefPtr<ChildPledge<nsCString>>> PledgeEntry;
-  static uint32_t sRequestCounter;
-  nsTArray<PledgeEntry> mRequestPledges;
+  CoatCheck<ChildPledge<nsCString>> mRequestPledges;
 };
 
 PMediaChild* AllocPMediaChild();
 bool DeallocPMediaChild(PMediaChild *aActor);
 
 } // namespace media
 } // namespace mozilla
 
--- a/dom/media/systemservices/MediaParent.cpp
+++ b/dom/media/systemservices/MediaParent.cpp
@@ -16,17 +16,17 @@
 #include "nsNetUtil.h"
 #include "nsILineInputStream.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsISupportsImpl.h"
 #include "mozilla/Logging.h"
 
 #undef LOG
 PRLogModuleInfo *gMediaParentLog;
-#define LOG(args) PR_LOG(gMediaParentLog, PR_LOG_DEBUG, args)
+#define LOG(args) MOZ_LOG(gMediaParentLog, PR_LOG_DEBUG, args)
 
 // A file in the profile dir is used to persist mOriginKeys used to anonymize
 // deviceIds to be unique per origin, to avoid them being supercookies.
 
 #define ORIGINKEYS_FILE "enumerate_devices.txt"
 #define ORIGINKEYS_VERSION "1"
 
 namespace mozilla {
@@ -99,42 +99,33 @@ class ParentSingleton : public nsISuppor
 
   protected:
     nsClassHashtable<nsCStringHashKey, OriginKey> mKeys;
   };
 
   class OriginKeysLoader : public OriginKeysTable
   {
   public:
-    OriginKeysLoader()
-    {
-      Load();
-    }
+    OriginKeysLoader() {}
 
     nsresult
     GetOriginKey(const nsACString& aOrigin, nsCString& result)
     {
       auto before = mKeys.Count();
       OriginKeysTable::GetOriginKey(aOrigin, result);
       if (mKeys.Count() != before) {
         Save();
       }
       return NS_OK;
     }
 
     already_AddRefed<nsIFile>
     GetFile()
     {
-      if (!mProfileDir) {
-        nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
-                                             getter_AddRefs(mProfileDir));
-        if (NS_WARN_IF(NS_FAILED(rv))) {
-          return nullptr;
-        }
-      }
+      MOZ_ASSERT(mProfileDir);
       nsCOMPtr<nsIFile> file;
       nsresult rv = mProfileDir->Clone(getter_AddRefs(file));
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return nullptr;
       }
       file->Append(NS_LITERAL_STRING(ORIGINKEYS_FILE));
       return file.forget();
     }
@@ -312,16 +303,27 @@ class ParentSingleton : public nsISuppor
         return NS_OK;
       }
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
       return NS_OK;
     }
 
+    void
+    SetProfileDir(nsIFile* aProfileDir)
+    {
+      MOZ_ASSERT(!NS_IsMainThread());
+      bool first = !mProfileDir;
+      mProfileDir = aProfileDir;
+      // Load from disk when we first get a profileDir, but not subsequently.
+      if (first) {
+        Load();
+      }
+    }
   private:
     nsCOMPtr<nsIFile> mProfileDir;
   };
 
 private:
   virtual ~ParentSingleton()
   {
     sParentSingleton = nullptr;
@@ -339,72 +341,137 @@ public:
 
     StaticMutexAutoLock lock(gMutex);
     if (!sParentSingleton) {
       sParentSingleton = new ParentSingleton();
     }
     return sParentSingleton;
   }
 
+  // Only accessed on StreamTS thread
   OriginKeysLoader mOriginKeys;
   OriginKeysTable mPrivateBrowsingOriginKeys;
+
+  // Only accessed on return thread
+  CoatCheck<Pledge<nsCString>> mOutstandingPledges;
 };
 
 NS_IMPL_ISUPPORTS0(ParentSingleton)
 
 bool
 Parent::RecvGetOriginKey(const uint32_t& aRequestId,
                          const nsCString& aOrigin,
                          const bool& aPrivateBrowsing)
 {
-  // Hand over to stream-transport thread.
+  // TODO: Replace all this when moving MediaParent to PContent soon (1037389)
+
+  nsRefPtr<ParentSingleton> singleton(mSingleton);
+  nsCOMPtr<nsIThread> returnThread = NS_GetCurrentThread();
+  nsRefPtr<Pledge<nsCString>> p = new Pledge<nsCString>();
+  nsresult rv;
+
+  // First, over to main thread to get profile dir.
+
+  // Pledges are non-threadsafe by design, so check them and pass an id instead.
+  uint32_t id = singleton->mOutstandingPledges.Append(*p);
 
-  nsCOMPtr<nsIEventTarget> sts = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
-  MOZ_ASSERT(sts);
-  nsRefPtr<ParentSingleton> singleton(mSingleton);
+  rv = NS_DispatchToMainThread(NewRunnableFrom([id, returnThread,
+                                                singleton, aOrigin,
+                                                aPrivateBrowsing]() -> nsresult {
+    MOZ_ASSERT(NS_IsMainThread());
+    nsCOMPtr<nsIFile> profileDir;
+    nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
+                                         getter_AddRefs(profileDir));
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+
+    // Then from there over to stream-transport thread to do the actual file io.
 
-  nsRefPtr<PledgeRunnable<nsCString>> p = PledgeRunnable<nsCString>::New(
-      [singleton, aOrigin, aPrivateBrowsing](nsCString& aResult) {
-    if (aPrivateBrowsing) {
-      singleton->mPrivateBrowsingOriginKeys.GetOriginKey(aOrigin, aResult);
-    } else {
-      singleton->mOriginKeys.GetOriginKey(aOrigin, aResult);
+    nsCOMPtr<nsIEventTarget> sts = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
+    MOZ_ASSERT(sts);
+    rv = sts->Dispatch(NewRunnableFrom([profileDir, id, returnThread, singleton,
+                                        aOrigin, aPrivateBrowsing]() -> nsresult {
+      MOZ_ASSERT(!NS_IsMainThread());
+      singleton->mOriginKeys.SetProfileDir(profileDir);
+      nsCString result;
+      if (aPrivateBrowsing) {
+        singleton->mPrivateBrowsingOriginKeys.GetOriginKey(aOrigin, result);
+      } else {
+        singleton->mOriginKeys.GetOriginKey(aOrigin, result);
+      }
+
+      // Pass result back to original thread.
+      nsresult rv;
+      rv = returnThread->Dispatch(NewRunnableFrom([id, singleton,
+                                                   result]() -> nsresult {
+        nsRefPtr<Pledge<nsCString>> p = singleton->mOutstandingPledges.Remove(id);
+        if (!p) {
+          return NS_ERROR_UNEXPECTED;
+        }
+        p->Resolve(result);
+        return NS_OK;
+      }), NS_DISPATCH_NORMAL);
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        return rv;
+      }
+      return NS_OK;
+    }), NS_DISPATCH_NORMAL);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
     }
     return NS_OK;
-  });
-  nsresult rv = sts->Dispatch(p, NS_DISPATCH_NORMAL);
+  }));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return false;
   }
+
   nsRefPtr<media::Parent> keepAlive(this);
   p->Then([this, keepAlive, aRequestId](const nsCString& aKey) mutable {
     if (!mDestroyed) {
       unused << SendGetOriginKeyResponse(aRequestId, aKey);
     }
     return NS_OK;
   });
   return true;
 }
 
 bool
 Parent::RecvSanitizeOriginKeys(const uint64_t& aSinceWhen)
 {
-  // Hand over to stream-transport thread.
-
-  nsCOMPtr<nsIEventTarget> sts = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
-  MOZ_ASSERT(sts);
   nsRefPtr<ParentSingleton> singleton(mSingleton);
 
-  nsRefPtr<PledgeRunnable<bool>> p = PledgeRunnable<bool>::New(
-      [singleton, aSinceWhen](bool) {
-    singleton->mPrivateBrowsingOriginKeys.Clear(aSinceWhen);
-    singleton->mOriginKeys.Clear(aSinceWhen);
+  // First, over to main to get profile dir.
+  nsresult rv;
+
+  rv = NS_DispatchToMainThread(NewRunnableFrom([singleton,
+                                                aSinceWhen]() -> nsresult {
+    MOZ_ASSERT(NS_IsMainThread());
+    nsCOMPtr<nsIFile> profileDir;
+    nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
+                                         getter_AddRefs(profileDir));
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+    // Then from there over to stream-transport thread to do the file io.
+
+    nsCOMPtr<nsIEventTarget> sts = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
+    MOZ_ASSERT(sts);
+    rv = sts->Dispatch(NewRunnableFrom([profileDir, singleton, aSinceWhen]() -> nsresult {
+      MOZ_ASSERT(!NS_IsMainThread());
+      singleton->mOriginKeys.SetProfileDir(profileDir);
+      singleton->mPrivateBrowsingOriginKeys.Clear(aSinceWhen);
+      singleton->mOriginKeys.Clear(aSinceWhen);
+      return NS_OK;
+    }), NS_DISPATCH_NORMAL);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
     return NS_OK;
-  });
-  nsresult rv = sts->Dispatch(p, NS_DISPATCH_NORMAL);
+  }));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return false;
   }
   return true;
 }
 
 void
 Parent::ActorDestroy(ActorDestroyReason aWhy)
--- a/dom/media/systemservices/MediaUtils.h
+++ b/dom/media/systemservices/MediaUtils.h
@@ -8,40 +8,59 @@
 #define mozilla_MediaUtils_h
 
 #include "nsAutoPtr.h"
 #include "nsThreadUtils.h"
 
 namespace mozilla {
 namespace media {
 
-// A media::Pledge is a promise-like pattern for c++ that takes lambda functions.
-//
-// Asynchronous APIs that proxy to the chrome process and back, may return a
-// pledge to allow callers to use pledge.Then() to specify a lambda function to
-// invoke with the result once the asynchronous API resolves later back on the
-// same thread.
-//
-// An advantage of this pattern is that lambdas allow "capturing" of local
-// variables, much like closures in JavaScript.
+/*
+ * media::Pledge - A promise-like pattern for c++ that takes lambda functions.
+ *
+ * Asynchronous APIs that proxy to another thread or to the chrome process and
+ * back may find it useful to return a pledge to callers who then use
+ * pledge.Then(func) to specify a lambda function to be invoked with the result
+ * later back on this same thread.
+ *
+ * Callers will enjoy that lambdas allow "capturing" of local variables, much
+ * like closures in JavaScript (safely by-copy by default).
+ *
+ * Callers will also enjoy that they do not need to be thread-safe (their code
+ * runs on the same thread after all).
+ *
+ * Advantageously, pledges are non-threadsafe by design (because locking and
+ * event queues are redundant). This means none of the lambdas you pass in,
+ * or variables you lambda-capture into them, need be threasafe or support
+ * threadsafe refcounting. After all, they'll run later on the same thread.
+ *
+ *   nsRefPtr<media::Pledge<Foo>> p = GetFooAsynchronously(); // returns a pledge
+ *   p->Then([](const Foo& foo) {
+ *     // use foo here (same thread. Need not be thread-safe!)
+ *   });
+ *
+ * See media::CoatCheck below for an example of GetFooAsynchronously().
+ */
 
 template<typename ValueType>
 class Pledge
 {
   // TODO: Remove workaround once mozilla allows std::function from <functional>
+  // wo/std::function support, do template + virtual trick to accept lambdas
   class FunctorsBase
   {
   public:
     FunctorsBase() {}
     virtual void Succeed(const ValueType& result) = 0;
     virtual void Fail(nsresult rv) = 0;
     virtual ~FunctorsBase() {};
   };
 
 public:
+  NS_INLINE_DECL_REFCOUNTING(Pledge);
   explicit Pledge() : mDone(false), mResult(NS_OK) {}
 
   template<typename OnSuccessType>
   void Then(OnSuccessType aOnSuccess)
   {
     Then(aOnSuccess, [](nsresult){});
   }
 
@@ -72,23 +91,22 @@ public:
       if (mResult == NS_OK) {
         mFunctors->Succeed(mValue);
       } else {
         mFunctors->Fail(mResult);
       }
     }
   }
 
-protected:
   void Resolve(const ValueType& aValue)
   {
     mValue = aValue;
     Resolve();
   }
-
+protected:
   void Resolve()
   {
     if (!mDone) {
       mDone = true;
       MOZ_ASSERT(mResult == NS_OK);
       if (mFunctors) {
         mFunctors->Succeed(mValue);
       }
@@ -103,95 +121,176 @@ protected:
       if (mFunctors) {
         mFunctors->Fail(mResult);
       }
     }
   }
 
   ValueType mValue;
 protected:
+  ~Pledge() {};
   bool mDone;
   nsresult mResult;
 private:
   nsAutoPtr<FunctorsBase> mFunctors;
 };
 
-// General purpose runnable that also acts as a Pledge for the resulting value.
-// Use PledgeRunnable<>::New() factory function to use with lambdas.
+/* media::NewRunnableFrom() - Create an nsRunnable from a lambda.
+ *
+ * Passing variables (closures) to an async function is clunky with nsRunnable:
+ *
+ *   void Foo()
+ *   {
+ *     class FooRunnable : public nsRunnable
+ *     {
+ *     public:
+ *       FooRunnable(const Bar &aBar) : mBar(aBar) {}
+ *       NS_IMETHOD Run()
+ *       {
+ *         // Use mBar
+ *       }
+ *     private:
+ *       nsRefPtr<Bar> mBar;
+ *     };
+ *
+ *     nsRefPtr<Bar> bar = new Bar();
+ *     NS_DispatchToMainThread(new FooRunnable(bar);
+ *   }
+ *
+ * It's worse with more variables. Lambdas have a leg up with variable capture:
+ *
+ *   void Foo()
+ *   {
+ *     nsRefPtr<Bar> bar = new Bar();
+ *     NS_DispatchToMainThread(media::NewRunnableFrom([bar]() mutable {
+ *       // use bar
+ *     });
+ *   }
+ *
+ * Capture is by-copy by default, so the nsRefPtr 'bar' is safely copied for
+ * access on the other thread (threadsafe refcounting in bar is assumed).
+ *
+ * The 'mutable' keyword is only needed for non-const access to bar.
+ */
 
-template<typename ValueType>
-class PledgeRunnable : public Pledge<ValueType>, public nsRunnable
+template<typename OnRunType>
+class LambdaRunnable : public nsRunnable
 {
 public:
-  template<typename OnRunType>
-  static PledgeRunnable<ValueType>*
-  New(OnRunType aOnRun)
-  {
-    class P : public PledgeRunnable<ValueType>
-    {
-    public:
-      explicit P(OnRunType& aOnRun)
-      : mOriginThread(NS_GetCurrentThread())
-      , mOnRun(aOnRun)
-      , mHasRun(false) {}
-    private:
-      virtual ~P() {}
-      NS_IMETHODIMP
-      Run()
-      {
-        if (!mHasRun) {
-          P::mResult = mOnRun(P::mValue);
-          mHasRun = true;
-          return mOriginThread->Dispatch(this, NS_DISPATCH_NORMAL);
-        }
-        bool on;
-        MOZ_RELEASE_ASSERT(NS_SUCCEEDED(mOriginThread->IsOnCurrentThread(&on)));
-        MOZ_RELEASE_ASSERT(on);
-
-        if (NS_SUCCEEDED(P::mResult)) {
-          P::Resolve();
-        } else {
-          P::Reject(P::mResult);
-        }
-        return NS_OK;
-      }
-      nsCOMPtr<nsIThread> mOriginThread;
-      OnRunType mOnRun;
-      bool mHasRun;
-    };
-
-    return new P(aOnRun);
-  }
-
-protected:
-  virtual ~PledgeRunnable() {}
-};
-
-// General purpose runnable with an eye toward lambdas
-
-namespace CallbackRunnable
-{
-template<typename OnRunType>
-class Impl : public nsRunnable
-{
-public:
-  explicit Impl(OnRunType& aOnRun) : mOnRun(aOnRun) {}
+  explicit LambdaRunnable(OnRunType& aOnRun) : mOnRun(aOnRun) {}
 private:
   NS_IMETHODIMP
   Run()
   {
     return mOnRun();
   }
   OnRunType mOnRun;
 };
 
 template<typename OnRunType>
-Impl<OnRunType>*
-New(OnRunType aOnRun)
+LambdaRunnable<OnRunType>*
+NewRunnableFrom(OnRunType aOnRun)
 {
-  return new Impl<OnRunType>(aOnRun);
+  return new LambdaRunnable<OnRunType>(aOnRun);
 }
-}
+
+/* media::CoatCheck - There and back again. Park an object in exchange for an id.
+ *
+ * A common problem with calling asynchronous functions that do work on other
+ * threads or processes is how to pass in a heap object for use once the
+ * function completes, without requiring that object to have threadsafe
+ * refcounting, contain mutexes, be marshaled, or leak if things fail
+ * (or worse, intermittent use-after-free because of lifetime issues).
+ *
+ * One solution is to set up a coat-check on the caller side, park your object
+ * in exchange for an id, and send the id. Common in IPC, but equally useful
+ * for same-process thread-hops, because by never leaving the thread there's
+ * no need for objects to be threadsafe or use threadsafe refcounting. E.g.
+ *
+ *   class FooDoer
+ *   {
+ *     CoatCheck<Foo> mOutstandingFoos;
+ *
+ *   public:
+ *     void DoFoo()
+ *     {
+ *       nsRefPtr<Foo> foo = new Foo();
+ *       uint32_t requestId = mOutstandingFoos.Append(foo);
+ *       sChild->SendFoo(requestId);
+ *     }
+ *
+ *     void RecvFooResponse(uint32_t requestId)
+ *     {
+ *       nsRefPtr<Foo> foo = mOutstandingFoos.Remove(requestId);
+ *       if (foo) {
+ *         // use foo
+ *       }
+ *     }
+ *   };
+ *
+ * If you read media::Pledge earlier, here's how this is useful for pledges:
+ *
+ *   class FooGetter
+ *   {
+ *     CoatCheck<Foo> mOutstandingPledges;
+ *
+ *   public:
+ *     already_addRefed<Pledge<Foo>> GetFooAsynchronously()
+ *     {
+ *       nsRefPtr<Pledge<Foo>> p = new Pledge<Foo>();
+ *       uint32_t requestId = mOutstandingPledges.Append(p);
+ *       sChild->SendFoo(requestId);
+ *       return p.forget();
+ *     }
+ *
+ *     void RecvFooResponse(uint32_t requestId, const Foo& fooResult)
+ *     {
+ *       nsRefPtr<Foo> p = mOutstandingPledges.Remove(requestId);
+ *       if (p) {
+ *         p->Resolve(fooResult);
+ *       }
+ *     }
+ *   };
+ *
+ * This helper is currently optimized for very small sets (i.e. not optimized).
+ * It is also not thread-safe as the whole point is to stay on the same thread.
+ */
+
+template<class T>
+class CoatCheck
+{
+public:
+  typedef std::pair<uint32_t, nsRefPtr<T>> Element;
+
+  uint32_t Append(T& t)
+  {
+    uint32_t id = GetNextId();
+    mElements.AppendElement(Element(id, nsRefPtr<T>(&t)));
+    return id;
+  }
+
+  already_AddRefed<T> Remove(uint32_t aId)
+  {
+    for (auto& element : mElements) {
+      if (element.first == aId) {
+        nsRefPtr<T> ref;
+        ref.swap(element.second);
+        mElements.RemoveElement(element);
+        return ref.forget();
+      }
+    }
+    MOZ_ASSERT_UNREACHABLE("Received id with no matching parked object!");
+    return nullptr;
+  }
+
+private:
+  static uint32_t GetNextId()
+  {
+    static uint32_t counter = 0;
+    return ++counter;
+  };
+  nsAutoTArray<Element, 3> mElements;
+};
 
 }
 }
 
 #endif // mozilla_MediaUtils_h
--- a/dom/media/systemservices/OpenSLESProvider.cpp
+++ b/dom/media/systemservices/OpenSLESProvider.cpp
@@ -10,17 +10,17 @@
 #include <dlfcn.h>
 #include <SLES/OpenSLES_Android.h>
 #include <SLES/OpenSLES_AndroidConfiguration.h>
 
 // NSPR_LOG_MODULES=OpenSLESProvider:5
 #undef LOG
 #undef LOG_ENABLED
 PRLogModuleInfo *gOpenSLESProviderLog;
-#define LOG(args) PR_LOG(gOpenSLESProviderLog, PR_LOG_DEBUG, args)
+#define LOG(args) MOZ_LOG(gOpenSLESProviderLog, PR_LOG_DEBUG, args)
 #define LOG_ENABLED() PR_LOG_TEST(gOpenSLESProviderLog, PR_LOG_DEBUG)
 
 namespace mozilla {
 
 OpenSLESProvider::OpenSLESProvider()
   : mLock("OpenSLESProvider.mLock"),
     mSLEngine(nullptr),
     mSLEngineUsers(0),
new file mode 100644
--- /dev/null
+++ b/dom/media/test/crashtests/1127188.html
@@ -0,0 +1,3 @@
+<script>
+  (new AudioContext).close();
+</script>
--- a/dom/media/test/crashtests/crashtests.list
+++ b/dom/media/test/crashtests/crashtests.list
@@ -73,12 +73,13 @@ load buffer-source-ended-1.html
 HTTP load media-element-source-seek-1.html
 load offline-buffer-source-ended-1.html
 load oscillator-ended-1.html
 load oscillator-ended-2.html
 load 1080986.html
 load 1158427.html
 load 1157994.html
 load 1122218.html
+load 1127188.html
 include ../../mediasource/test/crashtests/crashtests.list
 
 # This needs to run at the end to avoid leaking busted state into other tests.
 skip-if(B2G||winWidget||OSX==1006||OSX==1010&&isDebugBuild) load 691096-1.html
--- a/dom/media/test/mochitest.ini
+++ b/dom/media/test/mochitest.ini
@@ -395,16 +395,17 @@ skip-if = toolkit == 'android' # bug 104
 # in future however, so I'm not removing the test, just disabling it.
 [test_eme_persistent_sessions.html]
 skip-if = toolkit == 'android' # bug 1043403
 [test_eme_playback.html]
 skip-if = toolkit == 'android' # bug 1043403
 [test_eme_requestKeySystemAccess.html]
 skip-if = toolkit == 'android' # bug 1043403
 [test_eme_stream_capture_blocked.html]
+tags=msg
 skip-if = toolkit == 'android' || (os == 'win' && !debug) # bug 1043403, bug 1140675
 [test_empty_resource.html]
 [test_error_in_video_document.html]
 skip-if = toolkit == 'android' || (os == 'win' && !debug) || (os == 'mac' && !debug) # bug 608634
 [test_error_on_404.html]
 [test_fastSeek.html]
 skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_fastSeek-forwards.html]
@@ -422,41 +423,61 @@ skip-if = (toolkit == 'android' && proce
 [test_load_source.html]
 [test_loop.html]
 skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_media_selection.html]
 skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_media_sniffer.html]
 skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_mediarecorder_avoid_recursion.html]
+tags=msg
 [test_mediarecorder_creation.html]
+tags=msg
 [test_mediarecorder_creation_fail.html]
+tags=msg
 [test_mediarecorder_getencodeddata.html]
+tags=msg
 [test_mediarecorder_record_4ch_audiocontext.html]
+tags=msg
 [test_mediarecorder_record_audiocontext.html]
+tags=msg
 [test_mediarecorder_record_audiocontext_mlk.html]
+tags=msg
 [test_mediarecorder_record_audionode.html]
+tags=msg
 [test_mediarecorder_record_gum_video_timeslice.html]
+tags=msg
 skip-if = buildapp == 'b2g' || toolkit == 'android' # mimetype check, bug 969289
 [test_mediarecorder_record_immediate_stop.html]
+tags=msg
 [test_mediarecorder_record_no_timeslice.html]
+tags=msg
 skip-if = toolkit == 'gonk' && debug
 [test_mediarecorder_record_nosrc.html]
+tags=msg
 [test_mediarecorder_record_session.html]
+tags=msg
 [test_mediarecorder_record_startstopstart.html]
+tags=msg
 skip-if = toolkit == 'gonk' && debug
 [test_mediarecorder_record_stopms.html]
+tags=msg
 [test_mediarecorder_record_timeslice.html]
+tags=msg
 skip-if = toolkit == 'gonk' && debug
 [test_mediarecorder_reload_crash.html]
+tags=msg
 [test_mediarecorder_unsupported_src.html]
+tags=msg
 [test_mediarecorder_record_getdata_afterstart.html]
+tags=msg
 skip-if = toolkit == 'gonk' && debug
 [test_mediatrack_consuming_mediaresource.html]
 [test_mediatrack_consuming_mediastream.html]
+tags=msg
 [test_mediatrack_events.html]
 skip-if = toolkit == 'gonk' && debug # bug 1065924
 [test_mediatrack_parsing_ogg.html]
 [test_mediatrack_replay_from_end.html]
 [test_metadata.html]
 [test_mixed_principals.html]
 skip-if = true # bug 567954 and intermittent leaks
 [test_mozHasAudio.html]
@@ -525,28 +546,37 @@ skip-if = (toolkit == 'android' && proce
 [test_seekLies.html]
 [test_source.html]
 [test_source_media.html]
 [test_source_null.html]
 [test_source_write.html]
 [test_standalone.html]
 skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_streams_autoplay.html]
+tags=msg
 [test_streams_element_capture.html]
 #x86 only bug 914439, b2g desktop bug 752796
 skip-if = (toolkit == 'android' && processor == 'x86') || (buildapp == 'b2g' && toolkit != 'gonk')
+tags=msg
 [test_streams_element_capture_createObjectURL.html]
 skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
+tags=msg
 [test_streams_element_capture_playback.html]
+tags=msg
 [test_streams_element_capture_reset.html]
+tags=msg
 [test_streams_gc.html]
 skip-if = buildapp == 'b2g' && toolkit != 'gonk' # bug 1096270
+tags=msg
 [test_streams_individual_pause.html]
+tags=msg
 [test_streams_srcObject.html]
+tags=msg
 [test_streams_tracks.html]
+tags=msg
 [test_texttrack.html]
 [test_texttrackcue.html]
 [test_texttracklist.html]
 [test_texttrackregion.html]
 [test_timeupdate_small_files.html]
 skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_trackelementevent.html]
 [test_trackevent.html]
--- a/dom/media/tests/mochitest/identity/mochitest.ini
+++ b/dom/media/tests/mochitest/identity/mochitest.ini
@@ -1,16 +1,17 @@
 [DEFAULT]
 # strictContentSandbox - bug 1042735, Android 2.3 - bug 981881
 # won't run on b2g desktop tests - bug 1119993
 # broken HTTPS on b2g emulator - bug 1135339
 skip-if = (os == 'win' && strictContentSandbox) || android_version == '10' || android_version == '18' || (buildapp == 'b2g' && toolkit != 'gonk') || (buildapp == 'b2g' && toolkit == 'gonk') || buildapp == 'mulet'
 support-files =
   /.well-known/idp-proxy/idp.js
   identityPcTest.js
+tags = msg
 
 [test_idpproxy.html]
 support-files =
   /.well-known/idp-proxy/idp-redirect-http.js
   /.well-known/idp-proxy/idp-redirect-http.js^headers^
   /.well-known/idp-proxy/idp-redirect-http-trick.js
   /.well-known/idp-proxy/idp-redirect-http-trick.js^headers^
   /.well-known/idp-proxy/idp-redirect-https.js
--- a/dom/media/tests/mochitest/ipc/mochitest.ini
+++ b/dom/media/tests/mochitest/ipc/mochitest.ini
@@ -1,8 +1,9 @@
 [DEFAULT]
+tags=msg
 support-files =
   ipc.json
 
 skip-if = e10s
 
 [test_ipc.html]
 skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' #bug 910661 # b2g(nested ipc not working) b2g-debug(debug-only failure) b2g-desktop(nested ipc not working)
--- a/dom/media/tests/mochitest/mochitest.ini
+++ b/dom/media/tests/mochitest/mochitest.ini
@@ -1,10 +1,11 @@
 [DEFAULT]
 # strictContentSandbox - bug 1042735, Android 2.3 - bug 981881
+tags = msg webrtc
 skip-if = (os == 'win' && strictContentSandbox) || android_version == '10' || android_version == '18' || (buildapp == 'mulet')
 support-files =
   head.js
   dataChannel.js
   mediaStreamPlayback.js
   network.js
   nonTrickleIce.js
   pc.js
@@ -24,16 +25,18 @@ skip-if = toolkit == 'gonk' || buildapp 
 [test_dataChannel_basicDataOnly.html]
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g (Bug 1059867)
 [test_dataChannel_basicVideo.html]
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
 [test_dataChannel_bug1013809.html]
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g emulator seems to be too slow (Bug 1016498 and 1008080)
 [test_dataChannel_noOffer.html]
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g (Bug 1059867)
+[test_enumerateDevices.html]
+skip-if = buildapp == 'mulet'
 [test_getUserMedia_basicAudio.html]
 skip-if = (toolkit == 'gonk' || buildapp == 'mulet' && debug) # debug-only failure
 [test_getUserMedia_basicVideo.html]
 skip-if = (toolkit == 'gonk' || buildapp == 'mulet' && debug) # debug-only failure
 [test_getUserMedia_basicVideo_playAfterLoadedmetadata.html]
 skip-if = (toolkit == 'gonk' || buildapp == 'mulet' && debug) # debug-only failure
 [test_getUserMedia_basicScreenshare.html]
 skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' # no screenshare on b2g/android # Bug 1141029 Mulet parity with B2G Desktop for TC
@@ -186,12 +189,13 @@ skip-if = toolkit == 'gonk' || buildapp 
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g (Bug 1059867)
 [test_peerConnection_removeThenAddVideoTrackNoBundle.html]
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g (Bug 1059867)
 [test_peerConnection_addDataChannel.html]
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g (Bug 1059867)
 [test_peerConnection_addDataChannelNoBundle.html]
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g (Bug 1059867)
 [test_peerConnection_webAudio.html]
+tags = webaudio webrtc
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g (Bug 1059867)
 
 # Bug 950317: Hack for making a cleanup hook after finishing all WebRTC cases
 [test_zmedia_cleanup.html]
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_enumerateDevices.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <script src="mediaStreamPlayback.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+createHTML({ title: "Run enumerateDevices code", bug: "1046245" });
+/**
+  Tests covering enumerateDevices API. Exercise code.
+*/
+
+runTest(() => navigator.mediaDevices.enumerateDevices()
+  .then(devices => {
+    ok(devices.length > 0, "At least one device found");
+    devices.forEach(d => {
+      ok(d.kind == "videoinput" || d.kind == "audioinput", "Known device kind");
+      is(d.deviceId.length, 44, "Correct device id length");
+      ok(d.label.length !== undefined, "Device label: " + d.label);
+      is(d.groupId, "", "Don't support groupId yet");
+    });
+  }));
+
+</script>
+</pre>
+</body>
+</html>
--- a/dom/media/wave/WaveReader.cpp
+++ b/dom/media/wave/WaveReader.cpp
@@ -18,19 +18,19 @@
 #include <algorithm>
 
 namespace mozilla {
 
 // Un-comment to enable logging of seek bisections.
 //#define SEEK_LOGGING
 
 extern PRLogModuleInfo* gMediaDecoderLog;
-#define LOG(type, msg) PR_LOG(gMediaDecoderLog, type, msg)
+#define LOG(type, msg) MOZ_LOG(gMediaDecoderLog, type, msg)
 #ifdef SEEK_LOGGING
-#define SEEK_LOG(type, msg) PR_LOG(gMediaDecoderLog, type, msg)
+#define SEEK_LOG(type, msg) MOZ_LOG(gMediaDecoderLog, type, msg)
 #else
 #define SEEK_LOG(type, msg)
 #endif
 
 struct waveIdToName {
   uint32_t id;
   nsCString name;
 };
--- a/dom/media/webaudio/AudioBufferSourceNode.cpp
+++ b/dom/media/webaudio/AudioBufferSourceNode.cpp
@@ -170,17 +170,17 @@ public:
 
     if (aOutRate == mBufferSampleRate && !mResampler) {
       return;
     }
 
     if (!mResampler) {
       mChannels = aChannels;
       mResampler = speex_resampler_init(mChannels, mBufferSampleRate, aOutRate,
-                                        SPEEX_RESAMPLER_QUALITY_DEFAULT,
+                                        SPEEX_RESAMPLER_QUALITY_MIN,
                                         nullptr);
     } else {
       uint32_t currentOutSampleRate, currentInSampleRate;
       speex_resampler_get_rate(mResampler, &currentInSampleRate,
                                &currentOutSampleRate);
       if (currentOutSampleRate == static_cast<uint32_t>(aOutRate)) {
         return;
       }
--- a/dom/media/webaudio/AudioContext.cpp
+++ b/dom/media/webaudio/AudioContext.cpp
@@ -661,21 +661,19 @@ AudioContext::CurrentTime() const
                              StreamTimeToSeconds(stream->GetCurrentTime()));
 }
 
 void
 AudioContext::Shutdown()
 {
   mIsShutDown = true;
 
-  // We mute rather than suspending, because the delay between the ::Shutdown
-  // call and the CC would make us overbuffer in the MediaStreamGraph.
-  // See bug 936784 for details.
   if (!mIsOffline) {
-    Mute();
+    ErrorResult dummy;
+    nsRefPtr<Promise> ignored = Close(dummy);
   }
 
   // Release references to active nodes.
   // Active AudioNodes don't unregister in destructors, at which point the
   // Node is already unregistered.
   mActiveNodes.Clear();
 
   // For offline contexts, we can destroy the MediaStreamGraph at this point.
@@ -766,23 +764,29 @@ public:
                                 NS_LITERAL_STRING("statechange"),
                                 false, false);
   }
 
 private:
   nsRefPtr<AudioContext> mAudioContext;
 };
 
-
-
 void
 AudioContext::OnStateChanged(void* aPromise, AudioContextState aNewState)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
+  // This can happen if close() was called right after creating the
+  // AudioContext, before the context has switched to "running".
+  if (mAudioContextState == AudioContextState::Closed &&
+      aNewState == AudioContextState::Running &&
+      !aPromise) {
+    return;
+  }
+
   MOZ_ASSERT((mAudioContextState == AudioContextState::Suspended &&
               aNewState == AudioContextState::Running)   ||
              (mAudioContextState == AudioContextState::Running   &&
               aNewState == AudioContextState::Suspended) ||
              (mAudioContextState == AudioContextState::Running   &&
               aNewState == AudioContextState::Closed)    ||
              (mAudioContextState == AudioContextState::Suspended &&
               aNewState == AudioContextState::Closed)    ||
@@ -903,24 +907,28 @@ AudioContext::Close(ErrorResult& aRv)
   if (mAudioContextState == AudioContextState::Closed) {
     promise->MaybeResolve(NS_ERROR_DOM_INVALID_STATE_ERR);
     return promise.forget();
   }
 
   mCloseCalled = true;
 
   mPromiseGripArray.AppendElement(promise);
-  Graph()->ApplyAudioContextOperation(DestinationStream()->AsAudioNodeStream(),
-                                      AudioContextOperation::Close, promise);
 
+  // This can be called when freeing a document, and the streams are dead at
+  // this point, so we need extra null-checks.
   MediaStream* ds = DestinationStream();
   if (ds) {
-    ds->BlockStreamIfNeeded();
+    Graph()->ApplyAudioContextOperation(ds->AsAudioNodeStream(),
+                                        AudioContextOperation::Close, promise);
+
+    if (ds) {
+      ds->BlockStreamIfNeeded();
+    }
   }
-
   return promise.forget();
 }
 
 void
 AudioContext::UpdateNodeCount(int32_t aDelta)
 {
   bool firstNode = mNodeCount == 0;
   mNodeCount += aDelta;
--- a/dom/media/webaudio/MediaBufferDecoder.cpp
+++ b/dom/media/webaudio/MediaBufferDecoder.cpp
@@ -502,17 +502,22 @@ AsyncDecodeWebAudio(const char* aContent
     new MediaDecodeTask(aContentType, aBuffer, aLength, aDecodeJob);
   if (!task->CreateReader()) {
     nsCOMPtr<nsIRunnable> event =
       new ReportResultTask(aDecodeJob,
                            &WebAudioDecodeJob::OnFailure,
                            WebAudioDecodeJob::UnknownError);
     NS_DispatchToMainThread(event);
   } else {
-    task->Reader()->GetTaskQueue()->Dispatch(task);
+    // If we did this without a temporary:
+    //   task->Reader()->GetTaskQueue()->Dispatch(task.forget())
+    // we might evaluate the task.forget() before calling Reader(). Enforce
+    // a non-crashy order-of-operations.
+    MediaTaskQueue* taskQueue = task->Reader()->GetTaskQueue();
+    taskQueue->Dispatch(task.forget());
   }
 }
 
 WebAudioDecodeJob::WebAudioDecodeJob(const nsACString& aContentType,
                                      AudioContext* aContext,
                                      Promise* aPromise,
                                      DecodeSuccessCallback* aSuccessCallback,
                                      DecodeErrorCallback* aFailureCallback)
--- a/dom/media/webaudio/WaveShaperNode.cpp
+++ b/dom/media/webaudio/WaveShaperNode.cpp
@@ -82,22 +82,22 @@ public:
     if (aType == OverSampleType::None) {
       mBuffer.Clear();
       return;
     }
 
     mUpSampler = speex_resampler_init(aChannels,
                                       aSampleRate,
                                       aSampleRate * ValueOf(aType),
-                                      SPEEX_RESAMPLER_QUALITY_DEFAULT,
+                                      SPEEX_RESAMPLER_QUALITY_MIN,
                                       nullptr);
     mDownSampler = speex_resampler_init(aChannels,
                                         aSampleRate * ValueOf(aType),
                                         aSampleRate,
-                                        SPEEX_RESAMPLER_QUALITY_DEFAULT,
+                                        SPEEX_RESAMPLER_QUALITY_MIN,
                                         nullptr);
     mBuffer.SetLength(WEBAUDIO_BLOCK_SIZE*ValueOf(aType));
   }
 
   float* UpSample(uint32_t aChannel, const float* aInputData, uint32_t aBlocks)
   {
     uint32_t inSamples = WEBAUDIO_BLOCK_SIZE;
     uint32_t outSamples = WEBAUDIO_BLOCK_SIZE*aBlocks;
--- a/dom/media/webaudio/blink/HRTFDatabaseLoader.cpp
+++ b/dom/media/webaudio/blink/HRTFDatabaseLoader.cpp
@@ -51,25 +51,25 @@ TemporaryRef<HRTFDatabaseLoader> HRTFDat
     if (!s_loaderMap) {
         s_loaderMap = new nsTHashtable<LoaderByRateEntry>();
     }
 
     LoaderByRateEntry* entry = s_loaderMap->PutEntry(sampleRate);
     loader = entry->mLoader;
     if (loader) { // existing entry
         MOZ_ASSERT(sampleRate == loader->databaseSampleRate());
-        return loader;
+        return loader.forget();
     }
 
     loader = new HRTFDatabaseLoader(sampleRate);
     entry->mLoader = loader;
 
     loader->loadAsynchronously();
 
-    return loader;
+    return loader.forget();
 }
 
 HRTFDatabaseLoader::HRTFDatabaseLoader(float sampleRate)
     : m_refCnt(0)
     , m_threadLock("HRTFDatabaseLoader")
     , m_databaseLoaderThread(nullptr)
     , m_databaseSampleRate(sampleRate)
 {
--- a/dom/media/webaudio/blink/HRTFElevation.cpp
+++ b/dom/media/webaudio/blink/HRTFElevation.cpp
@@ -227,17 +227,17 @@ nsReturnRef<HRTFElevation> HRTFElevation
     static_assert(NumberOfTotalAzimuths ==
                   NumberOfRawAzimuths * InterpolationFactor, "Not a multiple");
 
     HRTFKernelList kernelListL;
     kernelListL.SetLength(NumberOfTotalAzimuths);
 
     SpeexResamplerState* resampler = sampleRate == rawSampleRate ? nullptr :
         speex_resampler_init(1, rawSampleRate, sampleRate,
-                             SPEEX_RESAMPLER_QUALITY_DEFAULT, nullptr);
+                             SPEEX_RESAMPLER_QUALITY_MIN, nullptr);
 
     // Load convolution kernels from HRTF files.
     int interpolatedIndex = 0;
     for (unsigned rawIndex = 0; rawIndex < NumberOfRawAzimuths; ++rawIndex) {
         // Don't let elevation exceed maximum for this azimuth.
         int maxElevation = maxElevations[rawIndex];
         int actualElevation = min(elevation, maxElevation);
 
--- a/dom/media/webaudio/test/blink/mochitest.ini
+++ b/dom/media/webaudio/test/blink/mochitest.ini
@@ -1,5 +1,6 @@
 [DEFAULT]
+tags=msg
 support-files =
   audio-testing.js
   convolution-testing.js
   panner-model-testing.js
--- a/dom/media/webaudio/test/mochitest.ini
+++ b/dom/media/webaudio/test/mochitest.ini
@@ -1,9 +1,11 @@
 [DEFAULT]
+tags=msg
+tags = webaudio
 skip-if = ((buildapp == 'mulet' || buildapp == 'b2g') && (toolkit != 'gonk' || debug)) || (os == 'win' && strictContentSandbox) #b2g-debug,b2g-desktop(bug 916135); strictContentSandbox(Bug 1042735)
 support-files =
   audio-expected.wav
   audio-mono-expected-2.wav
   audio-mono-expected.wav
   audio-quad.wav
   audio.ogv
   audioBufferSourceNodeNeutered_worker.js
--- a/dom/media/webaudio/test/test_audioContextSuspendResumeClose.html
+++ b/dom/media/webaudio/test/test_audioContextSuspendResumeClose.html
@@ -89,165 +89,158 @@ function tryLegalOpeerationsOnClosedCont
 // producing silence
 // ac1 produce a sine fed to a MediaStreamAudioDestinationNode
 // ac2 is connected to ac1 with a MediaStreamAudioSourceNode, and check that
 // there is silence when ac1 is suspended
 function testMultiContextOutput() {
   var ac1 = new AudioContext(),
       ac2 = new AudioContext();
 
-  var osc1 = ac1.createOscillator(),
-      mediaStreamDestination1 = ac1.createMediaStreamDestination();
+  ac1.onstatechange = function() {
+    ac1.onstatechange = null;
 
-  var mediaStreamAudioSourceNode2 =
-    ac2.createMediaStreamSource(mediaStreamDestination1.stream),
-    sp2 = ac2.createScriptProcessor(),
-    suspendCalled = false,
-    silentBuffersInARow = 0;
+    var osc1 = ac1.createOscillator(),
+        mediaStreamDestination1 = ac1.createMediaStreamDestination();
+
+    var mediaStreamAudioSourceNode2 =
+      ac2.createMediaStreamSource(mediaStreamDestination1.stream),
+      sp2 = ac2.createScriptProcessor(),
+      silentBuffersInARow = 0;
 
 
-  sp2.onaudioprocess = function(e) {
-    if (!suspendCalled) {
-      ac1.suspend();
-      suspendCalled = true;
-    } else {
-      // Wait until the context that produce the tone is actually suspended. It
-      // can be that the second context receives a little amount of data because
-      // of the buffering between the two contexts.
-      if (ac1.state == "suspended") {
-        var input = e.inputBuffer.getChannelData(0);
-        var silent = true;
-        for (var i = 0; i < input.length; i++) {
-          if (input[i] != 0.0) {
-            silent = false;
-          }
-        }
+    sp2.onaudioprocess = function(e) {
+      ac1.suspend().then(function() {
+        is(ac1.state, "suspended", "ac1 is suspended");
+        sp2.onaudioprocess = checkSilence;
+      });
+      sp2.onaudioprocess = null;
+    }
 
-        if (silent) {
-          silentBuffersInARow++;
-          if (silentBuffersInARow == 10) {
-            ok(true,
-                "MediaStreams produce silence when their input is blocked.");
-            sp2.onaudioprocess = null;
-            ac1.close();
-            ac2.close();
-            todo(false,"1");
-            finish();
-          }
-        } else {
-          is(silentBuffersInARow, 0,
-              "No non silent buffer inbetween silent buffers.");
+    function checkSilence(e) {
+      var input = e.inputBuffer.getChannelData(0);
+      var silent = true;
+      for (var i = 0; i < input.length; i++) {
+        if (input[i] != 0.0) {
+          silent = false;
         }
       }
-    }
-  }
+
+      todo(false, "input buffer is " + (silent ? "silent" : "noisy"));
 
-  osc1.connect(mediaStreamDestination1);
+      if (silent) {
+        silentBuffersInARow++;
+        if (silentBuffersInARow == 10) {
+          ok(true,
+              "MediaStreams produce silence when their input is blocked.");
+          sp2.onaudioprocess = null;
+          ac1.close();
+          ac2.close();
+          todo(false,"1");
+          finish();
+        }
+      } else {
+        is(silentBuffersInARow, 0,
+            "No non silent buffer inbetween silent buffers.");
+      }
+    }
 
-  mediaStreamAudioSourceNode2.connect(sp2);
-  osc1.start();
+    osc1.connect(mediaStreamDestination1);
+
+    mediaStreamAudioSourceNode2.connect(sp2);
+    osc1.start();
+  }
 }
 
 
 // Test that there is no buffering between contexts when connecting a running
 // AudioContext to a suspended AudioContext. Our ScriptProcessorNode does some
 // buffering internally, so we ensure this by using a very very low frequency
 // on a sine, and oberve that the phase has changed by a big enough margin.
 function testMultiContextInput() {
   var ac1 = new AudioContext(),
       ac2 = new AudioContext();
 
-  var osc1 = ac1.createOscillator(),
-      mediaStreamDestination1 = ac1.createMediaStreamDestination(),
-      sp1 = ac1.createScriptProcessor();
+  ac1.onstatechange = function() {
+    ac1.onstatechange = null;
 
-  var mediaStreamAudioSourceNode2 =
-    ac2.createMediaStreamSource(mediaStreamDestination1.stream),
-    sp2 = ac2.createScriptProcessor(),
-    resumed = false,
-    suspended = false,
-    countEventOnFirstSP = true,
-    eventReceived = 0;
+    var osc1 = ac1.createOscillator(),
+        mediaStreamDestination1 = ac1.createMediaStreamDestination(),
+        sp1 = ac1.createScriptProcessor();
+
+    var mediaStreamAudioSourceNode2 =
+      ac2.createMediaStreamSource(mediaStreamDestination1.stream),
+      sp2 = ac2.createScriptProcessor(),
+      eventReceived = 0;
 
 
-  osc1.frequency.value = 0.0001;
+    osc1.frequency.value = 0.0001;
 
-  // We keep a first ScriptProcessor to get a periodic callback, since we can't
-  // use setTimeout anymore.
-  sp1.onaudioprocess = function(e) {
-    if (countEventOnFirstSP) {
-      eventReceived++;
-    }
-    if (eventReceived > 3 && suspended) {
-      countEventOnFirstSP = false;
-      eventReceived = 0;
-      ac2.resume().then(function() {
-        resumed = true;
-      });
-    }
-  }
-
-  sp2.onaudioprocess = function(e) {
-    var inputBuffer = e.inputBuffer.getChannelData(0);
-    if (!resumed) {
-      // save the last value of the buffer before suspending.
-      sp2.value = inputBuffer[inputBuffer.length - 1];
-      ac2.suspend().then(function() {
-        suspended = true;
-      });
-    } else {
-      eventReceived++;
-      if (eventReceived == 3) {
+    function checkDiscontinuity(e) {
+      var inputBuffer = e.inputBuffer.getChannelData(0);
+      if (eventReceived++ == 3) {
         var delta = Math.abs(inputBuffer[1] - sp2.value),
             theoreticalIncrement = 2048 * 3 * Math.PI * 2 * osc1.frequency.value / ac1.sampleRate;
         ok(delta >= theoreticalIncrement,
             "Buffering did not occur when the context was suspended (delta:" + delta + " increment: " + theoreticalIncrement+")");
         ac1.close();
         ac2.close();
         sp1.onaudioprocess = null;
         sp2.onaudioprocess = null;
         todo(false, "2");
         finish();
       }
     }
-  }
 
-  osc1.connect(mediaStreamDestination1);
-  osc1.connect(sp1);
+    sp2.onaudioprocess = function(e) {
+      var inputBuffer = e.inputBuffer.getChannelData(0);
+      sp2.value = inputBuffer[inputBuffer.length - 1];
+      ac2.suspend().then(function() {
+          ac2.resume().then(function() {
+            sp2.onaudioprocess = checkDiscontinuity;
+            });
+          });
+    }
 
-  mediaStreamAudioSourceNode2.connect(sp2);
-  osc1.start();
+    osc1.connect(mediaStreamDestination1);
+    osc1.connect(sp1);
+
+    mediaStreamAudioSourceNode2.connect(sp2);
+    osc1.start();
+  }
 }
 
 // Test that ScriptProcessorNode's onaudioprocess don't get called while the
 // context is suspended/closed. It is possible that we get the handler called
 // exactly once after suspend, because the event has already been sent to the
 // event loop.
 function testScriptProcessNodeSuspended() {
   var ac = new AudioContext();
   var sp = ac.createScriptProcessor();
   var remainingIterations = 30;
   var afterResume = false;
-  sp.onaudioprocess = function() {
-    ok(ac.state == "running" || remainingIterations == 3, "If onaudioprocess is called, the context" +
-        " must be running (was " + ac.state + ", remainingIterations:" + remainingIterations +")");
-    remainingIterations--;
-    if (!afterResume) {
-      if (remainingIterations == 0) {
-        ac.suspend().then(function() {
-          ac.resume().then(function() {
-            remainingIterations = 30;
-            afterResume = true;
+  ac.onstatechange = function() {
+    ac.onstatechange = null;
+    sp.onaudioprocess = function() {
+      ok(ac.state == "running", "If onaudioprocess is called, the context" +
+          " must be running (was " + ac.state + ", remainingIterations:" + remainingIterations +")");
+      remainingIterations--;
+      if (!afterResume) {
+        if (remainingIterations == 0) {
+          ac.suspend().then(function() {
+            ac.resume().then(function() {
+              remainingIterations = 30;
+              afterResume = true;
+            });
           });
-        });
+        }
+      } else {
+        sp.onaudioprocess = null;
+        todo(false,"3");
+        finish();
       }
-    } else {
-      sp.onaudioprocess = null;
-      todo(false,"3");
-      finish();
     }
   }
   sp.connect(ac.destination);
 }
 
 // Take an AudioContext, make sure it switches to running when the audio starts
 // flowing, and then, call suspend, resume and close on it, tracking its state.
 function testAudioContext() {
--- a/dom/media/webm/IntelWebMVideoDecoder.cpp
+++ b/dom/media/webm/IntelWebMVideoDecoder.cpp
@@ -16,17 +16,17 @@
 #include "nestegg/nestegg.h"
 
 #define VPX_DONT_DEFINE_STDINT_TYPES
 #include "vpx/vp8dx.h"
 #include "vpx/vpx_decoder.h"
 
 #undef LOG
 PRLogModuleInfo* GetDemuxerLog();
-#define LOG(...) PR_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__))
+#define LOG(...) MOZ_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 
 using namespace mp4_demuxer;
 
 namespace mozilla {
 
 using layers::Image;
 using layers::LayerManager;
 using layers::LayersBackend;
--- a/dom/media/webm/WebMReader.cpp
+++ b/dom/media/webm/WebMReader.cpp
@@ -30,19 +30,19 @@
 #endif
 
 // Un-comment to enable logging of seek bisections.
 //#define SEEK_LOGGING
 
 #undef LOG
 
 #include "prprf.h"
-#define LOG(type, msg) PR_LOG(gMediaDecoderLog, type, msg)
+#define LOG(type, msg) MOZ_LOG(gMediaDecoderLog, type, msg)
 #ifdef SEEK_LOGGING
-#define SEEK_LOG(type, msg) PR_LOG(gMediaDecoderLog, type, msg)
+#define SEEK_LOG(type, msg) MOZ_LOG(gMediaDecoderLog, type, msg)
 #else
 #define SEEK_LOG(type, msg)
 #endif
 
 namespace mozilla {
 
 using namespace gfx;
 using namespace layers;
@@ -132,17 +132,17 @@ static void webm_log(nestegg * context,
       sevStr = "UNK";
       break;
   }
 
   va_start(args, format);
 
   PR_snprintf(msg, sizeof(msg), "%p [Nestegg-%s] ", context, sevStr);
   PR_vsnprintf(msg+strlen(msg), sizeof(msg)-strlen(msg), format, args);
-  PR_LOG(gNesteggLog, PR_LOG_DEBUG, (msg));
+  MOZ_LOG(gNesteggLog, PR_LOG_DEBUG, (msg));
 
   va_end(args);
 }
 
 ogg_packet InitOggPacket(const unsigned char* aData, size_t aLength,
                          bool aBOS, bool aEOS,
                          int64_t aGranulepos, int64_t aPacketNo)
 {
--- a/dom/media/webrtc/MediaEngineCameraVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineCameraVideoSource.cpp
@@ -11,18 +11,18 @@ namespace mozilla {
 using namespace mozilla::gfx;
 using dom::OwningLongOrConstrainLongRange;
 using dom::ConstrainLongRange;
 using dom::OwningDoubleOrConstrainDoubleRange;
 using dom::ConstrainDoubleRange;
 using dom::MediaTrackConstraintSet;
 
 extern PRLogModuleInfo* GetMediaManagerLog();
-#define LOG(msg) PR_LOG(GetMediaManagerLog(), PR_LOG_DEBUG, msg)
-#define LOGFRAME(msg) PR_LOG(GetMediaManagerLog(), 6, msg)
+#define LOG(msg) MOZ_LOG(GetMediaManagerLog(), PR_LOG_DEBUG, msg)
+#define LOGFRAME(msg) MOZ_LOG(GetMediaManagerLog(), 6, msg)
 
 // guts for appending data to the MSG track
 bool MediaEngineCameraVideoSource::AppendToTrack(SourceMediaStream* aSource,
                                                  layers::Image* aImage,
                                                  TrackID aID,
                                                  StreamTime delta)
 {
   MOZ_ASSERT(aSource);
--- a/dom/media/webrtc/MediaEngineGonkVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineGonkVideoSource.cpp
@@ -21,18 +21,18 @@
 namespace mozilla {
 
 using namespace mozilla::dom;
 using namespace mozilla::gfx;
 using namespace android;
 
 #undef LOG
 extern PRLogModuleInfo* GetMediaManagerLog();
-#define LOG(msg) PR_LOG(GetMediaManagerLog(), PR_LOG_DEBUG, msg)
-#define LOGFRAME(msg) PR_LOG(GetMediaManagerLog(), 6, msg)
+#define LOG(msg) MOZ_LOG(GetMediaManagerLog(), PR_LOG_DEBUG, msg)
+#define LOGFRAME(msg) MOZ_LOG(GetMediaManagerLog(), 6, msg)
 
 class MediaBufferListener : public GonkCameraSource::DirectBufferListener {
 public:
   MediaBufferListener(MediaEngineGonkVideoSource* aMediaEngine)
     : mMediaEngine(aMediaEngine)
   {
   }
 
--- a/dom/media/webrtc/MediaEngineWebRTC.cpp
+++ b/dom/media/webrtc/MediaEngineWebRTC.cpp
@@ -30,17 +30,17 @@ GetUserMediaLog()
 #endif
 
 #if defined(MOZ_B2G_CAMERA) && defined(MOZ_WIDGET_GONK)
 #include "ICameraControl.h"
 #include "MediaEngineGonkVideoSource.h"
 #endif
 
 #undef LOG
-#define LOG(args) PR_LOG(GetUserMediaLog(), PR_LOG_DEBUG, args)
+#define LOG(args) MOZ_LOG(GetUserMediaLog(), PR_LOG_DEBUG, args)
 
 namespace mozilla {
 
 MediaEngineWebRTC::MediaEngineWebRTC(MediaEnginePrefs &aPrefs)
     : mMutex("mozilla::MediaEngineWebRTC")
     , mScreenEngine(nullptr)
     , mBrowserEngine(nullptr)
     , mWinEngine(nullptr)
--- a/dom/media/webrtc/MediaEngineWebRTCAudio.cpp
+++ b/dom/media/webrtc/MediaEngineWebRTCAudio.cpp
@@ -32,18 +32,18 @@ static_assert(!(MAX_AEC_FIFO_DEPTH % 10)
 
 namespace mozilla {
 
 #ifdef LOG
 #undef LOG
 #endif
 
 extern PRLogModuleInfo* GetMediaManagerLog();
-#define LOG(msg) PR_LOG(GetMediaManagerLog(), PR_LOG_DEBUG, msg)
-#define LOG_FRAMES(msg) PR_LOG(GetMediaManagerLog(), 6, msg)
+#define LOG(msg) MOZ_LOG(GetMediaManagerLog(), PR_LOG_DEBUG, msg)
+#define LOG_FRAMES(msg) MOZ_LOG(GetMediaManagerLog(), 6, msg)
 
 /**
  * Webrtc audio source.
  */
 NS_IMPL_ISUPPORTS0(MediaEngineWebRTCAudioSource)
 
 // XXX temp until MSG supports registration
 StaticRefPtr<AudioOutputObserver> gFarendObserver;
--- a/dom/media/webrtc/MediaEngineWebRTCVideo.cpp
+++ b/dom/media/webrtc/MediaEngineWebRTCVideo.cpp
@@ -14,18 +14,18 @@
 namespace mozilla {
 
 using namespace mozilla::gfx;
 using dom::ConstrainLongRange;
 using dom::ConstrainDoubleRange;
 using dom::MediaTrackConstraintSet;
 
 extern PRLogModuleInfo* GetMediaManagerLog();
-#define LOG(msg) PR_LOG(GetMediaManagerLog(), PR_LOG_DEBUG, msg)
-#define LOGFRAME(msg) PR_LOG(GetMediaManagerLog(), 6, msg)
+#define LOG(msg) MOZ_LOG(GetMediaManagerLog(), PR_LOG_DEBUG, msg)
+#define LOGFRAME(msg) MOZ_LOG(GetMediaManagerLog(), 6, msg)
 
 /**
  * Webrtc video source.
  */
 
 NS_IMPL_ISUPPORTS0(MediaEngineWebRTCVideoSource)
 
 int
--- a/dom/media/webspeech/recognition/SpeechRecognition.cpp
+++ b/dom/media/webspeech/recognition/SpeechRecognition.cpp
@@ -53,17 +53,17 @@ GetSpeechRecognitionLog()
 {
   static PRLogModuleInfo* sLog;
   if (!sLog) {
     sLog = PR_NewLogModule("SpeechRecognition");
   }
 
   return sLog;
 }
-#define SR_LOG(...) PR_LOG(GetSpeechRecognitionLog(), PR_LOG_DEBUG, (__VA_ARGS__))
+#define SR_LOG(...) MOZ_LOG(GetSpeechRecognitionLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 
 already_AddRefed<nsISpeechRecognitionService>
 GetSpeechRecognitionService()
 {
   nsAutoCString speechRecognitionServiceCID;
 
   nsAdoptingCString prefValue =
   Preferences::GetCString(PREFERENCE_DEFAULT_RECOGNITION_SERVICE);
--- a/dom/media/webspeech/recognition/SpeechRecognition.h
+++ b/dom/media/webspeech/recognition/SpeechRecognition.h
@@ -40,17 +40,17 @@ namespace dom {
 #define TEST_PREFERENCE_FAKE_RECOGNITION_SERVICE "media.webspeech.test.fake_recognition_service"
 #define SPEECH_RECOGNITION_TEST_EVENT_REQUEST_TOPIC "SpeechRecognitionTest:RequestEvent"
 #define SPEECH_RECOGNITION_TEST_END_TOPIC "SpeechRecognitionTest:End"
 
 class GlobalObject;
 class SpeechEvent;
 
 PRLogModuleInfo* GetSpeechRecognitionLog();
-#define SR_LOG(...) PR_LOG(GetSpeechRecognitionLog(), PR_LOG_DEBUG, (__VA_ARGS__))
+#define SR_LOG(...) MOZ_LOG(GetSpeechRecognitionLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 
 already_AddRefed<nsISpeechRecognitionService> GetSpeechRecognitionService();
 
 class SpeechRecognition final : public DOMEventTargetHelper,
                                 public nsIObserver,
                                 public SupportsWeakPtr<SpeechRecognition>
 {
 public:
--- a/dom/media/webspeech/recognition/test/mochitest.ini
+++ b/dom/media/webspeech/recognition/test/mochitest.ini
@@ -1,9 +1,10 @@
 [DEFAULT]
+tags=msg
 support-files =
   head.js
   hello.ogg
   hello.ogg^headers^
   silence.ogg
   silence.ogg^headers^
 
 [test_abort.html]
--- a/dom/media/webspeech/synth/SpeechSynthesis.cpp
+++ b/dom/media/webspeech/synth/SpeechSynthesis.cpp
@@ -22,17 +22,17 @@ GetSpeechSynthLog()
   static PRLogModuleInfo* sLog = nullptr;
 
   if (!sLog) {
     sLog = PR_NewLogModule("SpeechSynthesis");
   }
 
   return sLog;
 }
-#define LOG(type, msg) PR_LOG(GetSpeechSynthLog(), type, msg)
+#define LOG(type, msg) MOZ_LOG(GetSpeechSynthLog(), type, msg)
 
 namespace mozilla {
 namespace dom {
 
 static PLDHashOperator
 TraverseCachedVoices(const nsAString& aKey, SpeechSynthesisVoice* aEntry, void* aData)
 {
   nsCycleCollectionTraversalCallback* cb = static_cast<nsCycleCollectionTraversalCallback*>(aData);
--- a/dom/media/webspeech/synth/nsSpeechTask.cpp
+++ b/dom/media/webspeech/synth/nsSpeechTask.cpp
@@ -11,17 +11,17 @@
 // GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
 // GetTickCount() and conflicts with nsSpeechTask::GetCurrentTime().
 #ifdef GetCurrentTime
 #undef GetCurrentTime
 #endif
 
 #undef LOG
 extern PRLogModuleInfo* GetSpeechSynthLog();
-#define LOG(type, msg) PR_LOG(GetSpeechSynthLog(), type, msg)
+#define LOG(type, msg) MOZ_LOG(GetSpeechSynthLog(), type, msg)
 
 namespace mozilla {
 namespace dom {
 
 class SynthStreamListener : public MediaStreamListener
 {
 public:
   explicit SynthStreamListener(nsSpeechTask* aSpeechTask) :
--- a/dom/media/webspeech/synth/nsSynthVoiceRegistry.cpp
+++ b/dom/media/webspeech/synth/nsSynthVoiceRegistry.cpp
@@ -19,17 +19,17 @@
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/unused.h"
 
 #include "SpeechSynthesisChild.h"
 #include "SpeechSynthesisParent.h"
 
 #undef LOG
 extern PRLogModuleInfo* GetSpeechSynthLog();
-#define LOG(type, msg) PR_LOG(GetSpeechSynthLog(), type, msg)
+#define LOG(type, msg) MOZ_LOG(GetSpeechSynthLog(), type, msg)
 
 namespace {
 
 void
 GetAllSpeechSynthActors(InfallibleTArray<mozilla::dom::SpeechSynthesisParent*>& aActors)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aActors.IsEmpty());
--- a/dom/media/webspeech/synth/test/mochitest.ini
+++ b/dom/media/webspeech/synth/test/mochitest.ini
@@ -1,9 +1,10 @@
 [DEFAULT]
+tags=msg
 support-files =
   common.js
   file_setup.html
   file_speech_queue.html
   file_speech_simple.html
   file_speech_cancel.html
   file_indirect_service_events.html
 
--- a/dom/media/wmf/WMFByteStream.cpp
+++ b/dom/media/wmf/WMFByteStream.cpp
@@ -21,17 +21,17 @@
 #include "mozilla/DebugOnly.h"
 #include "SharedThreadPool.h"
 #include <algorithm>
 #include <cassert>
 
 namespace mozilla {
 
 PRLogModuleInfo* gWMFByteStreamLog = nullptr;
-#define WMF_BS_LOG(...) PR_LOG(gWMFByteStreamLog, PR_LOG_DEBUG, (__VA_ARGS__))
+#define WMF_BS_LOG(...) MOZ_LOG(gWMFByteStreamLog, PR_LOG_DEBUG, (__VA_ARGS__))
 
 WMFByteStream::WMFByteStream(MediaResource* aResource,
                              WMFSourceReaderCallback* aSourceReaderCallback)
   : mSourceReaderCallback(aSourceReaderCallback),
     mResource(aResource),
     mReentrantMonitor("WMFByteStream.Data"),
     mOffset(0),
     mIsShutdown(false)
--- a/dom/media/wmf/WMFReader.cpp
+++ b/dom/media/wmf/WMFReader.cpp
@@ -29,17 +29,17 @@
 using namespace mozilla::gfx;
 using mozilla::layers::Image;
 using mozilla::layers::LayerManager;
 using mozilla::layers::LayersBackend;
 
 namespace mozilla {
 
 extern PRLogModuleInfo* gMediaDecoderLog;
-#define DECODER_LOG(...) PR_LOG(gMediaDecoderLog, PR_LOG_DEBUG, (__VA_ARGS__))
+#define DECODER_LOG(...) MOZ_LOG(gMediaDecoderLog, PR_LOG_DEBUG, (__VA_ARGS__))
 
 // Uncomment to enable verbose per-sample logging.
 //#define LOG_SAMPLE_DECODE 1
 
 WMFReader::WMFReader(AbstractMediaDecoder* aDecoder)
   : MediaDecoderReader(aDecoder),
     mSourceReader(nullptr),
     mAudioChannels(0),
--- a/dom/media/wmf/WMFSourceReaderCallback.cpp
+++ b/dom/media/wmf/WMFSourceReaderCallback.cpp
@@ -5,17 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WMFSourceReaderCallback.h"
 #include "WMFUtils.h"
 
 namespace mozilla {
 
 static PRLogModuleInfo* gWMFSourceReaderCallbackLog = nullptr;
-#define WMF_CB_LOG(...) PR_LOG(gWMFSourceReaderCallbackLog, PR_LOG_DEBUG, (__VA_ARGS__))
+#define WMF_CB_LOG(...) MOZ_LOG(gWMFSourceReaderCallbackLog, PR_LOG_DEBUG, (__VA_ARGS__))
 
 // IUnknown Methods
 STDMETHODIMP
 WMFSourceReaderCallback::QueryInterface(REFIID aIId, void **aInterface)
 {
   WMF_CB_LOG("WMFSourceReaderCallback::QueryInterface %s", GetGUIDName(aIId).get());
 
   if (aIId == IID_IMFSourceReaderCallback) {
--- a/dom/nfc/NfcContentHelper.js
+++ b/dom/nfc/NfcContentHelper.js
@@ -66,16 +66,18 @@ XPCOMUtils.defineLazyServiceGetter(this,
                                    "@mozilla.org/childprocessmessagemanager;1",
                                    "nsISyncMessageSender");
 
 function NfcContentHelper() {
   Services.obs.addObserver(this, NFC.TOPIC_MOZSETTINGS_CHANGED, false);
   Services.obs.addObserver(this, "xpcom-shutdown", false);
 
   this._requestMap = [];
+  this.initDOMRequestHelper(/* window */ null, NFC_IPC_MSG_NAMES);
+  this.eventListeners = {};
 }
 
 NfcContentHelper.prototype = {
   __proto__: DOMRequestIpcHelper.prototype,
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsINfcContentHelper,
                                          Ci.nsINfcBrowserAPI,
                                          Ci.nsISupportsWeakReference,
@@ -83,70 +85,21 @@ NfcContentHelper.prototype = {
   classID:   NFCCONTENTHELPER_CID,
   classInfo: XPCOMUtils.generateCI({
     classID:          NFCCONTENTHELPER_CID,
     classDescription: "NfcContentHelper",
     interfaces:       [Ci.nsINfcContentHelper,
                        Ci.nsINfcBrowserAPI]
   }),
 
-  _window: null,
   _requestMap: null,
-  _rfState: null,
-  _tabId: null,
-  eventListener: null,
-
-  init: function init(aWindow) {
-    if (aWindow == null) {
-      throw Components.Exception("Can't get window object",
-                                  Cr.NS_ERROR_UNEXPECTED);
-    }
-    this._window = aWindow;
-    this.initDOMRequestHelper(this._window, NFC_IPC_MSG_NAMES);
-
-    if (!NFC.DEBUG_CONTENT_HELPER && this._window.navigator.mozSettings) {
-      let lock = this._window.navigator.mozSettings.createLock();
-      var nfcDebug = lock.get(NFC.SETTING_NFC_DEBUG);
-      nfcDebug.onsuccess = function _nfcDebug() {
-        DEBUG = nfcDebug.result[NFC.SETTING_NFC_DEBUG];
-        updateDebug();
-      };
-    }
-
-    let info = cpmm.sendSyncMessage("NFC:QueryInfo")[0];
-    this._rfState = info.rfState;
-
-    // For now, we assume app will run in oop mode so we can get
-    // tab id for each app. Fix bug 1116449 if we are going to
-    // support in-process mode.
-    let docShell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
-                          .getInterface(Ci.nsIWebNavigation)
-                          .QueryInterface(Ci.nsIDocShell);
-    try {
-      this._tabId = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
-                            .getInterface(Ci.nsITabChild)
-                            .tabId;
-    } catch(e) {
-      // Only parent process does not have tab id, so in this case
-      // NfcContentHelper is used by system app. Use -1(tabId) to
-      // indicate its system app.
-      let inParent = Cc["@mozilla.org/xre/app-info;1"]
-                       .getService(Ci.nsIXULRuntime)
-                       .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
-      if (inParent) {
-        this._tabId = Ci.nsINfcBrowserAPI.SYSTEM_APP_ID;
-      } else {
-        throw Components.Exception("Can't get tab id in child process",
-                                   Cr.NS_ERROR_UNEXPECTED);
-      }
-    }
-  },
+  eventListeners: null,
 
   queryRFState: function queryRFState() {
-    return this._rfState;
+    return cpmm.sendSyncMessage("NFC:QueryInfo")[0].rfState;
   },
 
   setFocusApp: function setFocusApp(tabId, isFocus) {
     cpmm.sendAsyncMessage("NFC:SetFocusApp", {
       tabId: tabId,
       isFocus: isFocus
     });
   },
@@ -219,19 +172,37 @@ NfcContentHelper.prototype = {
 
   notifySendFileStatus: function notifySendFileStatus(status, requestId) {
     cpmm.sendAsyncMessage("NFC:NotifySendFileStatus", {
       status: status,
       requestId: requestId
     });
   },
 
-  addEventListener: function addEventListener(listener) {
-    this.eventListener = listener;
-    cpmm.sendAsyncMessage("NFC:AddEventListener", { tabId: this._tabId });
+  addEventListener: function addEventListener(listener, tabId) {
+    let _window = listener.window;
+
+    // TODO Bug 1166210 - enable NFC debug for child process.
+    if (!NFC.DEBUG_CONTENT_HELPER && _window.navigator.mozSettings) {
+      let lock = _window.navigator.mozSettings.createLock();
+      var nfcDebug = lock.get(NFC.SETTING_NFC_DEBUG);
+      nfcDebug.onsuccess = function _nfcDebug() {
+        DEBUG = nfcDebug.result[NFC.SETTING_NFC_DEBUG];
+        updateDebug();
+      };
+    }
+
+    this.eventListeners[tabId] = listener;
+    cpmm.sendAsyncMessage("NFC:AddEventListener", { tabId: tabId });
+  },
+
+  removeEventListener: function removeEventListener(tabId) {
+    delete this.eventListeners[tabId];
+
+    cpmm.sendAsyncMessage("NFC:RemoveEventListener", { tabId: tabId });
   },
 
   registerTargetForPeerReady: function registerTargetForPeerReady(appId) {
     cpmm.sendAsyncMessage("NFC:RegisterPeerReadyTarget", { appId: appId });
   },
 
   unregisterTargetForPeerReady: function unregisterTargetForPeerReady(appId) {
     cpmm.sendAsyncMessage("NFC:UnregisterPeerReadyTarget", { appId: appId });
@@ -312,55 +283,17 @@ NfcContentHelper.prototype = {
       case "NFC:WriteNDEFResponse": // Fall through.
       case "NFC:MakeReadOnlyResponse":
       case "NFC:FormatResponse":
       case "NFC:NotifySendFileStatusResponse":
       case "NFC:ChangeRFStateResponse":
         this.handleGeneralResponse(result);
         break;
       case "NFC:DOMEvent":
-        switch (result.event) {
-          case NFC.PEER_EVENT_READY:
-            this.eventListener.notifyPeerFound(result.sessionToken, /* isPeerReady */ true);
-            break;
-          case NFC.PEER_EVENT_FOUND:
-            this.eventListener.notifyPeerFound(result.sessionToken);
-            break;
-          case NFC.PEER_EVENT_LOST:
-            this.eventListener.notifyPeerLost(result.sessionToken);
-            break;
-          case NFC.TAG_EVENT_FOUND:
-            let ndefInfo = null;
-            if (result.tagType !== undefined &&
-                result.maxNDEFSize !== undefined &&
-                result.isReadOnly !== undefined &&
-                result.isFormatable !== undefined) {
-              ndefInfo = new TagNDEFInfo(result.tagType,
-                                         result.maxNDEFSize,
-                                         result.isReadOnly,
-                                         result.isFormatable);
-            }
-
-            let tagInfo = new TagInfo(result.techList, result.tagId);
-            this.eventListener.notifyTagFound(result.sessionToken,
-                                              tagInfo,
-                                              ndefInfo,
-                                              result.records);
-            break;
-          case NFC.TAG_EVENT_LOST:
-            this.eventListener.notifyTagLost(result.sessionToken);
-            break;
-          case NFC.RF_EVENT_STATE_CHANGED:
-            this._rfState = result.rfState;
-            this.eventListener.notifyRFStateChanged(this._rfState);
-            break;
-          case NFC.FOCUS_CHANGED:
-            this.eventListener.notifyFocusChanged(result.focus);
-            break;
-        }
+        this.handleDOMEvent(result);
         break;
     }
   },
 
   handle: function handle(name, result) {
     switch (name) {
       case NFC.SETTING_NFC_DEBUG:
         DEBUG = result;
@@ -394,26 +327,17 @@ NfcContentHelper.prototype = {
     }
     delete this._requestMap[requestId];
 
     if (result.errorMsg) {
       callback.notifyError(result.errorMsg);
       return;
     }
 
-    let ndefMsg = new this._window.Array();
-    let records = result.records;
-    for (let i = 0; i < records.length; i++) {
-      let record = records[i];
-      ndefMsg.push(new this._window.MozNDEFRecord({tnf: record.tnf,
-                                                   type: record.type,
-                                                   id: record.id,
-                                                   payload: record.payload}));
-    }
-    callback.notifySuccessWithNDEFRecords(ndefMsg);
+    callback.notifySuccessWithNDEFRecords(result.records);
   },
 
   handleCheckP2PRegistrationResponse: function handleCheckP2PRegistrationResponse(result) {
     let requestId = result.requestId;
     let callback = this._requestMap[requestId];
     if (!callback) {
       debug("not firing message handleCheckP2PRegistrationResponse for id: " + requestId);
       return;
@@ -436,16 +360,63 @@ NfcContentHelper.prototype = {
 
     if (result.errorMsg) {
       callback.notifyError(result.errorMsg);
       return;
     }
 
     callback.notifySuccessWithByteArray(result.response);
   },
+
+  handleDOMEvent: function handleDOMEvent(result) {
+    let listener = this.eventListeners[result.tabId];
+    if (!listener) {
+      debug("no listener for tabId " + result.tabId);
+      return;
+    }
+
+    switch (result.event) {
+      case NFC.PEER_EVENT_READY:
+        listener.notifyPeerFound(result.sessionToken, /* isPeerReady */ true);
+        break;
+      case NFC.PEER_EVENT_FOUND:
+        listener.notifyPeerFound(result.sessionToken);
+        break;
+      case NFC.PEER_EVENT_LOST:
+        listener.notifyPeerLost(result.sessionToken);
+        break;
+      case NFC.TAG_EVENT_FOUND:
+        let ndefInfo = null;
+        if (result.tagType !== undefined &&
+            result.maxNDEFSize !== undefined &&
+            result.isReadOnly !== undefined &&
+            result.isFormatable !== undefined) {
+          ndefInfo = new TagNDEFInfo(result.tagType,
+                                     result.maxNDEFSize,
+                                     result.isReadOnly,
+                                     result.isFormatable);
+        }
+
+        let tagInfo = new TagInfo(result.techList, result.tagId);
+        listener.notifyTagFound(result.sessionToken,
+                                          tagInfo,
+                                          ndefInfo,
+                                          result.records);
+        break;
+      case NFC.TAG_EVENT_LOST:
+        listener.notifyTagLost(result.sessionToken);
+        break;
+      case NFC.RF_EVENT_STATE_CHANGED:
+        listener.notifyRFStateChanged(result.rfState);
+        break;
+      case NFC.FOCUS_CHANGED:
+        listener.notifyFocusChanged(result.focus);
+        break;
+    }
+  }
 };
 
 function TagNDEFInfo(tagType, maxNDEFSize, isReadOnly, isFormatable) {
   this.tagType = tagType;
   this.maxNDEFSize = maxNDEFSize;
   this.isReadOnly = isReadOnly;
   this.isFormatable = isFormatable;
 }
--- a/dom/nfc/gonk/Nfc.js
+++ b/dom/nfc/gonk/Nfc.js
@@ -52,16 +52,17 @@ updateDebug();
 
 const NFC_CONTRACTID = "@mozilla.org/nfc;1";
 const NFC_CID =
   Components.ID("{2ff24790-5e74-11e1-b86c-0800200c9a66}");
 
 const NFC_IPC_MSG_ENTRIES = [
   { permission: null,
     messages: ["NFC:AddEventListener",
+               "NFC:RemoveEventListener",
                "NFC:QueryInfo",
                "NFC:CallDefaultFoundHandler",
                "NFC:CallDefaultLostHandler"] },
 
   { permission: "nfc",
     messages: ["NFC:ReadNDEF",
                "NFC:WriteNDEF",
                "NFC:MakeReadOnly",
@@ -214,16 +215,17 @@ XPCOMUtils.defineLazyGetter(this, "gMess
     },
 
     notifyDOMEvent: function notifyDOMEvent(target, options) {
       if (!target) {
         dump("invalid target");
         return;
       }
 
+      options.tabId = this.focusApp;
       target.sendAsyncMessage("NFC:DOMEvent", options);
     },
 
     setFocusApp: function setFocusApp(id, isFocus) {
       // if calling setNFCFocus(true) on the browser-element which is already
       // focused, or calling setNFCFocus(false) on the browser-element which has
       // lost focus already, ignore.
       if (isFocus == (id == this.focusApp)) {
@@ -250,22 +252,26 @@ XPCOMUtils.defineLazyGetter(this, "gMess
       }
 
       this.eventListeners[id] = target;
     },
 
     removeEventListener: function removeEventListener(target) {
       for (let id in this.eventListeners) {
         if (target == this.eventListeners[id]) {
-          delete this.eventListeners[id];
+          this.removeEventListenerById(id);
           break;
         }
       }
     },
 
+    removeEventListenerById: function removeEventListenerById(id) {
+      delete this.eventListeners[id];
+    },
+
     checkP2PRegistration: function checkP2PRegistration(message) {
       let target = this.peerTargets[message.data.appId];
       let sessionToken = SessionHelper.getCurrentP2PToken();
       let isValid = (sessionToken != null) && (target != null);
       let respMsg = { requestId: message.data.requestId };
       if (!isValid) {
         respMsg.errorMsg = this.nfc.getErrorMessage(NFC.NFC_GECKO_ERROR_P2P_REG_INVALID);
       }
@@ -379,16 +385,19 @@ XPCOMUtils.defineLazyGetter(this, "gMess
 
       switch (message.name) {
         case "NFC:SetFocusApp":
           this.setFocusApp(message.data.tabId, message.data.isFocus);
           return null;
         case "NFC:AddEventListener":
           this.addEventListener(message.target, message.data.tabId);
           return null;
+        case "NFC:RemoveEventListener":
+          this.removeEventListenerById(message.data.tabId);
+          return null;
         case "NFC:RegisterPeerReadyTarget":
           this.registerPeerReadyTarget(message.target, message.data.appId);
           return null;
         case "NFC:UnregisterPeerReadyTarget":
           this.unregisterPeerReadyTarget(message.data.appId);
           return null;
         case "NFC:CheckP2PRegistration":
           this.checkP2PRegistration(message);
--- a/dom/nfc/nsINfcContentHelper.idl
+++ b/dom/nfc/nsINfcContentHelper.idl
@@ -26,17 +26,17 @@ interface nsITagNDEFInfo : nsISupports
 
   readonly attribute long maxNDEFSize;
 
   readonly attribute boolean isReadOnly;
 
   readonly attribute boolean isFormatable;
 };
 
-[scriptable, uuid(151b4024-0443-434f-99ca-47ec247508ce)]
+[scriptable, uuid(86e46a0c-016d-4e5d-9fb5-789eb71848a1)]
 interface nsINfcEventListener : nsISupports
 {
   /**
    * Callback function used to notify tagfound.
    *
    * @param sessionToken
    *        SessionToken received from parent process
    * @param tagInfo
@@ -87,16 +87,21 @@ interface nsINfcEventListener : nsISuppo
 
   /**
    * Callback function used to notify focus changed.
    *
    * @param focus
    *        focus value receveid from parent process.
    */
   void notifyFocusChanged(in boolean focus);
+
+  /**
+   * The window object of this event listener.
+   */
+  readonly attribute nsIDOMWindow window;
 };
 
 [scriptable, uuid(6c913015-9658-46a9-88d9-6ecfda2bd020)]
 interface nsINfcRequestCallback : nsISupports
 {
   DOMString getCallbackId();
 
   void notifySuccess();
@@ -114,21 +119,19 @@ interface nsINfcRequestCallback : nsISup
 interface nsINfcBrowserAPI : nsISupports
 {
   const int32_t SYSTEM_APP_ID = -1;
 
   void setFocusApp(in uint64_t tabId,
                    in boolean isFocus);
 };
 
-[scriptable, uuid(9cf841c9-0347-4564-99e5-18c0f74eca4d)]
+[scriptable, uuid(75f0c8c0-2e5a-491f-a75d-4f3849c4feec)]
 interface nsINfcContentHelper : nsISupports
 {
-  void init(in nsIDOMWindow window);
-
   /**
    * Read current NDEF data on the tag.
    *
    * @param sessionToken
    *        Current token
    *
    * @param callback
    *        Called when request is finished
@@ -196,17 +199,17 @@ interface nsINfcContentHelper : nsISuppo
    *
    */
   void transceive(in DOMString sessionToken,
                   in DOMString technology,
                   in nsIVariant command,
                   in nsINfcRequestCallback callback);
 
   /**
-   * Get current RF state.
+   * Get current RF state. This function will be blocking.
    */
   DOMString queryRFState();
 
   /**
    * Initiate send file operation.
    *
    * @param blob
    *        Raw data of the file to be sent. This object represents a file-like
@@ -223,18 +226,28 @@ interface nsINfcContentHelper : nsISuppo
                 in DOMString sessionToken,
                 in nsINfcRequestCallback callback);
 
   /**
    * Add the event listener.
    *
    * @param listener
    *        An instance of the nsINfcEventListener.
+   * @param tabId
+   *        The tab ID of the listener.
    */
-  void addEventListener(in nsINfcEventListener listener);
+  void addEventListener(in nsINfcEventListener listener, in uint64_t tabId);
+
+  /**
+   * Remove event listener.
+   *
+   * @param tabId
+   *        The tabId provided in addEventListener.
+   */
+  void removeEventListener(in uint64_t tabId);
 
   /**
    * Register the given application id with parent process
    *
    * @param appId
    *        Application ID to be registered
    */
   void registerTargetForPeerReady(in unsigned long appId);
--- a/dom/nfc/nsNfc.js
+++ b/dom/nfc/nsNfc.js
@@ -68,17 +68,26 @@ NfcCallback.prototype = {
   },
 
   notifySuccessWithNDEFRecords: function notifySuccessWithNDEFRecords(aRecords) {
     let resolver = this.takePromiseResolver(atob(this._requestId));
     if (!resolver) {
       debug("can not find promise resolver for id: " + this._requestId);
       return;
     }
-    resolver.resolve(aRecords);
+
+    let records = new this._window.Array();
+    for (let i = 0; i < aRecords.length; i++) {
+      let record = aRecords[i];
+      records.push(new this._window.MozNDEFRecord({tnf: record.tnf,
+                                                   type: record.type,
+                                                   id: record.id,
+                                                   payload: record.payload}));
+    }
+    resolver.resolve(records);
   },
 
   notifySuccessWithByteArray: function notifySuccessWithByteArray(aArray) {
     let resolver = this.takePromiseResolver(atob(this._requestId));
     if (!resolver) {
       debug("can not find promise resolver for id: " + this._requestId);
       return;
     }
@@ -329,162 +338,214 @@ function MozNFCImpl() {
     debug("No NFC support.");
   }
 
   this.eventService = Cc["@mozilla.org/eventlistenerservice;1"]
                         .getService(Ci.nsIEventListenerService);
 }
 MozNFCImpl.prototype = {
   _nfcContentHelper: null,
-  _window: null,
+  window: null,
+  _tabId: null,
+  _innerWindowId: null,
   _rfState: null,
   _contentObj: null,
   nfcPeer: null,
   nfcTag: null,
   eventService: null,
 
   init: function init(aWindow) {
     debug("MozNFCImpl init called");
-    this._window = aWindow;
+    this.window = aWindow;
+    let util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+                      .getInterface(Ci.nsIDOMWindowUtils);
+    this._innerWindowId = util.currentInnerWindowID;
+
     this.defineEventHandlerGetterSetter("ontagfound");
     this.defineEventHandlerGetterSetter("ontaglost");
     this.defineEventHandlerGetterSetter("onpeerready");
     this.defineEventHandlerGetterSetter("onpeerfound");
     this.defineEventHandlerGetterSetter("onpeerlost");
 
+    Services.obs.addObserver(this, "inner-window-destroyed",
+                             /* weak-ref */ false);
+
     if (this._nfcContentHelper) {
-      this._nfcContentHelper.init(aWindow);
-      this._nfcContentHelper.addEventListener(this);
+      this._tabId = this.getTabId(aWindow);
+      this._nfcContentHelper.addEventListener(this, this._tabId);
       this._rfState = this._nfcContentHelper.queryRFState();
     }
   },
 
+  getTabId: function getTabId(aWindow) {
+    let tabId;
+    // For now, we assume app will run in oop mode so we can get
+    // tab id for each app. Fix bug 1116449 if we are going to
+    // support in-process mode.
+    let docShell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+                          .getInterface(Ci.nsIWebNavigation)
+                          .QueryInterface(Ci.nsIDocShell);
+    try {
+      tabId = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
+                      .getInterface(Ci.nsITabChild)
+                      .tabId;
+    } catch(e) {
+      // Only parent process does not have tab id, so in this case
+      // NfcContentHelper is used by system app. Use -1(tabId) to
+      // indicate its system app.
+      let inParent = Cc["@mozilla.org/xre/app-info;1"]
+                       .getService(Ci.nsIXULRuntime)
+                       .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
+      if (inParent) {
+        tabId = Ci.nsINfcBrowserAPI.SYSTEM_APP_ID;
+      } else {
+        throw Components.Exception("Can't get tab id in child process",
+                                   Cr.NS_ERROR_UNEXPECTED);
+      }
+    }
+
+    return tabId;
+  },
+
   // Only apps which have nfc-manager permission can call the following interfaces
   // 'checkP2PRegistration' , 'notifyUserAcceptedP2P' , 'notifySendFileStatus',
   // 'startPoll', 'stopPoll', and 'powerOff'.
   checkP2PRegistration: function checkP2PRegistration(manifestUrl) {
     // Get the AppID and pass it to ContentHelper
     let appID = appsService.getAppLocalIdByManifestURL(manifestUrl);
 
-    let callback = new NfcCallback(this._window);
+    let callback = new NfcCallback(this.window);
     this._nfcContentHelper.checkP2PRegistration(appID, callback);
     return callback.promise;
   },
 
   notifyUserAcceptedP2P: function notifyUserAcceptedP2P(manifestUrl) {
     let appID = appsService.getAppLocalIdByManifestURL(manifestUrl);
     // Notify chrome process of user's acknowledgement
     this._nfcContentHelper.notifyUserAcceptedP2P(appID);
   },
 
   notifySendFileStatus: function notifySendFileStatus(status, requestId) {
     this._nfcContentHelper.notifySendFileStatus(status, requestId);
   },
 
   startPoll: function startPoll() {
-    let callback = new NfcCallback(this._window);
+    let callback = new NfcCallback(this.window);
     this._nfcContentHelper.changeRFState(RFState.DISCOVERY, callback);
     return callback.promise;
   },
 
   stopPoll: function stopPoll() {
-    let callback = new NfcCallback(this._window);
+    let callback = new NfcCallback(this.window);
     this._nfcContentHelper.changeRFState(RFState.LISTEN, callback);
     return callback.promise;
   },
 
   powerOff: function powerOff() {
-    let callback = new NfcCallback(this._window);
+    let callback = new NfcCallback(this.window);
     this._nfcContentHelper.changeRFState(RFState.IDLE, callback);
     return callback.promise;
   },
 
   get enabled() {
     return this._rfState != RFState.IDLE;
   },
 
+  observe: function observe(subject, topic, data) {
+    if (topic !== "inner-window-destroyed") {
+      return;
+    }
+
+    let wId = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
+    if (wId != this._innerWindowId) {
+      return;
+    }
+
+    this._nfcContentHelper.removeEventListener(this._tabId);
+  },
+
   defineEventHandlerGetterSetter: function defineEventHandlerGetterSetter(name) {
     Object.defineProperty(this, name, {
       get: function get() {
         return this.__DOM_IMPL__.getEventHandler(name);
       },
       set: function set(handler) {
         this.__DOM_IMPL__.setEventHandler(name, handler);
       }
     });
   },
 
   eventListenerWasAdded: function(eventType) {
     if (eventType !== "peerready") {
       return;
     }
 
-    let appId = this._window.document.nodePrincipal.appId;
+    let appId = this.window.document.nodePrincipal.appId;
     this._nfcContentHelper.registerTargetForPeerReady(appId);
   },
 
   eventListenerWasRemoved: function(eventType) {
     if (eventType !== "peerready") {
       return;
     }
 
-    let appId = this._window.document.nodePrincipal.appId;
+    let appId = this.window.document.nodePrincipal.appId;
     this._nfcContentHelper.unregisterTargetForPeerReady(appId);
   },
 
   notifyTagFound: function notifyTagFound(sessionToken, tagInfo, ndefInfo, records) {
     if (!this.handleTagFound(sessionToken, tagInfo, ndefInfo, records)) {
       this._nfcContentHelper.callDefaultFoundHandler(sessionToken, false, records);
     };
   },
 
   /**
    * Handles Tag Found event.
    *
    * returns true if the app could process this event, false otherwise.
    */
   handleTagFound: function handleTagFound(sessionToken, tagInfo, ndefInfo, records) {
     if (this.hasDeadWrapper()) {
-      dump("this._window or this.__DOM_IMPL__ is a dead wrapper.");
+      dump("this.window or this.__DOM_IMPL__ is a dead wrapper.");
       return false;
     }
 
     if (!this.eventService.hasListenersFor(this.__DOM_IMPL__, "tagfound")) {
       debug("ontagfound is not registered.");
       return false;
     }
 
     if (!this.checkPermissions(["nfc"])) {
       return false;
     }
 
-    let tagImpl = new MozNFCTagImpl(this._window, sessionToken, tagInfo, ndefInfo);
-    let tag = this._window.MozNFCTag._create(this._window, tagImpl);
+    let tagImpl = new MozNFCTagImpl(this.window, sessionToken, tagInfo, ndefInfo);
+    let tag = this.window.MozNFCTag._create(this.window, tagImpl);
 
     tagImpl._contentObj = tag;
     this.nfcTag = tag;
 
     let length = records ? records.length : 0;
     let ndefRecords = records ? [] : null;
     for (let i = 0; i < length; i++) {
       let record = records[i];
-      ndefRecords.push(new this._window.MozNDEFRecord({tnf: record.tnf,
+      ndefRecords.push(new this.window.MozNDEFRecord({tnf: record.tnf,
                                                        type: record.type,
                                                        id: record.id,
                                                        payload: record.payload}));
     }
 
     let eventData = {
       "cancelable": true,
       "tag": tag,
       "ndefRecords": ndefRecords
     };
 
     debug("fire ontagfound " + sessionToken);
-    let tagEvent = new this._window.MozNFCTagEvent("tagfound", eventData);
+    let tagEvent = new this.window.MozNFCTagEvent("tagfound", eventData);
     this.__DOM_IMPL__.dispatchEvent(tagEvent);
 
     // If defaultPrevented is false, means we need to take the default action
     // for this event - redirect this event to System app. Before redirecting to
     // System app, we need revoke the tag object first.
     if (!tagEvent.defaultPrevented) {
       this.notifyTagLost(sessionToken);
     }
@@ -495,34 +556,34 @@ MozNFCImpl.prototype = {
   notifyTagLost: function notifyTagLost(sessionToken) {
     if (!this.handleTagLost(sessionToken)) {
       this._nfcContentHelper.callDefaultLostHandler(sessionToken, false);
     }
   },
 
   handleTagLost: function handleTagLost(sessionToken) {
     if (this.hasDeadWrapper()) {
-      dump("this._window or this.__DOM_IMPL__ is a dead wrapper.");
+      dump("this.window or this.__DOM_IMPL__ is a dead wrapper.");
       return false;
     }
 
     if (!this.checkPermissions(["nfc"])) {
       return false;
     }
 
     if (!this.nfcTag) {
       debug("No NFCTag object existing.");
       return false;
     }
 
     this.nfcTag.notifyLost();
     this.nfcTag = null;
 
     debug("fire ontaglost " + sessionToken);
-    let event = new this._window.Event("taglost");
+    let event = new this.window.Event("taglost");
     this.__DOM_IMPL__.dispatchEvent(event);
 
     return true;
   },
 
   notifyPeerFound: function notifyPeerFound(sessionToken, isPeerReady) {
     if (!this.handlePeerFound(sessionToken, isPeerReady)) {
       this._nfcContentHelper.callDefaultFoundHandler(sessionToken, true, null);
@@ -531,48 +592,48 @@ MozNFCImpl.prototype = {
 
   /**
    * Handles Peer Found/Peer Ready event.
    *
    * returns true if the app could process this event, false otherwise.
    */
   handlePeerFound: function handlePeerFound(sessionToken, isPeerReady) {
     if (this.hasDeadWrapper()) {
-      dump("this._window or this.__DOM_IMPL__ is a dead wrapper.");
+      dump("this.window or this.__DOM_IMPL__ is a dead wrapper.");
       return false;
     }
 
     if (!isPeerReady &&
         !this.eventService.hasListenersFor(this.__DOM_IMPL__, "peerfound")) {
       debug("onpeerfound is not registered.");
       return false;
     }
 
     let perm = isPeerReady ? ["nfc-share"] : ["nfc"];
     if (!this.checkPermissions(perm)) {
       return false;
     }
 
-    let peerImpl = new MozNFCPeerImpl(this._window, sessionToken);
-    this.nfcPeer = this._window.MozNFCPeer._create(this._window, peerImpl);
+    let peerImpl = new MozNFCPeerImpl(this.window, sessionToken);
+    this.nfcPeer = this.window.MozNFCPeer._create(this.window, peerImpl);
 
     let eventType;
     let eventData = {
       "peer": this.nfcPeer
     };
 
     if (isPeerReady) {
       eventType = "peerready";
     } else {
       eventData.cancelable = true;
       eventType = "peerfound";
     }
 
     debug("fire on" + eventType + " " + sessionToken);
-    let event = new this._window.MozNFCPeerEvent(eventType, eventData);
+    let event = new this.window.MozNFCPeerEvent(eventType, eventData);
     this.__DOM_IMPL__.dispatchEvent(event);
 
     // For peerready we don't take the default action.
     if (isPeerReady) {
       return true;
     }
 
     // If defaultPrevented is false, means we need to take the default action
@@ -588,34 +649,34 @@ MozNFCImpl.prototype = {
   notifyPeerLost: function notifyPeerLost(sessionToken) {
     if (!this.handlePeerLost(sessionToken)) {
       this._nfcContentHelper.callDefaultLostHandler(sessionToken, true);
     }
   },
 
   handlePeerLost: function handlePeerLost(sessionToken) {
     if (this.hasDeadWrapper()) {
-      dump("this._window or this.__DOM_IMPL__ is a dead wrapper.");
+      dump("this.window or this.__DOM_IMPL__ is a dead wrapper.");
       return false;
     }
 
     if (!this.checkPermissions(["nfc", "nfc-share"])) {
       return false;
     }
 
     if (!this.nfcPeer) {
       debug("No NFCPeer object existing.");
       return false;
     }
 
     this.nfcPeer.notifyLost();
     this.nfcPeer = null;
 
     debug("fire onpeerlost");
-    let event = new this._window.Event("peerlost");
+    let event = new this.window.Event("peerlost");
     this.__DOM_IMPL__.dispatchEvent(event);
 
     return true;
   },
 
   notifyRFStateChanged: function notifyRFStateChanged(rfState) {
     this._rfState = rfState;
   },
@@ -632,39 +693,40 @@ MozNFCImpl.prototype = {
 
     if (this.nfcPeer) {
       debug("losing focus, call peerlost.");
       this.notifyPeerLost(this.nfcPeer.session);
     }
   },
 
   checkPermissions: function checkPermissions(perms) {
-    let principal = this._window.document.nodePrincipal;
+    let principal = this.window.document.nodePrincipal;
     for (let perm of perms) {
       let permValue =
         Services.perms.testExactPermissionFromPrincipal(principal, perm);
       if (permValue == Ci.nsIPermissionManager.ALLOW_ACTION) {
         return true;
       } else {
         debug("doesn't have " + perm + " permission.");
       }
     }
 
     return false;
   },
 
   hasDeadWrapper: function hasDeadWrapper() {
-    return Cu.isDeadWrapper(this._window) || Cu.isDeadWrapper(this.__DOM_IMPL__);
+    return Cu.isDeadWrapper(this.window) || Cu.isDeadWrapper(this.__DOM_IMPL__);
   },
 
   classID: Components.ID("{6ff2b290-2573-11e3-8224-0800200c9a66}"),
   contractID: "@mozilla.org/nfc/manager;1",
   QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
                                          Ci.nsIDOMGlobalPropertyInitializer,
-                                         Ci.nsINfcEventListener]),
+                                         Ci.nsINfcEventListener,
+                                         Ci.nsIObserver]),
 };
 
 function NFCSendFileWrapper() {
 }
 NFCSendFileWrapper.prototype = {
   // nsISystemMessagesWrapper implementation.
   wrapMessage: function wrapMessage(aMessage, aWindow) {
     let peerImpl = new MozNFCPeerImpl(aWindow, aMessage.sessionToken);
--- a/dom/plugins/base/nsNPAPIPlugin.cpp
+++ b/dom/plugins/base/nsNPAPIPlugin.cpp
@@ -2463,20 +2463,20 @@ NPError
     NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_requestread called from the wrong thread\n"));
     return NPERR_INVALID_PARAM;
   }
   NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_RequestRead: stream=%p\n",
                                      (void*)pstream));
 
 #ifdef PLUGIN_LOGGING
   for(NPByteRange * range = rangeList; range != nullptr; range = range->next)
-    PR_LOG(nsPluginLogging::gNPNLog,PLUGIN_LOG_NOISY,
+    MOZ_LOG(nsPluginLogging::gNPNLog,PLUGIN_LOG_NOISY,
     ("%i-%i", range->offset, range->offset + range->length - 1));
 
-  PR_LOG(nsPluginLogging::gNPNLog,PLUGIN_LOG_NOISY, ("\n\n"));
+  MOZ_LOG(nsPluginLogging::gNPNLog,PLUGIN_LOG_NOISY, ("\n\n"));
   PR_LogFlush();
 #endif
 
   if (!pstream || !rangeList || !pstream->ndata)
     return NPERR_INVALID_PARAM;
 
   nsNPAPIStreamWrapper* streamWrapper = static_cast<nsNPAPIStreamWrapper*>(pstream->ndata);
   nsNPAPIPluginStreamListener* streamlistener = streamWrapper->GetStreamListener();
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -279,19 +279,19 @@ nsPluginHost::nsPluginHost()
 #endif
   }
 
 #ifdef PLUGIN_LOGGING
   nsPluginLogging::gNPNLog = PR_NewLogModule(NPN_LOG_NAME);
   nsPluginLogging::gNPPLog = PR_NewLogModule(NPP_LOG_NAME);
   nsPluginLogging::gPluginLog = PR_NewLogModule(PLUGIN_LOG_NAME);
 
-  PR_LOG(nsPluginLogging::gNPNLog, PLUGIN_LOG_ALWAYS,("NPN Logging Active!\n"));
-  PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_ALWAYS,("General Plugin Logging Active! (nsPluginHost::ctor)\n"));
-  PR_LOG(nsPluginLogging::gNPPLog, PLUGIN_LOG_ALWAYS,("NPP Logging Active!\n"));
+  MOZ_LOG(nsPluginLogging::gNPNLog, PLUGIN_LOG_ALWAYS,("NPN Logging Active!\n"));
+  MOZ_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_ALWAYS,("General Plugin Logging Active! (nsPluginHost::ctor)\n"));
+  MOZ_LOG(nsPluginLogging::gNPPLog, PLUGIN_LOG_ALWAYS,("NPP Logging Active!\n"));
 
   PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("nsPluginHost::ctor\n"));
   PR_LogFlush();
 #endif
 }
 
 nsPluginHost::~nsPluginHost()
 {
@@ -784,17 +784,17 @@ nsPluginHost::InstantiatePluginInstance(
 {
   NS_ENSURE_ARG_POINTER(aOwner);
 
 #ifdef PLUGIN_LOGGING
   nsAutoCString urlSpec;
   if (aURL)
     aURL->GetAsciiSpec(urlSpec);
 
-  PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
+  MOZ_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
         ("nsPluginHost::InstantiatePlugin Begin mime=%s, url=%s\n",
          PromiseFlatCString(aMimeType).get(), urlSpec.get()));
 
   PR_LogFlush();
 #endif
 
   if (aMimeType.IsEmpty()) {
     NS_NOTREACHED("Attempting to spawn a plugin with no mime type");
@@ -847,17 +847,17 @@ nsPluginHost::InstantiatePluginInstance(
 
   // At this point we consider instantiation to be successful. Do not return an error.
   instanceOwner.forget(aOwner);
 
 #ifdef PLUGIN_LOGGING
   nsAutoCString urlSpec2;
   if (aURL != nullptr) aURL->GetAsciiSpec(urlSpec2);
 
-  PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
+  MOZ_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
         ("nsPluginHost::InstantiatePlugin Finished mime=%s, rv=%d, url=%s\n",
          PromiseFlatCString(aMimeType).get(), rv, urlSpec2.get()));
 
   PR_LogFlush();
 #endif
 
   return NS_OK;
 }
@@ -925,17 +925,17 @@ nsresult
 nsPluginHost::TrySetUpPluginInstance(const nsACString &aMimeType,
                                      nsIURI *aURL,
                                      nsPluginInstanceOwner *aOwner)
 {
 #ifdef PLUGIN_LOGGING
   nsAutoCString urlSpec;
   if (aURL != nullptr) aURL->GetSpec(urlSpec);
 
-  PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
+  MOZ_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
         ("nsPluginHost::TrySetupPluginInstance Begin mime=%s, owner=%p, url=%s\n",
          PromiseFlatCString(aMimeType).get(), aOwner, urlSpec.get()));
 
   PR_LogFlush();
 #endif
 
 #ifdef XP_WIN
   bool changed;
@@ -988,17 +988,17 @@ nsPluginHost::TrySetUpPluginInstance(con
     pluginTag->mUnloadTimer->Cancel();
   }
 
 #ifdef PLUGIN_LOGGING
   nsAutoCString urlSpec2;
   if (aURL)
     aURL->GetSpec(urlSpec2);
 
-  PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC,
+  MOZ_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC,
         ("nsPluginHost::TrySetupPluginInstance Finished mime=%s, rv=%d, owner=%p, url=%s\n",
          PromiseFlatCString(aMimeType).get(), rv, aOwner, urlSpec2.get()));
 
   PR_LogFlush();
 #endif
 
   return rv;
 }
@@ -2962,17 +2962,17 @@ nsPluginHost::ReadPluginInfo()
     if (heapalloced)
       delete [] heapalloced;
 
     // Import flags from registry into prefs for old registry versions
     if (hasValidFlags && !pluginStateImported) {
       tag->ImportFlagsToPrefs(tagflag);
     }
 
-    PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC,
+    MOZ_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC,
       ("LoadCachedPluginsInfo : Loading Cached plugininfo for %s\n", tag->mFileName.get()));
     tag->mNext = mCachedPlugins;
     mCachedPlugins = tag;
   }
 
 // On Android we always want to try to load a plugin again (Flash). Bug 935676.
 #ifndef MOZ_WIDGET_ANDROID
   if (hasInvalidPlugins) {
--- a/dom/plugins/base/nsPluginLogging.h
+++ b/dom/plugins/base/nsPluginLogging.h
@@ -55,37 +55,37 @@ public:
 };
 
 #endif   // PLUGIN_LOGGING
 
 // Quick-use macros
 #ifdef PLUGIN_LOGGING
  #define NPN_PLUGIN_LOG(a, b)                              \
    PR_BEGIN_MACRO                                        \
-   PR_LOG(nsPluginLogging::gNPNLog, a, b); \
+   MOZ_LOG(nsPluginLogging::gNPNLog, a, b); \
    PR_LogFlush();                                                    \
    PR_END_MACRO
 #else
  #define NPN_PLUGIN_LOG(a, b)
 #endif
 
 #ifdef PLUGIN_LOGGING
  #define NPP_PLUGIN_LOG(a, b)                              \
    PR_BEGIN_MACRO                                         \
-   PR_LOG(nsPluginLogging::gNPPLog, a, b); \
+   MOZ_LOG(nsPluginLogging::gNPPLog, a, b); \
    PR_LogFlush();                                                    \
    PR_END_MACRO
 #else
  #define NPP_PLUGIN_LOG(a, b)
 #endif
 
 #ifdef PLUGIN_LOGGING
  #define PLUGIN_LOG(a, b)                              \
    PR_BEGIN_MACRO                                         \
-   PR_LOG(nsPluginLogging::gPluginLog, a, b); \
+   MOZ_LOG(nsPluginLogging::gPluginLog, a, b); \
    PR_LogFlush();                                                    \
    PR_END_MACRO
 #else
  #define PLUGIN_LOG(a, b)
 #endif
 
 #endif   // nsPluginLogging_h__
 
--- a/dom/plugins/base/nsPluginStreamListenerPeer.cpp
+++ b/dom/plugins/base/nsPluginStreamListenerPeer.cpp
@@ -275,17 +275,17 @@ nsPluginStreamListenerPeer::nsPluginStre
   mModified = 0;
   mStreamOffset = 0;
   mStreamComplete = 0;
 }
 
 nsPluginStreamListenerPeer::~nsPluginStreamListenerPeer()
 {
 #ifdef PLUGIN_LOGGING
-  PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
+  MOZ_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
          ("nsPluginStreamListenerPeer::dtor this=%p, url=%s\n",this, mURLSpec.get()));
 #endif
 
   if (mPStreamListener) {
     mPStreamListener->SetStreamListenerPeer(nullptr);
   }
 
   // close FD of mFileCacheOutputStream if it's still open
@@ -304,17 +304,17 @@ nsPluginStreamListenerPeer::~nsPluginStr
 nsresult nsPluginStreamListenerPeer::Initialize(nsIURI *aURL,
                                                 nsNPAPIPluginInstance *aInstance,
                                                 nsNPAPIPluginStreamListener* aListener)
 {
 #ifdef PLUGIN_LOGGING
   nsAutoCString urlSpec;
   if (aURL != nullptr) aURL->GetSpec(urlSpec);
 
-  PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
+  MOZ_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
          ("nsPluginStreamListenerPeer::Initialize instance=%p, url=%s\n", aInstance, urlSpec.get()));
 
   PR_LogFlush();
 #endif
 
   // Not gonna work out
   if (!aInstance) {
     return NS_ERROR_FAILURE;
@@ -550,17 +550,17 @@ nsPluginStreamListenerPeer::OnStartReque
     return rv;
 
   aURL->GetSpec(mURLSpec);
 
   if (!contentType.IsEmpty())
     mContentType = contentType;
 
 #ifdef PLUGIN_LOGGING
-  PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NOISY,
+  MOZ_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NOISY,
          ("nsPluginStreamListenerPeer::OnStartRequest this=%p request=%p mime=%s, url=%s\n",
           this, request, contentType.get(), mURLSpec.get()));
 
   PR_LogFlush();
 #endif
 
   // Set up the stream listener...
   rv = SetUpStreamListener(request, aURL);
--- a/dom/plugins/ipc/PluginInstanceChild.cpp
+++ b/dom/plugins/ipc/PluginInstanceChild.cpp
@@ -495,17 +495,17 @@ PluginInstanceChild::NPN_GetValue(NPNVar
     case NPNVasdEnabledBool:
     case NPNVisOfflineBool:
     case NPNVSupportsXEmbedBool:
     case NPNVSupportsWindowless:
         NS_NOTREACHED("NPNVariable should be handled in PluginModuleChild.");
 #endif
 
     default:
-        PR_LOG(GetPluginLog(), PR_LOG_WARNING,
+        MOZ_LOG(GetPluginLog(), PR_LOG_WARNING,
                ("In PluginInstanceChild::NPN_GetValue: Unhandled NPNVariable %i (%s)",
                 (int) aVar, NPNVariableToString(aVar)));
         return NPERR_GENERIC_ERROR;
     }
 
 }
 
 #ifdef MOZ_WIDGET_COCOA
@@ -524,17 +524,17 @@ PluginInstanceChild::Invalidate()
 
     InvalidateRect(&windowRect);
 }
 #endif
 
 NPError
 PluginInstanceChild::NPN_SetValue(NPPVariable aVar, void* aValue)
 {
-    PR_LOG(GetPluginLog(), PR_LOG_DEBUG, ("%s (aVar=%i, aValue=%p)",
+    MOZ_LOG(GetPluginLog(), PR_LOG_DEBUG, ("%s (aVar=%i, aValue=%p)",
                                       FULLFUNCTION, (int) aVar, aValue));
 
     AssertPluginThread();
 
     switch (aVar) {
     case NPPVpluginWindowBool: {
         NPError rv;
         bool windowed = (NPBool) (intptr_t) aValue;
@@ -613,17 +613,17 @@ PluginInstanceChild::NPN_SetValue(NPPVar
         PLUGIN_LOG_DEBUG(("  Plugin requested event model id # %i\n",
             eventModel));
 
         return rv;
     }
 #endif
 
     default:
-        PR_LOG(GetPluginLog(), PR_LOG_WARNING,
+        MOZ_LOG(GetPluginLog(), PR_LOG_WARNING,
                ("In PluginInstanceChild::NPN_SetValue: Unhandled NPPVariable %i (%s)",
                 (int) aVar, NPPVariableToString(aVar)));
         return NPERR_GENERIC_ERROR;
     }
 }
 
 bool
 PluginInstanceChild::AnswerNPP_GetValue_NPPVpluginWantsAllNetworkStreams(
@@ -2202,17 +2202,17 @@ PluginInstanceChild::FlashThrottleMessag
         task, kFlashWMUSERMessageThrottleDelayMs);
 }
 
 #endif // OS_WIN
 
 bool
 PluginInstanceChild::AnswerSetPluginFocus()
 {
-    PR_LOG(GetPluginLog(), PR_LOG_DEBUG, ("%s", FULLFUNCTION));
+    MOZ_LOG(GetPluginLog(), PR_LOG_DEBUG, ("%s", FULLFUNCTION));
 
 #if defined(OS_WIN)
     // Parent is letting us know the dom set focus to the plugin. Note,
     // focus can change during transit in certain edge cases, for example
     // when a button click brings up a full screen window. Since we send
     // this in response to a WM_SETFOCUS event on our parent, the parent
     // should have focus when we receive this. If not, ignore the call.
     if (::GetFocus() == mPluginWindowHWND ||
@@ -2225,17 +2225,17 @@ PluginInstanceChild::AnswerSetPluginFocu
     NS_NOTREACHED("PluginInstanceChild::AnswerSetPluginFocus not implemented!");
     return false;
 #endif
 }
 
 bool
 PluginInstanceChild::AnswerUpdateWindow()
 {
-    PR_LOG(GetPluginLog(), PR_LOG_DEBUG, ("%s", FULLFUNCTION));
+    MOZ_LOG(GetPluginLog(), PR_LOG_DEBUG, ("%s", FULLFUNCTION));
 
 #if defined(OS_WIN)
     if (mPluginWindowHWND) {
         RECT rect;
         if (GetUpdateRect(GetParent(mPluginWindowHWND), &rect, FALSE)) {
             ::InvalidateRect(mPluginWindowHWND, &rect, FALSE); 
         }
         UpdateWindow(mPluginWindowHWND);
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -1114,17 +1114,17 @@ PluginInstanceParent::NPP_GetValue(NPPVa
         }
 
         (*(nsCString*)_retval) = plugId;
         return NPERR_NO_ERROR;
     }
 #endif
 
     default:
-        PR_LOG(GetPluginLog(), PR_LOG_WARNING,
+        MOZ_LOG(GetPluginLog(), PR_LOG_WARNING,
                ("In PluginInstanceParent::NPP_GetValue: Unhandled NPPVariable %i (%s)",
                 (int) aVariable, NPPVariableToString(aVariable)));
         return NPERR_GENERIC_ERROR;
     }
 }
 
 NPError
 PluginInstanceParent::N