Merge m-c to inbound. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Mon, 03 Aug 2015 15:03:34 -0400
changeset 287635 7b898ef15bf491c18f14d7fe7b07cfa8ddbfb45b
parent 287634 134cb6e4b7ea5bf1b464eb73218ccdb84bd1fc89 (current diff)
parent 287559 abc56d57f6e1aebade48949fb557d26eae555df8 (diff)
child 287636 579d50cc0ca7ff59bb7772c25dcef9ce9fa5e96c
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone42.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to inbound. a=merge
browser/themes/osx/browser.css
dom/bluetooth/bluedroid/BluetoothDaemonConnector.cpp
dom/bluetooth/bluedroid/BluetoothDaemonConnector.h
--- a/b2g/config/aries/sources.xml
+++ b/b2g/config/aries/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="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="8dba2077f5e7137253fbb3faf10cd0b5f7da25c2"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="dbacf8364f4505d021b7d8fb9cabea325004dbcc"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9f45c1988fe72749f0659409e6e3320fabf7b79a"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="5bb657ada461be666c35f419dbe072ed2ce632fc"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ddfd98cdafefaa1b60273d5568b8dbd13730dae"/>
   <!-- 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"/>
--- 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="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="8dba2077f5e7137253fbb3faf10cd0b5f7da25c2"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="dbacf8364f4505d021b7d8fb9cabea325004dbcc"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9f45c1988fe72749f0659409e6e3320fabf7b79a"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="5bb657ada461be666c35f419dbe072ed2ce632fc"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ddfd98cdafefaa1b60273d5568b8dbd13730dae"/>
   <!-- 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"/>
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="1b0db93fb6b870b03467aff50d6419771ba0d88c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="8dba2077f5e7137253fbb3faf10cd0b5f7da25c2"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="dbacf8364f4505d021b7d8fb9cabea325004dbcc"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9f45c1988fe72749f0659409e6e3320fabf7b79a"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="8bc59310552179f9a8bc6cdd0188e2475df52fb7"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="9d0e5057ee5404a31ec1bf76131cb11336a7c3b6"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,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="660169a3d7e034a892359e39135e8c2785a6ad6f">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="8dba2077f5e7137253fbb3faf10cd0b5f7da25c2"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="dbacf8364f4505d021b7d8fb9cabea325004dbcc"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9f45c1988fe72749f0659409e6e3320fabf7b79a"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="5bb657ada461be666c35f419dbe072ed2ce632fc"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ddfd98cdafefaa1b60273d5568b8dbd13730dae"/>
   <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="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="8dba2077f5e7137253fbb3faf10cd0b5f7da25c2"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="dbacf8364f4505d021b7d8fb9cabea325004dbcc"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9f45c1988fe72749f0659409e6e3320fabf7b79a"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="5bb657ada461be666c35f419dbe072ed2ce632fc"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ddfd98cdafefaa1b60273d5568b8dbd13730dae"/>
   <!-- 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"/>
--- a/b2g/config/emulator-l/sources.xml
+++ b/b2g/config/emulator-l/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="07c383a786f188904311a37f6062c2cb84c9b61d">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="8dba2077f5e7137253fbb3faf10cd0b5f7da25c2"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="dbacf8364f4505d021b7d8fb9cabea325004dbcc"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9f45c1988fe72749f0659409e6e3320fabf7b79a"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="5bb657ada461be666c35f419dbe072ed2ce632fc"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ddfd98cdafefaa1b60273d5568b8dbd13730dae"/>
   <!-- Stock Android things -->
   <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" revision="8af5ff6f5dced9eb5a8127459df6c75d24342204"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" revision="30915518fa7ea07166efedc191a4f40aef516fe7"/>
   <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" revision="96eee58e3389fb05a835310d6a06a6ba4486097a"/>
   <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" revision="7c8a46698171aa2e0be09edb43d15a6acf832770"/>
   <project groups="pdk,linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" path="prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" revision="24b2038be8a636fd4a5d21f0abae1e466b07bcf7"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="1b0db93fb6b870b03467aff50d6419771ba0d88c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="8dba2077f5e7137253fbb3faf10cd0b5f7da25c2"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="dbacf8364f4505d021b7d8fb9cabea325004dbcc"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9f45c1988fe72749f0659409e6e3320fabf7b79a"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="8bc59310552179f9a8bc6cdd0188e2475df52fb7"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="9d0e5057ee5404a31ec1bf76131cb11336a7c3b6"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -10,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="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="8dba2077f5e7137253fbb3faf10cd0b5f7da25c2"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="dbacf8364f4505d021b7d8fb9cabea325004dbcc"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9f45c1988fe72749f0659409e6e3320fabf7b79a"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="5bb657ada461be666c35f419dbe072ed2ce632fc"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ddfd98cdafefaa1b60273d5568b8dbd13730dae"/>
   <!-- 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"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
-        "git_revision": "8dba2077f5e7137253fbb3faf10cd0b5f7da25c2", 
+        "git_revision": "dbacf8364f4505d021b7d8fb9cabea325004dbcc", 
         "remote": "https://git.mozilla.org/releases/gaia.git", 
         "branch": ""
     }, 
-    "revision": "4a0216037684d9f9299e8ca7470ca05c2ead4ab5", 
+    "revision": "5612f302a6b5bb48cd518d114c38597df570b66c", 
     "repo_path": "integration/gaia-central"
 }
--- 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="660169a3d7e034a892359e39135e8c2785a6ad6f">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="8dba2077f5e7137253fbb3faf10cd0b5f7da25c2"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="dbacf8364f4505d021b7d8fb9cabea325004dbcc"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9f45c1988fe72749f0659409e6e3320fabf7b79a"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="5bb657ada461be666c35f419dbe072ed2ce632fc"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ddfd98cdafefaa1b60273d5568b8dbd13730dae"/>
   <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/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/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="07c383a786f188904311a37f6062c2cb84c9b61d">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="8dba2077f5e7137253fbb3faf10cd0b5f7da25c2"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="dbacf8364f4505d021b7d8fb9cabea325004dbcc"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9f45c1988fe72749f0659409e6e3320fabf7b79a"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="5bb657ada461be666c35f419dbe072ed2ce632fc"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ddfd98cdafefaa1b60273d5568b8dbd13730dae"/>
   <!-- Stock Android things -->
   <project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.8" revision="8af5ff6f5dced9eb5a8127459df6c75d24342204"/>
   <project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8" revision="30915518fa7ea07166efedc191a4f40aef516fe7"/>
   <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6" revision="96eee58e3389fb05a835310d6a06a6ba4486097a"/>
   <project groups="pdk,linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" revision="7c8a46698171aa2e0be09edb43d15a6acf832770"/>
   <project groups="pdk,linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" path="prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.8" revision="24b2038be8a636fd4a5d21f0abae1e466b07bcf7"/>
--- a/browser/devtools/commandline/test/browser_cmd_highlight_02.js
+++ b/browser/devtools/commandline/test/browser_cmd_highlight_02.js
@@ -31,14 +31,14 @@ function test() {
     yield helpers.closeToolbar(options);
     yield helpers.closeTab(options);
   }).then(finish, helpers.handleError);
 }
 
 function getHighlighterNumber() {
   // Note that this only works as long as gcli tests aren't run with e10s on.
   // To make this e10s ready, execute this in a content frame script instead.
-  return require("gcli/commands/highlight").highlighters.length;
+  return require("devtools/toolkit/gcli/commands/highlight").highlighters.length;
 }
 
 function* runCommand(cmd, options) {
   yield helpers.audit(options, [{ setup: cmd, exec: {} }]);
 }
--- a/browser/devtools/commandline/test/browser_cmd_settings.js
+++ b/browser/devtools/commandline/test/browser_cmd_settings.js
@@ -18,17 +18,17 @@ function test() {
 
 function* spawnTest() {
   // Setup
   let options = yield helpers.openTab(TEST_URI);
 
   const { createSystem } = require("gcli/system");
   const system = createSystem({ location: "server" });
 
-  const gcliInit = require("gcli/commands/index");
+  const gcliInit = require("devtools/toolkit/gcli/commands/index");
   gcliInit.addAllItemsByModule(system);
   yield system.load();
 
   let settings = system.settings;
 
   let hideIntroEnabled = settings.get("devtools.gcli.hideIntro");
   let tabSize = settings.get("devtools.editor.tabsize");
   let remoteHost = settings.get("devtools.debugger.remote-host");
--- a/browser/devtools/shared/DeveloperToolbar.jsm
+++ b/browser/devtools/shared/DeveloperToolbar.jsm
@@ -36,17 +36,17 @@ XPCOMUtils.defineLazyGetter(this, "prefB
 XPCOMUtils.defineLazyGetter(this, "toolboxStrings", function () {
   return Services.strings.createBundle("chrome://browser/locale/devtools/toolbox.properties");
 });
 
 const Telemetry = require("devtools/shared/telemetry");
 
 XPCOMUtils.defineLazyGetter(this, "gcliInit", function() {
   try {
-    return require("gcli/commands/index");
+    return require("devtools/toolkit/gcli/commands/index");
   }
   catch (ex) {
     console.log(ex);
   }
 });
 
 XPCOMUtils.defineLazyGetter(this, "util", () => {
   return require("gcli/util/util");
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -1588,17 +1588,17 @@ toolbarbutton[constrain-size="true"][cui
   }
 }
 
 @media (-moz-mac-yosemite-theme) {
   .searchbar-textbox,
   #urlbar {
     border-color: #fff;
     border-radius: 3px;
-    box-shadow: 0 1px 0 0 rgba(0,0,0,0.2);
+    box-shadow: 0 .5px 0 0 rgba(0,0,0,0.2);
     background-image: none;
   }
   .searchbar-textbox:-moz-window-inactive,
   #urlbar:-moz-window-inactive {
     box-shadow: none;
     border-color: rgba(0,0,0,0.1);
   }
 }
--- a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
@@ -5,27 +5,26 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "BluetoothDaemonInterface.h"
 #include <cutils/properties.h>
 #include <fcntl.h>
 #include <stdlib.h>
 #include "BluetoothDaemonA2dpInterface.h"
 #include "BluetoothDaemonAvrcpInterface.h"
-#include "BluetoothDaemonConnector.h"
 #include "BluetoothDaemonGattInterface.h"
 #include "BluetoothDaemonHandsfreeInterface.h"
 #include "BluetoothDaemonHelpers.h"
 #include "BluetoothDaemonSetupInterface.h"
 #include "BluetoothDaemonSocketInterface.h"
 #include "mozilla/ipc/DaemonRunnables.h"
 #include "mozilla/ipc/DaemonSocket.h"
+#include "mozilla/ipc/DaemonSocketConnector.h"
 #include "mozilla/ipc/ListenSocket.h"
 #include "mozilla/unused.h"
-#include "prrng.h"
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 using namespace mozilla::ipc;
 
 static const int sRetryInterval = 100; // ms
 
 //
@@ -1758,56 +1757,16 @@ public:
   }
 
 private:
   BluetoothDaemonInterface* mInterface;
   nsRefPtr<BluetoothResultHandler> mRes;
   bool mRegisteredSocketModule;
 };
 
