Merge b2g-inbound to m-c. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 28 Oct 2014 16:22:39 -0400
changeset 212756 53d84829b2b8d4bc2a1f8201e6ddaceaab2d2f4e
parent 212719 3694deb38dd491144971e1ce0a40cb32073c3ccf (current diff)
parent 212755 027c26c99a739444b249987b82572ffb033121b3 (diff)
child 212757 ed2cdcdb52408e549b5f5d47c6ebc02d506d83bb
child 212784 33fe8108949750fffeeac08db371d7be92d1145a
child 212789 8c85981bfad41b4f9b28544e11ba4ed23cbf0371
push id51042
push userryanvm@gmail.com
push dateTue, 28 Oct 2014 20:25:03 +0000
treeherdermozilla-inbound@53d84829b2b8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone36.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 b2g-inbound to m-c. a=merge CLOSED TREE
--- a/CLOBBER
+++ b/CLOBBER
@@ -17,9 +17,12 @@
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
 # Are you updating CLOBBER because you think it's needed for your WebIDL
 # changes to stick? As of bug 928195, this shouldn't be necessary! Please
 # don't change CLOBBER for WebIDL changes any more.
 
-Backout of bug 1087560 needed a CLOBBER
+Updating CLOBBER for Bug 1084342
+
+There are some refactored files in in dom/bluetooth. Updating CLOBBER to not
+leave artifacts from older builds.
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -10,25 +10,25 @@
   <!--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="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="75e10bb632b1e4a47493d0a66bc32fb74249c57f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="b48f66220dff75f767eddf28a1d58192fc811410"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <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="be8b952fde51d8c83748b41ce232f02b2218451d"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f718a14ed4963ac99d613b7ba7a997dae7b13d70"/>
   <!-- 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"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="83760d213fb3bec7b4117d266fcfbf6fe2ba14ab"/>
   <project name="device/common" path="device/common" revision="6a2995683de147791e516aae2ccb31fdfbe2ad30"/>
@@ -108,17 +108,17 @@
   <project name="platform/frameworks/wilhelm" path="frameworks/wilhelm" revision="aac6c4bb59a6577c97cbda68699829b507b7490d"/>
   <project name="platform/hardware/libhardware" path="hardware/libhardware" revision="fbeca55f4695dd07c0291213403533b8fbca4885"/>
   <project name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="a8449b1de00c313a4ca90d55af44c9b706b17926"/>
   <project name="platform/libcore" path="libcore" revision="e195beab082c09217318fc19250caeaf4c1bd800"/>
   <project name="platform/libnativehelper" path="libnativehelper" revision="feeb36c2bd4adfe285f98f5de92e0f3771b2c115"/>
   <project name="platform/ndk" path="ndk" revision="e58ef003be4306bb53a8c11331146f39e4eab31f"/>
   <project name="platform/prebuilts/misc" path="prebuilts/misc" revision="ee724654c72825f8d732ba45caf75ca59e06975d"/>
   <project name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="c792f0bd9fff7aea2887c60bbb3a9bbdb534ffa3"/>
-  <project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="1a982dd6b02b939c75cd116d2d9de97e6ff3de24"/>
+  <project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="c24c8871173bf6aedcf236cab075edf092a7015c"/>
   <project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="cfcef469537869947abb9aa1d656774cc2678d4c"/>
   <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5a48c04c4bb5f079bc757e29864a42427378e051"/>
   <project name="platform/system/extras" path="system/extras" revision="10e78a05252b3de785f88c2d0b9ea8a428009c50"/>
   <project name="platform/system/media" path="system/media" revision="7ff72c2ea2496fa50b5e8a915e56e901c3ccd240"/>
   <project name="platform/system/netd" path="system/netd" revision="3ae56364946d4a5bf5a5f83f12f9a45a30398e33"/>
   <project name="platform/system/security" path="system/security" revision="ee8068b9e7bfb2770635062fc9c2035be2142bd8"/>
   <project name="platform/system/vold" path="system/vold" revision="2e43efe1b30d0b98574d293059556aebd2f46454"/>
   <!--original fetch url was http://sprdsource.spreadtrum.com:8085/b2g/android-->
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,23 +14,23 @@
   <!--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="70eb0cb0977d6295e7da8896f9efb9f3ca1c13ea">
     <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="75e10bb632b1e4a47493d0a66bc32fb74249c57f"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="b48f66220dff75f767eddf28a1d58192fc811410"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c058843242068d0df7c107e09da31b53d2e08fa6"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f718a14ed4963ac99d613b7ba7a997dae7b13d70"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
   <project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
   <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"/>
   <project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="52a1a862a8bac319652b8f82d9541ba40bfa45ce"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,20 +12,20 @@
   <!--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="8986df0f82e15ac2798df0b6c2ee3435400677ac">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="75e10bb632b1e4a47493d0a66bc32fb74249c57f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="b48f66220dff75f767eddf28a1d58192fc811410"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f718a14ed4963ac99d613b7ba7a997dae7b13d70"/>
   <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"/>
   <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="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,25 +10,25 @@
   <!--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="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="75e10bb632b1e4a47493d0a66bc32fb74249c57f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="b48f66220dff75f767eddf28a1d58192fc811410"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <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="be8b952fde51d8c83748b41ce232f02b2218451d"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f718a14ed4963ac99d613b7ba7a997dae7b13d70"/>
   <!-- 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"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="ac6eb97a37035c09fb5ede0852f0881e9aadf9ad"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="737f591c5f95477148d26602c7be56cbea0cdeb9"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="51da9b1981be481b92a59a826d4d78dc73d0989a"/>
   <project name="device/common" path="device/common" revision="798a3664597e6041985feab9aef42e98d458bc3d"/>
@@ -108,17 +108,17 @@
   <project name="platform/frameworks/wilhelm" path="frameworks/wilhelm" revision="eb6077f10ae6255a72337124188f0e08dcd10e3e"/>
   <project name="platform/hardware/libhardware" path="hardware/libhardware" revision="3b80c725cea54132df05d208930d91e00d19f999"/>
   <project name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="01f436c51dc68aec7cc1c85fda6e6792b2a95066"/>
   <project name="platform/libcore" path="libcore" revision="9877ade9617bb0db6e59aa2a54719a9bc92600f3"/>
   <project name="platform/libnativehelper" path="libnativehelper" revision="46c96ace65eb1ccab05bf15b9bf8e53e443039af"/>
   <project name="platform/ndk" path="ndk" revision="cb5519af32ae7b4a9c334913a612462ecd04c5d0"/>
   <project name="platform/prebuilts/misc" path="prebuilts/misc" revision="99c9a644e84a1b0e0a5d240406753b6bc4caca54"/>
   <project name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="6aa61f8557a22039a30b42b7f283996381fd625d"/>
-  <project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="1a982dd6b02b939c75cd116d2d9de97e6ff3de24"/>
+  <project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="c24c8871173bf6aedcf236cab075edf092a7015c"/>
   <project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="b562b01c93de9578d5db537b6a602a38e1aaa0ce"/>
   <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="387f03e815f57d536dd922706db1622bddba8d81"/>
   <project name="platform/system/extras" path="system/extras" revision="5356165f67f4a81c2ef28671c13697f1657590df"/>
   <project name="platform/system/media" path="system/media" revision="be0e2fe59a8043fa5200f75697df9220a99abe9d"/>
   <project name="platform/system/netd" path="system/netd" revision="36704b0da24debcab8090156568ac236315036bb"/>
   <project name="platform/system/security" path="system/security" revision="583374f69f531ba68fc3dcbff1f74893d2a96406"/>
   <project name="platform/system/vold" path="system/vold" revision="d4455b8cf361f8353e8aebac15ffd64b4aedd2b9"/>
   <project name="platform/external/icu4c" path="external/icu4c" remote="aosp" revision="b4c6379528887dc25ca9991a535a8d92a61ad6b6"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,23 +14,23 @@
   <!--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="70eb0cb0977d6295e7da8896f9efb9f3ca1c13ea">
     <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="75e10bb632b1e4a47493d0a66bc32fb74249c57f"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="b48f66220dff75f767eddf28a1d58192fc811410"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c058843242068d0df7c107e09da31b53d2e08fa6"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f718a14ed4963ac99d613b7ba7a997dae7b13d70"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
   <project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
   <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"/>
   <project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="52a1a862a8bac319652b8f82d9541ba40bfa45ce"/>
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -10,25 +10,25 @@
   <!--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="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="75e10bb632b1e4a47493d0a66bc32fb74249c57f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="b48f66220dff75f767eddf28a1d58192fc811410"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <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="be8b952fde51d8c83748b41ce232f02b2218451d"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f718a14ed4963ac99d613b7ba7a997dae7b13d70"/>
   <!-- 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"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="a32003194f707f66a2d8cdb913ed1869f1926c5d"/>
   <project name="device/common" path="device/common" revision="96d4d2006c4fcb2f19a3fa47ab10cb409faa017b"/>
@@ -108,17 +108,17 @@
   <project name="platform/frameworks/wilhelm" path="frameworks/wilhelm" revision="f0c3b4edf597c40aae4ea311575f39c8bcf203df"/>
   <project name="platform/hardware/libhardware" path="hardware/libhardware" revision="9a60e685a9fb38a716f18a89cd872942f75b4706"/>
   <project name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="adb52b35ecb523bd332854945c09828ee887e575"/>
   <project name="platform/libcore" path="libcore" revision="baf7d8068dd501cfa338d3a8b1b87216d6ce0571"/>
   <project name="platform/libnativehelper" path="libnativehelper" revision="50c4430e32849530ced32680fd6ee98963b3f7ac"/>
   <project name="platform/ndk" path="ndk" revision="e58ef003be4306bb53a8c11331146f39e4eab31f"/>
   <project name="platform/prebuilts/misc" path="prebuilts/misc" revision="a094aa8f160e211fb4994fdfaaac8a78aa6cc897"/>
   <project name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="c792f0bd9fff7aea2887c60bbb3a9bbdb534ffa3"/>
