Merge b2ginbound to central, a=merge
authorWes Kocher <wkocher@mozilla.com>
Thu, 17 Sep 2015 15:23:20 -0700
changeset 295718 01a75ffad1024a3f75d494fb77a022c96a497eb2
parent 295691 3929b8fc6c33bf9cc80299743063f0981f545452 (current diff)
parent 295717 1a5d7345c8430891ca5cb66bfd7c51792c453922 (diff)
child 295733 fc7b5864d8f528131f3a1b89b850eb0a82037b72
child 295746 76f3353f74fc6ceac01cfa679bfbb0d228de1668
child 295770 6031bfa8f63673c37b2f9e01cdcf9e3e0477a5dd
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 b2ginbound to central, a=merge
dom/browser-element/BrowserElementParent.js
netwerk/base/ClosingService.cpp
--- a/b2g/chrome/content/settings.js
+++ b/b2g/chrome/content/settings.js
@@ -532,16 +532,58 @@ SettingsListener.observe("theme.selected
   SettingsListener.observe('browser.proxy.port', 0, function(value) {
     Services.prefs.setIntPref('network.proxy.browsing.port', value);
     setPAC();
   });
 
   setPAC();
 })();
 
+#ifdef MOZ_B2G_RIL
+XPCOMUtils.defineLazyModuleGetter(this, "AppsUtils",
+                                  "resource://gre/modules/AppsUtils.jsm");
+
+// ======================= Dogfooders FOTA ==========================
+SettingsListener.observe('debug.performance_data.dogfooding', false,
+  isDogfooder => {
+    if (!isDogfooder) {
+      dump('AUS:Settings: Not a dogfooder!\n');
+      return;
+    }
+
+    if (!('mozTelephony' in navigator)) {
+      dump('AUS:Settings: There is no mozTelephony!\n');
+      return;
+    }
+
+    if (!('mozMobileConnections' in navigator)) {
+      dump('AUS:Settings: There is no mozMobileConnections!\n');
+      return;
+    }
+
+    let conn = navigator.mozMobileConnections[0];
+    conn.addEventListener('radiostatechange', function onradiostatechange() {
+      if (conn.radioState !== 'enabled') {
+        return;
+      }
+
+      conn.removeEventListener('radiostatechange', onradiostatechange);
+      navigator.mozTelephony.dial('*#06#').then(call => {
+        return call.result.then(res => {
+          if (res.success && res.statusMessage
+              && (res.serviceCode === 'scImei')) {
+            Services.prefs.setCharPref("app.update.imei_hash",
+                                       AppsUtils.computeHash(res.statusMessage, "SHA512"));
+          }
+        });
+      });
+    });
+  });
+#endif
+
 // =================== Various simple mapping  ======================
 var settingsToObserve = {
   'accessibility.screenreader_quicknav_modes': {
     prefName: 'accessibility.accessfu.quicknav_modes',
     resetToPref: true,
     defaultValue: ''
   },
   'accessibility.screenreader_quicknav_index': {
--- a/b2g/config/aries/sources.xml
+++ b/b2g/config/aries/sources.xml
@@ -10,21 +10,21 @@
   <!--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="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="aede8622d780ec71f766a3ecccbff74c04aaba4e"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="2082894c8e974b0c371e4dec298e0ad0f3ac56b1"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
-  <project name="moztt" path="external/moztt" remote="b2g" revision="f5d65f5b17d9766d7925aefd0486a1e526ae9bf0"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="2782648aabf0af464dd9c4202b367b408898546d"/>
   <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="a1f9532e4157df2dc8d3e9c8100120f80117dcd4"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -10,21 +10,21 @@
   <!--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="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="aede8622d780ec71f766a3ecccbff74c04aaba4e"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="2082894c8e974b0c371e4dec298e0ad0f3ac56b1"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
-  <project name="moztt" path="external/moztt" remote="b2g" revision="f5d65f5b17d9766d7925aefd0486a1e526ae9bf0"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="2782648aabf0af464dd9c4202b367b408898546d"/>
   <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="a1f9532e4157df2dc8d3e9c8100120f80117dcd4"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,22 +14,22 @@
   <!--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="aede8622d780ec71f766a3ecccbff74c04aaba4e"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="2082894c8e974b0c371e4dec298e0ad0f3ac56b1"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="27eb2f04e149fc2c9976d881b1b5984bbe7ee089"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="067c08fb3e5744b42b68d1f861245f7d507109bc"/>
-  <project name="moztt" path="external/moztt" remote="b2g" revision="f5d65f5b17d9766d7925aefd0486a1e526ae9bf0"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="2782648aabf0af464dd9c4202b367b408898546d"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
   <project name="platform_bionic" path="bionic" remote="b2g" revision="e2b3733ba3fa5e3f404e983d2e4142b1f6b1b846"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="425f8b5fadf5889834c5acd27d23c9e0b2129c28"/>
   <project name="device/common" path="device/common" revision="42b808b7e93d0619286ae8e59110b176b7732389"/>
   <project name="device/sample" path="device/sample" revision="237bd668d0f114d801a8d6455ef5e02cc3577587"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,19 +12,19 @@
   <!--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="aede8622d780ec71f766a3ecccbff74c04aaba4e"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="2082894c8e974b0c371e4dec298e0ad0f3ac56b1"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
-  <project name="moztt" path="external/moztt" remote="b2g" revision="f5d65f5b17d9766d7925aefd0486a1e526ae9bf0"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="2782648aabf0af464dd9c4202b367b408898546d"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a1f9532e4157df2dc8d3e9c8100120f80117dcd4"/>
   <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"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,21 +10,21 @@
   <!--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="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="aede8622d780ec71f766a3ecccbff74c04aaba4e"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="2082894c8e974b0c371e4dec298e0ad0f3ac56b1"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
-  <project name="moztt" path="external/moztt" remote="b2g" revision="f5d65f5b17d9766d7925aefd0486a1e526ae9bf0"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="2782648aabf0af464dd9c4202b367b408898546d"/>
   <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="a1f9532e4157df2dc8d3e9c8100120f80117dcd4"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="1950e4760fa14688b83cdbb5acaa1af9f82ef434"/>
--- a/b2g/config/emulator-l/sources.xml
+++ b/b2g/config/emulator-l/sources.xml
@@ -10,21 +10,21 @@
   <!--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="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="aede8622d780ec71f766a3ecccbff74c04aaba4e"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="2082894c8e974b0c371e4dec298e0ad0f3ac56b1"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
-  <project name="moztt" path="external/moztt" remote="b2g" revision="f5d65f5b17d9766d7925aefd0486a1e526ae9bf0"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="2782648aabf0af464dd9c4202b367b408898546d"/>
   <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="a1f9532e4157df2dc8d3e9c8100120f80117dcd4"/>
   <!-- Stock Android things -->
   <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" revision="8af5ff6f5dced9eb5a8127459df6c75d24342204"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,22 +14,22 @@
   <!--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="aede8622d780ec71f766a3ecccbff74c04aaba4e"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="2082894c8e974b0c371e4dec298e0ad0f3ac56b1"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="27eb2f04e149fc2c9976d881b1b5984bbe7ee089"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="067c08fb3e5744b42b68d1f861245f7d507109bc"/>
-  <project name="moztt" path="external/moztt" remote="b2g" revision="f5d65f5b17d9766d7925aefd0486a1e526ae9bf0"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="2782648aabf0af464dd9c4202b367b408898546d"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
   <project name="platform_bionic" path="bionic" remote="b2g" revision="e2b3733ba3fa5e3f404e983d2e4142b1f6b1b846"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="425f8b5fadf5889834c5acd27d23c9e0b2129c28"/>
   <project name="device/common" path="device/common" revision="42b808b7e93d0619286ae8e59110b176b7732389"/>
   <project name="device/sample" path="device/sample" revision="237bd668d0f114d801a8d6455ef5e02cc3577587"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -10,21 +10,21 @@
   <!--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="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="aede8622d780ec71f766a3ecccbff74c04aaba4e"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="2082894c8e974b0c371e4dec298e0ad0f3ac56b1"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
-  <project name="moztt" path="external/moztt" remote="b2g" revision="f5d65f5b17d9766d7925aefd0486a1e526ae9bf0"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="2782648aabf0af464dd9c4202b367b408898546d"/>
   <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="a1f9532e4157df2dc8d3e9c8100120f80117dcd4"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
-        "git_revision": "aede8622d780ec71f766a3ecccbff74c04aaba4e", 
+        "git_revision": "2082894c8e974b0c371e4dec298e0ad0f3ac56b1", 
         "remote": "https://git.mozilla.org/releases/gaia.git", 
         "branch": ""
     }, 
-    "revision": "dbd3a4ea9042cae987147f2d05f41d2a7ebaccbc", 
+    "revision": "0e712c8d330e10908f99194a9638e62a07c5c483", 
     "repo_path": "integration/gaia-central"
 }
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -12,19 +12,19 @@
   <!--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="aede8622d780ec71f766a3ecccbff74c04aaba4e"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="2082894c8e974b0c371e4dec298e0ad0f3ac56b1"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
-  <project name="moztt" path="external/moztt" remote="b2g" revision="f5d65f5b17d9766d7925aefd0486a1e526ae9bf0"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="2782648aabf0af464dd9c4202b367b408898546d"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a1f9532e4157df2dc8d3e9c8100120f80117dcd4"/>
   <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"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
--- a/b2g/config/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/sources.xml
@@ -10,21 +10,21 @@
   <!--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="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="aede8622d780ec71f766a3ecccbff74c04aaba4e"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="2082894c8e974b0c371e4dec298e0ad0f3ac56b1"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
-  <project name="moztt" path="external/moztt" remote="b2g" revision="f5d65f5b17d9766d7925aefd0486a1e526ae9bf0"/>
+  <project name="moztt" path="external/moztt" remote="b2g" revision="2782648aabf0af464dd9c4202b367b408898546d"/>
   <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="a1f9532e4157df2dc8d3e9c8100120f80117dcd4"/>
   <!-- Stock Android things -->
   <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" revision="8af5ff6f5dced9eb5a8127459df6c75d24342204"/>
--- a/dom/apps/AppsUtils.jsm
+++ b/dom/apps/AppsUtils.jsm
@@ -752,28 +752,28 @@ this.AppsUtils = {
       Cu.reportError("AppsUtils: Could not read from " +
                      aPath + " : " + ex + "\n" + ex.stack);
       deferred.resolve(null);
     }
 
     return deferred.promise;
   },
 