-nsresult
-BluetoothDaemonInterface::CreateRandomAddressString(
-  const nsACString& aPrefix, unsigned long aPostfixLength,
-  nsACString& aAddress)
-{
-  static const char sHexChar[16] = {
-    [0x0] = '0', [0x1] = '1', [0x2] = '2', [0x3] = '3',
-    [0x4] = '4', [0x5] = '5', [0x6] = '6', [0x7] = '7',
-    [0x8] = '8', [0x9] = '9', [0xa] = 'a', [0xb] = 'b',
-    [0xc] = 'c', [0xd] = 'd', [0xe] = 'e', [0xf] = 'f'
-  };
-
-  unsigned short seed[3];
-
-  if (NS_WARN_IF(!PR_GetRandomNoise(seed, sizeof(seed)))) {
-    return NS_ERROR_NOT_IMPLEMENTED;
-  }
-
-  aAddress = aPrefix;
-  aAddress.Append('-');
-
-  while (aPostfixLength) {
-
-    // Android doesn't provide rand_r, so we use nrand48 here,
-    // even though it's deprecated.
-    long value = nrand48(seed);
-
-    size_t bits = sizeof(value) * CHAR_BIT;
-
-    while ((bits > 4) && aPostfixLength) {
-      aAddress.Append(sHexChar[value&0xf]);
-      bits -= 4;
-      value >>= 4;
-      --aPostfixLength;
-    }
-  }
-
-  return NS_OK;
-}
-
 /*
  * The init procedure consists of several steps.
  *
  *  (1) Start listening for the command channel's socket connection: We
  *      do this before anything else, so that we don't miss connection
  *      requests from the Bluetooth daemon. This step will create a
  *      listen socket.
  *
@@ -1869,24 +1828,23 @@ BluetoothDaemonInterface::Init(
   }
 
   // The listen socket's name is generated with a random postfix. This
   // avoids naming collisions if we still have a listen socket from a
   // previously failed cleanup. It also makes it hard for malicious
   // external programs to capture the socket name or connect before
   // the daemon can do so. If no random postfix can be generated, we
   // simply use the base name as-is.
-  nsresult rv = CreateRandomAddressString(NS_LITERAL_CSTRING(BASE_SOCKET_NAME),
-                                          POSTFIX_LENGTH,
-                                          mListenSocketName);
+  nsresult rv = DaemonSocketConnector::CreateRandomAddressString(
+    NS_LITERAL_CSTRING(BASE_SOCKET_NAME), POSTFIX_LENGTH, mListenSocketName);
   if (NS_FAILED(rv)) {
     mListenSocketName.AssignLiteral(BASE_SOCKET_NAME);
   }
 
-  rv = mListenSocket->Listen(new BluetoothDaemonConnector(mListenSocketName),
+  rv = mListenSocket->Listen(new DaemonSocketConnector(mListenSocketName),
                              mCmdChannel);
   if (NS_FAILED(rv)) {
     OnConnectError(CMD_CHANNEL);
     return;
   }
 
   // The protocol implementation needs a command channel for
   // sending commands to the daemon. We set it here, because
--- a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.h
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.h
@@ -134,20 +134,16 @@ protected:
     LISTEN_SOCKET,
     CMD_CHANNEL,
     NTF_CHANNEL
   };
 
   BluetoothDaemonInterface();
   ~BluetoothDaemonInterface();
 
-  nsresult CreateRandomAddressString(const nsACString& aPrefix,
-                                     unsigned long aPostfixLength,
-                                     nsACString& aAddress);
-
   // Methods for |DaemonSocketConsumer| and |ListenSocketConsumer|
   //
 
   void OnConnectSuccess(int aIndex) override;
   void OnConnectError(int aIndex) override;
   void OnDisconnect(int aIndex) override;
 
 private:
--- a/dom/bluetooth/moz.build
+++ b/dom/bluetooth/moz.build
@@ -87,17 +87,16 @@ if CONFIG['MOZ_B2G_BT']:
                 'bluez',
             ]
             DEFINES['MOZ_B2G_BT_BLUEZ'] = True
         elif CONFIG['MOZ_B2G_BT_DAEMON']:
             SOURCES += [
                 'bluedroid/BluetoothA2dpManager.cpp',
                 'bluedroid/BluetoothDaemonA2dpInterface.cpp',
                 'bluedroid/BluetoothDaemonAvrcpInterface.cpp',
-                'bluedroid/BluetoothDaemonConnector.cpp',
                 'bluedroid/BluetoothDaemonGattInterface.cpp',
                 'bluedroid/BluetoothDaemonHandsfreeInterface.cpp',
                 'bluedroid/BluetoothDaemonHelpers.cpp',
                 'bluedroid/BluetoothDaemonInterface.cpp',
                 'bluedroid/BluetoothDaemonSetupInterface.cpp',
                 'bluedroid/BluetoothDaemonSocketInterface.cpp',
                 'bluedroid/BluetoothOppManager.cpp',
                 'bluedroid/BluetoothPbapManager.cpp',
new file mode 100644
--- /dev/null
+++ b/dom/browser-element/mochitest/browserElement_SetNFCFocus.js
@@ -0,0 +1,30 @@
+/* Any copyright is dedicated to the public domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Bug 1188639 - Check permission to use setNFCFocus
+"use strict";
+
+SimpleTest.waitForExplicitFinish();
+browserElementTestHelpers.setEnabledPref(true);
+browserElementTestHelpers.addPermission();
+
+function hasSetNFCFocus() {
+  return new Promise((resolve, reject) => {
+    var iframe = document.createElement('iframe');
+    iframe.setAttribute('mozbrowser', 'true');
+    iframe.addEventListener('mozbrowserloadend', e => {
+      is(iframe.setNFCFocus !== undefined, true,
+         "has permission to use setNFCFocus");
+      resolve();
+    });
+    document.body.appendChild(iframe);
+  });
+}
+
+function runTest() {
+  SpecialPowers.pushPermissions(
+    [{ 'type': 'nfc-manager', 'allow': 1, 'context': document }],
+    () => hasSetNFCFocus().then(SimpleTest.finish));
+}
+
+addEventListener('testready', runTest);
--- a/dom/browser-element/mochitest/mochitest-oop.ini
+++ b/dom/browser-element/mochitest/mochitest-oop.ini
@@ -108,8 +108,9 @@ disabled = bug 930449
 [test_browserElement_oop_CloseFromOpener.html]
 disabled = bug 924771
 [test_browserElement_oop_CloseApp.html]
 disabled = bug 924771
 [test_browserElement_oop_ExposableURI.html]
 disabled = bug 924771
 [test_browserElement_oop_GetContentDimensions.html]
 [test_browserElement_oop_AudioChannel.html]
+[test_browserElement_oop_SetNFCFocus.html]
--- a/dom/browser-element/mochitest/mochitest.ini
+++ b/dom/browser-element/mochitest/mochitest.ini
@@ -56,16 +56,17 @@ support-files =
   browserElement_Reload.js
   browserElement_ReloadPostRequest.js
   browserElement_RemoveBrowserElement.js
   browserElement_ScrollEvent.js
   browserElement_SecurityChange.js
   browserElement_SendEvent.js
   browserElement_SelectionStateBlur.js
   browserElement_SetInputMethodActive.js
+  browserElement_SetNFCFocus.js
   browserElement_SetVisible.js
   browserElement_SetVisibleFrames.js
   browserElement_SetVisibleFrames2.js
   browserElement_Stop.js
   browserElement_TargetBlank.js
   browserElement_TargetTop.js
   browserElement_Titlechange.js
   browserElement_TopBarrier.js
@@ -225,8 +226,9 @@ skip-if = (toolkit == 'gonk' && !debug)
 [test_browserElement_inproc_XFrameOptionsSameOrigin.html]
 [test_browserElement_oop_NextPaint.html]
 skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 936226
 # Disabled due to https://bugzilla.mozilla.org/show_bug.cgi?id=774100
 [test_browserElement_inproc_Reload.html]
 disabled = bug 774100
 [test_browserElement_inproc_GetContentDimensions.html]
 [test_browserElement_inproc_AudioChannel.html]
+[test_browserElement_inproc_SetNFCFocus.html]
new file mode 100644
--- /dev/null
+++ b/dom/browser-element/mochitest/test_browserElement_inproc_SetNFCFocus.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for Bug 1188639</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="browserElementTestHelpers.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<script type="application/javascript;version=1.7" src="browserElement_SetNFCFocus.js">
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/browser-element/mochitest/test_browserElement_oop_SetNFCFocus.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for Bug 1188639</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="browserElementTestHelpers.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<script type="application/javascript;version=1.7" src="browserElement_SetNFCFocus.js">
+</script>
+</body>
+</html>
--- a/dom/nfc/gonk/NfcService.cpp
+++ b/dom/nfc/gonk/NfcService.cpp
@@ -2,121 +2,186 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "NfcService.h"
 #include <binder/Parcel.h>
 #include <cutils/properties.h>
-#include "mozilla/ModuleUtils.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/dom/NfcOptionsBinding.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "mozilla/dom/RootedDictionary.h"
+#include "mozilla/ipc/ListenSocket.h"
+#include "mozilla/ipc/ListenSocketConsumer.h"
 #include "mozilla/ipc/NfcConnector.h"
+#include "mozilla/ipc/StreamSocket.h"
+#include "mozilla/ipc/StreamSocketConsumer.h"
+#include "mozilla/ModuleUtils.h"
 #include "mozilla/unused.h"
+#include "NfcMessageHandler.h"
+#include "NfcOptions.h"
 #include "nsAutoPtr.h"
 #include "nsString.h"
 #include "nsXULAppAPI.h"
-#include "NfcOptions.h"
 
 #define NS_NFCSERVICE_CID \
   { 0x584c9a21, 0x4e17, 0x43b7, {0xb1, 0x6a, 0x87, 0xa0, 0x42, 0xef, 0xd4, 0x64} }
 #define NS_NFCSERVICE_CONTRACTID "@mozilla.org/nfc/service;1"
 
 using namespace android;
 using namespace mozilla::dom;
 using namespace mozilla::ipc;
 
-namespace {
-
-class SendNfcSocketDataTask final : public nsRunnable
-{
-public:
-  SendNfcSocketDataTask(StreamSocket* aSocket, UnixSocketRawData* aRawData)
-    : mSocket(aSocket)
-    , mRawData(aRawData)
-  { }
-
-  NS_IMETHOD Run()
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    if (!mSocket || mSocket->GetConnectionStatus() != SOCKET_CONNECTED) {
-      // Probably shutting down.
-      return NS_OK;
-    }
-
-    mSocket->SendSocketData(mRawData.forget());
-    return NS_OK;
-  }
-
-private:
-  nsRefPtr<StreamSocket> mSocket;
-  nsAutoPtr<UnixSocketRawData> mRawData;
-};
-
-} // namespace
-
 namespace mozilla {
 
-static NfcService* gNfcService;
+static StaticRefPtr<NfcService> gNfcService;
 
 NS_IMPL_ISUPPORTS(NfcService, nsINfcService)
 
-void
-assertIsNfcServiceThread()
+//
+// NfcConsumer
+//
+
+/**
+ * |NfcConsumer| implements the details of the connection to an NFC daemon
+ * as well as the message passing.
+ */
+class NfcConsumer
+  : public ListenSocketConsumer
+  , public StreamSocketConsumer
 {
-  nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
-  MOZ_ASSERT(thread == gNfcService->GetThread());
+public:
+  NfcConsumer(NfcService* aNfcService);
+
+  nsresult Start();
+  void Shutdown();
+
+  nsresult Send(const CommandOptions& aCommandOptions);
+  nsresult Receive(UnixSocketBuffer* aBuffer);
+
+  // Methods for |StreamSocketConsumer| and |ListenSocketConsumer|
+  //
+
+  void ReceiveSocketData(
+    int aIndex, nsAutoPtr<mozilla::ipc::UnixSocketBuffer>& aBuffer) override;
+
+  void OnConnectSuccess(int aIndex) override;
+  void OnConnectError(int aIndex) override;
+  void OnDisconnect(int aIndex) override;
+
+private:
+  class DispatchNfcEventRunnable;
+  class ShutdownServiceRunnable;
+
+  enum SocketType {
+    LISTEN_SOCKET,
+    STREAM_SOCKET
+  };
+
+  bool IsNfcServiceThread() const;
+
+  nsRefPtr<NfcService> mNfcService;
+  nsCOMPtr<nsIThread> mThread;
+  nsRefPtr<mozilla::ipc::ListenSocket> mListenSocket;
+  nsRefPtr<mozilla::ipc::StreamSocket> mStreamSocket;
+  nsAutoPtr<NfcMessageHandler> mHandler;
+  nsCString mListenSocketName;
+};
+
+NfcConsumer::NfcConsumer(NfcService* aNfcService)
+  : mNfcService(aNfcService)
+{
+  MOZ_ASSERT(mNfcService);
 }
 