-  <project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="1a982dd6b02b939c75cd116d2d9de97e6ff3de24"/>
+  <project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="c24c8871173bf6aedcf236cab075edf092a7015c"/>
   <project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="69d524e80cdf3981006627c65ac85f3a871238a3"/>
   <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5a48c04c4bb5f079bc757e29864a42427378e051"/>
   <project name="platform/system/extras" path="system/extras" revision="576f57b6510de59c08568b53c0fb60588be8689e"/>
   <project name="platform/system/media" path="system/media" revision="20c2fb4c896aa59f2e8379d755f439dc59a5cf9b"/>
   <project name="platform/system/netd" path="system/netd" revision="a6531f7befb49b1c81bc0de7e51c5482b308e1c5"/>
   <project name="platform/system/security" path="system/security" revision="ee8068b9e7bfb2770635062fc9c2035be2142bd8"/>
   <project name="platform/system/vold" path="system/vold" revision="42fa2a0f14f965970a4b629a176bbd2666edf017"/>
   <project name="platform/external/icu4c" path="external/icu4c" revision="d3ec7428eb276db43b7ed0544e09344a6014806c"/>
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -12,20 +12,20 @@
   <!--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="8986df0f82e15ac2798df0b6c2ee3435400677ac">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="75e10bb632b1e4a47493d0a66bc32fb74249c57f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="b48f66220dff75f767eddf28a1d58192fc811410"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f718a14ed4963ac99d613b7ba7a997dae7b13d70"/>
   <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="e95b4ce22c825da44d14299e1190ea39a5260bde"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="471afab478649078ad7c75ec6b252481a59e19b8"/>
   <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": "", 
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "6b4f6119f0e3816af1db5b27a3fa76f8278f77f4", 
+    "revision": "f797c345e7f872424ce9fd24f1bd3b769cd6dc9d", 
     "repo_path": "/integration/gaia-central"
 }
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -12,22 +12,22 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="70eb0cb0977d6295e7da8896f9efb9f3ca1c13ea">
     <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="75e10bb632b1e4a47493d0a66bc32fb74249c57f"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="b48f66220dff75f767eddf28a1d58192fc811410"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f718a14ed4963ac99d613b7ba7a997dae7b13d70"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="746bc48f34f5060f90801925dcdd964030c1ab6d"/>
   <project name="platform/development" path="development" revision="2460485184bc8535440bb63876d4e63ec1b4770c"/>
   <project name="device/common" path="device/common" revision="0dcc1e03659db33b77392529466f9eb685cdd3c7"/>
   <project name="device/sample" path="device/sample" revision="68b1cb978a20806176123b959cb05d4fa8adaea4"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="70eb0cb0977d6295e7da8896f9efb9f3ca1c13ea">
     <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="75e10bb632b1e4a47493d0a66bc32fb74249c57f"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="b48f66220dff75f767eddf28a1d58192fc811410"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -12,20 +12,20 @@
   <!--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="8986df0f82e15ac2798df0b6c2ee3435400677ac">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="75e10bb632b1e4a47493d0a66bc32fb74249c57f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="b48f66220dff75f767eddf28a1d58192fc811410"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f718a14ed4963ac99d613b7ba7a997dae7b13d70"/>
   <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"/>
   <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="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -12,22 +12,22 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="70eb0cb0977d6295e7da8896f9efb9f3ca1c13ea">
     <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="75e10bb632b1e4a47493d0a66bc32fb74249c57f"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="b48f66220dff75f767eddf28a1d58192fc811410"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f718a14ed4963ac99d613b7ba7a997dae7b13d70"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="cd5dfce80bc3f0139a56b58aca633202ccaee7f8"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="e0a9ac010df3afaa47ba107192c05ac8b5516435"/>
   <project name="platform/development" path="development" revision="a384622f5fcb1d2bebb9102591ff7ae91fe8ed2d"/>
   <project name="device/common" path="device/common" revision="7c65ea240157763b8ded6154a17d3c033167afb7"/>
   <project name="device/sample" path="device/sample" revision="c328f3d4409db801628861baa8d279fb8855892f"/>
--- a/dom/bluetooth/bluedroid/BluetoothSocketHALInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothSocketHALInterface.cpp
@@ -1,19 +1,17 @@
 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
 /* vim: set ts=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 "BluetoothSocketHALInterface.h"
-#include <errno.h>
-#include <unistd.h>
-#include <sys/socket.h>
 #include "BluetoothHALHelpers.h"
+#include "BluetoothSocketMessageWatcher.h"
 #include "mozilla/FileUtils.h"
 #include "nsClassHashtable.h"
 #include "nsXULAppAPI.h"
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 typedef
   BluetoothHALInterfaceRunnable1<BluetoothSocketResultHandler, void,
@@ -102,304 +100,16 @@ BluetoothSocketHALInterface::Listen(Blue
 
   if (aRes) {
     DispatchBluetoothSocketHALResult(
       aRes, &BluetoothSocketResultHandler::Listen, fd,
       ConvertDefault(status, STATUS_FAIL));
   }
 }
 
-#define CMSGHDR_CONTAINS_FD(_cmsghdr) \
-    ( ((_cmsghdr)->cmsg_level == SOL_SOCKET) && \
-      ((_cmsghdr)->cmsg_type == SCM_RIGHTS) )
-
-class SocketMessageWatcher;
-
-/* |SocketMessageWatcherWrapper| wraps SocketMessageWatcher to keep it from
- * being released by hash table's Remove() method.
- */
-class SocketMessageWatcherWrapper
-{
-public:
-  SocketMessageWatcherWrapper(SocketMessageWatcher* aSocketMessageWatcher)
-  : mSocketMessageWatcher(aSocketMessageWatcher)
-  {
-    MOZ_ASSERT(mSocketMessageWatcher);
-  }
-
-  SocketMessageWatcher* GetSocketMessageWatcher()
-  {
-    return mSocketMessageWatcher;
-  }
-
-private:
-  SocketMessageWatcher* mSocketMessageWatcher;
-};
-
-/* |sWatcherHashTable| maps result handlers to corresponding watchers */
-static nsClassHashtable<nsRefPtrHashKey<BluetoothSocketResultHandler>,
-                        SocketMessageWatcherWrapper>
-  sWatcherHashtable;
-
-/* |SocketMessageWatcher| receives Bluedroid's socket setup
- * messages on the I/O thread. You need to inherit from this
- * class to make use of it.
- *
- * Bluedroid sends two socket info messages (20 bytes) at
- * the beginning of a connection to both peers.
- *
- *   - 1st message: [channel:4]
- *   - 2nd message: [size:2][bd address:6][channel:4][connection status:4]
- *
- * On the server side, the second message will contain a
- * socket file descriptor for the connection. The client
- * uses the original file descriptor.
- */
-class SocketMessageWatcher : public MessageLoopForIO::Watcher
-{
-public:
-  static const unsigned char MSG1_SIZE = 4;
-  static const unsigned char MSG2_SIZE = 16;
-
-  static const unsigned char OFF_CHANNEL1 = 0;
-  static const unsigned char OFF_SIZE = 4;
-  static const unsigned char OFF_BDADDRESS = 6;
-  static const unsigned char OFF_CHANNEL2 = 12;
-  static const unsigned char OFF_STATUS = 16;
-
-  SocketMessageWatcher(int aFd, BluetoothSocketResultHandler* aRes)
-  : mFd(aFd)
-  , mClientFd(-1)
-  , mLen(0)
-  , mRes(aRes)
-  {
-    MOZ_ASSERT(mRes);
-  }
-
-  virtual ~SocketMessageWatcher()
-  { }
-
-  virtual void Proceed(BluetoothStatus aStatus) = 0;
-
-  void OnFileCanReadWithoutBlocking(int aFd) MOZ_OVERRIDE
-  {
-    BluetoothStatus status;
-
-    switch (mLen) {
-      case 0:
-        status = RecvMsg1();
-        break;
-      case MSG1_SIZE:
-        status = RecvMsg2();
-        break;
-      default:
-        /* message-size error */
-        status = STATUS_FAIL;
-        break;
-    }
-
-    if (IsComplete() || status != STATUS_SUCCESS) {
-      StopWatching();
-      Proceed(status);
-    }
-  }
-
-  void OnFileCanWriteWithoutBlocking(int aFd) MOZ_OVERRIDE
-  { }
-
-  void Watch()
-  {
-    // add this watcher and its result handler to hash table
-    sWatcherHashtable.Put(mRes, new SocketMessageWatcherWrapper(this));
-
-    MessageLoopForIO::current()->WatchFileDescriptor(
-      mFd,
-      true,
-      MessageLoopForIO::WATCH_READ,
-      &mWatcher,
-      this);
-  }
-
-  void StopWatching()
-  {
-    mWatcher.StopWatchingFileDescriptor();
-
-    // remove this watcher and its result handler from hash table
-    sWatcherHashtable.Remove(mRes);
-  }
-
-  bool IsComplete() const
-  {
-    return mLen == (MSG1_SIZE + MSG2_SIZE);
-  }
-
-  int GetFd() const
-  {
-    return mFd;
-  }
-
-  int32_t GetChannel1() const
-  {
-    return ReadInt32(OFF_CHANNEL1);
-  }
-
-  int32_t GetSize() const
-  {
-    return ReadInt16(OFF_SIZE);
-  }
-
-  nsString GetBdAddress() const
-  {
-    nsString bdAddress;
-    ReadBdAddress(OFF_BDADDRESS, bdAddress);
-    return bdAddress;
-  }
-
-  int32_t GetChannel2() const
-  {
-    return ReadInt32(OFF_CHANNEL2);
-  }
-
-  int32_t GetConnectionStatus() const
-  {
-    return ReadInt32(OFF_STATUS);
-  }
-
-  int GetClientFd() const
-  {
-    return mClientFd;
-  }
-
-  BluetoothSocketResultHandler* GetResultHandler() const
-  {
-    return mRes;
-  }
-
-private:
-  BluetoothStatus RecvMsg1()
-  {
-    struct iovec iv;
-    memset(&iv, 0, sizeof(iv));
-    iv.iov_base = mBuf;
-    iv.iov_len = MSG1_SIZE;
-
-    struct msghdr msg;
-    memset(&msg, 0, sizeof(msg));
-    msg.msg_iov = &iv;
-    msg.msg_iovlen = 1;
-
-    ssize_t res = TEMP_FAILURE_RETRY(recvmsg(mFd, &msg, MSG_NOSIGNAL));
-    if (res <= 0) {
-      return STATUS_FAIL;
-    }
-
-    mLen += res;
-
-    return STATUS_SUCCESS;
-  }
-
-  BluetoothStatus RecvMsg2()
-  {
-    struct iovec iv;
-    memset(&iv, 0, sizeof(iv));
-    iv.iov_base = mBuf + MSG1_SIZE;
-    iv.iov_len = MSG2_SIZE;
-
-    struct msghdr msg;
-    struct cmsghdr cmsgbuf[2 * sizeof(cmsghdr) + 0x100];
-    memset(&msg, 0, sizeof(msg));
-    msg.msg_iov = &iv;
-    msg.msg_iovlen = 1;
-    msg.msg_control = cmsgbuf;
-    msg.msg_controllen = sizeof(cmsgbuf);
-
-    ssize_t res = TEMP_FAILURE_RETRY(recvmsg(mFd, &msg, MSG_NOSIGNAL));
-    if (res <= 0) {
-      return STATUS_FAIL;
-    }
-
-    mLen += res;
-
-    if (msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) {
-      return STATUS_FAIL;
-    }
-
-    struct cmsghdr *cmsgptr = CMSG_FIRSTHDR(&msg);
-
-    // Extract client fd from message header
-    for (; cmsgptr; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
-      if (CMSGHDR_CONTAINS_FD(cmsgptr)) {
-        // if multiple file descriptors have been sent, we close
-        // all but the final one.
-        if (mClientFd != -1) {
-          TEMP_FAILURE_RETRY(close(mClientFd));
-        }
-        // retrieve sent client fd
-        mClientFd = *(static_cast<int*>(CMSG_DATA(cmsgptr)));
-      }
-    }
-
-    return STATUS_SUCCESS;
-  }
-
-  int16_t ReadInt16(unsigned long aOffset) const
-  {
-    /* little-endian buffer */
-    return (static_cast<int16_t>(mBuf[aOffset + 1]) << 8) |
-            static_cast<int16_t>(mBuf[aOffset]);
-  }
-
-  int32_t ReadInt32(unsigned long aOffset) const
-  {
-    /* little-endian buffer */
-    return (static_cast<int32_t>(mBuf[aOffset + 3]) << 24) |
-           (static_cast<int32_t>(mBuf[aOffset + 2]) << 16) |
-           (static_cast<int32_t>(mBuf[aOffset + 1]) << 8) |
-            static_cast<int32_t>(mBuf[aOffset]);
-  }
-
-  void ReadBdAddress(unsigned long aOffset, nsAString& aBdAddress) const
-  {
-    const bt_bdaddr_t* bdAddress =
-      reinterpret_cast<const bt_bdaddr_t*>(mBuf+aOffset);
-
-    if (NS_FAILED(Convert(*bdAddress, aBdAddress))) {
-      aBdAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE);
-    }
-  }
-
-  MessageLoopForIO::FileDescriptorWatcher mWatcher;
-  int mFd;
-  int mClientFd;
-  unsigned char mLen;
-  uint8_t mBuf[MSG1_SIZE + MSG2_SIZE];
-  nsRefPtr<BluetoothSocketResultHandler> mRes;
-};
-
-/* |SocketMessageWatcherTask| starts a SocketMessageWatcher
- * on the I/O task
- */
-class SocketMessageWatcherTask MOZ_FINAL : public Task
-{
-public:
-  SocketMessageWatcherTask(SocketMessageWatcher* aWatcher)
-  : mWatcher(aWatcher)
-  {
-    MOZ_ASSERT(mWatcher);
-  }
-
-  void Run() MOZ_OVERRIDE
-  {
-    mWatcher->Watch();
-  }
-
-private:
-  SocketMessageWatcher* mWatcher;
-};
-
 /* |DeleteTask| deletes a class instance on the I/O thread
  */
 template <typename T>
 class DeleteTask MOZ_FINAL : public Task
 {
 public:
   DeleteTask(T* aPtr)
   : mPtr(aPtr)
@@ -414,21 +124,22 @@ private:
   nsAutoPtr<T> mPtr;
 };
 
 /* |ConnectWatcher| specializes SocketMessageWatcher for
  * connect operations by reading the socket messages from
  * Bluedroid and forwarding the connected socket to the
  * resource handler.
  */