-  // Returns the MD5 hash of a string.
-  computeHash: function(aString) {
+  // Returns the hash of a string, with MD5 as a default hashing function.
+  computeHash: function(aString, aAlgorithm = "MD5") {
     let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
                       .createInstance(Ci.nsIScriptableUnicodeConverter);
     converter.charset = "UTF-8";
     let result = {};
     // Data is an array of bytes.
     let data = converter.convertToByteArray(aString, result);
 
     let hasher = Cc["@mozilla.org/security/hash;1"]
                    .createInstance(Ci.nsICryptoHash);
-    hasher.init(hasher.MD5);
+    hasher.initWithString(aAlgorithm);
     hasher.update(data, data.length);
     // We're passing false to get the binary hash and not base64.
     let hash = hasher.finish(false);
 
     function toHexString(charCode) {
       return ("0" + charCode.toString(16)).slice(-2);
     }
 
new file mode 100644
--- /dev/null
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonCoreInterface.cpp
@@ -0,0 +1,1254 @@
+/* -*- 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 "BluetoothDaemonCoreInterface.h"
+#include "mozilla/unused.h"
+
+BEGIN_BLUETOOTH_NAMESPACE
+
+using namespace mozilla::ipc;
+
+//
+// Core module
+//
+
+const int BluetoothDaemonCoreModule::MAX_NUM_CLIENTS = 1;
+
+BluetoothNotificationHandler* BluetoothDaemonCoreModule::sNotificationHandler;
+
+void
+BluetoothDaemonCoreModule::SetNotificationHandler(
+  BluetoothNotificationHandler* aNotificationHandler)
+{
+  sNotificationHandler = aNotificationHandler;
+}
+
+BluetoothNotificationHandler*
+BluetoothDaemonCoreModule::GetNotificationHandler()
+{
+  return sNotificationHandler;
+}
+
+void
+BluetoothDaemonCoreModule::HandleSvc(const DaemonSocketPDUHeader& aHeader,
+                                     DaemonSocketPDU& aPDU,
+                                     DaemonSocketResultHandler* aRes)
+{
+  static void (BluetoothDaemonCoreModule::* const HandleOp[])(
+    const DaemonSocketPDUHeader&, DaemonSocketPDU&,
+    DaemonSocketResultHandler*) = {
+    [0] = &BluetoothDaemonCoreModule::HandleRsp,
+    [1] = &BluetoothDaemonCoreModule::HandleNtf
+  };
+
+  MOZ_ASSERT(!NS_IsMainThread());
+
+  (this->*(HandleOp[!!(aHeader.mOpcode & 0x80)]))(aHeader, aPDU, aRes);
+}
+
+// Commands
+//
+
+nsresult
+BluetoothDaemonCoreModule::EnableCmd(BluetoothResultHandler* aRes)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsAutoPtr<DaemonSocketPDU> pdu(
+    new DaemonSocketPDU(SERVICE_ID, OPCODE_ENABLE,
+                        0));
+
+  nsresult rv = Send(pdu, aRes);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << pdu.forget();
+  return rv;
+}
+
+nsresult
+BluetoothDaemonCoreModule::DisableCmd(BluetoothResultHandler* aRes)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsAutoPtr<DaemonSocketPDU> pdu(
+    new DaemonSocketPDU(SERVICE_ID, OPCODE_DISABLE,
+                        0));
+
+  nsresult rv = Send(pdu, aRes);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << pdu.forget();
+  return rv;
+}
+
+nsresult
+BluetoothDaemonCoreModule::GetAdapterPropertiesCmd(
+  BluetoothResultHandler* aRes)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsAutoPtr<DaemonSocketPDU> pdu(
+    new DaemonSocketPDU(SERVICE_ID, OPCODE_GET_ADAPTER_PROPERTIES,
+                        0));
+
+  nsresult rv = Send(pdu, aRes);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << pdu.forget();
+  return rv;
+}
+
+nsresult
+BluetoothDaemonCoreModule::GetAdapterPropertyCmd(const nsAString& aName,
+                                                 BluetoothResultHandler* aRes)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsAutoPtr<DaemonSocketPDU> pdu(
+    new DaemonSocketPDU(SERVICE_ID, OPCODE_GET_ADAPTER_PROPERTY,
+                        0));
+
+  nsresult rv = PackPDU(
+    PackConversion<const nsAString, BluetoothPropertyType>(aName), *pdu);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  rv = Send(pdu, aRes);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << pdu.forget();
+  return rv;
+}
+
+nsresult
+BluetoothDaemonCoreModule::SetAdapterPropertyCmd(
+  const BluetoothNamedValue& aProperty, BluetoothResultHandler* aRes)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsAutoPtr<DaemonSocketPDU> pdu(
+    new DaemonSocketPDU(SERVICE_ID, OPCODE_SET_ADAPTER_PROPERTY,
+                        0));
+
+  nsresult rv = PackPDU(aProperty, *pdu);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  rv = Send(pdu, aRes);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << pdu.forget();
+  return rv;
+}
+
+nsresult
+BluetoothDaemonCoreModule::GetRemoteDevicePropertiesCmd(
+  const nsAString& aRemoteAddr, BluetoothResultHandler* aRes)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsAutoPtr<DaemonSocketPDU> pdu(
+    new DaemonSocketPDU(SERVICE_ID, OPCODE_GET_REMOTE_DEVICE_PROPERTIES,
+                        0));
+
+  nsresult rv = PackPDU(
+    PackConversion<nsAString, BluetoothAddress>(aRemoteAddr), *pdu);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  rv = Send(pdu, aRes);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << pdu.forget();
+  return rv;
+}
+
+nsresult
+BluetoothDaemonCoreModule::GetRemoteDevicePropertyCmd(
+  const nsAString& aRemoteAddr,
+  const nsAString& aName,
+  BluetoothResultHandler* aRes)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsAutoPtr<DaemonSocketPDU> pdu(
+    new DaemonSocketPDU(SERVICE_ID, OPCODE_GET_REMOTE_DEVICE_PROPERTY,
+                        0));
+
+  nsresult rv = PackPDU(
+    PackConversion<nsAString, BluetoothAddress>(aRemoteAddr),
+    PackConversion<nsAString, BluetoothPropertyType>(aName), *pdu);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  rv = Send(pdu, aRes);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << pdu.forget();
+  return rv;
+}
+
+nsresult
+BluetoothDaemonCoreModule::SetRemoteDevicePropertyCmd(
+  const nsAString& aRemoteAddr,
+  const BluetoothNamedValue& aProperty,
+  BluetoothResultHandler* aRes)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsAutoPtr<DaemonSocketPDU> pdu(
+    new DaemonSocketPDU(SERVICE_ID, OPCODE_SET_REMOTE_DEVICE_PROPERTY,
+                        0));
+
+  nsresult rv = PackPDU(
+    PackConversion<nsAString, BluetoothAddress>(aRemoteAddr),
+    aProperty, *pdu);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  rv = Send(pdu, aRes);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << pdu.forget();
+  return rv;
+}
+
+nsresult
+BluetoothDaemonCoreModule::GetRemoteServiceRecordCmd(
+  const nsAString& aRemoteAddr, const uint8_t aUuid[16],
+  BluetoothResultHandler* aRes)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsAutoPtr<DaemonSocketPDU> pdu(
+    new DaemonSocketPDU(SERVICE_ID, OPCODE_GET_REMOTE_SERVICE_RECORD,
+                        0));
+
+  nsresult rv = PackPDU(
+    PackConversion<nsAString, BluetoothAddress>(aRemoteAddr),
+    PackArray<uint8_t>(aUuid, 16), *pdu);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  rv = Send(pdu, aRes);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << pdu.forget();
+  return rv;
+}
+
+nsresult
+BluetoothDaemonCoreModule::GetRemoteServicesCmd(
+  const nsAString& aRemoteAddr, BluetoothResultHandler* aRes)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsAutoPtr<DaemonSocketPDU> pdu(
+    new DaemonSocketPDU(SERVICE_ID, OPCODE_GET_REMOTE_SERVICES, 0));
+
+  nsresult rv = PackPDU(
+    PackConversion<nsAString, BluetoothAddress>(aRemoteAddr), *pdu);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  rv = Send(pdu, aRes);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << pdu.forget();
+  return rv;
+}
+
+nsresult
+BluetoothDaemonCoreModule::StartDiscoveryCmd(BluetoothResultHandler* aRes)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsAutoPtr<DaemonSocketPDU> pdu(
+    new DaemonSocketPDU(SERVICE_ID, OPCODE_START_DISCOVERY,
+                        0));
+
+  nsresult rv = Send(pdu, aRes);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << pdu.forget();
+  return rv;
+}
+
+nsresult
+BluetoothDaemonCoreModule::CancelDiscoveryCmd(BluetoothResultHandler* aRes)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsAutoPtr<DaemonSocketPDU> pdu(
+    new DaemonSocketPDU(SERVICE_ID, OPCODE_CANCEL_DISCOVERY,
+                        0));
+
+  nsresult rv = Send(pdu, aRes);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << pdu.forget();
+  return rv;
+}
+
+nsresult
+BluetoothDaemonCoreModule::CreateBondCmd(const nsAString& aBdAddr,
+                                         BluetoothTransport aTransport,
+                                         BluetoothResultHandler* aRes)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsAutoPtr<DaemonSocketPDU> pdu(
+    new DaemonSocketPDU(SERVICE_ID, OPCODE_CREATE_BOND,
+                        0));
+
+#if ANDROID_VERSION >= 21
+  nsresult rv = PackPDU(
+    PackConversion<nsAString, BluetoothAddress>(aBdAddr), aTransport, *pdu);
+#else
+  nsresult rv = PackPDU(
+    PackConversion<nsAString, BluetoothAddress>(aBdAddr), *pdu);
+#endif
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  rv = Send(pdu, aRes);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << pdu.forget();
+  return rv;
+}
+
+nsresult
+BluetoothDaemonCoreModule::RemoveBondCmd(const nsAString& aBdAddr,
+                                         BluetoothResultHandler* aRes)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsAutoPtr<DaemonSocketPDU> pdu(
+    new DaemonSocketPDU(SERVICE_ID, OPCODE_REMOVE_BOND,
+                        0));
+
+  nsresult rv = PackPDU(
+    PackConversion<nsAString, BluetoothAddress>(aBdAddr), *pdu);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  rv = Send(pdu, aRes);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << pdu.forget();
+  return rv;
+}
+
+nsresult
+BluetoothDaemonCoreModule::CancelBondCmd(const nsAString& aBdAddr,
+                                         BluetoothResultHandler* aRes)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsAutoPtr<DaemonSocketPDU> pdu(
+    new DaemonSocketPDU(SERVICE_ID, OPCODE_CANCEL_BOND,
+                        0));
+
+  nsresult rv = PackPDU(
+    PackConversion<nsAString, BluetoothAddress>(aBdAddr), *pdu);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  rv = Send(pdu, aRes);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << pdu.forget();
+  return rv;
+}
+
+nsresult
+BluetoothDaemonCoreModule::PinReplyCmd(const nsAString& aBdAddr, bool aAccept,
+                                       const nsAString& aPinCode,
+                                       BluetoothResultHandler* aRes)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsAutoPtr<DaemonSocketPDU> pdu(
+    new DaemonSocketPDU(SERVICE_ID, OPCODE_PIN_REPLY,
+                        0));
+
+  nsresult rv = PackPDU(
+    PackConversion<nsAString, BluetoothAddress>(aBdAddr),
+    aAccept,
+    PackConversion<nsAString, BluetoothPinCode>(aPinCode), *pdu);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  rv = Send(pdu, aRes);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << pdu.forget();
+  return rv;
+}
+
+nsresult
+BluetoothDaemonCoreModule::SspReplyCmd(const nsAString& aBdAddr,
+                                       BluetoothSspVariant aVariant,
+                                       bool aAccept, uint32_t aPasskey,
+                                       BluetoothResultHandler* aRes)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsAutoPtr<DaemonSocketPDU> pdu(
+    new DaemonSocketPDU(SERVICE_ID, OPCODE_SSP_REPLY,
+                        0));
+
+  nsresult rv = PackPDU(
+    PackConversion<nsAString, BluetoothAddress>(aBdAddr),
+    aVariant, aAccept, aPasskey, *pdu);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  rv = Send(pdu, aRes);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << pdu.forget();
+  return rv;
+}
+
+nsresult
+BluetoothDaemonCoreModule::DutModeConfigureCmd(bool aEnable,
+                                               BluetoothResultHandler* aRes)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsAutoPtr<DaemonSocketPDU> pdu(
+    new DaemonSocketPDU(SERVICE_ID, OPCODE_DUT_MODE_CONFIGURE,
+                        0));
+
+  nsresult rv = PackPDU(aEnable, *pdu);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  rv = Send(pdu, aRes);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << pdu.forget();
+  return rv;
+}
+
+nsresult
+BluetoothDaemonCoreModule::DutModeSendCmd(uint16_t aOpcode,
+                                          uint8_t* aBuf, uint8_t aLen,
+                                          BluetoothResultHandler* aRes)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsAutoPtr<DaemonSocketPDU> pdu(
+    new DaemonSocketPDU(SERVICE_ID, OPCODE_DUT_MODE_SEND,
+                        0));
+
+  nsresult rv = PackPDU(aOpcode, aLen, PackArray<uint8_t>(aBuf, aLen),
+                        *pdu);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  rv = Send(pdu, aRes);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << pdu.forget();
+  return rv;
+}
+
+nsresult
+BluetoothDaemonCoreModule::LeTestModeCmd(uint16_t aOpcode,
+                                         uint8_t* aBuf, uint8_t aLen,
+                                         BluetoothResultHandler* aRes)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsAutoPtr<DaemonSocketPDU> pdu(
+    new DaemonSocketPDU(SERVICE_ID, OPCODE_LE_TEST_MODE,
+                        0));
+
+  nsresult rv = PackPDU(aOpcode, aLen, PackArray<uint8_t>(aBuf, aLen),
+                        *pdu);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  rv = Send(pdu, aRes);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  unused << pdu.forget();
+  return rv;
+}
+
+// Responses
+//
+
+void
+BluetoothDaemonCoreModule::ErrorRsp(const DaemonSocketPDUHeader& aHeader,
+                                    DaemonSocketPDU& aPDU,
+                                    BluetoothResultHandler* aRes)
+{
+  ErrorRunnable::Dispatch(
+    aRes, &BluetoothResultHandler::OnError, UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonCoreModule::EnableRsp(const DaemonSocketPDUHeader& aHeader,
+                                     DaemonSocketPDU& aPDU,
+                                     BluetoothResultHandler* aRes)
+{
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothResultHandler::Enable, UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonCoreModule::DisableRsp(const DaemonSocketPDUHeader& aHeader,
+                                      DaemonSocketPDU& aPDU,
+                                      BluetoothResultHandler* aRes)
+{
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothResultHandler::Disable, UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonCoreModule::GetAdapterPropertiesRsp(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+  BluetoothResultHandler* aRes)
+{
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothResultHandler::GetAdapterProperties,
+    UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonCoreModule::GetAdapterPropertyRsp(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+  BluetoothResultHandler* aRes)
+{
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothResultHandler::GetAdapterProperty,
+    UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonCoreModule::SetAdapterPropertyRsp(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+  BluetoothResultHandler* aRes)
+{
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothResultHandler::SetAdapterProperty,
+    UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonCoreModule::GetRemoteDevicePropertiesRsp(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+  BluetoothResultHandler* aRes)
+{
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothResultHandler::GetRemoteDeviceProperties,
+    UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonCoreModule::GetRemoteDevicePropertyRsp(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+  BluetoothResultHandler* aRes)
+{
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothResultHandler::GetRemoteDeviceProperty,
+    UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonCoreModule::SetRemoteDevicePropertyRsp(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+  BluetoothResultHandler* aRes)
+{
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothResultHandler::SetRemoteDeviceProperty,
+    UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonCoreModule::GetRemoteServiceRecordRsp(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+  BluetoothResultHandler* aRes)
+{
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothResultHandler::GetRemoteServiceRecord,
+    UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonCoreModule::GetRemoteServicesRsp(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+  BluetoothResultHandler* aRes)
+{
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothResultHandler::GetRemoteServices,
+    UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonCoreModule::StartDiscoveryRsp(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+  BluetoothResultHandler* aRes)
+{
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothResultHandler::StartDiscovery,
+    UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonCoreModule::CancelDiscoveryRsp(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+  BluetoothResultHandler* aRes)
+{
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothResultHandler::CancelDiscovery,
+    UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonCoreModule::CreateBondRsp(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+  BluetoothResultHandler* aRes)
+{
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothResultHandler::CreateBond,
+    UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonCoreModule::RemoveBondRsp(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+  BluetoothResultHandler* aRes)
+{
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothResultHandler::RemoveBond,
+    UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonCoreModule::CancelBondRsp(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+  BluetoothResultHandler* aRes)
+{
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothResultHandler::CancelBond,
+    UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonCoreModule::PinReplyRsp(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+  BluetoothResultHandler* aRes)
+{
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothResultHandler::PinReply,
+    UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonCoreModule::SspReplyRsp(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+  BluetoothResultHandler* aRes)
+{
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothResultHandler::SspReply,
+    UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonCoreModule::DutModeConfigureRsp(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+  BluetoothResultHandler* aRes)
+{
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothResultHandler::DutModeConfigure,
+    UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonCoreModule::DutModeSendRsp(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+  BluetoothResultHandler* aRes)
+{
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothResultHandler::DutModeSend,
+    UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonCoreModule::LeTestModeRsp(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+  BluetoothResultHandler* aRes)
+{
+  ResultRunnable::Dispatch(
+    aRes, &BluetoothResultHandler::LeTestMode,
+    UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonCoreModule::HandleRsp(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+  DaemonSocketResultHandler* aRes)
+{
+  static void (BluetoothDaemonCoreModule::* const HandleRsp[])(
+    const DaemonSocketPDUHeader&,
+    DaemonSocketPDU&,
+    BluetoothResultHandler*) = {
+    [OPCODE_ERROR] =
+      &BluetoothDaemonCoreModule::ErrorRsp,
+    [OPCODE_ENABLE] =
+      &BluetoothDaemonCoreModule::EnableRsp,
+    [OPCODE_DISABLE] =
+      &BluetoothDaemonCoreModule::DisableRsp,
+    [OPCODE_GET_ADAPTER_PROPERTIES] =
+      &BluetoothDaemonCoreModule::GetAdapterPropertiesRsp,
+    [OPCODE_GET_ADAPTER_PROPERTY] =
+      &BluetoothDaemonCoreModule::GetAdapterPropertyRsp,
+    [OPCODE_SET_ADAPTER_PROPERTY] =
+      &BluetoothDaemonCoreModule::SetAdapterPropertyRsp,
+    [OPCODE_GET_REMOTE_DEVICE_PROPERTIES] =
+      &BluetoothDaemonCoreModule::GetRemoteDevicePropertiesRsp,
+    [OPCODE_GET_REMOTE_DEVICE_PROPERTY] =
+      &BluetoothDaemonCoreModule::GetRemoteDevicePropertyRsp,
+    [OPCODE_SET_REMOTE_DEVICE_PROPERTY] =
+      &BluetoothDaemonCoreModule::SetRemoteDevicePropertyRsp,
+    [OPCODE_GET_REMOTE_SERVICE_RECORD] =
+      &BluetoothDaemonCoreModule::GetRemoteServiceRecordRsp,
+    [OPCODE_GET_REMOTE_SERVICES] =
+      &BluetoothDaemonCoreModule::GetRemoteServicesRsp,
+    [OPCODE_START_DISCOVERY] =
+      &BluetoothDaemonCoreModule::StartDiscoveryRsp,
+    [OPCODE_CANCEL_DISCOVERY] =
+      &BluetoothDaemonCoreModule::CancelDiscoveryRsp,
+    [OPCODE_CREATE_BOND] =
+      &BluetoothDaemonCoreModule::CreateBondRsp,
+    [OPCODE_REMOVE_BOND] =
+      &BluetoothDaemonCoreModule::RemoveBondRsp,
+    [OPCODE_CANCEL_BOND] =
+      &BluetoothDaemonCoreModule::CancelBondRsp,
+    [OPCODE_PIN_REPLY] =
+      &BluetoothDaemonCoreModule::PinReplyRsp,
+    [OPCODE_SSP_REPLY] =
+      &BluetoothDaemonCoreModule::SspReplyRsp,
+    [OPCODE_DUT_MODE_CONFIGURE] =
+      &BluetoothDaemonCoreModule::DutModeConfigureRsp,
+    [OPCODE_DUT_MODE_SEND] =
+      &BluetoothDaemonCoreModule::DutModeSendRsp,
+    [OPCODE_LE_TEST_MODE] =
+      &BluetoothDaemonCoreModule::LeTestModeRsp,
+  };
+
+  MOZ_ASSERT(!NS_IsMainThread());
+
+  if (NS_WARN_IF(!(aHeader.mOpcode < MOZ_ARRAY_LENGTH(HandleRsp))) ||
+      NS_WARN_IF(!HandleRsp[aHeader.mOpcode])) {
+    return;
+  }
+
+  nsRefPtr<BluetoothResultHandler> res =
+    static_cast<BluetoothResultHandler*>(aRes);
+
+  if (!res) {
+    return; // Return early if no result handler has been set for response
+  }
+
+  (this->*(HandleRsp[aHeader.mOpcode]))(aHeader, aPDU, res);
+}
+
+// Notifications
+//
+
+class BluetoothDaemonCoreModule::NotificationHandlerWrapper final
+{
+public:
+  typedef BluetoothNotificationHandler ObjectType;
+
+  static ObjectType* GetInstance()
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+
+    return sNotificationHandler;
+  }
+};
+
+void
+BluetoothDaemonCoreModule::AdapterStateChangedNtf(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
+{
+  AdapterStateChangedNotification::Dispatch(
+    &BluetoothNotificationHandler::AdapterStateChangedNotification,
+    UnpackPDUInitOp(aPDU));
+}
+
+// Init operator class for AdapterPropertiesNotification
+class BluetoothDaemonCoreModule::AdapterPropertiesInitOp final
+  : private PDUInitOp
+{
+public:
+  AdapterPropertiesInitOp(DaemonSocketPDU& aPDU)
+    : PDUInitOp(aPDU)
+  { }
+
+  nsresult
+  operator () (BluetoothStatus& aArg1, int& aArg2,
+               nsAutoArrayPtr<BluetoothProperty>& aArg3) const
+  {
+    DaemonSocketPDU& pdu = GetPDU();
+
+    /* Read status */
+    nsresult rv = UnpackPDU(pdu, aArg1);
+    if (NS_FAILED(rv)) {
+        return rv;
+    }
+
+    /* Read number of properties */
+    uint8_t numProperties;
+    rv = UnpackPDU(pdu, numProperties);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+    aArg2 = numProperties;
+
+    /* Read properties array */
+    UnpackArray<BluetoothProperty> properties(aArg3, aArg2);
+    rv = UnpackPDU(pdu, properties);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+    WarnAboutTrailingData();
+    return NS_OK;
+  }
+};
+
+void
+BluetoothDaemonCoreModule::AdapterPropertiesNtf(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
+{
+  AdapterPropertiesNotification::Dispatch(
+    &BluetoothNotificationHandler::AdapterPropertiesNotification,
+    AdapterPropertiesInitOp(aPDU));
+}
+
+// Init operator class for RemoteDevicePropertiesNotification
+class BluetoothDaemonCoreModule::RemoteDevicePropertiesInitOp final
+  : private PDUInitOp
+{
+public:
+  RemoteDevicePropertiesInitOp(DaemonSocketPDU& aPDU)
+    : PDUInitOp(aPDU)
+  { }
+
+  nsresult
+  operator () (BluetoothStatus& aArg1, nsString& aArg2, int& aArg3,
+               nsAutoArrayPtr<BluetoothProperty>& aArg4) const
+  {
+    DaemonSocketPDU& pdu = GetPDU();
+
+    /* Read status */
+    nsresult rv = UnpackPDU(pdu, aArg1);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    /* Read address */
+    rv = UnpackPDU(
+      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    /* Read number of properties */
+    uint8_t numProperties;
+    rv = UnpackPDU(pdu, numProperties);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+    aArg3 = numProperties;
+
+    /* Read properties array */
+    UnpackArray<BluetoothProperty> properties(aArg4, aArg3);
+    rv = UnpackPDU(pdu, properties);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+    WarnAboutTrailingData();
+    return NS_OK;
+  }
+};
+
+void
+BluetoothDaemonCoreModule::RemoteDevicePropertiesNtf(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
+{
+  RemoteDevicePropertiesNotification::Dispatch(
+    &BluetoothNotificationHandler::RemoteDevicePropertiesNotification,
+    RemoteDevicePropertiesInitOp(aPDU));
+}
+
+// Init operator class for DeviceFoundNotification
+class BluetoothDaemonCoreModule::DeviceFoundInitOp final
+  : private PDUInitOp
+{
+public:
+  DeviceFoundInitOp(DaemonSocketPDU& aPDU)
+    : PDUInitOp(aPDU)
+  { }
+
+  nsresult
+  operator () (int& aArg1, nsAutoArrayPtr<BluetoothProperty>& aArg2) const
+  {
+    DaemonSocketPDU& pdu = GetPDU();
+
+    /* Read number of properties */
+    uint8_t numProperties;
+    nsresult rv = UnpackPDU(pdu, numProperties);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+    aArg1 = numProperties;
+
+    /* Read properties array */
+    UnpackArray<BluetoothProperty> properties(aArg2, aArg1);
+    rv = UnpackPDU(pdu, properties);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+    WarnAboutTrailingData();
+    return NS_OK;
+  }
+};
+
+void
+BluetoothDaemonCoreModule::DeviceFoundNtf(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
+{
+  DeviceFoundNotification::Dispatch(
+    &BluetoothNotificationHandler::DeviceFoundNotification,
+    DeviceFoundInitOp(aPDU));
+}
+
+void
+BluetoothDaemonCoreModule::DiscoveryStateChangedNtf(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
+{
+  DiscoveryStateChangedNotification::Dispatch(
+    &BluetoothNotificationHandler::DiscoveryStateChangedNotification,
+    UnpackPDUInitOp(aPDU));
+}
+
+// Init operator class for PinRequestNotification
+class BluetoothDaemonCoreModule::PinRequestInitOp final
+  : private PDUInitOp
+{
+public:
+  PinRequestInitOp(DaemonSocketPDU& aPDU)
+    : PDUInitOp(aPDU)
+  { }
+
+  nsresult
+  operator () (nsString& aArg1, nsString& aArg2, uint32_t& aArg3) const
+  {
+    DaemonSocketPDU& pdu = GetPDU();
+
+    /* Read remote address */
+    nsresult rv = UnpackPDU(
+      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg1));
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    /* Read remote name */
+    rv = UnpackPDU(
+      pdu, UnpackConversion<BluetoothRemoteName, nsAString>(aArg2));
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    /* Read CoD */
+    rv = UnpackPDU(pdu, aArg3);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+    WarnAboutTrailingData();
+    return NS_OK;
+  }
+};
+
+void
+BluetoothDaemonCoreModule::PinRequestNtf(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
+{
+  PinRequestNotification::Dispatch(
+    &BluetoothNotificationHandler::PinRequestNotification,
+    PinRequestInitOp(aPDU));
+}
+
+// Init operator class for SspRequestNotification
+class BluetoothDaemonCoreModule::SspRequestInitOp final
+  : private PDUInitOp
+{
+public:
+  SspRequestInitOp(DaemonSocketPDU& aPDU)
+    : PDUInitOp(aPDU)
+  { }
+
+  nsresult
+  operator () (nsString& aArg1, nsString& aArg2, uint32_t& aArg3,
+               BluetoothSspVariant& aArg4, uint32_t& aArg5) const
+  {
+    DaemonSocketPDU& pdu = GetPDU();
+
+    /* Read remote address */
+    nsresult rv = UnpackPDU(
+      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg1));
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    /* Read remote name */
+    rv = UnpackPDU(
+      pdu, UnpackConversion<BluetoothRemoteName, nsAString>(aArg2));
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    /* Read CoD */
+    rv = UnpackPDU(pdu, aArg3);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    /* Read pairing variant */
+    rv = UnpackPDU(pdu, aArg4);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    /* Read passkey */
+    rv = UnpackPDU(pdu, aArg5);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+    WarnAboutTrailingData();
+    return NS_OK;
+  }
+};
+
+void
+BluetoothDaemonCoreModule::SspRequestNtf(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
+{
+  SspRequestNotification::Dispatch(
+    &BluetoothNotificationHandler::SspRequestNotification,
+    SspRequestInitOp(aPDU));
+}
+
+// Init operator class for BondStateChangedNotification
+class BluetoothDaemonCoreModule::BondStateChangedInitOp final
+  : private PDUInitOp
+{
+public:
+  BondStateChangedInitOp(DaemonSocketPDU& aPDU)
+    : PDUInitOp(aPDU)
+  { }
+
+  nsresult
+  operator () (BluetoothStatus& aArg1, nsString& aArg2,
+               BluetoothBondState& aArg3) const
+  {
+    DaemonSocketPDU& pdu = GetPDU();
+
+    /* Read status */
+    nsresult rv = UnpackPDU(pdu, aArg1);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    /* Read remote address */
+    rv = UnpackPDU(
+      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    /* Read bond state */
+    rv = UnpackPDU(pdu, aArg3);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+    WarnAboutTrailingData();
+    return NS_OK;
+  }
+};
+
+void
+BluetoothDaemonCoreModule::BondStateChangedNtf(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
+{
+  BondStateChangedNotification::Dispatch(
+    &BluetoothNotificationHandler::BondStateChangedNotification,
+    BondStateChangedInitOp(aPDU));
+}
+
+// Init operator class for AclStateChangedNotification
+class BluetoothDaemonCoreModule::AclStateChangedInitOp final
+  : private PDUInitOp
+{
+public:
+  AclStateChangedInitOp(DaemonSocketPDU& aPDU)
+    : PDUInitOp(aPDU)
+  { }
+
+  nsresult
+  operator () (BluetoothStatus& aArg1, nsString& aArg2, bool& aArg3) const
+  {
+    DaemonSocketPDU& pdu = GetPDU();
+
+    /* Read status */
+    nsresult rv = UnpackPDU(pdu, aArg1);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    /* Read remote address */
+    rv = UnpackPDU(
+      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    /* Read ACL state */
+    rv = UnpackPDU(
+      pdu, UnpackConversion<BluetoothAclState, bool>(aArg3));
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+    WarnAboutTrailingData();
+    return NS_OK;
+  }
+};
+
+void
+BluetoothDaemonCoreModule::AclStateChangedNtf(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
+{
+  AclStateChangedNotification::Dispatch(
+    &BluetoothNotificationHandler::AclStateChangedNotification,
+    AclStateChangedInitOp(aPDU));
+}
+
+// Init operator class for DutModeRecvNotification
+class BluetoothDaemonCoreModule::DutModeRecvInitOp final
+  : private PDUInitOp
+{
+public:
+  DutModeRecvInitOp(DaemonSocketPDU& aPDU)
+    : PDUInitOp(aPDU)
+  { }
+
+  nsresult
+  operator () (uint16_t& aArg1, nsAutoArrayPtr<uint8_t>& aArg2,
+               uint8_t& aArg3) const
+  {
+    DaemonSocketPDU& pdu = GetPDU();
+
+    /* Read opcode */
+    nsresult rv = UnpackPDU(pdu, aArg1);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    /* Read length */
+    rv = UnpackPDU(pdu, aArg3);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    /* Read data */
+    rv = UnpackPDU(pdu, UnpackArray<uint8_t>(aArg2, aArg3));
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+    WarnAboutTrailingData();
+    return NS_OK;
+  }
+};
+
+void
+BluetoothDaemonCoreModule::DutModeRecvNtf(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
+{
+  DutModeRecvNotification::Dispatch(
+    &BluetoothNotificationHandler::DutModeRecvNotification,
+    DutModeRecvInitOp(aPDU));
+}
+
+void
+BluetoothDaemonCoreModule::LeTestModeNtf(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
+{
+  LeTestModeNotification::Dispatch(
+    &BluetoothNotificationHandler::LeTestModeNotification,
+    UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonCoreModule::HandleNtf(
+  const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+  DaemonSocketResultHandler* aRes)
+{
+  static void (BluetoothDaemonCoreModule::* const HandleNtf[])(
+    const DaemonSocketPDUHeader&, DaemonSocketPDU&) = {
+    [0] = &BluetoothDaemonCoreModule::AdapterStateChangedNtf,
+    [1] = &BluetoothDaemonCoreModule::AdapterPropertiesNtf,
+    [2] = &BluetoothDaemonCoreModule::RemoteDevicePropertiesNtf,
+    [3] = &BluetoothDaemonCoreModule::DeviceFoundNtf,
+    [4] = &BluetoothDaemonCoreModule::DiscoveryStateChangedNtf,
+    [5] = &BluetoothDaemonCoreModule::PinRequestNtf,
+    [6] = &BluetoothDaemonCoreModule::SspRequestNtf,
+    [7] = &BluetoothDaemonCoreModule::BondStateChangedNtf,
+    [8] = &BluetoothDaemonCoreModule::AclStateChangedNtf,
+    [9] = &BluetoothDaemonCoreModule::DutModeRecvNtf,
+    [10] = &BluetoothDaemonCoreModule::LeTestModeNtf
+  };
+
+  MOZ_ASSERT(!NS_IsMainThread());
+
+  uint8_t index = aHeader.mOpcode - 0x81;
+
+  if (NS_WARN_IF(!(index < MOZ_ARRAY_LENGTH(HandleNtf))) ||
+      NS_WARN_IF(!HandleNtf[index])) {
+    return;
+  }
+
+    (this->*(HandleNtf[index]))(aHeader, aPDU);
+}
+
+END_BLUETOOTH_NAMESPACE
new file mode 100644
--- /dev/null
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonCoreInterface.h
@@ -0,0 +1,346 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_bluetooth_bluedroid_BluetoothDaemonCoreInterface_h
+#define mozilla_dom_bluetooth_bluedroid_BluetoothDaemonCoreInterface_h
+
+#include "BluetoothDaemonHelpers.h"
+#include "BluetoothInterface.h"
+#include "mozilla/ipc/DaemonRunnables.h"
+
+BEGIN_BLUETOOTH_NAMESPACE
+
+using mozilla::ipc::DaemonSocketPDU;
+using mozilla::ipc::DaemonSocketPDUHeader;
+using mozilla::ipc::DaemonSocketResultHandler;
+
+class BluetoothDaemonCoreModule
+{
+public:
+  enum {
+    SERVICE_ID = 0x01
+  };
+
+  enum {
+    OPCODE_ERROR = 0x00,
+    OPCODE_ENABLE = 0x01,
+    OPCODE_DISABLE = 0x02,
+    OPCODE_GET_ADAPTER_PROPERTIES = 0x03,
+    OPCODE_GET_ADAPTER_PROPERTY = 0x04,
+    OPCODE_SET_ADAPTER_PROPERTY = 0x05,
+    OPCODE_GET_REMOTE_DEVICE_PROPERTIES = 0x06,
+    OPCODE_GET_REMOTE_DEVICE_PROPERTY = 0x07,
+    OPCODE_SET_REMOTE_DEVICE_PROPERTY = 0x08,
+    OPCODE_GET_REMOTE_SERVICE_RECORD = 0x09,
+    OPCODE_GET_REMOTE_SERVICES = 0x0a,
+    OPCODE_START_DISCOVERY = 0x0b,
+    OPCODE_CANCEL_DISCOVERY = 0x0c,
+    OPCODE_CREATE_BOND = 0x0d,
+    OPCODE_REMOVE_BOND = 0x0e,
+    OPCODE_CANCEL_BOND = 0x0f,
+    OPCODE_PIN_REPLY = 0x10,
+    OPCODE_SSP_REPLY = 0x11,
+    OPCODE_DUT_MODE_CONFIGURE = 0x12,
+    OPCODE_DUT_MODE_SEND = 0x13,
+    OPCODE_LE_TEST_MODE = 0x14,
+    OPCODE_ADAPTER_STATE_CHANGED_NTF = 0x81,
+    OPCODE_ADAPTER_PROPERTIES_NTF = 0x82,
+    OPCODE_REMOTE_DEVICE_PROPERTIES_NTF = 0x83,
+    OPCODE_DEVICE_FOUND_NTF = 0x84,
+    OPCODE_DISCOVERY_STATE_CHANGED_NTF = 0x85,
+    OPCODE_PIN_REQUEST_NTF = 0x86,
+    OPCODE_SSP_REQUEST_NTF = 0x87,
+    OPCODE_BOND_STATE_CHANGED_NTF = 0x88,
+    OPCODE_ACL_STATE_CHANGED_NTF = 0x89,
+    OPCODE_DUT_MODE_RECV_NTF = 0x8a,
+    OPCODE_LE_TEST_MODE_NTF = 0x8b
+  };
+
+  static const int MAX_NUM_CLIENTS;
+
+  virtual nsresult Send(DaemonSocketPDU* aPDU,
+                        DaemonSocketResultHandler* aRes) = 0;
+
+  void SetNotificationHandler(
+    BluetoothNotificationHandler* aNotificationHandler);
+
+  BluetoothNotificationHandler* GetNotificationHandler();
+
+  //
+  // Commands
+  //
+
+  nsresult EnableCmd(BluetoothResultHandler* aRes);
+
+  nsresult DisableCmd(BluetoothResultHandler* aRes);
+
+  nsresult GetAdapterPropertiesCmd(BluetoothResultHandler* aRes);
+
+  nsresult GetAdapterPropertyCmd(const nsAString& aName,
+                                 BluetoothResultHandler* aRes);
+
+  nsresult SetAdapterPropertyCmd(const BluetoothNamedValue& aProperty,
+                                 BluetoothResultHandler* aRes);
+
+  nsresult GetRemoteDevicePropertiesCmd(const nsAString& aRemoteAddr,
+                                        BluetoothResultHandler* aRes);
+
+  nsresult GetRemoteDevicePropertyCmd(const nsAString& aRemoteAddr,
+                                      const nsAString& aName,
+                                      BluetoothResultHandler* aRes);
+
+  nsresult SetRemoteDevicePropertyCmd(const nsAString& aRemoteAddr,
+                                      const BluetoothNamedValue& aProperty,
+                                      BluetoothResultHandler* aRes);
+
+  nsresult GetRemoteServiceRecordCmd(const nsAString& aRemoteAddr,
+                                     const uint8_t aUuid[16],
+                                     BluetoothResultHandler* aRes);
+
+  nsresult GetRemoteServicesCmd(const nsAString& aRemoteAddr,
+                                BluetoothResultHandler* aRes);
+
+  nsresult StartDiscoveryCmd(BluetoothResultHandler* aRes);
+
+  nsresult CancelDiscoveryCmd(BluetoothResultHandler* aRes);
+
+  nsresult CreateBondCmd(const nsAString& aBdAddr,
+                         BluetoothTransport aTransport,
+                         BluetoothResultHandler* aRes);
+
+  nsresult RemoveBondCmd(const nsAString& aBdAddr,
+                         BluetoothResultHandler* aRes);
+
+  nsresult CancelBondCmd(const nsAString& aBdAddr,
+                         BluetoothResultHandler* aRes);
+
+  nsresult PinReplyCmd(const nsAString& aBdAddr, bool aAccept,
+                       const nsAString& aPinCode,
+                       BluetoothResultHandler* aRes);
+
+  nsresult SspReplyCmd(const nsAString& aBdAddr, BluetoothSspVariant aVariant,
+                       bool aAccept, uint32_t aPasskey,
+                       BluetoothResultHandler* aRes);
+
+  nsresult DutModeConfigureCmd(bool aEnable, BluetoothResultHandler* aRes);
+
+  nsresult DutModeSendCmd(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
+                          BluetoothResultHandler* aRes);
+
+  nsresult LeTestModeCmd(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
+                         BluetoothResultHandler* aRes);
+
+protected:
+  void HandleSvc(const DaemonSocketPDUHeader& aHeader,
+                 DaemonSocketPDU& aPDU, DaemonSocketResultHandler* aRes);
+
+private:
+
+  //
+  // Responses
+  //
+
+  typedef mozilla::ipc::DaemonResultRunnable0<
+    BluetoothResultHandler, void>
+    ResultRunnable;
+
+  typedef mozilla::ipc::DaemonResultRunnable1<
+    BluetoothResultHandler, void, BluetoothStatus, BluetoothStatus>
+    ErrorRunnable;
+
+  void ErrorRsp(const DaemonSocketPDUHeader& aHeader,
+                DaemonSocketPDU& aPDU,
+                BluetoothResultHandler* aRes);
+
+  void EnableRsp(const DaemonSocketPDUHeader& aHeader,
+                 DaemonSocketPDU& aPDU,
+                 BluetoothResultHandler* aRes);
+
+  void DisableRsp(const DaemonSocketPDUHeader& aHeader,
+                  DaemonSocketPDU& aPDU,
+                  BluetoothResultHandler* aRes);
+
+  void GetAdapterPropertiesRsp(const DaemonSocketPDUHeader& aHeader,
+                               DaemonSocketPDU& aPDU,
+                               BluetoothResultHandler* aRes);
+
+  void GetAdapterPropertyRsp(const DaemonSocketPDUHeader& aHeader,
+                             DaemonSocketPDU& aPDU,
+                             BluetoothResultHandler* aRes);
+
+  void SetAdapterPropertyRsp(const DaemonSocketPDUHeader& aHeader,
+                             DaemonSocketPDU& aPDU,
+                             BluetoothResultHandler* aRes);
+
+  void GetRemoteDevicePropertiesRsp(const DaemonSocketPDUHeader& aHeader,
+                                    DaemonSocketPDU& aPDU,
+                                    BluetoothResultHandler* aRes);
+
+  void
+  GetRemoteDevicePropertyRsp(const DaemonSocketPDUHeader& aHeader,
+                             DaemonSocketPDU& aPDU,
+                             BluetoothResultHandler* aRes);
+
+  void SetRemoteDevicePropertyRsp(const DaemonSocketPDUHeader& aHeader,
+                                  DaemonSocketPDU& aPDU,
+                                  BluetoothResultHandler* aRes);
+  void GetRemoteServiceRecordRsp(const DaemonSocketPDUHeader& aHeader,
+                                 DaemonSocketPDU& aPDU,
+                                 BluetoothResultHandler* aRes);
+  void GetRemoteServicesRsp(const DaemonSocketPDUHeader& aHeader,
+                            DaemonSocketPDU& aPDU,
+                            BluetoothResultHandler* aRes);
+
+  void StartDiscoveryRsp(const DaemonSocketPDUHeader& aHeader,
+                         DaemonSocketPDU& aPDU,
+                         BluetoothResultHandler* aRes);
+  void CancelDiscoveryRsp(const DaemonSocketPDUHeader& aHeader,
+                          DaemonSocketPDU& aPDU,
+                          BluetoothResultHandler* aRes);
+
+  void CreateBondRsp(const DaemonSocketPDUHeader& aHeader,
+                     DaemonSocketPDU& aPDU,
+                     BluetoothResultHandler* aRes);
+  void RemoveBondRsp(const DaemonSocketPDUHeader& aHeader,
+                     DaemonSocketPDU& aPDU,
+                     BluetoothResultHandler* aRes);
+  void CancelBondRsp(const DaemonSocketPDUHeader& aHeader,
+                     DaemonSocketPDU& aPDU,
+                     BluetoothResultHandler* aRes);
+
+  void PinReplyRsp(const DaemonSocketPDUHeader& aHeader,
+                   DaemonSocketPDU& aPDU,
+                   BluetoothResultHandler* aRes);
+  void SspReplyRsp(const DaemonSocketPDUHeader& aHeader,
+                   DaemonSocketPDU& aPDU,
+                   BluetoothResultHandler* aRes);
+
+  void DutModeConfigureRsp(const DaemonSocketPDUHeader& aHeader,
+                           DaemonSocketPDU& aPDU,
+                           BluetoothResultHandler* aRes);
+
+  void DutModeSendRsp(const DaemonSocketPDUHeader& aHeader,
+                      DaemonSocketPDU& aPDU,
+                      BluetoothResultHandler* aRes);
+
+  void LeTestModeRsp(const DaemonSocketPDUHeader& aHeader,
+                     DaemonSocketPDU& aPDU,
+                     BluetoothResultHandler* aRes);
+
+  void HandleRsp(const DaemonSocketPDUHeader& aHeader,
+                 DaemonSocketPDU& aPDU, DaemonSocketResultHandler* aRes);
+
+  //
+  // Notifications
+  //
+
+  class NotificationHandlerWrapper;
+
+  typedef mozilla::ipc::DaemonNotificationRunnable1<
+    NotificationHandlerWrapper, void, bool>
+    AdapterStateChangedNotification;
+
+  typedef mozilla::ipc::DaemonNotificationRunnable3<
+    NotificationHandlerWrapper, void, BluetoothStatus, int,
+    nsAutoArrayPtr<BluetoothProperty>, BluetoothStatus, int,
+    const BluetoothProperty*>
+    AdapterPropertiesNotification;
+
+  typedef mozilla::ipc::DaemonNotificationRunnable4<
+    NotificationHandlerWrapper, void, BluetoothStatus, nsString, int,
+    nsAutoArrayPtr<BluetoothProperty>, BluetoothStatus, const nsAString&,
+    int, const BluetoothProperty*>
+    RemoteDevicePropertiesNotification;
+
+  typedef mozilla::ipc::DaemonNotificationRunnable2<
+    NotificationHandlerWrapper, void, int, nsAutoArrayPtr<BluetoothProperty>,
+    int, const BluetoothProperty*>
+    DeviceFoundNotification;
+
+  typedef mozilla::ipc::DaemonNotificationRunnable1<
+    NotificationHandlerWrapper, void, bool>
+    DiscoveryStateChangedNotification;
+
+  typedef mozilla::ipc::DaemonNotificationRunnable3<
+    NotificationHandlerWrapper, void, nsString, nsString, uint32_t,
+    const nsAString&, const nsAString&>
+    PinRequestNotification;
+
+  typedef mozilla::ipc::DaemonNotificationRunnable5<
+    NotificationHandlerWrapper, void, nsString, nsString, uint32_t,
+    BluetoothSspVariant, uint32_t, const nsAString&, const nsAString&>
+    SspRequestNotification;
+
+  typedef mozilla::ipc::DaemonNotificationRunnable3<
+    NotificationHandlerWrapper, void, BluetoothStatus, nsString,
+    BluetoothBondState, BluetoothStatus, const nsAString&>
+    BondStateChangedNotification;
+
+  typedef mozilla::ipc::DaemonNotificationRunnable3<
+    NotificationHandlerWrapper, void, BluetoothStatus, nsString, bool,
+    BluetoothStatus, const nsAString&>
+    AclStateChangedNotification;
+
+  typedef mozilla::ipc::DaemonNotificationRunnable3<
+    NotificationHandlerWrapper, void, uint16_t, nsAutoArrayPtr<uint8_t>,
+    uint8_t, uint16_t, const uint8_t*>
+    DutModeRecvNotification;
+
+  typedef mozilla::ipc::DaemonNotificationRunnable2<
+    NotificationHandlerWrapper, void, BluetoothStatus, uint16_t>
+    LeTestModeNotification;
+
+  class AclStateChangedInitOp;
+  class AdapterPropertiesInitOp;
+  class BondStateChangedInitOp;
+  class DeviceFoundInitOp;
+  class DutModeRecvInitOp;
+  class PinRequestInitOp;
+  class RemoteDevicePropertiesInitOp;
+  class SspRequestInitOp;
+
+  void AdapterStateChangedNtf(const DaemonSocketPDUHeader& aHeader,
+                              DaemonSocketPDU& aPDU);
+
+  void AdapterPropertiesNtf(const DaemonSocketPDUHeader& aHeader,
+                            DaemonSocketPDU& aPDU);
+
+  void RemoteDevicePropertiesNtf(const DaemonSocketPDUHeader& aHeader,
+                                 DaemonSocketPDU& aPDU);
+
+  void DeviceFoundNtf(const DaemonSocketPDUHeader& aHeader,
+                      DaemonSocketPDU& aPDU);
+
+  void DiscoveryStateChangedNtf(const DaemonSocketPDUHeader& aHeader,
+                                DaemonSocketPDU& aPDU);
+
+  void PinRequestNtf(const DaemonSocketPDUHeader& aHeader,
+                     DaemonSocketPDU& aPDU);
+
+  void SspRequestNtf(const DaemonSocketPDUHeader& aHeader,
+                     DaemonSocketPDU& aPDU);
+
+  void BondStateChangedNtf(const DaemonSocketPDUHeader& aHeader,
+                           DaemonSocketPDU& aPDU);
+
+  void AclStateChangedNtf(const DaemonSocketPDUHeader& aHeader,
+                          DaemonSocketPDU& aPDU);
+
+  void DutModeRecvNtf(const DaemonSocketPDUHeader& aHeader,
+                      DaemonSocketPDU& aPDU);
+
+  void LeTestModeNtf(const DaemonSocketPDUHeader& aHeader,
+                     DaemonSocketPDU& aPDU);
+
+  void HandleNtf(const DaemonSocketPDUHeader& aHeader,
+                 DaemonSocketPDU& aPDU, DaemonSocketResultHandler* aRes);
+
+  static BluetoothNotificationHandler* sNotificationHandler;
+};
+
+END_BLUETOOTH_NAMESPACE
+
+#endif // mozilla_dom_bluetooth_bluedroid_BluetoothDaemonCoreInterface_h
--- a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
@@ -5,16 +5,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "BluetoothDaemonInterface.h"
 #include <cutils/properties.h>
 #include <fcntl.h>
 #include <stdlib.h>
 #include "BluetoothDaemonA2dpInterface.h"
 #include "BluetoothDaemonAvrcpInterface.h"
+#include "BluetoothDaemonCoreInterface.h"
 #include "BluetoothDaemonGattInterface.h"
 #include "BluetoothDaemonHandsfreeInterface.h"
 #include "BluetoothDaemonHelpers.h"
 #include "BluetoothDaemonSetupInterface.h"
 #include "BluetoothDaemonSocketInterface.h"
 #include "mozilla/ipc/DaemonRunnables.h"
 #include "mozilla/ipc/DaemonSocket.h"
 #include "mozilla/ipc/DaemonSocketConnector.h"
@@ -23,1184 +24,16 @@
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 using namespace mozilla::ipc;
 
 static const int sRetryInterval = 100; // ms
 
 //
-// Core module
-//
-
-static BluetoothNotificationHandler* sNotificationHandler;
-
-class BluetoothDaemonCoreModule
-{
-public:
-
-  static const int MAX_NUM_CLIENTS;
-
-  virtual nsresult Send(DaemonSocketPDU* aPDU,
-                        DaemonSocketResultHandler* aRes) = 0;
-
-  nsresult EnableCmd(BluetoothResultHandler* aRes)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(0x01, 0x01, 0));
-
-    nsresult rv = Send(pdu, aRes);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    unused << pdu.forget();
-    return rv;
-  }
-
-  nsresult DisableCmd(BluetoothResultHandler* aRes)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(0x01, 0x02, 0));
-
-    nsresult rv = Send(pdu, aRes);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    unused << pdu.forget();
-    return rv;
-  }
-
-  nsresult GetAdapterPropertiesCmd(BluetoothResultHandler* aRes)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(0x01, 0x03, 0));
-
-    nsresult rv = Send(pdu, aRes);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    unused << pdu.forget();
-    return rv;
-  }
-
-  nsresult GetAdapterPropertyCmd(const nsAString& aName,
-                                 BluetoothResultHandler* aRes)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(0x01, 0x04, 0));
-
-    nsresult rv = PackPDU(
-      PackConversion<const nsAString, BluetoothPropertyType>(aName), *pdu);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    rv = Send(pdu, aRes);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    unused << pdu.forget();
-    return rv;
-  }
-
-  nsresult SetAdapterPropertyCmd(const BluetoothNamedValue& aProperty,
-                                 BluetoothResultHandler* aRes)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(0x01, 0x05, 0));
-
-    nsresult rv = PackPDU(aProperty, *pdu);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    rv = Send(pdu, aRes);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    unused << pdu.forget();
-    return rv;
-  }
-
-  nsresult GetRemoteDevicePropertiesCmd(const nsAString& aRemoteAddr,
-                                        BluetoothResultHandler* aRes)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(0x01, 0x06, 0));
-
-    nsresult rv = PackPDU(
-      PackConversion<nsAString, BluetoothAddress>(aRemoteAddr), *pdu);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    rv = Send(pdu, aRes);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    unused << pdu.forget();
-    return rv;
-  }
-
-  nsresult GetRemoteDevicePropertyCmd(const nsAString& aRemoteAddr,
-                                      const nsAString& aName,
-                                      BluetoothResultHandler* aRes)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(0x01, 0x07, 0));
-
-    nsresult rv = PackPDU(
-      PackConversion<nsAString, BluetoothAddress>(aRemoteAddr),
-      PackConversion<nsAString, BluetoothPropertyType>(aName), *pdu);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    rv = Send(pdu, aRes);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    unused << pdu.forget();
-    return rv;
-  }
-
-  nsresult SetRemoteDevicePropertyCmd(const nsAString& aRemoteAddr,
-                                      const BluetoothNamedValue& aProperty,
-                                      BluetoothResultHandler* aRes)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(0x01, 0x08, 0));
-
-    nsresult rv = PackPDU(
-      PackConversion<nsAString, BluetoothAddress>(aRemoteAddr),
-      aProperty, *pdu);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    rv = Send(pdu, aRes);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    unused << pdu.forget();
-    return rv;
-  }
-
-  nsresult GetRemoteServiceRecordCmd(const nsAString& aRemoteAddr,
-                                     const uint8_t aUuid[16],
-                                     BluetoothResultHandler* aRes)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(0x01, 0x09, 0));
-
-    nsresult rv = PackPDU(
-      PackConversion<nsAString, BluetoothAddress>(aRemoteAddr),
-      PackArray<uint8_t>(aUuid, 16), *pdu);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    rv = Send(pdu, aRes);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    unused << pdu.forget();
-    return rv;
-  }
-
-  nsresult GetRemoteServicesCmd(const nsAString& aRemoteAddr,
-                                BluetoothResultHandler* aRes)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(0x01, 0x0a, 0));
-
-    nsresult rv = PackPDU(
-      PackConversion<nsAString, BluetoothAddress>(aRemoteAddr), *pdu);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    rv = Send(pdu, aRes);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    unused << pdu.forget();
-    return rv;
-  }
-
-  nsresult StartDiscoveryCmd(BluetoothResultHandler* aRes)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(0x01, 0x0b, 0));
-
-    nsresult rv = Send(pdu, aRes);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    unused << pdu.forget();
-    return rv;
-  }
-
-  nsresult CancelDiscoveryCmd(BluetoothResultHandler* aRes)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(0x01, 0x0c, 0));
-
-    nsresult rv = Send(pdu, aRes);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    unused << pdu.forget();
-    return rv;
-  }
-
-  nsresult CreateBondCmd(const nsAString& aBdAddr,
-                         BluetoothTransport aTransport,
-                         BluetoothResultHandler* aRes)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(0x01, 0x0d, 0));
-
-#if ANDROID_VERSION >= 21
-    nsresult rv = PackPDU(
-      PackConversion<nsAString, BluetoothAddress>(aBdAddr), aTransport, *pdu);
-#else
-    nsresult rv = PackPDU(
-      PackConversion<nsAString, BluetoothAddress>(aBdAddr), *pdu);
-#endif
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    rv = Send(pdu, aRes);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    unused << pdu.forget();
-    return rv;
-  }
-
-  nsresult RemoveBondCmd(const nsAString& aBdAddr,
-                         BluetoothResultHandler* aRes)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(0x01, 0x0e, 0));
-
-    nsresult rv = PackPDU(
-      PackConversion<nsAString, BluetoothAddress>(aBdAddr), *pdu);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    rv = Send(pdu, aRes);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    unused << pdu.forget();
-    return rv;
-  }
-
-  nsresult CancelBondCmd(const nsAString& aBdAddr,
-                         BluetoothResultHandler* aRes)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(0x01, 0x0f, 0));
-
-    nsresult rv = PackPDU(
-      PackConversion<nsAString, BluetoothAddress>(aBdAddr), *pdu);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    rv = Send(pdu, aRes);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    unused << pdu.forget();
-    return rv;
-  }
-
-  nsresult PinReplyCmd(const nsAString& aBdAddr, bool aAccept,
-                       const nsAString& aPinCode,
-                       BluetoothResultHandler* aRes)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(0x01, 0x10, 0));
-
-    nsresult rv = PackPDU(
-      PackConversion<nsAString, BluetoothAddress>(aBdAddr),
-      aAccept,
-      PackConversion<nsAString, BluetoothPinCode>(aPinCode), *pdu);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    rv = Send(pdu, aRes);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    unused << pdu.forget();
-    return rv;
-  }
-
-  nsresult SspReplyCmd(const nsAString& aBdAddr, BluetoothSspVariant aVariant,
-                       bool aAccept, uint32_t aPasskey,
-                       BluetoothResultHandler* aRes)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(0x01, 0x11, 0));
-
-    nsresult rv = PackPDU(
-      PackConversion<nsAString, BluetoothAddress>(aBdAddr),
-      aVariant, aAccept, aPasskey, *pdu);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    rv = Send(pdu, aRes);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    unused << pdu.forget();
-    return rv;
-  }
-
-  nsresult DutModeConfigureCmd(bool aEnable, BluetoothResultHandler* aRes)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(0x01, 0x12, 0));
-
-    nsresult rv = PackPDU(aEnable, *pdu);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    rv = Send(pdu, aRes);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    unused << pdu.forget();
-    return rv;
-  }
-
-  nsresult DutModeSendCmd(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
-                          BluetoothResultHandler* aRes)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(0x01, 0x13, 0));
-
-    nsresult rv = PackPDU(aOpcode, aLen, PackArray<uint8_t>(aBuf, aLen),
-                          *pdu);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    rv = Send(pdu, aRes);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    unused << pdu.forget();
-    return rv;
-  }
-
-  nsresult LeTestModeCmd(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
-                         BluetoothResultHandler* aRes)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(0x01, 0x14, 0));
-
-    nsresult rv = PackPDU(aOpcode, aLen, PackArray<uint8_t>(aBuf, aLen),
-                          *pdu);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    rv = Send(pdu, aRes);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    unused << pdu.forget();
-    return rv;
-  }
-
-protected:
-
-  void HandleSvc(const DaemonSocketPDUHeader& aHeader,
-                 DaemonSocketPDU& aPDU, DaemonSocketResultHandler* aRes)
-  {
-    static void (BluetoothDaemonCoreModule::* const HandleOp[])(
-      const DaemonSocketPDUHeader&, DaemonSocketPDU&,
-      DaemonSocketResultHandler*) = {
-      [0] = &BluetoothDaemonCoreModule::HandleRsp,
-      [1] = &BluetoothDaemonCoreModule::HandleNtf
-    };
-
-    MOZ_ASSERT(!NS_IsMainThread());
-
-    (this->*(HandleOp[!!(aHeader.mOpcode & 0x80)]))(aHeader, aPDU, aRes);
-  }
-
-private:
-
-  // Responses
-  //
-
-  typedef mozilla::ipc::DaemonResultRunnable0<
-    BluetoothResultHandler, void>
-    ResultRunnable;
-
-  typedef mozilla::ipc::DaemonResultRunnable1<
-    BluetoothResultHandler, void, BluetoothStatus, BluetoothStatus>
-    ErrorRunnable;
-
-  void ErrorRsp(const DaemonSocketPDUHeader& aHeader,
-                DaemonSocketPDU& aPDU,
-                BluetoothResultHandler* aRes)
-  {
-    ErrorRunnable::Dispatch(
-      aRes, &BluetoothResultHandler::OnError, UnpackPDUInitOp(aPDU));
-  }
-
-  void EnableRsp(const DaemonSocketPDUHeader& aHeader,
-                 DaemonSocketPDU& aPDU,
-                 BluetoothResultHandler* aRes)
-  {
-    ResultRunnable::Dispatch(
-      aRes, &BluetoothResultHandler::Enable, UnpackPDUInitOp(aPDU));
-  }
-
-  void DisableRsp(const DaemonSocketPDUHeader& aHeader,
-                  DaemonSocketPDU& aPDU,
-                  BluetoothResultHandler* aRes)
-  {
-    ResultRunnable::Dispatch(
-      aRes, &BluetoothResultHandler::Disable, UnpackPDUInitOp(aPDU));
-  }
-
-  void GetAdapterPropertiesRsp(const DaemonSocketPDUHeader& aHeader,
-                               DaemonSocketPDU& aPDU,
-                               BluetoothResultHandler* aRes)
-  {
-    ResultRunnable::Dispatch(
-      aRes, &BluetoothResultHandler::GetAdapterProperties,
-      UnpackPDUInitOp(aPDU));
-  }
-
-  void GetAdapterPropertyRsp(const DaemonSocketPDUHeader& aHeader,
-                             DaemonSocketPDU& aPDU,
-                             BluetoothResultHandler* aRes)
-  {
-    ResultRunnable::Dispatch(
-      aRes, &BluetoothResultHandler::GetAdapterProperty,
-      UnpackPDUInitOp(aPDU));
-  }
-
-  void SetAdapterPropertyRsp(const DaemonSocketPDUHeader& aHeader,
-                             DaemonSocketPDU& aPDU,
-                             BluetoothResultHandler* aRes)
-  {
-    ResultRunnable::Dispatch(
-      aRes, &BluetoothResultHandler::SetAdapterProperty,
-      UnpackPDUInitOp(aPDU));
-  }
-
-  void GetRemoteDevicePropertiesRsp(const DaemonSocketPDUHeader& aHeader,
-                                    DaemonSocketPDU& aPDU,
-                                    BluetoothResultHandler* aRes)
-  {
-    ResultRunnable::Dispatch(
-      aRes, &BluetoothResultHandler::GetRemoteDeviceProperties,
-      UnpackPDUInitOp(aPDU));
-  }
-
-  void
-  GetRemoteDevicePropertyRsp(const DaemonSocketPDUHeader& aHeader,
-                             DaemonSocketPDU& aPDU,
-                             BluetoothResultHandler* aRes)
-  {
-    ResultRunnable::Dispatch(
-      aRes, &BluetoothResultHandler::GetRemoteDeviceProperty,
-      UnpackPDUInitOp(aPDU));
-  }
-
-  void SetRemoteDevicePropertyRsp(const DaemonSocketPDUHeader& aHeader,
-                                  DaemonSocketPDU& aPDU,
-                                  BluetoothResultHandler* aRes)
-  {
-    ResultRunnable::Dispatch(
-      aRes, &BluetoothResultHandler::SetRemoteDeviceProperty,
-      UnpackPDUInitOp(aPDU));
-  }
-
-  void GetRemoteServiceRecordRsp(const DaemonSocketPDUHeader& aHeader,
-                                 DaemonSocketPDU& aPDU,
-                                 BluetoothResultHandler* aRes)
-  {
-    ResultRunnable::Dispatch(
-      aRes, &BluetoothResultHandler::GetRemoteServiceRecord,
-      UnpackPDUInitOp(aPDU));
-  }
-
-  void GetRemoteServicesRsp(const DaemonSocketPDUHeader& aHeader,
-                            DaemonSocketPDU& aPDU,
-                            BluetoothResultHandler* aRes)
-  {
-    ResultRunnable::Dispatch(
-      aRes, &BluetoothResultHandler::GetRemoteServices,
-      UnpackPDUInitOp(aPDU));
-  }
-
-  void StartDiscoveryRsp(const DaemonSocketPDUHeader& aHeader,
-                         DaemonSocketPDU& aPDU,
-                         BluetoothResultHandler* aRes)
-  {
-    ResultRunnable::Dispatch(
-      aRes, &BluetoothResultHandler::StartDiscovery,
-      UnpackPDUInitOp(aPDU));
-  }
-
-  void CancelDiscoveryRsp(const DaemonSocketPDUHeader& aHeader,
-                          DaemonSocketPDU& aPDU,
-                          BluetoothResultHandler* aRes)
-  {
-    ResultRunnable::Dispatch(
-      aRes, &BluetoothResultHandler::CancelDiscovery,
-      UnpackPDUInitOp(aPDU));
-  }
-
-  void CreateBondRsp(const DaemonSocketPDUHeader& aHeader,
-                     DaemonSocketPDU& aPDU,
-                     BluetoothResultHandler* aRes)
-  {
-    ResultRunnable::Dispatch(
-      aRes, &BluetoothResultHandler::CreateBond,
-      UnpackPDUInitOp(aPDU));
-  }
-
-  void RemoveBondRsp(const DaemonSocketPDUHeader& aHeader,
-                     DaemonSocketPDU& aPDU,
-                     BluetoothResultHandler* aRes)
-  {
-    ResultRunnable::Dispatch(
-      aRes, &BluetoothResultHandler::RemoveBond,
-      UnpackPDUInitOp(aPDU));
-  }
-
-  void CancelBondRsp(const DaemonSocketPDUHeader& aHeader,
-                     DaemonSocketPDU& aPDU,
-                     BluetoothResultHandler* aRes)
-  {
-    ResultRunnable::Dispatch(
-      aRes, &BluetoothResultHandler::CancelBond,
-      UnpackPDUInitOp(aPDU));
-  }
-
-  void PinReplyRsp(const DaemonSocketPDUHeader& aHeader,
-                   DaemonSocketPDU& aPDU,
-                   BluetoothResultHandler* aRes)
-  {
-    ResultRunnable::Dispatch(
-      aRes, &BluetoothResultHandler::PinReply,
-      UnpackPDUInitOp(aPDU));
-  }
-
-  void SspReplyRsp(const DaemonSocketPDUHeader& aHeader,
-                   DaemonSocketPDU& aPDU,
-                   BluetoothResultHandler* aRes)
-  {
-    ResultRunnable::Dispatch(
-      aRes, &BluetoothResultHandler::SspReply,
-      UnpackPDUInitOp(aPDU));
-  }
-
-  void DutModeConfigureRsp(const DaemonSocketPDUHeader& aHeader,
-                           DaemonSocketPDU& aPDU,
-                           BluetoothResultHandler* aRes)
-  {
-    ResultRunnable::Dispatch(
-      aRes, &BluetoothResultHandler::DutModeConfigure,
-      UnpackPDUInitOp(aPDU));
-  }
-
-  void DutModeSendRsp(const DaemonSocketPDUHeader& aHeader,
-                      DaemonSocketPDU& aPDU,
-                      BluetoothResultHandler* aRes)
-  {
-    ResultRunnable::Dispatch(
-      aRes, &BluetoothResultHandler::DutModeSend,
-      UnpackPDUInitOp(aPDU));
-  }
-
-  void LeTestModeRsp(const DaemonSocketPDUHeader& aHeader,
-                     DaemonSocketPDU& aPDU,
-                     BluetoothResultHandler* aRes)
-  {
-    ResultRunnable::Dispatch(
-      aRes, &BluetoothResultHandler::LeTestMode,
-      UnpackPDUInitOp(aPDU));
-  }
-
-  void HandleRsp(const DaemonSocketPDUHeader& aHeader,
-                 DaemonSocketPDU& aPDU, DaemonSocketResultHandler* aRes)
-  {
-    static void (BluetoothDaemonCoreModule::* const HandleRsp[])(
-      const DaemonSocketPDUHeader&,
-      DaemonSocketPDU&,
-      BluetoothResultHandler*) = {
-      [0x00] = &BluetoothDaemonCoreModule::ErrorRsp,
-      [0x01] = &BluetoothDaemonCoreModule::EnableRsp,
-      [0x02] = &BluetoothDaemonCoreModule::DisableRsp,
-      [0x03] = &BluetoothDaemonCoreModule::GetAdapterPropertiesRsp,
-      [0x04] = &BluetoothDaemonCoreModule::GetAdapterPropertyRsp,
-      [0x05] = &BluetoothDaemonCoreModule::SetAdapterPropertyRsp,
-      [0x06] = &BluetoothDaemonCoreModule::GetRemoteDevicePropertiesRsp,
-      [0x07] = &BluetoothDaemonCoreModule::GetRemoteDevicePropertyRsp,
-      [0x08] = &BluetoothDaemonCoreModule::SetRemoteDevicePropertyRsp,
-      [0x09] = &BluetoothDaemonCoreModule::GetRemoteServiceRecordRsp,
-      [0x0a] = &BluetoothDaemonCoreModule::GetRemoteServicesRsp,
-      [0x0b] = &BluetoothDaemonCoreModule::StartDiscoveryRsp,
-      [0x0c] = &BluetoothDaemonCoreModule::CancelDiscoveryRsp,
-      [0x0d] = &BluetoothDaemonCoreModule::CreateBondRsp,
-      [0x0e] = &BluetoothDaemonCoreModule::RemoveBondRsp,
-      [0x0f] = &BluetoothDaemonCoreModule::CancelBondRsp,
-      [0x10] = &BluetoothDaemonCoreModule::PinReplyRsp,
-      [0x11] = &BluetoothDaemonCoreModule::SspReplyRsp,
-      [0x12] = &BluetoothDaemonCoreModule::DutModeConfigureRsp,
-      [0x13] = &BluetoothDaemonCoreModule::DutModeSendRsp,
-      [0x14] = &BluetoothDaemonCoreModule::LeTestModeRsp,
-    };
-
-    MOZ_ASSERT(!NS_IsMainThread());
-
-    if (NS_WARN_IF(!(aHeader.mOpcode < MOZ_ARRAY_LENGTH(HandleRsp))) ||
-        NS_WARN_IF(!HandleRsp[aHeader.mOpcode])) {
-      return;
-    }
-
-    nsRefPtr<BluetoothResultHandler> res =
-      static_cast<BluetoothResultHandler*>(aRes);
-
-    if (!res) {
-      return; // Return early if no result handler has been set for response
-    }
-
-    (this->*(HandleRsp[aHeader.mOpcode]))(aHeader, aPDU, res);
-  }
-
-  // Notifications
-  //
-
-  class NotificationHandlerWrapper
-  {
-  public:
-    typedef BluetoothNotificationHandler ObjectType;
-
-    static ObjectType* GetInstance()
-    {
-      MOZ_ASSERT(NS_IsMainThread());
-
-      return sNotificationHandler;
-    }
-  };
-
-  typedef mozilla::ipc::DaemonNotificationRunnable1<
-    NotificationHandlerWrapper, void, bool>
-    AdapterStateChangedNotification;
-
-  typedef mozilla::ipc::DaemonNotificationRunnable3<
-    NotificationHandlerWrapper, void, BluetoothStatus, int,
-    nsAutoArrayPtr<BluetoothProperty>, BluetoothStatus, int,
-    const BluetoothProperty*>
-    AdapterPropertiesNotification;
-
-  typedef mozilla::ipc::DaemonNotificationRunnable4<
-    NotificationHandlerWrapper, void, BluetoothStatus, nsString, int,
-    nsAutoArrayPtr<BluetoothProperty>, BluetoothStatus, const nsAString&,
-    int, const BluetoothProperty*>
-    RemoteDevicePropertiesNotification;
-
-  typedef mozilla::ipc::DaemonNotificationRunnable2<
-    NotificationHandlerWrapper, void, int, nsAutoArrayPtr<BluetoothProperty>,
-    int, const BluetoothProperty*>
-    DeviceFoundNotification;
-
-  typedef mozilla::ipc::DaemonNotificationRunnable1<
-    NotificationHandlerWrapper, void, bool>
-    DiscoveryStateChangedNotification;
-
-  typedef mozilla::ipc::DaemonNotificationRunnable3<
-    NotificationHandlerWrapper, void, nsString, nsString, uint32_t,
-    const nsAString&, const nsAString&>
-    PinRequestNotification;
-
-  typedef mozilla::ipc::DaemonNotificationRunnable5<
-    NotificationHandlerWrapper, void, nsString, nsString, uint32_t,
-    BluetoothSspVariant, uint32_t, const nsAString&, const nsAString&>
-    SspRequestNotification;
-
-  typedef mozilla::ipc::DaemonNotificationRunnable3<
-    NotificationHandlerWrapper, void, BluetoothStatus, nsString,
-    BluetoothBondState, BluetoothStatus, const nsAString&>
-    BondStateChangedNotification;
-
-  typedef mozilla::ipc::DaemonNotificationRunnable3<
-    NotificationHandlerWrapper, void, BluetoothStatus, nsString, bool,
-    BluetoothStatus, const nsAString&>
-    AclStateChangedNotification;
-
-  typedef mozilla::ipc::DaemonNotificationRunnable3<
-    NotificationHandlerWrapper, void, uint16_t, nsAutoArrayPtr<uint8_t>,
-    uint8_t, uint16_t, const uint8_t*>
-    DutModeRecvNotification;
-
-  typedef mozilla::ipc::DaemonNotificationRunnable2<
-    NotificationHandlerWrapper, void, BluetoothStatus, uint16_t>
-    LeTestModeNotification;
-
-  void AdapterStateChangedNtf(const DaemonSocketPDUHeader& aHeader,
-                              DaemonSocketPDU& aPDU)
-  {
-    AdapterStateChangedNotification::Dispatch(
-      &BluetoothNotificationHandler::AdapterStateChangedNotification,
-      UnpackPDUInitOp(aPDU));
-  }
-
-  // Init operator class for AdapterPropertiesNotification
-  class AdapterPropertiesInitOp final : private PDUInitOp
-  {
-  public:
-    AdapterPropertiesInitOp(DaemonSocketPDU& aPDU)
-    : PDUInitOp(aPDU)
-    { }
-
-    nsresult
-    operator () (BluetoothStatus& aArg1, int& aArg2,
-                 nsAutoArrayPtr<BluetoothProperty>& aArg3) const
-    {
-      DaemonSocketPDU& pdu = GetPDU();
-
-      /* Read status */
-      nsresult rv = UnpackPDU(pdu, aArg1);
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-
-      /* Read number of properties */
-      uint8_t numProperties;
-      rv = UnpackPDU(pdu, numProperties);
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-      aArg2 = numProperties;
-
-      /* Read properties array */
-      UnpackArray<BluetoothProperty> properties(aArg3, aArg2);
-      rv = UnpackPDU(pdu, properties);
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-      WarnAboutTrailingData();
-      return NS_OK;
-    }
-  };
-
-  void AdapterPropertiesNtf(const DaemonSocketPDUHeader& aHeader,
-                            DaemonSocketPDU& aPDU)
-  {
-    AdapterPropertiesNotification::Dispatch(
-      &BluetoothNotificationHandler::AdapterPropertiesNotification,
-      AdapterPropertiesInitOp(aPDU));
-  }
-
-  // Init operator class for RemoteDevicePropertiesNotification
-  class RemoteDevicePropertiesInitOp final : private PDUInitOp
-  {
-  public:
-    RemoteDevicePropertiesInitOp(DaemonSocketPDU& aPDU)
-    : PDUInitOp(aPDU)
-    { }
-
-    nsresult
-    operator () (BluetoothStatus& aArg1, nsString& aArg2, int& aArg3,
-                 nsAutoArrayPtr<BluetoothProperty>& aArg4) const
-    {
-      DaemonSocketPDU& pdu = GetPDU();
-
-      /* Read status */
-      nsresult rv = UnpackPDU(pdu, aArg1);
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-
-      /* Read address */
-      rv = UnpackPDU(
-        pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-
-      /* Read number of properties */
-      uint8_t numProperties;
-      rv = UnpackPDU(pdu, numProperties);
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-      aArg3 = numProperties;
-
-      /* Read properties array */
-      UnpackArray<BluetoothProperty> properties(aArg4, aArg3);
-      rv = UnpackPDU(pdu, properties);
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-      WarnAboutTrailingData();
-      return NS_OK;
-    }
-  };
-
-  void RemoteDevicePropertiesNtf(const DaemonSocketPDUHeader& aHeader,
-                                 DaemonSocketPDU& aPDU)
-  {
-    RemoteDevicePropertiesNotification::Dispatch(
-      &BluetoothNotificationHandler::RemoteDevicePropertiesNotification,
-      RemoteDevicePropertiesInitOp(aPDU));
-  }
-
-  // Init operator class for DeviceFoundNotification
-  class DeviceFoundInitOp final : private PDUInitOp
-  {
-  public:
-    DeviceFoundInitOp(DaemonSocketPDU& aPDU)
-    : PDUInitOp(aPDU)
-    { }
-
-    nsresult
-    operator () (int& aArg1, nsAutoArrayPtr<BluetoothProperty>& aArg2) const
-    {
-      DaemonSocketPDU& pdu = GetPDU();
-
-      /* Read number of properties */
-      uint8_t numProperties;
-      nsresult rv = UnpackPDU(pdu, numProperties);
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-      aArg1 = numProperties;
-
-      /* Read properties array */
-      UnpackArray<BluetoothProperty> properties(aArg2, aArg1);
-      rv = UnpackPDU(pdu, properties);
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-      WarnAboutTrailingData();
-      return NS_OK;
-    }
-  };
-
-  void DeviceFoundNtf(const DaemonSocketPDUHeader& aHeader,
-                      DaemonSocketPDU& aPDU)
-  {
-    DeviceFoundNotification::Dispatch(
-      &BluetoothNotificationHandler::DeviceFoundNotification,
-      DeviceFoundInitOp(aPDU));
-  }
-
-  void DiscoveryStateChangedNtf(const DaemonSocketPDUHeader& aHeader,
-                                DaemonSocketPDU& aPDU)
-  {
-    DiscoveryStateChangedNotification::Dispatch(
-      &BluetoothNotificationHandler::DiscoveryStateChangedNotification,
-      UnpackPDUInitOp(aPDU));
-  }
-
-  // Init operator class for PinRequestNotification
-  class PinRequestInitOp final : private PDUInitOp
-  {
-  public:
-    PinRequestInitOp(DaemonSocketPDU& aPDU)
-    : PDUInitOp(aPDU)
-    { }
-
-    nsresult
-    operator () (nsString& aArg1, nsString& aArg2, uint32_t& aArg3) const
-    {
-      DaemonSocketPDU& pdu = GetPDU();
-
-      /* Read remote address */
-      nsresult rv = UnpackPDU(
-        pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg1));
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-
-      /* Read remote name */
-      rv = UnpackPDU(
-        pdu, UnpackConversion<BluetoothRemoteName, nsAString>(aArg2));
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-
-      /* Read CoD */
-      rv = UnpackPDU(pdu, aArg3);
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-      WarnAboutTrailingData();
-      return NS_OK;
-    }
-  };
-
-  void PinRequestNtf(const DaemonSocketPDUHeader& aHeader,
-                     DaemonSocketPDU& aPDU)
-  {
-    PinRequestNotification::Dispatch(
-      &BluetoothNotificationHandler::PinRequestNotification,
-      PinRequestInitOp(aPDU));
-  }
-
-  // Init operator class for SspRequestNotification
-  class SspRequestInitOp final : private PDUInitOp
-  {
-  public:
-    SspRequestInitOp(DaemonSocketPDU& aPDU)
-    : PDUInitOp(aPDU)
-    { }
-
-    nsresult
-    operator () (nsString& aArg1, nsString& aArg2, uint32_t& aArg3,
-                 BluetoothSspVariant& aArg4, uint32_t& aArg5) const
-    {
-      DaemonSocketPDU& pdu = GetPDU();
-
-      /* Read remote address */
-      nsresult rv = UnpackPDU(
-        pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg1));
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-
-      /* Read remote name */
-      rv = UnpackPDU(
-        pdu, UnpackConversion<BluetoothRemoteName, nsAString>(aArg2));
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-
-      /* Read CoD */
-      rv = UnpackPDU(pdu, aArg3);
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-
-      /* Read pairing variant */
-      rv = UnpackPDU(pdu, aArg4);
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-
-      /* Read passkey */
-      rv = UnpackPDU(pdu, aArg5);
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-      WarnAboutTrailingData();
-      return NS_OK;
-    }
-  };
-
-  void SspRequestNtf(const DaemonSocketPDUHeader& aHeader,
-                     DaemonSocketPDU& aPDU)
-  {
-    SspRequestNotification::Dispatch(
-      &BluetoothNotificationHandler::SspRequestNotification,
-      SspRequestInitOp(aPDU));
-  }
-
-  // Init operator class for BondStateChangedNotification
-  class BondStateChangedInitOp final : private PDUInitOp
-  {
-  public:
-    BondStateChangedInitOp(DaemonSocketPDU& aPDU)
-    : PDUInitOp(aPDU)
-    { }
-
-    nsresult
-    operator () (BluetoothStatus& aArg1, nsString& aArg2,
-                 BluetoothBondState& aArg3) const
-    {
-      DaemonSocketPDU& pdu = GetPDU();
-
-      /* Read status */
-      nsresult rv = UnpackPDU(pdu, aArg1);
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-
-      /* Read remote address */
-      rv = UnpackPDU(
-        pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-
-      /* Read bond state */
-      rv = UnpackPDU(pdu, aArg3);
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-      WarnAboutTrailingData();
-      return NS_OK;
-    }
-  };
-
-  void BondStateChangedNtf(const DaemonSocketPDUHeader& aHeader,
-                           DaemonSocketPDU& aPDU)
-  {
-    BondStateChangedNotification::Dispatch(
-      &BluetoothNotificationHandler::BondStateChangedNotification,
-      BondStateChangedInitOp(aPDU));
-  }
-
-  // Init operator class for AclStateChangedNotification
-  class AclStateChangedInitOp final : private PDUInitOp
-  {
-  public:
-    AclStateChangedInitOp(DaemonSocketPDU& aPDU)
-    : PDUInitOp(aPDU)
-    { }
-
-    nsresult
-    operator () (BluetoothStatus& aArg1, nsString& aArg2, bool& aArg3) const
-    {
-      DaemonSocketPDU& pdu = GetPDU();
-
-      /* Read status */
-      nsresult rv = UnpackPDU(pdu, aArg1);
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-
-      /* Read remote address */
-      rv = UnpackPDU(
-        pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-
-      /* Read ACL state */
-      rv = UnpackPDU(
-        pdu, UnpackConversion<BluetoothAclState, bool>(aArg3));
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-      WarnAboutTrailingData();
-      return NS_OK;
-    }
-  };
-
-  void AclStateChangedNtf(const DaemonSocketPDUHeader& aHeader,
-                          DaemonSocketPDU& aPDU)
-  {
-    AclStateChangedNotification::Dispatch(
-      &BluetoothNotificationHandler::AclStateChangedNotification,
-      AclStateChangedInitOp(aPDU));
-  }
-
-  // Init operator class for DutModeRecvNotification
-  class DutModeRecvInitOp final : private PDUInitOp
-  {
-  public:
-    DutModeRecvInitOp(DaemonSocketPDU& aPDU)
-    : PDUInitOp(aPDU)
-    { }
-
-    nsresult
-    operator () (uint16_t& aArg1, nsAutoArrayPtr<uint8_t>& aArg2,
-                 uint8_t& aArg3) const
-    {
-      DaemonSocketPDU& pdu = GetPDU();
-
-      /* Read opcode */
-      nsresult rv = UnpackPDU(pdu, aArg1);
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-
-      /* Read length */
-      rv = UnpackPDU(pdu, aArg3);
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-
-      /* Read data */
-      rv = UnpackPDU(pdu, UnpackArray<uint8_t>(aArg2, aArg3));
-      if (NS_FAILED(rv)) {
-        return rv;
-      }
-      WarnAboutTrailingData();
-      return NS_OK;
-    }
-  };
-
-  void DutModeRecvNtf(const DaemonSocketPDUHeader& aHeader,
-                      DaemonSocketPDU& aPDU)
-  {
-    DutModeRecvNotification::Dispatch(
-      &BluetoothNotificationHandler::DutModeRecvNotification,
-      DutModeRecvInitOp(aPDU));
-  }
-
-  void LeTestModeNtf(const DaemonSocketPDUHeader& aHeader,
-                     DaemonSocketPDU& aPDU)
-  {
-    LeTestModeNotification::Dispatch(
-      &BluetoothNotificationHandler::LeTestModeNotification,
-      UnpackPDUInitOp(aPDU));
-  }
-
-  void HandleNtf(const DaemonSocketPDUHeader& aHeader,
-                 DaemonSocketPDU& aPDU, DaemonSocketResultHandler* aRes)
-  {
-    static void (BluetoothDaemonCoreModule::* const HandleNtf[])(
-      const DaemonSocketPDUHeader&, DaemonSocketPDU&) = {
-      [0] = &BluetoothDaemonCoreModule::AdapterStateChangedNtf,
-      [1] = &BluetoothDaemonCoreModule::AdapterPropertiesNtf,
-      [2] = &BluetoothDaemonCoreModule::RemoteDevicePropertiesNtf,
-      [3] = &BluetoothDaemonCoreModule::DeviceFoundNtf,
-      [4] = &BluetoothDaemonCoreModule::DiscoveryStateChangedNtf,
-      [5] = &BluetoothDaemonCoreModule::PinRequestNtf,
-      [6] = &BluetoothDaemonCoreModule::SspRequestNtf,
-      [7] = &BluetoothDaemonCoreModule::BondStateChangedNtf,
-      [8] = &BluetoothDaemonCoreModule::AclStateChangedNtf,
-      [9] = &BluetoothDaemonCoreModule::DutModeRecvNtf,
-      [10] = &BluetoothDaemonCoreModule::LeTestModeNtf
-    };
-
-    MOZ_ASSERT(!NS_IsMainThread());
-
-    uint8_t index = aHeader.mOpcode - 0x81;
-
-    if (NS_WARN_IF(!(index < MOZ_ARRAY_LENGTH(HandleNtf))) ||
-        NS_WARN_IF(!HandleNtf[index])) {
-      return;
-    }
-
-    (this->*(HandleNtf[index]))(aHeader, aPDU);
-  }
-};
-
-const int BluetoothDaemonCoreModule::MAX_NUM_CLIENTS = 1;
-
-//
 // Protocol handling
 //
 
 // |BluetoothDaemonProtocol| is the central class for communicating
 // with the Bluetooth daemon. It maintains both socket connections
 // to the external daemon and implements the complete HAL protocol
 // by inheriting from base-class modules.
 //
@@ -1416,18 +249,20 @@ BluetoothDaemonProtocol::HandleGattSvc(
 void
 BluetoothDaemonProtocol::Handle(DaemonSocketPDU& aPDU)
 {
   static void (BluetoothDaemonProtocol::* const HandleSvc[])(
     const DaemonSocketPDUHeader&, DaemonSocketPDU&,
     DaemonSocketResultHandler*) = {
     [BluetoothDaemonSetupModule::SERVICE_ID] =
       &BluetoothDaemonProtocol::HandleSetupSvc,
-    [0x01] = &BluetoothDaemonProtocol::HandleCoreSvc,
-    [0x02] = &BluetoothDaemonProtocol::HandleSocketSvc,
+    [BluetoothDaemonCoreModule::SERVICE_ID] =
+      &BluetoothDaemonProtocol::HandleCoreSvc,
+    [BluetoothDaemonSocketModule::SERVICE_ID] =
+      &BluetoothDaemonProtocol::HandleSocketSvc,
     [0x03] = nullptr, // HID host
     [0x04] = nullptr, // PAN
     [BluetoothDaemonHandsfreeModule::SERVICE_ID] =
       &BluetoothDaemonProtocol::HandleHandsfreeSvc,
     [BluetoothDaemonA2dpModule::SERVICE_ID] =
       &BluetoothDaemonProtocol::HandleA2dpSvc,
     [0x07] = nullptr, // Health
     [BluetoothDaemonAvrcpModule::SERVICE_ID] =
@@ -1639,23 +474,23 @@ BluetoothDaemonInterface::Init(
 #define BASE_SOCKET_NAME "bluetoothd"
   static unsigned long POSTFIX_LENGTH = 16;
 
   // If we could not cleanup properly before and an old
   // instance of the daemon is still running, we kill it
   // here.
   unused << NS_WARN_IF(property_set("ctl.stop", "bluetoothd"));
 
-  sNotificationHandler = aNotificationHandler;
-
   mResultHandlerQ.AppendElement(aRes);
 
   if (!mProtocol) {
     mProtocol = new BluetoothDaemonProtocol();
   }
+  static_cast<BluetoothDaemonCoreModule*>(mProtocol)->SetNotificationHandler(
+    aNotificationHandler);
 
   if (!mListenSocket) {
     mListenSocket = new ListenSocket(this, LISTEN_SOCKET);
   }
 
   // Init, step 1: Listen for command channel... */
 
   if (!mCmdChannel) {
@@ -1755,18 +590,18 @@ private:
  *
  * Rolling-back half-completed cleanups is not possible. In the case of
  * an error, we simply push forward and try to recover during the next
  * initialization.
  */
 void
 BluetoothDaemonInterface::Cleanup(BluetoothResultHandler* aRes)
 {
-
-  sNotificationHandler = nullptr;
+  static_cast<BluetoothDaemonCoreModule*>(mProtocol)->SetNotificationHandler(
+    nullptr);
 
   // Cleanup, step 1: Unregister Socket module
   nsresult rv = mProtocol->UnregisterModuleCmd(
     0x02, new CleanupResultHandler(this));
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
     return;
   }
@@ -2241,24 +1076,29 @@ BluetoothDaemonInterface::OnDisconnect(i
         // Cleanup, step 5: Signal success to caller
         if (res) {
           res->Cleanup();
         }
       }
       break;
   }
 
+  BluetoothNotificationHandler* notificationHandler =
+    static_cast<BluetoothDaemonCoreModule*>(mProtocol)->
+      GetNotificationHandler();
+
   /* For recovery make sure all sockets disconnected, in order to avoid
    * the remaining disconnects interfere with the restart procedure.
    */
-  if (sNotificationHandler && mResultHandlerQ.IsEmpty()) {
+  if (notificationHandler && mResultHandlerQ.IsEmpty()) {
     if (mListenSocket->GetConnectionStatus() == SOCKET_DISCONNECTED &&
         mCmdChannel->GetConnectionStatus() == SOCKET_DISCONNECTED &&
         mNtfChannel->GetConnectionStatus() == SOCKET_DISCONNECTED) {
       // Assume daemon crashed during regular service; notify
       // BluetoothServiceBluedroid to prepare restart-daemon procedure
-      sNotificationHandler->BackendErrorNotification(true);
-      sNotificationHandler = nullptr;
+      notificationHandler->BackendErrorNotification(true);
+      static_cast<BluetoothDaemonCoreModule*>(mProtocol)->
+        SetNotificationHandler(nullptr);
     }
   }
 }
 
 END_BLUETOOTH_NAMESPACE
--- a/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.cpp
@@ -27,17 +27,19 @@ BluetoothDaemonSocketModule::ListenCmd(B
                                        const nsAString& aServiceName,
                                        const uint8_t aServiceUuid[16],
                                        int aChannel, bool aEncrypt,
                                        bool aAuth,
                                        BluetoothSocketResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(0x02, 0x01, 0));
+  nsAutoPtr<DaemonSocketPDU> pdu(
+    new DaemonSocketPDU(SERVICE_ID, OPCODE_LISTEN,
+                        0));
 
   nsresult rv = PackPDU(
     aType,
     PackConversion<nsAString, BluetoothServiceName>(aServiceName),
     PackArray<uint8_t>(aServiceUuid, 16),
     PackConversion<int, int32_t>(aChannel),
     SocketFlags(aEncrypt, aAuth), *pdu);
   if (NS_FAILED(rv)) {
@@ -56,17 +58,19 @@ BluetoothDaemonSocketModule::ConnectCmd(
                                         BluetoothSocketType aType,
                                         const uint8_t aUuid[16],
                                         int aChannel, bool aEncrypt,
                                         bool aAuth,
                                         BluetoothSocketResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(0x02, 0x02, 0));
+  nsAutoPtr<DaemonSocketPDU> pdu(
+    new DaemonSocketPDU(SERVICE_ID, OPCODE_CONNECT,
+                        0));
 
   nsresult rv = PackPDU(
     PackConversion<nsAString, BluetoothAddress>(aBdAddr),
     aType,
     PackArray<uint8_t>(aUuid, 16),
     PackConversion<int, int32_t>(aChannel),
     SocketFlags(aEncrypt, aAuth), *pdu);
   if (NS_FAILED(rv)) {
@@ -161,19 +165,19 @@ void
 BluetoothDaemonSocketModule::HandleSvc(const DaemonSocketPDUHeader& aHeader,
                                        DaemonSocketPDU& aPDU,
                                        DaemonSocketResultHandler* aRes)
 {
   static void (BluetoothDaemonSocketModule::* const HandleRsp[])(
     const DaemonSocketPDUHeader&,
     DaemonSocketPDU&,
     BluetoothSocketResultHandler*) = {
-    [0x00] = &BluetoothDaemonSocketModule::ErrorRsp,
-    [0x01] = &BluetoothDaemonSocketModule::ListenRsp,
-    [0x02] = &BluetoothDaemonSocketModule::ConnectRsp
+    [OPCODE_ERROR] = &BluetoothDaemonSocketModule::ErrorRsp,
+    [OPCODE_LISTEN] = &BluetoothDaemonSocketModule::ListenRsp,
+    [OPCODE_CONNECT] = &BluetoothDaemonSocketModule::ConnectRsp
   };
 
   if (NS_WARN_IF(MOZ_ARRAY_LENGTH(HandleRsp) <= aHeader.mOpcode) ||
       NS_WARN_IF(!HandleRsp[aHeader.mOpcode])) {
     return;
   }
 
   nsRefPtr<BluetoothSocketResultHandler> res =
--- a/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.h
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.h
@@ -15,16 +15,26 @@ BEGIN_BLUETOOTH_NAMESPACE
 
 using mozilla::ipc::DaemonSocketPDU;
 using mozilla::ipc::DaemonSocketPDUHeader;
 using mozilla::ipc::DaemonSocketResultHandler;
 
 class BluetoothDaemonSocketModule
 {
 public:
+  enum {
+    SERVICE_ID = 0x02
+  };
+
+  enum {
+    OPCODE_ERROR = 0x00,
+    OPCODE_LISTEN = 0x01,
+    OPCODE_CONNECT = 0x02
+  };
+
   static const int MAX_NUM_CLIENTS;
 
   virtual nsresult Send(DaemonSocketPDU* aPDU,
                         DaemonSocketResultHandler* aRes) = 0;
 
   // Commands
   //
 
--- a/dom/bluetooth/moz.build
+++ b/dom/bluetooth/moz.build
@@ -69,16 +69,17 @@ if CONFIG['MOZ_B2G_BT']:
             ]
             DEFINES['MOZ_B2G_BT_BLUEZ'] = True
         elif CONFIG['MOZ_B2G_BT_DAEMON']:
             SOURCES += [
                 'bluedroid/BluetoothA2dpManager.cpp',
                 'bluedroid/BluetoothAvrcpManager.cpp',
                 'bluedroid/BluetoothDaemonA2dpInterface.cpp',
                 'bluedroid/BluetoothDaemonAvrcpInterface.cpp',
+                'bluedroid/BluetoothDaemonCoreInterface.cpp',
                 'bluedroid/BluetoothDaemonGattInterface.cpp',
                 'bluedroid/BluetoothDaemonHandsfreeInterface.cpp',
                 'bluedroid/BluetoothDaemonHelpers.cpp',
                 'bluedroid/BluetoothDaemonInterface.cpp',
                 'bluedroid/BluetoothDaemonSetupInterface.cpp',
                 'bluedroid/BluetoothDaemonSocketInterface.cpp',
                 'bluedroid/BluetoothGattManager.cpp',
                 'bluedroid/BluetoothMapFolder.cpp',
--- a/dom/browser-element/BrowserElementCopyPaste.js
+++ b/dom/browser-element/BrowserElementCopyPaste.js
@@ -67,17 +67,18 @@ var CopyPasteAssistent = {
         canCopy: this._isCommandEnabled("copy"),
         canPaste: this._isCommandEnabled("paste"),
       },
       zoomFactor: zoomFactor,
       reason: e.reason,
       collapsed: e.collapsed,
       caretVisible: e.caretVisible,
       selectionVisible: e.selectionVisible,
-      selectionEditable: e.selectionEditable
+      selectionEditable: e.selectionEditable,
+      selectedTextContent: e.selectedTextContent
     };
 
     // Get correct geometry information if we have nested iframe.
     let currentWindow = e.target.defaultView;
     while (currentWindow.realFrameElement) {
       let currentRect = currentWindow.realFrameElement.getBoundingClientRect();
       detail.rect.top += currentRect.top;
       detail.rect.bottom += currentRect.top;
--- a/dom/browser-element/BrowserElementParent.js
+++ b/dom/browser-element/BrowserElementParent.js
@@ -454,16 +454,18 @@ BrowserElementParent.prototype = {
   //  - zoomFactor: Current zoom factor in child frame.
   //  - reason: The reason causes the state changed. Include "visibilitychange",
   //            "updateposition", "longpressonemptycontent", "taponcaret", "presscaret",
   //            "releasecaret".
   //  - collapsed: Indicate current selection is collapsed or not.
   //  - caretVisible: Indicate the caret visiibility.
   //  - selectionVisible: Indicate current selection is visible or not.
   //  - selectionEditable: Indicate current selection is editable or not.
+  //  - selectedTextContent: Contains current selected text content, which is
+  //                         equivalent to the string returned by Selection.toString().
   _handleCaretStateChanged: function(data) {
     let evt = this._createEvent('caretstatechanged', data.json,
                                 /* cancelable = */ false);
 
     let self = this;
     function sendDoCommandMsg(cmd) {
       let data = { command: cmd };
       self._sendAsyncMsg('copypaste-do-command', data);
--- a/dom/webidl/CaretStateChangedEvent.webidl
+++ b/dom/webidl/CaretStateChangedEvent.webidl
@@ -15,20 +15,22 @@ enum CaretChangedReason {
 
 dictionary CaretStateChangedEventInit : EventInit {
   boolean collapsed = true;
   DOMRectReadOnly? boundingClientRect = null;
   CaretChangedReason reason = "visibilitychange";
   boolean caretVisible = false;
   boolean selectionVisible = false;
   boolean selectionEditable = false;
+  DOMString selectedTextContent = "";
 };
 
 [Constructor(DOMString type, optional CaretStateChangedEventInit eventInit),
  ChromeOnly]
 interface CaretStateChangedEvent : Event {
   readonly attribute boolean collapsed;
   readonly attribute DOMRectReadOnly? boundingClientRect;
   readonly attribute CaretChangedReason reason;
   readonly attribute boolean caretVisible;
   readonly attribute boolean selectionVisible;
   readonly attribute boolean selectionEditable;
+  readonly attribute DOMString selectedTextContent;
 };
--- a/ipc/glue/MessageLink.cpp
+++ b/ipc/glue/MessageLink.cpp
@@ -8,17 +8,17 @@
 #include "mozilla/ipc/MessageLink.h"
 #include "mozilla/ipc/MessageChannel.h"
 #include "mozilla/ipc/BrowserProcessSubThread.h"
 #include "mozilla/ipc/ProtocolUtils.h"
 
 #ifdef MOZ_NUWA_PROCESS
 #include "ipc/Nuwa.h"
 #include "mozilla/Preferences.h"
-#include "mozilla/dom/PContent.h"
+#include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/PNuwa.h"
 #include "mozilla/hal_sandbox/PHal.h"
 #if defined(DEBUG) || defined(ENABLE_TESTS)
 #include "jsprf.h"
 extern "C" char* PrintJSStack();
 #endif
 #endif
 
@@ -139,17 +139,17 @@ ProcessLink::Open(mozilla::ipc::Transpor
             // over the channel from the previous listener and process
             // any queued messages.
             mIOLoop->PostTask(
                 FROM_HERE,
                 NewRunnableMethod(this, &ProcessLink::OnTakeConnectedChannel));
         }
 
 #ifdef MOZ_NUWA_PROCESS
-        if (IsNuwaProcess() &&
+        if (IsNuwaProcess() && NS_IsMainThread() &&
             Preferences::GetBool("dom.ipc.processPrelaunch.testMode")) {
             // The pref value is turned on in a deadlock test against the Nuwa
             // process. The sleep here makes it easy to trigger the deadlock
             // that an IPC channel is still opening but the worker loop is
             // already frozen.
             sleep(5);
         }
 #endif
--- a/layout/base/AccessibleCaretManager.cpp
+++ b/layout/base/AccessibleCaretManager.cpp
@@ -948,16 +948,17 @@ AccessibleCaretManager::DispatchCaretSta
   init.mSelectionEditable = commonAncestorFrame &&
     commonAncestorFrame->GetContent()->GetEditingHost();
 
   init.mBoundingClientRect = domRect;
   init.mReason = aReason;
   init.mCollapsed = sel->IsCollapsed();
   init.mCaretVisible = mFirstCaret->IsLogicallyVisible() ||
                        mSecondCaret->IsLogicallyVisible();
+  sel->Stringify(init.mSelectedTextContent);
 
   nsRefPtr<CaretStateChangedEvent> event =
     CaretStateChangedEvent::Constructor(doc, NS_LITERAL_STRING("mozcaretstatechanged"), init);
 
   event->SetTrusted(true);
   event->GetInternalNSEvent()->mFlags.mOnlyChromeDispatch = true;
 
   AC_LOG("%s: reason %d, collapsed %d, caretVisible %d", __FUNCTION__,
--- a/testing/taskcluster/mach_commands.py
+++ b/testing/taskcluster/mach_commands.py
@@ -191,17 +191,17 @@ def set_interactive_task(task, interacti
 
 def remove_caches_from_task(task):
     r"""Remove all caches but tc-vcs from the task.
 
     :param task: task definition.
     """
     whitelist = [
         "tc-vcs",
-        "tc-vcs-public-source",
+        "tc-vcs-public-sources",
         "tooltool-cache",
     ]
     try:
         caches = task["task"]["payload"]["cache"]
         for cache in caches.keys():
             if cache not in whitelist:
                 caches.pop(cache)
     except KeyError:
--- a/toolkit/mozapps/update/nsUpdateService.js
+++ b/toolkit/mozapps/update/nsUpdateService.js
@@ -26,16 +26,17 @@ const PREF_APP_UPDATE_BACKGROUNDERRORS  
 const PREF_APP_UPDATE_BACKGROUNDMAXERRORS = "app.update.backgroundMaxErrors";
 const PREF_APP_UPDATE_CANCELATIONS        = "app.update.cancelations";
 const PREF_APP_UPDATE_CERTS_BRANCH        = "app.update.certs.";
 const PREF_APP_UPDATE_CERT_CHECKATTRS     = "app.update.cert.checkAttributes";
 const PREF_APP_UPDATE_CERT_ERRORS         = "app.update.cert.errors";
 const PREF_APP_UPDATE_CERT_MAXERRORS      = "app.update.cert.maxErrors";
 const PREF_APP_UPDATE_CERT_REQUIREBUILTIN = "app.update.cert.requireBuiltIn";
 const PREF_APP_UPDATE_CUSTOM              = "app.update.custom";
+const PREF_APP_UPDATE_IMEI_HASH           = "app.update.imei_hash";
 const PREF_APP_UPDATE_ENABLED             = "app.update.enabled";
 const PREF_APP_UPDATE_IDLETIME            = "app.update.idletime";
 const PREF_APP_UPDATE_INCOMPATIBLE_MODE   = "app.update.incompatible.mode";
 const PREF_APP_UPDATE_INTERVAL            = "app.update.interval";
 const PREF_APP_UPDATE_LOG                 = "app.update.log";
 const PREF_APP_UPDATE_MODE                = "app.update.mode";
 const PREF_APP_UPDATE_NEVER_BRANCH        = "app.update.never.";
 const PREF_APP_UPDATE_NOTIFIEDUNSUPPORTED = "app.update.notifiedUnsupported";
@@ -3541,16 +3542,18 @@ Checker.prototype = {
                         sysLibs.libcutils.property_get("ro.product.model"));
       if (buildType == "user" || buildType == "userdebug") {
         url = url.replace(/%PRODUCT_DEVICE%/g, productDevice);
       } else {
         url = url.replace(/%PRODUCT_DEVICE%/g, productDevice + "-" + buildType);
       }
       url = url.replace(/%B2G_VERSION%/g,
                         getPref("getCharPref", PREF_APP_B2G_VERSION, null));
+      url = url.replace(/%IMEI%/g,
+                        getPref("getCharPref", PREF_APP_UPDATE_IMEI_HASH, "default"));
     }
 
     if (force) {
       url += (url.indexOf("?") != -1 ? "&" : "?") + "force=1";
     }
 
     LOG("Checker:getUpdateURL - update URL: " + url);
     return url;