-// Runnable used to call Marshall on the NFC thread.
-class NfcCommandRunnable final : public nsRunnable
+nsresult
+NfcConsumer::Start()
 {
-public:
-  NfcCommandRunnable(NfcMessageHandler* aHandler,
-                     NfcService* aService,
-                     CommandOptions aOptions)
-    : mHandler(aHandler)
-    , mService(aService)
-    , mOptions(aOptions)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
+  static const char BASE_SOCKET_NAME[] = "nfcd";
+
+  MOZ_ASSERT(!mThread); // already started
+
+  // Store a pointer of the consumer's NFC thread for
+  // use with |IsNfcServiceThread|.
+  mThread = do_GetCurrentThread();
+
+  // If we could not cleanup properly before and an old
+  // instance of the daemon is still running, we kill it
+  // here.
+  unused << NS_WARN_IF(property_set("ctl.stop", "nfcd") < 0);
+
+  mHandler = new NfcMessageHandler();
+
+  mStreamSocket = new StreamSocket(this, STREAM_SOCKET);
+
+  mListenSocketName = BASE_SOCKET_NAME;
+
+  mListenSocket = new ListenSocket(this, LISTEN_SOCKET);
+  nsresult rv = mListenSocket->Listen(new NfcConnector(mListenSocketName),
+                                      mStreamSocket);
+  if (NS_FAILED(rv)) {
+    mStreamSocket = nullptr;
+    mHandler = nullptr;
+    mThread = nullptr;
+    return rv;
   }
 
-  NS_IMETHOD Run()
-  {
-    assertIsNfcServiceThread();
+  return NS_OK;
+}
+
+void
+NfcConsumer::Shutdown()
+{
+  MOZ_ASSERT(IsNfcServiceThread());
+
+  mListenSocket->Close();
+  mListenSocket = nullptr;
+  mStreamSocket->Close();
+  mStreamSocket = nullptr;
 
-    Parcel parcel;
-    parcel.writeInt32(0); // Parcel Size.
-    mHandler->Marshall(parcel, mOptions);
-    parcel.setDataPosition(0);
-    uint32_t sizeBE = htonl(parcel.dataSize() - sizeof(int));
-    parcel.writeInt32(sizeBE);
-    mService->PostToNfcDaemon(parcel.data(), parcel.dataSize());
-    return NS_OK;
+  mHandler = nullptr;
+
+  mThread = nullptr;
+}
+
+nsresult
+NfcConsumer::Send(const CommandOptions& aOptions)
+{
+  MOZ_ASSERT(IsNfcServiceThread());
+
+  if (NS_WARN_IF(!mStreamSocket) ||
+      NS_WARN_IF(mStreamSocket->GetConnectionStatus() != SOCKET_CONNECTED)) {
+    return NS_OK; // Probably shutting down.
   }
 
-private:
-   NfcMessageHandler* mHandler;
-   NfcService* mService;
-   CommandOptions mOptions;
-};
+  Parcel parcel;
+  parcel.writeInt32(0); // Parcel Size.
+  mHandler->Marshall(parcel, aOptions);
+  parcel.setDataPosition(0);
+  uint32_t sizeBE = htonl(parcel.dataSize() - sizeof(int));
+  parcel.writeInt32(sizeBE);
+
+  // TODO: Zero-copy buffer transfers
+  mStreamSocket->SendSocketData(
+    new UnixSocketRawData(parcel.data(), parcel.dataSize()));
+
+  return NS_OK;
+}
 
 // Runnable used dispatch the NfcEventOptions on the main thread.
-class NfcEventDispatcher : public nsRunnable
+class NfcConsumer::DispatchNfcEventRunnable final : public nsRunnable
 {
 public:
-  NfcEventDispatcher(EventOptions& aEvent)
-    : mEvent(aEvent)
+  DispatchNfcEventRunnable(NfcService* aNfcService, const EventOptions& aEvent)
+    : mNfcService(aNfcService)
+    , mEvent(aEvent)
   {
-    assertIsNfcServiceThread();
+    MOZ_ASSERT(mNfcService);
   }
 
   NS_IMETHOD Run()
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     mozilla::AutoSafeJSContext cx;
     RootedDictionary<NfcEventOptions> event(cx);
@@ -245,64 +310,132 @@ public:
       event.mResponse.Construct();
       event.mResponse.Value().Init(
         Uint8Array::Create(cx, mEvent.mResponse.Length(), mEvent.mResponse.Elements()));
     }
 
 #undef COPY_FIELD
 #undef COPY_OPT_FIELD
 
-    gNfcService->DispatchNfcEvent(event);
+    mNfcService->DispatchNfcEvent(event);
     return NS_OK;
   }
 
 private:
+  nsRefPtr<NfcService> mNfcService;
   EventOptions mEvent;
 };
 
-// Runnable used to call Unmarshall on the NFC thread.
-class NfcEventRunnable : public nsRunnable
+nsresult
+NfcConsumer::Receive(UnixSocketBuffer* aBuffer)
 {
-public:
-  NfcEventRunnable(NfcMessageHandler* aHandler, UnixSocketBuffer* aData)
-    : mHandler(aHandler), mData(aData)
-  {
-    MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(IsNfcServiceThread());
+  MOZ_ASSERT(mHandler);
+  MOZ_ASSERT(aBuffer);
+
+  while (aBuffer->GetSize()) {
+    const uint8_t* data = aBuffer->GetData();
+    uint32_t parcelSize = ((data[0] & 0xff) << 24) |
+                          ((data[1] & 0xff) << 16) |
+                          ((data[2] & 0xff) <<  8) |
+                           (data[3] & 0xff);
+    MOZ_ASSERT(parcelSize <= aBuffer->GetSize());
+
+    // TODO: Zero-copy buffer transfers
+    Parcel parcel;
+    parcel.setData(aBuffer->GetData(), parcelSize + sizeof(parcelSize));
+    aBuffer->Consume(parcelSize + sizeof(parcelSize));
+
+    EventOptions event;
+    mHandler->Unmarshall(parcel, event);
+
+    NS_DispatchToMainThread(new DispatchNfcEventRunnable(mNfcService, event));
   }
 
-  NS_IMETHOD Run()
-  {
-    assertIsNfcServiceThread();
+  return NS_OK;
+}
+
+bool
+NfcConsumer::IsNfcServiceThread() const
+{
+  return nsCOMPtr<nsIThread>(do_GetCurrentThread()) == mThread;
+}
+
+// |StreamSocketConsumer|, |ListenSocketConsumer|
+
+void
+NfcConsumer::ReceiveSocketData(
+  int aIndex, nsAutoPtr<mozilla::ipc::UnixSocketBuffer>& aBuffer)
+{
+  MOZ_ASSERT(IsNfcServiceThread());
+  MOZ_ASSERT(aIndex == STREAM_SOCKET);
+
+  Receive(aBuffer);
+}
+
+void
+NfcConsumer::OnConnectSuccess(int aIndex)
+{
+  MOZ_ASSERT(IsNfcServiceThread());
 
-    while (mData->GetSize()) {
-      EventOptions event;
-      const uint8_t* data = mData->GetData();
-      uint32_t parcelSize = ((data[0] & 0xff) << 24) |
-                            ((data[1] & 0xff) << 16) |
-                            ((data[2] & 0xff) <<  8) |
-                             (data[3] & 0xff);
-      MOZ_ASSERT(parcelSize <= mData->GetSize());
+  switch (aIndex) {
+    case LISTEN_SOCKET: {
+      nsCString value("nfcd:-S -a ");
+      value.Append(mListenSocketName);
+      if (NS_WARN_IF(property_set("ctl.start", value.get()) < 0)) {
+        OnConnectError(STREAM_SOCKET);
+      }
+      break;
+    }
+    case STREAM_SOCKET:
+      /* nothing to do */
+      break;
+  }
+}
 
-      Parcel parcel;
-      parcel.setData(mData->GetData(), parcelSize + sizeof(parcelSize));
-      mHandler->Unmarshall(parcel, event);
-      nsCOMPtr<nsIRunnable> runnable = new NfcEventDispatcher(event);
-      NS_DispatchToMainThread(runnable);
+class NfcConsumer::ShutdownServiceRunnable final : public nsRunnable
+{
+public:
+  ShutdownServiceRunnable(NfcService* aNfcService)
+    : mNfcService(aNfcService)
+  {
+    MOZ_ASSERT(mNfcService);
+  }
 
-      mData->Consume(parcelSize + sizeof(parcelSize));
-    }
+  NS_IMETHOD Run() override
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+
+    mNfcService->Shutdown();
 
     return NS_OK;
   }
 
 private:
-  NfcMessageHandler* mHandler;
-  nsAutoPtr<UnixSocketBuffer> mData;
+  nsRefPtr<NfcService> mNfcService;
 };
 
+void
+NfcConsumer::OnConnectError(int aIndex)
+{
+  MOZ_ASSERT(IsNfcServiceThread());
+
+  NS_DispatchToMainThread(new ShutdownServiceRunnable(mNfcService));
+}
+
+void
+NfcConsumer::OnDisconnect(int aIndex)
+{
+  MOZ_ASSERT(IsNfcServiceThread());
+}
+
+//
+// NfcService
+//
+
 NfcService::NfcService()
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!gNfcService);
 }
 
 NfcService::~NfcService()
 {
@@ -318,173 +451,226 @@ NfcService::FactoryCreate()
 
   MOZ_ASSERT(NS_IsMainThread());
 
   if (!gNfcService) {
     gNfcService = new NfcService();
     ClearOnShutdown(&gNfcService);
   }
 
-  nsRefPtr<NfcService> service = gNfcService;
+  nsRefPtr<NfcService> service(gNfcService);
   return service.forget();
 }
 
+/**
+ * |StartConsumerRunnable| calls |NfcConsumer::Start| on the NFC thread.
+ */
+class NfcService::StartConsumerRunnable final : public nsRunnable
+{
+public:
+  StartConsumerRunnable(NfcConsumer* aNfcConsumer)
+    : mNfcConsumer(aNfcConsumer)
+  {
+    MOZ_ASSERT(mNfcConsumer);
+  }
+
+  NS_IMETHOD Run() override
+  {
+    mNfcConsumer->Start();
+
+    return NS_OK;
+  }
+
+private:
+  NfcConsumer* mNfcConsumer;
+};
+
 NS_IMETHODIMP
 NfcService::Start(nsINfcGonkEventListener* aListener)
 {
-  static const char BASE_SOCKET_NAME[] = "nfcd";
-
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aListener);
   MOZ_ASSERT(!mThread);
-  MOZ_ASSERT(!mListenSocket);
+  MOZ_ASSERT(!mNfcConsumer);
 
-  // If we could not cleanup properly before and an old
-  // instance of the daemon is still running, we kill it
-  // here.
-  unused << NS_WARN_IF(property_set("ctl.stop", "nfcd") < 0);
+  nsAutoPtr<NfcConsumer> nfcConsumer(new NfcConsumer(this));
 
-  mListener = aListener;
-  mHandler = new NfcMessageHandler();
-  mStreamSocket = new StreamSocket(this, STREAM_SOCKET);
-
-  mListenSocketName = BASE_SOCKET_NAME;
-
-  mListenSocket = new ListenSocket(this, LISTEN_SOCKET);
-  nsresult rv = mListenSocket->Listen(new NfcConnector(mListenSocketName),
-                                      mStreamSocket);
+  nsresult rv = NS_NewNamedThread("NfcThread", getter_AddRefs(mThread));
   if (NS_FAILED(rv)) {
-    mStreamSocket = nullptr;
+    NS_WARNING("Can't create Nfc worker thread.");
     return rv;
   }
 
-  rv = NS_NewNamedThread("NfcThread", getter_AddRefs(mThread));
+  rv = mThread->Dispatch(new StartConsumerRunnable(nfcConsumer),
+                         nsIEventTarget::DISPATCH_NORMAL);
   if (NS_FAILED(rv)) {
-    NS_WARNING("Can't create Nfc worker thread.");
-    mListenSocket->Close();
-    mListenSocket = nullptr;
-    mStreamSocket->Close();
-    mStreamSocket = nullptr;
-    return NS_ERROR_FAILURE;
+    return rv;
   }
 
