Merge m-c to fx-team, a=merge
authorWes Kocher <wkocher@mozilla.com>
Thu, 20 Aug 2015 12:53:30 -0700
changeset 291205 b2dd3ab04f6ec43207654be94bef6a65d87f8afb
parent 291204 c4c4a57e0d742b5a7fc49ffc09141956657e96ca (current diff)
parent 291193 095988abdc560bf8ba07a94a425c6922a3e9bfd6 (diff)
child 291206 e32341309d701cb6fb360accd3afe937be10ba20
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone43.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
dom/messagechannel/tests/test_messageChannel_pref.html
widget/nsIGfxInfo2.idl
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -922,18 +922,16 @@ pref("memory_info_dumper.watch_fifo.dire
 // See ua-update.json.in for the packaged UA override list
 pref("general.useragent.updates.enabled", true);
 pref("general.useragent.updates.url", "https://dynamicua.cdn.mozilla.net/0/%APP_ID%");
 pref("general.useragent.updates.interval", 604800); // 1 week
 pref("general.useragent.updates.retry", 86400); // 1 day
 // Device ID can be composed of letter, numbers, hyphen ("-") and dot (".")
 pref("general.useragent.device_id", "");
 
-// Make <audio> and <video> talk to the AudioChannelService.
-pref("media.useAudioChannelService", true);
 // Add Mozilla AudioChannel APIs.
 pref("media.useAudioChannelAPI", true);
 
 pref("b2g.version", @MOZ_B2G_VERSION@);
 pref("b2g.osName", @MOZ_B2G_OS_NAME@);
 
 // Disable console buffering to save memory.
 pref("consoleservice.buffered", 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="aacd9b12da7fc3c8f4deaaa8eedfbb158f4fefe7">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="89e0096a3de0378e3eda77e6a2a0bb5ca03eb8bb"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="c6705f739fb605031eb2a0b943ba55c64bee5a03"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="bfdb6348725a33bdcdc4e17999cb500be6beedb5"/>
   <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="a6f9a1245d98c51172c15afecb9ade1a6ca511e2"/>
--- 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="aacd9b12da7fc3c8f4deaaa8eedfbb158f4fefe7">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="89e0096a3de0378e3eda77e6a2a0bb5ca03eb8bb"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="c6705f739fb605031eb2a0b943ba55c64bee5a03"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="bfdb6348725a33bdcdc4e17999cb500be6beedb5"/>
   <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="a6f9a1245d98c51172c15afecb9ade1a6ca511e2"/>
--- 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="1b0db93fb6b870b03467aff50d6419771ba0d88c">
     <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="89e0096a3de0378e3eda77e6a2a0bb5ca03eb8bb"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="c6705f739fb605031eb2a0b943ba55c64bee5a03"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="2d58f4b9206b50b8fda0d5036da6f0c62608db7c"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="d70e4bfdcb65e7514de0f9315b74aea1c811678d"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="bfdb6348725a33bdcdc4e17999cb500be6beedb5"/>
   <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="660169a3d7e034a892359e39135e8c2785a6ad6f">
     <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="89e0096a3de0378e3eda77e6a2a0bb5ca03eb8bb"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="c6705f739fb605031eb2a0b943ba55c64bee5a03"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="bfdb6348725a33bdcdc4e17999cb500be6beedb5"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a6f9a1245d98c51172c15afecb9ade1a6ca511e2"/>
   <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="aacd9b12da7fc3c8f4deaaa8eedfbb158f4fefe7">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="89e0096a3de0378e3eda77e6a2a0bb5ca03eb8bb"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="c6705f739fb605031eb2a0b943ba55c64bee5a03"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="bfdb6348725a33bdcdc4e17999cb500be6beedb5"/>
   <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="a6f9a1245d98c51172c15afecb9ade1a6ca511e2"/>
--- 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="05a36844c1046a1eb07d5b1325f85ed741f961ea">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="89e0096a3de0378e3eda77e6a2a0bb5ca03eb8bb"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="c6705f739fb605031eb2a0b943ba55c64bee5a03"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="bfdb6348725a33bdcdc4e17999cb500be6beedb5"/>
   <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="a6f9a1245d98c51172c15afecb9ade1a6ca511e2"/>
--- 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="1b0db93fb6b870b03467aff50d6419771ba0d88c">
     <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="89e0096a3de0378e3eda77e6a2a0bb5ca03eb8bb"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="c6705f739fb605031eb2a0b943ba55c64bee5a03"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="2d58f4b9206b50b8fda0d5036da6f0c62608db7c"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="d70e4bfdcb65e7514de0f9315b74aea1c811678d"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="bfdb6348725a33bdcdc4e17999cb500be6beedb5"/>
   <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="aacd9b12da7fc3c8f4deaaa8eedfbb158f4fefe7">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="89e0096a3de0378e3eda77e6a2a0bb5ca03eb8bb"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="c6705f739fb605031eb2a0b943ba55c64bee5a03"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="bfdb6348725a33bdcdc4e17999cb500be6beedb5"/>
   <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="a6f9a1245d98c51172c15afecb9ade1a6ca511e2"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
-        "git_revision": "89e0096a3de0378e3eda77e6a2a0bb5ca03eb8bb", 
+        "git_revision": "c6705f739fb605031eb2a0b943ba55c64bee5a03", 
         "remote": "https://git.mozilla.org/releases/gaia.git", 
         "branch": ""
     }, 
-    "revision": "68da3c242dcd332c0aa579fbdc9da20d9db60022", 
+    "revision": "69fd2d2a3adce973a5e86ea2f96d1e311e11239d", 
     "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="660169a3d7e034a892359e39135e8c2785a6ad6f">
     <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="89e0096a3de0378e3eda77e6a2a0bb5ca03eb8bb"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="c6705f739fb605031eb2a0b943ba55c64bee5a03"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="bfdb6348725a33bdcdc4e17999cb500be6beedb5"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a6f9a1245d98c51172c15afecb9ade1a6ca511e2"/>
   <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="05a36844c1046a1eb07d5b1325f85ed741f961ea">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="89e0096a3de0378e3eda77e6a2a0bb5ca03eb8bb"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="c6705f739fb605031eb2a0b943ba55c64bee5a03"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="62cfa11ae7d77f6330de019a5aa79607e35be7d1"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="bfdb6348725a33bdcdc4e17999cb500be6beedb5"/>
   <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="a6f9a1245d98c51172c15afecb9ade1a6ca511e2"/>
--- a/browser/base/content/browser-fxaccounts.js
+++ b/browser/base/content/browser-fxaccounts.js
@@ -442,34 +442,34 @@ let gFxAccounts = {
       break;
     case "migrate-signup":
     case "migrate-verify":
       // The migration flow calls for the menu item to open sync prefs rather
       // than requesting migration start immediately.
       this.openPreferences();
       break;
     default:
-      this.openAccountsPage(null, { entryPoint: "menupanel" });
+      this.openAccountsPage(null, { entrypoint: "menupanel" });
       break;
     }
 
     PanelUI.hide();
   },
 
   openPreferences: function () {
     openPreferences("paneSync");
   },
 
   openAccountsPage: function (action, urlParams={}) {
-    // An entryPoint param is used for server-side metrics.  If the current tab
+    // An entrypoint param is used for server-side metrics.  If the current tab
     // is UITour, assume that it initiated the call to this method and override
-    // the entryPoint accordingly.
+    // the entrypoint accordingly.
     if (UITour.tourBrowsersByWindow.get(window) &&
         UITour.tourBrowsersByWindow.get(window).has(gBrowser.selectedBrowser)) {
-      urlParams.entryPoint = "uitour";
+      urlParams.entrypoint = "uitour";
     }
     let params = new URLSearchParams();
     if (action) {
       params.set("action", action);
     }
     for (let name in urlParams) {
       if (urlParams[name] !== undefined) {
         params.set(name, urlParams[name]);
@@ -477,17 +477,17 @@ let gFxAccounts = {
     }
     let url = "about:accounts?" + params;
     switchToTabHavingURI(url, true, {
       replaceQueryString: true
     });
   },
 
   openSignInAgainPage: function (entryPoint) {
-    this.openAccountsPage("reauth", { entryPoint: entryPoint });
+    this.openAccountsPage("reauth", { entrypoint: entryPoint });
   },
 };
 
 XPCOMUtils.defineLazyGetter(gFxAccounts, "FxAccountsCommon", function () {
   return Cu.import("resource://gre/modules/FxAccountsCommon.js", {});
 });
 
 XPCOMUtils.defineLazyModuleGetter(gFxAccounts, "fxaMigrator",
--- a/browser/base/content/test/general/browser_audioTabIcon.js
+++ b/browser/base/content/test/general/browser_audioTabIcon.js
@@ -358,17 +358,16 @@ function* test_on_browser(browser) {
   } else {
     yield test_browser_swapping(tab, browser);
   }
 }
 
 add_task(function*() {
   yield new Promise((resolve) => {
     SpecialPowers.pushPrefEnv({"set": [
-                                ["media.useAudioChannelService", true],
                                 ["browser.tabs.showAudioPlayingIcon", true],
                               ]}, resolve);
   });
 });
 
 requestLongerTimeout(2);
 add_task(function* test_page() {
   yield BrowserTestUtils.withNewTab({
--- a/browser/base/content/test/general/browser_fxaccounts.js
+++ b/browser/base/content/test/general/browser_fxaccounts.js
@@ -79,17 +79,17 @@ add_task(function* test_nouser() {
   // Check the world - the FxA footer area is visible as it is offering a signin.
   Assert.ok(isFooterVisible())
 
   Assert.equal(panelUILabel.getAttribute("label"), panelUIStatus.getAttribute("defaultlabel"));
   Assert.ok(!panelUIStatus.hasAttribute("tooltiptext"), "no tooltip when signed out");
   Assert.ok(!panelUIFooter.hasAttribute("fxastatus"), "no fxsstatus when signed out");
   Assert.ok(!panelUIFooter.hasAttribute("fxaprofileimage"), "no fxaprofileimage when signed out");
 
-  let promiseOpen = promiseTabOpen("about:accounts?entryPoint=menupanel");
+  let promiseOpen = promiseTabOpen("about:accounts?entrypoint=menupanel");
   panelUIStatus.click();
   yield promiseOpen;
 });
 
 /*
 XXX - Bug 1191162 - need a better hawk mock story or this will leak in debug builds.
 
 add_task(function* test_unverifiedUser() {
--- a/browser/locales/en-US/chrome/browser/devtools/netmonitor.dtd
+++ b/browser/locales/en-US/chrome/browser/devtools/netmonitor.dtd
@@ -206,20 +206,16 @@
   -  in a "wait" state. -->
 <!ENTITY netmonitorUI.timings.wait        "Waiting:">
 
 <!-- LOCALIZATION NOTE (netmonitorUI.timings.receive): This is the label displayed
   -  in the network details timings tab identifying the amount of time spent
   -  in a "receive" state. -->
 <!ENTITY netmonitorUI.timings.receive     "Receiving:">
 
-<!-- LOCALIZATION NOTE (netmonitorUI.security.warning.protocol): A tooltip
-  -  for warning icon that indicates a connection uses insecure protocol. -->
-<!ENTITY netmonitorUI.security.warning.sslv3      "The protocol SSL 3.0 is deprecated and insecure.">
-
 <!-- LOCALIZATION NOTE (netmonitorUI.security.warning.cipher): A tooltip
   -  for warning icon that indicates a connection uses insecure cipher suite. -->
 <!ENTITY netmonitorUI.security.warning.cipher     "The cipher used for encryption is deprecated and insecure.">
 
 <!-- LOCALIZATION NOTE (netmonitorUI.security.error): This is the label displayed
   -  in the security tab if a security error prevented the connection. -->
 <!ENTITY netmonitorUI.security.error      "An error occured:">
 
--- a/build/autoconf/android.m4
+++ b/build/autoconf/android.m4
@@ -59,17 +59,17 @@ case "$target" in
         AC_MSG_ERROR([You must specify --with-android-ndk=/path/to/ndk when targeting Android.])
     fi
 
     if test -z "$android_toolchain" ; then
         AC_MSG_CHECKING([for android toolchain directory])
 
         kernel_name=`uname -s | tr "[[:upper:]]" "[[:lower:]]"`
 
-        for version in $android_gnu_compiler_version 4.9 4.8 4.7 4.6 4.4.3; do
+        for version in $android_gnu_compiler_version 4.9 4.8 4.7; do
             case "$target_cpu" in
             arm)
                 target_name=arm-linux-androideabi-$version
                 ;;
             i?86)
                 target_name=x86-$version
                 ;;
             mipsel)
--- a/caps/BasePrincipal.cpp
+++ b/caps/BasePrincipal.cpp
@@ -14,57 +14,73 @@
 #include "nsPrincipal.h"
 #include "nsNetUtil.h"
 #include "nsIURIWithPrincipal.h"
 #include "nsNullPrincipal.h"
 #include "nsScriptSecurityManager.h"
 #include "nsServiceManagerUtils.h"
 
 #include "mozilla/dom/CSPDictionariesBinding.h"
+#include "mozilla/dom/quota/QuotaManager.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "mozilla/dom/URLSearchParams.h"
 
 namespace mozilla {
 
 using dom::URLParams;
 
 void
 OriginAttributes::CreateSuffix(nsACString& aStr) const
 {
   MOZ_RELEASE_ASSERT(mAppId != nsIScriptSecurityManager::UNKNOWN_APP_ID);
 
   UniquePtr<URLParams> params(new URLParams());
   nsAutoString value;
 
+  //
+  // Important: While serializing any string-valued attributes, perform a
+  // release-mode assertion to make sure that they don't contain characters that
+  // will break the quota manager when it uses the serialization for file
+  // naming (see addonId below).
+  //
+
   if (mAppId != nsIScriptSecurityManager::NO_APP_ID) {
     value.AppendInt(mAppId);
     params->Set(NS_LITERAL_STRING("appId"), value);
   }
 
   if (mInBrowser) {
     params->Set(NS_LITERAL_STRING("inBrowser"), NS_LITERAL_STRING("1"));
   }
 
   if (!mAddonId.IsEmpty()) {
+    MOZ_RELEASE_ASSERT(mAddonId.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) == kNotFound);
     params->Set(NS_LITERAL_STRING("addonId"), mAddonId);
   }
 
   if (mUserContextId != nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID) {
     value.Truncate();
     value.AppendInt(mUserContextId);
     params->Set(NS_LITERAL_STRING("userContextId"), value);
   }
 
   aStr.Truncate();
 
   params->Serialize(value);
   if (!value.IsEmpty()) {
     aStr.AppendLiteral("^");
     aStr.Append(NS_ConvertUTF16toUTF8(value));
   }
+
+// In debug builds, check the whole string for illegal characters too (just in case).
+#ifdef DEBUG
+  nsAutoCString str;
+  str.Assign(aStr);
+  MOZ_ASSERT(str.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) == kNotFound);
+#endif
 }
 
 namespace {
 
 class MOZ_STACK_CLASS PopulateFromSuffixIterator final
   : public URLParams::ForEachIterator
 {
 public:
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -43,16 +43,17 @@
 #include "nsDOMCID.h"
 #include "nsNetCID.h"
 #include "nsNetUtil.h"
 #include "mozilla/net/ReferrerPolicy.h"
 #include "nsRect.h"
 #include "prenv.h"
 #include "nsIDOMWindow.h"
 #include "nsIGlobalObject.h"
+#include "nsIViewSourceChannel.h"
 #include "nsIWebBrowserChrome.h"
 #include "nsPoint.h"
 #include "nsIObserverService.h"
 #include "nsIPrompt.h"
 #include "nsIAuthPrompt.h"
 #include "nsIAuthPrompt2.h"
 #include "nsIChannelEventSink.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
@@ -10390,83 +10391,87 @@ nsDocShell::DoURILoad(nsIURI* aURI,
   if (inherit) {
     securityFlags |= nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
   }
   if (isSandBoxed) {
     securityFlags |= nsILoadInfo::SEC_SANDBOXED;
   }
 
   if (!isSrcdoc) {
-    nsCOMPtr<nsILoadInfo> loadInfo =
-      new LoadInfo(requestingNode ? requestingNode->NodePrincipal() :
-                                    triggeringPrincipal.get(),
-                   triggeringPrincipal,
-                   requestingNode,
-                   securityFlags,
-                   aContentPolicyType,
-                   aBaseURI);
     rv = NS_NewChannelInternal(getter_AddRefs(channel),
                                aURI,
-                               loadInfo,
-                               nullptr,   // loadGroup
-                               static_cast<nsIInterfaceRequestor*>(this),
-                               loadFlags);
+                               requestingNode,
+                               requestingNode
+                                 ? requestingNode->NodePrincipal()
+                                 : triggeringPrincipal.get(),
+                                triggeringPrincipal,
+                                securityFlags,
+                                aContentPolicyType,
+                                nullptr,   // loadGroup
+                                static_cast<nsIInterfaceRequestor*>(this),
+                                loadFlags);
 
     if (NS_FAILED(rv)) {
       if (rv == NS_ERROR_UNKNOWN_PROTOCOL) {
         // This is a uri with a protocol scheme we don't know how
         // to handle.  Embedders might still be interested in
         // handling the load, though, so we fire a notification
         // before throwing the load away.
         bool abort = false;
         nsresult rv2 = mContentListener->OnStartURIOpen(aURI, &abort);
         if (NS_SUCCEEDED(rv2) && abort) {
           // Hey, they're handling the load for us!  How convenient!
           return NS_OK;
         }
       }
       return rv;
     }
+    if (aBaseURI) {
+        nsCOMPtr<nsIViewSourceChannel> vsc = do_QueryInterface(channel);
+        if (vsc) {
+            vsc->SetBaseURI(aBaseURI);
+        }
+    }
   } else {
     nsAutoCString scheme;
     rv = aURI->GetScheme(scheme);
     NS_ENSURE_SUCCESS(rv, rv);
     bool isViewSource;
     aURI->SchemeIs("view-source", &isViewSource);
 
     if (isViewSource) {
       nsViewSourceHandler* vsh = nsViewSourceHandler::GetInstance();
       NS_ENSURE_TRUE(vsh, NS_ERROR_FAILURE);
 
-      rv = vsh->NewSrcdocChannel(aURI, aSrcdoc, getter_AddRefs(channel));
-      NS_ENSURE_SUCCESS(rv, rv);
-      nsCOMPtr<nsILoadInfo> loadInfo =
-        new LoadInfo(requestingNode ? requestingNode->NodePrincipal() :
-                                      triggeringPrincipal.get(),
-                     triggeringPrincipal,
-                     requestingNode,
-                     securityFlags,
-                     aContentPolicyType,
-                     aBaseURI);
-      channel->SetLoadInfo(loadInfo);
+      rv = vsh->NewSrcdocChannel(aURI, aBaseURI, aSrcdoc,
+                                 requestingNode,
+                                 requestingNode
+                                   ? requestingNode->NodePrincipal()
+                                   : triggeringPrincipal.get(),
+                                 triggeringPrincipal,
+                                 securityFlags,
+                                 aContentPolicyType,
+                                 getter_AddRefs(channel));
     } else {
       rv = NS_NewInputStreamChannelInternal(getter_AddRefs(channel),
                                             aURI,
                                             aSrcdoc,
                                             NS_LITERAL_CSTRING("text/html"),
                                             requestingNode,
                                             requestingNode ?
                                               requestingNode->NodePrincipal() :
                                               triggeringPrincipal.get(),
                                             triggeringPrincipal,
                                             securityFlags,
                                             aContentPolicyType,
-                                            true,
-                                            aBaseURI);
+                                            true);
       NS_ENSURE_SUCCESS(rv, rv);
+      nsCOMPtr<nsIInputStreamChannel> isc = do_QueryInterface(channel);
+      MOZ_ASSERT(isc);
+      isc->SetBaseURI(aBaseURI);
     }
   }
 
   nsCOMPtr<nsIApplicationCacheChannel> appCacheChannel =
     do_QueryInterface(channel);
   if (appCacheChannel) {
     // Any document load should not inherit application cache.
     appCacheChannel->SetInheritApplicationCache(false);
@@ -11730,17 +11735,17 @@ nsDocShell::AddToSessionHistory(nsIURI* 
     inStrmChan->GetIsSrcdocChannel(&isSrcdocChannel);
     if (isSrcdocChannel) {
       nsAutoString srcdoc;
       inStrmChan->GetSrcdocData(srcdoc);
       entry->SetSrcdocData(srcdoc);
       nsCOMPtr<nsILoadInfo> loadInfo;
       aChannel->GetLoadInfo(getter_AddRefs(loadInfo));
       nsCOMPtr<nsIURI> baseURI;
-      loadInfo->GetBaseURI(getter_AddRefs(baseURI));
+      inStrmChan->GetBaseURI(getter_AddRefs(baseURI));
       entry->SetBaseURI(baseURI);
     }
   }
   /* If cache got a 'no-store', ask SH not to store
    * HistoryLayoutState. By default, SH will set this
    * flag to true and save HistoryLayoutState.
    */
   if (discardLayoutState) {
--- a/dom/apps/Webapps.js
+++ b/dom/apps/Webapps.js
@@ -311,29 +311,26 @@ WebappsRegistry.prototype = {
 
     if (!manifestURL) {
       return new Promise((aResolve, aReject) => {
         aReject("NotInApp");
       });
     }
 
     this.addMessageListeners(["Webapps:GetLocalizationResource:Return"]);
-    return this.createPromise((aResolve, aReject) => {
+    return this.createPromiseWithId((aResolverId) => {
       cpmm.sendAsyncMessage("Webapps:GetLocalizationResource", {
         manifestURL: manifestURL,
         lang: aLanguage,
         version: aVersion,
         path: aPath,
         dataType: aType,
         oid: this._id,
         topId: this._topId,
-        requestID: this.getPromiseResolverId({
-          resolve: aResolve,
-          reject: aReject
-        })
+        requestID: aResolverId
       });
     });
   },
 
   // nsIDOMGlobalPropertyInitializer implementation
   init: function(aWindow) {
     const prefs = new Preferences();
 
@@ -604,46 +601,40 @@ WebappsApplication.prototype = {
       Services.DOMRequest.fireErrorAsync(request, "NO_CLEARABLE_BROWSER");
     }
     return request;
   },
 
   connect: function(aKeyword, aRules) {
     this.addMessageListeners(["Webapps:Connect:Return:OK",
                               "Webapps:Connect:Return:KO"]);
-    return this.createPromise(function (aResolve, aReject) {
+    return this.createPromiseWithId((aResolverId) => {
       let from = this._window.location.origin + this._window.location.pathname;
       cpmm.sendAsyncMessage("Webapps:Connect", {
         keyword: aKeyword,
         rules: aRules,
         manifestURL: this.manifestURL,
         pubPageURL: from,
         outerWindowID: this._id,
         topWindowID: this._topId,
-        requestID: this.getPromiseResolverId({
-          resolve: aResolve,
-          reject: aReject
-        })
+        requestID: aResolverId
       });
-    }.bind(this));
+    });
   },
 
   getConnections: function() {
     this.addMessageListeners("Webapps:GetConnections:Return:OK");
-    return this.createPromise(function (aResolve, aReject) {
+    return this.createPromiseWithId((aResolverId) => {
       cpmm.sendAsyncMessage("Webapps:GetConnections", {
         manifestURL: this.manifestURL,
         outerWindowID: this._id,
         topWindowID: this._topId,
-        requestID: this.getPromiseResolverId({
-          resolve: aResolve,
-          reject: aReject
-        })
+        requestID: aResolverId
       });
-    }.bind(this));
+    });
   },
 
   addReceipt: function(receipt) {
     let request = this.createRequest();
 
     this.addMessageListeners(["Webapps:AddReceipt:Return:OK",
                               "Webapps:AddReceipt:Return:KO"]);
 
@@ -684,43 +675,37 @@ WebappsApplication.prototype = {
                                                       topId: this._topId,
                                                       requestID: this.getRequestId(request) });
 
     return request;
   },
 
   export: function() {
     this.addMessageListeners(["Webapps:Export:Return"]);
-    return this.createPromise((aResolve, aReject) => {
+    return this.createPromiseWithId((aResolverId) => {
       cpmm.sendAsyncMessage("Webapps:Export",
         { manifestURL: this.manifestURL,
           oid: this._id,
           topId: this._topId,
-          requestID: this.getPromiseResolverId({
-            resolve: aResolve,
-            reject: aReject
-          })
+          requestID: aResolverId
         });
     });
   },
 
   getLocalizedValue: function(aProperty, aLang, aEntryPoint) {
     this.addMessageListeners(["Webapps:GetLocalizedValue:Return"]);
-    return this.createPromise((aResolve, aReject) => {
+    return this.createPromiseWithId((aResolverId) => {
       cpmm.sendAsyncMessage("Webapps:GetLocalizedValue",
         { manifestURL: this.manifestURL,
           oid: this._id,
           topId: this._topId,
           property: aProperty,
           lang: aLang,
           entryPoint: aEntryPoint,
-          requestID: this.getPromiseResolverId({
-            resolve: aResolve,
-            reject: aReject
-          })
+          requestID: aResolverId
         });
     });
   },
 
   _prepareForContent: function() {
     if (this.__DOM_IMPL__) {
       return this.__DOM_IMPL__;
     }
@@ -953,29 +938,26 @@ WebappsApplicationMgmt.prototype = {
       Services.DOMRequest.fireSuccessAsync(request,
                                            convertAppsArray(aApps, window));
     });
 
     return request;
   },
 
   getIcon: function(aApp, aIconID, aEntryPoint) {
-    return this.createPromise(function(aResolve, aReject) {
+    return this.createPromiseWithId((aResolverId) => {
       cpmm.sendAsyncMessage("Webapps:GetIcon", {
         oid: this._id,
         topId: this._topId,
         manifestURL: aApp.manifestURL,
         iconID: aIconID,
         entryPoint: aEntryPoint,
-        requestID: this.getPromiseResolverId({
-          resolve: aResolve,
-          reject: aReject
-        })
+        requestID: aResolverId
       });
-    }.bind(this));
+    });
   },
 
   getNotInstalled: function() {
     let request = this.createRequest();
     let principal = this._window.document.nodePrincipal;
 
     cpmm.sendAsyncMessage("Webapps:GetNotInstalled", {
       oid: this._id,
@@ -983,39 +965,35 @@ WebappsApplicationMgmt.prototype = {
       requestID: this.getRequestId(request)
     }, null, principal);
 
     return request;
   },
 
   import: function(aBlob) {
     let principal = this._window.document.nodePrincipal;
-    return this.createPromise((aResolve, aReject) => {
+    return this.createPromiseWithId((aResolverId) => {
       cpmm.sendAsyncMessage("Webapps:Import",
         { blob: aBlob,
           oid: this._id,
           topId: this._topId,
-          requestID: this.getPromiseResolverId({
-            resolve: aResolve,
-            reject: aReject
-          })}, null, principal);
+          requestID: aResolverId
+        }, null, principal);
     });
   },
 
   extractManifest: function(aBlob) {
     let principal = this._window.document.nodePrincipal;
-    return this.createPromise((aResolve, aReject) => {
+    return this.createPromiseWithId((aResolverId) => {
       cpmm.sendAsyncMessage("Webapps:ExtractManifest",
         { blob: aBlob,
           oid: this._id,
           topId: this._topId,
-          requestID: this.getPromiseResolverId({
-            resolve: aResolve,
-            reject: aReject
-          })}, null, principal);
+          requestID: aResolverId
+        }, null, principal);
     });
   },
 
   setEnabled: function(aApp, aValue) {
     let principal = this._window.document.nodePrincipal;
 
     cpmm.sendAsyncMessage("Webapps:SetEnabled",
                           { manifestURL: aApp.manifestURL,
--- a/dom/base/DOMRequestHelper.jsm
+++ b/dom/base/DOMRequestHelper.jsm
@@ -293,16 +293,27 @@ DOMRequestIpcHelper.prototype = {
     // If we don't have a valid window object, throw.
     if (!this._window) {
       Cu.reportError("DOMRequestHelper trying to create a Promise without a valid window, failing.");
       throw Cr.NS_ERROR_FAILURE;
     }
     return new this._window.Promise(aPromiseInit);
   },
 
+  /**
+   * createPromiseWithId() creates a new Promise, accepting a callback
+   * which is immediately called with the generated resolverId.
+   */
+  createPromiseWithId: function(aCallback) {
+    return this.createPromise(function(aResolve, aReject) {
+      let resolverId = this.getPromiseResolverId({ resolve: aResolve, reject: aReject });
+      aCallback(resolverId);
+    }.bind(this));
+  },
+
   forEachRequest: function(aCallback) {
     if (!this._requests) {
       return;
     }
 
     Object.keys(this._requests).forEach((aKey) => {
       if (this.getRequest(aKey) instanceof this._window.DOMRequest) {
         aCallback(aKey);
--- a/dom/base/nsContentSink.cpp
+++ b/dom/base/nsContentSink.cpp
@@ -80,22 +80,24 @@ NS_INTERFACE_MAP_END
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsContentSink)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsContentSink)
   if (tmp->mDocument) {
     tmp->mDocument->RemoveObserver(tmp);
   }
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mParser)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mCSSLoader)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mNodeInfoManager)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mScriptLoader)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsContentSink)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParser)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCSSLoader)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNodeInfoManager)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mScriptLoader)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 
 nsContentSink::nsContentSink()
 {
   // We have a zeroing operator new
--- a/dom/base/test/test_audioNotification.html
+++ b/dom/base/test/test_audioNotification.html
@@ -26,20 +26,16 @@ var observer = {
 var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
                                    .getService(SpecialPowers.Ci.nsIObserverService);
 
 var audio = new Audio();
 audio.src = "audio.ogg";
 
 var tests = [
   function() {
-    SpecialPowers.pushPrefEnv({"set": [["media.useAudioChannelService", true]]}, runTest);
-  },
-
-  function() {
     observerService.addObserver(observer, "audio-playback", false);
     ok(true, "Observer set");
     runTest();
   },
 
   function() {
     expectedNotification = 'active';
     audio.play();
--- a/dom/base/test/test_audioNotificationStopOnNavigation.html
+++ b/dom/base/test/test_audioNotificationStopOnNavigation.html
@@ -26,20 +26,16 @@ var observer = {
 };
 
 var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
                                    .getService(SpecialPowers.Ci.nsIObserverService);
 
 var tests = [
   function() {
     iframe = document.querySelector("iframe");
-    SpecialPowers.pushPrefEnv({"set": [["media.useAudioChannelService", true]]}, runTest);
-  },
-
-  function() {
     observerService.addObserver(observer, "audio-playback", false);
     ok(true, "Observer set");
     runTest();
   },
 
   function() {
     expectedNotification = 'active';
     iframe.src = "file_audioLoop.html";
--- a/dom/base/test/test_audioWindowUtils.html
+++ b/dom/base/test/test_audioWindowUtils.html
@@ -94,14 +94,14 @@ function runTest() {
     utils.audioMuted = false;
     ok(utils.audioVolume.toFixed(2), "0.60", "Volume should be preserved");
 
     SimpleTest.finish();
   };
   iframe.src = "data:text/html,page";
 }
 
-SpecialPowers.pushPrefEnv({ "set": [["media.useAudioChannelService", true]]}, runTest);
+onload = runTest;
 SimpleTest.waitForExplicitFinish();
 
 </script>
 </body>
 </html>
--- a/dom/base/test/test_bug913761.html
+++ b/dom/base/test/test_bug913761.html
@@ -9,35 +9,32 @@ https://bugzilla.mozilla.org/show_bug.cg
   <title>Test for Bug 913761 - basic support</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=913761">Mozilla Bug 913761</a>
 <script type="application/javascript">
 
-  function runTest() {
-    var transportChannel = new MessageChannel();
-    transportChannel.port1.onmessage = function (event) {
-      ok(true, 'Port Returned.');
-      var portToService = event.data.port;
-      portToService.onmessage = function (event) {
-        ok(true, "message received");
-        SimpleTest.finish();
-      };
-      portToService.postMessage('READY?');
-    }
-    
-    var serviceChannel = new MessageChannel();
-    serviceChannel.port1.onmessage = function (event) {
-      if (event.data == 'READY?') {
-        this.postMessage('READY!');
-      }
-    }
-    
-    transportChannel.port2.postMessage({ port: serviceChannel.port2}, [serviceChannel.port2]);
+  var transportChannel = new MessageChannel();
+  transportChannel.port1.onmessage = function (event) {
+    ok(true, 'Port Returned.');
+    var portToService = event.data.port;
+    portToService.onmessage = function (event) {
+      ok(true, "message received");
+      SimpleTest.finish();
+    };
+    portToService.postMessage('READY?');
   }
 
+  var serviceChannel = new MessageChannel();
+  serviceChannel.port1.onmessage = function (event) {
+    if (event.data == 'READY?') {
+      this.postMessage('READY!');
+    }
+  }
+
+  transportChannel.port2.postMessage({ port: serviceChannel.port2}, [serviceChannel.port2]);
+
   SimpleTest.waitForExplicitFinish();
-  SpecialPowers.pushPrefEnv({"set": [["dom.messageChannel.enabled", true]]}, runTest);
 </script>
 </body>
 </html>
--- a/dom/base/test/test_domrequesthelper.xul
+++ b/dom/base/test/test_domrequesthelper.xul
@@ -404,16 +404,28 @@
         ok(Promise, "Promise object exists");
         var promise = dummy.createPromise(function(resolve, reject) {
           resolve(true);
         });
         ok(promise instanceof Promise, "Returned a Promise");
         promise.then(next);
       },
       function() {
+        info("== Test createPromiseWithId()");
+        var _resolverId;
+        var promise = dummy.createPromiseWithId(function(resolverId) {
+          _resolverId = resolverId;
+        });
+        var resolver = dummy.getPromiseResolver(_resolverId);
+        ok(promise instanceof Promise, "Returned a Promise");
+        ok(typeof _resolverId === "string", "resolverId is a string");
+        ok(resolver != null, "resolverId is a valid id");
+        next();
+      },
+      function() {
         info("== Test getResolver()");
         var id;
         var resolver;
         var promise = dummy.createPromise(function(resolve, reject) {
           var r = { resolve: resolve, reject: reject };
           id = dummy.getPromiseResolverId(r);
           resolver = r;
           ok(typeof id === "string", "id is a string");
--- a/dom/base/test/test_messagePort.html
+++ b/dom/base/test/test_messagePort.html
@@ -102,14 +102,14 @@ https://bugzilla.mozilla.org/show_bug.cg
       return;
     }
 
     var test = tests.shift();
     test();
   }
 
   SimpleTest.waitForExplicitFinish();
-  SpecialPowers.pushPrefEnv({"set": [["dom.messageChannel.enabled", true]]}, runTest);
+  runTest();
 
 </script>
 </body>
 </html>
 
--- a/dom/base/test/test_noAudioNotification.html
+++ b/dom/base/test/test_noAudioNotification.html
@@ -34,20 +34,16 @@ video.onplay = video.onpause  = function
         runTest();
       });
     });
   });
 };
 
 var tests = [
   function() {
-    SpecialPowers.pushPrefEnv({"set": [["media.useAudioChannelService", true]]}, runTest);
-  },
-
-  function() {
     observerService.addObserver(observer, "audio-playback", false);
     ok(true, "Observer set");
     runTest();
   },
 
   function() {
     video.play();
   },
--- a/dom/base/test/test_noAudioNotificationOnMutedElement.html
+++ b/dom/base/test/test_noAudioNotificationOnMutedElement.html
@@ -30,20 +30,16 @@ var observer = {
 var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
                                    .getService(SpecialPowers.Ci.nsIObserverService);
 
 var audio = new Audio();
 audio.loop = true;
 
 var tests = [
   function() {
-    SpecialPowers.pushPrefEnv({"set": [["media.useAudioChannelService", true]]}, runTest);
-  },
-
-  function() {
     observerService.addObserver(observer, "audio-playback", false);
     ok(true, "Observer set");
 
     audio.src = "audio.ogg";
     // Wait for the audio metadata to become available so that we have an audio track.
     audio.onloadedmetadata = runTest;
   },
 
--- a/dom/base/test/test_noAudioNotificationOnMutedOrVolume0Element.html
+++ b/dom/base/test/test_noAudioNotificationOnMutedOrVolume0Element.html
@@ -30,20 +30,16 @@ var observer = {
 var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
                                    .getService(SpecialPowers.Ci.nsIObserverService);
 
 var audio = new Audio();
 audio.loop = true;
 
 var tests = [
   function() {
-    SpecialPowers.pushPrefEnv({"set": [["media.useAudioChannelService", true]]}, runTest);
-  },
-
-  function() {
     observerService.addObserver(observer, "audio-playback", false);
     ok(true, "Observer set");
 
     audio.src = "audio.ogg";
     // Wait for the audio metadata to become available so that we have an audio track.
     audio.onloadedmetadata = runTest;
   },
 
--- a/dom/base/test/test_noAudioNotificationOnVolume0Element.html
+++ b/dom/base/test/test_noAudioNotificationOnVolume0Element.html
@@ -30,20 +30,16 @@ var observer = {
 var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
                                    .getService(SpecialPowers.Ci.nsIObserverService);
 
 var audio = new Audio();
 audio.loop = true;
 
 var tests = [
   function() {
-    SpecialPowers.pushPrefEnv({"set": [["media.useAudioChannelService", true]]}, runTest);
-  },
-
-  function() {
     observerService.addObserver(observer, "audio-playback", false);
     ok(true, "Observer set");
 
     audio.src = "audio.ogg";
     // Wait for the audio metadata to become available so that we have an audio track.
     audio.onloadedmetadata = runTest;
   },
 
--- a/dom/base/test/test_noWebAudioNotification.html
+++ b/dom/base/test/test_noWebAudioNotification.html
@@ -22,20 +22,16 @@ var observer = {
 
 var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
                                    .getService(SpecialPowers.Ci.nsIObserverService);
 
 var ac;
 
 var tests = [
   function() {
-    SpecialPowers.pushPrefEnv({"set": [["media.useAudioChannelService", true]]}, runTest);
-  },
-
-  function() {
     observerService.addObserver(observer, "audio-playback", false);
     ok(true, "Observer set");
     runTest();
   },
 
   function() {
     ac = new AudioContext();
     setTimeout(runTest, 100);
--- a/dom/base/test/test_pluginAudioNotification.html
+++ b/dom/base/test/test_pluginAudioNotification.html
@@ -59,20 +59,16 @@ var observer = {
 };
 
 var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
                                    .getService(SpecialPowers.Ci.nsIObserverService);
 
 var tests = [
   function() {
     iframe = document.querySelector("iframe");
-    SpecialPowers.pushPrefEnv({"set": [["media.useAudioChannelService", true]]}, runTest);
-  },
-
-  function() {
     observerService.addObserver(observer, "audio-playback", false);
     ok(true, "Observer set");
     runTest();
   },
 
   function() {
     expectedNotification = 'active';
     iframe.src = "file_pluginAudio.html";
--- a/dom/base/test/test_postMessages.html
+++ b/dom/base/test/test_postMessages.html
@@ -380,12 +380,12 @@ function next() {
     return;
   }
 
   var test = tests.shift();
   test();
 }
 
 SimpleTest.waitForExplicitFinish();
-SpecialPowers.pushPrefEnv({"set": [["dom.messageChannel.enabled", true]]}, next);
+next();
 </script>
 </body>
 </html>
--- a/dom/base/test/test_webaudioNotification.html
+++ b/dom/base/test/test_webaudioNotification.html
@@ -26,20 +26,16 @@ var observer = {
 };
 
 var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
                                    .getService(SpecialPowers.Ci.nsIObserverService);
 
 var tests = [
   function() {
     iframe = document.querySelector("iframe");
-    SpecialPowers.pushPrefEnv({"set": [["media.useAudioChannelService", true]]}, runTest);
-  },
-
-  function() {
     observerService.addObserver(observer, "audio-playback", false);
     ok(true, "Observer set");
     runTest();
   },
 
   function() {
     iframe.src = "file_webaudioLoop.html";
     expectedNotification = 'active';
--- a/dom/base/test/test_webaudioNotificationStopOnNavigation.html
+++ b/dom/base/test/test_webaudioNotificationStopOnNavigation.html
@@ -26,20 +26,16 @@ var observer = {
 };
 
 var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
                                    .getService(SpecialPowers.Ci.nsIObserverService);
 
 var tests = [
   function() {
     iframe = document.querySelector("iframe");
-    SpecialPowers.pushPrefEnv({"set": [["media.useAudioChannelService", true]]}, runTest);
-  },
-
-  function() {
     observerService.addObserver(observer, "audio-playback", false);
     ok(true, "Observer set");
     runTest();
   },
 
   function() {
     expectedNotification = 'active';
     iframe.src = "file_webaudioLoop2.html";
--- a/dom/bluetooth/BluetoothInterface.cpp
+++ b/dom/bluetooth/BluetoothInterface.cpp
@@ -81,40 +81,22 @@ BluetoothAvrcpInterface::~BluetoothAvrcp
 
 //
 // Bluetooth GATT Interface
 //
 
 // Notification handling
 //
 
-BluetoothGattClientNotificationHandler::~BluetoothGattClientNotificationHandler()
-{ }
-
-BluetoothGattServerNotificationHandler::~BluetoothGattServerNotificationHandler()
-{ }
-
 BluetoothGattNotificationHandler::~BluetoothGattNotificationHandler()
 { }
 
 // Interface
 //
 
-BluetoothGattClientInterface::BluetoothGattClientInterface()
-{ }
-
-BluetoothGattClientInterface::~BluetoothGattClientInterface()
-{ }
-
-BluetoothGattServerInterface::BluetoothGattServerInterface()
-{ }
-
-BluetoothGattServerInterface::~BluetoothGattServerInterface()
-{ }
-
 BluetoothGattInterface::BluetoothGattInterface()
 { }
 
 BluetoothGattInterface::~BluetoothGattInterface()
 { }
 
 //
 // Bluetooth Core Interface
--- a/dom/bluetooth/BluetoothInterface.h
+++ b/dom/bluetooth/BluetoothInterface.h
@@ -488,17 +488,17 @@ protected:
   BluetoothAvrcpInterface();
   virtual ~BluetoothAvrcpInterface();
 };
 
 //
 // GATT Interface
 //
 
-class BluetoothGattClientNotificationHandler
+class BluetoothGattNotificationHandler
 {
 public:
   virtual void
   RegisterClientNotification(BluetoothGattStatus aStatus,
                              int aClientIf,
                              const BluetoothUuid& aAppUuid)
   { }
 
@@ -597,26 +597,16 @@ public:
                              const nsAString& aBdAddr,
                              int aRssi,
                              BluetoothGattStatus aStatus)
   { }
 
   virtual void
   ListenNotification(BluetoothGattStatus aStatus, int aServerIf) { }
 
-protected:
-  BluetoothGattClientNotificationHandler()
-  { }
-
-  virtual ~BluetoothGattClientNotificationHandler();
-};
-
-class BluetoothGattServerNotificationHandler
-{
-public:
   virtual void
   RegisterServerNotification(BluetoothGattStatus aStatus,
                              int aServerIf,
                              const BluetoothUuid& aAppUuid)
   { }
 
   virtual void
   ConnectionNotification(int aConnId,
@@ -718,56 +708,35 @@ public:
   { }
 
   virtual void
   MtuChangedNotification(int aConnId,
                          int aMtu)
   { }
 
 protected:
-  BluetoothGattServerNotificationHandler()
+  BluetoothGattNotificationHandler()
   { }
 
-  virtual ~BluetoothGattServerNotificationHandler();
-};
-
-class BluetoothGattNotificationHandler
-  : public BluetoothGattClientNotificationHandler
-  , public BluetoothGattServerNotificationHandler
-{
-public:
   virtual ~BluetoothGattNotificationHandler();
-
-protected:
-  BluetoothGattNotificationHandler()
-  { }
 };
 
 class BluetoothGattResultHandler
 {
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BluetoothGattResultHandler)
 
   virtual void OnError(BluetoothStatus aStatus)
   {
     BT_WARNING("Received error code %d", (int)aStatus);
   }
 
   virtual void Init() { }
   virtual void Cleanup() { }
 
-protected:
-  virtual ~BluetoothGattResultHandler() { }
-};
-
-class BluetoothGattClientResultHandler : public BluetoothGattResultHandler
-{
-public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BluetoothGattClientResultHandler)
-
   virtual void RegisterClient() { }
   virtual void UnregisterClient() { }
 
   virtual void Scan() { }
 
   virtual void Connect() { }
   virtual void Disconnect() { }
 
@@ -789,25 +758,16 @@ public:
   virtual void RegisterNotification() { }
   virtual void DeregisterNotification() { }
 
   virtual void ReadRemoteRssi() { }
   virtual void GetDeviceType(BluetoothTypeOfDevice type) { }
   virtual void SetAdvData() { }
   virtual void TestCommand() { }
 
-protected:
-  virtual ~BluetoothGattClientResultHandler() { }
-};
-
-class BluetoothGattServerResultHandler : public BluetoothGattResultHandler
-{
-public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BluetoothGattServerResultHandler)
-
   virtual void RegisterServer() { }
   virtual void UnregisterServer() { }
 
   virtual void ConnectPeripheral() { }
   virtual void DisconnectPeripheral() { }
 
   virtual void AddService() { }
   virtual void AddIncludedService() { }
@@ -818,239 +778,219 @@ public:
   virtual void StopService() { }
   virtual void DeleteService() { }
 
   virtual void SendIndication() { }
 
   virtual void SendResponse() { }
 
 protected:
-  virtual ~BluetoothGattServerResultHandler() { }
+  virtual ~BluetoothGattResultHandler() { }
 };
 
-class BluetoothGattClientInterface
+class BluetoothGattInterface
 {
 public:
+  virtual void Init(BluetoothGattNotificationHandler* aNotificationHandler,
+                    BluetoothGattResultHandler* aRes) = 0;
+  virtual void Cleanup(BluetoothGattResultHandler* aRes) = 0;
+
   /* Register / Unregister */
   virtual void RegisterClient(const BluetoothUuid& aUuid,
-                              BluetoothGattClientResultHandler* aRes) = 0;
+                              BluetoothGattResultHandler* aRes) = 0;
   virtual void UnregisterClient(int aClientIf,
-                                BluetoothGattClientResultHandler* aRes) = 0;
+                                BluetoothGattResultHandler* aRes) = 0;
 
   /* Start / Stop LE Scan */
   virtual void Scan(int aClientIf, bool aStart,
-                    BluetoothGattClientResultHandler* aRes) = 0;
+                    BluetoothGattResultHandler* aRes) = 0;
 
   /* Connect / Disconnect */
   virtual void Connect(int aClientIf,
                        const nsAString& aBdAddr,
                        bool aIsDirect, /* auto connect */
                        BluetoothTransport aTransport,
-                       BluetoothGattClientResultHandler* aRes) = 0;
+                       BluetoothGattResultHandler* aRes) = 0;
   virtual void Disconnect(int aClientIf,
                           const nsAString& aBdAddr,
                           int aConnId,
-                          BluetoothGattClientResultHandler* aRes) = 0;
+                          BluetoothGattResultHandler* aRes) = 0;
 
   /* Start / Stop advertisements to listen for incoming connections */
   virtual void Listen(int aClientIf,
                       bool aIsStart,
-                      BluetoothGattClientResultHandler* aRes) = 0;
+                      BluetoothGattResultHandler* aRes) = 0;
 
   /* Clear the attribute cache for a given device*/
   virtual void Refresh(int aClientIf,
                        const nsAString& aBdAddr,
-                       BluetoothGattClientResultHandler* aRes) = 0;
+                       BluetoothGattResultHandler* aRes) = 0;
 
   /* Enumerate Attributes */
   virtual void SearchService(int aConnId,
                              bool aSearchAll,
                              const BluetoothUuid& aUuid,
-                             BluetoothGattClientResultHandler* aRes) = 0;
+                             BluetoothGattResultHandler* aRes) = 0;
   virtual void GetIncludedService(
     int aConnId,
     const BluetoothGattServiceId& aServiceId,
     bool aFirst,
     const BluetoothGattServiceId& aStartServiceId,
-    BluetoothGattClientResultHandler* aRes) = 0;
+    BluetoothGattResultHandler* aRes) = 0;
   virtual void GetCharacteristic(int aConnId,
                                  const BluetoothGattServiceId& aServiceId,
                                  bool aFirst,
                                  const BluetoothGattId& aStartCharId,
-                                 BluetoothGattClientResultHandler* aRes) = 0;
+                                 BluetoothGattResultHandler* aRes) = 0;
   virtual void GetDescriptor(int aConnId,
                              const BluetoothGattServiceId& aServiceId,
                              const BluetoothGattId& aCharId,
                              bool aFirst,
                              const BluetoothGattId& aDescriptorId,
-                             BluetoothGattClientResultHandler* aRes) = 0;
+                             BluetoothGattResultHandler* aRes) = 0;
 
   /* Read / Write An Attribute */
   virtual void ReadCharacteristic(int aConnId,
                                   const BluetoothGattServiceId& aServiceId,
                                   const BluetoothGattId& aCharId,
                                   BluetoothGattAuthReq aAuthReq,
-                                  BluetoothGattClientResultHandler* aRes) = 0;
+                                  BluetoothGattResultHandler* aRes) = 0;
   virtual void WriteCharacteristic(int aConnId,
                                    const BluetoothGattServiceId& aServiceId,
                                    const BluetoothGattId& aCharId,
                                    BluetoothGattWriteType aWriteType,
                                    BluetoothGattAuthReq aAuthReq,
                                    const nsTArray<uint8_t>& aValue,
-                                   BluetoothGattClientResultHandler* aRes) = 0;
+                                   BluetoothGattResultHandler* aRes) = 0;
   virtual void ReadDescriptor(int aConnId,
                               const BluetoothGattServiceId& aServiceId,
                               const BluetoothGattId& aCharId,
                               const BluetoothGattId& aDescriptorId,
                               BluetoothGattAuthReq aAuthReq,
-                              BluetoothGattClientResultHandler* aRes) = 0;
+                              BluetoothGattResultHandler* aRes) = 0;
   virtual void WriteDescriptor(int aConnId,
                                const BluetoothGattServiceId& aServiceId,
                                const BluetoothGattId& aCharId,
                                const BluetoothGattId& aDescriptorId,
                                BluetoothGattWriteType aWriteType,
                                BluetoothGattAuthReq aAuthReq,
                                const nsTArray<uint8_t>& aValue,
-                               BluetoothGattClientResultHandler* aRes) = 0;
+                               BluetoothGattResultHandler* aRes) = 0;
 
   /* Execute / Abort Prepared Write*/
   virtual void ExecuteWrite(int aConnId,
                             int aIsExecute,
-                            BluetoothGattClientResultHandler* aRes) = 0;
-
+                            BluetoothGattResultHandler* aRes) = 0;
 
   /* Register / Deregister Characteristic Notifications or Indications */
   virtual void RegisterNotification(
     int aClientIf,
     const nsAString& aBdAddr,
     const BluetoothGattServiceId& aServiceId,
     const BluetoothGattId& aCharId,
-    BluetoothGattClientResultHandler* aRes) = 0;
+    BluetoothGattResultHandler* aRes) = 0;
   virtual void DeregisterNotification(
     int aClientIf,
     const nsAString& aBdAddr,
     const BluetoothGattServiceId& aServiceId,
     const BluetoothGattId& aCharId,
-    BluetoothGattClientResultHandler* aRes) = 0;
+    BluetoothGattResultHandler* aRes) = 0;
 
   virtual void ReadRemoteRssi(int aClientIf,
                               const nsAString& aBdAddr,
-                              BluetoothGattClientResultHandler* aRes) = 0;
+                              BluetoothGattResultHandler* aRes) = 0;
 
   virtual void GetDeviceType(const nsAString& aBdAddr,
-                             BluetoothGattClientResultHandler* aRes) = 0;
+                             BluetoothGattResultHandler* aRes) = 0;
 
   /* Set advertising data or scan response data */
   virtual void SetAdvData(int aServerIf,
                           bool aIsScanRsp,
                           bool aIsNameIncluded,
                           bool aIsTxPowerIncluded,
                           int aMinInterval,
                           int aMaxInterval,
                           int aApperance,
                           uint16_t aManufacturerLen,
                           char* aManufacturerData,
                           uint16_t aServiceDataLen,
                           char* aServiceData,
                           uint16_t aServiceUUIDLen,
                           char* aServiceUUID,
-                          BluetoothGattClientResultHandler* aRes) = 0;
+                          BluetoothGattResultHandler* aRes) = 0;
 
   virtual void TestCommand(int aCommand,
                            const BluetoothGattTestParam& aTestParam,
-                           BluetoothGattClientResultHandler* aRes) = 0;
+                           BluetoothGattResultHandler* aRes) = 0;
 
-protected:
-  BluetoothGattClientInterface();
-  virtual ~BluetoothGattClientInterface();
-};
-
-class BluetoothGattServerInterface
-{
-public:
   /* Register / Unregister */
   virtual void RegisterServer(const BluetoothUuid& aUuid,
-                              BluetoothGattServerResultHandler* aRes) = 0;
+                              BluetoothGattResultHandler* aRes) = 0;
   virtual void UnregisterServer(int aServerIf,
-                                BluetoothGattServerResultHandler* aRes) = 0;
+                                BluetoothGattResultHandler* aRes) = 0;
 
   /* Connect / Disconnect */
   virtual void ConnectPeripheral(int aServerIf,
                                  const nsAString& aBdAddr,
                                  bool aIsDirect, /* auto connect */
                                  BluetoothTransport aTransport,
-                                 BluetoothGattServerResultHandler* aRes) = 0;
+                                 BluetoothGattResultHandler* aRes) = 0;
   virtual void DisconnectPeripheral(int aServerIf,
                                     const nsAString& aBdAddr,
                                     int aConnId,
-                                    BluetoothGattServerResultHandler* aRes) = 0;
+                                    BluetoothGattResultHandler* aRes) = 0;
 
   /* Add a services / a characteristic / a descriptor */
   virtual void AddService(int aServerIf,
                           const BluetoothGattServiceId& aServiceId,
                           int aNumHandles,
-                          BluetoothGattServerResultHandler* aRes) = 0;
+                          BluetoothGattResultHandler* aRes) = 0;
   virtual void AddIncludedService(int aServerIf,
                                   int aServiceHandle,
                                   int aIncludedServiceHandle,
-                                  BluetoothGattServerResultHandler* aRes) = 0;
+                                  BluetoothGattResultHandler* aRes) = 0;
   virtual void AddCharacteristic(int aServerIf,
                                  int aServiceHandle,
                                  const BluetoothUuid& aUuid,
                                  BluetoothGattCharProp aProperties,
                                  BluetoothGattAttrPerm aPermissions,
-                                 BluetoothGattServerResultHandler* aRes) = 0;
+                                 BluetoothGattResultHandler* aRes) = 0;
   virtual void AddDescriptor(int aServerIf,
                              int aServiceHandle,
                              const BluetoothUuid& aUuid,
                              BluetoothGattAttrPerm aPermissions,
-                             BluetoothGattServerResultHandler* aRes) = 0;
+                             BluetoothGattResultHandler* aRes) = 0;
 
   /* Start / Stop / Delete a service */
   virtual void StartService(int aServerIf,
                             int aServiceHandle,
                             BluetoothTransport aTransport,
-                            BluetoothGattServerResultHandler* aRes) = 0;
+                            BluetoothGattResultHandler* aRes) = 0;
   virtual void StopService(int aServerIf,
                            int aServiceHandle,
-                           BluetoothGattServerResultHandler* aRes) = 0;
+                           BluetoothGattResultHandler* aRes) = 0;
   virtual void DeleteService(int aServerIf,
                              int aServiceHandle,
-                             BluetoothGattServerResultHandler* aRes) = 0;
+                             BluetoothGattResultHandler* aRes) = 0;
 
   /* Send an indication or a notification */
   virtual void SendIndication(int aServerIf,
                               int aAttributeHandle,
                               int aConnId,
                               const nsTArray<uint8_t>& aValue,
                               bool aConfirm, /* true: indication */
                                              /* false: notification */
-                              BluetoothGattServerResultHandler* aRes) = 0;
+                              BluetoothGattResultHandler* aRes) = 0;
 
   /* Send a response for an incoming indication */
   virtual void SendResponse(int aConnId,
                             int aTransId,
                             BluetoothGattStatus aStatus,
                             const BluetoothGattResponse& aResponse,
-                            BluetoothGattServerResultHandler* aRes) = 0;
-
-protected:
-  BluetoothGattServerInterface();
-  virtual ~BluetoothGattServerInterface();
-};
-
-class BluetoothGattInterface
-{
-public:
-  virtual void Init(BluetoothGattNotificationHandler* aNotificationHandler,
-                    BluetoothGattResultHandler* aRes) = 0;
-  virtual void Cleanup(BluetoothGattResultHandler* aRes) = 0;
-
-  virtual BluetoothGattClientInterface* GetBluetoothGattClientInterface() = 0;
-  virtual BluetoothGattServerInterface* GetBluetoothGattServerInterface() = 0;
+                            BluetoothGattResultHandler* aRes) = 0;
 
 protected:
   BluetoothGattInterface();
   virtual ~BluetoothGattInterface();
 };
 
 //
 // Bluetooth Core Interface
--- a/dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.cpp
@@ -33,34 +33,16 @@ BluetoothDaemonGattModule::Send(DaemonSo
                                 BluetoothGattResultHandler* aRes)
 {
   if (aRes) {
     aRes->AddRef(); // Keep reference for response
   }
   return Send(aPDU, static_cast<void*>(aRes));
 }
 
-nsresult
-BluetoothDaemonGattModule::Send(DaemonSocketPDU* aPDU,
-                                BluetoothGattClientResultHandler* aRes)
-{
-  if (aRes) {
-    aRes->AddRef(); // Keep reference for response
-  }
-  return Send(aPDU, static_cast<void*>(aRes));
-}
-
-nsresult
-BluetoothDaemonGattModule::Send(DaemonSocketPDU* aPDU,
-                                BluetoothGattServerResultHandler* aRes)
-{
-  aRes->AddRef(); // Keep reference for response
-  return Send(aPDU, static_cast<void*>(aRes));
-}
-
 void
 BluetoothDaemonGattModule::HandleSvc(const DaemonSocketPDUHeader& aHeader,
                                      DaemonSocketPDU& aPDU, void* aUserData)
 {
   static void (BluetoothDaemonGattModule::* const HandleOp[])(
     const DaemonSocketPDUHeader&, DaemonSocketPDU&, void*) = {
     INIT_ARRAY_AT(0, &BluetoothDaemonGattModule::HandleRsp),
     INIT_ARRAY_AT(1, &BluetoothDaemonGattModule::HandleNtf),
@@ -74,17 +56,17 @@ BluetoothDaemonGattModule::HandleSvc(con
   (this->*(HandleOp[isNtf]))(aHeader, aPDU, aUserData);
 }
 
 // Commands
 //
 
 nsresult
 BluetoothDaemonGattModule::ClientRegisterCmd(
-  const BluetoothUuid& aUuid, BluetoothGattClientResultHandler* aRes)
+  const BluetoothUuid& aUuid, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_REGISTER,
                         16)); // Service UUID
 
   nsresult rv = PackPDU(aUuid, *pdu);
@@ -97,17 +79,17 @@ BluetoothDaemonGattModule::ClientRegiste
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientUnregisterCmd(
-  int aClientIf, BluetoothGattClientResultHandler* aRes)
+  int aClientIf, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_UNREGISTER,
                         4)); // Client Interface
 
   nsresult rv = PackPDU(aClientIf, *pdu);
@@ -119,17 +101,17 @@ BluetoothDaemonGattModule::ClientUnregis
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientScanCmd(
-  int aClientIf, bool aStart, BluetoothGattClientResultHandler* aRes)
+  int aClientIf, bool aStart, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_SCAN,
                         4 + // Client Interface
                         1)); // Start
 
@@ -144,17 +126,17 @@ BluetoothDaemonGattModule::ClientScanCmd
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientConnectCmd(
   int aClientIf, const nsAString& aBdAddr, bool aIsDirect,
-  BluetoothTransport aTransport, BluetoothGattClientResultHandler* aRes)
+  BluetoothTransport aTransport, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_CONNECT,
                         4 + // Client Interface
                         6 + // Remote Address
                         1 + // Is Direct
@@ -174,17 +156,17 @@ BluetoothDaemonGattModule::ClientConnect
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientDisconnectCmd(
   int aClientIf, const nsAString& aBdAddr, int aConnId,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_DISCONNECT,
                         4 + // Client Interface
                         6 + // Remote Address
                         4)); // Connection ID
@@ -201,17 +183,17 @@ BluetoothDaemonGattModule::ClientDisconn
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientListenCmd(
-  int aClientIf, bool aIsStart, BluetoothGattClientResultHandler* aRes)
+  int aClientIf, bool aIsStart, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_LISTEN,
                         4 + // Client Interface
                         1)); // Start
 
@@ -226,18 +208,17 @@ BluetoothDaemonGattModule::ClientListenC
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientRefreshCmd(
-  int aClientIf, const nsAString& aBdAddr,
-  BluetoothGattClientResultHandler* aRes)
+  int aClientIf, const nsAString& aBdAddr, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_REFRESH,
                         4 + // Client Interface
                         6)); // Remote Address
 
@@ -253,17 +234,17 @@ BluetoothDaemonGattModule::ClientRefresh
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientSearchServiceCmd(
   int aConnId, bool aFiltered, const BluetoothUuid& aUuid,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_SEARCH_SERVICE,
                         4 + // Connection ID
                         1 + // Filtered
                         16)); // UUID
@@ -282,17 +263,17 @@ BluetoothDaemonGattModule::ClientSearchS
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientGetIncludedServiceCmd(
   int aConnId, const BluetoothGattServiceId& aServiceId, bool aContinuation,
   const BluetoothGattServiceId& aStartServiceId,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_GET_INCLUDED_SERVICE,
                         4 + // Connection ID
                         18 + // Service ID
                         1 + // Continuation
@@ -311,17 +292,17 @@ BluetoothDaemonGattModule::ClientGetIncl
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientGetCharacteristicCmd(
   int aConnId, const BluetoothGattServiceId& aServiceId, bool aContinuation,
   const BluetoothGattId& aStartCharId,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_GET_CHARACTERISTIC,
                         4 + // Connection ID
                         18 + // Service ID
                         1 + // Continuation
@@ -342,17 +323,17 @@ BluetoothDaemonGattModule::ClientGetChar
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientGetDescriptorCmd(
   int aConnId, const BluetoothGattServiceId& aServiceId,
   const BluetoothGattId& aCharId, bool aContinuation,
   const BluetoothGattId& aStartDescriptorId,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_GET_DESCRIPTOR,
                         4 + // Connection ID
                         18 + // Service ID
                         17 + // Characteristic ID
@@ -373,17 +354,17 @@ BluetoothDaemonGattModule::ClientGetDesc
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientReadCharacteristicCmd(
   int aConnId, const BluetoothGattServiceId& aServiceId,
   const BluetoothGattId& aCharId, BluetoothGattAuthReq aAuthReq,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_READ_CHARACTERISTIC,
                         4 + // Connection ID
                         18 + // Service ID
                         17 + // Characteristic ID
@@ -402,17 +383,17 @@ BluetoothDaemonGattModule::ClientReadCha
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientWriteCharacteristicCmd(
   int aConnId, const BluetoothGattServiceId& aServiceId,
   const BluetoothGattId& aCharId, BluetoothGattWriteType aWriteType,
   int aLength, BluetoothGattAuthReq aAuthReq, char* aValue,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_WRITE_CHARACTERISTIC, 0));
 
   nsresult rv = PackPDU(PackConversion<int, int32_t>(aConnId), aServiceId,
                         aCharId, aWriteType,
@@ -428,17 +409,17 @@ BluetoothDaemonGattModule::ClientWriteCh
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientReadDescriptorCmd(
   int aConnId, const BluetoothGattServiceId& aServiceId,
   const BluetoothGattId& aCharId, const BluetoothGattId& aDescriptorId,
-  BluetoothGattAuthReq aAuthReq, BluetoothGattClientResultHandler* aRes)
+  BluetoothGattAuthReq aAuthReq, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_READ_DESCRIPTOR,
                         4 + // Connection ID
                         18 + // Service ID
                         17 + // Characteristic ID
@@ -459,17 +440,17 @@ BluetoothDaemonGattModule::ClientReadDes
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientWriteDescriptorCmd(
   int aConnId, const BluetoothGattServiceId& aServiceId,
   const BluetoothGattId& aCharId, const BluetoothGattId& aDescriptorId,
   BluetoothGattWriteType aWriteType, int aLength,
   BluetoothGattAuthReq aAuthReq, char* aValue,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_WRITE_DESCRIPTOR, 0));
 
   nsresult rv = PackPDU(PackConversion<int, int32_t>(aConnId), aServiceId,
                         aCharId, aDescriptorId, aWriteType,
@@ -483,17 +464,17 @@ BluetoothDaemonGattModule::ClientWriteDe
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientExecuteWriteCmd(
-  int aConnId, int aIsExecute, BluetoothGattClientResultHandler* aRes)
+  int aConnId, int aIsExecute, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_EXECUTE_WRITE,
                         4 + // Connection ID
                         4)); // Execute
 
@@ -509,17 +490,17 @@ BluetoothDaemonGattModule::ClientExecute
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientRegisterNotificationCmd(
   int aClientIf, const nsAString& aBdAddr,
   const BluetoothGattServiceId& aServiceId, const BluetoothGattId& aCharId,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_REGISTER_NOTIFICATION,
                         4 + // Client Interface
                         6 + // Remote Address
                         18 + // Service ID
@@ -538,17 +519,17 @@ BluetoothDaemonGattModule::ClientRegiste
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientDeregisterNotificationCmd(
   int aClientIf, const nsAString& aBdAddr,
   const BluetoothGattServiceId& aServiceId, const BluetoothGattId& aCharId,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_DEREGISTER_NOTIFICATION,
                         4 + // Client Interface
                         6 + // Remote Address
                         18 + // Service ID
@@ -566,17 +547,17 @@ BluetoothDaemonGattModule::ClientDeregis
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientReadRemoteRssiCmd(
   int aClientIf, const nsAString& aBdAddr,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_READ_REMOTE_RSSI,
                         4 + // Client Interface
                         6)); // Remote Address
 
@@ -591,17 +572,17 @@ BluetoothDaemonGattModule::ClientReadRem
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientGetDeviceTypeCmd(
-  const nsAString& aBdAddr, BluetoothGattClientResultHandler* aRes)
+  const nsAString& aBdAddr, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_GET_DEVICE_TYPE,
                         6)); // Remote Address
 
   nsresult rv = PackPDU(
@@ -619,17 +600,17 @@ BluetoothDaemonGattModule::ClientGetDevi
 
 nsresult
 BluetoothDaemonGattModule::ClientSetAdvDataCmd(
   int aServerIf, bool aIsScanRsp, bool aIsNameIncluded,
   bool aIsTxPowerIncluded, int aMinInterval, int aMaxInterval, int aApperance,
   uint16_t aManufacturerLen, char* aManufacturerData,
   uint16_t aServiceDataLen, char* aServiceData,
   uint16_t aServiceUuidLen, char* aServiceUuid,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_SET_ADV_DATA, 0));
 
   nsresult rv = PackPDU(
     PackConversion<int, int32_t>(aServerIf),
@@ -651,17 +632,17 @@ BluetoothDaemonGattModule::ClientSetAdvD
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientTestCommandCmd(
   int aCommand, const BluetoothGattTestParam& aTestParam,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_TEST_COMMAND,
                         4 + // Command
                         6 + // Address
                         16 + // UUID
@@ -684,17 +665,17 @@ BluetoothDaemonGattModule::ClientTestCom
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ServerRegisterCmd(
-  const BluetoothUuid& aUuid, BluetoothGattServerResultHandler* aRes)
+  const BluetoothUuid& aUuid, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_SERVER_REGISTER,
                         16)); // Uuid
 
   nsresult rv = PackPDU(aUuid, *pdu);
@@ -706,17 +687,17 @@ BluetoothDaemonGattModule::ServerRegiste
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ServerUnregisterCmd(
-  int aServerIf, BluetoothGattServerResultHandler* aRes)
+  int aServerIf, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_SERVER_UNREGISTER,
                         4)); // Server Interface
 
   nsresult rv = PackPDU(PackConversion<int, int32_t>(aServerIf), *pdu);
@@ -729,17 +710,17 @@ BluetoothDaemonGattModule::ServerUnregis
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ServerConnectPeripheralCmd(
   int aServerIf, const nsAString& aBdAddr, bool aIsDirect,
-  BluetoothTransport aTransport, BluetoothGattServerResultHandler* aRes)
+  BluetoothTransport aTransport, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_SERVER_CONNECT_PERIPHERAL,
                         4 + // Server Interface
                         6 + // Remote Address
                         1 + // Is Direct
@@ -759,17 +740,17 @@ BluetoothDaemonGattModule::ServerConnect
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ServerDisconnectPeripheralCmd(
   int aServerIf, const nsAString& aBdAddr, int aConnId,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_SERVER_DISCONNECT_PERIPHERAL,
                         4 + // Server Interface
                         6 + // Remote Address
                         4)); // Connection Id
@@ -786,17 +767,17 @@ BluetoothDaemonGattModule::ServerDisconn
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ServerAddServiceCmd(
   int aServerIf, const BluetoothGattServiceId& aServiceId, int aNumHandles,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_SERVER_ADD_SERVICE,
                         4 + // Server Interface
                         18 + // Service ID
                         4)); // Number of Handles
@@ -812,17 +793,17 @@ BluetoothDaemonGattModule::ServerAddServ
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ServerAddIncludedServiceCmd(
   int aServerIf, int aServiceHandle, int aIncludedServiceHandle,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_SERVER_ADD_INCLUDED_SERVICE,
                         4 + // Server Interface
                         4 + // Service Handle
                         4)); // Included Service Handle
@@ -841,17 +822,17 @@ BluetoothDaemonGattModule::ServerAddIncl
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ServerAddCharacteristicCmd(
   int aServerIf, int aServiceHandle, const BluetoothUuid& aUuid,
   BluetoothGattCharProp aProperties, BluetoothGattAttrPerm aPermissions,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_SERVER_ADD_CHARACTERISTIC,
                         4 + // Server Interface
                         4 + // Service Handle
                         16 + // UUID
@@ -870,17 +851,17 @@ BluetoothDaemonGattModule::ServerAddChar
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ServerAddDescriptorCmd(
   int aServerIf, int aServiceHandle, const BluetoothUuid& aUuid,
-  BluetoothGattAttrPerm aPermissions, BluetoothGattServerResultHandler* aRes)
+  BluetoothGattAttrPerm aPermissions, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_SERVER_ADD_DESCRIPTOR,
                         4 + // Server Interface
                         4 + // Service Handle
                         16 + // UUID
@@ -898,17 +879,17 @@ BluetoothDaemonGattModule::ServerAddDesc
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ServerStartServiceCmd(
   int aServerIf, int aServiceHandle, BluetoothTransport aTransport,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_SERVER_START_SERVICE,
                         4 + // Server Interface
                         4 + // Service Handle
                         4)); // Transport
@@ -925,17 +906,17 @@ BluetoothDaemonGattModule::ServerStartSe
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ServerStopServiceCmd(
-  int aServerIf, int aServiceHandle, BluetoothGattServerResultHandler* aRes)
+  int aServerIf, int aServiceHandle, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_SERVER_STOP_SERVICE,
                         4 + // Server Interface
                         4)); // Service Handle
 
@@ -949,17 +930,17 @@ BluetoothDaemonGattModule::ServerStopSer
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ServerDeleteServiceCmd(
-  int aServerIf, int aServiceHandle, BluetoothGattServerResultHandler* aRes)
+  int aServerIf, int aServiceHandle, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_SERVER_DELETE_SERVICE,
                         4 + // Server Interface
                         4)); // Service Handle
 
@@ -974,17 +955,17 @@ BluetoothDaemonGattModule::ServerDeleteS
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ServerSendIndicationCmd(
   int aServerIf, int aAttributeHandle, int aConnId, int aLength, bool aConfirm,
-  uint8_t* aValue, BluetoothGattServerResultHandler* aRes)
+  uint8_t* aValue, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_SERVER_SEND_INDICATION,
                         0));
 
   nsresult rv = PackPDU(PackConversion<int, int32_t>(aServerIf),
@@ -1003,17 +984,17 @@ BluetoothDaemonGattModule::ServerSendInd
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ServerSendResponseCmd(
   int aConnId, int aTransId, BluetoothGattStatus aStatus,
   const BluetoothGattResponse& aResponse,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_SERVER_SEND_RESPONSE,
                         0));
 
   nsresult rv = PackPDU(
@@ -1047,196 +1028,196 @@ BluetoothDaemonGattModule::ErrorRsp(
 {
   ErrorRunnable::Dispatch(
     aRes, &BluetoothGattResultHandler::OnError, UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientRegisterRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ClientResultRunnable::Dispatch(
-    aRes, &BluetoothGattClientResultHandler::RegisterClient,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::RegisterClient,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientUnregisterRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ClientResultRunnable::Dispatch(
-    aRes, &BluetoothGattClientResultHandler::UnregisterClient,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::UnregisterClient,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientScanRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ClientResultRunnable::Dispatch(
-    aRes, &BluetoothGattClientResultHandler::Scan, UnpackPDUInitOp(aPDU));
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::Scan, UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientConnectRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ClientResultRunnable::Dispatch(
-    aRes, &BluetoothGattClientResultHandler::Connect, UnpackPDUInitOp(aPDU));
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::Connect, UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientDisconnectRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ClientResultRunnable::Dispatch(
-    aRes, &BluetoothGattClientResultHandler::Disconnect,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::Disconnect,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientListenRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ClientResultRunnable::Dispatch(
-    aRes, &BluetoothGattClientResultHandler::Listen, UnpackPDUInitOp(aPDU));
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::Listen, UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientRefreshRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ClientResultRunnable::Dispatch(
-    aRes, &BluetoothGattClientResultHandler::Refresh, UnpackPDUInitOp(aPDU));
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::Refresh, UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientSearchServiceRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ClientResultRunnable::Dispatch(
-    aRes, &BluetoothGattClientResultHandler::SearchService,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::SearchService,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientGetIncludedServiceRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ClientResultRunnable::Dispatch(
-    aRes, &BluetoothGattClientResultHandler::GetIncludedService,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::GetIncludedService,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientGetCharacteristicRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ClientResultRunnable::Dispatch(
-    aRes, &BluetoothGattClientResultHandler::GetCharacteristic,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::GetCharacteristic,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientGetDescriptorRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ClientResultRunnable::Dispatch(
-    aRes, &BluetoothGattClientResultHandler::GetDescriptor,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::GetDescriptor,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientReadCharacteristicRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ClientResultRunnable::Dispatch(
-    aRes, &BluetoothGattClientResultHandler::ReadCharacteristic,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::ReadCharacteristic,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientWriteCharacteristicRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ClientResultRunnable::Dispatch(
-    aRes, &BluetoothGattClientResultHandler::WriteCharacteristic,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::WriteCharacteristic,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientReadDescriptorRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ClientResultRunnable::Dispatch(
-    aRes, &BluetoothGattClientResultHandler::ReadDescriptor,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::ReadDescriptor,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientWriteDescriptorRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ClientResultRunnable::Dispatch(
-    aRes, &BluetoothGattClientResultHandler::WriteDescriptor,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::WriteDescriptor,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientExecuteWriteRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ClientResultRunnable::Dispatch(
-    aRes, &BluetoothGattClientResultHandler::ExecuteWrite,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::ExecuteWrite,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientRegisterNotificationRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ClientResultRunnable::Dispatch(
-    aRes, &BluetoothGattClientResultHandler::RegisterNotification,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::RegisterNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientDeregisterNotificationRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ClientResultRunnable::Dispatch(
-    aRes, &BluetoothGattClientResultHandler::DeregisterNotification,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::DeregisterNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientReadRemoteRssiRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ClientResultRunnable::Dispatch(
-    aRes, &BluetoothGattClientResultHandler::ReadRemoteRssi,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::ReadRemoteRssi,
     UnpackPDUInitOp(aPDU));
 }
 
 // Init operator class for ClientGetDeviceTypeRsp
 class BluetoothDaemonGattModule::ClientGetDeviceTypeInitOp final
   : private PDUInitOp
 {
 public:
@@ -1256,191 +1237,184 @@ public:
     WarnAboutTrailingData();
     return NS_OK;
   }
 };
 
 void
 BluetoothDaemonGattModule::ClientGetDeviceTypeRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   ClientGetDeviceTypeResultRunnable::Dispatch(
-    aRes, &BluetoothGattClientResultHandler::GetDeviceType,
+    aRes, &BluetoothGattResultHandler::GetDeviceType,
     ClientGetDeviceTypeInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientSetAdvDataRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ClientResultRunnable::Dispatch(
-    aRes, &BluetoothGattClientResultHandler::SetAdvData,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::SetAdvData,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientTestCommandRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ClientResultRunnable::Dispatch(
-    aRes, &BluetoothGattClientResultHandler::TestCommand,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::TestCommand,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ServerRegisterRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ServerResultRunnable::Dispatch(
-    aRes, &BluetoothGattServerResultHandler::RegisterServer,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::RegisterServer,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ServerUnregisterRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ServerResultRunnable::Dispatch(
-    aRes, &BluetoothGattServerResultHandler::UnregisterServer,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::UnregisterServer,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ServerConnectPeripheralRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ServerResultRunnable::Dispatch(
-    aRes, &BluetoothGattServerResultHandler::ConnectPeripheral,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::ConnectPeripheral,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ServerDisconnectPeripheralRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ServerResultRunnable::Dispatch(
-    aRes, &BluetoothGattServerResultHandler::DisconnectPeripheral,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::DisconnectPeripheral,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ServerAddServiceRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ServerResultRunnable::Dispatch(
-    aRes, &BluetoothGattServerResultHandler::AddService,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::AddService,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ServerAddIncludedServiceRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ServerResultRunnable::Dispatch(
-    aRes, &BluetoothGattServerResultHandler::AddIncludedService,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::AddIncludedService,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ServerAddCharacteristicRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ServerResultRunnable::Dispatch(
-    aRes, &BluetoothGattServerResultHandler::AddCharacteristic,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::AddCharacteristic,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ServerAddDescriptorRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ServerResultRunnable::Dispatch(
-    aRes, &BluetoothGattServerResultHandler::AddDescriptor,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::AddDescriptor,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ServerStartServiceRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ServerResultRunnable::Dispatch(
-    aRes, &BluetoothGattServerResultHandler::StartService,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::StartService,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ServerStopServiceRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ServerResultRunnable::Dispatch(
-    aRes, &BluetoothGattServerResultHandler::StopService,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::StopService,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ServerDeleteServiceRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ServerResultRunnable::Dispatch(
-    aRes, &BluetoothGattServerResultHandler::DeleteService,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::DeleteService,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ServerSendIndicationRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ServerResultRunnable::Dispatch(
-    aRes, &BluetoothGattServerResultHandler::SendIndication,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::SendIndication,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ServerSendResponseRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
-  ServerResultRunnable::Dispatch(
-    aRes, &BluetoothGattServerResultHandler::SendResponse,
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothGattResultHandler::SendResponse,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::HandleRsp(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
   void* aUserData)
 {
   static void (BluetoothDaemonGattModule::* const HandleRsp[])(
     const DaemonSocketPDUHeader&,
     DaemonSocketPDU&,
     BluetoothGattResultHandler*) = {
     INIT_ARRAY_AT(OPCODE_ERROR,
-      &BluetoothDaemonGattModule::ErrorRsp)
-    };
-
-  static void (BluetoothDaemonGattModule::* const HandleClientRsp[])(
-    const DaemonSocketPDUHeader&,
-    DaemonSocketPDU&,
-    BluetoothGattClientResultHandler*) = {
-    INIT_ARRAY_AT(0, nullptr),
+      &BluetoothDaemonGattModule::ErrorRsp),
     INIT_ARRAY_AT(OPCODE_CLIENT_REGISTER,
       &BluetoothDaemonGattModule::ClientRegisterRsp),
     INIT_ARRAY_AT(OPCODE_CLIENT_UNREGISTER,
       &BluetoothDaemonGattModule::ClientUnregisterRsp),
     INIT_ARRAY_AT(OPCODE_CLIENT_SCAN,
       &BluetoothDaemonGattModule::ClientScanRsp),
     INIT_ARRAY_AT(OPCODE_CLIENT_CONNECT,
       &BluetoothDaemonGattModule::ClientConnectRsp),
@@ -1474,52 +1448,17 @@ BluetoothDaemonGattModule::HandleRsp(
       &BluetoothDaemonGattModule::ClientDeregisterNotificationRsp),
     INIT_ARRAY_AT(OPCODE_CLIENT_READ_REMOTE_RSSI,
       &BluetoothDaemonGattModule::ClientReadRemoteRssiRsp),
     INIT_ARRAY_AT(OPCODE_CLIENT_GET_DEVICE_TYPE,
       &BluetoothDaemonGattModule::ClientGetDeviceTypeRsp),
     INIT_ARRAY_AT(OPCODE_CLIENT_SET_ADV_DATA,
       &BluetoothDaemonGattModule::ClientSetAdvDataRsp),
     INIT_ARRAY_AT(OPCODE_CLIENT_TEST_COMMAND,
-      &BluetoothDaemonGattModule::ClientTestCommandRsp)
-  };
-
-  /**
-   * These client opcodes are added since non-trivial designated initializers
-   * are not supported.
-   * We could use a single array for GattRsp, GattClientRsp, and GattServerRsp
-   * after combining result handlers in Bug 1181512.
-   **/
-  static void (BluetoothDaemonGattModule::* const HandleServerRsp[])(
-    const DaemonSocketPDUHeader&,
-    DaemonSocketPDU&,
-    BluetoothGattServerResultHandler*) = {
-    INIT_ARRAY_AT(0, nullptr),
-    INIT_ARRAY_AT(OPCODE_CLIENT_REGISTER, nullptr),
-    INIT_ARRAY_AT(OPCODE_CLIENT_UNREGISTER, nullptr),
-    INIT_ARRAY_AT(OPCODE_CLIENT_SCAN, nullptr),
-    INIT_ARRAY_AT(OPCODE_CLIENT_CONNECT, nullptr),
-    INIT_ARRAY_AT(OPCODE_CLIENT_DISCONNECT, nullptr),
-    INIT_ARRAY_AT(OPCODE_CLIENT_LISTEN, nullptr),
-    INIT_ARRAY_AT(OPCODE_CLIENT_REFRESH, nullptr),
-    INIT_ARRAY_AT(OPCODE_CLIENT_SEARCH_SERVICE, nullptr),
-    INIT_ARRAY_AT(OPCODE_CLIENT_GET_INCLUDED_SERVICE, nullptr),
-    INIT_ARRAY_AT(OPCODE_CLIENT_GET_CHARACTERISTIC, nullptr),
-    INIT_ARRAY_AT(OPCODE_CLIENT_GET_DESCRIPTOR, nullptr),
-    INIT_ARRAY_AT(OPCODE_CLIENT_READ_CHARACTERISTIC, nullptr),
-    INIT_ARRAY_AT(OPCODE_CLIENT_WRITE_CHARACTERISTIC, nullptr),
-    INIT_ARRAY_AT(OPCODE_CLIENT_READ_DESCRIPTOR, nullptr),
-    INIT_ARRAY_AT(OPCODE_CLIENT_WRITE_DESCRIPTOR, nullptr),
-    INIT_ARRAY_AT(OPCODE_CLIENT_EXECUTE_WRITE, nullptr),
-    INIT_ARRAY_AT(OPCODE_CLIENT_REGISTER_NOTIFICATION, nullptr),
-    INIT_ARRAY_AT(OPCODE_CLIENT_DEREGISTER_NOTIFICATION, nullptr),
-    INIT_ARRAY_AT(OPCODE_CLIENT_READ_REMOTE_RSSI, nullptr),
-    INIT_ARRAY_AT(OPCODE_CLIENT_GET_DEVICE_TYPE, nullptr),
-    INIT_ARRAY_AT(OPCODE_CLIENT_SET_ADV_DATA, nullptr),
-    INIT_ARRAY_AT(OPCODE_CLIENT_TEST_COMMAND, nullptr),
+      &BluetoothDaemonGattModule::ClientTestCommandRsp),
     INIT_ARRAY_AT(OPCODE_SERVER_REGISTER,
       &BluetoothDaemonGattModule::ServerRegisterRsp),
     INIT_ARRAY_AT(OPCODE_SERVER_UNREGISTER,
       &BluetoothDaemonGattModule::ServerUnregisterRsp),
     INIT_ARRAY_AT(OPCODE_SERVER_CONNECT_PERIPHERAL,
       &BluetoothDaemonGattModule::ServerConnectPeripheralRsp),
     INIT_ARRAY_AT(OPCODE_SERVER_DISCONNECT_PERIPHERAL,
       &BluetoothDaemonGattModule::ServerDisconnectPeripheralRsp),
@@ -1540,51 +1479,30 @@ BluetoothDaemonGattModule::HandleRsp(
     INIT_ARRAY_AT(OPCODE_SERVER_SEND_INDICATION,
       &BluetoothDaemonGattModule::ServerSendIndicationRsp),
     INIT_ARRAY_AT(OPCODE_SERVER_SEND_RESPONSE,
       &BluetoothDaemonGattModule::ServerSendResponseRsp)
   };
 
   MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
 
-  bool isInGattArray = aHeader.mOpcode < MOZ_ARRAY_LENGTH(HandleRsp) &&
-                       HandleRsp[aHeader.mOpcode];
-  bool isInGattClientArray =
-    aHeader.mOpcode < MOZ_ARRAY_LENGTH(HandleClientRsp) &&
-    HandleClientRsp[aHeader.mOpcode];
-
-  bool isInGattServerArray =
-    aHeader.mOpcode < MOZ_ARRAY_LENGTH(HandleServerRsp) &&
-    HandleServerRsp[aHeader.mOpcode];
-
-  if (NS_WARN_IF(!isInGattArray && !isInGattClientArray &&
-                 !isInGattServerArray)) {
+  if (NS_WARN_IF(!(aHeader.mOpcode < MOZ_ARRAY_LENGTH(HandleRsp))) ||
+      NS_WARN_IF(!HandleRsp[aHeader.mOpcode])) {
     return;
   }
 
-  if (!aUserData) {
-    return; // Return early if no result handler has been set for response
-  }
+  nsRefPtr<BluetoothGattResultHandler> res =
+    already_AddRefed<BluetoothGattResultHandler>(
+      static_cast<BluetoothGattResultHandler*>(aUserData));
 
-  if (isInGattArray) {
-    nsRefPtr<BluetoothGattResultHandler> res =
-      already_AddRefed<BluetoothGattResultHandler>(
-        static_cast<BluetoothGattResultHandler*>(aUserData));
-    (this->*(HandleRsp[aHeader.mOpcode]))(aHeader, aPDU, res);
-  } else if (isInGattClientArray) {
-    nsRefPtr<BluetoothGattClientResultHandler> res =
-      already_AddRefed<BluetoothGattClientResultHandler>(
-        static_cast<BluetoothGattClientResultHandler*>(aUserData));
-    (this->*(HandleClientRsp[aHeader.mOpcode]))(aHeader, aPDU, res);
-  } else { // isInGattServerArray
-    nsRefPtr<BluetoothGattServerResultHandler> res =
-      already_AddRefed<BluetoothGattServerResultHandler>(
-        static_cast<BluetoothGattServerResultHandler*>(aUserData));
-    (this->*(HandleServerRsp[aHeader.mOpcode]))(aHeader, aPDU, res);
-  }
+  if (!res) {
+    return;
+  } // Return early if no result handler has been set for response
+
+  (this->*(HandleRsp[aHeader.mOpcode]))(aHeader, aPDU, res);
 }
 
 // Notifications
 //
 
 // Returns the current notification handler to a notification runnable
 class BluetoothDaemonGattModule::NotificationHandlerWrapper final
 {
@@ -1594,50 +1512,22 @@ public:
   static ObjectType* GetInstance()
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     return sNotificationHandler;
   }
 };
 
-// Returns the current notification handler to a notification runnable
-class BluetoothDaemonGattModule::ClientNotificationHandlerWrapper final
-{
-public:
-  typedef BluetoothGattClientNotificationHandler ObjectType;
-
-  static ObjectType* GetInstance()
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    return sNotificationHandler;
-  }
-};
-
-// Returns the current notification handler to a notification runnable
-class BluetoothDaemonGattModule::ServerNotificationHandlerWrapper final
-{
-public:
-  typedef BluetoothGattServerNotificationHandler ObjectType;
-
-  static ObjectType* GetInstance()
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    return sNotificationHandler;
-  }
-};
-
 void
 BluetoothDaemonGattModule::ClientRegisterNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ClientRegisterNotification::Dispatch(
-    &BluetoothGattClientNotificationHandler::RegisterClientNotification,
+    &BluetoothGattNotificationHandler::RegisterClientNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 // Init operator class for ClientScanResultNotification
 class BluetoothDaemonGattModule::ClientScanResultInitOp final
   : private PDUInitOp
 {
 public:
@@ -1680,17 +1570,17 @@ public:
   }
 };
 
 void
 BluetoothDaemonGattModule::ClientScanResultNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ClientScanResultNotification::Dispatch(
-    &BluetoothGattClientNotificationHandler::ScanResultNotification,
+    &BluetoothGattNotificationHandler::ScanResultNotification,
     ClientScanResultInitOp(aPDU));
 }
 
 // Init operator class for ClientConnect/DisconnectNotification
 class BluetoothDaemonGattModule::ClientConnectDisconnectInitOp final
   : private PDUInitOp
 {
 public:
@@ -1733,134 +1623,134 @@ public:
   }
 };
 
 void
 BluetoothDaemonGattModule::ClientConnectNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ClientConnectNotification::Dispatch(
-    &BluetoothGattClientNotificationHandler::ConnectNotification,
+    &BluetoothGattNotificationHandler::ConnectNotification,
     ClientConnectDisconnectInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientDisconnectNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ClientDisconnectNotification::Dispatch(
-    &BluetoothGattClientNotificationHandler::DisconnectNotification,
+    &BluetoothGattNotificationHandler::DisconnectNotification,
     ClientConnectDisconnectInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientSearchCompleteNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ClientSearchCompleteNotification::Dispatch(
-    &BluetoothGattClientNotificationHandler::SearchCompleteNotification,
+    &BluetoothGattNotificationHandler::SearchCompleteNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientSearchResultNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ClientSearchResultNotification::Dispatch(
-    &BluetoothGattClientNotificationHandler::SearchResultNotification,
+    &BluetoothGattNotificationHandler::SearchResultNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientGetCharacteristicNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ClientGetCharacteristicNotification::Dispatch(
-    &BluetoothGattClientNotificationHandler::GetCharacteristicNotification,
+    &BluetoothGattNotificationHandler::GetCharacteristicNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientGetDescriptorNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ClientGetDescriptorNotification::Dispatch(
-    &BluetoothGattClientNotificationHandler::GetDescriptorNotification,
+    &BluetoothGattNotificationHandler::GetDescriptorNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientGetIncludedServiceNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ClientGetIncludedServiceNotification::Dispatch(
-    &BluetoothGattClientNotificationHandler::GetIncludedServiceNotification,
+    &BluetoothGattNotificationHandler::GetIncludedServiceNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientRegisterNotificationNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ClientRegisterNotificationNotification::Dispatch(
-    &BluetoothGattClientNotificationHandler::RegisterNotificationNotification,
+    &BluetoothGattNotificationHandler::RegisterNotificationNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientNotifyNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ClientNotifyNotification::Dispatch(
-    &BluetoothGattClientNotificationHandler::NotifyNotification,
+    &BluetoothGattNotificationHandler::NotifyNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientReadCharacteristicNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ClientReadCharacteristicNotification::Dispatch(
-    &BluetoothGattClientNotificationHandler::ReadCharacteristicNotification,
+    &BluetoothGattNotificationHandler::ReadCharacteristicNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientWriteCharacteristicNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ClientWriteCharacteristicNotification::Dispatch(
-    &BluetoothGattClientNotificationHandler::WriteCharacteristicNotification,
+    &BluetoothGattNotificationHandler::WriteCharacteristicNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientReadDescriptorNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ClientReadDescriptorNotification::Dispatch(
-    &BluetoothGattClientNotificationHandler::ReadDescriptorNotification,
+    &BluetoothGattNotificationHandler::ReadDescriptorNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientWriteDescriptorNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ClientWriteDescriptorNotification::Dispatch(
-    &BluetoothGattClientNotificationHandler::WriteDescriptorNotification,
+    &BluetoothGattNotificationHandler::WriteDescriptorNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientExecuteWriteNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ClientExecuteWriteNotification::Dispatch(
-    &BluetoothGattClientNotificationHandler::ExecuteWriteNotification,
+    &BluetoothGattNotificationHandler::ExecuteWriteNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 // Init operator class for ClientReadRemoteRssiNotification
 class BluetoothDaemonGattModule::ClientReadRemoteRssiInitOp final
   : private PDUInitOp
 {
 public:
@@ -1902,35 +1792,35 @@ public:
   }
 };
 
 void
 BluetoothDaemonGattModule::ClientReadRemoteRssiNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ClientReadRemoteRssiNotification::Dispatch(
-    &BluetoothGattClientNotificationHandler::ReadRemoteRssiNotification,
+    &BluetoothGattNotificationHandler::ReadRemoteRssiNotification,
     ClientReadRemoteRssiInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ClientListenNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ClientListenNotification::Dispatch(
-    &BluetoothGattClientNotificationHandler::ListenNotification,
+    &BluetoothGattNotificationHandler::ListenNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ServerRegisterNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ServerRegisterNotification::Dispatch(
-    &BluetoothGattServerNotificationHandler::RegisterServerNotification,
+    &BluetoothGattNotificationHandler::RegisterServerNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 // Init operator class for ServerConnectionNotification
 class BluetoothDaemonGattModule::ServerConnectionInitOp final
   : private PDUInitOp
 {
 public:
@@ -1973,80 +1863,80 @@ public:
   }
 };
 
 void
 BluetoothDaemonGattModule::ServerConnectionNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ServerConnectionNotification::Dispatch(
-    &BluetoothGattServerNotificationHandler::ConnectionNotification,
+    &BluetoothGattNotificationHandler::ConnectionNotification,
     ServerConnectionInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ServerServiceAddedNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ServerServiceAddedNotification::Dispatch(
-    &BluetoothGattServerNotificationHandler::ServiceAddedNotification,
+    &BluetoothGattNotificationHandler::ServiceAddedNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ServerIncludedServiceAddedNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ServerIncludedServiceAddedNotification::Dispatch(
-    &BluetoothGattServerNotificationHandler::IncludedServiceAddedNotification,
+    &BluetoothGattNotificationHandler::IncludedServiceAddedNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ServerCharacteristicAddedNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ServerCharacteristicAddedNotification::Dispatch(
-    &BluetoothGattServerNotificationHandler::CharacteristicAddedNotification,
+    &BluetoothGattNotificationHandler::CharacteristicAddedNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ServerDescriptorAddedNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ServerDescriptorAddedNotification::Dispatch(
-    &BluetoothGattServerNotificationHandler::DescriptorAddedNotification,
+    &BluetoothGattNotificationHandler::DescriptorAddedNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ServerServiceStartedNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ServerServiceStartedNotification::Dispatch(
-    &BluetoothGattServerNotificationHandler::ServiceStartedNotification,
+    &BluetoothGattNotificationHandler::ServiceStartedNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ServerServiceStoppedNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ServerServiceStoppedNotification::Dispatch(
-    &BluetoothGattServerNotificationHandler::ServiceStoppedNotification,
+    &BluetoothGattNotificationHandler::ServiceStoppedNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ServerServiceDeletedNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ServerServiceDeletedNotification::Dispatch(
-    &BluetoothGattServerNotificationHandler::ServiceDeletedNotification,
+    &BluetoothGattNotificationHandler::ServiceDeletedNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 // Init operator class for ServerRequestReadNotification
 class BluetoothDaemonGattModule::ServerRequestReadInitOp final
   : private PDUInitOp
 {
 public:
@@ -2101,17 +1991,17 @@ public:
   }
 };
 
 void
 BluetoothDaemonGattModule::ServerRequestReadNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ServerRequestReadNotification::Dispatch(
-    &BluetoothGattServerNotificationHandler::RequestReadNotification,
+    &BluetoothGattNotificationHandler::RequestReadNotification,
     ServerRequestReadInitOp(aPDU));
 }
 
 // Init operator class for ServerRequestWriteNotification
 class BluetoothDaemonGattModule::ServerRequestWriteInitOp final
   : private PDUInitOp
 {
 public:
@@ -2185,17 +2075,17 @@ public:
   }
 };
 
 void
 BluetoothDaemonGattModule::ServerRequestWriteNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ServerRequestWriteNotification::Dispatch(
-    &BluetoothGattServerNotificationHandler::RequestWriteNotification,
+    &BluetoothGattNotificationHandler::RequestWriteNotification,
     ServerRequestWriteInitOp(aPDU));
 }
 
 // Init operator class for ServerRequestExecuteWriteNotification
 class BluetoothDaemonGattModule::ServerRequestExecuteWriteInitOp final
   : private PDUInitOp
 {
 public:
@@ -2238,26 +2128,26 @@ public:
   }
 };
 
 void
 BluetoothDaemonGattModule::ServerRequestExecuteWriteNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ServerRequestExecuteWriteNotification::Dispatch(
-    &BluetoothGattServerNotificationHandler::RequestExecuteWriteNotification,
+    &BluetoothGattNotificationHandler::RequestExecuteWriteNotification,
     ServerRequestExecuteWriteInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::ServerResponseConfirmationNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
 {
   ServerResponseConfirmationNotification::Dispatch(
-    &BluetoothGattServerNotificationHandler::ResponseConfirmationNotification,
+    &BluetoothGattNotificationHandler::ResponseConfirmationNotification,
     UnpackPDUInitOp(aPDU));
 }
 
 void
 BluetoothDaemonGattModule::HandleNtf(
   const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
   void* aUserData)
 {
@@ -2307,26 +2197,16 @@ BluetoothDaemonGattModule::HandleNtf(
 
   (this->*(HandleNtf[index]))(aHeader, aPDU);
 }
 
 //
 // Gatt interface
 //
 
-BluetoothDaemonGattClientInterface::BluetoothDaemonGattClientInterface(
-  BluetoothDaemonGattModule* aModule)
-  : mModule(aModule)
-{ }
-
-BluetoothDaemonGattServerInterface::BluetoothDaemonGattServerInterface(
-  BluetoothDaemonGattModule* aModule)
-  : mModule(aModule)
-{ }
-
 BluetoothDaemonGattInterface::BluetoothDaemonGattInterface(
   BluetoothDaemonGattModule* aModule)
   : mModule(aModule)
 { }
 
 BluetoothDaemonGattInterface::~BluetoothDaemonGattInterface()
 { }
 
@@ -2434,585 +2314,540 @@ BluetoothDaemonGattInterface::Cleanup(
     new CleanupResultHandler(mModule, aRes));
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 /* Register / Unregister */
 void
-BluetoothDaemonGattClientInterface::RegisterClient(
-  const BluetoothUuid& aUuid, BluetoothGattClientResultHandler* aRes)
+BluetoothDaemonGattInterface::RegisterClient(
+  const BluetoothUuid& aUuid, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientRegisterCmd(aUuid, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonGattClientInterface::UnregisterClient(
-  int aClientIf, BluetoothGattClientResultHandler* aRes)
+BluetoothDaemonGattInterface::UnregisterClient(
+  int aClientIf, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientUnregisterCmd(aClientIf, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 /* Start / Stop LE Scan */
 void
-BluetoothDaemonGattClientInterface::Scan(
-  int aClientIf, bool aStart, BluetoothGattClientResultHandler* aRes)
+BluetoothDaemonGattInterface::Scan(
+  int aClientIf, bool aStart, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientScanCmd(aClientIf, aStart, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 /* Connect / Disconnect */
 
 void
-BluetoothDaemonGattClientInterface::Connect(
+BluetoothDaemonGattInterface::Connect(
   int aClientIf, const nsAString& aBdAddr, bool aIsDirect,
-  BluetoothTransport aTransport, BluetoothGattClientResultHandler* aRes)
+  BluetoothTransport aTransport, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientConnectCmd(
     aClientIf, aBdAddr, aIsDirect, aTransport, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonGattClientInterface::Disconnect(
+BluetoothDaemonGattInterface::Disconnect(
   int aClientIf, const nsAString& aBdAddr, int aConnId,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientDisconnectCmd(
     aClientIf, aBdAddr, aConnId, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 /* Start / Stop advertisements to listen for incoming connections */
 void
-BluetoothDaemonGattClientInterface::Listen(
-  int aClientIf, bool aIsStart, BluetoothGattClientResultHandler* aRes)
+BluetoothDaemonGattInterface::Listen(
+  int aClientIf, bool aIsStart, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientListenCmd(aClientIf, aIsStart, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 /* Clear the attribute cache for a given device*/
 void
-BluetoothDaemonGattClientInterface::Refresh(
-  int aClientIf, const nsAString& aBdAddr,
-  BluetoothGattClientResultHandler* aRes)
+BluetoothDaemonGattInterface::Refresh(
+  int aClientIf, const nsAString& aBdAddr, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientRefreshCmd(aClientIf, aBdAddr, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 /* Enumerate Attributes */
 void
-BluetoothDaemonGattClientInterface::SearchService(
+BluetoothDaemonGattInterface::SearchService(
   int aConnId, bool aSearchAll, const BluetoothUuid& aUuid,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientSearchServiceCmd(
     aConnId, !aSearchAll /* Filtered */, aUuid, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonGattClientInterface::GetIncludedService(
+BluetoothDaemonGattInterface::GetIncludedService(
   int aConnId, const BluetoothGattServiceId& aServiceId, bool aFirst,
   const BluetoothGattServiceId& aStartServiceId,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientGetIncludedServiceCmd(
     aConnId, aServiceId, !aFirst /* Continuation */, aStartServiceId, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonGattClientInterface::GetCharacteristic(
+BluetoothDaemonGattInterface::GetCharacteristic(
   int aConnId, const BluetoothGattServiceId& aServiceId, bool aFirst,
-  const BluetoothGattId& aStartCharId, BluetoothGattClientResultHandler* aRes)
+  const BluetoothGattId& aStartCharId, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientGetCharacteristicCmd(
     aConnId, aServiceId, !aFirst /* Continuation */, aStartCharId, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonGattClientInterface::GetDescriptor(
+BluetoothDaemonGattInterface::GetDescriptor(
   int aConnId, const BluetoothGattServiceId& aServiceId,
   const BluetoothGattId& aCharId, bool aFirst,
-  const BluetoothGattId& aDescriptorId, BluetoothGattClientResultHandler* aRes)
+  const BluetoothGattId& aDescriptorId, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientGetDescriptorCmd(
     aConnId, aServiceId, aCharId, !aFirst /* Continuation */, aDescriptorId,
     aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 /* Read / Write An Attribute */
 void
-BluetoothDaemonGattClientInterface::ReadCharacteristic(
+BluetoothDaemonGattInterface::ReadCharacteristic(
   int aConnId, const BluetoothGattServiceId& aServiceId,
   const BluetoothGattId& aCharId, BluetoothGattAuthReq aAuthReq,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientReadCharacteristicCmd(
     aConnId, aServiceId, aCharId, aAuthReq, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonGattClientInterface::WriteCharacteristic(
+BluetoothDaemonGattInterface::WriteCharacteristic(
   int aConnId, const BluetoothGattServiceId& aServiceId,
   const BluetoothGattId& aCharId, BluetoothGattWriteType aWriteType,
   BluetoothGattAuthReq aAuthReq, const nsTArray<uint8_t>& aValue,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientWriteCharacteristicCmd(
     aConnId, aServiceId, aCharId, aWriteType,
     aValue.Length() * sizeof(uint8_t), aAuthReq,
     reinterpret_cast<char*>(const_cast<uint8_t*>(aValue.Elements())), aRes);
 
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonGattClientInterface::ReadDescriptor(
+BluetoothDaemonGattInterface::ReadDescriptor(
   int aConnId, const BluetoothGattServiceId& aServiceId,
   const BluetoothGattId& aCharId, const BluetoothGattId& aDescriptorId,
-  BluetoothGattAuthReq aAuthReq, BluetoothGattClientResultHandler* aRes)
+  BluetoothGattAuthReq aAuthReq, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientReadDescriptorCmd(
     aConnId, aServiceId, aCharId, aDescriptorId, aAuthReq, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonGattClientInterface::WriteDescriptor(
+BluetoothDaemonGattInterface::WriteDescriptor(
   int aConnId, const BluetoothGattServiceId& aServiceId,
   const BluetoothGattId& aCharId, const BluetoothGattId& aDescriptorId,
   BluetoothGattWriteType aWriteType, BluetoothGattAuthReq aAuthReq,
-  const nsTArray<uint8_t>& aValue, BluetoothGattClientResultHandler* aRes)
+  const nsTArray<uint8_t>& aValue, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientWriteDescriptorCmd(
     aConnId, aServiceId, aCharId, aDescriptorId, aWriteType,
     aValue.Length() * sizeof(uint8_t), aAuthReq,
     reinterpret_cast<char*>(const_cast<uint8_t*>(aValue.Elements())), aRes);
 
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 /* Execute / Abort Prepared Write*/
 void
-BluetoothDaemonGattClientInterface::ExecuteWrite(
-  int aConnId, int aIsExecute, BluetoothGattClientResultHandler* aRes)
+BluetoothDaemonGattInterface::ExecuteWrite(
+  int aConnId, int aIsExecute, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientExecuteWriteCmd(aConnId, aIsExecute, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 /* Register / Deregister Characteristic Notifications or Indications */
 void
-BluetoothDaemonGattClientInterface::RegisterNotification(
+BluetoothDaemonGattInterface::RegisterNotification(
   int aClientIf, const nsAString& aBdAddr,
   const BluetoothGattServiceId& aServiceId, const BluetoothGattId& aCharId,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientRegisterNotificationCmd(
     aClientIf, aBdAddr, aServiceId, aCharId, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonGattClientInterface::DeregisterNotification(
+BluetoothDaemonGattInterface::DeregisterNotification(
   int aClientIf, const nsAString& aBdAddr,
   const BluetoothGattServiceId& aServiceId, const BluetoothGattId& aCharId,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientDeregisterNotificationCmd(
     aClientIf, aBdAddr, aServiceId, aCharId, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonGattClientInterface::ReadRemoteRssi(
+BluetoothDaemonGattInterface::ReadRemoteRssi(
   int aClientIf, const nsAString& aBdAddr,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientReadRemoteRssiCmd(
     aClientIf, aBdAddr, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonGattClientInterface::GetDeviceType(
-  const nsAString& aBdAddr, BluetoothGattClientResultHandler* aRes)
+BluetoothDaemonGattInterface::GetDeviceType(
+  const nsAString& aBdAddr, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientGetDeviceTypeCmd(aBdAddr, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonGattClientInterface::SetAdvData(
+BluetoothDaemonGattInterface::SetAdvData(
   int aServerIf, bool aIsScanRsp, bool aIsNameIncluded,
   bool aIsTxPowerIncluded, int aMinInterval, int aMaxInterval, int aApperance,
   uint16_t aManufacturerLen, char* aManufacturerData,
   uint16_t aServiceDataLen, char* aServiceData,
   uint16_t aServiceUUIDLen, char* aServiceUUID,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientSetAdvDataCmd(
     aServerIf, aIsScanRsp, aIsNameIncluded, aIsTxPowerIncluded, aMinInterval,
     aMaxInterval, aApperance, aManufacturerLen, aManufacturerData,
     aServiceDataLen, aServiceData, aServiceUUIDLen, aServiceUUID, aRes);
 
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonGattClientInterface::TestCommand(
+BluetoothDaemonGattInterface::TestCommand(
   int aCommand, const BluetoothGattTestParam& aTestParam,
-  BluetoothGattClientResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientTestCommandCmd(aCommand, aTestParam, aRes);
 
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 /* Register / Unregister */
 void
-BluetoothDaemonGattServerInterface::RegisterServer(
-  const BluetoothUuid& aUuid, BluetoothGattServerResultHandler* aRes)
+BluetoothDaemonGattInterface::RegisterServer(
+  const BluetoothUuid& aUuid, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ServerRegisterCmd(aUuid, aRes);
 
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonGattServerInterface::UnregisterServer(
-  int aServerIf, BluetoothGattServerResultHandler* aRes)
+BluetoothDaemonGattInterface::UnregisterServer(
+  int aServerIf, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ServerUnregisterCmd(aServerIf, aRes);
 
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 /* Connect / Disconnect */
 void
-BluetoothDaemonGattServerInterface::ConnectPeripheral(
+BluetoothDaemonGattInterface::ConnectPeripheral(
   int aServerIf, const nsAString& aBdAddr, bool aIsDirect, /* auto connect */
-  BluetoothTransport aTransport, BluetoothGattServerResultHandler* aRes)
+  BluetoothTransport aTransport, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ServerConnectPeripheralCmd(
     aServerIf, aBdAddr, aIsDirect, aTransport, aRes);
 
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonGattServerInterface::DisconnectPeripheral(
+BluetoothDaemonGattInterface::DisconnectPeripheral(
   int aServerIf, const nsAString& aBdAddr, int aConnId,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ServerDisconnectPeripheralCmd(
     aServerIf, aBdAddr, aConnId, aRes);
 
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 /* Add a services / a characteristic / a descriptor */
 void
-BluetoothDaemonGattServerInterface::AddService(
+BluetoothDaemonGattInterface::AddService(
   int aServerIf, const BluetoothGattServiceId& aServiceId, int aNumHandles,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ServerAddServiceCmd(
     aServerIf, aServiceId, aNumHandles, aRes);
 
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonGattServerInterface::AddIncludedService(
+BluetoothDaemonGattInterface::AddIncludedService(
   int aServerIf, int aServiceHandle, int aIncludedServiceHandle,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ServerAddIncludedServiceCmd(
     aServerIf, aServiceHandle, aIncludedServiceHandle, aRes);
 
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonGattServerInterface::AddCharacteristic(
+BluetoothDaemonGattInterface::AddCharacteristic(
   int aServerIf, int aServiceHandle, const BluetoothUuid& aUuid,
   BluetoothGattCharProp aProperties, BluetoothGattAttrPerm aPermissions,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ServerAddCharacteristicCmd(
     aServerIf, aServiceHandle, aUuid, aProperties, aPermissions, aRes);
 
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonGattServerInterface::AddDescriptor(
+BluetoothDaemonGattInterface::AddDescriptor(
   int aServerIf, int aServiceHandle, const BluetoothUuid& aUuid,
-  BluetoothGattAttrPerm aPermissions, BluetoothGattServerResultHandler* aRes)
+  BluetoothGattAttrPerm aPermissions, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ServerAddDescriptorCmd(
     aServerIf, aServiceHandle, aUuid, aPermissions, aRes);
 
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 /* Start / Stop / Delete a service */
 void
-BluetoothDaemonGattServerInterface::StartService(
+BluetoothDaemonGattInterface::StartService(
   int aServerIf, int aServiceHandle, BluetoothTransport aTransport,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ServerStartServiceCmd(
     aServerIf, aServiceHandle, aTransport, aRes);
 
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonGattServerInterface::StopService(
-  int aServerIf, int aServiceHandle, BluetoothGattServerResultHandler* aRes)
+BluetoothDaemonGattInterface::StopService(
+  int aServerIf, int aServiceHandle, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ServerStopServiceCmd(aServerIf, aServiceHandle, aRes);
 
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonGattServerInterface::DeleteService(
-  int aServerIf, int aServiceHandle, BluetoothGattServerResultHandler* aRes)
+BluetoothDaemonGattInterface::DeleteService(
+  int aServerIf, int aServiceHandle, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ServerDeleteServiceCmd(
     aServerIf, aServiceHandle, aRes);
 
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonGattServerInterface::SendIndication(
+BluetoothDaemonGattInterface::SendIndication(
   int aServerIf, int aAttributeHandle, int aConnId,
   const nsTArray<uint8_t>& aValue, bool aConfirm,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ServerSendIndicationCmd(
     aServerIf, aAttributeHandle, aConnId,
     aValue.Length() * sizeof(uint8_t), aConfirm,
     const_cast<uint8_t*>(aValue.Elements()), aRes);
 
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonGattServerInterface::SendResponse(
+BluetoothDaemonGattInterface::SendResponse(
   int aConnId, int aTransId, BluetoothGattStatus aStatus,
   const BluetoothGattResponse& aResponse,
-  BluetoothGattServerResultHandler* aRes)
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ServerSendResponseCmd(
     aConnId, aTransId, aStatus, aResponse, aRes);
 
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonGattClientInterface::DispatchError(
-  BluetoothGattClientResultHandler* aRes, BluetoothStatus aStatus)
-{
-  DaemonResultRunnable1<BluetoothGattClientResultHandler, void,
-                        BluetoothStatus, BluetoothStatus>::Dispatch(
-    aRes, &BluetoothGattResultHandler::OnError,
-    ConstantInitOp1<BluetoothStatus>(aStatus));
-}
-
-void
-BluetoothDaemonGattClientInterface::DispatchError(
-  BluetoothGattClientResultHandler* aRes, nsresult aRv)
-{
-  BluetoothStatus status;
-
-  if (NS_WARN_IF(NS_FAILED(Convert(aRv, status)))) {
-    status = STATUS_FAIL;
-  }
-  DispatchError(aRes, status);
-}
-
-void
-BluetoothDaemonGattServerInterface::DispatchError(
-  BluetoothGattServerResultHandler* aRes, BluetoothStatus aStatus)
-{
-  DaemonResultRunnable1<BluetoothGattServerResultHandler, void,
-                        BluetoothStatus, BluetoothStatus>::Dispatch(
-    aRes, &BluetoothGattResultHandler::OnError,
-    ConstantInitOp1<BluetoothStatus>(aStatus));
-}
-
-void
-BluetoothDaemonGattServerInterface::DispatchError(
-  BluetoothGattServerResultHandler* aRes, nsresult aRv)
-{
-  BluetoothStatus status;
-
-  if (NS_WARN_IF(NS_FAILED(Convert(aRv, status)))) {
-    status = STATUS_FAIL;
-  }
-  DispatchError(aRes, status);
-}
-
-void
 BluetoothDaemonGattInterface::DispatchError(
   BluetoothGattResultHandler* aRes, BluetoothStatus aStatus)
 {
   DaemonResultRunnable1<BluetoothGattResultHandler, void,
                         BluetoothStatus, BluetoothStatus>::Dispatch(
     aRes, &BluetoothGattResultHandler::OnError,
     ConstantInitOp1<BluetoothStatus>(aStatus));
 }
@@ -3024,31 +2859,9 @@ BluetoothDaemonGattInterface::DispatchEr
   BluetoothStatus status;
 
   if (NS_WARN_IF(NS_FAILED(Convert(aRv, status)))) {
     status = STATUS_FAIL;
   }
   DispatchError(aRes, status);
 }
 
-BluetoothGattClientInterface*
-BluetoothDaemonGattInterface::GetBluetoothGattClientInterface()
-{
-  MOZ_ASSERT(mModule);
-
-  BluetoothDaemonGattClientInterface* gattClientInterface =
-    new BluetoothDaemonGattClientInterface(mModule);
-
-  return gattClientInterface;
-}
-
-BluetoothGattServerInterface*
-BluetoothDaemonGattInterface::GetBluetoothGattServerInterface()
-{
-  MOZ_ASSERT(mModule);
-
-  BluetoothDaemonGattServerInterface* gattServerInterface =
-    new BluetoothDaemonGattServerInterface(mModule);
-
-  return gattServerInterface;
-}
-
 END_BLUETOOTH_NAMESPACE
--- a/dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.h
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.h
@@ -80,608 +80,592 @@ public:
     BluetoothGattNotificationHandler* aNotificationHandler);
 
   //
   // Commands
   //
 
   /* Register / Unregister */
   nsresult ClientRegisterCmd(const BluetoothUuid& aUuid,
-                             BluetoothGattClientResultHandler* aRes);
+                             BluetoothGattResultHandler* aRes);
 
   nsresult ClientUnregisterCmd(int aClientIf,
-                               BluetoothGattClientResultHandler* aRes);
+                               BluetoothGattResultHandler* aRes);
 
   /* Start / Stop LE Scan */
   nsresult ClientScanCmd(int aClientIf, bool aStart,
-                         BluetoothGattClientResultHandler* aRes);
+                         BluetoothGattResultHandler* aRes);
 
   /* Connect / Disconnect */
   nsresult ClientConnectCmd(int aClientIf,
                             const nsAString& aBdAddr,
                             bool aIsDirect, /* auto connect */
                             BluetoothTransport aTransport,
-                            BluetoothGattClientResultHandler* aRes);
+                            BluetoothGattResultHandler* aRes);
 
   nsresult ClientDisconnectCmd(int aClientIf,
                                const nsAString& aBdAddr,
                                int aConnId,
-                               BluetoothGattClientResultHandler* aRes);
+                               BluetoothGattResultHandler* aRes);
 
   /* Start / Stop advertisements to listen for incoming connections */
   nsresult ClientListenCmd(int aClientIf,
                            bool aIsStart,
-                           BluetoothGattClientResultHandler* aRes);
+                           BluetoothGattResultHandler* aRes);
 
   /* Clear the attribute cache for a given device*/
   nsresult ClientRefreshCmd(int aClientIf,
                             const nsAString& aBdAddr,
-                            BluetoothGattClientResultHandler* aRes);
+                            BluetoothGattResultHandler* aRes);
 
   /* Enumerate Attributes */
   nsresult ClientSearchServiceCmd(int aConnId,
                                   bool aFiltered,
                                   const BluetoothUuid& aUuid,
-                                  BluetoothGattClientResultHandler* aRes);
+                                  BluetoothGattResultHandler* aRes);
 
   nsresult ClientGetIncludedServiceCmd(
     int aConnId,
     const BluetoothGattServiceId& aServiceId,
     bool aContinuation,
     const BluetoothGattServiceId& aStartServiceId,
-    BluetoothGattClientResultHandler* aRes);
+    BluetoothGattResultHandler* aRes);
 
   nsresult ClientGetCharacteristicCmd(int aConnId,
                                       const BluetoothGattServiceId& aServiceId,
                                       bool aContinuation,
                                       const BluetoothGattId& aStartCharId,
-                                      BluetoothGattClientResultHandler* aRes);
+                                      BluetoothGattResultHandler* aRes);
 
   nsresult ClientGetDescriptorCmd(int aConnId,
                                   const BluetoothGattServiceId& aServiceId,
                                   const BluetoothGattId& aCharId,
                                   bool aContinuation,
                                   const BluetoothGattId& aDescriptorId,
-                                  BluetoothGattClientResultHandler* aRes);
+                                  BluetoothGattResultHandler* aRes);
 
   /* Read / Write An Attribute */
   nsresult ClientReadCharacteristicCmd(
     int aConnId,
     const BluetoothGattServiceId& aServiceId,
     const BluetoothGattId& aCharId,
     BluetoothGattAuthReq aAuthReq,
-    BluetoothGattClientResultHandler* aRes);
+    BluetoothGattResultHandler* aRes);
 
   nsresult ClientWriteCharacteristicCmd(
     int aConnId,
     const BluetoothGattServiceId& aServiceId,
     const BluetoothGattId& aCharId,
     BluetoothGattWriteType aWriteType,
     int aLength,
     BluetoothGattAuthReq aAuthReq,
     char* aValue,
-    BluetoothGattClientResultHandler* aRes);
+    BluetoothGattResultHandler* aRes);
 
   nsresult ClientReadDescriptorCmd(int aConnId,
                                    const BluetoothGattServiceId& aServiceId,
                                    const BluetoothGattId& aCharId,
                                    const BluetoothGattId& aDescriptorId,
                                    BluetoothGattAuthReq aAuthReq,
-                                   BluetoothGattClientResultHandler* aRes);
+                                   BluetoothGattResultHandler* aRes);
 
   nsresult ClientWriteDescriptorCmd(int aConnId,
                                     const BluetoothGattServiceId& aServiceId,
                                     const BluetoothGattId& aCharId,
                                     const BluetoothGattId& aDescriptorId,
                                     BluetoothGattWriteType aWriteType,
                                     int aLength,
                                     BluetoothGattAuthReq aAuthReq,
                                     char* aValue,
-                                    BluetoothGattClientResultHandler* aRes);
+                                    BluetoothGattResultHandler* aRes);
 
   /* Execute / Abort Prepared Write*/
   nsresult ClientExecuteWriteCmd(int aConnId,
                                  int aIsExecute,
-                                 BluetoothGattClientResultHandler* aRes);
+                                 BluetoothGattResultHandler* aRes);
 
   /* Register / Deregister Characteristic Notifications or Indications */
   nsresult ClientRegisterNotificationCmd(
     int aClientIf,
     const nsAString& aBdAddr,
     const BluetoothGattServiceId& aServiceId,
     const BluetoothGattId& aCharId,
-    BluetoothGattClientResultHandler* aRes);
+    BluetoothGattResultHandler* aRes);
 
   nsresult ClientDeregisterNotificationCmd(
     int aClientIf,
     const nsAString& aBdAddr,
     const BluetoothGattServiceId& aServiceId,
     const BluetoothGattId& aCharId,
-    BluetoothGattClientResultHandler* aRes);
+    BluetoothGattResultHandler* aRes);
 
   nsresult ClientReadRemoteRssiCmd(int aClientIf,
                                    const nsAString& aBdAddr,
-                                   BluetoothGattClientResultHandler* aRes);
+                                   BluetoothGattResultHandler* aRes);
 
   nsresult ClientGetDeviceTypeCmd(const nsAString& aBdAddr,
-                                  BluetoothGattClientResultHandler* aRes);
+                                  BluetoothGattResultHandler* aRes);
 
   /* Set advertising data or scan response data */
   nsresult ClientSetAdvDataCmd(int aServerIf,
                                bool aIsScanRsp,
                                bool aIsNameIncluded,
                                bool aIsTxPowerIncluded,
                                int aMinInterval,
                                int aMaxInterval,
                                int aApperance,
                                uint16_t aManufacturerLen,
                                char* aManufacturerData,
                                uint16_t aServiceDataLen,
                                char* aServiceData,
                                uint16_t aServiceUUIDLen,
                                char* aServiceUUID,
-                               BluetoothGattClientResultHandler* aRes);
+                               BluetoothGattResultHandler* aRes);
 
   nsresult ClientTestCommandCmd(int aCommand,
                                 const BluetoothGattTestParam& aTestParam,
-                                BluetoothGattClientResultHandler* aRes);
+                                BluetoothGattResultHandler* aRes);
 
   /* Register / Unregister */
   nsresult ServerRegisterCmd(const BluetoothUuid& aUuid,
-                             BluetoothGattServerResultHandler* aRes);
+                             BluetoothGattResultHandler* aRes);
 
   nsresult ServerUnregisterCmd(int aServerIf,
-                               BluetoothGattServerResultHandler* aRes);
+                               BluetoothGattResultHandler* aRes);
 
   /* Connect / Disconnect */
   nsresult ServerConnectPeripheralCmd(int aServerIf,
                                       const nsAString& aBdAddr,
                                       bool aIsDirect,
                                       BluetoothTransport aTransport,
-                                      BluetoothGattServerResultHandler* aRes);
+                                      BluetoothGattResultHandler* aRes);
 
   nsresult ServerDisconnectPeripheralCmd(
     int aServerIf,
     const nsAString& aBdAddr,
     int aConnId,
-    BluetoothGattServerResultHandler* aRes);
+    BluetoothGattResultHandler* aRes);
 
   /* Add a services / a characteristic / a descriptor */
   nsresult ServerAddServiceCmd(int aServerIf,
                                const BluetoothGattServiceId& aServiceId,
                                int aNumHandles,
-                               BluetoothGattServerResultHandler* aRes);
+                               BluetoothGattResultHandler* aRes);
 
   nsresult ServerAddIncludedServiceCmd(int aServerIf,
                                        int aServiceHandle,
                                        int aIncludedServiceHandle,
-                                       BluetoothGattServerResultHandler* aRes);
+                                       BluetoothGattResultHandler* aRes);
 
   nsresult ServerAddCharacteristicCmd(int aServerIf,
                                       int aServiceHandle,
                                       const BluetoothUuid& aUuid,
                                       BluetoothGattCharProp aProperties,
                                       BluetoothGattAttrPerm aPermissions,
-                                      BluetoothGattServerResultHandler* aRes);
+                                      BluetoothGattResultHandler* aRes);
 
   nsresult ServerAddDescriptorCmd(int aServerIf,
                                   int aServiceHandle,
                                   const BluetoothUuid& aUuid,
                                   BluetoothGattAttrPerm aPermissions,
-                                  BluetoothGattServerResultHandler* aRes);
+                                  BluetoothGattResultHandler* aRes);
 
   /* Start / Stop / Delete a service */
   nsresult ServerStartServiceCmd(int aServerIf,
                                  int aServiceHandle,
                                  BluetoothTransport aTransport,
-                                 BluetoothGattServerResultHandler* aRes);
+                                 BluetoothGattResultHandler* aRes);
 
   nsresult ServerStopServiceCmd(int aServerIf,
                                 int aServiceHandle,
-                                BluetoothGattServerResultHandler* aRes);
+                                BluetoothGattResultHandler* aRes);
 
   nsresult ServerDeleteServiceCmd(int aServerIf,
                                   int aServiceHandle,
-                                  BluetoothGattServerResultHandler* aRes);
+                                  BluetoothGattResultHandler* aRes);
 
   /* Send an indication or a notification */
   nsresult ServerSendIndicationCmd(int aServerIf,
                                    int aAttributeHandle,
                                    int aConnId,
                                    int aLength,
                                    bool aConfirm,
                                    uint8_t* aValue,
-                                   BluetoothGattServerResultHandler* aRes);
+                                   BluetoothGattResultHandler* aRes);
 
   /* Send a response for an incoming indication */
   nsresult ServerSendResponseCmd(int aConnId,
                                  int aTransId,
                                  BluetoothGattStatus aStatus,
                                  const BluetoothGattResponse& aResponse,
-                                 BluetoothGattServerResultHandler* aRes);
+                                 BluetoothGattResultHandler* aRes);
   // TODO: Add L support
 
 protected:
   nsresult Send(DaemonSocketPDU* aPDU,
                 BluetoothGattResultHandler* aRes);
 
-  nsresult Send(DaemonSocketPDU* aPDU,
-                BluetoothGattClientResultHandler* aRes);
-
-  nsresult Send(DaemonSocketPDU* aPDU,
-                BluetoothGattServerResultHandler* aRes);
-
   void HandleSvc(const DaemonSocketPDUHeader& aHeader,
                  DaemonSocketPDU& aPDU, void* aUserData);
 
   //
   // Responses
   //
 
   typedef mozilla::ipc::DaemonResultRunnable0<
-    BluetoothGattClientResultHandler, void>
-    ClientResultRunnable;
+    BluetoothGattResultHandler, void>
+    ResultRunnable;
 
   typedef mozilla::ipc::DaemonResultRunnable1<
-    BluetoothGattClientResultHandler, void,
+    BluetoothGattResultHandler, void,
     BluetoothTypeOfDevice, BluetoothTypeOfDevice>
     ClientGetDeviceTypeResultRunnable;
 
-  typedef mozilla::ipc::DaemonResultRunnable0<
-    BluetoothGattServerResultHandler, void>
-    ServerResultRunnable;
-
-  typedef mozilla::ipc::DaemonResultRunnable0<
-    BluetoothGattResultHandler, void>
-    ResultRunnable;
-
   typedef mozilla::ipc::DaemonResultRunnable1<
     BluetoothGattResultHandler, void, BluetoothStatus, BluetoothStatus>
     ErrorRunnable;
 
   void ErrorRsp(const DaemonSocketPDUHeader& aHeader,
                 DaemonSocketPDU& aPDU,
                 BluetoothGattResultHandler* aRes);
 
   void ClientRegisterRsp(const DaemonSocketPDUHeader& aHeader,
                          DaemonSocketPDU& aPDU,
-                         BluetoothGattClientResultHandler* aRes);
+                         BluetoothGattResultHandler* aRes);
 
   void ClientUnregisterRsp(const DaemonSocketPDUHeader& aHeader,
                            DaemonSocketPDU& aPDU,
-                           BluetoothGattClientResultHandler* aRes);
+                           BluetoothGattResultHandler* aRes);
 
   void ClientScanRsp(const DaemonSocketPDUHeader& aHeader,
                      DaemonSocketPDU& aPDU,
-                     BluetoothGattClientResultHandler* aRes);
+                     BluetoothGattResultHandler* aRes);
 
   void ClientConnectRsp(const DaemonSocketPDUHeader& aHeader,
                         DaemonSocketPDU& aPDU,
-                        BluetoothGattClientResultHandler* aRes);
+                        BluetoothGattResultHandler* aRes);
 
   void ClientDisconnectRsp(const DaemonSocketPDUHeader& aHeader,
                            DaemonSocketPDU& aPDU,
-                           BluetoothGattClientResultHandler* aRes);
+                           BluetoothGattResultHandler* aRes);
 
   void ClientListenRsp(const DaemonSocketPDUHeader& aHeader,
                        DaemonSocketPDU& aPDU,
-                       BluetoothGattClientResultHandler* aRes);
+                       BluetoothGattResultHandler* aRes);
 
   void ClientRefreshRsp(const DaemonSocketPDUHeader& aHeader,
                         DaemonSocketPDU& aPDU,
-                        BluetoothGattClientResultHandler* aRes);
+                        BluetoothGattResultHandler* aRes);
 
   void ClientSearchServiceRsp(const DaemonSocketPDUHeader& aHeader,
                               DaemonSocketPDU& aPDU,
-                              BluetoothGattClientResultHandler* aRes);
+                              BluetoothGattResultHandler* aRes);
 
   void ClientGetIncludedServiceRsp(const DaemonSocketPDUHeader& aHeader,
                                    DaemonSocketPDU& aPDU,
-                                   BluetoothGattClientResultHandler* aRes);
+                                   BluetoothGattResultHandler* aRes);
 
   void ClientGetCharacteristicRsp(const DaemonSocketPDUHeader& aHeader,
                                   DaemonSocketPDU& aPDU,
-                                  BluetoothGattClientResultHandler* aRes);
+                                  BluetoothGattResultHandler* aRes);
 
   void ClientGetDescriptorRsp(const DaemonSocketPDUHeader& aHeader,
                               DaemonSocketPDU& aPDU,
-                              BluetoothGattClientResultHandler* aRes);
+                              BluetoothGattResultHandler* aRes);
 
   void ClientReadCharacteristicRsp(const DaemonSocketPDUHeader& aHeader,
                                    DaemonSocketPDU& aPDU,
-                                   BluetoothGattClientResultHandler* aRes);
+                                   BluetoothGattResultHandler* aRes);
 
   void ClientWriteCharacteristicRsp(const DaemonSocketPDUHeader& aHeader,
                                     DaemonSocketPDU& aPDU,
-                                    BluetoothGattClientResultHandler* aRes);
+                                    BluetoothGattResultHandler* aRes);
 
   void ClientReadDescriptorRsp(const DaemonSocketPDUHeader& aHeader,
                                DaemonSocketPDU& aPDU,
-                               BluetoothGattClientResultHandler* aRes);
+                               BluetoothGattResultHandler* aRes);
 
   void ClientWriteDescriptorRsp(const DaemonSocketPDUHeader& aHeader,
                                 DaemonSocketPDU& aPDU,
-                                BluetoothGattClientResultHandler* aRes);
+                                BluetoothGattResultHandler* aRes);
 
   void ClientExecuteWriteRsp(const DaemonSocketPDUHeader& aHeader,
                              DaemonSocketPDU& aPDU,
-                             BluetoothGattClientResultHandler* aRes);
+                             BluetoothGattResultHandler* aRes);
 
   void ClientRegisterNotificationRsp(const DaemonSocketPDUHeader& aHeader,
                                      DaemonSocketPDU& aPDU,
-                                     BluetoothGattClientResultHandler* aRes);
+                                     BluetoothGattResultHandler* aRes);
 
   void ClientDeregisterNotificationRsp(const DaemonSocketPDUHeader& aHeader,
                                        DaemonSocketPDU& aPDU,
-                                       BluetoothGattClientResultHandler* aRes);
+                                       BluetoothGattResultHandler* aRes);
 
   void ClientReadRemoteRssiRsp(const DaemonSocketPDUHeader& aHeader,
                                DaemonSocketPDU& aPDU,
-                               BluetoothGattClientResultHandler* aRes);
+                               BluetoothGattResultHandler* aRes);
 
   void ClientGetDeviceTypeRsp(const DaemonSocketPDUHeader& aHeader,
                               DaemonSocketPDU& aPDU,
-                              BluetoothGattClientResultHandler* aRes);
+                              BluetoothGattResultHandler* aRes);
 
   void ClientSetAdvDataRsp(const DaemonSocketPDUHeader& aHeader,
                            DaemonSocketPDU& aPDU,
-                           BluetoothGattClientResultHandler* aRes);
+                           BluetoothGattResultHandler* aRes);
 
   void ClientTestCommandRsp(const DaemonSocketPDUHeader& aHeader,
                             DaemonSocketPDU& aPDU,
-                            BluetoothGattClientResultHandler* aRes);
+                            BluetoothGattResultHandler* aRes);
 
   void ServerRegisterRsp(const DaemonSocketPDUHeader& aHeader,
                          DaemonSocketPDU& aPDU,
-                         BluetoothGattServerResultHandler* aRes);
+                         BluetoothGattResultHandler* aRes);
 
   void ServerUnregisterRsp(const DaemonSocketPDUHeader& aHeader,
                            DaemonSocketPDU& aPDU,
-                           BluetoothGattServerResultHandler* aRes);
+                           BluetoothGattResultHandler* aRes);
 
   void ServerConnectPeripheralRsp(const DaemonSocketPDUHeader& aHeader,
                                   DaemonSocketPDU& aPDU,
-                                  BluetoothGattServerResultHandler* aRes);
+                                  BluetoothGattResultHandler* aRes);
 
   void ServerDisconnectPeripheralRsp(const DaemonSocketPDUHeader& aHeader,
                                      DaemonSocketPDU& aPDU,
-                                     BluetoothGattServerResultHandler* aRes);
+                                     BluetoothGattResultHandler* aRes);
 
   void ServerAddServiceRsp(const DaemonSocketPDUHeader& aHeader,
                            DaemonSocketPDU& aPDU,
-                           BluetoothGattServerResultHandler* aRes);
+                           BluetoothGattResultHandler* aRes);
 
   void ServerAddIncludedServiceRsp(const DaemonSocketPDUHeader& aHeader,
                                    DaemonSocketPDU& aPDU,
-                                   BluetoothGattServerResultHandler* aRes);
+                                   BluetoothGattResultHandler* aRes);
 
   void ServerAddCharacteristicRsp(const DaemonSocketPDUHeader& aHeader,
                                   DaemonSocketPDU& aPDU,
-                                  BluetoothGattServerResultHandler* aRes);
+                                  BluetoothGattResultHandler* aRes);
 
   void ServerAddDescriptorRsp(const DaemonSocketPDUHeader& aHeader,
                               DaemonSocketPDU& aPDU,
-                              BluetoothGattServerResultHandler* aRes);
+                              BluetoothGattResultHandler* aRes);
 
   void ServerStartServiceRsp(const DaemonSocketPDUHeader& aHeader,
                              DaemonSocketPDU& aPDU,
-                             BluetoothGattServerResultHandler* aRes);
+                             BluetoothGattResultHandler* aRes);
 
   void ServerStopServiceRsp(const DaemonSocketPDUHeader& aHeader,
                             DaemonSocketPDU& aPDU,
-                            BluetoothGattServerResultHandler* aRes);
+                            BluetoothGattResultHandler* aRes);
 
   void ServerDeleteServiceRsp(const DaemonSocketPDUHeader& aHeader,
                               DaemonSocketPDU& aPDU,
-                              BluetoothGattServerResultHandler* aRes);
+                              BluetoothGattResultHandler* aRes);
 
   void ServerSendIndicationRsp(const DaemonSocketPDUHeader& aHeader,
                                DaemonSocketPDU& aPDU,
-                               BluetoothGattServerResultHandler* aRes);
+                               BluetoothGattResultHandler* aRes);
 
   void ServerSendResponseRsp(const DaemonSocketPDUHeader& aHeader,
                              DaemonSocketPDU& aPDU,
-                             BluetoothGattServerResultHandler* aRes);
+                             BluetoothGattResultHandler* aRes);
 
   // TODO: Add L support
 
   void HandleRsp(const DaemonSocketPDUHeader& aHeader,
                  DaemonSocketPDU& aPDU,
                  void* aUserData);
 
   //
   // Notifications
   //
 
   class NotificationHandlerWrapper;
-  class ClientNotificationHandlerWrapper;
-  class ServerNotificationHandlerWrapper;
 
   typedef mozilla::ipc::DaemonNotificationRunnable3<
-    ClientNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     BluetoothGattStatus, int, BluetoothUuid,
     BluetoothGattStatus, int, const BluetoothUuid&>
     ClientRegisterNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable3<
-    ClientNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     nsString, int, BluetoothGattAdvData,
     const nsAString&, int, const BluetoothGattAdvData&>
     ClientScanResultNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable4<
-    ClientNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     int, BluetoothGattStatus, int, nsString,
     int, BluetoothGattStatus, int, const nsAString&>
     ClientConnectNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable4<
-    ClientNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     int, BluetoothGattStatus, int, nsString,
     int, BluetoothGattStatus, int, const nsAString&>
     ClientDisconnectNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
-    ClientNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     int, BluetoothGattStatus>
     ClientSearchCompleteNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
-    ClientNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     int, BluetoothGattServiceId,
     int, const BluetoothGattServiceId&>
     ClientSearchResultNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable5<
-    ClientNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     int, BluetoothGattStatus, BluetoothGattServiceId,
     BluetoothGattId, BluetoothGattCharProp,
     int, BluetoothGattStatus, const BluetoothGattServiceId&,
     const BluetoothGattId&, const BluetoothGattCharProp&>
     ClientGetCharacteristicNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable5<
-    ClientNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     int, BluetoothGattStatus, BluetoothGattServiceId,
     BluetoothGattId, BluetoothGattId,
     int, BluetoothGattStatus, const BluetoothGattServiceId&,
     const BluetoothGattId&, const BluetoothGattId&>
     ClientGetDescriptorNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable4<
-    ClientNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     int, BluetoothGattStatus, BluetoothGattServiceId, BluetoothGattServiceId,
     int, BluetoothGattStatus, const BluetoothGattServiceId&,
     const BluetoothGattServiceId&>
     ClientGetIncludedServiceNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable5<
-    ClientNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     int, int, BluetoothGattStatus,
     BluetoothGattServiceId, BluetoothGattId,
     int, int, BluetoothGattStatus,
     const BluetoothGattServiceId&, const BluetoothGattId&>
     ClientRegisterNotificationNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
-    ClientNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     int, BluetoothGattNotifyParam,
     int, const BluetoothGattNotifyParam&>
     ClientNotifyNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable3<
-    ClientNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     int, BluetoothGattStatus, BluetoothGattReadParam,
     int, BluetoothGattStatus, const BluetoothGattReadParam&>
     ClientReadCharacteristicNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable3<
-    ClientNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     int, BluetoothGattStatus, BluetoothGattWriteParam,
     int, BluetoothGattStatus, const BluetoothGattWriteParam&>
     ClientWriteCharacteristicNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable3<
-    ClientNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     int, BluetoothGattStatus, BluetoothGattReadParam,
     int, BluetoothGattStatus, const BluetoothGattReadParam&>
     ClientReadDescriptorNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable3<
-    ClientNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     int, BluetoothGattStatus, BluetoothGattWriteParam,
     int, BluetoothGattStatus, const BluetoothGattWriteParam&>
     ClientWriteDescriptorNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
-    ClientNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     int, BluetoothGattStatus>
     ClientExecuteWriteNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable4<
-    ClientNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     int, nsString, int, BluetoothGattStatus,
     int, const nsAString&, int, BluetoothGattStatus>
     ClientReadRemoteRssiNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
-    ClientNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     BluetoothGattStatus, int>
     ClientListenNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable3<
-    ServerNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     BluetoothGattStatus, int, BluetoothUuid,
     BluetoothGattStatus, int, const BluetoothUuid&>
     ServerRegisterNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable4<
-    ServerNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     int, int, bool, nsString,
     int, int, bool, const nsAString&>
     ServerConnectionNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable4<
-    ServerNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     BluetoothGattStatus, int, BluetoothGattServiceId, int,
     BluetoothGattStatus, int, const BluetoothGattServiceId&, int>
     ServerServiceAddedNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable4<
-    ServerNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     BluetoothGattStatus, int, int, int>
     ServerIncludedServiceAddedNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable5<
-    ServerNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     BluetoothGattStatus, int, BluetoothUuid, int, int,
     BluetoothGattStatus, int, const BluetoothUuid&, int, int>
     ServerCharacteristicAddedNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable5<
-    ServerNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     BluetoothGattStatus, int, BluetoothUuid, int, int,
     BluetoothGattStatus, int, const BluetoothUuid&, int, int>
     ServerDescriptorAddedNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable3<
-    ServerNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     BluetoothGattStatus, int, int>
     ServerServiceStartedNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable3<
-    ServerNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     BluetoothGattStatus, int, int>
     ServerServiceStoppedNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable3<
-    ServerNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     BluetoothGattStatus, int, int>
     ServerServiceDeletedNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable6<
-    ServerNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     int, int, nsString, int, int, bool,
     int, int, const nsAString&, int, int, bool>
     ServerRequestReadNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable9<
-    ServerNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     int, int, nsString, int, int, int, nsAutoArrayPtr<uint8_t>, bool, bool,
     int, int, const nsAString&, int, int, int, const uint8_t*, bool, bool>
     ServerRequestWriteNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable4<
-    ServerNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     int, int, nsString, bool,
     int, int, const nsAString&, bool>
     ServerRequestExecuteWriteNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
-    ServerNotificationHandlerWrapper, void,
+    NotificationHandlerWrapper, void,
     BluetoothGattStatus, int>
     ServerResponseConfirmationNotification;
 
   class ClientScanResultInitOp;
   class ClientConnectDisconnectInitOp;
   class ClientReadRemoteRssiInitOp;
   class ClientGetDeviceTypeInitOp;
   class ServerConnectionInitOp;
@@ -796,243 +780,212 @@ class BluetoothDaemonGattInterface final
 {
   class CleanupResultHandler;
   class InitResultHandler;
 
 public:
   BluetoothDaemonGattInterface(BluetoothDaemonGattModule* aModule);
   ~BluetoothDaemonGattInterface();
 
-  void Init(
-    BluetoothGattNotificationHandler* aNotificationHandler,
-    BluetoothGattResultHandler* aRes);
+  void Init(BluetoothGattNotificationHandler* aNotificationHandler,
+            BluetoothGattResultHandler* aRes);
   void Cleanup(BluetoothGattResultHandler* aRes);
 
-  BluetoothGattClientInterface* GetBluetoothGattClientInterface();
-  BluetoothGattServerInterface* GetBluetoothGattServerInterface();
-
-private:
-  void DispatchError(BluetoothGattResultHandler* aRes,
-                     BluetoothStatus aStatus);
-  void DispatchError(BluetoothGattResultHandler* aRes, nsresult aRv);
-
-  BluetoothDaemonGattModule* mModule;
-};
-
-class BluetoothDaemonGattClientInterface final
-  : public BluetoothGattClientInterface
-{
-public:
-  BluetoothDaemonGattClientInterface(BluetoothDaemonGattModule* aModule);
-
   /* Register / Unregister */
   void RegisterClient(const BluetoothUuid& aUuid,
-                      BluetoothGattClientResultHandler* aRes);
+                      BluetoothGattResultHandler* aRes);
   void UnregisterClient(int aClientIf,
-                        BluetoothGattClientResultHandler* aRes);
+                        BluetoothGattResultHandler* aRes);
 
   /* Start / Stop LE Scan */
   void Scan(int aClientIf, bool aStart,
-            BluetoothGattClientResultHandler* aRes);
+            BluetoothGattResultHandler* aRes);
 
   /* Connect / Disconnect */
   void Connect(int aClientIf,
                const nsAString& aBdAddr,
                bool aIsDirect, /* auto connect */
                BluetoothTransport aTransport,
-               BluetoothGattClientResultHandler* aRes);
+               BluetoothGattResultHandler* aRes);
   void Disconnect(int aClientIf,
                   const nsAString& aBdAddr,
                   int aConnId,
-                  BluetoothGattClientResultHandler* aRes);
+                  BluetoothGattResultHandler* aRes);
 
   /* Start / Stop advertisements to listen for incoming connections */
   void Listen(int aClientIf,
               bool aIsStart,
-              BluetoothGattClientResultHandler* aRes);
+              BluetoothGattResultHandler* aRes);
 
   /* Clear the attribute cache for a given device*/
   void Refresh(int aClientIf,
                const nsAString& aBdAddr,
-               BluetoothGattClientResultHandler* aRes);
+               BluetoothGattResultHandler* aRes);
 
   /* Enumerate Attributes */
   void SearchService(int aConnId,
                      bool aSearchAll,
                      const BluetoothUuid& aUuid,
-                     BluetoothGattClientResultHandler* aRes);
+                     BluetoothGattResultHandler* aRes);
   void GetIncludedService(int aConnId,
                           const BluetoothGattServiceId& aServiceId,
                           bool aFirst,
                           const BluetoothGattServiceId& aStartServiceId,
-                          BluetoothGattClientResultHandler* aRes);
+                          BluetoothGattResultHandler* aRes);
   void GetCharacteristic(int aConnId,
                          const BluetoothGattServiceId& aServiceId,
                          bool aFirst,
                          const BluetoothGattId& aStartCharId,
-                         BluetoothGattClientResultHandler* aRes);
+                         BluetoothGattResultHandler* aRes);
   void GetDescriptor(int aConnId,
                      const BluetoothGattServiceId& aServiceId,
                      const BluetoothGattId& aCharId,
                      bool aFirst,
                      const BluetoothGattId& aDescriptorId,
-                     BluetoothGattClientResultHandler* aRes);
+                     BluetoothGattResultHandler* aRes);
 
   /* Read / Write An Attribute */
   void ReadCharacteristic(int aConnId,
                           const BluetoothGattServiceId& aServiceId,
                           const BluetoothGattId& aCharId,
                           BluetoothGattAuthReq aAuthReq,
-                          BluetoothGattClientResultHandler* aRes);
+                          BluetoothGattResultHandler* aRes);
   void WriteCharacteristic(int aConnId,
                            const BluetoothGattServiceId& aServiceId,
                            const BluetoothGattId& aCharId,
                            BluetoothGattWriteType aWriteType,
                            BluetoothGattAuthReq aAuthReq,
                            const nsTArray<uint8_t>& aValue,
-                           BluetoothGattClientResultHandler* aRes);
+                           BluetoothGattResultHandler* aRes);
   void ReadDescriptor(int aConnId,
                       const BluetoothGattServiceId& aServiceId,
                       const BluetoothGattId& aCharId,
                       const BluetoothGattId& aDescriptorId,
                       BluetoothGattAuthReq aAuthReq,
-                      BluetoothGattClientResultHandler* aRes);
+                      BluetoothGattResultHandler* aRes);
   void WriteDescriptor(int aConnId,
                        const BluetoothGattServiceId& aServiceId,
                        const BluetoothGattId& aCharId,
                        const BluetoothGattId& aDescriptorId,
                        BluetoothGattWriteType aWriteType,
                        BluetoothGattAuthReq aAuthReq,
                        const nsTArray<uint8_t>& aValue,
-                       BluetoothGattClientResultHandler* aRes);
+                       BluetoothGattResultHandler* aRes);
 
   /* Execute / Abort Prepared Write*/
   void ExecuteWrite(int aConnId,
                     int aIsExecute,
-                    BluetoothGattClientResultHandler* aRes);
+                    BluetoothGattResultHandler* aRes);
 
 
   /* Register / Deregister Characteristic Notifications or Indications */
   void RegisterNotification(int aClientIf,
                             const nsAString& aBdAddr,
                             const BluetoothGattServiceId& aServiceId,
                             const BluetoothGattId& aCharId,
-                            BluetoothGattClientResultHandler* aRes);
+                            BluetoothGattResultHandler* aRes);
   void DeregisterNotification(int aClientIf,
                               const nsAString& aBdAddr,
                               const BluetoothGattServiceId& aServiceId,
                               const BluetoothGattId& aCharId,
-                              BluetoothGattClientResultHandler* aRes);
+                              BluetoothGattResultHandler* aRes);
 
   void ReadRemoteRssi(int aClientIf,
                       const nsAString& aBdAddr,
-                      BluetoothGattClientResultHandler* aRes);
+                      BluetoothGattResultHandler* aRes);
 
   void GetDeviceType(const nsAString& aBdAddr,
-                     BluetoothGattClientResultHandler* aRes);
+                     BluetoothGattResultHandler* aRes);
 
   /* Set advertising data or scan response data */
   void SetAdvData(int aServerIf,
                   bool aIsScanRsp,
                   bool aIsNameIncluded,
                   bool aIsTxPowerIncluded,
                   int aMinInterval,
                   int aMaxInterval,
                   int aApperance,
                   uint16_t aManufacturerLen, char* aManufacturerData,
                   uint16_t aServiceDataLen, char* aServiceData,
                   uint16_t aServiceUuidLen, char* aServiceUuid,
-                  BluetoothGattClientResultHandler* aRes);
+                  BluetoothGattResultHandler* aRes);
 
   void TestCommand(int aCommand,
                    const BluetoothGattTestParam& aTestParam,
-                   BluetoothGattClientResultHandler* aRes);
-
-private:
-  void DispatchError(BluetoothGattClientResultHandler* aRes,
-                     BluetoothStatus aStatus);
-  void DispatchError(BluetoothGattClientResultHandler* aRes, nsresult aRv);
-  BluetoothDaemonGattModule* mModule;
-};
-
-class BluetoothDaemonGattServerInterface final
-  : public BluetoothGattServerInterface
-{
-public:
-  BluetoothDaemonGattServerInterface(BluetoothDaemonGattModule* aModule);
+                   BluetoothGattResultHandler* aRes);
 
   /* Register / Unregister */
   void RegisterServer(const BluetoothUuid& aUuid,
-                      BluetoothGattServerResultHandler* aRes);
+                      BluetoothGattResultHandler* aRes);
   void UnregisterServer(int aServerIf,
-                        BluetoothGattServerResultHandler* aRes);
+                        BluetoothGattResultHandler* aRes);
 
   /* Connect / Disconnect */
   void ConnectPeripheral(int aServerIf,
                          const nsAString& aBdAddr,
                          bool aIsDirect, /* auto connect */
                          BluetoothTransport aTransport,
-                         BluetoothGattServerResultHandler* aRes);
+                         BluetoothGattResultHandler* aRes);
   void DisconnectPeripheral(int aServerIf,
                             const nsAString& aBdAddr,
                             int aConnId,
-                            BluetoothGattServerResultHandler* aRes);
+                            BluetoothGattResultHandler* aRes);
 
   /* Add a services / a characteristic / a descriptor */
   void AddService(int aServerIf,
                   const BluetoothGattServiceId& aServiceId,
                   int aNumHandles,
-                  BluetoothGattServerResultHandler* aRes);
+                  BluetoothGattResultHandler* aRes);
   void AddIncludedService(int aServerIf,
                           int aServiceHandle,
                           int aIncludedServiceHandle,
-                          BluetoothGattServerResultHandler* aRes);
+                          BluetoothGattResultHandler* aRes);
   void AddCharacteristic(int aServerIf,
                          int aServiceHandle,
                          const BluetoothUuid& aUuid,
                          BluetoothGattCharProp aProperties,
                          BluetoothGattAttrPerm aPermissions,
-                         BluetoothGattServerResultHandler* aRes);
+                         BluetoothGattResultHandler* aRes);
   void AddDescriptor(int aServerIf,
                      int aServiceHandle,
                      const BluetoothUuid& aUuid,
                      BluetoothGattAttrPerm aPermissions,
-                     BluetoothGattServerResultHandler* aRes);
+                     BluetoothGattResultHandler* aRes);
 
   /* Start / Stop / Delete a service */
   void StartService(int aServerIf,
                     int aServiceHandle,
                     BluetoothTransport aTransport,
-                    BluetoothGattServerResultHandler* aRes);
+                    BluetoothGattResultHandler* aRes);
   void StopService(int aServerIf,
                    int aServiceHandle,
-                   BluetoothGattServerResultHandler* aRes);
+                   BluetoothGattResultHandler* aRes);
   void DeleteService(int aServerIf,
                      int aServiceHandle,
-                     BluetoothGattServerResultHandler* aRes);
+                     BluetoothGattResultHandler* aRes);
 
   /* Send an indication or a notification */
   void SendIndication(
     int aServerIf,
     int aAttributeHandle,
     int aConnId,
     const nsTArray<uint8_t>& aValue,
     bool aConfirm, /* true: indication, false: notification */
-    BluetoothGattServerResultHandler* aRes);
+    BluetoothGattResultHandler* aRes);
 
   /* Send a response for an incoming indication */
   void SendResponse(int aConnId,
                     int aTransId,
                     BluetoothGattStatus aStatus,
                     const BluetoothGattResponse& aResponse,
-                    BluetoothGattServerResultHandler* aRes);
-
+                    BluetoothGattResultHandler* aRes);
 
 private:
-  void DispatchError(BluetoothGattServerResultHandler* aRes,
+  void DispatchError(BluetoothGattResultHandler* aRes,
                      BluetoothStatus aStatus);
-  void DispatchError(BluetoothGattServerResultHandler* aRes, nsresult aRv);
+  void DispatchError(BluetoothGattResultHandler* aRes, nsresult aRv);
+
   BluetoothDaemonGattModule* mModule;
 };
 
 END_BLUETOOTH_NAMESPACE
 
 #endif // mozilla_dom_bluetooth_bluedroid_BluetoothDaemonGattInterface_h
--- a/dom/bluetooth/bluedroid/BluetoothGattManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothGattManager.cpp
@@ -27,18 +27,16 @@
   } while(0)
 
 using namespace mozilla;
 USING_BLUETOOTH_NAMESPACE
 
 namespace {
   StaticRefPtr<BluetoothGattManager> sBluetoothGattManager;
   static BluetoothGattInterface* sBluetoothGattInterface;
-  static BluetoothGattClientInterface* sBluetoothGattClientInterface;
-  static BluetoothGattServerInterface* sBluetoothGattServerInterface;
 } // namespace
 
 bool BluetoothGattManager::mInShutdown = false;
 
 static StaticAutoPtr<nsTArray<nsRefPtr<BluetoothGattClient> > > sClients;
 
 struct BluetoothGattClientReadCharState
 {
@@ -298,24 +296,16 @@ BluetoothGattManager::InitGattInterface(
   if (!sBluetoothGattInterface) {
     BT_LOGR("Error: Bluetooth GATT interface not available");
     if (aRes) {
       aRes->OnError(NS_ERROR_FAILURE);
     }
     return;
   }
 
-  sBluetoothGattClientInterface =
-    sBluetoothGattInterface->GetBluetoothGattClientInterface();
-  NS_ENSURE_TRUE_VOID(sBluetoothGattClientInterface);
-
-  sBluetoothGattServerInterface =
-    sBluetoothGattInterface->GetBluetoothGattServerInterface();
-  NS_ENSURE_TRUE_VOID(sBluetoothGattServerInterface);
-
   if (!sClients) {
     sClients = new nsTArray<nsRefPtr<BluetoothGattClient> >;
   }
 
   BluetoothGattManager* gattManager = BluetoothGattManager::Get();
   sBluetoothGattInterface->Init(gattManager,
                                 new InitGattResultHandler(aRes));
 }
@@ -334,18 +324,16 @@ public:
                (int)aStatus);
     if (mRes) {
       mRes->OnError(NS_ERROR_FAILURE);
     }
   }
 
   void Cleanup() override
   {
-    sBluetoothGattClientInterface = nullptr;
-    sBluetoothGattServerInterface = nullptr;
     sBluetoothGattInterface = nullptr;
     sClients = nullptr;
 
     if (mRes) {
       mRes->Deinit();
     }
   }
 
@@ -387,28 +375,28 @@ BluetoothGattManager::DeinitGattInterfac
     nsRefPtr<nsRunnable> r = new CleanupResultHandlerRunnable(aRes);
     if (NS_FAILED(NS_DispatchToMainThread(r))) {
       BT_LOGR("Failed to dispatch cleanup-result-handler runnable");
     }
   }
 }
 
 class BluetoothGattManager::RegisterClientResultHandler final
-  : public BluetoothGattClientResultHandler
+  : public BluetoothGattResultHandler
 {
 public:
   RegisterClientResultHandler(BluetoothGattClient* aClient)
   : mClient(aClient)
   {
     MOZ_ASSERT(mClient);
   }
 
   void OnError(BluetoothStatus aStatus) override
   {
-    BT_WARNING("BluetoothGattClientInterface::RegisterClient failed: %d",
+    BT_WARNING("BluetoothGattInterface::RegisterClient failed: %d",
                (int)aStatus);
 
     BluetoothService* bs = BluetoothService::Get();
     NS_ENSURE_TRUE_VOID(bs);
 
     // Notify BluetoothGatt for client disconnected
     bs->DistributeSignal(
       NS_LITERAL_STRING(GATT_CONNECTION_STATE_CHANGED_ID),
@@ -425,17 +413,17 @@ public:
     sClients->RemoveElement(mClient);
   }
 
 private:
   nsRefPtr<BluetoothGattClient> mClient;
 };
 
 class BluetoothGattManager::UnregisterClientResultHandler final
-  : public BluetoothGattClientResultHandler
+  : public BluetoothGattResultHandler
 {
 public:
   UnregisterClientResultHandler(BluetoothGattClient* aClient)
   : mClient(aClient)
   {
     MOZ_ASSERT(mClient);
   }
 
@@ -455,17 +443,17 @@ public:
     DispatchReplySuccess(mClient->mUnregisterClientRunnable);
     mClient->mUnregisterClientRunnable = nullptr;
 
     sClients->RemoveElement(mClient);
   }
 
   void OnError(BluetoothStatus aStatus) override
   {
-    BT_WARNING("BluetoothGattClientInterface::UnregisterClient failed: %d",
+    BT_WARNING("BluetoothGattInterface::UnregisterClient failed: %d",
                (int)aStatus);
     MOZ_ASSERT(mClient->mUnregisterClientRunnable);
 
     // Reject the unregister request
     DispatchReplyError(mClient->mUnregisterClientRunnable,
                        NS_LITERAL_STRING("Unregister GATT client failed"));
     mClient->mUnregisterClientRunnable = nullptr;
   }
@@ -488,23 +476,23 @@ BluetoothGattManager::UnregisterClient(i
   if (NS_WARN_IF(index == sClients->NoIndex)) {
     DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
     return;
   }
 
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
   client->mUnregisterClientRunnable = aRunnable;
 
-  sBluetoothGattClientInterface->UnregisterClient(
+  sBluetoothGattInterface->UnregisterClient(
     aClientIf,
     new UnregisterClientResultHandler(client));
 }
 
 class BluetoothGattManager::StartLeScanResultHandler final
-  : public BluetoothGattClientResultHandler
+  : public BluetoothGattResultHandler
 {
 public:
   StartLeScanResultHandler(BluetoothGattClient* aClient)
     : mClient(aClient)
   { }
 
   void Scan() override
   {
@@ -512,17 +500,17 @@ public:
 
     DispatchReplySuccess(mClient->mStartLeScanRunnable,
                          BluetoothValue(mClient->mAppUuid));
     mClient->mStartLeScanRunnable = nullptr;
   }
 
   void OnError(BluetoothStatus aStatus) override
   {
-    BT_WARNING("BluetoothGattClientInterface::StartLeScan failed: %d",
+    BT_WARNING("BluetoothGattInterface::StartLeScan failed: %d",
                (int)aStatus);
     MOZ_ASSERT(mClient->mStartLeScanRunnable);
 
     // Unregister client if startLeScan failed
     if (mClient->mClientIf > 0) {
       BluetoothGattManager* gattManager = BluetoothGattManager::Get();
       NS_ENSURE_TRUE_VOID(gattManager);
 
@@ -535,17 +523,17 @@ public:
     mClient->mStartLeScanRunnable = nullptr;
   }
 
 private:
   nsRefPtr<BluetoothGattClient> mClient;
 };
 
 class BluetoothGattManager::StopLeScanResultHandler final
-  : public BluetoothGattClientResultHandler
+  : public BluetoothGattResultHandler
 {
 public:
    StopLeScanResultHandler(BluetoothReplyRunnable* aRunnable, int aClientIf)
      : mRunnable(aRunnable), mClientIf(aClientIf)
   { }
 
   void Scan() override
   {
@@ -559,17 +547,17 @@ public:
       nsRefPtr<BluetoothVoidReplyRunnable> result =
         new BluetoothVoidReplyRunnable(nullptr);
       gattManager->UnregisterClient(mClientIf, result);
     }
   }
 
   void OnError(BluetoothStatus aStatus) override
   {
-    BT_WARNING("BluetoothGattClientInterface::StopLeScan failed: %d",
+    BT_WARNING("BluetoothGattInterface::StopLeScan failed: %d",
                 (int)aStatus);
     DispatchReplyError(mRunnable, aStatus);
   }
 
 private:
   nsRefPtr<BluetoothReplyRunnable> mRunnable;
   int mClientIf;
 };
@@ -599,17 +587,17 @@ BluetoothGattManager::StartLeScan(const 
   sClients->AppendElement(new BluetoothGattClient(appUuidStr, EmptyString()));
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
   client->mStartLeScanRunnable = aRunnable;
 
   BluetoothUuid appUuid;
   StringToUuid(NS_ConvertUTF16toUTF8(appUuidStr).get(), appUuid);
 
   // 'startLeScan' will be proceeded after client registered
-  sBluetoothGattClientInterface->RegisterClient(
+  sBluetoothGattInterface->RegisterClient(
     appUuid, new RegisterClientResultHandler(client));
 }
 
 void
 BluetoothGattManager::StopLeScan(const nsAString& aScanUuid,
                                  BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
@@ -620,35 +608,35 @@ BluetoothGattManager::StopLeScan(const n
   size_t index = sClients->IndexOf(aScanUuid, 0 /* Start */, UuidComparator());
   if (NS_WARN_IF(index == sClients->NoIndex)) {
     // Reject the stop LE scan request
     DispatchReplyError(aRunnable, NS_LITERAL_STRING("StopLeScan failed"));
     return;
   }
 
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
-  sBluetoothGattClientInterface->Scan(
+  sBluetoothGattInterface->Scan(
     client->mClientIf,
     false /* Stop */,
     new StopLeScanResultHandler(aRunnable, client->mClientIf));
 }
 
 class BluetoothGattManager::ConnectResultHandler final
-  : public BluetoothGattClientResultHandler
+  : public BluetoothGattResultHandler
 {
 public:
   ConnectResultHandler(BluetoothGattClient* aClient)
   : mClient(aClient)
   {
     MOZ_ASSERT(mClient);
   }
 
   void OnError(BluetoothStatus aStatus) override
   {
-    BT_WARNING("BluetoothGattClientInterface::Connect failed: %d",
+    BT_WARNING("BluetoothGattInterface::Connect failed: %d",
                (int)aStatus);
     MOZ_ASSERT(mClient->mConnectRunnable);
 
     BluetoothService* bs = BluetoothService::Get();
     NS_ENSURE_TRUE_VOID(bs);
 
     // Notify BluetoothGatt for client disconnected
     bs->DistributeSignal(
@@ -681,44 +669,44 @@ BluetoothGattManager::Connect(const nsAS
     index = sClients->Length();
     sClients->AppendElement(new BluetoothGattClient(aAppUuid, aDeviceAddr));
   }
 
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
   client->mConnectRunnable = aRunnable;
 
   if (client->mClientIf > 0) {
-    sBluetoothGattClientInterface->Connect(client->mClientIf,
+    sBluetoothGattInterface->Connect(client->mClientIf,
                                            aDeviceAddr,
                                            true, // direct connect
                                            TRANSPORT_AUTO,
                                            new ConnectResultHandler(client));
   } else {
     BluetoothUuid uuid;
     StringToUuid(NS_ConvertUTF16toUTF8(aAppUuid).get(), uuid);
 
     // connect will be proceeded after client registered
-    sBluetoothGattClientInterface->RegisterClient(
+    sBluetoothGattInterface->RegisterClient(
       uuid, new RegisterClientResultHandler(client));
   }
 }
 
 class BluetoothGattManager::DisconnectResultHandler final
-  : public BluetoothGattClientResultHandler
+  : public BluetoothGattResultHandler
 {
 public:
   DisconnectResultHandler(BluetoothGattClient* aClient)
   : mClient(aClient)
   {
     MOZ_ASSERT(mClient);
   }
 
   void OnError(BluetoothStatus aStatus) override
   {
-    BT_WARNING("BluetoothGattClientInterface::Disconnect failed: %d",
+    BT_WARNING("BluetoothGattInterface::Disconnect failed: %d",
                (int)aStatus);
     MOZ_ASSERT(mClient->mDisconnectRunnable);
 
     BluetoothService* bs = BluetoothService::Get();
     NS_ENSURE_TRUE_VOID(bs);
 
     // Notify BluetoothGatt that the client remains connected
     bs->DistributeSignal(
@@ -750,36 +738,36 @@ BluetoothGattManager::Disconnect(const n
   if (NS_WARN_IF(index == sClients->NoIndex)) {
     DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
     return;
   }
 
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
   client->mDisconnectRunnable = aRunnable;
 
-  sBluetoothGattClientInterface->Disconnect(
+  sBluetoothGattInterface->Disconnect(
     client->mClientIf,
     aDeviceAddr,
     client->mConnId,
     new DisconnectResultHandler(client));
 }
 
 class BluetoothGattManager::DiscoverResultHandler final
-  : public BluetoothGattClientResultHandler
+  : public BluetoothGattResultHandler
 {
 public:
   DiscoverResultHandler(BluetoothGattClient* aClient)
   : mClient(aClient)
   {
     MOZ_ASSERT(mClient);
   }
 
   void OnError(BluetoothStatus aStatus) override
   {
-    BT_WARNING("BluetoothGattClientInterface::Discover failed: %d",
+    BT_WARNING("BluetoothGattInterface::Discover failed: %d",
                (int)aStatus);
 
     mClient->NotifyDiscoverCompleted(false);
   }
 
 private:
   nsRefPtr<BluetoothGattClient> mClient;
 };
@@ -813,36 +801,36 @@ BluetoothGattManager::Discover(const nsA
    * 1) Discover all services.
    * 2) After all services are discovered, for each service S, we will do
    *    following actions.
    *    2-1) Discover all included services of service S.
    *    2-2) Discover all characteristics of service S.
    *    2-3) Discover all descriptors of those characteristics discovered in
    *         2-2).
    */
-  sBluetoothGattClientInterface->SearchService(
+  sBluetoothGattInterface->SearchService(
     client->mConnId,
     true, // search all services
     BluetoothUuid(),
     new DiscoverResultHandler(client));
 }
 
 class BluetoothGattManager::ReadRemoteRssiResultHandler final
-  : public BluetoothGattClientResultHandler
+  : public BluetoothGattResultHandler
 {
 public:
   ReadRemoteRssiResultHandler(BluetoothGattClient* aClient)
   : mClient(aClient)
   {
     MOZ_ASSERT(mClient);
   }
 
   void OnError(BluetoothStatus aStatus) override
   {
-    BT_WARNING("BluetoothGattClientInterface::ReadRemoteRssi failed: %d",
+    BT_WARNING("BluetoothGattInterface::ReadRemoteRssi failed: %d",
                (int)aStatus);
     MOZ_ASSERT(mClient->mReadRemoteRssiRunnable);
 
     BluetoothService* bs = BluetoothService::Get();
     NS_ENSURE_TRUE_VOID(bs);
 
     // Reject the read remote rssi request
     DispatchReplyError(mClient->mReadRemoteRssiRunnable,
@@ -869,23 +857,23 @@ BluetoothGattManager::ReadRemoteRssi(int
   if (NS_WARN_IF(index == sClients->NoIndex)) {
     DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
     return;
   }
 
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
   client->mReadRemoteRssiRunnable = aRunnable;
 
-  sBluetoothGattClientInterface->ReadRemoteRssi(
+  sBluetoothGattInterface->ReadRemoteRssi(
     aClientIf, aDeviceAddr,
     new ReadRemoteRssiResultHandler(client));
 }
 
 class BluetoothGattManager::RegisterNotificationsResultHandler final
-  : public BluetoothGattClientResultHandler
+  : public BluetoothGattResultHandler
 {
 public:
   RegisterNotificationsResultHandler(BluetoothGattClient* aClient)
   : mClient(aClient)
   {
     MOZ_ASSERT(mClient);
   }
 
@@ -904,17 +892,17 @@ public:
      */
     DispatchReplySuccess(mClient->mRegisterNotificationsRunnable);
     mClient->mRegisterNotificationsRunnable = nullptr;
   }
 
   void OnError(BluetoothStatus aStatus) override
   {
     BT_WARNING(
-      "BluetoothGattClientInterface::RegisterNotifications failed: %d",
+      "BluetoothGattInterface::RegisterNotifications failed: %d",
       (int)aStatus);
     MOZ_ASSERT(mClient->mRegisterNotificationsRunnable);
 
     DispatchReplyError(mClient->mRegisterNotificationsRunnable,
                        NS_LITERAL_STRING("RegisterNotifications failed"));
     mClient->mRegisterNotificationsRunnable = nullptr;
   }
 
@@ -945,23 +933,23 @@ BluetoothGattManager::RegisterNotificati
   if (client->mRegisterNotificationsRunnable || client->mConnId <= 0) {
     DispatchReplyError(aRunnable,
                        NS_LITERAL_STRING("RegisterNotifications failed"));
     return;
   }
 
   client->mRegisterNotificationsRunnable = aRunnable;
 
-  sBluetoothGattClientInterface->RegisterNotification(
+  sBluetoothGattInterface->RegisterNotification(
     client->mClientIf, client->mDeviceAddr, aServId, aCharId,
     new RegisterNotificationsResultHandler(client));
 }
 
 class BluetoothGattManager::DeregisterNotificationsResultHandler final
-  : public BluetoothGattClientResultHandler
+  : public BluetoothGattResultHandler
 {
 public:
   DeregisterNotificationsResultHandler(BluetoothGattClient* aClient)
   : mClient(aClient)
   {
     MOZ_ASSERT(mClient);
   }
 
@@ -980,17 +968,17 @@ public:
      */
     DispatchReplySuccess(mClient->mDeregisterNotificationsRunnable);
     mClient->mDeregisterNotificationsRunnable = nullptr;
   }
 
   void OnError(BluetoothStatus aStatus) override
   {
     BT_WARNING(
-      "BluetoothGattClientInterface::DeregisterNotifications failed: %d",
+      "BluetoothGattInterface::DeregisterNotifications failed: %d",
       (int)aStatus);
     MOZ_ASSERT(mClient->mDeregisterNotificationsRunnable);
 
     DispatchReplyError(mClient->mDeregisterNotificationsRunnable,
                        NS_LITERAL_STRING("DeregisterNotifications failed"));
     mClient->mDeregisterNotificationsRunnable = nullptr;
   }
 
@@ -1020,34 +1008,34 @@ BluetoothGattManager::DeregisterNotifica
   if (client->mDeregisterNotificationsRunnable) {
     DispatchReplyError(aRunnable,
                        NS_LITERAL_STRING("DeregisterNotifications failed"));
     return;
   }
 
   client->mDeregisterNotificationsRunnable = aRunnable;
 
-  sBluetoothGattClientInterface->DeregisterNotification(
+  sBluetoothGattInterface->DeregisterNotification(
     client->mClientIf, client->mDeviceAddr, aServId, aCharId,
     new DeregisterNotificationsResultHandler(client));
 }
 
 class BluetoothGattManager::ReadCharacteristicValueResultHandler final
-  : public BluetoothGattClientResultHandler
+  : public BluetoothGattResultHandler
 {
 public:
   ReadCharacteristicValueResultHandler(BluetoothGattClient* aClient)
     : mClient(aClient)
   {
     MOZ_ASSERT(mClient);
   }
 
   void OnError(BluetoothStatus aStatus) override
   {
-    BT_WARNING("BluetoothGattClientInterface::ReadCharacteristicValue failed" \
+    BT_WARNING("BluetoothGattInterface::ReadCharacteristicValue failed" \
                ": %d", (int)aStatus);
     MOZ_ASSERT(mClient->mReadCharacteristicState.mRunnable);
 
     nsRefPtr<BluetoothReplyRunnable> runnable =
       mClient->mReadCharacteristicState.mRunnable;
     mClient->mReadCharacteristicState.Reset();
 
     // Reject the read characteristic value request
@@ -1095,37 +1083,37 @@ BluetoothGattManager::ReadCharacteristic
 
   client->mReadCharacteristicState.Assign(false, aRunnable);
 
   /**
    * First, read the characteristic value through an unauthenticated physical
    * link. If the operation fails due to insufficient authentication/encryption
    * key size, retry to read through an authenticated physical link.
    */
-  sBluetoothGattClientInterface->ReadCharacteristic(
+  sBluetoothGattInterface->ReadCharacteristic(
     client->mConnId,
     aServiceId,
     aCharacteristicId,
     GATT_AUTH_REQ_NONE,
     new ReadCharacteristicValueResultHandler(client));
 }
 
 class BluetoothGattManager::WriteCharacteristicValueResultHandler final
-  : public BluetoothGattClientResultHandler
+  : public BluetoothGattResultHandler
 {
 public:
   WriteCharacteristicValueResultHandler(BluetoothGattClient* aClient)
   : mClient(aClient)
   {
     MOZ_ASSERT(mClient);
   }
 
   void OnError(BluetoothStatus aStatus) override
   {
-    BT_WARNING("BluetoothGattClientInterface::WriteCharacteristicValue failed" \
+    BT_WARNING("BluetoothGattInterface::WriteCharacteristicValue failed" \
                ": %d", (int)aStatus);
     MOZ_ASSERT(mClient->mWriteCharacteristicState.mRunnable);
 
     nsRefPtr<BluetoothReplyRunnable> runnable =
       mClient->mWriteCharacteristicState.mRunnable;
     mClient->mWriteCharacteristicState.Reset();
 
     // Reject the write characteristic value request
@@ -1176,39 +1164,39 @@ BluetoothGattManager::WriteCharacteristi
   client->mWriteCharacteristicState.Assign(
     aWriteType, aValue, false, aRunnable);
 
   /**
    * First, write the characteristic value through an unauthenticated physical
    * link. If the operation fails due to insufficient authentication/encryption
    * key size, retry to write through an authenticated physical link.
    */
-  sBluetoothGattClientInterface->WriteCharacteristic(
+  sBluetoothGattInterface->WriteCharacteristic(
     client->mConnId,
     aServiceId,
     aCharacteristicId,
     aWriteType,
     GATT_AUTH_REQ_NONE,
     aValue,
     new WriteCharacteristicValueResultHandler(client));
 }
 
 class BluetoothGattManager::ReadDescriptorValueResultHandler final
-  : public BluetoothGattClientResultHandler
+  : public BluetoothGattResultHandler
 {
 public:
   ReadDescriptorValueResultHandler(BluetoothGattClient* aClient)
   : mClient(aClient)
   {
     MOZ_ASSERT(mClient);
   }
 
   void OnError(BluetoothStatus aStatus) override
   {
-    BT_WARNING("BluetoothGattClientInterface::ReadDescriptorValue failed: %d",
+    BT_WARNING("BluetoothGattInterface::ReadDescriptorValue failed: %d",
                (int)aStatus);
     MOZ_ASSERT(mClient->mReadDescriptorState.mRunnable);
 
     nsRefPtr<BluetoothReplyRunnable> runnable =
       mClient->mReadDescriptorState.mRunnable;
     mClient->mReadDescriptorState.Reset();
 
     // Reject the read descriptor value request
@@ -1257,38 +1245,38 @@ BluetoothGattManager::ReadDescriptorValu
 
   client->mReadDescriptorState.Assign(false, aRunnable);
 
   /**
    * First, read the descriptor value through an unauthenticated physical
    * link. If the operation fails due to insufficient authentication/encryption
    * key size, retry to read through an authenticated physical link.
    */
-  sBluetoothGattClientInterface->ReadDescriptor(
+  sBluetoothGattInterface->ReadDescriptor(
     client->mConnId,
     aServiceId,
     aCharacteristicId,
     aDescriptorId,
     GATT_AUTH_REQ_NONE,
     new ReadDescriptorValueResultHandler(client));
 }
 
 class BluetoothGattManager::WriteDescriptorValueResultHandler final
-  : public BluetoothGattClientResultHandler
+  : public BluetoothGattResultHandler
 {
 public:
   WriteDescriptorValueResultHandler(BluetoothGattClient* aClient)
   : mClient(aClient)
   {
     MOZ_ASSERT(mClient);
   }
 
   void OnError(BluetoothStatus aStatus) override
   {
-    BT_WARNING("BluetoothGattClientInterface::WriteDescriptorValue failed: %d",
+    BT_WARNING("BluetoothGattInterface::WriteDescriptorValue failed: %d",
                (int)aStatus);
     MOZ_ASSERT(mClient->mWriteDescriptorState.mRunnable);
 
     nsRefPtr<BluetoothReplyRunnable> runnable =
       mClient->mWriteDescriptorState.mRunnable;
     mClient->mWriteDescriptorState.Reset();
 
     // Reject the write descriptor value request
@@ -1338,17 +1326,17 @@ BluetoothGattManager::WriteDescriptorVal
 
   /**
    * First, write the descriptor value through an unauthenticated physical
    * link. If the operation fails due to insufficient authentication/encryption
    * key size, retry to write through an authenticated physical link.
    */
   client->mWriteDescriptorState.Assign(aValue, false, aRunnable);
 
-  sBluetoothGattClientInterface->WriteDescriptor(
+  sBluetoothGattInterface->WriteDescriptor(
     client->mConnId,
     aServiceId,
     aCharacteristicId,
     aDescriptorId,
     GATT_WRITE_TYPE_NORMAL,
     GATT_AUTH_REQ_NONE,
     aValue,
     new WriteDescriptorValueResultHandler(client));
@@ -1406,30 +1394,30 @@ BluetoothGattManager::RegisterClientNoti
 
   // Notify BluetoothGatt to update the clientIf
   bs->DistributeSignal(
     NS_LITERAL_STRING("ClientRegistered"),
     uuid, BluetoothValue(uint32_t(aClientIf)));
 
   if (client->mStartLeScanRunnable) {
     // Client just registered, proceed remaining startLeScan request.
-    sBluetoothGattClientInterface->Scan(
+    sBluetoothGattInterface->Scan(
       aClientIf, true /* start */,
       new StartLeScanResultHandler(client));
   } else if (client->mConnectRunnable) {
     // Client just registered, proceed remaining connect request.
-    sBluetoothGattClientInterface->Connect(
+    sBluetoothGattInterface->Connect(
       aClientIf, client->mDeviceAddr, true /* direct connect */,
       TRANSPORT_AUTO,
       new ConnectResultHandler(client));
   }
 }
 
 class BluetoothGattManager::ScanDeviceTypeResultHandler final
-  : public BluetoothGattClientResultHandler
+  : public BluetoothGattResultHandler
 {
 public:
   ScanDeviceTypeResultHandler(const nsAString& aBdAddr, int aRssi,
                               const BluetoothGattAdvData& aAdvData)
   : mBdAddr(aBdAddr)
   , mRssi(static_cast<int32_t>(aRssi))
   {
     mAdvData.AppendElements(aAdvData.mAdvData, sizeof(aAdvData.mAdvData));
@@ -1472,21 +1460,21 @@ private:
 
 void
 BluetoothGattManager::ScanResultNotification(
   const nsAString& aBdAddr, int aRssi,
   const BluetoothGattAdvData& aAdvData)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  NS_ENSURE_TRUE_VOID(sBluetoothGattClientInterface);
+  NS_ENSURE_TRUE_VOID(sBluetoothGattInterface);
 
   // Distribute "LeDeviceFound" signal after we know the corresponding
   // BluetoothTypeOfDevice of the device
-  sBluetoothGattClientInterface->GetDeviceType(
+  sBluetoothGattInterface->GetDeviceType(
     aBdAddr,
     new ScanDeviceTypeResultHandler(aBdAddr, aRssi, aAdvData));
 }
 
 void
 BluetoothGattManager::ConnectNotification(int aConnId,
                                           BluetoothGattStatus aStatus,
                                           int aClientIf,
@@ -1611,17 +1599,17 @@ BluetoothGattManager::SearchCompleteNoti
   // Notify BluetoothGatt to create all services
   bs->DistributeSignal(NS_LITERAL_STRING("ServicesDiscovered"),
                        client->mAppUuid,
                        BluetoothValue(client->mServices));
 
   // All services are discovered, continue to search included services of each
   // service if existed, otherwise, notify application that discover completed
   if (!client->mServices.IsEmpty()) {
-    sBluetoothGattClientInterface->GetIncludedService(
+    sBluetoothGattInterface->GetIncludedService(
       aConnId,
       client->mServices[0], // start from first service
       true, // first included service
       BluetoothGattServiceId(),
       new DiscoverResultHandler(client));
   } else {
     client->NotifyDiscoverCompleted(true);
   }
@@ -1670,17 +1658,17 @@ BluetoothGattManager::GetCharacteristicN
         ? GATT_WRITE_TYPE_NO_RESPONSE
         : GATT_WRITE_TYPE_NORMAL;
 
     // Save to mCharacteristics for distributing to applications and
     // discovering descriptors of this characteristic later
     client->mCharacteristics.AppendElement(attribute);
 
     // Get next characteristic of this service
-    sBluetoothGattClientInterface->GetCharacteristic(
+    sBluetoothGattInterface->GetCharacteristic(
       aConnId,
       aServiceId,
       false,
       aCharId,
       new DiscoverResultHandler(client));
   } else { // all characteristics of this service are discovered
     // Notify BluetoothGatt to make BluetoothGattService create characteristics
     // then proceed
@@ -1715,17 +1703,17 @@ BluetoothGattManager::GetDescriptorNotif
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
   MOZ_ASSERT(client->mDiscoverRunnable);
 
   if (aStatus == GATT_STATUS_SUCCESS) {
     // Save to mDescriptors for distributing to applications
     client->mDescriptors.AppendElement(aDescriptorId);
 
     // Get next descriptor of this characteristic
-    sBluetoothGattClientInterface->GetDescriptor(
+    sBluetoothGattInterface->GetDescriptor(
       aConnId,
       aServiceId,
       aCharId,
       false,
       aDescriptorId,
       new DiscoverResultHandler(client));
   } else { // all descriptors of this characteristic are discovered
     // Notify BluetoothGatt to make BluetoothGattCharacteristic create
@@ -1762,17 +1750,17 @@ BluetoothGattManager::GetIncludedService
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
   MOZ_ASSERT(client->mDiscoverRunnable);
 
   if (aStatus == GATT_STATUS_SUCCESS) {
     // Save to mIncludedServices for distributing to applications
     client->mIncludedServices.AppendElement(aIncludedServId);
 
     // Get next included service of this service
-    sBluetoothGattClientInterface->GetIncludedService(
+    sBluetoothGattInterface->GetIncludedService(
       aConnId,
       aServiceId,
       false,
       aIncludedServId,
       new DiscoverResultHandler(client));
   } else { // all included services of this service are discovered
     // Notify BluetoothGatt to make BluetoothGattService create included
     // services
@@ -1782,17 +1770,17 @@ BluetoothGattManager::GetIncludedService
                           client->mIncludedServices);
 
     bs->DistributeSignal(NS_LITERAL_STRING("IncludedServicesDiscovered"),
                          client->mAppUuid,
                          BluetoothValue(values));
     client->mIncludedServices.Clear();
 
     // Start to discover characteristics of this service
-    sBluetoothGattClientInterface->GetCharacteristic(
+    sBluetoothGattInterface->GetCharacteristic(
       aConnId,
       aServiceId,
       true, // first characteristic
       BluetoothGattId(),
       new DiscoverResultHandler(client));
   }
 }
 
@@ -1903,17 +1891,17 @@ BluetoothGattManager::ReadCharacteristic
 
     // Resolve the promise
     DispatchReplySuccess(runnable, BluetoothValue(value));
   } else if (!client->mReadCharacteristicState.mAuthRetry &&
              (aStatus == GATT_STATUS_INSUFFICIENT_AUTHENTICATION ||
               aStatus == GATT_STATUS_INSUFFICIENT_ENCRYPTION)) {
     client->mReadCharacteristicState.mAuthRetry = true;
     // Retry with another authentication requirement
-    sBluetoothGattClientInterface->ReadCharacteristic(
+    sBluetoothGattInterface->ReadCharacteristic(
       aConnId,
       aReadParam.mServiceId,
       aReadParam.mCharId,
       GATT_AUTH_REQ_MITM,
       new ReadCharacteristicValueResultHandler(client));
   } else {
     client->mReadCharacteristicState.Reset();
     // Reject the promise
@@ -1942,17 +1930,17 @@ BluetoothGattManager::WriteCharacteristi
     client->mWriteCharacteristicState.Reset();
     // Resolve the promise
     DispatchReplySuccess(runnable);
   } else if (!client->mWriteCharacteristicState.mAuthRetry &&
              (aStatus == GATT_STATUS_INSUFFICIENT_AUTHENTICATION ||
               aStatus == GATT_STATUS_INSUFFICIENT_ENCRYPTION)) {
     client->mWriteCharacteristicState.mAuthRetry = true;
     // Retry with another authentication requirement
-    sBluetoothGattClientInterface->WriteCharacteristic(
+    sBluetoothGattInterface->WriteCharacteristic(
       aConnId,
       aWriteParam.mServiceId,
       aWriteParam.mCharId,
       client->mWriteCharacteristicState.mWriteType,
       GATT_AUTH_REQ_MITM,
       client->mWriteCharacteristicState.mWriteValue,
       new WriteCharacteristicValueResultHandler(client));
   } else {
@@ -1997,17 +1985,17 @@ BluetoothGattManager::ReadDescriptorNoti
 
     // Resolve the promise
     DispatchReplySuccess(runnable, BluetoothValue(value));
   } else if (!client->mReadDescriptorState.mAuthRetry &&
              (aStatus == GATT_STATUS_INSUFFICIENT_AUTHENTICATION ||
               aStatus == GATT_STATUS_INSUFFICIENT_ENCRYPTION)) {
     client->mReadDescriptorState.mAuthRetry = true;
     // Retry with another authentication requirement
-    sBluetoothGattClientInterface->ReadDescriptor(
+    sBluetoothGattInterface->ReadDescriptor(
       aConnId,
       aReadParam.mServiceId,
       aReadParam.mCharId,
       aReadParam.mDescriptorId,
       GATT_AUTH_REQ_MITM,
       new ReadDescriptorValueResultHandler(client));
   } else {
     client->mReadDescriptorState.Reset();
@@ -2037,17 +2025,17 @@ BluetoothGattManager::WriteDescriptorNot
     client->mWriteDescriptorState.Reset();
     // Resolve the promise
     DispatchReplySuccess(runnable);
   } else if (!client->mWriteDescriptorState.mAuthRetry &&
              (aStatus == GATT_STATUS_INSUFFICIENT_AUTHENTICATION ||
               aStatus == GATT_STATUS_INSUFFICIENT_ENCRYPTION)) {
     client->mWriteDescriptorState.mAuthRetry = true;
     // Retry with another authentication requirement
-    sBluetoothGattClientInterface->WriteDescriptor(
+    sBluetoothGattInterface->WriteDescriptor(
       aConnId,
       aWriteParam.mServiceId,
       aWriteParam.mCharId,
       aWriteParam.mDescriptorId,
       GATT_WRITE_TYPE_NORMAL,
       GATT_AUTH_REQ_MITM,
       client->mWriteDescriptorState.mWriteValue,
       new WriteDescriptorValueResultHandler(client));
@@ -2161,26 +2149,26 @@ BluetoothGattManager::ProceedDiscoverPro
    *      Proceed to discover descriptors of the first saved characteristic.
    * 2) mCharacteristics is empty but mServices is not empty:
    *      This service does not have any saved characteristics left, proceed to
    *      discover included services of the next service.
    * 3) Both arrays are already empty:
    *      Discover is done, notify application.
    */
   if (!aClient->mCharacteristics.IsEmpty()) {
-    sBluetoothGattClientInterface->GetDescriptor(
+    sBluetoothGattInterface->GetDescriptor(
       aClient->mConnId,
       aServiceId,
       aClient->mCharacteristics[0].mId,
       true, // first descriptor
       BluetoothGattId(),
       new DiscoverResultHandler(aClient));
     aClient->mCharacteristics.RemoveElementAt(0);
   } else if (!aClient->mServices.IsEmpty()) {
-    sBluetoothGattClientInterface->GetIncludedService(
+    sBluetoothGattInterface->GetIncludedService(
       aClient->mConnId,
       aClient->mServices[0],
       true, // first included service
       BluetoothGattServiceId(),
       new DiscoverResultHandler(aClient));
     aClient->mServices.RemoveElementAt(0);
   } else {
     aClient->NotifyDiscoverCompleted(true);
--- a/dom/browser-element/mochitest/browserElement_AudioChannel.js
+++ b/dom/browser-element/mochitest/browserElement_AudioChannel.js
@@ -4,18 +4,16 @@
 // Bug 1113086 - tests for AudioChannel API into BrowserElement
 
 "use strict";
 
 SimpleTest.waitForExplicitFinish();
 browserElementTestHelpers.setEnabledPref(true);
 browserElementTestHelpers.addPermission();
 
-SpecialPowers.setBoolPref("media.useAudioChannelService", true);
-
 function noaudio() {
   var iframe = document.createElement('iframe');
   iframe.setAttribute('mozbrowser', 'true');
   iframe.setAttribute('mozapp', 'http://example.org/manifest.webapp');
   iframe.src = 'http://example.org/tests/dom/browser-element/mochitest/file_empty.html';
 
   function noaudio_loadend() {
     ok("mute" in iframe, "iframe.mute exists");
--- a/dom/browser-element/mochitest/browserElement_AudioPlayback.js
+++ b/dom/browser-element/mochitest/browserElement_AudioPlayback.js
@@ -63,13 +63,9 @@ function runTest() {
     ok(false,
        'mozbrowseraudioplaybackchange should dispatch to the correct browser');
   });
 
   // Load a simple page to get the process started.
   iframe.src = browserElementTestHelpers.emptyPage1;
 }
 
-addEventListener('testready', () => {
-  // Audio channel service is needed for events
-  SpecialPowers.pushPrefEnv({"set": [["media.useAudioChannelService", true]]},
-                            runTest);
-});
+addEventListener('testready', runTest);
--- a/dom/browser-element/mochitest/priority/test_Audio.html
+++ b/dom/browser-element/mochitest/priority/test_Audio.html
@@ -42,18 +42,13 @@ function runTest() {
     var p = expectPriorityChange(childID, 'FOREGROUND');
     iframe.setVisible(true);
     return p;
   }).then(SimpleTest.finish);
 
   document.body.appendChild(iframe);
 }
 
-// This test relies on <audio> elements interacting with the audio channel
-// service.  This is controled by the media.useAudioChannelService pref.
-addEventListener('testready', function() {
-  SpecialPowers.pushPrefEnv({set: [['media.useAudioChannelService', true]]},
-                            runTest);
-});
+addEventListener('testready', runTest);
 
 </script>
 </body>
 </html>
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -1009,17 +1009,17 @@ CanvasRenderingContext2D::ParseColor(con
     return false;
   }
 
   if (value.IsNumericColorUnit()) {
     // if we already have a color we can just use it directly
     *aColor = value.GetColorValue();
   } else {
     // otherwise resolve it
-    nsIPresShell* presShell = GetPresShell();
+    nsCOMPtr<nsIPresShell> presShell = GetPresShell();
     nsRefPtr<nsStyleContext> parentContext;
     if (mCanvasElement && mCanvasElement->IsInDoc()) {
       // Inherit from the canvas element.
       parentContext = nsComputedDOMStyle::GetStyleContextForElement(
         mCanvasElement, nullptr, presShell);
     }
 
     unused << nsRuleNode::ComputeColor(
@@ -2146,34 +2146,47 @@ CreateFontStyleRule(const nsAString& aFo
     error);
 }
 
 static already_AddRefed<nsStyleContext>
 GetFontParentStyleContext(Element* aElement, nsIPresShell* presShell,
                           ErrorResult& error)
 {
   if (aElement && aElement->IsInDoc()) {
-    // inherit from the canvas element
-    return nsComputedDOMStyle::GetStyleContextForElement(aElement, nullptr,
-                                                         presShell);
+    // Inherit from the canvas element.
+    nsRefPtr<nsStyleContext> result =
+      nsComputedDOMStyle::GetStyleContextForElement(aElement, nullptr,
+                                                    presShell);
+    if (!result) {
+      error.Throw(NS_ERROR_FAILURE);
+      return nullptr;
+    }
+    return result.forget();
   }
 
   // otherwise inherit from default (10px sans-serif)
   bool changed;
   nsRefPtr<css::StyleRule> parentRule =
     CreateFontStyleRule(NS_LITERAL_STRING("10px sans-serif"),
                         presShell->GetDocument(), &changed, error);
 
   if (error.Failed()) {
     return nullptr;
   }
 
   nsTArray<nsCOMPtr<nsIStyleRule>> parentRules;
   parentRules.AppendElement(parentRule);
-  return presShell->StyleSet()->ResolveStyleForRules(nullptr, parentRules);
+  nsRefPtr<nsStyleContext> result =
+    presShell->StyleSet()->ResolveStyleForRules(nullptr, parentRules);
+
+  if (!result) {
+    error.Throw(NS_ERROR_FAILURE);
+    return nullptr;
+  }
+  return result.forget();
 }
 
 static bool
 PropertyIsInheritOrInitial(StyleRule* aRule, const nsCSSProperty aProperty)
 {
   css::Declaration* declaration = aRule->GetDeclaration();
   // We know the declaration is not !important, so we can use
   // GetNormalBlock().
@@ -2217,16 +2230,22 @@ GetFontStyleContext(Element* aElement, c
   nsRefPtr<nsStyleContext> parentContext =
     GetFontParentStyleContext(aElement, presShell, error);
 
   if (error.Failed()) {
     error.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
+  MOZ_RELEASE_ASSERT(parentContext,
+                     "GetFontParentStyleContext should have returned an error if it couldn't get a parent context.");
+
+  MOZ_ASSERT(!presShell->IsDestroying(),
+             "GetFontParentStyleContext should have returned an error if the presshell is being destroyed.");
+
   nsTArray<nsCOMPtr<nsIStyleRule>> rules;
   rules.AppendElement(rule);
   // add a rule to prevent text zoom from affecting the style
   rules.AppendElement(new nsDisableTextZoomStyleRule);
 
   nsStyleSet* styleSet = presShell->StyleSet();
   nsRefPtr<nsStyleContext> sc =
     styleSet->ResolveStyleForRules(parentContext, rules);
@@ -2294,17 +2313,17 @@ CanvasRenderingContext2D::ParseFilter(co
                                       ErrorResult& error)
 {
   if (!mCanvasElement && !mDocShell) {
     NS_WARNING("Canvas element must be non-null or a docshell must be provided");
     error.Throw(NS_ERROR_FAILURE);
     return false;
   }
 
-  nsIPresShell* presShell = GetPresShell();
+  nsCOMPtr<nsIPresShell> presShell = GetPresShell();
   if (!presShell) {
     error.Throw(NS_ERROR_FAILURE);
     return false;
   }
 
   nsString usedFont;
   nsRefPtr<nsStyleContext> parentContext =
     GetFontStyleContext(mCanvasElement, GetFont(),
@@ -3030,41 +3049,48 @@ CanvasRenderingContext2D::TransformWillU
 //
 // text
 //
 
 void
 CanvasRenderingContext2D::SetFont(const nsAString& font,
                                   ErrorResult& error)
 {
+  SetFontInternal(font, error);
+}
+
+bool
+CanvasRenderingContext2D::SetFontInternal(const nsAString& font,
+                                          ErrorResult& error)
+{
   /*
     * If font is defined with relative units (e.g. ems) and the parent
     * style context changes in between calls, setting the font to the
     * same value as previous could result in a different computed value,
     * so we cannot have the optimization where we check if the new font
     * string is equal to the old one.
     */
 
   if (!mCanvasElement && !mDocShell) {
     NS_WARNING("Canvas element must be non-null or a docshell must be provided");
     error.Throw(NS_ERROR_FAILURE);
-    return;
-  }
-
-  nsIPresShell* presShell = GetPresShell();
+    return false;
+  }
+
+  nsCOMPtr<nsIPresShell> presShell = GetPresShell();
   if (!presShell) {
     error.Throw(NS_ERROR_FAILURE);
-    return;
+    return false;
   }
 
   nsString usedFont;
   nsRefPtr<nsStyleContext> sc =
     GetFontStyleContext(mCanvasElement, font, presShell, usedFont, error);
   if (!sc) {
-    return;
+    return false;
   }
 
   const nsStyleFont* fontStyle = sc->StyleFont();
 
   nsPresContext *c = presShell->GetPresContext();
 
   // Purposely ignore the font size that respects the user's minimum
   // font preference (fontStyle->mFont.size) in favor of the computed
@@ -3094,16 +3120,18 @@ CanvasRenderingContext2D::SetFont(const 
   gfxFontGroup* newFontGroup = metrics->GetThebesFontGroup();
   CurrentState().fontGroup = newFontGroup;
   NS_ASSERTION(CurrentState().fontGroup, "Could not get font group");
   CurrentState().font = usedFont;
   CurrentState().fontFont = fontStyle->mFont;
   CurrentState().fontFont.size = fontStyle->mSize;
   CurrentState().fontLanguage = fontStyle->mLanguage;
   CurrentState().fontExplicitLanguage = fontStyle->mExplicitLanguage;
+
+  return true;
 }
 
 void
 CanvasRenderingContext2D::SetTextAlign(const nsAString& ta)
 {
   if (ta.EqualsLiteral("start"))
     CurrentState().textAlign = TextAlign::START;
   else if (ta.EqualsLiteral("end"))
@@ -3688,17 +3716,22 @@ CanvasRenderingContext2D::DrawOrMeasureT
 
     isRTL = canvasStyle->StyleVisibility()->mDirection ==
       NS_STYLE_DIRECTION_RTL;
   } else {
     isRTL = GET_BIDI_OPTION_DIRECTION(document->GetBidiOptions()) == IBMBIDI_TEXTDIRECTION_RTL;
   }
 
   gfxFontGroup* currentFontStyle = GetCurrentFontStyle();
-  NS_ASSERTION(currentFontStyle, "font group is null");
+  if (!currentFontStyle) {
+    return NS_ERROR_FAILURE;
+  }
+
+  MOZ_ASSERT(!presShell->IsDestroying(),
+             "GetCurrentFontStyle() should have returned null if the presshell is being destroyed");
 
   // ensure user font set is up to date
   currentFontStyle->
     SetUserFontSet(presShell->GetPresContext()->GetUserFontSet());
 
   if (currentFontStyle->GetStyle()->size == 0.0F) {
     if (aWidth) {
       *aWidth = 0;
@@ -3886,37 +3919,35 @@ CanvasRenderingContext2D::DrawOrMeasureT
 
 gfxFontGroup *CanvasRenderingContext2D::GetCurrentFontStyle()
 {
   // use lazy initilization for the font group since it's rather expensive
   if (!CurrentState().fontGroup) {
     ErrorResult err;
     NS_NAMED_LITERAL_STRING(kDefaultFontStyle, "10px sans-serif");
     static float kDefaultFontSize = 10.0;
-    SetFont(kDefaultFontStyle, err);
-    if (err.Failed()) {
+    nsCOMPtr<nsIPresShell> presShell = GetPresShell();
+    bool fontUpdated = SetFontInternal(kDefaultFontStyle, err);
+    if (err.Failed() || !fontUpdated) {
       gfxFontStyle style;
       style.size = kDefaultFontSize;
       CurrentState().fontGroup =
         gfxPlatform::GetPlatform()->CreateFontGroup(FontFamilyList(eFamily_sans_serif),
                                                     &style,
                                                     nullptr);
       if (CurrentState().fontGroup) {
         CurrentState().font = kDefaultFontStyle;
-
-        nsIPresShell* presShell = GetPresShell();
-        if (presShell) {
+        if (presShell && !presShell->IsDestroying()) {
           CurrentState().fontGroup->SetTextPerfMetrics(
             presShell->GetPresContext()->GetTextPerfMetrics());
         }
       } else {
         NS_ERROR("Default canvas font is invalid");
       }
     }
-
   }
 
   return CurrentState().fontGroup;
 }
 
 //
 // line caps/joins
 //
--- a/dom/canvas/CanvasRenderingContext2D.h
+++ b/dom/canvas/CanvasRenderingContext2D.h
@@ -592,16 +592,20 @@ protected:
 
   static void StyleColorToString(const nscolor& aColor, nsAString& aStr);
 
    // Returns whether a filter was successfully parsed.
   bool ParseFilter(const nsAString& aString,
                    nsTArray<nsStyleFilter>& aFilterChain,
                    ErrorResult& error);
 
+  // Returns whether the font was successfully updated.
+  bool SetFontInternal(const nsAString& font, mozilla::ErrorResult& error);
+
+
   /**
    * Creates the error target, if it doesn't exist
    */
   static void EnsureErrorTarget();
 
   /* This function ensures there is a writable pathbuilder available, this
    * pathbuilder may be working in user space or in device space or
    * device space.
@@ -626,17 +630,17 @@ protected:
    * in creating the target then it will put sErrorTarget in place. If there
    * is in turn an error in creating the sErrorTarget then they would both
    * be null so IsTargetValid() would still return null.
    *
    * Returns the actual rendering mode being used by the created target.
    */
   RenderingMode EnsureTarget(RenderingMode aRenderMode = RenderingMode::DefaultBackendMode);
 
-  /*
+  /**
    * Disposes an old target and prepares to lazily create a new target.
    */
   void ClearTarget();
 
   /*
    * Returns the target to the buffer provider. i.e. this will queue a frame for
    * rendering.
    */
@@ -862,20 +866,20 @@ protected:
     FILL,
     STROKE,
     MEASURE
   };
 
 protected:
   gfxFontGroup *GetCurrentFontStyle();
 
-  /*
-    * Implementation of the fillText, strokeText, and measure functions with
-    * the operation abstracted to a flag.
-    */
+  /**
+   * Implementation of the fillText, strokeText, and measure functions with
+   * the operation abstracted to a flag.
+   */
   nsresult DrawOrMeasureText(const nsAString& text,
                              float x,
                              float y,
                              const Optional<double>& maxWidth,
                              TextDrawOperation op,
                              float* aWidth);
 
   bool CheckSizeForSkiaGL(mozilla::gfx::IntSize size);
--- a/dom/canvas/WebGLContextFramebufferOperations.cpp
+++ b/dom/canvas/WebGLContextFramebufferOperations.cpp
@@ -90,17 +90,17 @@ WebGLContext::ClearColor(GLfloat r, GLfl
 void
 WebGLContext::ClearDepth(GLclampf v)
 {
     if (IsContextLost())
         return;
 
     MakeContextCurrent();
     mDepthClearValue = GLClampFloat(v);
-    gl->fClearDepth(v);
+    gl->fClearDepth(mDepthClearValue);
 }
 
 void
 WebGLContext::ClearStencil(GLint v)
 {
     if (IsContextLost())
         return;
 
--- a/dom/canvas/test/reftest/reftest.list
+++ b/dom/canvas/test/reftest/reftest.list
@@ -154,9 +154,9 @@ skip-if(!winWidget) pref(webgl.disable-a
 
 # focus rings
 pref(canvas.focusring.enabled,true) skip-if(B2G) skip-if(Android&&AndroidVersion<15,8,500) skip-if(winWidget) needs-focus == drawFocusIfNeeded.html drawFocusIfNeeded-ref.html
 pref(canvas.customfocusring.enabled,true) skip-if(B2G) skip-if(Android&&AndroidVersion<15,8,500) skip-if(winWidget) needs-focus == drawCustomFocusRing.html drawCustomFocusRing-ref.html
 
 # Check that captureStream() displays in a local video element
 pref(canvas.capturestream.enabled,true) skip-if(winWidget&&layersGPUAccelerated&&d2d) == capturestream.html wrapper.html?green.png
 
-fuzzy-if(Android,3,40) == 1177726-text-stroke-bounds.html 1177726-text-stroke-bounds-ref.html
+fuzzy-if(Android,3,40) fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),1,1) == 1177726-text-stroke-bounds.html 1177726-text-stroke-bounds-ref.html
--- a/dom/engineeringmode/EngineeringModeAPI.js
+++ b/dom/engineeringmode/EngineeringModeAPI.js
@@ -47,46 +47,40 @@ EngineeringModeAPI.prototype = {
 
   uninit: function() {
     cpmm.sendAsyncMessage("EngineeringMode:Unregister", null);
   },
 
   // This returns a Promise<DOMString>
   getValue: function getValue(aName) {
     debug("getValue " + aName);
-    let promiseInit = function(resolve, reject) {
-      debug("promise init called for getValue " + aName);
-      let resolverId = this.getPromiseResolverId({resolve: resolve,
-                                                  reject: reject });
-      debug("promise init " + resolverId);
+    let promiseInit = function(aResolverId) {
+      debug("promise init called for getValue " + aName + " has resolverId " + aResolverId);
       cpmm.sendAsyncMessage("EngineeringMode:GetValue", {
-        requestId: resolverId,
+        requestId: aResolverId,
         name: aName
       });
     }.bind(this);
 
-    return this.createPromise(promiseInit);
+    return this.createPromiseWithId(promiseInit);
   },
 
   // This returns a Promise<void>
   setValue: function setValue(aName, aValue) {
     debug("setValue " + aName + ' as ' + aValue );
-    let promiseInit = function(resolve, reject) {
-      debug("promise init called for setValue " + aName);
-      let resolverId = this.getPromiseResolverId({resolve: resolve,
-                                                  reject: reject });
-      debug("promise init " + resolverId);
+    let promiseInit = function(aResolverId) {
+      debug("promise init called for getValue " + aName + " has resolverId " + aResolverId);
       cpmm.sendAsyncMessage("EngineeringMode:SetValue", {
-        requestId: resolverId,
+        requestId: aResolverId,
         name: aName,
         value: aValue
       });
     }.bind(this);
 
-    return this.createPromise(promiseInit);
+    return this.createPromiseWithId(promiseInit);
   },
 
   set onmessage(aHandler) {
     this.__DOM_IMPL__.setEventHandler("onmessage", aHandler);
   },
 
   get onmessage() {
     return this.__DOM_IMPL__.getEventHandler("onmessage");
--- a/dom/events/test/test_messageEvent.html
+++ b/dom/events/test/test_messageEvent.html
@@ -55,12 +55,12 @@ https://bugzilla.mozilla.org/show_bug.cg
     } catch(e) {
       ok(true, "Source has to be a window or a port");
     }
 
     SimpleTest.finish();
   }
 
   SimpleTest.waitForExplicitFinish();
-  SpecialPowers.pushPrefEnv({"set": [["dom.messageChannel.enabled", true]]}, runTest);
+  runTest();
   </script>
 </body>
 </html>
--- a/dom/fmradio/FMRadio.cpp
+++ b/dom/fmradio/FMRadio.cpp
@@ -130,20 +130,16 @@ FMRadio::Init(nsPIDOMWindow *aWindow)
                                              /* default = */ false);
   if (mHasInternalAntenna) {
     LOG("We have an internal antenna.");
   } else {
     mHeadphoneState = GetCurrentSwitchState(SWITCH_HEADPHONES);
     RegisterSwitchObserver(SWITCH_HEADPHONES, this);
   }
 
-  // All of the codes below are for AudioChannel. We can directly return here
-  // if preferences doesn't enable AudioChannelService.
-  NS_ENSURE_TRUE_VOID(Preferences::GetBool("media.useAudioChannelService"));
-
   nsCOMPtr<nsIAudioChannelAgent> audioChannelAgent =
     do_CreateInstance("@mozilla.org/audiochannelagent;1");
   NS_ENSURE_TRUE_VOID(audioChannelAgent);
 
   audioChannelAgent->InitWithWeakCallback(
     GetOwner(),
     nsIAudioChannelAgent::AUDIO_AGENT_CHANNEL_CONTENT,
     this);
--- a/dom/html/HTMLCanvasElement.cpp
+++ b/dom/html/HTMLCanvasElement.cpp
@@ -873,29 +873,31 @@ HTMLCanvasElement::MozGetIPCContext(cons
 nsresult
 HTMLCanvasElement::UpdateContext(JSContext* aCx, JS::Handle<JS::Value> aNewContextOptions)
 {
   if (!mCurrentContext)
     return NS_OK;
 
   nsIntSize sz = GetWidthHeight();
 
-  nsresult rv = mCurrentContext->SetIsOpaque(HasAttr(kNameSpaceID_None, nsGkAtoms::moz_opaque));
+  nsCOMPtr<nsICanvasRenderingContextInternal> currentContext = mCurrentContext;
+
+  nsresult rv = currentContext->SetIsOpaque(HasAttr(kNameSpaceID_None, nsGkAtoms::moz_opaque));
   if (NS_FAILED(rv)) {
     mCurrentContext = nullptr;
     return rv;
   }
 
-  rv = mCurrentContext->SetContextOptions(aCx, aNewContextOptions);
+  rv = currentContext->SetContextOptions(aCx, aNewContextOptions);
   if (NS_FAILED(rv)) {
     mCurrentContext = nullptr;
     return rv;
   }
 
-  rv = mCurrentContext->SetDimensions(sz.width, sz.height);
+  rv = currentContext->SetDimensions(sz.width, sz.height);
   if (NS_FAILED(rv)) {
     mCurrentContext = nullptr;
     return rv;
   }
 
   return rv;
 }
 
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -1092,21 +1092,16 @@ void HTMLMediaElement::ResumeLoad(Preloa
   }
 }
 
 static bool IsAutoplayEnabled()
 {
   return Preferences::GetBool("media.autoplay.enabled");
 }
 
-static bool UseAudioChannelService()
-{
-  return Preferences::GetBool("media.useAudioChannelService");
-}
-
 static bool UseAudioChannelAPI()
 {
   return Preferences::GetBool("media.useAudioChannelAPI");
 }
 
 void HTMLMediaElement::UpdatePreloadAction()
 {
   PreloadAction nextAction = PRELOAD_UNDEFINED;
@@ -2406,20 +2401,16 @@ bool HTMLMediaElement::ParseAttribute(in
   }
 
   return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
                                               aResult);
 }
 
 bool HTMLMediaElement::CheckAudioChannelPermissions(const nsAString& aString)
 {
-  if (!UseAudioChannelService()) {
-    return true;
-  }
-
   // Only normal channel doesn't need permission.
   if (aString.EqualsASCII("normal")) {
     return true;
   }
 
   // Maybe this audio channel is equal to the default value from the pref.
   nsString audioChannel;
   AudioChannelService::GetDefaultAudioChannelString(audioChannel);
@@ -4452,20 +4443,16 @@ NS_IMETHODIMP HTMLMediaElement::SetMozPr
 ImageContainer* HTMLMediaElement::GetImageContainer()
 {
   VideoFrameContainer* container = GetVideoFrameContainer();
   return container ? container->GetImageContainer() : nullptr;
 }
 
 nsresult HTMLMediaElement::UpdateChannelMuteState(float aVolume, bool aMuted)
 {
-  if (!UseAudioChannelService()) {
-    return NS_OK;
-  }
-
   if (mAudioChannelVolume != aVolume) {
     mAudioChannelVolume = aVolume;
     SetVolumeInternal();
   }
 
   // We have to mute this channel.
   if (aMuted && !ComputedMuted()) {
     SetMutedInternal(mMuted | MUTED_BY_AUDIO_CHANNEL);
@@ -4482,20 +4469,16 @@ nsresult HTMLMediaElement::UpdateChannel
 #ifdef PAUSE_MEDIA_ELEMENT_FROM_AUDIOCHANNEL
   SuspendOrResumeElement(ComputedMuted(), false);
 #endif
   return NS_OK;
 }
 
 void HTMLMediaElement::UpdateAudioChannelPlayingState()
 {
-  if (!UseAudioChannelService()) {
-    return;
-  }
-
   bool playingThroughTheAudioChannel =
      (!mPaused &&
       !Muted() &&
       std::fabs(Volume()) > 1e-7 &&
       (HasAttr(kNameSpaceID_None, nsGkAtoms::loop) ||
        (mReadyState >= nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA &&
         !IsPlaybackEnded()) ||
        mPlayingThroughTheAudioChannelBeforeSeek));
@@ -4546,17 +4529,17 @@ HTMLMediaElement::NotifyAudioChannelAgen
   } else {
     mAudioChannelAgent->NotifyStoppedPlaying(notify);
     mAudioChannelAgent = nullptr;
   }
 }
 
 NS_IMETHODIMP HTMLMediaElement::WindowVolumeChanged(float aVolume, bool aMuted)
 {
-  NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
+  MOZ_ASSERT(NS_IsMainThread());
 
   UpdateChannelMuteState(aVolume, aMuted);
 
 #ifdef PAUSE_MEDIA_ELEMENT_FROM_AUDIOCHANNEL
   mPaused.SetCanPlay(!aMuted);
 #endif
 
   return NS_OK;
--- a/dom/inputmethod/MozKeyboard.js
+++ b/dom/inputmethod/MozKeyboard.js
@@ -389,17 +389,17 @@ MozInputMethod.prototype = {
         inputId: inputId,
         inputManifest: inputManifest,
         appId: appId
       });
     }.bind(this));
   },
 
   removeInput: function(inputId) {
-    return this._sendPromise(function(resolverId) {
+    return this.createPromiseWithId(function(resolverId) {
       let appId = this._window.document.nodePrincipal.appId;
 
       cpmm.sendAsyncMessage('InputRegistry:Remove', {
         requestId: resolverId,
         inputId: inputId,
         appId: appId
       });
     }.bind(this));
@@ -430,24 +430,16 @@ MozInputMethod.prototype = {
     this._ensureIsSystem();
     cpmm.sendAsyncMessage('System:RemoveFocus', {});
   },
 
   _ensureIsSystem: function() {
     if (!this._isSystem) {
       throw new this._window.Error("Should have 'input-manage' permssion.");
     }
-  },
-
-  _sendPromise: function(callback) {
-    let self = this;
-    return this.createPromise(function(resolve, reject) {
-      let resolverId = self.getPromiseResolverId({ resolve: resolve, reject: reject });
-      callback(resolverId);
-    });
   }
 };
 
  /**
  * ==============================================
  * InputContextDOMRequestIpcHelper
  * ==============================================
  */
@@ -781,21 +773,20 @@ MozInputContext.prototype = {
         requestId: resolverId,
         text: text || ''
       });
     });
   },
 
   _sendPromise: function(callback) {
     let self = this;
-    return this._ipcHelper.createPromise(function(resolve, reject) {
-      let resolverId = self._ipcHelper.getPromiseResolverId({ resolve: resolve, reject: reject });
+    return this._ipcHelper.createPromiseWithId(function(aResolverId) {
       if (!WindowMap.isActive(self._window)) {
-        self._ipcHelper.removePromiseResolver(resolverId);
+        self._ipcHelper.removePromiseResolver(aResolverId);
         reject('Input method is not active.');
         return;
       }
-      callback(resolverId);
+      callback(aResolverId);
     });
   }
 };
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([MozInputMethod]);
--- a/dom/locales/en-US/chrome/security/security.properties
+++ b/dom/locales/en-US/chrome/security/security.properties
@@ -63,12 +63,10 @@ InvalidIntegrityBase64=The hash containe
 # LOCALIZATION NOTE: Do not translate "integrity"
 IntegrityMismatch=None of the "%1$S" hashes in the integrity attribute match the content of the subresource.
 IneligibleResource="%1$S" is not eligible for integrity checks since it's neither CORS-enabled nor same-origin.
 # LOCALIZATION NOTE: Do not translate "integrity"
 UnsupportedHashAlg=Unsupported hash algorithm in the integrity attribute: "%1$S"
 # LOCALIZATION NOTE: Do not translate "integrity"
 NoValidMetadata=The integrity attribute does not contain any valid metadata.
 
-# LOCALIZATION NOTE: Do not translate "SSL 3.0".
-WeakProtocolVersionWarning=This site uses the protocol SSL 3.0 for encryption, which is deprecated and insecure.
 # LOCALIZATION NOTE: Do not translate "RC4".
 WeakCipherSuiteWarning=This site uses the cipher RC4 for encryption, which is deprecated and insecure.
--- a/dom/media/BufferMediaResource.h
+++ b/dom/media/BufferMediaResource.h
@@ -21,16 +21,17 @@ class BufferMediaResource : public Media
 {
 public:
   BufferMediaResource(const uint8_t* aBuffer,
                       uint32_t aLength,
                       nsIPrincipal* aPrincipal,
                       const nsACString& aContentType) :
     mBuffer(aBuffer),
     mLength(aLength),
+    mOffset(0),
     mPrincipal(aPrincipal),
     mContentType(aContentType)
   {
     MOZ_COUNT_CTOR(BufferMediaResource);
   }
 
 protected:
   virtual ~BufferMediaResource()
--- a/dom/media/DecodedStream.cpp
+++ b/dom/media/DecodedStream.cpp
@@ -100,17 +100,18 @@ UpdateStreamBlocking(MediaStream* aStrea
  * We have at most one DecodedStreamDaata per MediaDecoder. Its stream
  * is used as the input for each ProcessedMediaStream created by calls to
  * captureStream(UntilEnded). Seeking creates a new source stream, as does
  * replaying after the input as ended. In the latter case, the new source is
  * not connected to streams created by captureStreamUntilEnded.
  */
 class DecodedStreamData {
 public:
-  DecodedStreamData(SourceMediaStream* aStream, bool aPlaying);
+  DecodedStreamData(SourceMediaStream* aStream, bool aPlaying,
+                    MozPromiseHolder<GenericPromise>&& aPromise);
   ~DecodedStreamData();
   bool IsFinished() const;
   int64_t GetPosition() const;
   void SetPlaying(bool aPlaying);
 
   /* The following group of fields are protected by the decoder's monitor
    * and can be read or written on any thread.
    */
@@ -134,36 +135,33 @@ public:
 
   // The decoder is responsible for calling Destroy() on this stream.
   const nsRefPtr<SourceMediaStream> mStream;
   nsRefPtr<DecodedStreamGraphListener> mListener;
   bool mPlaying;
   // True if we need to send a compensation video frame to ensure the
   // StreamTime going forward.
   bool mEOSVideoCompensation;
-  // This promise will be resolved when the SourceMediaStream is finished.
-  nsRefPtr<GenericPromise> mFinishPromise;
 };
 
-DecodedStreamData::DecodedStreamData(SourceMediaStream* aStream, bool aPlaying)
+DecodedStreamData::DecodedStreamData(SourceMediaStream* aStream, bool aPlaying,
+                                     MozPromiseHolder<GenericPromise>&& aPromise)
   : mAudioFramesWritten(0)
   , mNextVideoTime(-1)
   , mNextAudioTime(-1)
   , mStreamInitialized(false)
   , mHaveSentFinish(false)
   , mHaveSentFinishAudio(false)
   , mHaveSentFinishVideo(false)
   , mStream(aStream)
   , mPlaying(aPlaying)
   , mEOSVideoCompensation(false)
 {
-  MozPromiseHolder<GenericPromise> promise;
-  mFinishPromise = promise.Ensure(__func__);
   // DecodedStreamGraphListener will resolve this promise.
-  mListener = new DecodedStreamGraphListener(mStream, Move(promise));
+  mListener = new DecodedStreamGraphListener(mStream, Move(aPromise));
   mStream->AddListener(mListener);
 
   // Block the stream if we are not playing.
   if (!aPlaying) {
     UpdateStreamBlocking(mStream, true);
   }
 }
 
@@ -288,20 +286,29 @@ OutputStreamData::Disconnect()
 
 void
 OutputStreamData::Remove()
 {
   MOZ_ASSERT(NS_IsMainThread());
   mOwner->Remove(mStream);
 }
 
+MediaStreamGraph*
+OutputStreamData::Graph() const
+{
+  return mStream->Graph();
+}
+
 void
 OutputStreamManager::Add(ProcessedMediaStream* aStream, bool aFinishWhenEnded)
 {
   MOZ_ASSERT(NS_IsMainThread());
+  // All streams must belong to the same graph.
+  MOZ_ASSERT(!Graph() || Graph() == aStream->Graph());
+
   // Ensure that aStream finishes the moment mDecodedStream does.
   if (aFinishWhenEnded) {
     aStream->SetAutofinish(true);
   }
 
   OutputStreamData* p = mStreams.AppendElement();
   p->Init(this, aStream);
 
@@ -354,112 +361,123 @@ DecodedStream::DecodedStream(MediaQueue<
   , mVolume(1.0)
   , mAudioQueue(aAudioQueue)
   , mVideoQueue(aVideoQueue)
 {
 }
 
 DecodedStream::~DecodedStream()
 {
+  MOZ_ASSERT(mStartTime.isNothing(), "playback should've ended.");
 }
 
 nsRefPtr<GenericPromise>
 DecodedStream::StartPlayback(int64_t aStartTime, const MediaInfo& aInfo)
 {
   ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
   MOZ_ASSERT(mStartTime.isNothing(), "playback already started.");
+
   mStartTime.emplace(aStartTime);
   mInfo = aInfo;
 
-  // TODO: Unfortunately, current call flow of MDSM guarantees mData is non-null
-  // when StartPlayback() is called which imposes an obscure dependency on MDSM.
-  // We will align the life cycle of mData with {Start,Stop}Playback so that
-  // DecodedStream doesn't need to make assumptions about mData's life cycle.
-  return mData->mFinishPromise;
+  class R : public nsRunnable {
+    typedef MozPromiseHolder<GenericPromise> Promise;
+    typedef void(DecodedStream::*Method)(Promise&&);
+  public:
+    R(DecodedStream* aThis, Method aMethod, Promise&& aPromise)
+      : mThis(aThis), mMethod(aMethod)
+    {
+      mPromise = Move(aPromise);
+    }
+    NS_IMETHOD Run() override
+    {
+      (mThis->*mMethod)(Move(mPromise));
+      return NS_OK;
+    }
+  private:
+    nsRefPtr<DecodedStream> mThis;
+    Method mMethod;
+    Promise mPromise;
+  };
+
+  MozPromiseHolder<GenericPromise> promise;
+  nsRefPtr<GenericPromise> rv = promise.Ensure(__func__);
+  nsCOMPtr<nsIRunnable> r = new R(this, &DecodedStream::CreateData, Move(promise));
+  AbstractThread::MainThread()->Dispatch(r.forget());
+
+  return rv.forget();
 }
 
 void DecodedStream::StopPlayback()
 {
   ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
+  // Playback didn't even start at all.
+  if (mStartTime.isNothing()) {
+    return;
+  }
   mStartTime.reset();
-}
 
-void
-DecodedStream::DestroyData()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-
-  // Avoid the redundant blocking to output stream.
-  if (!mData) {
+  // Clear mData immediately when this playback session ends so we won't
+  // send data to the wrong stream in SendData() in next playback session.
+  DecodedStreamData* data = mData.release();
+  // mData is not yet created on the main thread.
+  if (!data) {
     return;
   }
 
-  mOutputStreamManager.Disconnect();
-  mData = nullptr;
-}
-
-void
-DecodedStream::RecreateData()
-{
   nsRefPtr<DecodedStream> self = this;
-  nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([self] () -> void {
-    self->RecreateData(nullptr);
+  nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([=] () {
+    self->mOutputStreamManager.Disconnect();
+    delete data;
   });
   AbstractThread::MainThread()->Dispatch(r.forget());
 }
 
 void
-DecodedStream::RecreateData(MediaStreamGraph* aGraph)
+DecodedStream::CreateData(MozPromiseHolder<GenericPromise>&& aPromise)
 {
   MOZ_ASSERT(NS_IsMainThread());
   ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-  MOZ_ASSERT((aGraph && !mData && !HasConsumers()) || // first time
-             (!aGraph && mData)); // 2nd time and later
+  MOZ_ASSERT(!mData, "Already created.");
 
-  if (!aGraph) {
-    aGraph = mData->mStream->Graph();
+  // No need to create a source stream when there are no output streams. This
+  // happens when RemoveOutput() is called immediately after StartPlayback().
+  // We also bail out when the playback session has ended. This happens when
+  // StopPlayback() is called immediately after StartPlayback().
+  if (!mOutputStreamManager.Graph() || mStartTime.isNothing()) {
+    // Resolve the promise to indicate the end of playback.
+    aPromise.Resolve(true, __func__);
+    return;
   }
-  auto source = aGraph->CreateSourceStream(nullptr);
-  DestroyData();
-  mData.reset(new DecodedStreamData(source, mPlaying));
 
-  // Note that the delay between removing ports in DestroyData
-  // and adding new ones won't cause a glitch since all graph operations
-  // between main-thread stable states take effect atomically.
+  auto source = mOutputStreamManager.Graph()->CreateSourceStream(nullptr);
+  mData.reset(new DecodedStreamData(source, mPlaying, Move(aPromise)));
   mOutputStreamManager.Connect(mData->mStream);
 }
 
 bool
 DecodedStream::HasConsumers() const
 {
   return !mOutputStreamManager.IsEmpty();
 }
 
 ReentrantMonitor&
 DecodedStream::GetReentrantMonitor() const
 {
   return mMonitor;
 }
 
 void
-DecodedStream::Connect(ProcessedMediaStream* aStream, bool aFinishWhenEnded)
+DecodedStream::AddOutput(ProcessedMediaStream* aStream, bool aFinishWhenEnded)
 {
-  MOZ_ASSERT(NS_IsMainThread());
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-
-  if (!mData) {
-    RecreateData(aStream->Graph());
-  }
-
   mOutputStreamManager.Add(aStream, aFinishWhenEnded);
 }
 
 void
-DecodedStream::Remove(MediaStream* aStream)
+DecodedStream::RemoveOutput(MediaStream* aStream)
 {
   mOutputStreamManager.Remove(aStream);
 }
 
 void
 DecodedStream::SetPlaying(bool aPlaying)
 {
   ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
@@ -731,16 +749,21 @@ DecodedStream::AdvanceTracks()
 }
 
 void
 DecodedStream::SendData()
 {
   ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
   MOZ_ASSERT(mStartTime.isSome(), "Must be called after StartPlayback()");
 
+  // Not yet created on the main thread. MDSM will try again later.
+  if (!mData) {
+    return;
+  }
+
   // Nothing to do when the stream is finished.
   if (mData->mHaveSentFinish) {
     return;
   }
 
   InitTracks();
   SendAudio(mVolume, mSameOrigin);
   SendVideo(mSameOrigin);
@@ -754,36 +777,36 @@ DecodedStream::SendData()
     mData->mStream->Finish();
   }
 }
 
 int64_t
 DecodedStream::AudioEndTime() const
 {
   ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-  if (mStartTime.isSome() && mInfo.HasAudio()) {
+  if (mStartTime.isSome() && mInfo.HasAudio() && mData) {
     CheckedInt64 t = mStartTime.ref() +
       FramesToUsecs(mData->mAudioFramesWritten, mInfo.mAudio.mRate);
     if (t.isValid()) {
       return t.value();
     }
   }
   return -1;
 }
 
 int64_t
 DecodedStream::GetPosition() const
 {
   ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
   // This is only called after MDSM starts playback. So mStartTime is
   // guaranteed to be something.
   MOZ_ASSERT(mStartTime.isSome());
-  return mStartTime.ref() + mData->GetPosition();
+  return mStartTime.ref() + (mData ? mData->GetPosition() : 0);
 }
 
 bool
 DecodedStream::IsFinished() const
 {
   ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-  return mData->IsFinished();
+  return mData && mData->IsFinished();
 }
 
 } // namespace mozilla
--- a/dom/media/DecodedStream.h
+++ b/dom/media/DecodedStream.h
@@ -51,16 +51,18 @@ public:
   // managed by OutputStreamManager.
   void Remove();
   // Return true if aStream points to the same object as mStream.
   // Used by OutputStreamManager to remove an output stream.
   bool Equals(MediaStream* aStream)
   {
     return mStream == aStream;
   }
+  // Return the graph mStream belongs to.
+  MediaStreamGraph* Graph() const;
 
 private:
   OutputStreamManager* mOwner;
   nsRefPtr<ProcessedMediaStream> mStream;
   // mPort connects our mStream to an input stream.
   nsRefPtr<MediaInputPort> mPort;
   nsRefPtr<OutputStreamListener> mListener;
 };
@@ -76,16 +78,22 @@ public:
   {
     MOZ_ASSERT(NS_IsMainThread());
     return mStreams.IsEmpty();
   }
   // Connect all output streams in the collection to the input stream.
   void Connect(MediaStream* aStream);
   // Disconnect all output streams from the input stream.
   void Disconnect();
+  // Return the graph these streams belong to or null if empty.
+  MediaStreamGraph* Graph() const
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    return !IsEmpty() ? mStreams[0].Graph() : nullptr;
+  }
 
 private:
   // Keep the input stream so we can connect the output streams that
   // are added after Connect().
   nsRefPtr<MediaStream> mInputStream;
   nsTArray<OutputStreamData> mStreams;
 };
 
@@ -100,20 +108,18 @@ public:
   //
   // Return a promise which will be resolved when the stream is finished
   // or rejected if any error.
   nsRefPtr<GenericPromise> StartPlayback(int64_t aStartTime,
                                          const MediaInfo& aInfo);
   // Mimic MDSM::StopAudioThread.
   void StopPlayback();
 
-  void DestroyData();
-  void RecreateData();
-  void Connect(ProcessedMediaStream* aStream, bool aFinishWhenEnded);
-  void Remove(MediaStream* aStream);
+  void AddOutput(ProcessedMediaStream* aStream, bool aFinishWhenEnded);
+  void RemoveOutput(MediaStream* aStream);
 
   void SetPlaying(bool aPlaying);
   void SetVolume(double aVolume);
   void SetSameOrigin(bool aSameOrigin);
 
   int64_t AudioEndTime() const;
   int64_t GetPosition() const;
   bool IsFinished() const;
@@ -121,17 +127,17 @@ public:
 
   void SendData();
 
 protected:
   virtual ~DecodedStream();
 
 private:
   ReentrantMonitor& GetReentrantMonitor() const;
-  void RecreateData(MediaStreamGraph* aGraph);
+  void CreateData(MozPromiseHolder<GenericPromise>&& aPromise);
   void InitTracks();
   void AdvanceTracks();
   void SendAudio(double aVolume, bool aIsSameOrigin);
   void SendVideo(bool aIsSameOrigin);
 
   UniquePtr<DecodedStreamData> mData;
   // Data about MediaStreams that are being fed by the decoder.
   OutputStreamManager mOutputStreamManager;
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -381,17 +381,19 @@ void MediaDecoderStateMachine::SendStrea
   const auto clockTime = GetClock();
   while (true) {
     const MediaData* a = AudioQueue().PeekFront();
 
     // If we discard audio samples fed to the stream immediately, we will
     // keep decoding audio samples till the end and consume a lot of memory.
     // Therefore we only discard those behind the stream clock to throttle
     // the decoding speed.
-    if (a && a->mTime <= clockTime) {
+    // Note we don't discard a sample when |a->mTime == clockTime| because that
+    // will discard the 1st sample when clockTime is still 0.
+    if (a && a->mTime < clockTime) {
       nsRefPtr<MediaData> releaseMe = AudioQueue().PopFront();
       continue;
     }
     break;
   }
 }
 
 bool MediaDecoderStateMachine::HaveEnoughDecodedAudio(int64_t aAmpleAudioUSecs)
@@ -1547,20 +1549,16 @@ MediaDecoderStateMachine::InitiateSeek()
   NS_ASSERTION(end != -1, "Should know end time by now");
   int64_t seekTime = mCurrentSeek.mTarget.mTime;
   seekTime = std::min(seekTime, end);
   seekTime = std::max(int64_t(0), seekTime);
   NS_ASSERTION(seekTime >= 0 && seekTime <= end,
                "Can only seek in range [0,duration]");
   mCurrentSeek.mTarget.mTime = seekTime;
 
-  if (mAudioCaptured) {
-    mDecodedStream->RecreateData();
-  }
-
   mDropAudioUntilNextDiscontinuity = HasAudio();
   mDropVideoUntilNextDiscontinuity = HasVideo();
   mCurrentTimeBeforeSeek = GetMediaTime();
 
   // Stop playback now to ensure that while we're outside the monitor
   // dispatching SeekingStarted, playback doesn't advance and mess with
   // mCurrentPosition that we've setting to seekTime here.
   StopPlayback();
@@ -3168,25 +3166,25 @@ void MediaDecoderStateMachine::DispatchA
   OwnerThread()->Dispatch(r.forget());
 }
 
 void MediaDecoderStateMachine::AddOutputStream(ProcessedMediaStream* aStream,
                                                bool aFinishWhenEnded)
 {
   MOZ_ASSERT(NS_IsMainThread());
   DECODER_LOG("AddOutputStream aStream=%p!", aStream);
-  mDecodedStream->Connect(aStream, aFinishWhenEnded);
+  mDecodedStream->AddOutput(aStream, aFinishWhenEnded);
   DispatchAudioCaptured();
 }
 
 void MediaDecoderStateMachine::RemoveOutputStream(MediaStream* aStream)
 {
   MOZ_ASSERT(NS_IsMainThread());
   DECODER_LOG("RemoveOutputStream=%p!", aStream);
-  mDecodedStream->Remove(aStream);
+  mDecodedStream->RemoveOutput(aStream);
   if (!mDecodedStream->HasConsumers()) {
     DispatchAudioUncaptured();
   }
 }
 
 } // namespace mozilla
 
 // avoid redefined macro in unified build
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -314,17 +314,16 @@ public:
   }
 
   // Drop reference to decoder.  Only called during shutdown dance.
   void BreakCycles() {
     MOZ_ASSERT(NS_IsMainThread());
     if (mReader) {
       mReader->BreakCycles();
     }
-    mDecodedStream->DestroyData();
     mResource = nullptr;
     mDecoder = nullptr;
   }
 
   // Copy queued audio/video data in the reader to any output MediaStreams that
   // need it.
   void SendStreamData();
   void FinishStreamData();
--- a/dom/media/test/mochitest.ini
+++ b/dom/media/test/mochitest.ini
@@ -678,36 +678,32 @@ tags=msg
 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 capturestream
 [test_mediarecorder_record_no_timeslice.html]
 tags=msg capturestream
-skip-if = toolkit == 'gonk' && debug
 [test_mediarecorder_record_nosrc.html]
 tags=msg capturestream
 [test_mediarecorder_record_session.html]
 tags=msg capturestream
 [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 capturestream
-skip-if = toolkit == 'gonk' && debug
 [test_mediarecorder_reload_crash.html]
 tags=msg capturestream
 [test_mediarecorder_unsupported_src.html]
 tags=msg
 [test_mediarecorder_record_getdata_afterstart.html]
 tags=msg capturestream
-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]
--- a/dom/media/tests/mochitest/head.js
+++ b/dom/media/tests/mochitest/head.js
@@ -230,28 +230,26 @@ function setupEnvironment() {
   }
 
   // Running as a Mochitest.
   SimpleTest.requestFlakyTimeout("WebRTC inherently depends on timeouts");
   window.finish = () => SimpleTest.finish();
   SpecialPowers.pushPrefEnv({
     'set': [
       ['canvas.capturestream.enabled', true],
-      ['dom.messageChannel.enabled', true],
       ['media.peerconnection.enabled', true],
       ['media.peerconnection.identity.enabled', true],
       ['media.peerconnection.identity.timeout', 120000],
       ['media.peerconnection.ice.stun_client_maximum_transmits', 14],
       ['media.peerconnection.ice.trickle_grace_period', 30000],
       ['media.navigator.permission.disabled', true],
       ['media.navigator.streams.fake', FAKE_ENABLED],
       ['media.getusermedia.screensharing.enabled', true],
       ['media.getusermedia.screensharing.allowed_domains', "mochi.test"],
       ['media.getusermedia.audiocapture.enabled', true],
-      ['media.useAudioChannelService', true],
       ['media.recorder.audio_node.enabled', true]
     ]
   }, setTestOptions);
 
   // We don't care about waiting for this to complete, we just want to ensure
   // that we don't build up a huge backlog of GC work.
   SpecialPowers.exactGC(window);
 }
--- a/dom/media/tests/mochitest/identity/test_fingerprints.html
+++ b/dom/media/tests/mochitest/identity/test_fingerprints.html
@@ -100,14 +100,13 @@ function testMultipleFingerprints() {
       pcStrict.close();
       pcDouble.close();
       SimpleTest.finish();
     });
 }
 
 SimpleTest.waitForExplicitFinish();
 SpecialPowers.pushPrefEnv({
-  set: [ [ 'dom.messageChannel.enabled', true ],
-         [ 'media.peerconnection.identity.enabled', true ] ]
+  set: [ [ 'media.peerconnection.identity.enabled', true ] ]
 }, testMultipleFingerprints);
 </script>
   </body>
 </html>
--- a/dom/media/tests/mochitest/identity/test_idpproxy.html
+++ b/dom/media/tests/mochitest/identity/test_idpproxy.html
@@ -157,14 +157,12 @@ function run_all_tests() {
       .catch(e => ok(false, test.name + ' failed: ' +
                      SpecialPowers.wrap(e).message + '\n' +
                      SpecialPowers.wrap(e).stack));
   }, Promise.resolve())
     .then(() => SimpleTest.finish());
 }
 
 SimpleTest.waitForExplicitFinish();
-SpecialPowers.pushPrefEnv({
-  set: [ [ 'dom.messageChannel.enabled', true ] ]
-}, run_all_tests);
+run_all_tests();
 </script>
   </body>
 </html>
--- a/dom/media/webaudio/AudioDestinationNode.cpp
+++ b/dom/media/webaudio/AudioDestinationNode.cpp
@@ -300,21 +300,16 @@ public:
   }
 
 private:
   float mVolume;
   bool mLastInputMuted;
   bool mSuspended;
 };
 
-static bool UseAudioChannelService()
-{
-  return Preferences::GetBool("media.useAudioChannelService");
-}
-
 static bool UseAudioChannelAPI()
 {
   return Preferences::GetBool("media.useAudioChannelAPI");
 }
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(AudioDestinationNode, AudioNode,
                                    mAudioChannelAgent,
                                    mOfflineRenderingPromise)
@@ -592,20 +587,16 @@ AudioDestinationNode::SetMozAudioChannel
       CreateAudioChannelAgent();
     }
   }
 }
 
 bool
 AudioDestinationNode::CheckAudioChannelPermissions(AudioChannel aValue)
 {
-  if (!UseAudioChannelService()) {
-    return true;
-  }
-
   // Only normal channel doesn't need permission.
   if (aValue == AudioChannel::Normal) {
     return true;
   }
 
   // Maybe this audio channel is equal to the default one.
   if (aValue == AudioChannelService::GetDefaultAudioChannel()) {
     return true;
@@ -631,17 +622,17 @@ AudioDestinationNode::CheckAudioChannelP
     &perm);
 
   return perm == nsIPermissionManager::ALLOW_ACTION;
 }
 
 void
 AudioDestinationNode::CreateAudioChannelAgent()
 {
-  if (mIsOffline || !UseAudioChannelService()) {
+  if (mIsOffline) {
     return;
   }
 
   if (mAudioChannelAgent) {
     mAudioChannelAgent->NotifyStoppedPlaying(nsIAudioChannelAgent::AUDIO_AGENT_NOTIFY);
   }
 
   mAudioChannelAgent = new AudioChannelAgent();
--- a/dom/media/webaudio/test/test_mozaudiochannel.html
+++ b/dom/media/webaudio/test/test_mozaudiochannel.html
@@ -136,17 +136,16 @@ function runTest() {
     SimpleTest.finish();
     return;
   }
 
   var test = tests.shift();
   test();
 }
 
-SpecialPowers.pushPrefEnv({"set": [["media.useAudioChannelAPI", true ],
-                                   ["media.useAudioChannelService", true ]]}, runTest);
+SpecialPowers.pushPrefEnv({"set": [["media.useAudioChannelAPI", true ]]}, runTest);
 SimpleTest.waitForExplicitFinish();
 SimpleTest.requestLongerTimeout(5);
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/messagechannel/MessageChannel.cpp
+++ b/dom/messagechannel/MessageChannel.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "MessageChannel.h"
 
-#include "mozilla/Preferences.h"
 #include "mozilla/dom/MessageChannelBinding.h"
 #include "mozilla/dom/MessagePort.h"
 #include "mozilla/dom/Navigator.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/dom/WorkerRunnable.h"
 #include "nsContentUtils.h"
 #include "nsIDocument.h"
 #include "nsIPrincipal.h"
@@ -25,159 +24,16 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Me
 NS_IMPL_CYCLE_COLLECTING_ADDREF(MessageChannel)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(MessageChannel)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MessageChannel)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
-namespace {
-bool gPrefInitialized = false;
-bool gPrefEnabled = false;
-
-bool
-CheckPermission(nsIPrincipal* aPrincipal, bool aCallerChrome)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (!gPrefInitialized) {
-    Preferences::AddBoolVarCache(&gPrefEnabled, "dom.messageChannel.enabled");
-    gPrefInitialized = true;
-  }
-
-  // Enabled by pref
-  if (gPrefEnabled) {
-    return true;
-  }
-
-  // Chrome callers are allowed.
-  if (aCallerChrome) {
-    return true;
-  }
-
-  nsCOMPtr<nsIURI> uri;
-  if (NS_FAILED(aPrincipal->GetURI(getter_AddRefs(uri))) || !uri) {
-    return false;
-  }
-
-  bool isResource = false;
-  if (NS_FAILED(uri->SchemeIs("resource", &isResource))) {
-    return false;
-  }
-
-  return isResource;
-}
-
-nsIPrincipal*
-GetPrincipalFromWorkerPrivate(workers::WorkerPrivate* aWorkerPrivate)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsIPrincipal* principal = aWorkerPrivate->GetPrincipal();
-  if (principal) {
-    return principal;
-  }
-
-  // Walk up to our containing page
-  workers::WorkerPrivate* wp = aWorkerPrivate;
-  while (wp->GetParent()) {
-    wp = wp->GetParent();
-  }
-
-  nsPIDOMWindow* window = wp->GetWindow();
-  if (!window) {
-    return nullptr;
-  }
-
-  nsIDocument* doc = window->GetExtantDoc();
-  if (!doc) {
-    return nullptr;
-  }
-
-  return doc->NodePrincipal();
-}
-
-// A WorkerMainThreadRunnable to synchronously dispatch the call of
-// CheckPermission() from the worker thread to the main thread.
-class CheckPermissionRunnable final : public workers::WorkerMainThreadRunnable
-{
-public:
-  bool mResult;
-  bool mCallerChrome;
-
-  explicit CheckPermissionRunnable(workers::WorkerPrivate* aWorkerPrivate)
-    : workers::WorkerMainThreadRunnable(aWorkerPrivate)
-    , mResult(false)
-    , mCallerChrome(false)
-  {
-    MOZ_ASSERT(aWorkerPrivate);
-    aWorkerPrivate->AssertIsOnWorkerThread();
-    mCallerChrome = aWorkerPrivate->UsesSystemPrincipal();
-  }
-
-protected:
-  virtual bool
-  MainThreadRun() override
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    nsIPrincipal* principal = GetPrincipalFromWorkerPrivate(mWorkerPrivate);
-    if (!principal) {
-      return true;
-    }
-
-    bool isNullPrincipal;
-    nsresult rv = principal->GetIsNullPrincipal(&isNullPrincipal);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-       return true;
-    }
-
-    if (NS_WARN_IF(isNullPrincipal)) {
-      return true;
-    }
-
-    mResult = CheckPermission(principal, mCallerChrome);
-    return true;
-  }
-};
-
-} // namespace
-
-/* static */ bool
-MessageChannel::Enabled(JSContext* aCx, JSObject* aGlobal)
-{
-  if (NS_IsMainThread()) {
-    JS::Rooted<JSObject*> global(aCx, aGlobal);
-
-    nsCOMPtr<nsPIDOMWindow> win = Navigator::GetWindowFromGlobal(global);
-    if (!win) {
-      return false;
-    }
-
-    nsIDocument* doc = win->GetExtantDoc();
-    if (!doc) {
-      return false;
-    }
-
-    return CheckPermission(doc->NodePrincipal(),
-                           nsContentUtils::IsCallerChrome());
-  }
-
-  workers::WorkerPrivate* workerPrivate =
-    workers::GetWorkerPrivateFromContext(aCx);
-  workerPrivate->AssertIsOnWorkerThread();
-
-  nsRefPtr<CheckPermissionRunnable> runnable =
-    new CheckPermissionRunnable(workerPrivate);
-  runnable->Dispatch(aCx);
-
-  return runnable->mResult;
-}
-
 MessageChannel::MessageChannel(nsPIDOMWindow* aWindow)
   : mWindow(aWindow)
 {
 }
 
 MessageChannel::~MessageChannel()
 {
 }
--- a/dom/messagechannel/MessageChannel.h
+++ b/dom/messagechannel/MessageChannel.h
@@ -23,19 +23,16 @@ class MessagePort;
 
 class MessageChannel final : public nsISupports
                            , public nsWrapperCache
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MessageChannel)
 
-  static bool Enabled(JSContext* aCx, JSObject* aGlobal);
-
-public:
   nsPIDOMWindow*
   GetParentObject() const
   {
     return mWindow;
   }
 
   virtual JSObject*
   WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
--- a/dom/messagechannel/tests/mochitest.ini
+++ b/dom/messagechannel/tests/mochitest.ini
@@ -9,17 +9,16 @@ support-files =
   sharedWorker_messageChannel.js
   sharedWorker2_messageChannel.js
   iframe_messageChannel_sharedWorker2.html
 
 [test_messageChannel.html]
 [test_messageChannel_cloning.html]
 [test_messageChannel_pingpong.html]
 [test_messageChannel_post.html]
-[test_messageChannel_pref.html]
 [test_messageChannel_start.html]
 [test_messageChannel_transferable.html]
 [test_messageChannel_unshipped.html]
 [test_messageChannel_worker.html]
 [test_messageChannel_selfTransferring.html]
 [test_messageChannel_sharedWorker.html]
 [test_messageChannel_sharedWorker2.html]
 [test_messageChannel_any.html]
--- a/dom/messagechannel/tests/test_messageChannel.html
+++ b/dom/messagechannel/tests/test_messageChannel.html
@@ -16,34 +16,28 @@ https://bugzilla.mozilla.org/show_bug.cg
 <div id="content" style="display: none">
   <iframe name="x" id="x"></iframe>
   <iframe name="y" id="y"></iframe>
 </div>
 <pre id="test">
 </pre>
   <script type="application/javascript">
 
-  function runTest() {
-    /** Test for Bug 677638 **/
-    var a = new MessageChannel();
-    ok(a, "MessageChannel created");
+  /** Test for Bug 677638 **/
+  var a = new MessageChannel();
+  ok(a, "MessageChannel created");
 
-    var port1 = a.port1;
-    ok(port1, "MessageChannel.port1 exists");
-    is(port1, a.port1, "MessageChannel.port1 is port1");
+  var port1 = a.port1;
+  ok(port1, "MessageChannel.port1 exists");
+  is(port1, a.port1, "MessageChannel.port1 is port1");
 
-    var port2 = a.port2;
-    ok(port2, "MessageChannel.port1 exists");
-    is(port2, a.port2, "MessageChannel.port2 is port2");
+  var port2 = a.port2;
+  ok(port2, "MessageChannel.port1 exists");
+  is(port2, a.port2, "MessageChannel.port2 is port2");
 
-    [ 'postMessage', 'start', 'close' ].forEach(function(e) {
-      ok(e in port1, "MessagePort1." + e + " exists");
-      ok(e in port2, "MessagePort2." + e + " exists");
-    });
+  [ 'postMessage', 'start', 'close' ].forEach(function(e) {
+    ok(e in port1, "MessagePort1." + e + " exists");
+    ok(e in port2, "MessagePort2." + e + " exists");
+  });
 
-    SimpleTest.finish();
-  }
-
-  SimpleTest.waitForExplicitFinish();
-  SpecialPowers.pushPrefEnv({"set": [["dom.messageChannel.enabled", true]]}, runTest);
   </script>
 </body>
 </html>
--- a/dom/messagechannel/tests/test_messageChannel_any.html
+++ b/dom/messagechannel/tests/test_messageChannel_any.html
@@ -104,12 +104,12 @@ function runTest() {
       next();
     }
   };
 
   worker.postMessage(mc.port2, [mc.port2]);
 }
 
 SimpleTest.waitForExplicitFinish();
-SpecialPowers.pushPrefEnv({"set": [["dom.messageChannel.enabled", true]]}, runTest);
+runTest();
   </script>
 </body>
 </html>
--- a/dom/messagechannel/tests/test_messageChannel_bug1178076.html
+++ b/dom/messagechannel/tests/test_messageChannel_bug1178076.html
@@ -27,12 +27,12 @@ https://bugzilla.mozilla.org/show_bug.cg
     // In this test we want to see if we leak a neutered port closing port1
     // and sending port2 to the same window. This operation doesn't involve IPC.
     var mc = new MessageChannel();
     mc.port1.close();
     postMessage(42, '*', [mc.port2]);
   }
 
   SimpleTest.waitForExplicitFinish();
-  SpecialPowers.pushPrefEnv({"set": [["dom.messageChannel.enabled", true]]}, runTest);
+  runTest();
   </script>
 </body>
 </html>
--- a/dom/messagechannel/tests/test_messageChannel_cloning.html
+++ b/dom/messagechannel/tests/test_messageChannel_cloning.html
@@ -59,12 +59,12 @@ https://bugzilla.mozilla.org/show_bug.cg
       return;
     }
 
     var test = tests.shift();
     test();
   }
 
   SimpleTest.waitForExplicitFinish();
-  SpecialPowers.pushPrefEnv({"set": [["dom.messageChannel.enabled", true]]}, runTest);
+  runTest();
   </script>
 </body>
 </html>
--- a/dom/messagechannel/tests/test_messageChannel_forceClose.html
+++ b/dom/messagechannel/tests/test_messageChannel_forceClose.html
@@ -11,26 +11,20 @@ https://bugzilla.mozilla.org/show_bug.cg
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1176034">Mozilla Bug 1176034</a>
 <div id="content"></div>
 <pre id="test">
 </pre>
   <script type="application/javascript">
 
-  function runTests() {
-    var mc = new MessageChannel();
+  var mc = new MessageChannel();
 
-    try {
-      postMessage(42, "*", [ mc.port1, window ]);
-      ok(false, "Something went wrong.");
-    } catch(e) {
-      ok(true, "PostMessage should fail and we should not leak.");
-    }
-
-    SimpleTest.finish();
+  try {
+    postMessage(42, "*", [ mc.port1, window ]);
+    ok(false, "Something went wrong.");
+  } catch(e) {
+    ok(true, "PostMessage should fail and we should not leak.");
   }
 
-  SimpleTest.waitForExplicitFinish();
-  SpecialPowers.pushPrefEnv({"set": [["dom.messageChannel.enabled", true]]}, runTests);
   </script>
 </body>
 </html>
--- a/dom/messagechannel/tests/test_messageChannel_pingpong.html
+++ b/dom/messagechannel/tests/test_messageChannel_pingpong.html
@@ -66,12 +66,12 @@ https://bugzilla.mozilla.org/show_bug.cg
     div.appendChild(ifr);
 
     function iframeLoaded() {
       ifr.contentWindow.postMessage({ type: 'PORT', port: a.port2 }, '*', [a.port2]);
     }
   }
 
   SimpleTest.waitForExplicitFinish();
-  SpecialPowers.pushPrefEnv({"set": [["dom.messageChannel.enabled", true]]}, runTest);
+  runTest();
   </script>
 </body>
 </html>
--- a/dom/messagechannel/tests/test_messageChannel_post.html
+++ b/dom/messagechannel/tests/test_messageChannel_post.html
@@ -65,12 +65,12 @@ https://bugzilla.mozilla.org/show_bug.cg
         return;
       }
 
       a.port1.postMessage(tests[0]);
     }
   }
 
   SimpleTest.waitForExplicitFinish();
-  SpecialPowers.pushPrefEnv({"set": [["dom.messageChannel.enabled", true]]}, start);
+  start();
   </script>
 </body>
 </html>
deleted file mode 100644
--- a/dom/messagechannel/tests/test_messageChannel_pref.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=677638
--->
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 677638 - pref</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=677638">Mozilla Bug 677638</a>
-<div id="content"></div>
-<pre id="test">
-</pre>
-  <script type="application/javascript">
-
-  function runTest(what) {
-    var status;
-    try {
-      status = MessageChannel;
-      ok(what, "Should MessageChannel exist?");
-    } catch(e) {
-      ok(!what, "Should MessageChannel exist?");
-    }
-  }
-
-  SimpleTest.waitForExplicitFinish();
-
-  SpecialPowers.pushPrefEnv({"set": [["dom.messageChannel.enabled", false]]},
-  function() {
-    runTest(false);
-    SpecialPowers.pushPrefEnv({"set": [["dom.messageChannel.enabled", true]]},
-    function() {
-      runTest(true);
-      SimpleTest.finish();
-    });
-  });
-  </script>
-</body>
-</html>
--- a/dom/messagechannel/tests/test_messageChannel_selfTransferring.html
+++ b/dom/messagechannel/tests/test_messageChannel_selfTransferring.html
@@ -11,28 +11,23 @@ https://bugzilla.mozilla.org/show_bug.cg
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=677638">Mozilla Bug 677638</a>
 <div id="content"></div>
 <pre id="test">
 </pre>
   <script type="application/javascript">
 
-function runTest() {
   var a = new MessageChannel();
 
   var status = false;
   try {
     a.port1.postMessage('foobar', [a.port1]);
   } catch(e) {
     status =true;
   }
 
   ok(status, "Transfering the same port should throw");
-  SimpleTest.finish();
-}
 
-SimpleTest.waitForExplicitFinish();
-SpecialPowers.pushPrefEnv({"set": [["dom.messageChannel.enabled", true]]}, runTest);
   </script>
 </body>
 </html>
 
--- a/dom/messagechannel/tests/test_messageChannel_sharedWorker.html
+++ b/dom/messagechannel/tests/test_messageChannel_sharedWorker.html
@@ -15,25 +15,22 @@ https://bugzilla.mozilla.org/show_bug.cg
 <div id="content" style="display: none">
   <iframe name="x" id="x"></iframe>
   <iframe name="y" id="y"></iframe>
 </div>
 <pre id="test">
 </pre>
   <script type="application/javascript">
 
-  function runTest() {
-    var a = new SharedWorker('sharedWorker_messageChannel.js');
-    a.port.onmessage = function(evt) {
-      is(evt.ports.length, 1, "We received a port.");
-      evt.ports[0].onmessage = function(e) {
-        is(e.data, 42, "Message reiceved back!");
-        SimpleTest.finish();
-      }
-      evt.ports[0].postMessage(42);
+  var a = new SharedWorker('sharedWorker_messageChannel.js');
+  a.port.onmessage = function(evt) {
+    is(evt.ports.length, 1, "We received a port.");
+    evt.ports[0].onmessage = function(e) {
+      is(e.data, 42, "Message reiceved back!");
+      SimpleTest.finish();
     }
+    evt.ports[0].postMessage(42);
   }
 
-  SpecialPowers.pushPrefEnv({"set": [["dom.messageChannel.enabled", true]]}, runTest);
   SimpleTest.waitForExplicitFinish();
   </script>
 </body>
 </html>
--- a/dom/messagechannel/tests/test_messageChannel_sharedWorker2.html
+++ b/dom/messagechannel/tests/test_messageChannel_sharedWorker2.html
@@ -10,28 +10,25 @@ https://bugzilla.mozilla.org/show_bug.cg
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=677638">Mozilla Bug 677638</a>
   <div id="content"></div>
 
   <script type="application/javascript">
 
-  function runTest() {
-    var iframe = document.createElement('iframe');
-    iframe.setAttribute('src', "iframe_messageChannel_sharedWorker2.html");
-    document.getElementById('content').appendChild(iframe);
+  var iframe = document.createElement('iframe');
+  iframe.setAttribute('src', "iframe_messageChannel_sharedWorker2.html");
+  document.getElementById('content').appendChild(iframe);
 
-    var a = new SharedWorker('sharedWorker2_messageChannel.js');
-    a.port.onmessage = function(evt) {
-      is(evt.ports.length, 1, "We received a port.");
-      evt.ports[0].onmessage = function(e) {
-        is(e.data, "Hello from the iframe!", "Message reiceved from the iframe!");
-        SimpleTest.finish();
-      }
+  var a = new SharedWorker('sharedWorker2_messageChannel.js');
+  a.port.onmessage = function(evt) {
+    is(evt.ports.length, 1, "We received a port.");
+    evt.ports[0].onmessage = function(e) {
+      is(e.data, "Hello from the iframe!", "Message reiceved from the iframe!");
+      SimpleTest.finish();
     }
   }
 
-  SpecialPowers.pushPrefEnv({"set": [["dom.messageChannel.enabled", true]]}, runTest);
   SimpleTest.waitForExplicitFinish();
   </script>
 </body>
 </html>
--- a/dom/messagechannel/tests/test_messageChannel_start.html
+++ b/dom/messagechannel/tests/test_messageChannel_start.html
@@ -224,12 +224,12 @@ https://bugzilla.mozilla.org/show_bug.cg
     testAddEventListener2AndStart,
     testTimer,
     testAddEventListenerAndStartWrongOrder,
     testOnMessageClone,
   ];
 
   SimpleTest.waitForExplicitFinish();
   SimpleTest.requestFlakyTimeout("untriaged");
-  SpecialPowers.pushPrefEnv({"set": [["dom.messageChannel.enabled", true]]}, runTests);
+  runTests();
   </script>
 </body>
 </html>
--- a/dom/messagechannel/tests/test_messageChannel_transferable.html
+++ b/dom/messagechannel/tests/test_messageChannel_transferable.html
@@ -100,12 +100,12 @@ https://bugzilla.mozilla.org/show_bug.cg
       return;
     }
 
     var t = tests.shift();
     t();
   }
 
   SimpleTest.waitForExplicitFinish();
-  SpecialPowers.pushPrefEnv({"set": [["dom.messageChannel.enabled", true]]}, runTests);
+  runTests();
   </script>
 </body>
 </html>
--- a/dom/messagechannel/tests/test_messageChannel_unshipped.html
+++ b/dom/messagechannel/tests/test_messageChannel_unshipped.html
@@ -112,12 +112,12 @@ https://bugzilla.mozilla.org/show_bug.cg
       return;
     }
 
     var test = tests.shift();
     test();
   }
 
   SimpleTest.waitForExplicitFinish();
-  SpecialPowers.pushPrefEnv({"set": [["dom.messageChannel.enabled", true]]}, runTests);
+  runTests();
   </script>
 </body>
 </html>
--- a/dom/messagechannel/tests/test_messageChannel_worker.html
+++ b/dom/messagechannel/tests/test_messageChannel_worker.html
@@ -49,12 +49,12 @@ https://bugzilla.mozilla.org/show_bug.cg
         a.postMessage('a gift!', [ch.port2]);
       }
     }
 
     a.postMessage(tests.shift());
   }
 
   SimpleTest.waitForExplicitFinish();
-  SpecialPowers.pushPrefEnv({"set": [["dom.messageChannel.enabled", true]]}, runTests);
+  runTests();
   </script>
 </body>
 </html>
--- a/dom/nfc/nsNfc.js
+++ b/dom/nfc/nsNfc.js
@@ -32,21 +32,18 @@ function NfcCallback(aWindow) {
 NfcCallback.prototype = {
   __proto__: DOMRequestIpcHelper.prototype,
 
   _window: null,
   promise: null,
   _requestId: null,
 
   _createPromise: function _createPromise() {
-    this.promise = this.createPromise((aResolve, aReject) => {
-      this._requestId = btoa(this.getPromiseResolverId({
-        resolve: aResolve,
-        reject: aReject
-      }));
+    this.promise = this.createPromiseWithId((aResolverId) => {
+      this._requestId = btoa(aResolverId);
     });
   },
 
   getCallbackId: function getCallbackId() {
     return this._requestId;
   },
 
   notifySuccess: function notifySuccess() {
--- a/dom/presentation/PresentationDeviceInfoManager.js
+++ b/dom/presentation/PresentationDeviceInfoManager.js
@@ -99,20 +99,19 @@ PresentationDeviceInfoManager.prototype 
 
   set ondevicechange(aHandler) {
     this.__DOM_IMPL__.setEventHandler("ondevicechange", aHandler);
   },
 
   getAll: function() {
     log("getAll");
     let self = this;
-    return this.createPromise(function(aResolve, aReject) {
-      let resolverId = self.getPromiseResolverId({ resolve: aResolve, reject: aReject });
+    return this.createPromiseWithId(function(aResolverId) {
       cpmm.sendAsyncMessage("PresentationDeviceInfoManager:GetAll", {
-        requestId: resolverId,
+        requestId: aResolverId,
       });
     });
   },
 
   forceDiscovery: function() {
     cpmm.sendAsyncMessage("PresentationDeviceInfoManager:ForceDiscovery");
   },
 };
--- a/dom/quota/QuotaManager.cpp
+++ b/dom/quota/QuotaManager.cpp
@@ -87,16 +87,22 @@
 #define KB * 1024ULL
 #define MB * 1024ULL KB
 #define GB * 1024ULL MB
 
 namespace mozilla {
 namespace dom {
 namespace quota {
 
+// We want profiles to be platform-independent so we always need to replace
+// the same characters on every platform. Windows has the most extensive set
+// of illegal characters so we use its FILE_ILLEGAL_CHARACTERS and
+// FILE_PATH_SEPARATOR.
+const char QuotaManager::kReplaceChars[] = CONTROL_CHARACTERS "/:*?\"<>|\\";
+
 namespace {
 
 /*******************************************************************************
  * Constants
  ******************************************************************************/
 
 static_assert(
   static_cast<uint32_t>(StorageType::Persistent) ==
@@ -1070,29 +1076,24 @@ public:
     Append(':');
     Append(aOrigin);
   }
 };
 
 void
 SanitizeOriginString(nsCString& aOrigin)
 {
-  // We want profiles to be platform-independent so we always need to replace
-  // the same characters on every platform. Windows has the most extensive set
-  // of illegal characters so we use its FILE_ILLEGAL_CHARACTERS and
-  // FILE_PATH_SEPARATOR.
-  static const char kReplaceChars[] = CONTROL_CHARACTERS "/:*?\"<>|\\";
 
 #ifdef XP_WIN
-  NS_ASSERTION(!strcmp(kReplaceChars,
+  NS_ASSERTION(!strcmp(QuotaManager::kReplaceChars,
                        FILE_ILLEGAL_CHARACTERS FILE_PATH_SEPARATOR),
                "Illegal file characters have changed!");
 #endif
 
-  aOrigin.ReplaceChar(kReplaceChars, '+');
+  aOrigin.ReplaceChar(QuotaManager::kReplaceChars, '+');
 }
 
 bool
 IsTreatedAsPersistent(PersistenceType aPersistenceType,
                       bool aIsApp)
 {
   if (aPersistenceType == PERSISTENCE_TYPE_PERSISTENT ||
       (aPersistenceType == PERSISTENCE_TYPE_DEFAULT && aIsApp)) {
--- a/dom/quota/QuotaManager.h
+++ b/dom/quota/QuotaManager.h
@@ -119,16 +119,18 @@ class QuotaManager final : public nsIQuo
   typedef nsClassHashtable<nsCStringHashKey,
                            nsTArray<DirectoryLockImpl*>> DirectoryLockTable;
 
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIQUOTAMANAGER
   NS_DECL_NSIOBSERVER
 
+  static const char kReplaceChars[];
+
   // Returns a non-owning reference.
   static QuotaManager*
   GetOrCreate();
 
   // Returns a non-owning reference.
   static QuotaManager*
   Get();
 
--- a/dom/requestsync/RequestSyncManager.js
+++ b/dom/requestsync/RequestSyncManager.js
@@ -41,19 +41,18 @@ RequestSyncManager.prototype = {
     debug("init");
 
     // DOMRequestIpcHelper.initHelper sets this._window
     this.initDOMRequestHelper(aWindow, this._messages);
   },
 
   sendMessage: function(aMsg, aObj) {
     let self = this;
-    return this.createPromise(function(aResolve, aReject) {
-      aObj.requestID =
-        self.getPromiseResolverId({ resolve: aResolve, reject: aReject });
+    return this.createPromiseWithId(function(aResolverId) {
+      aObj.requestID = aResolverId;
       cpmm.sendAsyncMessage(aMsg, aObj, null,
                             self._window.document.nodePrincipal);
     });
   },
 
   registrations: function() {
     debug('registrations');
     return this.sendMessage("RequestSyncManager:Registrations", {});
--- a/dom/requestsync/RequestSyncScheduler.js
+++ b/dom/requestsync/RequestSyncScheduler.js
@@ -63,19 +63,18 @@ RequestSyncScheduler.prototype = {
   registration: function(aTask) {
     debug('registration');
     return this.sendMessage('RequestSync:Registration',
                             { task: aTask });
   },
 
   sendMessage: function(aMsg, aObj) {
     let self = this;
-    return this.createPromise(function(aResolve, aReject) {
-      aObj.requestID =
-        self.getPromiseResolverId({ resolve: aResolve, reject: aReject });
+    return this.createPromiseWithId(function(aResolverId) {
+      aObj.requestID = aResolverId;
       cpmm.sendAsyncMessage(aMsg, aObj, null,
                             self._window.document.nodePrincipal);
     });
   },
 
   receiveMessage: function(aMessage) {
     debug('receiveMessage');
 
--- a/dom/resourcestats/ResourceStatsManager.js
+++ b/dom/resourcestats/ResourceStatsManager.js
@@ -141,28 +141,16 @@ function ResourceStatsManager() {
   if (DEBUG) {
     debug("constructor()");
   }
 }
 
 ResourceStatsManager.prototype = {
   __proto__: DOMRequestIpcHelper.prototype,
 
-  _getPromise: function(aCallback) {
-    let self = this;
-    return this.createPromise(function(aResolve, aReject) {
-      let resolverId = self.getPromiseResolverId({
-        resolve: aResolve,
-        reject: aReject
-      });
-
-      aCallback(resolverId);
-    });
-  },
-
   // Check time range.
   _checkTimeRange: function(aStart, aEnd) {
     if (DEBUG) {
       debug("_checkTimeRange(): " + aStart + " to " + aEnd);
     }
 
     let start = aStart ? aStart : 0;
     let end = aEnd ? aEnd : Date.now();
@@ -175,17 +163,17 @@ ResourceStatsManager.prototype = {
   },
 
   getStats: function(aStatsOptions, aStart, aEnd) {
     // Check time range.
     let { start: start, end: end } = this._checkTimeRange(aStart, aEnd);
 
     // Create Promise.
     let self = this;
-    return this._getPromise(function(aResolverId) {
+    return this.createPromiseWithId(function(aResolverId) {
       self.cpmm.sendAsyncMessage("ResourceStats:GetStats", {
         resolverId: aResolverId,
         type: self.type,
         statsOptions: aStatsOptions,
         manifestURL: self._manifestURL,
         start: start,
         end: end
       });
@@ -193,32 +181,32 @@ ResourceStatsManager.prototype = {
   },
 
   clearStats: function(aStatsOptions, aStart, aEnd) {
     // Check time range.
     let {start: start, end: end} = this._checkTimeRange(aStart, aEnd);
 
     // Create Promise.
     let self = this;
-    return this._getPromise(function(aResolverId) {
+    return this.createPromiseWithId(function(aResolverId) {
       self.cpmm.sendAsyncMessage("ResourceStats:ClearStats", {
         resolverId: aResolverId,
         type: self.type,
         statsOptions: aStatsOptions,
         manifestURL: self._manifestURL,
         start: start,
         end: end
       });
     });
   },
 
   clearAllStats: function() {
     // Create Promise.
     let self = this;
-    return this._getPromise(function(aResolverId) {
+    return this.createPromiseWithId(function(aResolverId) {
       self.cpmm.sendAsyncMessage("ResourceStats:ClearAllStats", {
         resolverId: aResolverId,
         type: self.type,
         manifestURL: self._manifestURL
       });
     });
   },
 
@@ -234,71 +222,71 @@ ResourceStatsManager.prototype = {
     // Clone data object using structured clone algorithm.
     let data = null;
     if (aAlarmOptions.data) {
       data = Cu.cloneInto(aAlarmOptions.data, this._window);
     }
 
     // Create Promise.
     let self = this;
-    return this._getPromise(function(aResolverId) {
+    return this.createPromiseWithId(function(aResolverId) {
       self.cpmm.sendAsyncMessage("ResourceStats:AddAlarm", {
         resolverId: aResolverId,
         type: self.type,
         threshold: aThreshold,
         statsOptions: aStatsOptions,
         manifestURL: self._manifestURL,
         startTime: startTime,
         data: data
       });
     });
   },
 
   getAlarms: function(aStatsOptions) {
     // Create Promise.
     let self = this;
-    return this._getPromise(function(aResolverId) {
+    return this.createPromiseWithId(function(aResolverId) {
       self.cpmm.sendAsyncMessage("ResourceStats:GetAlarms", {
         resolverId: aResolverId,
         type: self.type,
         statsOptions: aStatsOptions,
         manifestURL: self._manifestURL
       });
     });
   },
 
   removeAlarm: function(aAlarmId) {
     // Create Promise.
     let self = this;
-    return this._getPromise(function(aResolverId) {
+    return this.createPromiseWithId(function(aResolverId) {
       self.cpmm.sendAsyncMessage("ResourceStats:RemoveAlarm", {
         resolverId: aResolverId,
         type: self.type,
         manifestURL: self._manifestURL,
         alarmId: aAlarmId
       });
     });
   },
 
   removeAllAlarms: function() {
     // Create Promise.
     let self = this;
-    return this._getPromise(function(aResolverId) {
+    return this.createPromiseWithId(function(aResolverId) {
       self.cpmm.sendAsyncMessage("ResourceStats:RemoveAllAlarms", {
         resolverId: aResolverId,
         type: self.type,
         manifestURL: self._manifestURL
       });
     });
   },
 
   getAvailableComponents: function() {
     // Create Promise.
     let self = this;
-    return this._getPromise(function(aResolverId) {
+    return this.createPromiseWithId(function(aResolverId) {
       self.cpmm.sendAsyncMessage("ResourceStats:GetComponents", {
         resolverId: aResolverId,
         type: self.type,
         manifestURL: self._manifestURL
       });
     });
   },
 
--- a/dom/secureelement/DOMSecureElement.js
+++ b/dom/secureelement/DOMSecureElement.js
@@ -57,22 +57,18 @@ PromiseHelpersSubclass.prototype = {
     let ctxCallback = (resolverId) => {
       if (ctx) {
         this._context[resolverId] = ctx;
       }
 
       callback(resolverId);
     };
 
-    return this.createPromise((resolve, reject) => {
-      let resolverId = this.getPromiseResolverId({
-        resolve: resolve,
-        reject: reject
-      });
-      ctxCallback(resolverId);
+    return this.createPromiseWithId((aResolverId) => {
+      ctxCallback(aResolverId);
     });
   },
 
   takePromise: function takePromise(resolverId) {
     let resolver = this.takePromiseResolver(resolverId);
     if (!resolver) {
       return;
     }
--- a/dom/system/SystemUpdateManager.js
+++ b/dom/system/SystemUpdateManager.js
@@ -220,43 +220,34 @@ SystemUpdateManager.prototype = {
     let self = this;
 
     this.forEachPromiseResolver(function(aKey) {
       self.takePromiseResolver(aKey).reject("SystemUpdateManager got destroyed");
     });
   },
 
   getProviders: function() {
-    return this._sendPromise(function(aResolverId) {
+    return this.createPromiseWithId(function(aResolverId) {
       cpmm.sendAsyncMessage("SystemUpdate:GetProviders", {
         requestId: aResolverId,
       });
     });
   },
 
   getActiveProvider: function() {
-    return this._sendPromise(function(aResolverId) {
+    return this.createPromiseWithId(function(aResolverId) {
       cpmm.sendAsyncMessage("SystemUpdate:GetActiveProvider", {
         requestId: aResolverId,
       });
     });
   },
 
   setActiveProvider: function(aUuid) {
-    return this._sendPromise(function(aResolverId) {
+    return this.createPromiseWithId(function(aResolverId) {
       cpmm.sendAsyncMessage("SystemUpdate:SetActiveProvider", {
         requestId: aResolverId,
         uuid: aUuid
       });
     });
-  },
-
-  _sendPromise: function(aCallback) {
-    let self = this;
-    return this.createPromise(function(aResolve, aReject) {
-      let resolverId = self.getPromiseResolverId({resolve: aResolve,
-                                                  reject: aReject});
-      aCallback(resolverId);
-    });
   }
 };
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SystemUpdateManager]);
--- a/dom/tethering/TetheringManager.js
+++ b/dom/tethering/TetheringManager.js
@@ -35,29 +35,16 @@ TetheringManager.prototype = {
                                          Ci.nsIObserver]),
 
   init: function(aWindow) {
     const messages = ["WifiManager:setWifiTethering:Return:OK",
                       "WifiManager:setWifiTethering:Return:NO"];
     this.initDOMRequestHelper(aWindow, messages);
   },
 
-  _getPromise: function(aCallback) {
-    let self = this;
-
-    return this.createPromise(function(aResolve, aReject) {
-      let resolverId = self.getPromiseResolverId({
-        resolve: aResolve,
-        reject: aReject
-      });
-
-      aCallback(resolverId);
-    });
-  },
-
   // TODO : aMessage format may be different after supporting bt/usb.
   //        for now, use wifi format first.
   receiveMessage: function(aMessage) {
     let data = aMessage.data.data;
 
     let resolver = this.takePromiseResolver(data.resolverId);
     if (!resolver) {
       return;
@@ -72,25 +59,25 @@ TetheringManager.prototype = {
         break;
     }
   },
 
   setTetheringEnabled: function setTetheringEnabled(aEnabled, aType, aConfig) {
     let self = this;
     switch (aType) {
       case TETHERING_TYPE_WIFI:
-        return this._getPromise(function(aResolverId) {
+        return this.createPromiseWithId(function(aResolverId) {
           let data = { resolverId: aResolverId, enabled: aEnabled, config: aConfig };
           cpmm.sendAsyncMessage("WifiManager:setWifiTethering", { data: data});
         });
       case TETHERING_TYPE_BLUETOOTH:
       case TETHERING_TYPE_USB:
       default:
         debug("tethering type(" + aType + ") doesn't support");
-        return this._getPromise(function(aResolverId) {
+        return this.createPromiseWithId(function(aResolverId) {
           self.takePromiseResolver(aResolverId).reject();
         });
     }
   },
 };
 
 this.NSGetFactory =
   XPCOMUtils.generateNSGetFactory([TetheringManager]);
--- a/dom/webidl/MessageChannel.webidl
+++ b/dom/webidl/MessageChannel.webidl
@@ -2,14 +2,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/.
  *
  * For more information on this interface, please see
  * http://www.whatwg.org/specs/web-apps/current-work/#channel-messaging
  */
 
-[Constructor, Func="MessageChannel::Enabled",
- Exposed=(Window,Worker)]
+[Constructor, Exposed=(Window,Worker)]
 interface MessageChannel {
   readonly attribute MessagePort port1;
   readonly attribute MessagePort port2;
 };
--- a/dom/workers/test/serviceworkers/test_installation_simple.html
+++ b/dom/workers/test/serviceworkers/test_installation_simple.html
@@ -197,17 +197,16 @@
         SimpleTest.finish();
       });
   }
 
   SimpleTest.waitForExplicitFinish();
   SpecialPowers.pushPrefEnv({"set": [
     ["dom.serviceWorkers.exemptFromPerDomainMax", true],
     ["dom.serviceWorkers.interception.enabled", true],
-    ["dom.messageChannel.enabled", true],
     ["dom.serviceWorkers.enabled", true],
     ["dom.serviceWorkers.testing.enabled", true],
     ["dom.caches.testing.enabled", true],
   ]}, runTest);
 </script>
 </pre>
 </body>
 </html>
--- a/editor/reftests/xul/reftest.list
+++ b/editor/reftests/xul/reftest.list
@@ -1,29 +1,29 @@
 fails-if(Android||B2G) skip-if((B2G&&browserIsRemote)||Mulet) == empty-1.xul empty-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if((B2G&&browserIsRemote)||Mulet) != empty-2.xul empty-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
-# There is no way to simulate an autocomplete textbox in windows XP/Vista/7 default theme using CSS.
+# There is no way to simulate an autocomplete textbox in windows XP/Vista/7/8/10 default theme using CSS.
 # Therefore, the equlity tests below should be marked as failing.
-fails-if(Android||B2G) fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(5\.[12]|6\.[012])/.test(http.oscpu)) skip-if((B2G&&browserIsRemote)||Mulet) == autocomplete-1.xul autocomplete-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
-fails-if(Android||B2G) fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(5\.[12]|6\.[012])/.test(http.oscpu)) skip-if((B2G&&browserIsRemote)||Mulet) == emptyautocomplete-1.xul emptyautocomplete-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
+fails-if(Android||B2G) fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(5\.[12]|6\.[012]|10\.0)/.test(http.oscpu)) skip-if((B2G&&browserIsRemote)||Mulet) == autocomplete-1.xul autocomplete-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
+fails-if(Android||B2G) fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(5\.[12]|6\.[012]|10\.0)/.test(http.oscpu)) skip-if((B2G&&browserIsRemote)||Mulet) == emptyautocomplete-1.xul emptyautocomplete-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if((B2G&&browserIsRemote)||Mulet) != emptymultiline-1.xul emptymultiline-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
 fails-if(Android||B2G) skip-if((B2G&&browserIsRemote)||Mulet) == emptymultiline-2.xul emptymultiline-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
 fails-if(Android||B2G) skip-if((B2G&&browserIsRemote)||Mulet) == emptytextbox-1.xul emptytextbox-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
 fails-if(Android||B2G) skip-if((B2G&&browserIsRemote)||Mulet) == emptytextbox-2.xul emptytextbox-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if((B2G&&browserIsRemote)||Mulet) != emptytextbox-3.xul emptytextbox-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if((B2G&&browserIsRemote)||Mulet) != emptytextbox-4.xul emptytextbox-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
 fails-if(Android||B2G) skip-if((B2G&&browserIsRemote)||Mulet) == emptytextbox-5.xul emptytextbox-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
 # There is no way to simulate a number textbox in windows XP/Vista/7 default theme using CSS.
 # Therefore, the equlity tests below should be marked as failing.
 skip-if((B2G&&browserIsRemote)||Mulet) != number-1.xul number-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if((B2G&&browserIsRemote)||Mulet) != number-2.xul number-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
-fails-if(Android||B2G) fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(5\.[12]|6\.[012])/.test(http.oscpu)) skip-if((B2G&&browserIsRemote)||Mulet) == number-3.xul number-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
+fails-if(Android||B2G) fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(5\.[12]|6\.[012]|10\.0)/.test(http.oscpu)) skip-if((B2G&&browserIsRemote)||Mulet) == number-3.xul number-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if((B2G&&browserIsRemote)||Mulet) != number-4.xul number-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
-fails-if(Android||B2G) fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(5\.[12]|6\.[012])/.test(http.oscpu)) skip-if((B2G&&browserIsRemote)||Mulet) == number-5.xul number-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
-fails-if(Android||B2G) fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(5\.[12]|6\.[012])/.test(http.oscpu)) skip-if((B2G&&browserIsRemote)||Mulet) == numberwithvalue-1.xul numberwithvalue-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
+fails-if(Android||B2G) fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(5\.[12]|6\.[012]|10\.0)/.test(http.oscpu)) skip-if((B2G&&browserIsRemote)||Mulet) == number-5.xul number-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
+fails-if(Android||B2G) fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(5\.[12]|6\.[012]|10\.0)/.test(http.oscpu)) skip-if((B2G&&browserIsRemote)||Mulet) == numberwithvalue-1.xul numberwithvalue-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
 fails-if(Android||B2G) skip-if((B2G&&browserIsRemote)||Mulet) == passwd-1.xul passwd-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
 fails-if(Android||B2G) skip-if((B2G&&browserIsRemote)||Mulet) == passwd-2.xul passwd-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if((B2G&&browserIsRemote)||Mulet) != passwd-3.xul passwd-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
 fails-if(Android||B2G) skip-if((B2G&&browserIsRemote)||Mulet) == plain-1.xul plain-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
 fails-if(Android||B2G) skip-if((B2G&&browserIsRemote)||Mulet) == textbox-1.xul textbox-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if((B2G&&browserIsRemote)||Mulet) != textbox-disabled.xul textbox-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
 # Read-only textboxes look like normal textboxes in windows Vista/7 default theme
-fails-if(windowsDefaultTheme&&/^Windows\x20NT\x206\.[012]/.test(http.oscpu)) skip-if((B2G&&browserIsRemote)||Mulet) != textbox-readonly.xul textbox-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
+fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(6\.[012]|10\.0)/.test(http.oscpu)) skip-if((B2G&&browserIsRemote)||Mulet) != textbox-readonly.xul textbox-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -2078,19 +2078,19 @@ UpdatePluginWindowState(uint64_t aId)
   CompositorParent::LayerTreeState& lts = sIndirectLayerTrees[aId];
   if (!lts.mPluginData.Length() && !lts.mUpdatedPluginDataAvailable) {
     return;
   }
 
   bool shouldComposePlugin = !!lts.mRoot &&
                              !!lts.mRoot->GetParent();
 
-  bool shouldHidePlugin = (!lts.mRoot ||
-                           !lts.mRoot->GetParent()) &&
-                          !lts.mUpdatedPluginDataAvailable;
+  bool shouldHidePlugin = !lts.mRoot ||
+                          !lts.mRoot->GetParent();
+
   if (shouldComposePlugin) {
     if (!lts.mPluginData.Length()) {
       // We will pass through here in cases where the previous shadow layer
       // tree contained visible plugins and the new tree does not. All we need
       // to do here is hide the plugins for the old tree, so don't waste time
       // calculating clipping.
       nsTArray<uintptr_t> aVisibleIdList;
       uintptr_t parentWidget = (uintptr_t)lts.mParent->GetWidget();
--- a/gfx/layers/ipc/ImageBridgeChild.cpp
+++ b/gfx/layers/ipc/ImageBridgeChild.cpp
@@ -183,17 +183,20 @@ static void ImageBridgeShutdownStep1(Ree
     InfallibleTArray<PCompositableChild*> compositables;
     sImageBridgeChildSingleton->ManagedPCompositableChild(compositables);
     for (int i = compositables.Length() - 1; i >= 0; --i) {
       CompositableClient::FromIPDLActor(compositables[i])->Destroy();
     }
     InfallibleTArray<PTextureChild*> textures;
     sImageBridgeChildSingleton->ManagedPTextureChild(textures);
     for (int i = textures.Length() - 1; i >= 0; --i) {
-      TextureClient::AsTextureClient(textures[i])->ForceRemove();
+      TextureClient* client = TextureClient::AsTextureClient(textures[i]);
+      if (client) {
+        client->ForceRemove();
+      }
     }
     sImageBridgeChildSingleton->SendWillStop();
     sImageBridgeChildSingleton->MarkShutDown();
     // From now on, no message can be sent through the image bridge from the
     // client side except the final Stop message.
   }
 
   *aDone = true;
--- a/gfx/tests/gtest/TestGfxWidgets.cpp
+++ b/gfx/tests/gtest/TestGfxWidgets.cpp
@@ -22,16 +22,45 @@ TEST(GfxWidgets, Split) {
   ASSERT_TRUE(atoi(aStr) == 132 && atoi(bStr) == 0 && atoi(cStr) == 0 && atoi(dStr) == 0);
 
   ASSERT_TRUE(SplitDriverVersion("2.3.0.0", aStr, bStr, cStr, dStr));
   ASSERT_TRUE(atoi(aStr) == 2 && atoi(bStr) == 3 && atoi(cStr) == 0 && atoi(dStr) == 0);
 
   ASSERT_TRUE(SplitDriverVersion("25.4.0.8", aStr, bStr, cStr, dStr));
   ASSERT_TRUE(atoi(aStr) == 25 && atoi(bStr) == 4 && atoi(cStr) == 0 && atoi(dStr) == 8);
 
+  ASSERT_TRUE(SplitDriverVersion("424.143.84437.3", aStr, bStr, cStr, dStr));
+  ASSERT_TRUE(atoi(aStr) == 424 && atoi(bStr) == 143 && atoi(cStr) == 8443 && atoi(dStr) == 3);
+
+  ASSERT_FALSE(SplitDriverVersion("25.4.0.8.", aStr, bStr, cStr, dStr));
+  ASSERT_TRUE(atoi(aStr) == 25 && atoi(bStr) == 4 && atoi(cStr) == 0 && atoi(dStr) == 8);
+
+  ASSERT_TRUE(SplitDriverVersion("424.143.8.3143243", aStr, bStr, cStr, dStr));
+  ASSERT_TRUE(atoi(aStr) == 424 && atoi(bStr) == 143 && atoi(cStr) == 8 && atoi(dStr) == 3143);
+
+  ASSERT_FALSE(SplitDriverVersion("25.4.0.8..", aStr, bStr, cStr, dStr));
+  ASSERT_TRUE(atoi(aStr) == 25 && atoi(bStr) == 4 && atoi(cStr) == 0 && atoi(dStr) == 8);
+
+  ASSERT_FALSE(SplitDriverVersion("424.143.8.3143243.", aStr, bStr, cStr, dStr));
+  ASSERT_TRUE(atoi(aStr) == 424 && atoi(bStr) == 143 && atoi(cStr) == 8 && atoi(dStr) == 3143);
+
+  ASSERT_FALSE(SplitDriverVersion("25.4.0.8.13", aStr, bStr, cStr, dStr));
+  ASSERT_TRUE(atoi(aStr) == 25 && atoi(bStr) == 4 && atoi(cStr) == 0 && atoi(dStr) == 8);
+
+  ASSERT_FALSE(SplitDriverVersion("4.1.8.13.24.35", aStr, bStr, cStr, dStr));
+  ASSERT_TRUE(atoi(aStr) == 4 && atoi(bStr) == 1 && atoi(cStr) == 8 && atoi(dStr) == 13);
+
+  ASSERT_TRUE(SplitDriverVersion("28...74", aStr, bStr, cStr, dStr));
+  ASSERT_TRUE(atoi(aStr) == 28 && atoi(bStr) == 0 && atoi(cStr) == 0 && atoi(dStr) == 74);
+
+  ASSERT_FALSE(SplitDriverVersion("4.1.8.13.24.35", aStr, bStr, cStr, dStr));
+  ASSERT_TRUE(atoi(aStr) == 4 && atoi(bStr) == 1 && atoi(cStr) == 8 && atoi(dStr) == 13);
+
+  ASSERT_TRUE(SplitDriverVersion("35..42.0", aStr, bStr, cStr, dStr));
+  ASSERT_TRUE(atoi(aStr) == 35 && atoi(bStr) == 0 && atoi(cStr) == 42 && atoi(dStr) == 0);
 }
 
 TEST(GfxWidgets, Versioning) {
   ASSERT_TRUE(mozilla::Version("0") < mozilla::Version("41.0a1"));
   ASSERT_TRUE(mozilla::Version("39.0.5b7") < mozilla::Version("41.0a1"));
   ASSERT_TRUE(mozilla::Version("18.0.5b7") < mozilla::Version("18.2"));
   ASSERT_TRUE(mozilla::Version("30.0.5b7") < mozilla::Version("41.0b9"));
   ASSERT_TRUE(mozilla::Version("100") > mozilla::Version("43.0a1"));
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -240,16 +240,17 @@ private:
   DECL_GFX_PREF(Once, "gfx.logging.crash.length",              GfxLoggingCrashLength, uint32_t, 6);
   DECL_GFX_PREF(Live, "gfx.perf-warnings.enabled",             PerfWarnings, bool, false);
   DECL_GFX_PREF(Live, "gfx.testing.device-reset",              DeviceResetForTesting, int32_t, 0);
   DECL_GFX_PREF(Live, "gfx.testing.device-fail",               DeviceFailForTesting, bool, false);
 
   // These times should be in milliseconds
   DECL_GFX_PREF(Once, "gfx.touch.resample.delay-threshold",    TouchResampleVsyncDelayThreshold, int32_t, 20);
   DECL_GFX_PREF(Once, "gfx.touch.resample.max-predict",        TouchResampleMaxPredict, int32_t, 8);
+  DECL_GFX_PREF(Once, "gfx.touch.resample.min-delta",          TouchResampleMinDelta, int32_t, 2);
   DECL_GFX_PREF(Once, "gfx.touch.resample.old-touch-threshold",TouchResampleOldTouchThreshold, int32_t, 17);
   DECL_GFX_PREF(Once, "gfx.touch.resample.vsync-adjust",       TouchVsyncSampleAdjust, int32_t, 5);
 
   DECL_GFX_PREF(Once, "gfx.vr.mirror-textures",                VRMirrorTextures, bool, false);
 
   DECL_GFX_PREF(Live, "gfx.vsync.collect-scroll-transforms",   CollectScrollTransforms, bool, false);
   DECL_GFX_PREF(Once, "gfx.vsync.compositor",                  VsyncAlignedCompositor, bool, false);
   // On b2g, in really bad cases, I've seen up to 80 ms delays between touch events and the main thread
--- a/image/Decoder.cpp
+++ b/image/Decoder.cpp
@@ -85,25 +85,28 @@ Decoder::Init()
 
   // Implementation-specific initialization
   InitInternal();
 
   mInitialized = true;
 }
 
 nsresult
-Decoder::Decode()
+Decoder::Decode(IResumable* aOnResume)
 {
   MOZ_ASSERT(mInitialized, "Should be initialized here");
   MOZ_ASSERT(mIterator, "Should have a SourceBufferIterator");
 
+  // If no IResumable was provided, default to |this|.
+  IResumable* onResume = aOnResume ? aOnResume : this;
+
   // We keep decoding chunks until the decode completes or there are no more
   // chunks available.
   while (!GetDecodeDone() && !HasError()) {
-    auto newState = mIterator->AdvanceOrScheduleResume(this);
+    auto newState = mIterator->AdvanceOrScheduleResume(onResume);
 
     if (newState == SourceBufferIterator::WAITING) {
       // We can't continue because the rest of the data hasn't arrived from the
       // network yet. We don't have to do anything special; the
       // SourceBufferIterator will ensure that Decode() gets called again on a
       // DecodePool thread when more data is available.
       return NS_OK;
     }
--- a/image/Decoder.h
+++ b/image/Decoder.h
@@ -31,23 +31,26 @@ public:
   explicit Decoder(RasterImage* aImage);
 
   /**
    * Initialize an image decoder. Decoders may not be re-initialized.
    */
   void Init();
 
   /**
-   * Decodes, reading all data currently available in the SourceBuffer. If more
-   * data is needed, Decode() automatically ensures that it will be called again
-   * on a DecodePool thread when the data becomes available.
+   * Decodes, reading all data currently available in the SourceBuffer.
+   *
+   * If more data is needed, Decode() will schedule @aOnResume to be called when
+   * more data is available. If @aOnResume is null or unspecified, the default
+   * implementation resumes decoding on a DecodePool thread. Most callers should
+   * use the default implementation.
    *
    * Any errors are reported by setting the appropriate state on the decoder.
    */
-  nsresult Decode();
+  nsresult Decode(IResumable* aOnResume = nullptr);
 
   /**
    * Given a maximum number of bytes we're willing to decode, @aByteLimit,
    * returns true if we should attempt to run this decoder synchronously.
    */
   bool ShouldSyncDecode(size_t aByteLimit);
 
   /**
--- a/image/SourceBuffer.cpp
+++ b/image/SourceBuffer.cpp
@@ -208,20 +208,16 @@ SourceBuffer::FibonacciCapacityWithMinim
 
 void
 SourceBuffer::AddWaitingConsumer(IResumable* aConsumer)
 {
   mMutex.AssertCurrentThreadOwns();
 
   MOZ_ASSERT(!mStatus, "Waiting when we're complete?");
 
-  if (MOZ_UNLIKELY(NS_IsMainThread())) {
-    NS_WARNING("SourceBuffer consumer on the main thread needed to wait");
-  }
-
   mWaitingConsumers.AppendElement(aConsumer);
 }
 
 void
 SourceBuffer::ResumeWaitingConsumers()
 {
   mMutex.AssertCurrentThreadOwns();
 
new file mode 100644
--- /dev/null
+++ b/image/test/gtest/TestDecoders.cpp
@@ -0,0 +1,249 @@
+/* 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 "gtest/gtest.h"
+
+#include "Common.h"
+#include "Decoder.h"
+#include "DecoderFactory.h"
+#include "decoders/nsBMPDecoder.h"
+#include "imgIContainer.h"
+#include "imgITools.h"
+#include "ImageFactory.h"
+#include "mozilla/gfx/2D.h"
+#include "nsComponentManagerUtils.h"
+#include "nsCOMPtr.h"
+#include "nsIInputStream.h"
+#include "nsIRunnable.h"
+#include "nsIThread.h"
+#include "mozilla/nsRefPtr.h"
+#include "nsStreamUtils.h"
+#include "nsString.h"
+#include "nsThreadUtils.h"
+#include "ProgressTracker.h"
+#include "SourceBuffer.h"
+
+using namespace mozilla;
+using namespace mozilla::gfx;
+using namespace mozilla::image;
+
+TEST(ImageDecoders, ImageModuleAvailable)
+{
+  // We can run into problems if XPCOM modules get initialized in the wrong
+  // order. It's important that this test run first, both as a sanity check and
+  // to ensure we get the module initialization order we want.
+  nsCOMPtr<imgITools> imgTools =
+    do_CreateInstance("@mozilla.org/image/tools;1");
+  EXPECT_TRUE(imgTools != nullptr);
+}
+
+static void
+CheckDecoderResults(const ImageTestCase& aTestCase, Decoder* aDecoder)
+{
+  EXPECT_TRUE(aDecoder->GetDecodeDone());
+  EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_HAS_ERROR),
+            aDecoder->HasError());
+  EXPECT_TRUE(!aDecoder->WasAborted());
+
+  // Verify that the decoder made the expected progress.
+  Progress progress = aDecoder->TakeProgress();
+  EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_HAS_ERROR),
+            bool(progress & FLAG_HAS_ERROR));
+
+  if (aTestCase.mFlags & TEST_CASE_HAS_ERROR) {
+    return;  // That's all we can check for bad images.
+  }
+
+  EXPECT_TRUE(bool(progress & FLAG_SIZE_AVAILABLE));
+  EXPECT_TRUE(bool(progress & FLAG_DECODE_COMPLETE));
+  EXPECT_TRUE(bool(progress & FLAG_FRAME_COMPLETE));
+  EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_IS_TRANSPARENT),
+            bool(progress & FLAG_HAS_TRANSPARENCY));
+  EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_IS_ANIMATED),
+            bool(progress & FLAG_IS_ANIMATED));
+
+  // The decoder should get the correct size.
+  IntSize size = aDecoder->GetSize();
+  EXPECT_EQ(aTestCase.mSize.width, size.width);
+  EXPECT_EQ(aTestCase.mSize.height, size.height);
+
+  // Get the current frame, which is always the first frame of the image
+  // because CreateAnonymousDecoder() forces a first-frame-only decode.
+  RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
+  nsRefPtr<SourceSurface> surface = currentFrame->GetSurface();
+
+  // Verify that the resulting surfaces matches our expectations.
+  EXPECT_EQ(SurfaceType::DATA, surface->GetType());
+  EXPECT_TRUE(surface->GetFormat() == SurfaceFormat::B8G8R8X8 ||
+              surface->GetFormat() == SurfaceFormat::B8G8R8A8);
+  EXPECT_EQ(aTestCase.mSize, surface->GetSize());
+  EXPECT_TRUE(IsSolidColor(surface, BGRAColor::Green(),
+                           aTestCase.mFlags & TEST_CASE_IS_FUZZY));
+}
+
+static void
+CheckDecoderSingleChunk(const ImageTestCase& aTestCase)
+{
+  nsCOMPtr<nsIInputStream> inputStream = LoadFile(aTestCase.mPath);
+  ASSERT_TRUE(inputStream != nullptr);
+
+  // Figure out how much data we have.
+  uint64_t length;
+  nsresult rv = inputStream->Available(&length);
+  ASSERT_TRUE(NS_SUCCEEDED(rv));
+
+  // Write the data into a SourceBuffer.
+  nsRefPtr<SourceBuffer> sourceBuffer = new SourceBuffer();
+  sourceBuffer->ExpectLength(length);
+  rv = sourceBuffer->AppendFromInputStream(inputStream, length);
+  ASSERT_TRUE(NS_SUCCEEDED(rv));
+  sourceBuffer->Complete(NS_OK);
+
+  // Create a decoder.
+  DecoderType decoderType =
+    DecoderFactory::GetDecoderType(aTestCase.mMimeType);
+  nsRefPtr<Decoder> decoder =
+    DecoderFactory::CreateAnonymousDecoder(decoderType, sourceBuffer,
+                                           DefaultSurfaceFlags());
+  ASSERT_TRUE(decoder != nullptr);
+
+  // Run the full decoder synchronously.
+  decoder->Decode();
+  
+  CheckDecoderResults(aTestCase, decoder);
+}
+
+class NoResume : public IResumable
+{
+public:
+  NS_INLINE_DECL_REFCOUNTING(NoResume, override)
+  virtual void Resume() override { }
+
+private:
+  ~NoResume() { }
+};
+
+static void
+CheckDecoderMultiChunk(const ImageTestCase& aTestCase)
+{
+  nsCOMPtr<nsIInputStream> inputStream = LoadFile(aTestCase.mPath);
+  ASSERT_TRUE(inputStream != nullptr);
+
+  // Figure out how much data we have.
+  uint64_t length;
+  nsresult rv = inputStream->Available(&length);
+  ASSERT_TRUE(NS_SUCCEEDED(rv));
+
+  // Create a SourceBuffer and a decoder.
+  nsRefPtr<SourceBuffer> sourceBuffer = new SourceBuffer();
+  sourceBuffer->ExpectLength(length);
+  DecoderType decoderType =
+    DecoderFactory::GetDecoderType(aTestCase.mMimeType);
+  nsRefPtr<Decoder> decoder =
+    DecoderFactory::CreateAnonymousDecoder(decoderType, sourceBuffer,
+                                           DefaultSurfaceFlags());
+  ASSERT_TRUE(decoder != nullptr);
+
+  // Decode synchronously, using a |NoResume| IResumable so the Decoder doesn't
+  // attempt to schedule itself on a nonexistent DecodePool when we write more
+  // data into the SourceBuffer.
+  nsRefPtr<NoResume> noResume = new NoResume();
+  for (uint64_t read = 0; read < length ; ++read) {
+    uint64_t available = 0;
+    rv = inputStream->Available(&available);
+    ASSERT_TRUE(available > 0);
+    ASSERT_TRUE(NS_SUCCEEDED(rv));
+
+    rv = sourceBuffer->AppendFromInputStream(inputStream, 1);
+    ASSERT_TRUE(NS_SUCCEEDED(rv));
+
+    decoder->Decode(noResume);
+  }
+
+  sourceBuffer->Complete(NS_OK);
+  decoder->Decode(noResume);
+  
+  CheckDecoderResults(aTestCase, decoder);
+}
+
+TEST(ImageDecoders, PNGSingleChunk)
+{
+  CheckDecoderSingleChunk(GreenPNGTestCase());
+}
+
+TEST(ImageDecoders, PNGMultiChunk)
+{
+  CheckDecoderMultiChunk(GreenPNGTestCase());
+}
+
+TEST(ImageDecoders, GIFSingleChunk)
+{
+  CheckDecoderSingleChunk(GreenGIFTestCase());
+}
+
+TEST(ImageDecoders, GIFMultiChunk)
+{
+  CheckDecoderMultiChunk(GreenGIFTestCase());
+}
+
+TEST(ImageDecoders, JPGSingleChunk)
+{
+  CheckDecoderSingleChunk(GreenJPGTestCase());
+}
+
+TEST(ImageDecoders, JPGMultiChunk)
+{
+  CheckDecoderMultiChunk(GreenJPGTestCase());
+}
+
+TEST(ImageDecoders, BMPSingleChunk)
+{
+  CheckDecoderSingleChunk(GreenBMPTestCase());
+}
+
+TEST(ImageDecoders, BMPMultiChunk)
+{
+  CheckDecoderMultiChunk(GreenBMPTestCase());
+}
+
+TEST(ImageDecoders, ICOSingleChunk)
+{
+  CheckDecoderSingleChunk(GreenICOTestCase());
+}
+
+// XXX(seth): Disabled. We'll fix this in bug 1196066.
+TEST(ImageDecoders, DISABLED_ICOMultiChunk)
+{
+  CheckDecoderMultiChunk(GreenICOTestCase());
+}
+
+TEST(ImageDecoders, AnimatedGIFSingleChunk)
+{
+  CheckDecoderSingleChunk(GreenFirstFrameAnimatedGIFTestCase());
+}
+
+TEST(ImageDecoders, AnimatedGIFMultiChunk)
+{
+  CheckDecoderMultiChunk(GreenFirstFrameAnimatedGIFTestCase());
+}
+
+TEST(ImageDecoders, AnimatedPNGSingleChunk)
+{
+  CheckDecoderSingleChunk(GreenFirstFrameAnimatedPNGTestCase());
+}
+
+TEST(ImageDecoders, AnimatedPNGMultiChunk)
+{
+  CheckDecoderMultiChunk(GreenFirstFrameAnimatedPNGTestCase());
+}
+
+TEST(ImageDecoders, CorruptSingleChunk)
+{
+  CheckDecoderSingleChunk(CorruptTestCase());
+}
+
+TEST(ImageDecoders, CorruptMultiChunk)
+{
+  CheckDecoderMultiChunk(CorruptTestCase());
+}
--- a/image/test/gtest/moz.build
+++ b/image/test/gtest/moz.build
@@ -5,16 +5,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 Library('imagetest')
 
 FAIL_ON_WARNINGS = True
 
 UNIFIED_SOURCES = [
     'Common.cpp',
+    'TestDecoders.cpp',
     'TestDecodeToSurface.cpp',
     'TestMetadata.cpp',
 ]
 
 TEST_HARNESS_FILES.gtest += [
     'corrupt.jpg',
     'first-frame-green.gif',
     'first-frame-green.png',
--- a/image/test/reftest/icon/win/reftest.list
+++ b/image/test/reftest/icon/win/reftest.list
@@ -1,2 +1,2 @@
-skip-if(!winWidget) skip-if(/^Windows\x20NT\x206\.2/.test(http.oscpu)) HTTP == bug415761.sjs bug415761.ico
-skip-if(!winWidget) skip-if(/^Windows\x20NT\x206\.2/.test(http.oscpu)) HTTP == bug415761cleanup.sjs about:blank
+skip-if(!winWidget) skip-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)||/^Windows\x20NT\x206\.2/.test(http.oscpu)) HTTP == bug415761.sjs bug415761.ico # See Bug 850194
+skip-if(!winWidget) skip-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)||/^Windows\x20NT\x206\.2/.test(http.oscpu)) HTTP == bug415761cleanup.sjs about:blank
new file mode 100644
--- /dev/null
+++ b/js/public/UbiNodeCensus.h
@@ -0,0 +1,222 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 et sw=4 tw=99:
+ * 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 js_UbiNodeCensus_h
+#define js_UbiNodeCensus_h
+
+#include "mozilla/Move.h"
+
+#include "js/UbiNode.h"
+#include "js/UbiNodeTraverse.h"
+
+// A census is a ubi::Node traversal that assigns each node to one or more
+// buckets, and returns a report with the size of each bucket.
+//
+// We summarize the results of a census with counts broken down according to
+// criteria selected by the API consumer code that is requesting the census. For
+// example, the following breakdown might give an interesting overview of the
+// heap:
+//
+//   - all nodes
+//     - objects
+//       - objects with a specific [[Class]] *
+//     - strings
+//     - scripts
+//     - all other Node types
+//       - nodes with a specific ubi::Node::typeName *
+//
+// Obviously, the parts of this tree marked with * represent many separate
+// counts, depending on how many distinct [[Class]] values and ubi::Node type
+// names we encounter.
+//
+// The supported types of breakdowns are documented in
+// js/src/doc/Debugger/Debugger.Memory.md.
+//
+// When we parse the 'breakdown' argument to takeCensus, we build a tree of
+// CountType nodes. For example, for the breakdown shown in the
+// Debugger.Memory.prototype.takeCensus, documentation:
+//
+//    {
+//      by: "coarseType",
+//      objects: { by: "objectClass" },
+//      other:    { by: "internalType" }
+//    }
+//
+// we would build the following tree of CountType subclasses:
+//
+//    ByCoarseType
+//      objects: ByObjectClass
+//        each class: SimpleCount
+//      scripts: SimpleCount
+//      strings: SimpleCount
+//      other: ByUbinodeType
+//        each type: SimpleCount
+//
+// The interior nodes are all breakdown types that categorize nodes according to
+// one characteristic or another; and the leaf nodes are all SimpleType.
+//
+// Each CountType has its own concrete C++ type that holds the counts it
+// produces. SimpleCount::Count just holds totals. ByObjectClass::Count has a
+// hash table whose keys are object class names and whose values are counts of
+// some other type (in the example above, SimpleCount).
+//
+// To keep actual count nodes small, they have no vtable. Instead, each count
+// points to its CountType, which knows how to carry out all the operations we
+// need on a Count. A CountType can produce new count nodes; process nodes as we
+// visit them; build a JS object reporting the results; and destruct count
+// nodes.
+
+
+namespace JS {
+namespace ubi {
+
+struct Census;
+
+class CountBase;
+
+struct CountDeleter {
+    void operator()(CountBase*);
+};
+
+using CountBasePtr = UniquePtr<CountBase, CountDeleter>;
+
+// Abstract base class for CountType nodes.
+struct CountType {
+    explicit CountType(Census& census) : census(census) { }
+    virtual ~CountType() { }
+
+    // Destruct a count tree node that this type instance constructed.
+    virtual void destructCount(CountBase& count) = 0;
+
+    // Return a fresh node for the count tree that categorizes nodes according
+    // to this type. Return a nullptr on OOM.
+    virtual CountBasePtr makeCount() = 0;
+
+    // Trace |count| and all its children, for garbage collection.
+    virtual void traceCount(CountBase& count, JSTracer* trc) = 0;
+
+    // Implement the 'count' method for counts returned by this CountType
+    // instance's 'newCount' method.
+    virtual bool count(CountBase& count, const Node& node) = 0;
+
+    // Implement the 'report' method for counts returned by this CountType
+    // instance's 'newCount' method.
+    virtual bool report(CountBase& count, MutableHandleValue report) = 0;
+
+  protected:
+    Census& census;
+};
+
+using CountTypePtr = UniquePtr<CountType, JS::DeletePolicy<CountType>>;
+
+// An abstract base class for count tree nodes.
+class CountBase {
+    // In lieu of a vtable, each CountBase points to its type, which
+    // carries not only the implementations of the CountBase methods, but also
+    // additional parameters for the type's behavior, as specified in the
+    // breakdown argument passed to takeCensus.
+    CountType& type;
+
+  protected:
+    ~CountBase() { }
+
+  public:
+    explicit CountBase(CountType& type) : type(type), total_(0) { }
+
+    // Categorize and count |node| as appropriate for this count's type.
+    bool count(const Node& node) { return type.count(*this, node); }
+
+    // Construct a JavaScript object reporting the counts recorded in this
+    // count, and store it in |report|. Return true on success, or false on
+    // failure.
+    bool report(MutableHandleValue report) { return type.report(*this, report); }
+
+    // Down-cast this CountBase to its true type, based on its 'type' member,
+    // and run its destructor.
+    void destruct() { return type.destructCount(*this); }
+
+    // Trace this count for garbage collection.
+    void trace(JSTracer* trc) { type.traceCount(*this, trc); }
+
+    size_t total_;
+};
+
+class RootedCount : JS::CustomAutoRooter {
+    CountBasePtr count;
+
+    void trace(JSTracer* trc) override { count->trace(trc); }
+
+  public:
+    RootedCount(JSContext* cx, CountBasePtr&& count)
+        : CustomAutoRooter(cx),
+          count(Move(count))
+          { }
+    CountBase* operator->() const { return count.get(); }
+    explicit operator bool() const { return count.get(); }
+    operator CountBasePtr&() { return count; }
+};
+
+// Common data for a census traversal, shared across all CountType nodes.
+struct Census {
+    JSContext* const cx;
+    // If the targetZones set is non-empty, then only consider nodes whose zone
+    // is an element of the set. If the targetZones set is empty, then nodes in
+    // all zones are considered.
+    JS::ZoneSet targetZones;
+    Zone* atomsZone;
+
+    explicit Census(JSContext* cx) : cx(cx), atomsZone(nullptr) { }
+
+    bool init();
+
+    // A 'new' work-alike that behaves like TempAllocPolicy: report OOM on this
+    // census's context, but don't charge the memory allocated to our context's
+    // GC pressure counters.
+    template<typename T, typename... Args>
+    T* new_(Args&&... args) MOZ_HEAP_ALLOCATOR {
+        void* memory = js_malloc(sizeof(T));
+        if (MOZ_UNLIKELY(!memory)) {
+            return nullptr;
+        }
+        return new(memory) T(mozilla::Forward<Args>(args)...);
+    }
+};
+
+// A BreadthFirst handler type that conducts a census, using a CountBase to
+// categorize and count each node.
+class CensusHandler {
+    Census& census;
+    CountBasePtr& rootCount;
+
+  public:
+    CensusHandler(Census& census, CountBasePtr& rootCount)
+      : census(census),
+        rootCount(rootCount)
+    { }
+
+    bool report(MutableHandleValue report) {
+        return rootCount->report(report);
+    }
+
+    // This class needs to retain no per-node data.
+    class NodeData { };
+
+    bool operator() (BreadthFirst<CensusHandler>& traversal,
+                     Node origin, const Edge& edge,
+                     NodeData* referentData, bool first);
+};
+
+using CensusTraversal = BreadthFirst<CensusHandler>;
+
+// Examine the census options supplied by the API consumer, and use that to
+// build a CountType tree.
+bool ParseCensusOptions(JSContext* cx, Census& census, HandleObject options,
+                        CountTypePtr& outResult);
+
+} // namespace ubi
+} // namespace JS
+
+#endif // js_UbiNodeCensus_h
--- a/js/src/frontend/BytecodeCompiler.cpp
+++ b/js/src/frontend/BytecodeCompiler.cpp
@@ -82,17 +82,16 @@ class MOZ_STACK_CLASS BytecodeCompiler
     bool checkArgumentsWithinEval(JSContext* cx, HandleFunction fun);
     bool maybeCheckEvalFreeVariables(HandleScript evalCaller, HandleObject scopeChain,
                                      ParseContext<FullParseHandler>& pc);
     bool maybeSetDisplayURL(TokenStream& tokenStream);
     bool maybeSetSourceMap(TokenStream& tokenStream);
     bool maybeSetSourceMapFromOptions();
     bool emitFinalReturn();
     bool initGlobalBindings(ParseContext<FullParseHandler>& pc);
-    void markFunctionsWithinEvalScript();
     bool maybeCompleteCompressSource();
 
     AutoCompilationTraceLogger traceLogger;
     AutoKeepAtoms keepAtoms;
 
     ExclusiveContext* cx;
     LifoAlloc* alloc;
     const ReadOnlyCompileOptions& options;
@@ -514,39 +513,16 @@ BytecodeCompiler::initGlobalBindings(Par
     {
         return false;
     }
 
     script->bindings = bindings;
     return true;
 }
 
-void
-BytecodeCompiler::markFunctionsWithinEvalScript()
-{
-    // Mark top level functions in an eval script as being within an eval.
-
-    if (!script->hasObjects())
-        return;
-
-    ObjectArray* objects = script->objects();
-    size_t start = script->innerObjectsStart();
-
-    for (size_t i = start; i < objects->length; i++) {
-        JSObject* obj = objects->vector[i];
-        if (obj->is<JSFunction>()) {
-            JSFunction* fun = &obj->as<JSFunction>();
-            if (fun->hasScript())
-                fun->nonLazyScript()->setDirectlyInsideEval();
-            else if (fun->isInterpretedLazy())
-                fun->lazyScript()->setDirectlyInsideEval();
-        }
-    }
-}
-
 bool
 BytecodeCompiler::maybeCompleteCompressSource()
 {
     return !maybeSourceCompressor || maybeSourceCompressor->complete();
 }
 
 JSScript*
 BytecodeCompiler::compileScript(HandleObject scopeChain, HandleScript evalCaller)
@@ -616,22 +592,16 @@ BytecodeCompiler::compileScript(HandleOb
         !maybeSetSourceMapFromOptions() ||
         !emitFinalReturn() ||
         !initGlobalBindings(pc.ref()) ||
         !JSScript::fullyInitFromEmitter(cx, script, emitter.ptr()))
     {
         return nullptr;
     }
 
-    // Note that this marking must happen before we tell Debugger
-    // about the new script, in case Debugger delazifies the script's
-    // inner functions.
-    if (options.forEval)
-        markFunctionsWithinEvalScript();
-
     emitter->tellDebuggerAboutCompiledScript(cx);
 
     if (!maybeCompleteCompressSource())
         return nullptr;
 
     MOZ_ASSERT_IF(cx->isJSContext(), !cx->asJSContext()->isExceptionPending());
     return script;
 }
@@ -785,18 +755,16 @@ frontend::CompileLazyFunction(JSContext*
 
     Rooted<JSScript*> script(cx, JSScript::Create(cx, enclosingScope, false, options,
                                                   sourceObject, lazy->begin(), lazy->end()));
     if (!script)
         return false;
 
     script->bindings = pn->pn_funbox->bindings;
 
-    if (lazy->directlyInsideEval())
-        script->setDirectlyInsideEval();
     if (lazy->usesArgumentsApplyAndThis())
         script->setUsesArgumentsApplyAndThis();
     if (lazy->hasBeenCloned())
         script->setHasBeenCloned();
 
     /*
      * We just pass false for insideNonGlobalEval and insideEval, because we
      * don't actually know whether we are or not.  The only consumer of those
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -8,16 +8,17 @@
  * JS bytecode generation.
  */
 
 #include "frontend/BytecodeEmitter.h"
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/FloatingPoint.h"
+#include "mozilla/Maybe.h"
 #include "mozilla/PodOperations.h"
 #include "mozilla/UniquePtr.h"
 
 #include <string.h>
 
 #include "jsapi.h"
 #include "jsatom.h"
 #include "jscntxt.h"
@@ -43,16 +44,18 @@
 #include "frontend/ParseNode-inl.h"
 #include "vm/NativeObject-inl.h"
 #include "vm/ScopeObject-inl.h"
 
 using namespace js;
 using namespace js::gc;
 using namespace js::frontend;
 
+using mozilla::Maybe;
+using mozilla::Some;
 using mozilla::DebugOnly;
 using mozilla::NumberIsInt32;
 using mozilla::PodCopy;
 using mozilla::UniquePtr;
 
 struct frontend::StmtInfoBCE : public StmtInfoBase
 {
     StmtInfoBCE*    enclosing;
@@ -102,26 +105,16 @@ struct frontend::LoopStmtInfo : public S
     explicit LoopStmtInfo(ExclusiveContext* cx) : StmtInfoBCE(cx) {}
 
     static LoopStmtInfo* fromStmtInfo(StmtInfoBCE* stmt) {
         MOZ_ASSERT(stmt->isLoop());
         return static_cast<LoopStmtInfo*>(stmt);
     }
 };
 
-void
-FunctionBox::switchStaticScopeToFunction()
-{
-    if (staticScope_->is<StaticFunctionBoxScopeObject>()) {
-        MOZ_ASSERT(staticScope_->as<StaticFunctionBoxScopeObject>().functionBox() == this);
-        staticScope_ = function();
-    }
-    MOZ_ASSERT(staticScope_ == function());
-}
-
 BytecodeEmitter::BytecodeEmitter(BytecodeEmitter* parent,
                                  Parser<FullParseHandler>* parser, SharedContext* sc,
                                  HandleScript script, Handle<LazyScript*> lazyScript,
                                  bool insideEval, HandleScript evalCaller,
                                  bool insideNonGlobalEval, uint32_t lineNum,
                                  EmitterMode emitterMode)
   : sc(sc),
     cx(sc->context),
@@ -1507,67 +1500,75 @@ BytecodeEmitter::tryConvertFreeName(Pars
     if (emitterMode == BytecodeEmitter::LazyFunction) {
         // The only statements within a lazy function which can push lexical
         // scopes are try/catch blocks. Use generic ops in this case.
         for (StmtInfoBCE* stmt = innermostStmt(); stmt; stmt = stmt->enclosing) {
             if (stmt->type == StmtType::CATCH)
                 return true;
         }
 
-        size_t hops = 0;
+        // Walk the static scope chain and look for an aliased binding with
+        // the name pn->pn_atom.
+        uint32_t hops = 0;
+        Maybe<uint32_t> slot;
         FunctionBox* funbox = sc->asFunctionBox();
-        if (funbox->hasExtensibleScope())
-            return false;
-        if (funbox->function()->isNamedLambda() && funbox->function()->atom() == pn->pn_atom)
-            return false;
-        if (funbox->isHeavyweight()) {
-            hops++;
-            if (funbox->function()->isNamedLambda())
-                hops++;
-        }
-        if (script->directlyInsideEval())
-            return false;
-        RootedObject outerScope(cx, script->enclosingStaticScope());
-        for (StaticScopeIter<CanGC> ssi(cx, outerScope); !ssi.done(); ssi++) {
-            if (ssi.type() != StaticScopeIter<CanGC>::Function) {
-                if (ssi.type() == StaticScopeIter<CanGC>::Block) {
-                    // Use generic ops if a catch block is encountered.
+        PropertyName* name = pn->pn_atom->asPropertyName();
+        for (StaticScopeIter<NoGC> ssi(funbox->staticScope()); !ssi.done(); ssi++) {
+            // Don't optimize names through eval.
+            if (ssi.type() == StaticScopeIter<NoGC>::Eval)
+                return false;
+
+            if (!ssi.hasSyntacticDynamicScopeObject())
+                continue;
+
+            // Look up for name in function and block scopes.
+            if (ssi.type() == StaticScopeIter<NoGC>::Function) {
+                RootedScript funScript(cx, ssi.funScript());
+                if (funScript->funHasExtensibleScope() || ssi.fun().atom() == pn->pn_atom)
                     return false;
+
+                // Skip the current function, since we're trying to convert a
+                // free name.
+                if (script != funScript) {
+                    uint32_t slot_;
+                    if (lookupAliasedName(funScript, name, &slot_, pn)) {
+                        slot = Some(slot_);
+                        break;
+                    }
                 }
-                if (ssi.hasSyntacticDynamicScopeObject())
-                    hops++;
-                continue;
+            } else if (ssi.type() == StaticScopeIter<NoGC>::Block) {
+                RootedShape shape(cx, ssi.block().lookupAliasedName(name));
+                if (shape) {
+                    // Don't optimize setting a 'const' binding. Let the slow
+                    // path do the error checking.
+                    if (!shape->writable() && pn->getOp() == JSOP_SETNAME)
+                        return false;
+                    slot = Some(shape->slot());
+                    pn->pn_dflags |= PND_LEXICAL;
+                    break;
+                }
+            } else {
+                MOZ_ASSERT(ssi.type() != StaticScopeIter<NoGC>::With);
             }
-            RootedScript script(cx, ssi.funScript());
-            if (script->functionNonDelazifying()->atom() == pn->pn_atom)
-                return false;
-            if (ssi.hasSyntacticDynamicScopeObject()) {
-                uint32_t slot;
-                if (lookupAliasedName(script, pn->pn_atom->asPropertyName(), &slot, pn)) {
-                    JSOp op;
-                    switch (pn->getOp()) {
-                      case JSOP_GETNAME: op = JSOP_GETALIASEDVAR; break;
-                      case JSOP_SETNAME: op = JSOP_SETALIASEDVAR; break;
-                      default: return false;
-                    }
-
-                    pn->setOp(op);
-                    MOZ_ALWAYS_TRUE(pn->pn_scopecoord.set(parser->tokenStream, hops, slot));
-                    return true;
-                }
-                hops++;
+
+            hops++;
+        }
+
+        // If we found a scope binding name, convert the name op to an aliased
+        // var op.
+        if (slot.isSome()) {
+            JSOp op;
+            switch (pn->getOp()) {
+              case JSOP_GETNAME: op = JSOP_GETALIASEDVAR; break;
+              case JSOP_SETNAME: op = JSOP_SETALIASEDVAR; break;
+              default: return false;
             }
-
-            // If this walk up and check for directlyInsideEval is ever removed,
-            // we'll need to adjust CompileLazyFunction to better communicate
-            // whether we're inside eval to the BytecodeEmitter.  For now, this
-            // walk is why CompileLazyFunction can claim that it's never inside
-            // eval.
-            if (script->funHasExtensibleScope() || script->directlyInsideEval())
-                return false;
+            pn->setOp(op);
+            MOZ_ALWAYS_TRUE(pn->pn_scopecoord.set(parser->tokenStream, hops, *slot));
+            return true;
         }
     }
 
     // Unbound names aren't recognizable global-property references if the
     // script is inside a non-global eval call.
     if (insideNonGlobalEval)
         return false;
 
@@ -7002,18 +7003,21 @@ BytecodeEmitter::emitPropertyList(ParseN
         ParseNode* key = propdef->pn_left;
         bool isIndex = false;
         if (key->isKind(PNK_NUMBER)) {
             if (!emitNumberOp(key->pn_dval))
                 return false;
             isIndex = true;
         } else if (key->isKind(PNK_OBJECT_PROPERTY_NAME) || key->isKind(PNK_STRING)) {
             // EmitClass took care of constructor already.
-            if (type == ClassBody && key->pn_atom == cx->names().constructor)
+            if (type == ClassBody && key->pn_atom == cx->names().constructor &&
+                !propdef->as<ClassMethod>().isStatic())
+            {
                 continue;
+            }
 
             // The parser already checked for atoms representing indexes and
             // used PNK_NUMBER instead, but also watch for ids which TI treats
             // as indexes for simpliciation of downstream analysis.
             jsid id = NameToId(key->pn_atom->asPropertyName());
             if (id != IdToTypeId(id)) {
                 if (!emitTree(key))
                     return false;
--- a/js/src/frontend/ParseNode.cpp
+++ b/js/src/frontend/ParseNode.cpp
@@ -1155,14 +1155,14 @@ void
 ObjectBox::trace(JSTracer* trc)
 {
     ObjectBox* box = this;
     while (box) {
         TraceRoot(trc, &box->object, "parser.object");
         if (box->isFunctionBox()) {
             FunctionBox* funbox = box->asFunctionBox();
             funbox->bindings.trace(trc);
-            if (funbox->staticScope_)
-                TraceRoot(trc, &funbox->staticScope_, "funbox-staticScope");
+            if (funbox->enclosingStaticScope_)
+                TraceRoot(trc, &funbox->enclosingStaticScope_, "funbox-enclosingStaticScope");
         }
         box = box->traceLink;
     }
 }
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -43,16 +43,32 @@
 
 using namespace js;
 using namespace js::gc;
 
 using mozilla::Maybe;
 
 using JS::AutoGCRooter;
 
+JSFunction::AutoParseUsingFunctionBox::AutoParseUsingFunctionBox(ExclusiveContext* cx,
+                                                                 frontend::FunctionBox* funbox)
+  : fun_(cx, funbox->function()),
+    oldEnv_(cx, fun_->environment())
+{
+    fun_->setFunctionBox(funbox);
+    funbox->computeAllowSyntax(fun_);
+    funbox->computeInWith(fun_);
+}
+
+JSFunction::AutoParseUsingFunctionBox::~AutoParseUsingFunctionBox()
+{
+    fun_->unsetFunctionBox();
+    fun_->setEnvironment(oldEnv_);
+}
+
 namespace js {
 namespace frontend {
 
 typedef Rooted<StaticBlockObject*> RootedStaticBlockObject;
 typedef Handle<StaticBlockObject*> HandleStaticBlockObject;
 typedef Rooted<NestedScopeObject*> RootedNestedScopeObject;
 typedef Handle<NestedScopeObject*> HandleNestedScopeObject;
 
@@ -608,22 +624,22 @@ Parser<ParseHandler>::newObjectBox(JSObj
 
     traceListHead = objbox;
 
     return objbox;
 }
 
 template <typename ParseHandler>
 FunctionBox::FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunction* fun,
-                         JSObject* staticScope, ParseContext<ParseHandler>* outerpc,
+                         JSObject* enclosingStaticScope, ParseContext<ParseHandler>* outerpc,
                          Directives directives, bool extraWarnings, GeneratorKind generatorKind)
   : ObjectBox(fun, traceListHead),
     SharedContext(cx, directives, extraWarnings),
     bindings(),
-    staticScope_(staticScope),
+    enclosingStaticScope_(enclosingStaticScope),
     bufStart(0),
     bufEnd(0),
     length(0),
     generatorKindBits_(GeneratorKindAsBits(generatorKind)),
     inGenexpLambda(false),
     hasDestructuringArgs(false),
     useAsm(false),
     insideUseAsm(outerpc && outerpc->useAsmOrInsideUseAsm()),
@@ -631,82 +647,53 @@ FunctionBox::FunctionBox(ExclusiveContex
     usesApply(false),
     usesThis(false),
     funCxFlags()
 {
     // Functions created at parse time may be set singleton after parsing and
     // baked into JIT code, so they must be allocated tenured. They are held by
     // the JSScript so cannot be collected during a minor GC anyway.
     MOZ_ASSERT(fun->isTenured());
-
-    if (staticScope->is<StaticFunctionBoxScopeObject>())
-        staticScope->as<StaticFunctionBoxScopeObject>().setFunctionBox(this);
-
-    computeAllowSyntax(staticScope);
-    computeInWith(staticScope);
 }
 
 template <typename ParseHandler>
 FunctionBox*
-Parser<ParseHandler>::newFunctionBoxWithScope(Node fn, JSFunction* fun,
-                                              ParseContext<ParseHandler>* outerpc,
-                                              Directives inheritedDirectives,
-                                              GeneratorKind generatorKind,
-                                              JSObject* staticScope)
-{
+Parser<ParseHandler>::newFunctionBox(Node fn, JSFunction* fun,
+                                     ParseContext<ParseHandler>* outerpc,
+                                     Directives inheritedDirectives,
+                                     GeneratorKind generatorKind,
+                                     JSObject* enclosingStaticScope)
+{
+    MOZ_ASSERT_IF(outerpc, enclosingStaticScope == outerpc->innermostStaticScope());
     MOZ_ASSERT(fun);
 
     /*
      * We use JSContext.tempLifoAlloc to allocate parsed objects and place them
      * on a list in this Parser to ensure GC safety. Thus the tempLifoAlloc
      * arenas containing the entries must be alive until we are done with
      * scanning, parsing and code generation for the whole script or top-level
      * function.
      */
     FunctionBox* funbox =
-        alloc.new_<FunctionBox>(context, traceListHead, fun, staticScope, outerpc,
-                                inheritedDirectives,
-                                options().extraWarningsOption,
+        alloc.new_<FunctionBox>(context, traceListHead, fun, enclosingStaticScope, outerpc,
+                                inheritedDirectives, options().extraWarningsOption,
                                 generatorKind);
     if (!funbox) {
         ReportOutOfMemory(context);
         return nullptr;
     }
 
     traceListHead = funbox;
     if (fn)
         handler.setFunctionBox(fn, funbox);
 
     return funbox;
 }
 
 template <typename ParseHandler>
-FunctionBox*
-Parser<ParseHandler>::newFunctionBox(Node fn, HandleFunction fun,
-                                     ParseContext<ParseHandler>* outerpc,
-                                     Directives inheritedDirectives,
-                                     GeneratorKind generatorKind,
-                                     HandleObject enclosingStaticScope)
-{
-    MOZ_ASSERT_IF(outerpc, enclosingStaticScope == outerpc->innermostStaticScope());
-
-    StaticFunctionBoxScopeObject* scope =
-        StaticFunctionBoxScopeObject::create(context, enclosingStaticScope);
-    if (!scope)
-        return nullptr;
-
-    FunctionBox* funbox = newFunctionBoxWithScope(fn, fun, outerpc, inheritedDirectives,
-                                                  generatorKind, scope);
-    if (!funbox)
-        return nullptr;
-
-    return funbox;
-}
-
-template <typename ParseHandler>
 void
 Parser<ParseHandler>::trace(JSTracer* trc)
 {
     traceListHead->trace(trc);
 }
 
 void
 MarkParser(JSTracer* trc, AutoGCRooter* parser)
@@ -1300,38 +1287,38 @@ Parser<ParseHandler>::newFunction(Handle
         flags = JSFunction::INTERPRETED_LAMBDA;
         break;
       case Arrow:
         flags = JSFunction::INTERPRETED_LAMBDA_ARROW;
         allocKind = gc::AllocKind::FUNCTION_EXTENDED;
         break;
       case Method:
         MOZ_ASSERT(generatorKind == NotGenerator || generatorKind == StarGenerator);
-        if (generatorKind == NotGenerator)
-            flags = JSFunction::INTERPRETED_METHOD;
-        else
-            flags = JSFunction::INTERPRETED_METHOD_GENERATOR;
+        flags = (generatorKind == NotGenerator
+                 ? JSFunction::INTERPRETED_METHOD
+                 : JSFunction::INTERPRETED_METHOD_GENERATOR);
         allocKind = gc::AllocKind::FUNCTION_EXTENDED;
         break;
       case ClassConstructor:
       case DerivedClassConstructor:
         flags = JSFunction::INTERPRETED_CLASS_CONSTRUCTOR;
         allocKind = gc::AllocKind::FUNCTION_EXTENDED;
         break;
       case Getter:
         flags = JSFunction::INTERPRETED_GETTER;
         allocKind = gc::AllocKind::FUNCTION_EXTENDED;
         break;
       case Setter:
         flags = JSFunction::INTERPRETED_SETTER;
         allocKind = gc::AllocKind::FUNCTION_EXTENDED;
         break;
       default:
-        flags = JSFunction::INTERPRETED_NORMAL;
-        break;
+        flags = (generatorKind == NotGenerator
+                 ? JSFunction::INTERPRETED_NORMAL
+                 : JSFunction::INTERPRETED_GENERATOR);
     }
 
     fun = NewFunctionWithProto(context, nullptr, 0, flags, nullptr, atom, proto,
                                allocKind, TenuredObject);
     if (!fun)
         return nullptr;
     if (options().selfHostingMode)
         fun->setIsSelfHostedBuiltin();
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -101,16 +101,21 @@ struct MOZ_STACK_CLASS ParseContext : pu
     typedef typename ParseHandler::DefinitionNode DefinitionNode;
 
     uint32_t        bodyid;         /* block number of program/function body */
 
     StmtInfoStack<StmtInfoPC> stmtStack;
 
     Node            maybeFunction;  /* sc->isFunctionBox, the pn where pn->pn_funbox == sc */
 
+    // If sc->isFunctionBox(), this is used to temporarily link up the
+    // FunctionBox with the JSFunction so the static scope chain may be walked
+    // without a JSScript.
+    mozilla::Maybe<JSFunction::AutoParseUsingFunctionBox> parseUsingFunctionBox;
+
     // lastYieldOffset stores the offset of the last yield that was parsed.
     // NoYieldOffset is its initial value.
     static const uint32_t NoYieldOffset = UINT32_MAX;
     uint32_t         lastYieldOffset;
 
     // Most functions start off being parsed as non-generators.
     // Non-generators transition to LegacyGenerator on parsing "yield" in JS 1.7.
     // An ES6 generator is marked as a "star generator" before its body is parsed.
@@ -265,16 +270,18 @@ struct MOZ_STACK_CLASS ParseContext : pu
         oldpc(prs->pc),
         lexdeps(prs->context),
         funcStmts(nullptr),
         innerFunctions(prs->context, TraceableVector<JSFunction*>(prs->context)),
         newDirectives(newDirectives),
         inDeclDestructuring(false)
     {
         prs->pc = this;
+        if (sc->isFunctionBox())
+            parseUsingFunctionBox.emplace(prs->context, sc->asFunctionBox());
     }
 
     ~ParseContext();
 
     bool init(Parser<ParseHandler>& parser);
 
     unsigned blockid() { return stmtStack.innermost() ? stmtStack.innermost()->blockid : bodyid; }
 
@@ -458,27 +465,20 @@ class Parser : private JS::AutoGCRooter,
      */
     Node parse();
 
     /*
      * Allocate a new parsed object or function container from
      * cx->tempLifoAlloc.
      */
     ObjectBox* newObjectBox(JSObject* obj);
-    FunctionBox* newFunctionBoxWithScope(Node fn, JSFunction* fun,
-                                         ParseContext<ParseHandler>* outerpc,
-                                         Directives directives, GeneratorKind generatorKind,
-                                         JSObject* staticScope);
+    FunctionBox* newFunctionBox(Node fn, JSFunction* fun, ParseContext<ParseHandler>* outerpc,
+                                Directives directives, GeneratorKind generatorKind,
+                                JSObject* enclosingStaticScope);
 
-  private:
-    FunctionBox* newFunctionBox(Node fn, HandleFunction fun, ParseContext<ParseHandler>* outerpc,
-                                Directives directives, GeneratorKind generatorKind,
-                                HandleObject enclosingStaticScope);
-
-  public:
     // Use when the funbox is the outermost.
     FunctionBox* newFunctionBox(Node fn, HandleFunction fun, Directives directives,
                                 GeneratorKind generatorKind, HandleObject enclosingStaticScope)
     {
         return newFunctionBox(fn, fun, nullptr, directives, generatorKind,
                               enclosingStaticScope);
     }
 
--- a/js/src/frontend/SharedContext.h
+++ b/js/src/frontend/SharedContext.h
@@ -186,20 +186,16 @@ class SharedContext
     bool extraWarnings;
 
   private:
     bool allowNewTarget_;
     bool allowSuperProperty_;
     bool inWith_;
     bool superScopeAlreadyNeedsHomeObject_;
 
-  protected:
-    void computeAllowSyntax(JSObject* staticScope);
-    void computeInWith(JSObject* staticScope);
-
   public:
     SharedContext(ExclusiveContext* cx, Directives directives,
                   bool extraWarnings)
       : context(cx),
         anyCxFlags(),
         strictScript(directives.strict()),
         localStrict(false),
         extraWarnings(extraWarnings),
@@ -210,16 +206,18 @@ class SharedContext
     { }
 
     // The unfortunate reason that staticScope() is a virtual is because
     // GlobalSharedContext and FunctionBox have different lifetimes.
     // GlobalSharedContexts are stack allocated and thus may use RootedObject
     // for the static scope. FunctionBoxes are LifoAlloc'd and need to
     // manually trace their static scope.
     virtual JSObject* staticScope() const = 0;
+    void computeAllowSyntax(JSObject* staticScope);
+    void computeInWith(JSObject* staticScope);
 
     virtual ObjectBox* toObjectBox() { return nullptr; }
     inline bool isFunctionBox() { return toObjectBox() && toObjectBox()->isFunctionBox(); }
     inline FunctionBox* asFunctionBox();
 
     bool allowNewTarget()              const { return allowNewTarget_; }
     bool allowSuperProperty()          const { return allowSuperProperty_; }
     bool inWith()                      const { return inWith_; }
@@ -272,46 +270,45 @@ class MOZ_STACK_CLASS GlobalSharedContex
 
     JSObject* staticScope() const override { return staticScope_; }
 };
 
 class FunctionBox : public ObjectBox, public SharedContext
 {
   public:
     Bindings        bindings;               /* bindings for this function */
-    JSObject*       staticScope_;
+    JSObject*       enclosingStaticScope_;
     uint32_t        bufStart;
     uint32_t        bufEnd;
     uint32_t        startLine;
     uint32_t        startColumn;
     uint16_t        length;
 
     uint8_t         generatorKindBits_;     /* The GeneratorKind of this function. */
-    bool            inWith_:1;              /* some enclosing scope is a with-statement */
     bool            inGenexpLambda:1;       /* lambda from generator expression */
     bool            hasDestructuringArgs:1; /* arguments list contains destructuring expression */
     bool            useAsm:1;               /* see useAsmOrInsideUseAsm */
     bool            insideUseAsm:1;         /* see useAsmOrInsideUseAsm */
 
     // Fields for use in heuristics.
     bool            usesArguments:1;  /* contains a free use of 'arguments' */
     bool            usesApply:1;      /* contains an f.apply() call */
     bool            usesThis:1;       /* contains 'this' */
 
     FunctionContextFlags funCxFlags;
 
     template <typename ParseHandler>
     FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunction* fun,
-                JSObject* staticScope, ParseContext<ParseHandler>* pc,
+                JSObject* enclosingStaticScope, ParseContext<ParseHandler>* pc,
                 Directives directives, bool extraWarnings, GeneratorKind generatorKind);
 
     ObjectBox* toObjectBox() override { return this; }
     JSFunction* function() const { return &object->as<JSFunction>(); }
-    JSObject* staticScope() const override { return staticScope_; }
-    void switchStaticScopeToFunction();
+    JSObject* staticScope() const override { return function(); }
+    JSObject* enclosingStaticScope() const { return enclosingStaticScope_; }
 
     GeneratorKind generatorKind() const { return GeneratorKindFromBits(generatorKindBits_); }
     bool isGenerator() const { return generatorKind() != NotGenerator; }
     bool isLegacyGenerator() const { return generatorKind() == LegacyGenerator; }
     bool isStarGenerator() const { return generatorKind() == StarGenerator; }
     bool isArrow() const { return function()->isArrow(); }
 
     void setGeneratorKind(GeneratorKind kind) {
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/bug1180054.js
@@ -0,0 +1,6 @@
+function entryFrame_1(d) {
+    assertJitStackInvariants();
+}
+for (i = 0Xa; i < 40; i++) {
+    new entryFrame_1();
+}
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug1185957.js
@@ -0,0 +1,15 @@
+// |jit-test| error: TypeError
+
+load(libdir + "class.js");
+
+var test = `
+class test {
+    constructor() {};
+}
+(function() {
+    test()
+})();
+`;
+
+if (classesEnabled())
+    eval(test);
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -1607,17 +1607,17 @@ BaselineCompiler::emit_JSOP_POW()
 
 bool
 BaselineCompiler::emitBinaryArith()
 {
     // Keep top JSStack value in R0 and R2
     frame.popRegsAndSync(2);
 
     // Call IC
-    ICBinaryArith_Fallback::Compiler stubCompiler(cx);
+    ICBinaryArith_Fallback::Compiler stubCompiler(cx, ICStubCompiler::Engine::Baseline);
     if (!emitOpIC(stubCompiler.getStub(&stubSpace_)))
         return false;
 
     // Mark R0 as pushed stack value.
     frame.push(R0);
     return true;
 }
 
--- a/js/src/jit/BaselineDebugModeOSR.h
+++ b/js/src/jit/BaselineDebugModeOSR.h
@@ -36,28 +36,40 @@ namespace jit {
 //     if (stub.invalid())
 //         return true;
 //
 //     // First use of stub after VM call.
 //
 template <typename T>
 class DebugModeOSRVolatileStub
 {
+    ICStubCompiler::Engine engine_;
     T stub_;
     BaselineFrame* frame_;
     uint32_t pcOffset_;
 
   public:
+    DebugModeOSRVolatileStub(ICStubCompiler::Engine engine, BaselineFrame* frame,
+                             ICFallbackStub* stub)
+      : engine_(engine),
+        stub_(static_cast<T>(stub)),
+        frame_(frame),
+        pcOffset_(stub->icEntry()->pcOffset())
+    { }
+
     DebugModeOSRVolatileStub(BaselineFrame* frame, ICFallbackStub* stub)
-      : stub_(static_cast<T>(stub)),
+      : engine_(ICStubCompiler::Engine::Baseline),
+        stub_(static_cast<T>(stub)),
         frame_(frame),
         pcOffset_(stub->icEntry()->pcOffset())
     { }
 
     bool invalid() const {
+        if (engine_ == ICStubCompiler::Engine::IonMonkey)
+            return false;
         MOZ_ASSERT(!frame_->isHandlingException());
         ICEntry& entry = frame_->script()->baselineScript()->icEntryFromPCOffset(pcOffset_);
         return stub_ != entry.fallbackStub();
     }
 
     operator const T&() const { MOZ_ASSERT(!invalid()); return stub_; }
     T operator->() const { MOZ_ASSERT(!invalid()); return stub_; }
     T* address() { MOZ_ASSERT(!invalid()); return &stub_; }
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -1857,581 +1857,16 @@ ICToNumber_Fallback::Compiler::generateS
     // Push arguments.
     masm.pushValue(R0);
     masm.push(ICStubReg);
 
     return tailCallVM(DoToNumberFallbackInfo, masm);
 }
 
 //
-// BinaryArith_Fallback
-//
-
-static bool
-DoBinaryArithFallback(JSContext* cx, BaselineFrame* frame, ICBinaryArith_Fallback* stub_,
-                      HandleValue lhs, HandleValue rhs, MutableHandleValue ret)
-{
-    // This fallback stub may trigger debug mode toggling.
-    DebugModeOSRVolatileStub<ICBinaryArith_Fallback*> stub(frame, stub_);
-
-    RootedScript script(cx, frame->script());
-    jsbytecode* pc = stub->icEntry()->pc(script);
-    JSOp op = JSOp(*pc);
-    FallbackICSpew(cx, stub, "BinaryArith(%s,%d,%d)", js_CodeName[op],
-            int(lhs.isDouble() ? JSVAL_TYPE_DOUBLE : lhs.extractNonDoubleType()),
-            int(rhs.isDouble() ? JSVAL_TYPE_DOUBLE : rhs.extractNonDoubleType()));
-
-    // Don't pass lhs/rhs directly, we need the original values when
-    // generating stubs.
-    RootedValue lhsCopy(cx, lhs);
-    RootedValue rhsCopy(cx, rhs);
-
-    // Perform the compare operation.
-    switch(op) {
-      case JSOP_ADD:
-        // Do an add.
-        if (!AddValues(cx, &lhsCopy, &rhsCopy, ret))
-            return false;
-        break;
-      case JSOP_SUB:
-        if (!SubValues(cx, &lhsCopy, &rhsCopy, ret))
-            return false;
-        break;
-      case JSOP_MUL:
-        if (!MulValues(cx, &lhsCopy, &rhsCopy, ret))
-            return false;
-        break;
-      case JSOP_DIV:
-        if (!DivValues(cx, &lhsCopy, &rhsCopy, ret))
-            return false;
-        break;
-      case JSOP_MOD:
-        if (!ModValues(cx, &lhsCopy, &rhsCopy, ret))
-            return false;
-        break;
-      case JSOP_POW:
-        if (!math_pow_handle(cx, lhsCopy, rhsCopy, ret))
-            return false;
-        break;
-      case JSOP_BITOR: {
-        int32_t result;
-        if (!BitOr(cx, lhs, rhs, &result))
-            return false;
-        ret.setInt32(result);
-        break;
-      }
-      case JSOP_BITXOR: {
-        int32_t result;
-        if (!BitXor(cx, lhs, rhs, &result))
-            return false;
-        ret.setInt32(result);
-        break;
-      }
-      case JSOP_BITAND: {
-        int32_t result;
-        if (!BitAnd(cx, lhs, rhs, &result))
-            return false;
-        ret.setInt32(result);
-        break;
-      }
-      case JSOP_LSH: {
-        int32_t result;
-        if (!BitLsh(cx, lhs, rhs, &result))
-            return false;
-        ret.setInt32(result);
-        break;
-      }
-      case JSOP_RSH: {
-        int32_t result;
-        if (!BitRsh(cx, lhs, rhs, &result))
-            return false;
-        ret.setInt32(result);
-        break;
-      }
-      case JSOP_URSH: {
-        if (!UrshOperation(cx, lhs, rhs, ret))
-            return false;
-        break;
-      }
-      default:
-        MOZ_CRASH("Unhandled baseline arith op");
-    }
-
-    // Check if debug mode toggling made the stub invalid.
-    if (stub.invalid())
-        return true;
-
-    if (ret.isDouble())
-        stub->setSawDoubleResult();
-
-    // Check to see if a new stub should be generated.
-    if (stub->numOptimizedStubs() >= ICBinaryArith_Fallback::MAX_OPTIMIZED_STUBS) {
-        stub->noteUnoptimizableOperands();
-        return true;
-    }
-
-    // Handle string concat.
-    if (op == JSOP_ADD) {
-        if (lhs.isString() && rhs.isString()) {
-            JitSpew(JitSpew_BaselineIC, "  Generating %s(String, String) stub", js_CodeName[op]);
-            MOZ_ASSERT(ret.isString());
-            ICBinaryArith_StringConcat::Compiler compiler(cx);
-            ICStub* strcatStub = compiler.getStub(compiler.getStubSpace(script));
-            if (!strcatStub)
-                return false;
-            stub->addNewStub(strcatStub);
-            return true;
-        }
-
-        if ((lhs.isString() && rhs.isObject()) || (lhs.isObject() && rhs.isString())) {
-            JitSpew(JitSpew_BaselineIC, "  Generating %s(%s, %s) stub", js_CodeName[op],
-                    lhs.isString() ? "String" : "Object",
-                    lhs.isString() ? "Object" : "String");
-            MOZ_ASSERT(ret.isString());
-            ICBinaryArith_StringObjectConcat::Compiler compiler(cx, lhs.isString());
-            ICStub* strcatStub = compiler.getStub(compiler.getStubSpace(script));
-            if (!strcatStub)
-                return false;
-            stub->addNewStub(strcatStub);
-            return true;
-        }
-    }
-
-    if (((lhs.isBoolean() && (rhs.isBoolean() || rhs.isInt32())) ||
-         (rhs.isBoolean() && (lhs.isBoolean() || lhs.isInt32()))) &&
-        (op == JSOP_ADD || op == JSOP_SUB || op == JSOP_BITOR || op == JSOP_BITAND ||
-         op == JSOP_BITXOR))
-    {
-        JitSpew(JitSpew_BaselineIC, "  Generating %s(%s, %s) stub", js_CodeName[op],
-                lhs.isBoolean() ? "Boolean" : "Int32", rhs.isBoolean() ? "Boolean" : "Int32");
-        ICBinaryArith_BooleanWithInt32::Compiler compiler(cx, op, lhs.isBoolean(), rhs.isBoolean());
-        ICStub* arithStub = compiler.getStub(compiler.getStubSpace(script));
-        if (!arithStub)
-            return false;
-        stub->addNewStub(arithStub);
-        return true;
-    }
-
-    // Handle only int32 or double.
-    if (!lhs.isNumber() || !rhs.isNumber()) {
-        stub->noteUnoptimizableOperands();
-        return true;
-    }
-
-    MOZ_ASSERT(ret.isNumber());
-
-    if (lhs.isDouble() || rhs.isDouble() || ret.isDouble()) {
-        if (!cx->runtime()->jitSupportsFloatingPoint)
-            return true;
-
-        switch (op) {
-          case JSOP_ADD:
-          case JSOP_SUB:
-          case JSOP_MUL:
-          case JSOP_DIV:
-          case JSOP_MOD: {
-            // Unlink int32 stubs, it's faster to always use the double stub.
-            stub->unlinkStubsWithKind(cx, ICStub::BinaryArith_Int32);
-            JitSpew(JitSpew_BaselineIC, "  Generating %s(Double, Double) stub", js_CodeName[op]);
-
-            ICBinaryArith_Double::Compiler compiler(cx, op);
-            ICStub* doubleStub = compiler.getStub(compiler.getStubSpace(script));
-            if (!doubleStub)
-                return false;
-            stub->addNewStub(doubleStub);
-            return true;
-          }
-          default:
-            break;
-        }
-    }
-
-    if (lhs.isInt32() && rhs.isInt32() && op != JSOP_POW) {
-        bool allowDouble = ret.isDouble();
-        if (allowDouble)
-            stub->unlinkStubsWithKind(cx, ICStub::BinaryArith_Int32);
-        JitSpew(JitSpew_BaselineIC, "  Generating %s(Int32, Int32%s) stub", js_CodeName[op],
-                allowDouble ? " => Double" : "");
-        ICBinaryArith_Int32::Compiler compilerInt32(cx, op, allowDouble);
-        ICStub* int32Stub = compilerInt32.getStub(compilerInt32.getStubSpace(script));
-        if (!int32Stub)
-            return false;
-        stub->addNewStub(int32Stub);
-        return true;
-    }
-
-    // Handle Double <BITOP> Int32 or Int32 <BITOP> Double case.
-    if (((lhs.isDouble() && rhs.isInt32()) || (lhs.isInt32() && rhs.isDouble())) &&
-        ret.isInt32())
-    {
-        switch(op) {
-          case JSOP_BITOR:
-          case JSOP_BITXOR:
-          case JSOP_BITAND: {
-            JitSpew(JitSpew_BaselineIC, "  Generating %s(%s, %s) stub", js_CodeName[op],
-                        lhs.isDouble() ? "Double" : "Int32",
-                        lhs.isDouble() ? "Int32" : "Double");
-            ICBinaryArith_DoubleWithInt32::Compiler compiler(cx, op, lhs.isDouble());
-            ICStub* optStub = compiler.getStub(compiler.getStubSpace(script));
-            if (!optStub)
-                return false;
-            stub->addNewStub(optStub);
-            return true;
-          }
-          default:
-            break;
-        }
-    }
-
-    stub->noteUnoptimizableOperands();
-    return true;
-}
-
-typedef bool (*DoBinaryArithFallbackFn)(JSContext*, BaselineFrame*, ICBinaryArith_Fallback*,
-                                        HandleValue, HandleValue, MutableHandleValue);
-static const VMFunction DoBinaryArithFallbackInfo =
-    FunctionInfo<DoBinaryArithFallbackFn>(DoBinaryArithFallback, TailCall, PopValues(2));
-
-bool
-ICBinaryArith_Fallback::Compiler::generateStubCode(MacroAssembler& masm)
-{
-    MOZ_ASSERT(engine_ == Engine::Baseline);
-    MOZ_ASSERT(R0 == JSReturnOperand);
-
-    // Restore the tail call register.
-    EmitRestoreTailCallReg(masm);
-
-    // Ensure stack is fully synced for the expression decompiler.
-    masm.pushValue(R0);
-    masm.pushValue(R1);
-
-    // Push arguments.
-    masm.pushValue(R1);
-    masm.pushValue(R0);
-    masm.push(ICStubReg);
-    pushFramePtr(masm, R0.scratchReg());
-
-    return tailCallVM(DoBinaryArithFallbackInfo, masm);
-}
-
-static bool
-DoConcatStrings(JSContext* cx, HandleString lhs, HandleString rhs, MutableHandleValue res)
-{
-    JSString* result = ConcatStrings<CanGC>(cx, lhs, rhs);
-    if (!result)
-        return false;
-
-    res.setString(result);
-    return true;
-}
-
-typedef bool (*DoConcatStringsFn)(JSContext*, HandleString, HandleString, MutableHandleValue);
-static const VMFunction DoConcatStringsInfo = FunctionInfo<DoConcatStringsFn>(DoConcatStrings, TailCall);
-
-bool
-ICBinaryArith_StringConcat::Compiler::generateStubCode(MacroAssembler& masm)
-{
-    MOZ_ASSERT(engine_ == Engine::Baseline);
-
-    Label failure;
-    masm.branchTestString(Assembler::NotEqual, R0, &failure);
-    masm.branchTestString(Assembler::NotEqual, R1, &failure);
-
-    // Restore the tail call register.
-    EmitRestoreTailCallReg(masm);
-
-    masm.unboxString(R0, R0.scratchReg());
-    masm.unboxString(R1, R1.scratchReg());
-
-    masm.push(R1.scratchReg());
-    masm.push(R0.scratchReg());
-    if (!tailCallVM(DoConcatStringsInfo, masm))
-        return false;
-
-    // Failure case - jump to next stub
-    masm.bind(&failure);
-    EmitStubGuardFailure(masm);
-    return true;
-}
-
-static JSString*
-ConvertObjectToStringForConcat(JSContext* cx, HandleValue obj)
-{
-    MOZ_ASSERT(obj.isObject());
-    RootedValue rootedObj(cx, obj);
-    if (!ToPrimitive(cx, &rootedObj))
-        return nullptr;
-    return ToString<CanGC>(cx, rootedObj);
-}
-
-static bool
-DoConcatStringObject(JSContext* cx, bool lhsIsString, HandleValue lhs, HandleValue rhs,
-                     MutableHandleValue res)
-{
-    JSString* lstr = nullptr;
-    JSString* rstr = nullptr;
-    if (lhsIsString) {
-        // Convert rhs first.
-        MOZ_ASSERT(lhs.isString() && rhs.isObject());
-        rstr = ConvertObjectToStringForConcat(cx, rhs);
-        if (!rstr)
-            return false;
-
-        // lhs is already string.
-        lstr = lhs.toString();
-    } else {
-        MOZ_ASSERT(rhs.isString() && lhs.isObject());
-        // Convert lhs first.
-        lstr = ConvertObjectToStringForConcat(cx, lhs);
-        if (!lstr)
-            return false;
-
-        // rhs is already string.
-        rstr = rhs.toString();
-    }
-
-    JSString* str = ConcatStrings<NoGC>(cx, lstr, rstr);
-    if (!str) {
-        RootedString nlstr(cx, lstr), nrstr(cx, rstr);
-        str = ConcatStrings<CanGC>(cx, nlstr, nrstr);
-        if (!str)
-            return false;
-    }
-
-    // Technically, we need to call TypeScript::MonitorString for this PC, however
-    // it was called when this stub was attached so it's OK.
-
-    res.setString(str);
-    return true;
-}
-
-typedef bool (*DoConcatStringObjectFn)(JSContext*, bool lhsIsString, HandleValue, HandleValue,
-                                       MutableHandleValue);
-static const VMFunction DoConcatStringObjectInfo =
-    FunctionInfo<DoConcatStringObjectFn>(DoConcatStringObject, TailCall, PopValues(2));
-
-bool
-ICBinaryArith_StringObjectConcat::Compiler::generateStubCode(MacroAssembler& masm)
-{
-    MOZ_ASSERT(engine_ == Engine::Baseline);
-
-    Label failure;
-    if (lhsIsString_) {
-        masm.branchTestString(Assembler::NotEqual, R0, &failure);
-        masm.branchTestObject(Assembler::NotEqual, R1, &failure);
-    } else {
-        masm.branchTestObject(Assembler::NotEqual, R0, &failure);
-        masm.branchTestString(Assembler::NotEqual, R1, &failure);
-    }
-
-    // Restore the tail call register.
-    EmitRestoreTailCallReg(masm);
-
-    // Sync for the decompiler.
-    masm.pushValue(R0);
-    masm.pushValue(R1);
-
-    // Push arguments.
-    masm.pushValue(R1);
-    masm.pushValue(R0);
-    masm.push(Imm32(lhsIsString_));
-    if (!tailCallVM(DoConcatStringObjectInfo, masm))
-        return false;
-
-    // Failure case - jump to next stub
-    masm.bind(&failure);
-    EmitStubGuardFailure(masm);
-    return true;
-}
-
-bool
-ICBinaryArith_Double::Compiler::generateStubCode(MacroAssembler& masm)
-{
-    MOZ_ASSERT(engine_ == Engine::Baseline);
-
-    Label failure;
-    masm.ensureDouble(R0, FloatReg0, &failure);
-    masm.ensureDouble(R1, FloatReg1, &failure);
-
-    switch (op) {
-      case JSOP_ADD:
-        masm.addDouble(FloatReg1, FloatReg0);
-        break;
-      case JSOP_SUB:
-        masm.subDouble(FloatReg1, FloatReg0);
-        break;
-      case JSOP_MUL:
-        masm.mulDouble(FloatReg1, FloatReg0);
-        break;
-      case JSOP_DIV:
-        masm.divDouble(FloatReg1, FloatReg0);
-        break;
-      case JSOP_MOD:
-        masm.setupUnalignedABICall(R0.scratchReg());
-        masm.passABIArg(FloatReg0, MoveOp::DOUBLE);
-        masm.passABIArg(FloatReg1, MoveOp::DOUBLE);
-        masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, NumberMod), MoveOp::DOUBLE);
-        MOZ_ASSERT(ReturnDoubleReg == FloatReg0);
-        break;
-      default:
-        MOZ_CRASH("Unexpected op");
-    }
-
-    masm.boxDouble(FloatReg0, R0);
-    EmitReturnFromIC(masm);
-
-    // Failure case - jump to next stub
-    masm.bind(&failure);
-    EmitStubGuardFailure(masm);
-    return true;
-}
-
-bool
-ICBinaryArith_BooleanWithInt32::Compiler::generateStubCode(MacroAssembler& masm)
-{
-    MOZ_ASSERT(engine_ == Engine::Baseline);
-
-    Label failure;
-    if (lhsIsBool_)
-        masm.branchTestBoolean(Assembler::NotEqual, R0, &failure);
-    else
-        masm.branchTestInt32(Assembler::NotEqual, R0, &failure);
-
-    if (rhsIsBool_)
-        masm.branchTestBoolean(Assembler::NotEqual, R1, &failure);
-    else
-        masm.branchTestInt32(Assembler::NotEqual, R1, &failure);
-
-    Register lhsReg = lhsIsBool_ ? masm.extractBoolean(R0, ExtractTemp0)
-                                 : masm.extractInt32(R0, ExtractTemp0);
-    Register rhsReg = rhsIsBool_ ? masm.extractBoolean(R1, ExtractTemp1)
-                                 : masm.extractInt32(R1, ExtractTemp1);
-
-    MOZ_ASSERT(op_ == JSOP_ADD || op_ == JSOP_SUB ||
-               op_ == JSOP_BITOR || op_ == JSOP_BITXOR || op_ == JSOP_BITAND);
-
-    switch(op_) {
-      case JSOP_ADD: {
-        Label fixOverflow;
-
-        masm.branchAdd32(Assembler::Overflow, rhsReg, lhsReg, &fixOverflow);
-        masm.tagValue(JSVAL_TYPE_INT32, lhsReg, R0);
-        EmitReturnFromIC(masm);
-
-        masm.bind(&fixOverflow);
-        masm.sub32(rhsReg, lhsReg);
-        // Proceed to failure below.
-        break;
-      }
-      case JSOP_SUB: {
-        Label fixOverflow;
-
-        masm.branchSub32(Assembler::Overflow, rhsReg, lhsReg, &fixOverflow);
-        masm.tagValue(JSVAL_TYPE_INT32, lhsReg, R0);
-        EmitReturnFromIC(masm);
-
-        masm.bind(&fixOverflow);
-        masm.add32(rhsReg, lhsReg);
-        // Proceed to failure below.
-        break;
-      }
-      case JSOP_BITOR: {
-        masm.orPtr(rhsReg, lhsReg);
-        masm.tagValue(JSVAL_TYPE_INT32, lhsReg, R0);
-        EmitReturnFromIC(masm);
-        break;
-      }
-      case JSOP_BITXOR: {
-        masm.xorPtr(rhsReg, lhsReg);
-        masm.tagValue(JSVAL_TYPE_INT32, lhsReg, R0);
-        EmitReturnFromIC(masm);
-        break;
-      }
-      case JSOP_BITAND: {
-        masm.andPtr(rhsReg, lhsReg);
-        masm.tagValue(JSVAL_TYPE_INT32, lhsReg, R0);
-        EmitReturnFromIC(masm);
-        break;
-      }
-      default:
-       MOZ_CRASH("Unhandled op for BinaryArith_BooleanWithInt32.");
-    }
-
-    // Failure case - jump to next stub
-    masm.bind(&failure);
-    EmitStubGuardFailure(masm);
-    return true;
-}
-
-bool
-ICBinaryArith_DoubleWithInt32::Compiler::generateStubCode(MacroAssembler& masm)
-{
-    MOZ_ASSERT(engine_ == Engine::Baseline);
-    MOZ_ASSERT(op == JSOP_BITOR || op == JSOP_BITAND || op == JSOP_BITXOR);
-
-    Label failure;
-    Register intReg;
-    Register scratchReg;
-    if (lhsIsDouble_) {
-        masm.branchTestDouble(Assembler::NotEqual, R0, &failure);
-        masm.branchTestInt32(Assembler::NotEqual, R1, &failure);
-        intReg = masm.extractInt32(R1, ExtractTemp0);
-        masm.unboxDouble(R0, FloatReg0);
-        scratchReg = R0.scratchReg();
-    } else {
-        masm.branchTestInt32(Assembler::NotEqual, R0, &failure);
-        masm.branchTestDouble(Assembler::NotEqual, R1, &failure);
-        intReg = masm.extractInt32(R0, ExtractTemp0);
-        masm.unboxDouble(R1, FloatReg0);
-        scratchReg = R1.scratchReg();
-    }
-
-    // Truncate the double to an int32.
-    {
-        Label doneTruncate;
-        Label truncateABICall;
-        masm.branchTruncateDouble(FloatReg0, scratchReg, &truncateABICall);
-        masm.jump(&doneTruncate);
-
-        masm.bind(&truncateABICall);
-        masm.push(intReg);
-        masm.setupUnalignedABICall(scratchReg);
-        masm.passABIArg(FloatReg0, MoveOp::DOUBLE);
-        masm.callWithABI(mozilla::BitwiseCast<void*, int32_t(*)(double)>(JS::ToInt32));
-        masm.storeCallResult(scratchReg);
-        masm.pop(intReg);
-
-        masm.bind(&doneTruncate);
-    }
-
-    Register intReg2 = scratchReg;
-    // All handled ops commute, so no need to worry about ordering.
-    switch(op) {
-      case JSOP_BITOR:
-        masm.orPtr(intReg, intReg2);
-        break;
-      case JSOP_BITXOR:
-        masm.xorPtr(intReg, intReg2);
-        break;
-      case JSOP_BITAND:
-        masm.andPtr(intReg, intReg2);
-        break;
-      default:
-       MOZ_CRASH("Unhandled op for BinaryArith_DoubleWithInt32.");
-    }
-    masm.tagValue(JSVAL_TYPE_INT32, intReg2, R0);
-    EmitReturnFromIC(masm);
-
-    // Failure case - jump to next stub
-    masm.bind(&failure);
-    EmitStubGuardFailure(masm);
-    return true;
-}
-
-//
 // UnaryArith_Fallback
 //
 
 static bool
 DoUnaryArithFallback(JSContext* cx, BaselineFrame* frame, ICUnaryArith_Fallback* stub_,
                      HandleValue val, MutableHandleValue res)
 {
     // This fallback stub may trigger debug mode toggling.
--- a/js/src/jit/BaselineIC.h
+++ b/js/src/jit/BaselineIC.h
@@ -1099,290 +1099,16 @@ class ICToNumber_Fallback : public ICFal
           : ICStubCompiler(cx, ICStub::ToNumber_Fallback, Engine::Baseline) {}
 
         ICStub* getStub(ICStubSpace* space) {
             return newStub<ICToNumber_Fallback>(space, getStubCode());
         }
     };
 };
 
-// BinaryArith
-//      JSOP_ADD
-//      JSOP_BITAND, JSOP_BITXOR, JSOP_BITOR
-//      JSOP_LSH, JSOP_RSH, JSOP_URSH
-
-class ICBinaryArith_Fallback : public ICFallbackStub
-{
-    friend class ICStubSpace;
-
-    explicit ICBinaryArith_Fallback(JitCode* stubCode)
-      : ICFallbackStub(BinaryArith_Fallback, stubCode)
-    {
-        extra_ = 0;
-    }
-
-    static const uint16_t SAW_DOUBLE_RESULT_BIT = 0x1;
-    static const uint16_t UNOPTIMIZABLE_OPERANDS_BIT = 0x2;
-
</