-class ConnectWatcher MOZ_FINAL : public SocketMessageWatcher
+class BluetoothSocketHALInterface::ConnectWatcher MOZ_FINAL
+  : public SocketMessageWatcher
 {
 public:
   ConnectWatcher(int aFd, BluetoothSocketResultHandler* aRes)
-  : SocketMessageWatcher(aFd, aRes)
+    : SocketMessageWatcher(aFd, aRes)
   { }
 
   void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE
   {
     DispatchBluetoothSocketHALResult(
       GetResultHandler(), &BluetoothSocketResultHandler::Connect,
       GetFd(), GetBdAddress(), GetConnectionStatus(), aStatus);
 
@@ -472,21 +183,22 @@ BluetoothSocketHALInterface::Connect(con
 
 /* |AcceptWatcher| specializes SocketMessageWatcher for Accept
  * operations by reading the socket messages from Bluedroid and
  * forwarding the received client socket to the resource handler.
  * The first message is received immediately. When there's a new
  * connection, Bluedroid sends the 2nd message with the socket
  * info and socket file descriptor.
  */
-class AcceptWatcher MOZ_FINAL : public SocketMessageWatcher
+class BluetoothSocketHALInterface::AcceptWatcher MOZ_FINAL
+  : public SocketMessageWatcher
 {
 public:
   AcceptWatcher(int aFd, BluetoothSocketResultHandler* aRes)
-  : SocketMessageWatcher(aFd, aRes)
+    : SocketMessageWatcher(aFd, aRes)
   { }
 
   void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE
   {
     if ((aStatus != STATUS_SUCCESS) && (GetClientFd() != -1)) {
       mozilla::ScopedClose(GetClientFd()); // Close received socket fd on error
     }
 
@@ -503,46 +215,16 @@ void
 BluetoothSocketHALInterface::Accept(int aFd,
                                     BluetoothSocketResultHandler* aRes)
 {
   /* receive Bluedroid's socket-setup messages and client fd */
   Task* t = new SocketMessageWatcherTask(new AcceptWatcher(aFd, aRes));
   XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
 }
 
-/* |DeleteSocketMessageWatcherTask| deletes a watching SocketMessageWatcher
- * on the I/O task
- */
-class DeleteSocketMessageWatcherTask MOZ_FINAL : public Task
-{
-public:
-  DeleteSocketMessageWatcherTask(BluetoothSocketResultHandler* aRes)
-  : mRes(aRes)
-  {
-    MOZ_ASSERT(mRes);
-  }
-
-  void Run() MOZ_OVERRIDE
-  {
-    // look up hash table for the watcher corresponding to |mRes|
-    SocketMessageWatcherWrapper* wrapper = sWatcherHashtable.Get(mRes);
-    if (!wrapper) {
-      return;
-    }
-
-    // stop the watcher if it exists
-    SocketMessageWatcher* watcher = wrapper->GetSocketMessageWatcher();
-    watcher->StopWatching();
-    watcher->Proceed(STATUS_DONE);
-  }
-
-private:
-  BluetoothSocketResultHandler* mRes;
-};
-
 void
 BluetoothSocketHALInterface::Close(BluetoothSocketResultHandler* aRes)
 {
   MOZ_ASSERT(aRes);
 
   /* stop the watcher corresponding to |aRes| */
   Task* t = new DeleteSocketMessageWatcherTask(aRes);
   XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
--- a/dom/bluetooth/bluedroid/BluetoothSocketHALInterface.h
+++ b/dom/bluetooth/bluedroid/BluetoothSocketHALInterface.h
@@ -15,16 +15,19 @@
 BEGIN_BLUETOOTH_NAMESPACE
 
 class BluetoothHALInterface;
 
 class BluetoothSocketHALInterface MOZ_FINAL
   : public BluetoothSocketInterface
 {
 public:
+  class ConnectWatcher;
+  class AcceptWatcher;
+
   friend class BluetoothHALInterface;
 
   void Listen(BluetoothSocketType aType,
               const nsAString& aServiceName,
               const uint8_t aServiceUuid[16],
               int aChannel, bool aEncrypt, bool aAuth,
               BluetoothSocketResultHandler* aRes);
 
new file mode 100644
--- /dev/null
+++ b/dom/bluetooth/bluedroid/BluetoothSocketMessageWatcher.cpp
@@ -0,0 +1,325 @@
+/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
+/* vim: set ts=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 "BluetoothSocketMessageWatcher.h"
+#include <errno.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include "BluetoothInterface.h"
+#include "nsClassHashtable.h"
+
+BEGIN_BLUETOOTH_NAMESPACE
+
+//
+// SocketMessageWatcherWrapper
+//
+
+/* |SocketMessageWatcherWrapper| wraps SocketMessageWatcher to keep it from
+ * being released by hash table's Remove() method.
+ */
+class SocketMessageWatcherWrapper
+{
+public:
+  SocketMessageWatcherWrapper(SocketMessageWatcher* aSocketMessageWatcher)
+    : mSocketMessageWatcher(aSocketMessageWatcher)
+  {
+    MOZ_ASSERT(mSocketMessageWatcher);
+  }
+
+  SocketMessageWatcher* GetSocketMessageWatcher()
+  {
+    return mSocketMessageWatcher;
+  }
+
+private:
+  SocketMessageWatcher* mSocketMessageWatcher;
+};
+
+/* |sWatcherHashTable| maps result handlers to corresponding watchers */
+static nsClassHashtable<nsRefPtrHashKey<BluetoothSocketResultHandler>,
+                        SocketMessageWatcherWrapper>
+  sWatcherHashtable;
+
+//
+// SocketMessageWatcher
+//
+
+SocketMessageWatcher::SocketMessageWatcher(
+  int aFd, BluetoothSocketResultHandler* aRes)
+  : mFd(aFd)
+  , mClientFd(-1)
+  , mLen(0)
+  , mRes(aRes)
+{
+  MOZ_ASSERT(mRes);
+}
+
+SocketMessageWatcher::~SocketMessageWatcher()
+{ }
+
+void
+SocketMessageWatcher::OnFileCanReadWithoutBlocking(int aFd)
+{
+  BluetoothStatus status;
+
+  switch (mLen) {
+    case 0:
+      status = RecvMsg1();
+      break;
+    case MSG1_SIZE:
+      status = RecvMsg2();
+      break;
+    default:
+      /* message-size error */
+      status = STATUS_FAIL;
+      break;
+  }
+
+  if (IsComplete() || status != STATUS_SUCCESS) {
+    StopWatching();
+    Proceed(status);
+  }
+}
+
+void
+SocketMessageWatcher::OnFileCanWriteWithoutBlocking(int aFd)
+{ }
+
+void
+SocketMessageWatcher::Watch()
+{
+  // add this watcher and its result handler to hash table
+  sWatcherHashtable.Put(mRes, new SocketMessageWatcherWrapper(this));
+
+  MessageLoopForIO::current()->WatchFileDescriptor(
+    mFd,
+    true,
+    MessageLoopForIO::WATCH_READ,
+    &mWatcher,
+    this);
+}
+
+void
+SocketMessageWatcher::StopWatching()
+{
+  mWatcher.StopWatchingFileDescriptor();
+
+  // remove this watcher and its result handler from hash table
+  sWatcherHashtable.Remove(mRes);
+}
+
+bool
+SocketMessageWatcher::IsComplete() const
+{
+  return mLen == (MSG1_SIZE + MSG2_SIZE);
+}
+
+int
+SocketMessageWatcher::GetFd() const
+{
+  return mFd;
+}
+
+int32_t
+SocketMessageWatcher::GetChannel1() const
+{
+  return ReadInt32(OFF_CHANNEL1);
+}
+
+int32_t
+SocketMessageWatcher::GetSize() const
+{
+  return ReadInt16(OFF_SIZE);
+}
+
+nsString
+SocketMessageWatcher::GetBdAddress() const
+{
+  nsString bdAddress;
+  ReadBdAddress(OFF_BDADDRESS, bdAddress);
+  return bdAddress;
+}
+
+int32_t
+SocketMessageWatcher::GetChannel2() const
+{
+  return ReadInt32(OFF_CHANNEL2);
+}
+
+int32_t
+SocketMessageWatcher::GetConnectionStatus() const
+{
+  return ReadInt32(OFF_STATUS);
+}
+
+int
+SocketMessageWatcher::GetClientFd() const
+{
+  return mClientFd;
+}
+
+BluetoothSocketResultHandler*
+SocketMessageWatcher::GetResultHandler() const
+{
+  return mRes;
+}
+
+BluetoothStatus
+SocketMessageWatcher::RecvMsg1()
+{
+  struct iovec iv;
+  memset(&iv, 0, sizeof(iv));
+  iv.iov_base = mBuf;
+  iv.iov_len = MSG1_SIZE;
+
+  struct msghdr msg;
+  memset(&msg, 0, sizeof(msg));
+  msg.msg_iov = &iv;
+  msg.msg_iovlen = 1;
+
+  ssize_t res = TEMP_FAILURE_RETRY(recvmsg(mFd, &msg, MSG_NOSIGNAL));
+  if (res <= 0) {
+    return STATUS_FAIL;
+  }
+
+  mLen += res;
+
+  return STATUS_SUCCESS;
+}
+
+#define CMSGHDR_CONTAINS_FD(_cmsghdr) \
+    ( ((_cmsghdr)->cmsg_level == SOL_SOCKET) && \
+      ((_cmsghdr)->cmsg_type == SCM_RIGHTS) )
+
+BluetoothStatus
+SocketMessageWatcher::RecvMsg2()
+{
+  struct iovec iv;
+  memset(&iv, 0, sizeof(iv));
+  iv.iov_base = mBuf + MSG1_SIZE;
+  iv.iov_len = MSG2_SIZE;
+
+  struct msghdr msg;
+  struct cmsghdr cmsgbuf[CMSG_SPACE(sizeof(int))];
+  memset(&msg, 0, sizeof(msg));
+  msg.msg_iov = &iv;
+  msg.msg_iovlen = 1;
+  msg.msg_control = cmsgbuf;
+  msg.msg_controllen = sizeof(cmsgbuf);
+
+  ssize_t res = TEMP_FAILURE_RETRY(recvmsg(mFd, &msg, MSG_NOSIGNAL));
+  if (res <= 0) {
+    return STATUS_FAIL;
+  }
+
+  mLen += res;
+
+  if (msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) {
+    return STATUS_FAIL;
+  }
+
+  struct cmsghdr *cmsgptr = CMSG_FIRSTHDR(&msg);
+
+  // Extract client fd from message header
+  for (; cmsgptr; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
+    if (CMSGHDR_CONTAINS_FD(cmsgptr)) {
+      // if multiple file descriptors have been sent, we close
+      // all but the final one.
+      if (mClientFd != -1) {
+        TEMP_FAILURE_RETRY(close(mClientFd));
+      }
+      // retrieve sent client fd
+      memcpy(&mClientFd, CMSG_DATA(cmsgptr), sizeof(mClientFd));
+    }
+  }
+
+  return STATUS_SUCCESS;
+}
+
+int16_t
+SocketMessageWatcher::ReadInt16(unsigned long aOffset) const
+{
+  /* little-endian buffer */
+  return (static_cast<int16_t>(mBuf[aOffset + 1]) << 8) |
+          static_cast<int16_t>(mBuf[aOffset]);
+}
+
+int32_t
+SocketMessageWatcher::ReadInt32(unsigned long aOffset) const
+{
+  /* little-endian buffer */
+  return (static_cast<int32_t>(mBuf[aOffset + 3]) << 24) |
+         (static_cast<int32_t>(mBuf[aOffset + 2]) << 16) |
+         (static_cast<int32_t>(mBuf[aOffset + 1]) << 8) |
+          static_cast<int32_t>(mBuf[aOffset]);
+}
+
+void
+SocketMessageWatcher::ReadBdAddress(unsigned long aOffset,
+                                    nsAString& aBdAddress) const
+{
+  char str[BLUETOOTH_ADDRESS_LENGTH + 1];
+
+  int res = snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
+                     static_cast<int>(mBuf[aOffset + 0]),
+                     static_cast<int>(mBuf[aOffset + 1]),
+                     static_cast<int>(mBuf[aOffset + 2]),
+                     static_cast<int>(mBuf[aOffset + 3]),
+                     static_cast<int>(mBuf[aOffset + 4]),
+                     static_cast<int>(mBuf[aOffset + 5]));
+  if (res < 0) {
+    aBdAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE);
+  } else if ((size_t)res >= sizeof(str)) { /* string buffer too small */
+    aBdAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE);
+  } else {
+    aBdAddress = NS_ConvertUTF8toUTF16(str);
+  }
+}
+
+//
+// SocketMessageWatcherTask
+//
+
+SocketMessageWatcherTask::SocketMessageWatcherTask(
+  SocketMessageWatcher* aWatcher)
+  : mWatcher(aWatcher)
+{
+  MOZ_ASSERT(mWatcher);
+}
+
+void
+SocketMessageWatcherTask::Run()
+{
+  mWatcher->Watch();
+}
+
+//
+// DeleteSocketMessageWatcherTask
+//
+
+DeleteSocketMessageWatcherTask::DeleteSocketMessageWatcherTask(
+  BluetoothSocketResultHandler* aRes)
+  : mRes(aRes)
+{
+  MOZ_ASSERT(mRes);
+}
+
+void
+DeleteSocketMessageWatcherTask::Run()
+{
+  // look up hash table for the watcher corresponding to |mRes|
+  SocketMessageWatcherWrapper* wrapper = sWatcherHashtable.Get(mRes);
+  if (!wrapper) {
+    return;
+  }
+
+  // stop the watcher if it exists
+  SocketMessageWatcher* watcher = wrapper->GetSocketMessageWatcher();
+  watcher->StopWatching();
+  watcher->Proceed(STATUS_DONE);
+}
+
+END_BLUETOOTH_NAMESPACE
new file mode 100644
--- /dev/null
+++ b/dom/bluetooth/bluedroid/BluetoothSocketMessageWatcher.h
@@ -0,0 +1,109 @@
+/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
+/* vim: set ts=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 "base/message_loop.h"
+#include "BluetoothCommon.h"
+
+BEGIN_BLUETOOTH_NAMESPACE
+
+class BluetoothSocketResultHandler;
+
+/* |SocketMessageWatcher| receives Bluedroid's socket setup
+ * messages on the I/O thread. You need to inherit from this
+ * class to make use of it.
+ *
+ * Bluedroid sends two socket info messages (20 bytes) at
+ * the beginning of a connection to both peers.
+ *
+ *   - 1st message: [channel:4]
+ *   - 2nd message: [size:2][bd address:6][channel:4][connection status:4]
+ *
+ * On the server side, the second message will contain a
+ * socket file descriptor for the connection. The client
+ * uses the original file descriptor.
+ */
+class SocketMessageWatcher : public MessageLoopForIO::Watcher
+{
+public:
+  static const unsigned char MSG1_SIZE = 4;
+  static const unsigned char MSG2_SIZE = 16;
+
+  static const unsigned char OFF_CHANNEL1 = 0;
+  static const unsigned char OFF_SIZE = 4;
+  static const unsigned char OFF_BDADDRESS = 6;
+  static const unsigned char OFF_CHANNEL2 = 12;
+  static const unsigned char OFF_STATUS = 16;
+
+  virtual ~SocketMessageWatcher();
+
+  virtual void Proceed(BluetoothStatus aStatus) = 0;
+
+  void OnFileCanReadWithoutBlocking(int aFd) MOZ_OVERRIDE;
+  void OnFileCanWriteWithoutBlocking(int aFd) MOZ_OVERRIDE;
+
+  void Watch();
+  void StopWatching();
+
+  bool IsComplete() const;
+
+  int      GetFd() const;
+  int32_t  GetChannel1() const;
+  int32_t  GetSize() const;
+  nsString GetBdAddress() const;
+  int32_t  GetChannel2() const;
+  int32_t  GetConnectionStatus() const;
+  int      GetClientFd() const;
+
+  BluetoothSocketResultHandler* GetResultHandler() const;
+
+protected:
+  SocketMessageWatcher(int aFd, BluetoothSocketResultHandler* aRes);
+
+private:
+  BluetoothStatus RecvMsg1();
+  BluetoothStatus RecvMsg2();
+
+  int16_t ReadInt16(unsigned long aOffset) const;
+  int32_t ReadInt32(unsigned long aOffset) const;
+  void    ReadBdAddress(unsigned long aOffset, nsAString& aBdAddress) const;
+
+  MessageLoopForIO::FileDescriptorWatcher mWatcher;
+  int mFd;
+  int mClientFd;
+  unsigned char mLen;
+  uint8_t mBuf[MSG1_SIZE + MSG2_SIZE];
+  nsRefPtr<BluetoothSocketResultHandler> mRes;
+};
+
+/* |SocketMessageWatcherTask| starts a SocketMessageWatcher
+ * on the I/O task
+ */
+class SocketMessageWatcherTask MOZ_FINAL : public Task
+{
+public:
+  SocketMessageWatcherTask(SocketMessageWatcher* aWatcher);
+
+  void Run() MOZ_OVERRIDE;
+
+private:
+  SocketMessageWatcher* mWatcher;
+};
+
+/* |DeleteSocketMessageWatcherTask| deletes a watching SocketMessageWatcher
+ * on the I/O task
+ */
+class DeleteSocketMessageWatcherTask MOZ_FINAL : public Task
+{
+public:
+  DeleteSocketMessageWatcherTask(BluetoothSocketResultHandler* aRes);
+
+  void Run() MOZ_OVERRIDE;
+
+private:
+  BluetoothSocketResultHandler* mRes;
+};
+
+END_BLUETOOTH_NAMESPACE
--- a/dom/bluetooth/moz.build
+++ b/dom/bluetooth/moz.build
@@ -50,16 +50,17 @@ if CONFIG['MOZ_B2G_BT']:
                 'bluedroid/BluetoothAvrcpHALInterface.cpp',
                 'bluedroid/BluetoothHALHelpers.cpp',
                 'bluedroid/BluetoothHALInterface.cpp',
                 'bluedroid/BluetoothHandsfreeHALInterface.cpp',
                 'bluedroid/BluetoothOppManager.cpp',
                 'bluedroid/BluetoothServiceBluedroid.cpp',
                 'bluedroid/BluetoothSocket.cpp',
                 'bluedroid/BluetoothSocketHALInterface.cpp',
+                'bluedroid/BluetoothSocketMessageWatcher.cpp',
                 'bluedroid/BluetoothUtils.cpp',
             ]
             LOCAL_INCLUDES += [
                 'bluedroid',
             ]
 
             if CONFIG['MOZ_B2G_RIL']:
                 SOURCES += [
--- a/dom/bluetooth2/bluedroid/BluetoothSocketHALInterface.cpp
+++ b/dom/bluetooth2/bluedroid/BluetoothSocketHALInterface.cpp
@@ -1,19 +1,17 @@
 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
 /* vim: set ts=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 "BluetoothSocketHALInterface.h"
-#include <errno.h>
-#include <sys/socket.h>
-#include <unistd.h>
 #include "BluetoothHALHelpers.h"
+#include "BluetoothSocketMessageWatcher.h"
 #include "mozilla/FileUtils.h"
 #include "nsClassHashtable.h"
 #include "nsXULAppAPI.h"
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 typedef
   BluetoothHALInterfaceRunnable1<BluetoothSocketResultHandler, void,
@@ -102,304 +100,16 @@ BluetoothSocketHALInterface::Listen(Blue
 
   if (aRes) {
     DispatchBluetoothSocketHALResult(
       aRes, &BluetoothSocketResultHandler::Listen, fd,
       ConvertDefault(status, STATUS_FAIL));
   }
 }
 
-#define CMSGHDR_CONTAINS_FD(_cmsghdr) \
-    ( ((_cmsghdr)->cmsg_level == SOL_SOCKET) && \
-      ((_cmsghdr)->cmsg_type == SCM_RIGHTS) )
-
-class SocketMessageWatcher;
-
-/* |SocketMessageWatcherWrapper| wraps SocketMessageWatcher to keep it from
- * being released by hash table's Remove() method.
- */
-class SocketMessageWatcherWrapper
-{
-public:
-  SocketMessageWatcherWrapper(SocketMessageWatcher* aSocketMessageWatcher)
-  : mSocketMessageWatcher(aSocketMessageWatcher)
-  {
-    MOZ_ASSERT(mSocketMessageWatcher);
-  }
-
-  SocketMessageWatcher* GetSocketMessageWatcher()
-  {
-    return mSocketMessageWatcher;
-  }
-
-private:
-  SocketMessageWatcher* mSocketMessageWatcher;
-};
-
-/* |sWatcherHashTable| maps result handlers to corresponding watchers */
-static nsClassHashtable<nsRefPtrHashKey<BluetoothSocketResultHandler>,
-                        SocketMessageWatcherWrapper>
-  sWatcherHashtable;
-
-/* |SocketMessageWatcher| receives Bluedroid's socket setup
- * messages on the I/O thread. You need to inherit from this
- * class to make use of it.
- *
- * Bluedroid sends two socket info messages (20 bytes) at
- * the beginning of a connection to both peers.
- *
- *   - 1st message: [channel:4]
- *   - 2nd message: [size:2][bd address:6][channel:4][connection status:4]
- *
- * On the server side, the second message will contain a
- * socket file descriptor for the connection. The client
- * uses the original file descriptor.
- */
-class SocketMessageWatcher : public MessageLoopForIO::Watcher
-{
-public:
-  static const unsigned char MSG1_SIZE = 4;
-  static const unsigned char MSG2_SIZE = 16;
-
-  static const unsigned char OFF_CHANNEL1 = 0;
-  static const unsigned char OFF_SIZE = 4;
-  static const unsigned char OFF_BDADDRESS = 6;
-  static const unsigned char OFF_CHANNEL2 = 12;
-  static const unsigned char OFF_STATUS = 16;
-
-  SocketMessageWatcher(int aFd, BluetoothSocketResultHandler* aRes)
-  : mFd(aFd)
-  , mClientFd(-1)
-  , mLen(0)
-  , mRes(aRes)
-  {
-    MOZ_ASSERT(mRes);
-  }
-
-  virtual ~SocketMessageWatcher()
-  { }
-
-  virtual void Proceed(BluetoothStatus aStatus) = 0;
-
-  void OnFileCanReadWithoutBlocking(int aFd) MOZ_OVERRIDE
-  {
-    BluetoothStatus status;
-
-    switch (mLen) {
-      case 0:
-        status = RecvMsg1();
-        break;
-      case MSG1_SIZE:
-        status = RecvMsg2();
-        break;
-      default:
-        /* message-size error */
-        status = STATUS_FAIL;
-        break;
-    }
-
-    if (IsComplete() || status != STATUS_SUCCESS) {
-      StopWatching();
-      Proceed(status);
-    }
-  }
-
-  void OnFileCanWriteWithoutBlocking(int aFd) MOZ_OVERRIDE
-  { }
-
-  void Watch()
-  {
-    // add this watcher and its result handler to hash table
-    sWatcherHashtable.Put(mRes, new SocketMessageWatcherWrapper(this));
-
-    MessageLoopForIO::current()->WatchFileDescriptor(
-      mFd,
-      true,
-      MessageLoopForIO::WATCH_READ,
-      &mWatcher,
-      this);
-  }
-
-  void StopWatching()
-  {
-    mWatcher.StopWatchingFileDescriptor();
-
-    // remove this watcher and its result handler from hash table
-    sWatcherHashtable.Remove(mRes);
-  }
-
-  bool IsComplete() const
-  {
-    return mLen == (MSG1_SIZE + MSG2_SIZE);
-  }
-
-  int GetFd() const
-  {
-    return mFd;
-  }
-
-  int32_t GetChannel1() const
-  {
-    return ReadInt32(OFF_CHANNEL1);
-  }
-
-  int32_t GetSize() const
-  {
-    return ReadInt16(OFF_SIZE);
-  }
-
-  nsString GetBdAddress() const
-  {
-    nsString bdAddress;
-    ReadBdAddress(OFF_BDADDRESS, bdAddress);
-    return bdAddress;
-  }
-
-  int32_t GetChannel2() const
-  {
-    return ReadInt32(OFF_CHANNEL2);
-  }
-
-  int32_t GetConnectionStatus() const
-  {
-    return ReadInt32(OFF_STATUS);
-  }
-
-  int GetClientFd() const
-  {
-    return mClientFd;
-  }
-
-  BluetoothSocketResultHandler* GetResultHandler() const
-  {
-    return mRes;
-  }
-
-private:
-  BluetoothStatus RecvMsg1()
-  {
-    struct iovec iv;
-    memset(&iv, 0, sizeof(iv));
-    iv.iov_base = mBuf;
-    iv.iov_len = MSG1_SIZE;
-
-    struct msghdr msg;
-    memset(&msg, 0, sizeof(msg));
-    msg.msg_iov = &iv;
-    msg.msg_iovlen = 1;
-
-    ssize_t res = TEMP_FAILURE_RETRY(recvmsg(mFd, &msg, MSG_NOSIGNAL));
-    if (res <= 0) {
-      return STATUS_FAIL;
-    }
-
-    mLen += res;
-
-    return STATUS_SUCCESS;
-  }
-
-  BluetoothStatus RecvMsg2()
-  {
-    struct iovec iv;
-    memset(&iv, 0, sizeof(iv));
-    iv.iov_base = mBuf + MSG1_SIZE;
-    iv.iov_len = MSG2_SIZE;
-
-    struct msghdr msg;
-    struct cmsghdr cmsgbuf[2 * sizeof(cmsghdr) + 0x100];
-    memset(&msg, 0, sizeof(msg));
-    msg.msg_iov = &iv;
-    msg.msg_iovlen = 1;
-    msg.msg_control = cmsgbuf;
-    msg.msg_controllen = sizeof(cmsgbuf);
-
-    ssize_t res = TEMP_FAILURE_RETRY(recvmsg(mFd, &msg, MSG_NOSIGNAL));
-    if (res <= 0) {
-      return STATUS_FAIL;
-    }
-
-    mLen += res;
-
-    if (msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) {
-      return STATUS_FAIL;
-    }
-
-    struct cmsghdr *cmsgptr = CMSG_FIRSTHDR(&msg);
-
-    // Extract client fd from message header
-    for (; cmsgptr; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
-      if (CMSGHDR_CONTAINS_FD(cmsgptr)) {
-        // if multiple file descriptors have been sent, we close
-        // all but the final one.
-        if (mClientFd != -1) {
-          TEMP_FAILURE_RETRY(close(mClientFd));
-        }
-        // retrieve sent client fd
-        mClientFd = *(static_cast<int*>(CMSG_DATA(cmsgptr)));
-      }
-    }
-
-    return STATUS_SUCCESS;
-  }
-
-  int16_t ReadInt16(unsigned long aOffset) const
-  {
-    /* little-endian buffer */
-    return (static_cast<int16_t>(mBuf[aOffset + 1]) << 8) |
-            static_cast<int16_t>(mBuf[aOffset]);
-  }
-
-  int32_t ReadInt32(unsigned long aOffset) const
-  {
-    /* little-endian buffer */
-    return (static_cast<int32_t>(mBuf[aOffset + 3]) << 24) |
-           (static_cast<int32_t>(mBuf[aOffset + 2]) << 16) |
-           (static_cast<int32_t>(mBuf[aOffset + 1]) << 8) |
-            static_cast<int32_t>(mBuf[aOffset]);
-  }
-
-  void ReadBdAddress(unsigned long aOffset, nsAString& aBdAddress) const
-  {
-    const bt_bdaddr_t* bdAddress =
-      reinterpret_cast<const bt_bdaddr_t*>(mBuf+aOffset);
-
-    if (NS_FAILED(Convert(*bdAddress, aBdAddress))) {
-      aBdAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE);
-    }
-  }
-
-  MessageLoopForIO::FileDescriptorWatcher mWatcher;
-  int mFd;
-  int mClientFd;
-  unsigned char mLen;
-  uint8_t mBuf[MSG1_SIZE + MSG2_SIZE];
-  nsRefPtr<BluetoothSocketResultHandler> mRes;
-};
-
-/* |SocketMessageWatcherTask| starts a SocketMessageWatcher
- * on the I/O task
- */
-class SocketMessageWatcherTask MOZ_FINAL : public Task
-{
-public:
-  SocketMessageWatcherTask(SocketMessageWatcher* aWatcher)
-  : mWatcher(aWatcher)
-  {
-    MOZ_ASSERT(mWatcher);
-  }
-
-  void Run() MOZ_OVERRIDE
-  {
-    mWatcher->Watch();
-  }
-
-private:
-  SocketMessageWatcher* mWatcher;
-};
-
 /* |DeleteTask| deletes a class instance on the I/O thread
  */
 template <typename T>
 class DeleteTask MOZ_FINAL : public Task
 {
 public:
   DeleteTask(T* aPtr)
   : mPtr(aPtr)
@@ -414,21 +124,22 @@ private:
   nsAutoPtr<T> mPtr;
 };
 
 /* |ConnectWatcher| specializes SocketMessageWatcher for
  * connect operations by reading the socket messages from
  * Bluedroid and forwarding the connected socket to the
  * resource handler.
  */
-class ConnectWatcher MOZ_FINAL : public SocketMessageWatcher
+class BluetoothSocketHALInterface::ConnectWatcher MOZ_FINAL
+  : public SocketMessageWatcher
 {
 public:
   ConnectWatcher(int aFd, BluetoothSocketResultHandler* aRes)
-  : SocketMessageWatcher(aFd, aRes)
+    : SocketMessageWatcher(aFd, aRes)
   { }
 
   void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE
   {
     DispatchBluetoothSocketHALResult(
       GetResultHandler(), &BluetoothSocketResultHandler::Connect,
       GetFd(), GetBdAddress(), GetConnectionStatus(), aStatus);
 
@@ -472,21 +183,22 @@ BluetoothSocketHALInterface::Connect(con
 
 /* |AcceptWatcher| specializes |SocketMessageWatcher| for accept
  * operations by reading the socket messages from Bluedroid and
  * forwarding the received client socket to the resource handler.
  * The first message is received immediately. When there's a new
  * connection, Bluedroid sends the 2nd message with the socket
  * info and socket file descriptor.
  */
-class AcceptWatcher MOZ_FINAL : public SocketMessageWatcher
+class BluetoothSocketHALInterface::AcceptWatcher MOZ_FINAL
+  : public SocketMessageWatcher
 {
 public:
   AcceptWatcher(int aFd, BluetoothSocketResultHandler* aRes)
-  : SocketMessageWatcher(aFd, aRes)
+    : SocketMessageWatcher(aFd, aRes)
   { }
 
   void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE
   {
     if ((aStatus != STATUS_SUCCESS) && (GetClientFd() != -1)) {
       mozilla::ScopedClose(GetClientFd()); // Close received socket fd on error
     }
 
@@ -503,46 +215,16 @@ void
 BluetoothSocketHALInterface::Accept(int aFd,
                                     BluetoothSocketResultHandler* aRes)
 {
   /* receive Bluedroid's socket-setup messages and client fd */
   Task* t = new SocketMessageWatcherTask(new AcceptWatcher(aFd, aRes));
   XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
 }
 
-/* |DeleteSocketMessageWatcherTask| deletes a watching SocketMessageWatcher
- * on the I/O task
- */
-class DeleteSocketMessageWatcherTask MOZ_FINAL : public Task
-{
-public:
-  DeleteSocketMessageWatcherTask(BluetoothSocketResultHandler* aRes)
-  : mRes(aRes)
-  {
-    MOZ_ASSERT(mRes);
-  }
-
-  void Run() MOZ_OVERRIDE
-  {
-    // look up hash table for the watcher corresponding to |mRes|
-    SocketMessageWatcherWrapper* wrapper = sWatcherHashtable.Get(mRes);
-    if (!wrapper) {
-      return;
-    }
-
-    // stop the watcher if it exists
-    SocketMessageWatcher* watcher = wrapper->GetSocketMessageWatcher();
-    watcher->StopWatching();
-    watcher->Proceed(STATUS_DONE);
-  }
-
-private:
-  BluetoothSocketResultHandler* mRes;
-};
-
 void
 BluetoothSocketHALInterface::Close(BluetoothSocketResultHandler* aRes)
 {
   MOZ_ASSERT(aRes);
 
   /* stop the watcher corresponding to |aRes| */
   Task* t = new DeleteSocketMessageWatcherTask(aRes);
   XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
--- a/dom/bluetooth2/bluedroid/BluetoothSocketHALInterface.h
+++ b/dom/bluetooth2/bluedroid/BluetoothSocketHALInterface.h
@@ -15,16 +15,19 @@
 BEGIN_BLUETOOTH_NAMESPACE
 
 class BluetoothHALInterface;
 
 class BluetoothSocketHALInterface MOZ_FINAL
   : public BluetoothSocketInterface
 {
 public:
+  class ConnectWatcher;
+  class AcceptWatcher;
+
   friend class BluetoothHALInterface;
 
   void Listen(BluetoothSocketType aType,
               const nsAString& aServiceName,
               const uint8_t aServiceUuid[16],
               int aChannel, bool aEncrypt, bool aAuth,
               BluetoothSocketResultHandler* aRes);
 
new file mode 100644
--- /dev/null
+++ b/dom/bluetooth2/bluedroid/BluetoothSocketMessageWatcher.cpp
@@ -0,0 +1,325 @@
+/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
+/* vim: set ts=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 "BluetoothSocketMessageWatcher.h"
+#include <errno.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include "BluetoothInterface.h"
+#include "nsClassHashtable.h"
+
+BEGIN_BLUETOOTH_NAMESPACE
+
+//
+// SocketMessageWatcherWrapper
+//
+
+/* |SocketMessageWatcherWrapper| wraps SocketMessageWatcher to keep it from
+ * being released by hash table's Remove() method.
+ */
+class SocketMessageWatcherWrapper
+{
+public:
+  SocketMessageWatcherWrapper(SocketMessageWatcher* aSocketMessageWatcher)
+    : mSocketMessageWatcher(aSocketMessageWatcher)
+  {
+    MOZ_ASSERT(mSocketMessageWatcher);
+  }
+
+  SocketMessageWatcher* GetSocketMessageWatcher()
+  {
+    return mSocketMessageWatcher;
+  }
+
+private:
+  SocketMessageWatcher* mSocketMessageWatcher;
+};
+
+/* |sWatcherHashTable| maps result handlers to corresponding watchers */
+static nsClassHashtable<nsRefPtrHashKey<BluetoothSocketResultHandler>,
+                        SocketMessageWatcherWrapper>
+  sWatcherHashtable;
+
+//
+// SocketMessageWatcher
+//
+
+SocketMessageWatcher::SocketMessageWatcher(
+  int aFd, BluetoothSocketResultHandler* aRes)
+  : mFd(aFd)
+  , mClientFd(-1)
+  , mLen(0)
+  , mRes(aRes)
+{
+  MOZ_ASSERT(mRes);
+}
+
+SocketMessageWatcher::~SocketMessageWatcher()
+{ }
+
+void
+SocketMessageWatcher::OnFileCanReadWithoutBlocking(int aFd)
+{
+  BluetoothStatus status;
+
+  switch (mLen) {
+    case 0:
+      status = RecvMsg1();
+      break;
+    case MSG1_SIZE:
+      status = RecvMsg2();
+      break;
+    default:
+      /* message-size error */
+      status = STATUS_FAIL;
+      break;
+  }
+
+  if (IsComplete() || status != STATUS_SUCCESS) {
+    StopWatching();
+    Proceed(status);
+  }
+}
+
+void
+SocketMessageWatcher::OnFileCanWriteWithoutBlocking(int aFd)
+{ }
+
+void
+SocketMessageWatcher::Watch()
+{
+  // add this watcher and its result handler to hash table
+  sWatcherHashtable.Put(mRes, new SocketMessageWatcherWrapper(this));
+
+  MessageLoopForIO::current()->WatchFileDescriptor(
+    mFd,
+    true,
+    MessageLoopForIO::WATCH_READ,
+    &mWatcher,
+    this);
+}
+
+void
+SocketMessageWatcher::StopWatching()
+{
+  mWatcher.StopWatchingFileDescriptor();
+
+  // remove this watcher and its result handler from hash table
+  sWatcherHashtable.Remove(mRes);
+}
+
+bool
+SocketMessageWatcher::IsComplete() const
+{
+  return mLen == (MSG1_SIZE + MSG2_SIZE);
+}
+
+int
+SocketMessageWatcher::GetFd() const
+{
+  return mFd;
+}
+
+int32_t
+SocketMessageWatcher::GetChannel1() const
+{
+  return ReadInt32(OFF_CHANNEL1);
+}
+
+int32_t
+SocketMessageWatcher::GetSize() const
+{
+  return ReadInt16(OFF_SIZE);
+}
+
+nsString
+SocketMessageWatcher::GetBdAddress() const
+{
+  nsString bdAddress;
+  ReadBdAddress(OFF_BDADDRESS, bdAddress);
+  return bdAddress;
+}
+
+int32_t
+SocketMessageWatcher::GetChannel2() const
+{
+  return ReadInt32(OFF_CHANNEL2);
+}
+
+int32_t
+SocketMessageWatcher::GetConnectionStatus() const
+{
+  return ReadInt32(OFF_STATUS);
+}
+
+int
+SocketMessageWatcher::GetClientFd() const
+{
+  return mClientFd;
+}
+
+BluetoothSocketResultHandler*
+SocketMessageWatcher::GetResultHandler() const
+{
+  return mRes;
+}
+
+BluetoothStatus
+SocketMessageWatcher::RecvMsg1()
+{
+  struct iovec iv;
+  memset(&iv, 0, sizeof(iv));
+  iv.iov_base = mBuf;
+  iv.iov_len = MSG1_SIZE;
+
+  struct msghdr msg;
+  memset(&msg, 0, sizeof(msg));
+  msg.msg_iov = &iv;
+  msg.msg_iovlen = 1;
+
+  ssize_t res = TEMP_FAILURE_RETRY(recvmsg(mFd, &msg, MSG_NOSIGNAL));
+  if (res <= 0) {
+    return STATUS_FAIL;
+  }
+
+  mLen += res;
+
+  return STATUS_SUCCESS;
+}
+
+#define CMSGHDR_CONTAINS_FD(_cmsghdr) \
+    ( ((_cmsghdr)->cmsg_level == SOL_SOCKET) && \
+      ((_cmsghdr)->cmsg_type == SCM_RIGHTS) )
+
+BluetoothStatus
+SocketMessageWatcher::RecvMsg2()
+{
+  struct iovec iv;
+  memset(&iv, 0, sizeof(iv));
+  iv.iov_base = mBuf + MSG1_SIZE;
+  iv.iov_len = MSG2_SIZE;
+
+  struct msghdr msg;
+  struct cmsghdr cmsgbuf[CMSG_SPACE(sizeof(int))];
+  memset(&msg, 0, sizeof(msg));
+  msg.msg_iov = &iv;
+  msg.msg_iovlen = 1;
+  msg.msg_control = cmsgbuf;
+  msg.msg_controllen = sizeof(cmsgbuf);
+
+  ssize_t res = TEMP_FAILURE_RETRY(recvmsg(mFd, &msg, MSG_NOSIGNAL));
+  if (res <= 0) {
+    return STATUS_FAIL;
+  }
+
+  mLen += res;
+
+  if (msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) {
+    return STATUS_FAIL;
+  }
+
+  struct cmsghdr *cmsgptr = CMSG_FIRSTHDR(&msg);
+
+  // Extract client fd from message header
+  for (; cmsgptr; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
+    if (CMSGHDR_CONTAINS_FD(cmsgptr)) {
+      // if multiple file descriptors have been sent, we close
+      // all but the final one.
+      if (mClientFd != -1) {
+        TEMP_FAILURE_RETRY(close(mClientFd));
+      }
+      // retrieve sent client fd
+      memcpy(&mClientFd, CMSG_DATA(cmsgptr), sizeof(mClientFd));
+    }
+  }
+
+  return STATUS_SUCCESS;
+}
+
+int16_t
+SocketMessageWatcher::ReadInt16(unsigned long aOffset) const
+{
+  /* little-endian buffer */
+  return (static_cast<int16_t>(mBuf[aOffset + 1]) << 8) |
+          static_cast<int16_t>(mBuf[aOffset]);
+}
+
+int32_t
+SocketMessageWatcher::ReadInt32(unsigned long aOffset) const
+{
+  /* little-endian buffer */
+  return (static_cast<int32_t>(mBuf[aOffset + 3]) << 24) |
+         (static_cast<int32_t>(mBuf[aOffset + 2]) << 16) |
+         (static_cast<int32_t>(mBuf[aOffset + 1]) << 8) |
+          static_cast<int32_t>(mBuf[aOffset]);
+}
+
+void
+SocketMessageWatcher::ReadBdAddress(unsigned long aOffset,
+                                    nsAString& aBdAddress) const
+{
+  char str[BLUETOOTH_ADDRESS_LENGTH + 1];
+
+  int res = snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
+                     static_cast<int>(mBuf[aOffset + 0]),
+                     static_cast<int>(mBuf[aOffset + 1]),
+                     static_cast<int>(mBuf[aOffset + 2]),
+                     static_cast<int>(mBuf[aOffset + 3]),
+                     static_cast<int>(mBuf[aOffset + 4]),
+                     static_cast<int>(mBuf[aOffset + 5]));
+  if (res < 0) {
+    aBdAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE);
+  } else if ((size_t)res >= sizeof(str)) { /* string buffer too small */
+    aBdAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE);
+  } else {
+    aBdAddress = NS_ConvertUTF8toUTF16(str);
+  }
+}
+
+//
+// SocketMessageWatcherTask
+//
+
+SocketMessageWatcherTask::SocketMessageWatcherTask(
+  SocketMessageWatcher* aWatcher)
+  : mWatcher(aWatcher)
+{
+  MOZ_ASSERT(mWatcher);
+}
+
+void
+SocketMessageWatcherTask::Run()
+{
+  mWatcher->Watch();
+}
+
+//
+// DeleteSocketMessageWatcherTask
+//
+
+DeleteSocketMessageWatcherTask::DeleteSocketMessageWatcherTask(
+  BluetoothSocketResultHandler* aRes)
+  : mRes(aRes)
+{
+  MOZ_ASSERT(mRes);
+}
+
+void
+DeleteSocketMessageWatcherTask::Run()
+{
+  // look up hash table for the watcher corresponding to |mRes|
+  SocketMessageWatcherWrapper* wrapper = sWatcherHashtable.Get(mRes);
+  if (!wrapper) {
+    return;
+  }
+
+  // stop the watcher if it exists
+  SocketMessageWatcher* watcher = wrapper->GetSocketMessageWatcher();
+  watcher->StopWatching();
+  watcher->Proceed(STATUS_DONE);
+}
+
+END_BLUETOOTH_NAMESPACE
new file mode 100644
--- /dev/null
+++ b/dom/bluetooth2/bluedroid/BluetoothSocketMessageWatcher.h
@@ -0,0 +1,109 @@
+/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
+/* vim: set ts=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 "base/message_loop.h"
+#include "BluetoothCommon.h"
+
+BEGIN_BLUETOOTH_NAMESPACE
+
+class BluetoothSocketResultHandler;
+
+/* |SocketMessageWatcher| receives Bluedroid's socket setup
+ * messages on the I/O thread. You need to inherit from this
+ * class to make use of it.
+ *
+ * Bluedroid sends two socket info messages (20 bytes) at
+ * the beginning of a connection to both peers.
+ *
+ *   - 1st message: [channel:4]
+ *   - 2nd message: [size:2][bd address:6][channel:4][connection status:4]
+ *
+ * On the server side, the second message will contain a
+ * socket file descriptor for the connection. The client
+ * uses the original file descriptor.
+ */
+class SocketMessageWatcher : public MessageLoopForIO::Watcher
+{
+public:
+  static const unsigned char MSG1_SIZE = 4;
+  static const unsigned char MSG2_SIZE = 16;
+
+  static const unsigned char OFF_CHANNEL1 = 0;
+  static const unsigned char OFF_SIZE = 4;
+  static const unsigned char OFF_BDADDRESS = 6;
+  static const unsigned char OFF_CHANNEL2 = 12;
+  static const unsigned char OFF_STATUS = 16;
+
+  virtual ~SocketMessageWatcher();
+
+  virtual void Proceed(BluetoothStatus aStatus) = 0;
+
+  void OnFileCanReadWithoutBlocking(int aFd) MOZ_OVERRIDE;
+  void OnFileCanWriteWithoutBlocking(int aFd) MOZ_OVERRIDE;
+
+  void Watch();
+  void StopWatching();
+
+  bool IsComplete() const;
+
+  int      GetFd() const;
+  int32_t  GetChannel1() const;
+  int32_t  GetSize() const;
+  nsString GetBdAddress() const;
+  int32_t  GetChannel2() const;
+  int32_t  GetConnectionStatus() const;
+  int      GetClientFd() const;
+
+  BluetoothSocketResultHandler* GetResultHandler() const;
+
+protected:
+  SocketMessageWatcher(int aFd, BluetoothSocketResultHandler* aRes);
+
+private:
+  BluetoothStatus RecvMsg1();
+  BluetoothStatus RecvMsg2();
+
+  int16_t ReadInt16(unsigned long aOffset) const;
+  int32_t ReadInt32(unsigned long aOffset) const;
+  void    ReadBdAddress(unsigned long aOffset, nsAString& aBdAddress) const;
+
+  MessageLoopForIO::FileDescriptorWatcher mWatcher;
+  int mFd;
+  int mClientFd;
+  unsigned char mLen;
+  uint8_t mBuf[MSG1_SIZE + MSG2_SIZE];
+  nsRefPtr<BluetoothSocketResultHandler> mRes;
+};
+
+/* |SocketMessageWatcherTask| starts a SocketMessageWatcher
+ * on the I/O task
+ */
+class SocketMessageWatcherTask MOZ_FINAL : public Task
+{
+public:
+  SocketMessageWatcherTask(SocketMessageWatcher* aWatcher);
+
+  void Run() MOZ_OVERRIDE;
+
+private:
+  SocketMessageWatcher* mWatcher;
+};
+
+/* |DeleteSocketMessageWatcherTask| deletes a watching SocketMessageWatcher
+ * on the I/O task
+ */
+class DeleteSocketMessageWatcherTask MOZ_FINAL : public Task
+{
+public:
+  DeleteSocketMessageWatcherTask(BluetoothSocketResultHandler* aRes);
+
+  void Run() MOZ_OVERRIDE;
+
+private:
+  BluetoothSocketResultHandler* mRes;
+};
+
+END_BLUETOOTH_NAMESPACE
--- a/dom/bluetooth2/moz.build
+++ b/dom/bluetooth2/moz.build
@@ -55,16 +55,17 @@ if CONFIG['MOZ_B2G_BT']:
                 'bluedroid/BluetoothGattManager.cpp',
                 'bluedroid/BluetoothHALHelpers.cpp',
                 'bluedroid/BluetoothHALInterface.cpp',
                 'bluedroid/BluetoothHandsfreeHALInterface.cpp',
                 'bluedroid/BluetoothOppManager.cpp',
                 'bluedroid/BluetoothServiceBluedroid.cpp',
                 'bluedroid/BluetoothSocket.cpp',
                 'bluedroid/BluetoothSocketHALInterface.cpp',
+                'bluedroid/BluetoothSocketMessageWatcher.cpp',
                 'bluedroid/BluetoothUtils.cpp',
             ]
             LOCAL_INCLUDES += [
                 'bluedroid',
             ]
 
             if CONFIG['MOZ_B2G_RIL']:
                 SOURCES += [
--- a/dom/camera/DOMCameraManager.cpp
+++ b/dom/camera/DOMCameraManager.cpp
@@ -306,16 +306,24 @@ nsDOMCameraManager::GetCamera(const nsAS
 
   nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(mWindow);
   if (!sop) {
     aRv.Throw(NS_ERROR_UNEXPECTED);
     return nullptr;
   }
 
   nsCOMPtr<nsIPrincipal> principal = sop->GetPrincipal();
+  // If we are a CERTIFIED app, we can short-circuit the permission check,
+  // which gets us a performance win.
+  uint16_t status = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
+  principal->GetAppStatus(&status);
+  if (status == nsIPrincipal::APP_STATUS_CERTIFIED && CheckPermission(mWindow)) {
+    PermissionAllowed(cameraId, aInitialConfig, successCallback, errorCallback, promise);
+    return promise.forget();
+  }
 
   nsCOMPtr<nsIRunnable> permissionRequest =
     new CameraPermissionRequest(principal, mWindow, this, cameraId, aInitialConfig,
                                 successCallback, errorCallback, promise);
 
   NS_DispatchToMainThread(permissionRequest);
   return promise.forget();
 }
--- a/dom/icc/Icc.cpp
+++ b/dom/icc/Icc.cpp
@@ -333,74 +333,16 @@ Icc::UpdateContact(const JSContext* aCx,
     aRv.Throw(rv);
     return nullptr;
   }
 
   return request.forget().downcast<DOMRequest>();
 }
 
 already_AddRefed<DOMRequest>
-Icc::IccOpenChannel(const nsAString& aAid, ErrorResult& aRv)
-{
-  if (!mProvider) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  nsRefPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->IccOpenChannel(mClientId, GetOwner(), aAid,
-                                          getter_AddRefs(request));
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-    return nullptr;
-  }
-
-  return request.forget().downcast<DOMRequest>();
-}
-
-already_AddRefed<DOMRequest>
-Icc::IccExchangeAPDU(const JSContext* aCx, int32_t aChannel,
-                     JS::Handle<JS::Value> aApdu, ErrorResult& aRv)
-{
-  if (!mProvider) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  nsRefPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->IccExchangeAPDU(mClientId, GetOwner(), aChannel,
-                                           aApdu, getter_AddRefs(request));
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-    return nullptr;
-  }
-
-  return request.forget().downcast<DOMRequest>();
-}
-
-already_AddRefed<DOMRequest>
-Icc::IccCloseChannel(int32_t aChannel, ErrorResult& aRv)
-{
-  if (!mProvider) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  nsRefPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->IccCloseChannel(mClientId, GetOwner(), aChannel,
-                                           getter_AddRefs(request));
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-    return nullptr;
-  }
-
-  return request.forget().downcast<DOMRequest>();
-}
-
-already_AddRefed<DOMRequest>
 Icc::MatchMvno(const nsAString& aMvnoType,
                const nsAString& aMvnoData,
                ErrorResult& aRv)
 {
   if (!mProvider) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
--- a/dom/icc/Icc.h
+++ b/dom/icc/Icc.h
@@ -95,26 +95,16 @@ public:
   ReadContacts(const nsAString& aContactType, ErrorResult& aRv);
 
   already_AddRefed<DOMRequest>
   UpdateContact(const JSContext* aCx, const nsAString& aContactType,
                 JS::Handle<JS::Value> aContact, const nsAString& aPin2,
                 ErrorResult& aRv);
 
   already_AddRefed<DOMRequest>
-  IccOpenChannel(const nsAString& aAid, ErrorResult& aRv);
-
-  already_AddRefed<DOMRequest>
-  IccExchangeAPDU(const JSContext* aCx, int32_t aChannel,
-                  JS::Handle<JS::Value> aApdu, ErrorResult& aRv);
-
-  already_AddRefed<DOMRequest>
-  IccCloseChannel(int32_t aChannel, ErrorResult& aRv);
-
-  already_AddRefed<DOMRequest>
   MatchMvno(const nsAString& aMvnoType, const nsAString& aMatchData,
             ErrorResult& aRv);
 
   IMPL_EVENT_HANDLER(iccinfochange)
   IMPL_EVENT_HANDLER(cardstatechange)
   IMPL_EVENT_HANDLER(stkcommand)
   IMPL_EVENT_HANDLER(stksessionend)
 
--- a/dom/media/CubebUtils.cpp
+++ b/dom/media/CubebUtils.cpp
@@ -167,17 +167,17 @@ uint32_t PreferredSampleRate()
   return sPreferredSampleRate;
 }
 
 #if defined(__ANDROID__) && defined(MOZ_B2G)
 cubeb_stream_type ConvertChannelToCubebType(dom::AudioChannel aChannel)
 {
   switch(aChannel) {
     case dom::AudioChannel::Normal:
-      return CUBEB_STREAM_TYPE_SYSTEM;
+      /* FALLTHROUGH */
     case dom::AudioChannel::Content:
       return CUBEB_STREAM_TYPE_MUSIC;
     case dom::AudioChannel::Notification:
       return CUBEB_STREAM_TYPE_NOTIFICATION;
     case dom::AudioChannel::Alarm:
       return CUBEB_STREAM_TYPE_ALARM;
     case dom::AudioChannel::Telephony:
       return CUBEB_STREAM_TYPE_VOICE_CALL;
--- a/dom/network/NetUtils.cpp
+++ b/dom/network/NetUtils.cpp
@@ -64,22 +64,24 @@ DEFINE_DLFUNC(dhcp_stop, int32_t, const 
 NetUtils::NetUtils()
   : mIfcMutex("NetUtils::mIfcMutex")
 {
 }
 
 int32_t NetUtils::do_ifc_enable(const char *ifname)
 {
   USE_DLFUNC(ifc_enable)
+  mozilla::MutexAutoLock lock(mIfcMutex);
   return ifc_enable(ifname);
 }
 
 int32_t NetUtils::do_ifc_disable(const char *ifname)
 {
   USE_DLFUNC(ifc_disable)
+  mozilla::MutexAutoLock lock(mIfcMutex);
   return ifc_disable(ifname);
 }
 
 int32_t NetUtils::do_ifc_configure(const char *ifname,
                                        in_addr_t address,
                                        uint32_t prefixLength,
                                        in_addr_t gateway,
                                        in_addr_t dns1,
--- a/dom/webidl/MozIcc.webidl
+++ b/dom/webidl/MozIcc.webidl
@@ -409,68 +409,16 @@ interface MozIcc : EventTarget
    *
    * @return a DOMRequest.
    */
   [Throws]
   DOMRequest updateContact(DOMString contactType,
                            any contact,
                            optional DOMString? pin2 = null);
 
-  // Integrated Circuit Card Secure Element Interfaces.
-
-  /**
-   * A secure element is a smart card chip that can hold
-   * several different applications with the necessary security.
-   * The most known secure element is the Universal Integrated Circuit Card
-   * (UICC).
-   */
-
-  /**
-   * Send request to open a logical channel defined by its
-   * application identifier (AID).
-   *
-   * @param aid
-   *        The application identifier of the applet to be selected on this
-   *        channel.
-   *
-   * @return a DOMRequest.
-   *         The request's result will be an instance of channel (channelID)
-   *         if available or null.
-   */
-  [Throws]
-  DOMRequest iccOpenChannel(DOMString aid);
-
-  /**
-   * Interface, used to communicate with an applet through the
-   * application data protocol units (APDUs) and is
-   * used for all data that is exchanged between the UICC and the terminal (ME).
-   *
-   * @param channel
-   *        The application identifier of the applet to which APDU is directed.
-   * @param apdu
-   *        Application protocol data unit.
-   *
-   * @return a DOMRequest.
-   *         The request's result will be response APDU.
-   */
-  [Throws]
-  DOMRequest iccExchangeAPDU(long channel, any apdu);
-
-  /**
-   * Send request to close the selected logical channel identified by its
-   * application identifier (AID).
-   *
-   * @param aid
-   *        The application identifier of the applet, to be closed.
-   *
-   * @return a DOMRequest.
-   */
-  [Throws]
-  DOMRequest iccCloseChannel(long channel);
-
   // Integrated Circuit Card Helpers.
 
   /**
    * Verify whether the passed data (matchData) matches with some ICC's field
    * according to the mvno type (mvnoType).
    *
    * @param mvnoType
    *        Mvno type to use to compare the match data.
--- a/dom/wifi/WifiP2pManager.jsm
+++ b/dom/wifi/WifiP2pManager.jsm
@@ -1325,26 +1325,35 @@ function P2pStateMachine(aP2pCommand, aN
 
   var stateDisabling = _sm.makeState("DISABLING", {
     enter: function() {
       _sm.pause();
       aNetUtil.stopDhcpServer(function (success) { // Stopping DHCP server is harmless.
         debug('Stop DHCP server result: ' + success);
         aP2pCommand.p2pDisable(function(success) {
           debug('P2P function disabled');
-          aP2pCommand.closeSupplicantConnection(function (status) {
+          closeSupplicantConnectionIfNeeded(function() {
             debug('Supplicant connection closed');
             gNetworkService.disableInterface(P2P_INTERFACE_NAME, function (success){
               debug('Disabled interface: ' + P2P_INTERFACE_NAME);
               _onDisabled(true);
               _sm.gotoState(stateDisabled);
             });
           });
         });
       });
+
+      function closeSupplicantConnectionIfNeeded(callback) {
+        // No need to connect to supplicant on KK. Call back directly.
+        if (aP2pCommand.getSdkVersion() >= 19) {
+          callback();
+          return;
+        }
+        aP2pCommand.closeSupplicantConnection(callback);
+      }
     },
 
     handleEvent: function(aEvent) {
       return false; // We will not receive any event in this state.
     }
   });
 
   //----------------------------------------------------------
--- a/hal/gonk/GonkDiskSpaceWatcher.cpp
+++ b/hal/gonk/GonkDiskSpaceWatcher.cpp
@@ -164,16 +164,19 @@ GonkDiskSpaceWatcher::DoStart()
   NS_ASSERTION(XRE_GetIOMessageLoop() == MessageLoopForIO::current(),
                "Not on the correct message loop");
 
   mFd = fanotify_init(FAN_CLASS_NOTIF, FAN_CLOEXEC);
   if (mFd == -1) {
     NS_WARNING("Error calling inotify_init()");
     if (errno == ENOSYS) {
       NS_WARNING("Warning: No fanotify support in this device's kernel.\n");
+#if ANDROID_VERSION >= 19
+      MOZ_CRASH("Fanotify support must be enabled in the kernel.");
+#endif
     }
     return;
   }
 
   if (fanotify_mark(mFd, FAN_MARK_ADD | FAN_MARK_MOUNT, FAN_CLOSE,
                     0, kWatchedPath) < 0) {
     NS_WARNING("Error calling fanotify_mark");
     close(mFd);