+  mListener = aListener;
+  mNfcConsumer = nfcConsumer.forget();
+
   return NS_OK;
 }
 
+/**
+ * |CleanupRunnable| deletes instances of the NFC consumer and
+ * thread on the main thread. This has to be down after shutting
+ * down the NFC consumer on the NFC thread.
+ */
+class NfcService::CleanupRunnable final : public nsRunnable
+{
+public:
+  CleanupRunnable(NfcConsumer* aNfcConsumer,
+                  already_AddRefed<nsIThread> aThread)
+    : mNfcConsumer(aNfcConsumer)
+    , mThread(aThread)
+  {
+    MOZ_ASSERT(mNfcConsumer);
+    MOZ_ASSERT(mThread);
+  }
+
+  NS_IMETHOD Run() override
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+
+    mNfcConsumer = nullptr; // deletes NFC consumer
+
+    mThread->Shutdown();
+    mThread = nullptr; // deletes NFC worker thread
+
+    return NS_OK;
+  }
+
+private:
+  nsAutoPtr<NfcConsumer> mNfcConsumer;
+  nsCOMPtr<nsIThread> mThread;
+};
+
+/**
+ * |ShutdownConsumerRunnable| calls |NfcConsumer::Shutdown| on the
+ * NFC thread. Optionally, it can dispatch a |CleanupRunnable| to
+ * the main thread for cleaning up the NFC resources.
+ */
+class NfcService::ShutdownConsumerRunnable final : public nsRunnable
+{
+public:
+  ShutdownConsumerRunnable(NfcConsumer* aNfcConsumer, bool aCleanUp)
+    : mNfcConsumer(aNfcConsumer)
+    , mCleanUp(aCleanUp)
+  {
+    MOZ_ASSERT(mNfcConsumer);
+  }
+
+  NS_IMETHOD Run() override
+  {
+    mNfcConsumer->Shutdown();
+
+    if (mCleanUp) {
+      NS_DispatchToMainThread(
+        new CleanupRunnable(mNfcConsumer, do_GetCurrentThread()));
+    }
+
+    return NS_OK;
+  }
+
+private:
+  NfcConsumer* mNfcConsumer;
+  bool mCleanUp;
+};
+
 NS_IMETHODIMP
 NfcService::Shutdown()
 {
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (mThread) {
-    mThread->Shutdown();
-    mThread = nullptr;
+  if (!mNfcConsumer) {
+    return NS_OK; // NFC was shut down meanwhile; not an error
   }
 
-  mListenSocket->Close();
-  mListenSocket = nullptr;
-  mStreamSocket->Close();
-  mStreamSocket = nullptr;
+  nsresult rv = mThread->Dispatch(new ShutdownConsumerRunnable(mNfcConsumer,
+                                                               true),
+                                  nsIEventTarget::DISPATCH_NORMAL);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+
+  // |CleanupRunnable| will take care of these pointers
+  unused << mNfcConsumer.forget();
+  unused << mThread.forget();
 
   return NS_OK;
 }
 
-bool
-NfcService::PostToNfcDaemon(const uint8_t* aData, size_t aSize)
+/**
+ * |SendRunnable| calls |NfcConsumer::Send| on the NFC thread.
+ */
+class NfcService::SendRunnable final : public nsRunnable
 {
-  MOZ_ASSERT(!NS_IsMainThread());
+public:
+  SendRunnable(NfcConsumer* aNfcConsumer, const CommandOptions& aOptions)
+    : mNfcConsumer(aNfcConsumer)
+    , mOptions(aOptions)
+  {
+    MOZ_ASSERT(mNfcConsumer);
+  }
 
-  UnixSocketRawData* raw = new UnixSocketRawData(aData, aSize);
-  nsRefPtr<SendNfcSocketDataTask> task =
-    new SendNfcSocketDataTask(mStreamSocket, raw);
-  NS_DispatchToMainThread(task);
-  return true;
-}
+  NS_IMETHOD Run() override
+  {
+    mNfcConsumer->Send(mOptions);
+
+    return NS_OK;
+  }
+
+private:
+   NfcConsumer* mNfcConsumer;
+   CommandOptions mOptions;
+};
 
 NS_IMETHODIMP
 NfcService::SendCommand(JS::HandleValue aOptions, JSContext* aCx)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   NfcCommandOptions options;
 
   if (!options.Init(aCx, aOptions)) {
     NS_WARNING("Bad dictionary passed to NfcService::SendCommand");
     return NS_ERROR_FAILURE;
   }
 
   // Dispatch the command to the NFC thread.
-  CommandOptions commandOptions(options);
-  nsCOMPtr<nsIRunnable> runnable = new NfcCommandRunnable(mHandler, this,
-                                                          commandOptions);
-  mThread->Dispatch(runnable, nsIEventTarget::DISPATCH_NORMAL);
+  nsresult rv = mThread->Dispatch(new SendRunnable(mNfcConsumer,
+                                                   CommandOptions(options)),
+                                  nsIEventTarget::DISPATCH_NORMAL);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+
   return NS_OK;
 }
 
 void
 NfcService::DispatchNfcEvent(const mozilla::dom::NfcEventOptions& aOptions)
 {
   MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(mListener);
+
+  if (!mNfcConsumer) {
+    return; // NFC has been shutdown meanwhile; not en error
+  }
 
   mozilla::AutoSafeJSContext cx;
   JS::RootedValue val(cx);
 
   if (!ToJSValue(cx, aOptions, &val)) {
     return;
   }
 
   mListener->OnEvent(val);
 }
 
-// |StreamSocketConsumer|, |ListenSocketConsumer|
-
-void
-NfcService::ReceiveSocketData(
-  int aIndex, nsAutoPtr<mozilla::ipc::UnixSocketBuffer>& aBuffer)
-{
-  MOZ_ASSERT(mHandler);
-  nsCOMPtr<nsIRunnable> runnable =
-    new NfcEventRunnable(mHandler, aBuffer.forget());
-  mThread->Dispatch(runnable, nsIEventTarget::DISPATCH_NORMAL);
-}
-
-void
-NfcService::OnConnectSuccess(int aIndex)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  switch (aIndex) {
-    case LISTEN_SOCKET: {
-        nsCString value("nfcd:-S -a ");
-        value.Append(mListenSocketName);
-        if (NS_WARN_IF(property_set("ctl.start", value.get()) < 0)) {
-          OnConnectError(STREAM_SOCKET);
-        }
-      }
-      break;
-    case STREAM_SOCKET:
-      /* nothing to do */
-      break;
-  }
-}
-
-void
-NfcService::OnConnectError(int aIndex)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  Shutdown();
-}
-
-void
-NfcService::OnDisconnect(int aIndex)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-}
-
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(NfcService,
                                          NfcService::FactoryCreate)
 
 NS_DEFINE_NAMED_CID(NS_NFCSERVICE_CID);
 
 static const mozilla::Module::CIDEntry kNfcServiceCIDs[] = {
   { &kNS_NFCSERVICE_CID, false, nullptr, NfcServiceConstructor },
   { nullptr }
--- a/dom/nfc/gonk/NfcService.h
+++ b/dom/nfc/gonk/NfcService.h
@@ -2,71 +2,47 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef NfcService_h
 #define NfcService_h
 
-#include <mozilla/ipc/ListenSocket.h>
-#include "mozilla/ipc/ListenSocketConsumer.h"
-#include <mozilla/ipc/StreamSocket.h>
-#include "mozilla/ipc/StreamSocketConsumer.h"
 #include "nsCOMPtr.h"
 #include "nsINfcService.h"
-#include "NfcMessageHandler.h"
 
 class nsIThread;
 
 namespace mozilla {
 namespace dom {
 class NfcEventOptions;
 } // namespace dom
 
-class NfcService final
-  : public nsINfcService
-  , public mozilla::ipc::StreamSocketConsumer
-  , public mozilla::ipc::ListenSocketConsumer
+class NfcConsumer;
+
+class NfcService final : public nsINfcService
 {
 public:
-  NS_DECL_ISUPPORTS
+  NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSINFCSERVICE
 
   static already_AddRefed<NfcService> FactoryCreate();
 
   void DispatchNfcEvent(const mozilla::dom::NfcEventOptions& aOptions);
 
-  bool PostToNfcDaemon(const uint8_t* aData, size_t aSize);
-
-  nsCOMPtr<nsIThread> GetThread() {
-    return mThread;
-  }
-
-  // Methods for |StreamSocketConsumer| and |ListenSocketConsumer|
-  //
-
-  void ReceiveSocketData(
-    int aIndex, nsAutoPtr<mozilla::ipc::UnixSocketBuffer>& aBuffer) override;
-  void OnConnectSuccess(int aIndex) override;
-  void OnConnectError(int aIndex) override;
-  void OnDisconnect(int aIndex) override;
-
 private:
-  enum SocketType {
-    LISTEN_SOCKET,
-    STREAM_SOCKET
-  };
+  class CleanupRunnable;
+  class SendRunnable;
+  class ShutdownConsumerRunnable;
+  class StartConsumerRunnable;
 
   NfcService();
   ~NfcService();
 
   nsCOMPtr<nsIThread> mThread;
   nsCOMPtr<nsINfcGonkEventListener> mListener;
-  nsRefPtr<mozilla::ipc::ListenSocket> mListenSocket;
-  nsRefPtr<mozilla::ipc::StreamSocket> mStreamSocket;
-  nsAutoPtr<NfcMessageHandler> mHandler;
-  nsCString mListenSocketName;
+  nsAutoPtr<NfcConsumer> mNfcConsumer;
 };
 
 } // namespace mozilla
 
 #endif // NfcService_h
--- a/dom/webidl/BrowserElement.webidl
+++ b/dom/webidl/BrowserElement.webidl
@@ -146,17 +146,17 @@ interface BrowserElementPrivileged {
 
   [Throws,
    Pref="dom.mozBrowserFramesEnabled",
    CheckAllPermissions="browser input-manage"]
   DOMRequest setInputMethodActive(boolean isActive);
 
   [Throws,
    Pref="dom.mozBrowserFramesEnabled",
-   CheckAllPermissions="browser setNFCFocus"]
+   CheckAllPermissions="browser nfc-manager"]
   void setNFCFocus(boolean isFocus);
 
   [Throws,
    Pref="dom.mozBrowserFramesEnabled",
    CheckAnyPermissions="browser"]
   void findAll(DOMString searchString, BrowserFindCaseSensitivity caseSensitivity);
 
   [Throws,
rename from dom/bluetooth/bluedroid/BluetoothDaemonConnector.cpp
rename to ipc/hal/DaemonSocketConnector.cpp
--- a/dom/bluetooth/bluedroid/BluetoothDaemonConnector.cpp
+++ b/ipc/hal/DaemonSocketConnector.cpp
@@ -1,49 +1,104 @@
 /* -*- 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 "BluetoothDaemonConnector.h"
+#include "DaemonSocketConnector.h"
 #include <fcntl.h>
+#include <limits.h>
+#include <stddef.h>
+#include <string.h>
 #include <sys/un.h>
 #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, MOZ_COUNT_DTOR
-#include "nsThreadUtils.h"
+#include "prrng.h"
+
+#ifdef CHROMIUM_LOG
+#undef CHROMIUM_LOG
+#endif
+
+#if defined(MOZ_WIDGET_GONK)
+#include <android/log.h>
+#define CHROMIUM_LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "I/O", args);
+#else
+#include <stdio.h>
+#define IODEBUG true
+#define CHROMIUM_LOG(args...) if (IODEBUG) printf(args);
+#endif
+
+namespace mozilla {
+namespace ipc {
 
-BEGIN_BLUETOOTH_NAMESPACE
+nsresult
+DaemonSocketConnector::CreateRandomAddressString(
+  const nsACString& aPrefix, unsigned long aPostfixLength,
+  nsACString& aAddress)
+{
+  static const char sHexChar[16] = {
+    [0x0] = '0', [0x1] = '1', [0x2] = '2', [0x3] = '3',
+    [0x4] = '4', [0x5] = '5', [0x6] = '6', [0x7] = '7',
+    [0x8] = '8', [0x9] = '9', [0xa] = 'a', [0xb] = 'b',
+    [0xc] = 'c', [0xd] = 'd', [0xe] = 'e', [0xf] = 'f'
+  };
+
+  unsigned short seed[3];
+
+  if (NS_WARN_IF(!PR_GetRandomNoise(seed, sizeof(seed)))) {
+    return NS_ERROR_NOT_IMPLEMENTED;
+  }
 
-BluetoothDaemonConnector::BluetoothDaemonConnector(
-  const nsACString& aSocketName)
+  aAddress = aPrefix;
+  aAddress.Append('-');
+
+  while (aPostfixLength) {
+    // Android doesn't provide rand_r, so we use nrand48 here,
+    // even though it's deprecated.
+    long value = nrand48(seed);
+
+    size_t bits = sizeof(value) * CHAR_BIT;
+
+    while ((bits > 4) && aPostfixLength) {
+      aAddress.Append(sHexChar[value&0xf]);
+      bits -= 4;
+      value >>= 4;
+      --aPostfixLength;
+    }
+  }
+
+  return NS_OK;
+}
+
+DaemonSocketConnector::DaemonSocketConnector(const nsACString& aSocketName)
   : mSocketName(aSocketName)
 {
-  MOZ_COUNT_CTOR_INHERITED(BluetoothDaemonConnector, UnixSocketConnector);
+  MOZ_COUNT_CTOR_INHERITED(DaemonSocketConnector, UnixSocketConnector);
 }
 
-BluetoothDaemonConnector::~BluetoothDaemonConnector()
+DaemonSocketConnector::~DaemonSocketConnector()
 {
-  MOZ_COUNT_CTOR_INHERITED(BluetoothDaemonConnector, UnixSocketConnector);
+  MOZ_COUNT_CTOR_INHERITED(DaemonSocketConnector, UnixSocketConnector);
 }
 
 nsresult
-BluetoothDaemonConnector::CreateSocket(int& aFd) const
+DaemonSocketConnector::CreateSocket(int& aFd) const
 {
   aFd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
   if (aFd < 0) {
-    BT_WARNING("Could not open Bluetooth daemon socket!");
+    CHROMIUM_LOG("Could not open daemon socket!");
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
 nsresult
-BluetoothDaemonConnector::SetSocketFlags(int aFd) const
+DaemonSocketConnector::SetSocketFlags(int aFd) const
 {
   static const int sReuseAddress = 1;
 
   // Set close-on-exec bit.
   int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFD));
   if (flags < 0) {
     return NS_ERROR_FAILURE;
   }
@@ -70,17 +125,17 @@ BluetoothDaemonConnector::SetSocketFlags
   if (res < 0) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
 nsresult
-BluetoothDaemonConnector::CreateAddress(struct sockaddr& aAddress,
+DaemonSocketConnector::CreateAddress(struct sockaddr& aAddress,
                                         socklen_t& aAddressLength) const
 {
   static const size_t sNameOffset = 1;
 
   struct sockaddr_un* address =
     reinterpret_cast<struct sockaddr_un*>(&aAddress);
 
   size_t namesiz = mSocketName.Length() + 1; // include trailing '\0'
@@ -97,34 +152,34 @@ BluetoothDaemonConnector::CreateAddress(
     offsetof(struct sockaddr_un, sun_path) + sNameOffset + namesiz;
 
   return NS_OK;
 }
 
 // |UnixSocketConnector|
 
 nsresult
-BluetoothDaemonConnector::ConvertAddressToString(
+DaemonSocketConnector::ConvertAddressToString(
   const struct sockaddr& aAddress, socklen_t aAddressLength,
   nsACString& aAddressString)
 {
   MOZ_ASSERT(aAddress.sa_family == AF_UNIX);
 
   const struct sockaddr_un* un =
     reinterpret_cast<const struct sockaddr_un*>(&aAddress);
 
   size_t len = aAddressLength - offsetof(struct sockaddr_un, sun_path);
 
   aAddressString.Assign(un->sun_path, len);
 
   return NS_OK;
 }
 
 nsresult
-BluetoothDaemonConnector::CreateListenSocket(struct sockaddr* aAddress,
+DaemonSocketConnector::CreateListenSocket(struct sockaddr* aAddress,
                                              socklen_t* aAddressLength,
                                              int& aListenFd)
 {
   ScopedClose fd;
 
   nsresult rv = CreateSocket(fd.rwget());
   if (NS_FAILED(rv)) {
     return rv;
@@ -141,48 +196,49 @@ BluetoothDaemonConnector::CreateListenSo
   }
 
   aListenFd = fd.forget();
 
   return NS_OK;
 }
 
 nsresult
-BluetoothDaemonConnector::AcceptStreamSocket(int aListenFd,
+DaemonSocketConnector::AcceptStreamSocket(int aListenFd,
                                              struct sockaddr* aAddress,
                                              socklen_t* aAddressLength,
                                              int& aStreamFd)
 {
   ScopedClose fd(
     TEMP_FAILURE_RETRY(accept(aListenFd, aAddress, aAddressLength)));
   if (fd < 0) {
-    NS_WARNING("Cannot accept file descriptor!");
+    CHROMIUM_LOG("Cannot accept file descriptor!");
     return NS_ERROR_FAILURE;
   }
   nsresult rv = SetSocketFlags(fd);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   aStreamFd = fd.forget();
 
   return NS_OK;
 }
 
 nsresult
-BluetoothDaemonConnector::CreateStreamSocket(struct sockaddr* aAddress,
+DaemonSocketConnector::CreateStreamSocket(struct sockaddr* aAddress,
                                              socklen_t* aAddressLength,
                                              int& aStreamFd)
 {
-  MOZ_CRASH("|BluetoothDaemonConnector| does not support "
+  MOZ_CRASH("|DaemonSocketConnector| does not support "
             "creating stream sockets.");
   return NS_ERROR_ABORT;
 }
 
 nsresult
-BluetoothDaemonConnector::Duplicate(UnixSocketConnector*& aConnector)
+DaemonSocketConnector::Duplicate(UnixSocketConnector*& aConnector)
 {
-  aConnector = new BluetoothDaemonConnector(*this);
+  aConnector = new DaemonSocketConnector(*this);
 
   return NS_OK;
 }
 
-END_BLUETOOTH_NAMESPACE
+} // namespace ipc
+} // namespace mozilla
rename from dom/bluetooth/bluedroid/BluetoothDaemonConnector.h
rename to ipc/hal/DaemonSocketConnector.h
--- a/dom/bluetooth/bluedroid/BluetoothDaemonConnector.h
+++ b/ipc/hal/DaemonSocketConnector.h
@@ -1,29 +1,33 @@
 /* -*- 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/. */
 
-#ifndef mozilla_dom_bluetooth_bluedroid_bluetoothdaemonconnector_h
-#define mozilla_dom_bluetooth_bluedroid_bluetoothdaemonconnector_h
+#ifndef mozilla_ipc_DaemonSocketConnector_h
+#define mozilla_ipc_DaemonSocketConnector_h
 
-#include "mozilla/dom/bluetooth/BluetoothCommon.h"
 #include "mozilla/ipc/UnixSocketConnector.h"
-
-BEGIN_BLUETOOTH_NAMESPACE
+#include "nsString.h"
 
-class BluetoothDaemonConnector final
-  : public mozilla::ipc::UnixSocketConnector
+namespace mozilla {
+namespace ipc {
+
+class DaemonSocketConnector final : public UnixSocketConnector
 {
 public:
-  BluetoothDaemonConnector(const nsACString& aSocketName);
-  ~BluetoothDaemonConnector();
+  static nsresult CreateRandomAddressString(const nsACString& aPrefix,
+                                            unsigned long aPostfixLength,
+                                            nsACString& aAddress);
+
+  DaemonSocketConnector(const nsACString& aSocketName);
+  ~DaemonSocketConnector();
 
   // Methods for |UnixSocketConnector|
   //
 
   nsresult ConvertAddressToString(const struct sockaddr& aAddress,
                                   socklen_t aAddressLength,
                                   nsACString& aAddressString) override;
 
@@ -46,11 +50,12 @@ private:
   nsresult CreateSocket(int& aFd) const;
   nsresult SetSocketFlags(int aFd) const;
   nsresult CreateAddress(struct sockaddr& aAddress,
                          socklen_t& aAddressLength) const;
 
   nsCString mSocketName;
 };
 
-END_BLUETOOTH_NAMESPACE
+} // namespace ipc
+} // namespace mozilla
 
-#endif
+#endif // mozilla_ipc_DaemonSocketConnector_h
--- a/ipc/hal/moz.build
+++ b/ipc/hal/moz.build
@@ -2,23 +2,25 @@
 # vim: set filetype=python:
 # 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/.
 
 EXPORTS.mozilla.ipc += [
     'DaemonRunnables.h',
     'DaemonSocket.h',
+    'DaemonSocketConnector.h',
     'DaemonSocketConsumer.h',
     'DaemonSocketPDU.h',
     'DaemonSocketPDUHelpers.h'
 ]
 
 UNIFIED_SOURCES += [
     'DaemonSocket.cpp',
+    'DaemonSocketConnector.cpp',
     'DaemonSocketConsumer.cpp',
     'DaemonSocketPDU.cpp',
     'DaemonSocketPDUHelpers.cpp'
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
--- a/layout/base/PositionedEventTargeting.cpp
+++ b/layout/base/PositionedEventTargeting.cpp
@@ -29,31 +29,31 @@ namespace mozilla {
 /*
  * The basic goal of FindFrameTargetedByInputEvent() is to find a good
  * target element that can respond to mouse events. Both mouse events and touch
  * events are targeted at this element. Note that even for touch events, we
  * check responsiveness to mouse events. We assume Web authors
  * designing for touch events will take their own steps to account for
  * inaccurate touch events.
  *
- * IsElementClickable() encapsulates the heuristic that determines whether an
+ * GetClickableAncestor() encapsulates the heuristic that determines whether an
  * element is expected to respond to mouse events. An element is deemed
  * "clickable" if it has registered listeners for "click", "mousedown" or
  * "mouseup", or is on a whitelist of element tags (<a>, <button>, <input>,
  * <select>, <textarea>, <label>), or has role="button", or is a link, or
  * is a suitable XUL element.
  * Any descendant (in the same document) of a clickable element is also
  * deemed clickable since events will propagate to the clickable element from its
  * descendant.
  *
  * If the element directly under the event position is clickable (or
  * event radii are disabled), we always use that element. Otherwise we collect
  * all frames intersecting a rectangle around the event position (taking CSS
  * transforms into account) and choose the best candidate in GetClosest().
- * Only IsElementClickable() candidates are considered; if none are found,
+ * Only GetClickableAncestor() candidates are considered; if none are found,
  * then we revert to targeting the element under the event position.
  * We ignore candidates outside the document subtree rooted by the
  * document of the element directly under the event position. This ensures that
  * event listeners in ancestor documents don't make it completely impossible
  * to target a non-clickable element in a child document.
  *
  * When both a frame and its ancestor are in the candidate list, we ignore
  * the ancestor. Otherwise a large ancestor element with a mouse event listener
@@ -182,83 +182,83 @@ IsDescendant(nsIFrame* aFrame, nsIConten
     }
     if (content == aAncestor) {
       return true;
     }
   }
   return false;
 }
 
-static bool
-IsElementClickable(nsIFrame* aFrame, nsIAtom* stopAt = nullptr, nsAutoString* aLabelTargetId = nullptr)
+static nsIContent*
+GetClickableAncestor(nsIFrame* aFrame, nsIAtom* stopAt = nullptr, nsAutoString* aLabelTargetId = nullptr)
 {
   // Input events propagate up the content tree so we'll follow the content
   // ancestors to look for elements accepting the click.
   for (nsIContent* content = aFrame->GetContent(); content;
        content = content->GetFlattenedTreeParent()) {
     if (stopAt && content->IsHTMLElement(stopAt)) {
       break;
     }
     if (HasTouchListener(content) || HasMouseListener(content)) {
-      return true;
+      return content;
     }
     if (content->IsAnyOfHTMLElements(nsGkAtoms::button,
                                      nsGkAtoms::input,
                                      nsGkAtoms::select,
                                      nsGkAtoms::textarea)) {
-      return true;
+      return content;
     }
     if (content->IsHTMLElement(nsGkAtoms::label)) {
       if (aLabelTargetId) {
         content->GetAttr(kNameSpaceID_None, nsGkAtoms::_for, *aLabelTargetId);
       }
-      return true;
+      return content;
     }
 
     // Bug 921928: we don't have access to the content of remote iframe.
     // So fluffing won't go there. We do an optimistic assumption here:
     // that the content of the remote iframe needs to be a target.
     if (content->IsHTMLElement(nsGkAtoms::iframe) &&
         content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::mozbrowser,
                              nsGkAtoms::_true, eIgnoreCase) &&
         content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::Remote,
                              nsGkAtoms::_true, eIgnoreCase)) {
-      return true;
+      return content;
     }
 
     // See nsCSSFrameConstructor::FindXULTagData. This code is not
     // really intended to be used with XUL, though.
     if (content->IsAnyOfXULElements(nsGkAtoms::button,
                                     nsGkAtoms::checkbox,
                                     nsGkAtoms::radio,
                                     nsGkAtoms::autorepeatbutton,
                                     nsGkAtoms::menu,
                                     nsGkAtoms::menubutton,
                                     nsGkAtoms::menuitem,
                                     nsGkAtoms::menulist,
                                     nsGkAtoms::scrollbarbutton,
                                     nsGkAtoms::resizer)) {
-      return true;
+      return content;
     }
 
     static nsIContent::AttrValuesArray clickableRoles[] =
       { &nsGkAtoms::button, &nsGkAtoms::key, nullptr };
     if (content->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::role,
                                  clickableRoles, eIgnoreCase) >= 0) {
-      return true;
+      return content;
     }
     if (content->IsEditable()) {
-      return true;
+      return content;
     }
     nsCOMPtr<nsIURI> linkURI;
     if (content->IsLink(getter_AddRefs(linkURI))) {
-      return true;
+      return content;
     }
   }
-  return false;
+  return nullptr;
 }
 
 static nscoord
 AppUnitsFromMM(nsIFrame* aFrame, uint32_t aMM, bool aVertical)
 {
   nsPresContext* pc = aFrame->PresContext();
   float result = float(aMM) *
     (pc->DeviceContext()->AppUnitsPerPhysicalInch() / MM_PER_INCH_FLOAT);
@@ -357,84 +357,88 @@ static bool IsElementPresent(nsTArray<ns
 }
 
 static nsIFrame*
 GetClosest(nsIFrame* aRoot, const nsPoint& aPointRelativeToRootFrame,
            const nsRect& aTargetRect, const EventRadiusPrefs* aPrefs,
            nsIFrame* aRestrictToDescendants, nsIContent* aClickableAncestor,
            nsTArray<nsIFrame*>& aCandidates, int32_t* aElementsInCluster)
 {
+  std::vector<nsIContent*> mContentsInCluster;  // List of content elements in the cluster without duplicate
   nsIFrame* bestTarget = nullptr;
   // Lower is better; distance is in appunits
   float bestDistance = 1e6f;
   nsRegion exposedRegion(aTargetRect);
   for (uint32_t i = 0; i < aCandidates.Length(); ++i) {
     nsIFrame* f = aCandidates[i];
     PET_LOG("Checking candidate %p\n", f);
 
     bool preservesAxisAlignedRectangles = false;
     nsRect borderBox = nsLayoutUtils::TransformFrameRectToAncestor(f,
         nsRect(nsPoint(0, 0), f->GetSize()), aRoot, &preservesAxisAlignedRectangles);
     nsRegion region;
     region.And(exposedRegion, borderBox);
-
     if (region.IsEmpty()) {
       PET_LOG("  candidate %p had empty hit region\n", f);
       continue;
     }
 
     if (preservesAxisAlignedRectangles) {
       // Subtract from the exposed region if we have a transform that won't make
       // the bounds include a bunch of area that we don't actually cover.
       SubtractFromExposedRegion(&exposedRegion, region);
     }
 
     nsAutoString labelTargetId;
-    if (aClickableAncestor) {
-      if (!IsDescendant(f, aClickableAncestor, &labelTargetId)) {
-        PET_LOG("  candidate %p is not a descendant of required ancestor\n", f);
-        continue;
-      }
-    } else if (!IsElementClickable(f, nsGkAtoms::body, &labelTargetId)) {
+    if (aClickableAncestor && !IsDescendant(f, aClickableAncestor, &labelTargetId)) {
+      PET_LOG("  candidate %p is not a descendant of required ancestor\n", f);
+      continue;
+    }
+
+    nsIContent* clickableContent = GetClickableAncestor(f, nsGkAtoms::body, &labelTargetId);
+    if (!aClickableAncestor && !clickableContent) {
       PET_LOG("  candidate %p was not clickable\n", f);
       continue;
     }
     // If our current closest frame is a descendant of 'f', skip 'f' (prefer
     // the nested frame).
     if (bestTarget && nsLayoutUtils::IsProperAncestorFrameCrossDoc(f, bestTarget, aRoot)) {
       PET_LOG("  candidate %p was ancestor for bestTarget %p\n", f, bestTarget);
       continue;
     }
-    if (!nsLayoutUtils::IsAncestorFrameCrossDoc(aRestrictToDescendants, f, aRoot)) {
+    if (!aClickableAncestor && !nsLayoutUtils::IsAncestorFrameCrossDoc(aRestrictToDescendants, f, aRoot)) {
       PET_LOG("  candidate %p was not descendant of restrictroot %p\n", f, aRestrictToDescendants);
       continue;
     }
 
     // If the first clickable ancestor of f is a label element
     // and "for" attribute is present in label element, search the frame list for the "for" element
     // If this element is present in the current list, do not count the frame in
     // the cluster elements counter
     if (labelTargetId.IsEmpty() || !IsElementPresent(aCandidates, labelTargetId)) {
-      (*aElementsInCluster)++;
+      if (std::find(mContentsInCluster.begin(), mContentsInCluster.end(), clickableContent) == mContentsInCluster.end()) {
+        mContentsInCluster.push_back(clickableContent);
+      }
     }
 
     // distance is in appunits
     float distance = ComputeDistanceFromRegion(aPointRelativeToRootFrame, region);
     nsIContent* content = f->GetContent();
     if (content && content->IsElement() &&
         content->AsElement()->State().HasState(
                                         EventStates(NS_EVENT_STATE_VISITED))) {
       distance *= aPrefs->mVisitedWeight / 100.0f;
     }
     if (distance < bestDistance) {
       PET_LOG("  candidate %p is the new best\n", f);
       bestDistance = distance;
       bestTarget = f;
     }
   }
+  *aElementsInCluster = mContentsInCluster.size();
   return bestTarget;
 }
 
 /*
  * Return always true when touch cluster detection is OFF.
  * When cluster detection is ON, return true:
  *   if the text inside the frame is readable (by human eyes)
  *   or
@@ -519,37 +523,39 @@ FindFrameTargetedByInputEvent(WidgetGUIE
     mozilla::layers::Stringify(aPointRelativeToRootFrame).c_str(), aRootFrame);
 
   const EventRadiusPrefs* prefs = GetPrefsFor(aEvent->mClass);
   if (!prefs || !prefs->mEnabled) {
     PET_LOG("Retargeting disabled\n");
     return target;
   }
   nsIContent* clickableAncestor = nullptr;
-  if (target && IsElementClickable(target, nsGkAtoms::body)) {
-    if (!IsElementClickableAndReadable(target, aEvent, prefs)) {
-      aEvent->AsMouseEventBase()->hitCluster = true;
+  if (target) {
+    clickableAncestor = GetClickableAncestor(target, nsGkAtoms::body);
+    if (clickableAncestor) {
+      if (!IsElementClickableAndReadable(target, aEvent, prefs)) {
+        aEvent->AsMouseEventBase()->hitCluster = true;
+      }
+      PET_LOG("Target %p is clickable\n", target);
     }
-    PET_LOG("Target %p is clickable\n", target);
-    clickableAncestor = target->GetContent();
   }
 
   // Do not modify targeting for actual mouse hardware; only for mouse
   // events generated by touch-screen hardware.
   if (aEvent->mClass == eMouseEventClass &&
       prefs->mTouchOnly &&
       aEvent->AsMouseEvent()->inputSource !=
         nsIDOMMouseEvent::MOZ_SOURCE_TOUCH) {
     PET_LOG("Mouse input event is not from a touch source\n");
     return target;
   }
 
   // If the exact target is non-null, only consider candidate targets in the same
   // document as the exact target. Otherwise, if an ancestor document has
-  // a mouse event handler for example, targets that are !IsElementClickable can
+  // a mouse event handler for example, targets that are !GetClickableAncestor can
   // never be targeted --- something nsSubDocumentFrame in an ancestor document
   // would be targeted instead.
   nsIFrame* restrictToDescendants = target ?
     target->PresContext()->PresShell()->GetRootFrame() : aRootFrame;
 
   nsRect targetRect = GetTargetRect(aRootFrame, aPointRelativeToRootFrame,
                                     restrictToDescendants, prefs, aFlags);
   PET_LOG("Expanded point to target rect %s\n",
--- a/toolkit/devtools/gcli/commands/index.js
+++ b/toolkit/devtools/gcli/commands/index.js
@@ -49,35 +49,35 @@ exports.baseModules = [
   "gcli/commands/pref",
 ];
 
 /**
  * Some commands belong to a tool (see getToolModules). This is a list of the
  * modules that are *not* owned by a tool.
  */
 exports.devtoolsModules = [
-  "gcli/commands/addon",
-  "gcli/commands/appcache",
-  "gcli/commands/calllog",
-  "gcli/commands/cmd",
-  "gcli/commands/cookie",
-  "gcli/commands/csscoverage",
-  "gcli/commands/folder",
-  "gcli/commands/highlight",
-  "gcli/commands/inject",
-  "gcli/commands/jsb",
-  "gcli/commands/listen",
-  "gcli/commands/media",
-  "gcli/commands/pagemod",
-  "gcli/commands/paintflashing",
-  "gcli/commands/restart",
-  "gcli/commands/rulers",
-  "gcli/commands/screenshot",
-  "gcli/commands/security",
-  "gcli/commands/tools",
+  "devtools/toolkit/gcli/commands/addon",
+  "devtools/toolkit/gcli/commands/appcache",
+  "devtools/toolkit/gcli/commands/calllog",
+  "devtools/toolkit/gcli/commands/cmd",
+  "devtools/toolkit/gcli/commands/cookie",
+  "devtools/toolkit/gcli/commands/csscoverage",
+  "devtools/toolkit/gcli/commands/folder",
+  "devtools/toolkit/gcli/commands/highlight",
+  "devtools/toolkit/gcli/commands/inject",
+  "devtools/toolkit/gcli/commands/jsb",
+  "devtools/toolkit/gcli/commands/listen",
+  "devtools/toolkit/gcli/commands/media",
+  "devtools/toolkit/gcli/commands/pagemod",
+  "devtools/toolkit/gcli/commands/paintflashing",
+  "devtools/toolkit/gcli/commands/restart",
+  "devtools/toolkit/gcli/commands/rulers",
+  "devtools/toolkit/gcli/commands/screenshot",
+  "devtools/toolkit/gcli/commands/security",
+  "devtools/toolkit/gcli/commands/tools",
 ];
 
 /**
  * Register commands from tools with 'command: [ "some/module" ]' definitions.
  * The map/reduce incantation squashes the array of arrays to a single array.
  */
 try {
   const defaultTools = require("definitions").defaultTools;
@@ -106,17 +106,17 @@ try {
  * Add modules to a system for use in a content process (but don't call load)
  */
 exports.addAllItemsByModule = function(system) {
   system.addItemsByModule(exports.baseModules, { delayedLoad: true });
   system.addItemsByModule(exports.devtoolsModules, { delayedLoad: true });
   system.addItemsByModule(exports.devtoolsToolModules, { delayedLoad: true });
   system.addItemsByModule(exports.devtoolsButtonModules, { delayedLoad: true });
 
-  const { mozDirLoader } = require("gcli/commands/cmd");
+  const { mozDirLoader } = require("devtools/toolkit/gcli/commands/cmd");
   system.addItemsByModule("mozcmd", { delayedLoad: true, loader: mozDirLoader });
 };
 
 /**
  * This is WeakMap<Target, Links> where Links is an object that looks like
  *   { refs: number, promise: Promise<System>, front: GcliFront }
  */
 var linksForTarget = new WeakMap();
--- a/toolkit/devtools/server/actors/gcli.js
+++ b/toolkit/devtools/server/actors/gcli.js
@@ -239,17 +239,17 @@ const GcliActor = ActorClass({
     }
 
     const Requisition = require("gcli/cli").Requisition;
     const tabActor = this._tabActor;
 
     this._system = createSystem({ location: "server" });
     this._system.commands.onCommandsChange.add(this._commandsChanged);
 
-    const gcliInit = require("gcli/commands/index");
+    const gcliInit = require("devtools/toolkit/gcli/commands/index");
     gcliInit.addAllItemsByModule(this._system);
 
     // this._requisitionPromise should be created synchronously with the call
     // to _getRequisition so that destroy can tell whether there is an async
     // init in progress
     this._requisitionPromise = this._system.load().then(() => {
       const environment = {
         get chromeWindow() {
--- a/toolkit/devtools/server/actors/storage.js
+++ b/toolkit/devtools/server/actors/storage.js
@@ -644,19 +644,19 @@ StorageActors.createActor({
     if (!DebuggerServer.isInChildProcess) {
       this.getCookiesFromHost = cookieHelpers.getCookiesFromHost;
       this.addCookieObservers = cookieHelpers.addCookieObservers;
       this.removeCookieObservers = cookieHelpers.removeCookieObservers;
       return;
     }
 
     const { sendSyncMessage, addMessageListener } =
-      DebuggerServer.parentMessageManager;
+      this.conn.parentMessageManager;
 
-    DebuggerServer.setupInParent({
+    this.conn.setupInParent({
       module: "devtools/server/actors/storage",
       setupParent: "setupParentProcessForCookies"
     });
 
     this.getCookiesFromHost =
       callParentProcess.bind(null, "getCookiesFromHost");
     this.addCookieObservers =
       callParentProcess.bind(null, "addCookieObservers");
@@ -744,37 +744,36 @@ let cookieHelpers = {
         let host = msg.data.args[0];
         let cookies = cookieHelpers.getCookiesFromHost(host);
         return JSON.stringify(cookies);
       case "addCookieObservers":
         return cookieHelpers.addCookieObservers();
         break;
       case "removeCookieObservers":
         return cookieHelpers.removeCookieObservers();
-        return null;
       default:
         console.error("ERR_DIRECTOR_PARENT_UNKNOWN_METHOD", msg.json.method);
         throw new Error("ERR_DIRECTOR_PARENT_UNKNOWN_METHOD");
     }
   },
 };
 
 /**
  * E10S parent/child setup helpers
  */
 
-exports.setupParentProcessForCookies = function({mm, childID}) {
+exports.setupParentProcessForCookies = function({mm, prefix}) {
   cookieHelpers.onCookieChanged =
     callChildProcess.bind(null, "onCookieChanged");
 
   // listen for director-script requests from the child process
   mm.addMessageListener("storage:storage-cookie-request-parent",
                         cookieHelpers.handleChildRequest);
 
-  DebuggerServer.once("disconnected-from-child:" + childID,
+  DebuggerServer.once("disconnected-from-child:" + prefix,
                       handleMessageManagerDisconnected);
 
   gTrackedMessageManager.set("cookies", mm);
 
   function handleMessageManagerDisconnected(evt, { mm: disconnected_mm }) {
     // filter out not subscribed message managers
     if (disconnected_mm !== mm || !gTrackedMessageManager.has(mm)) {
       return;
@@ -1033,16 +1032,19 @@ DatabaseMetadata.prototype = {
 };
 
 StorageActors.createActor({
   typeName: "indexedDB",
   storeObjectType: "idbstoreobject"
 }, {
   initialize: function(storageActor) {
     protocol.Actor.prototype.initialize.call(this, null);
+
+    this.storageActor = storageActor;
+
     this.maybeSetupChildProcess();
 
     this.objectsSize = {};
     this.storageActor = storageActor;
     this.onWindowReady = this.onWindowReady.bind(this);
     this.onWindowDestroyed = this.onWindowDestroyed.bind(this);
 
     events.on(this.storageActor, "window-ready", this.onWindowReady);
@@ -1231,19 +1233,19 @@ StorageActors.createActor({
       this.getValuesForHost = indexedDBHelpers.getValuesForHost;
       this.getObjectStoreData = indexedDBHelpers.getObjectStoreData;
       this.patchMetadataMapsAndProtos =
         indexedDBHelpers.patchMetadataMapsAndProtos;
       return;
     }
 
     const { sendSyncMessage, addMessageListener } =
-      DebuggerServer.parentMessageManager;
+      this.conn.parentMessageManager;
 
-    DebuggerServer.setupInParent({
+    this.conn.setupInParent({
       module: "devtools/server/actors/storage",
       setupParent: "setupParentProcessForIndexedDB"
     });
 
     this.getDBMetaData =
       callParentProcessAsync.bind(null, "getDBMetaData");
     this.getDBNamesForHost =
       callParentProcessAsync.bind(null, "getDBNamesForHost");
@@ -1597,22 +1599,22 @@ let indexedDBHelpers = {
     }
   }
 };
 
 /**
  * E10S parent/child setup helpers
  */
 
-exports.setupParentProcessForIndexedDB = function({mm, childID}) {
+exports.setupParentProcessForIndexedDB = function({mm, prefix}) {
   // listen for director-script requests from the child process
   mm.addMessageListener("storage:storage-indexedDB-request-parent",
                         indexedDBHelpers.handleChildRequest);
 
-  DebuggerServer.once("disconnected-from-child:" + childID,
+  DebuggerServer.once("disconnected-from-child:" + prefix,
                       handleMessageManagerDisconnected);
 
   gTrackedMessageManager.set("indexedDB", mm);
 
   function handleMessageManagerDisconnected(evt, { mm: disconnected_mm }) {
     // filter out not subscribed message managers
     if (disconnected_mm !== mm || !gTrackedMessageManager.has(mm)) {
       return;
--- a/toolkit/devtools/server/child.js
+++ b/toolkit/devtools/server/child.js
@@ -12,24 +12,21 @@ let chromeGlobal = this;
 // more than once.
 (function () {
   let Cu = Components.utils;
   let { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
   const DevToolsUtils = devtools.require("devtools/toolkit/DevToolsUtils.js");
   const { dumpn } = DevToolsUtils;
   const { DebuggerServer, ActorPool } = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {});
 
+  // Note that this frame script may be evaluated in non-e10s build
+  // In such case, DebuggerServer is already going to be initialized.
   if (!DebuggerServer.initialized) {
     DebuggerServer.init();
-
-    // message manager helpers provided for actor module parent/child message exchange
-    DebuggerServer.parentMessageManager = {
-      sendSyncMessage: sendSyncMessage,
-      addMessageListener: addMessageListener
-    };
+    DebuggerServer.isInChildProcess = true;
   }
 
   // In case of apps being loaded in parent process, DebuggerServer is already
   // initialized, but child specific actors are not registered.
   // Otherwise, for apps in child process, we need to load actors the first
   // time we load child.js
   DebuggerServer.addChildActors();
 
@@ -37,16 +34,17 @@ let chromeGlobal = this;
 
   let onConnect = DevToolsUtils.makeInfallible(function (msg) {
     removeMessageListener("debug:connect", onConnect);
 
     let mm = msg.target;
     let prefix = msg.data.prefix;
 
     let conn = DebuggerServer.connectToParent(prefix, mm);
+    conn.parentMessageManager = mm;
     connections.set(prefix, conn);
 
     let actor = new DebuggerServer.ContentActor(conn, chromeGlobal, prefix);
     let actorPool = new ActorPool(conn);
     actorPool.addActor(actor);
     conn.addActorPool(actorPool);
 
     sendAsyncMessage("debug:actor", {actor: actor.form(), prefix: prefix});
--- a/toolkit/devtools/server/docs/actor-e10s-handling.md
+++ b/toolkit/devtools/server/docs/actor-e10s-handling.md
@@ -20,25 +20,27 @@ E.g. in the **director-registry**:
 
   // Setup the child<->parent communication only if the actor module
   // is running in a child process.
   if (DebuggerServer.isInChildProcess) {
     setupChildProcess();
   }
 
   function setupChildProcess() {
-    DebuggerServer.setupInParent({
+    // `setupInParent`  is defined on DebuggerServerConnection,
+    // your actor receive a reference to one instance in its constructor.
+    conn.setupInParent({
       module: "devtools/server/actors/director-registry",
       setupParent: "setupParentProcess"
     });
     // ...
   }
 ```
 
-The `setupChildProcess` helper defined and used in the previous example uses the `DebuggerServer.setupInParent` to run a given setup function in the parent process Debugger Server, e.g. in the **director-registry** module.
+The `setupChildProcess` helper defined and used in the previous example uses the `DebuggerServerConnection.setupInParent` to run a given setup function in the parent process Debugger Server, e.g. in the **director-registry** module.
 
 With this, the `DebuggerServer` running in the parent process will require the requested module (**director-registry**) and call its `setupParentProcess` function (which should be exported on the module).
 
 The `setupParentProcess` function will receive a parameter that contains a reference to the **MessageManager** and a prefix that should be used to send/receive messages between the child and parent processes.
 
 See below an example implementation of a `setupParent` function in the parent process:
 
 ```
@@ -76,27 +78,27 @@ exports.setupParentProcess = function se
 
     gTrackedMessageManager.delete(mm);
 
     // unregister for director-script requests handlers from the parent process (if any)
     mm.removeMessageListener("debug:director-registry-request", handleChildRequest);
   }
 ```
 
-The `DebuggerServer` emits "disconnected-from-child:CHILDID" events to give the actor modules the chance to cleanup their handlers registered on the disconnected message manager.
+The `DebuggerServer` emits "disconnected-from-child:PREFIX" events to give the actor modules the chance to cleanup their handlers registered on the disconnected message manager.
 
 ## Summary of the setup flow
 
 In the child process:
 
 * The `DebuggerServer` loads an actor module,
 * the actor module checks `DebuggerServer.isInChildProcess` to know whether it runs in a child process or not,
-* the actor module then uses the `DebuggerServer.setupInParent` helper to start setting up a parent-process counterpart,
-* the `DebuggerServer.setupInParent` helper asks the parent process to run the required module's setup function,
-* the actor module uses the `DebuggerServer.parentMessageManager.sendSyncMessage` and `DebuggerServer.parentMessageManager.addMessageListener` helpers to send or listen to message.
+* the actor module then uses the `DebuggerServerConnection.setupInParent` helper to start setting up a parent-process counterpart,
+* the `DebuggerServerConnection.setupInParent` helper asks the parent process to run the required module's setup function,
+* the actor module uses the `DebuggerServerConnection.parentMessageManager.sendSyncMessage` and `DebuggerServerConnection.parentMessageManager.addMessageListener` helpers to send or listen to message.
 
 In the parent process:
 
-* The DebuggerServer receives the `DebuggerServer.setupInParent` request,
+* The DebuggerServer receives the `DebuggerServerConnection.setupInParent` request,
 * tries to load the required module,
 * tries to call the `module[setupParent]` function with the frame message manager and the prefix as parameters `{ mm, prefix }`,
 * the `setupParent` function then uses the mm to subscribe the messagemanager events,
-* the `setupParent` function also uses the DebuggerServer object to subscribe *once* to the `"disconnected-from-child:PREFIX"` event to unsubscribe from messagemanager events.
\ No newline at end of file
+* the `setupParent` function also uses the DebuggerServer object to subscribe *once* to the `"disconnected-from-child:PREFIX"` event to unsubscribe from messagemanager events.
--- a/toolkit/devtools/server/main.js
+++ b/toolkit/devtools/server/main.js
@@ -873,73 +873,51 @@ var DebuggerServer = {
         }
       };
       aDbg.addListener(listener);
     });
   },
 
   /**
    * Check if the caller is running in a content child process.
+   * (Eventually set by child.js)
    *
    * @return boolean
    *         true if the caller is running in a content
    */
-  get isInChildProcess() {
-    return !!this.parentMessageManager;
-  },
+  isInChildProcess: false,
 
   /**
    * In a chrome parent process, ask all content child processes
    * to execute a given module setup helper.
    *
    * @param module
    *        The module to be required
    * @param setupChild
    *        The name of the setup helper exported by the above module
    *        (setup helper signature: function ({mm}) { ... })
    */
   setupInChild: function({ module, setupChild, args }) {
     if (this.isInChildProcess) {
       return;
     }
 
-    const gMessageManager = Cc["@mozilla.org/globalmessagemanager;1"].
-      getService(Ci.nsIMessageListenerManager);
-
-    gMessageManager.broadcastAsyncMessage("debug:setup-in-child", {
-      module: module,
-      setupChild: setupChild,
-      args: args,
+    this._childMessageManagers.forEach(mm => {
+      mm.sendAsyncMessage("debug:setup-in-child", {
+        module: module,
+        setupChild: setupChild,
+        args: args,
+      });
     });
   },
 
   /**
-   * In a content child process, ask the DebuggerServer in the parent process
-   * to execute a given module setup helper.
-   *
-   * @param module
-   *        The module to be required
-   * @param setupParent
-   *        The name of the setup helper exported by the above module
-   *        (setup helper signature: function ({mm}) { ... })
-   * @return boolean
-   *         true if the setup helper returned successfully
+   * Live list of all currenctly attached child's message managers.
    */
-  setupInParent: function({ module, setupParent }) {
-    if (!this.isInChildProcess) {
-      return false;
-    }
-
-    let { sendSyncMessage } = DebuggerServer.parentMessageManager;
-
-    return sendSyncMessage("debug:setup-in-parent", {
-      module: module,
-      setupParent: setupParent
-    });
-  },
+  _childMessageManagers: new Set(),
 
   /**
    * Connect to a child process.
    *
    * @param object aConnection
    *        The debugger server connection to use.
    * @param nsIDOMElement aFrame
    *        The browser element that holds the child process.
@@ -952,16 +930,17 @@ var DebuggerServer = {
    *         established.
    */
   connectToChild: function(aConnection, aFrame, aOnDestroy) {
     let deferred = defer();
 
     let mm = aFrame.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader
              .messageManager;
     mm.loadFrameScript("resource://gre/modules/devtools/server/child.js", false);
+    this._childMessageManagers.add(mm);
 
     let actor, childTransport;
     let prefix = aConnection.allocID("child");
     let netMonitor = null;
 
     // provides hook to actor modules that need to exchange messages
     // between e10s parent and child processes
     let onSetupInParent = function (msg) {
@@ -1057,16 +1036,18 @@ var DebuggerServer = {
 
       // Cleanup all listeners
       Services.obs.removeObserver(onMessageManagerClose, "message-manager-close");
       mm.removeMessageListener("debug:setup-in-parent", onSetupInParent);
       if (!actor) {
         mm.removeMessageListener("debug:actor", onActorCreated);
       }
       events.off(aConnection, "closed", destroy);
+
+      DebuggerServer._childMessageManagers.delete(mm);
     });
 
     // Listen for app process exit
     let onMessageManagerClose = function (subject, topic, data) {
       if (subject == mm) {
         destroy();
       }
     };
@@ -1328,16 +1309,23 @@ function DebuggerServerConnection(aPrefi
 
 DebuggerServerConnection.prototype = {
   _prefix: null,
   get prefix() { return this._prefix },
 
   _transport: null,
   get transport() { return this._transport },
 
+  /**
+   * Message manager used to communicate with the parent process,
+   * set by child.js. Is only defined for connections instantiated
+   * within a child process.
+   */
+  parentMessageManager: null,
+
   close: function() {
     this._transport.close();
   },
 
   send: function DSC_send(aPacket) {
     this.transport.send(aPacket);
   },
 
@@ -1716,10 +1704,35 @@ DebuggerServerConnection.prototype = {
 
   /*
    * Debugging helper for inspecting the state of an actor pool.
    */
   _dumpPool: function DSC_dumpPools(aPool) {
     dumpn("/-------------------- dumping pool:");
     dumpn("--------------------- actorPool actors: " +
           uneval(Object.keys(aPool._actors)));
-  }
+  },
+
+  /**
+   * In a content child process, ask the DebuggerServer in the parent process
+   * to execute a given module setup helper.
+   *
+   * @param module
+   *        The module to be required
+   * @param setupParent
+   *        The name of the setup helper exported by the above module
+   *        (setup helper signature: function ({mm}) { ... })
+   * @return boolean
+   *         true if the setup helper returned successfully
+   */
+  setupInParent: function({ conn, module, setupParent }) {
+    if (!this.parentMessageManager) {
+      return false;
+    }
+
+    let { sendSyncMessage } = this.parentMessageManager;
+
+    return sendSyncMessage("debug:setup-in-parent", {
+      module: module,
+      setupParent: setupParent
+    });
+  },
 };
--- a/toolkit/devtools/server/tests/mochitest/chrome.ini
+++ b/toolkit/devtools/server/tests/mochitest/chrome.ini
@@ -11,16 +11,18 @@ support-files =
   inspector-helpers.js
   inspector-styles-data.css
   inspector-styles-data.html
   inspector-traversal-data.html
   large-image.jpg
   memory-helpers.js
   nonchrome_unsafeDereference.html
   small-image.gif
+  setup-in-child.js
+  setup-in-parent.js
 
 [test_connection-manager.html]
 skip-if = buildapp == 'mulet'
 [test_connectToChild.html]
 skip-if = buildapp == 'mulet'
 [test_css-logic.html]
 [test_css-logic-inheritance.html]
 [test_css-logic-media-queries.html]
@@ -81,15 +83,16 @@ skip-if = buildapp == 'mulet'
 [test_memory_attach_02.html]
 [test_memory_census.html]
 [test_memory_gc_01.html]
 [test_memory_gc_events.html]
 [test_preference.html]
 [test_registerActor.html]
 [test_SaveHeapSnapshot.html]
 [test_settings.html]
+[test_setupInParentChild.html]
 [test_styles-applied.html]
 [test_styles-computed.html]
 [test_styles-layout.html]
 [test_styles-matched.html]
 [test_styles-modify.html]
 [test_styles-svg.html]
 [test_unsafeDereference.html]
new file mode 100644
--- /dev/null
+++ b/toolkit/devtools/server/tests/mochitest/setup-in-child.js
@@ -0,0 +1,20 @@
+const {Cc, Ci} = require("chrome");
+const cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"].
+  getService(Ci.nsIMessageListenerManager);
+const { DebuggerServer } = require("devtools/server/main");
+
+exports.setupChild = function (a, b, c) {
+  cpmm.sendAsyncMessage("test:setupChild", [a, b, c]);
+}
+
+exports.callParent = function () {
+  // Hack! Fetch DebuggerServerConnection objects directly within DebuggerServer guts.
+  for (let id in DebuggerServer._connections) {
+    let conn = DebuggerServer._connections[id];
+    conn.setupInParent({
+      module: "chrome://mochitests/content/chrome/toolkit/devtools/server/tests/mochitest/setup-in-parent.js",
+      setupParent: "setupParent",
+      args: [{one: true}, 2, "three"]
+    });
+  }
+}
new file mode 100644
--- /dev/null
+++ b/toolkit/devtools/server/tests/mochitest/setup-in-parent.js
@@ -0,0 +1,10 @@
+let {Ci} = require("chrome");
+let Services = require("Services");
+
+exports.setupParent = function ({mm, prefix}) {
+  let args = [
+    !!mm.QueryInterface(Ci.nsIMessageSender),
+    prefix
+  ];
+  Services.obs.notifyObservers(null, "test:setupParent", JSON.stringify(args));
+}
new file mode 100644
--- /dev/null
+++ b/toolkit/devtools/server/tests/mochitest/test_setupInParentChild.html
@@ -0,0 +1,109 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+Bug 1181100 - Test DebuggerServerConnection.setupInParent and DebuggerServer.setupInChild
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Mozilla Bug</title>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript;version=1.8">
+
+let Cu = Components.utils;
+let Cc = Components.classes;
+let Ci = Components.interfaces;
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/devtools/dbg-client.jsm");
+Cu.import("resource://gre/modules/devtools/dbg-server.jsm");
+
+window.onload = function() {
+  SimpleTest.waitForExplicitFinish();
+
+  SpecialPowers.pushPrefEnv({
+    "set": [
+      // Always log packets when running tests.
+      ["devtools.debugger.log", true],
+      ["dom.mozBrowserFramesEnabled", true]
+    ]
+  }, runTests);
+}
+
+function runTests() {
+  // Create a minimal iframe with a message manager
+  let iframe = document.createElement("iframe");
+  iframe.mozbrowser = true;
+  document.body.appendChild(iframe);
+
+  let mm = iframe.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.messageManager;
+
+  // Instantiate a minimal server
+  if (!DebuggerServer.initialized) {
+    DebuggerServer.init();
+  }
+  if (!DebuggerServer.createRootActor) {
+    DebuggerServer.addBrowserActors();
+  }
+
+  // Fake a connection to an iframe
+  let transport = DebuggerServer.connectPipe();
+  let conn = transport._serverConnection;
+  let client = new DebuggerClient(transport);
+
+  // Wait for a response from setupInChild
+  const ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
+                 .getService(Ci.nsIMessageListenerManager);
+  let onChild = msg => {
+    ppmm.removeMessageListener("test:setupChild", onChild);
+    let args = msg.json;
+
+    is(args[0], 1, "Got first numeric argument");
+    is(args[1], "two", "Got second string argument");
+    is(args[2].three, true, "Got last JSON argument");
+
+    // Ask the child to call setupInParent
+    DebuggerServer.setupInChild({
+      module: "chrome://mochitests/content/chrome/toolkit/devtools/server/tests/mochitest/setup-in-child.js",
+      setupChild: "callParent"
+    });
+  };
+  ppmm.addMessageListener("test:setupChild", onChild);
+
+  // Wait also for a reponse from setupInParent called from setup-in-child.js
+  let onParent = (_, topic, args) => {
+    Services.obs.removeObserver(onParent, "test:setupParent", false);
+    args = JSON.parse(args);
+
+    is(args[0], true, "Got `mm` argument, a message manager");
+    ok(args[1].match(/server\d+.conn\d+.child\d+/), "Got `prefix` argument");
+
+    cleanup();
+  };
+  Services.obs.addObserver(onParent, "test:setupParent", false);
+
+  // Instanciate e10s machinery and call setupInChild
+  DebuggerServer.connectToChild(conn, iframe).then(actor => {
+    DebuggerServer.setupInChild({
+      module: "chrome://mochitests/content/chrome/toolkit/devtools/server/tests/mochitest/setup-in-child.js",
+      setupChild: "setupChild",
+      args: [1, "two", {three: true}]
+    });
+  });
+
+  function cleanup() {
+    client.close(function () {
+      DebuggerServer.destroy();
+      iframe.remove();
+      SimpleTest.finish()
+    });
+  }
+
+}
+</script>
+</pre>
+</body>
+</html>
--- a/toolkit/devtools/server/tests/unit/head_dbg.js
+++ b/toolkit/devtools/server/tests/unit/head_dbg.js
@@ -313,16 +313,17 @@ function startTestDebuggerServer(title, 
   let client = new DebuggerClient(transport);
 
   return connect(client).then(() => client);
 }
 
 function finishClient(aClient)
 {
   aClient.close(function() {
+    DebuggerServer.destroy();
     do_test_finished();
   });
 }
 
 // Create a server, connect to it and fetch tab actors for the parent process;
 // pass |aCallback| the debugger client and tab actor form with all actor IDs.
 function get_chrome_actors(callback)
 {