Merge mozilla-central to mozilla-inbound
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Fri, 27 Nov 2015 11:11:01 +0100
changeset 308652 2c0df58d9443dec00c684b00b111dfaf96613997
parent 308651 f45e2942e1e1bed99c5332c98fcb31e3d901f044 (current diff)
parent 308566 47b49b0d32360fab04b11ff9120970979c426911 (diff)
child 308653 244c7dcd5a10301d82d1769eac44f32969409f87
push id5513
push userraliiev@mozilla.com
push dateMon, 25 Jan 2016 13:55:34 +0000
treeherdermozilla-beta@5ee97dd05b5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone45.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 mozilla-central to mozilla-inbound
--- a/b2g/config/aries/sources.xml
+++ b/b2g/config/aries/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="86959c405348d27ba5686956ae3a8ffc274d3db8"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="ee6d8625c9d76de2f6614c87bb82b301bc37c7a9"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ac7e9ae8a24ab4a3f3da801ca53f95f39a32b89f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="86959c405348d27ba5686956ae3a8ffc274d3db8"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="ee6d8625c9d76de2f6614c87bb82b301bc37c7a9"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ac7e9ae8a24ab4a3f3da801ca53f95f39a32b89f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was git://github.com/mozilla/-->
   <remote fetch="https://git.mozilla.org/b2g" name="mozilla"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gecko and Gaia -->
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="86959c405348d27ba5686956ae3a8ffc274d3db8"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="ee6d8625c9d76de2f6614c87bb82b301bc37c7a9"/>
   <!-- Gonk-specific things and forks -->
   <project name="platform_bionic" path="bionic" remote="b2g" revision="e2b3733ba3fa5e3f404e983d2e4142b1f6b1b846"/>
   <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="android-development" path="development" remote="b2g" revision="2bdf22305b523af644e1891b4ddfd9229336d0ce"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="660169a3d7e034a892359e39135e8c2785a6ad6f">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="86959c405348d27ba5686956ae3a8ffc274d3db8"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="ee6d8625c9d76de2f6614c87bb82b301bc37c7a9"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ac7e9ae8a24ab4a3f3da801ca53f95f39a32b89f"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="5de6856fad82857028f9f059f50680a9bea5b75c"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="86959c405348d27ba5686956ae3a8ffc274d3db8"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="ee6d8625c9d76de2f6614c87bb82b301bc37c7a9"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ac7e9ae8a24ab4a3f3da801ca53f95f39a32b89f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="5de6856fad82857028f9f059f50680a9bea5b75c"/>
@@ -127,15 +127,15 @@
   <default remote="caf" revision="refs/tags/android-4.4.2_r1" sync-j="4"/>
   <!-- Emulator specific things -->
   <project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="72ffdf71c68a96309212eb13d63560d66db14c9e"/>
   <project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="58800ecb50e4e41cfb0a36cb43c82b73fb3612e5"/>
   <project name="platform_bionic" path="bionic" remote="b2g" revision="3e85c4683c121530c1c3a48c696a569bf5f587e2"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="b2f83825411be614e8f7ec75fc731fc9c67a7078"/>
   <project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="f37bd545063039e30a92f2550ae78c0e6e4e2d08"/>
   <project name="platform_external_wpa_supplicant_8" path="external/wpa_supplicant_8" remote="b2g" revision="0c6a6547cd1fd302fa2b0f6e375654df36bf0ec4"/>
-  <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="29cbaa03a380ab69d47c476dd433059f7680837c"/>
+  <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d3ab8090c5c2ac77429575131c4718d96bfb93cc"/>
   <project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="5f4b68c799927b6e078f987b12722c3a6ccd4a45"/>
   <project name="platform/development" path="development" revision="5968ff4e13e0d696ad8d972281fc27ae5a12829b"/>
   <project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="6a1bb59af65b6485b1090522f66fac95c3f9e22c"/>
   <project name="android-sdk" path="sdk" remote="b2g" revision="0951179277915335251c5e11d242e4e1a8c2236f"/>
   <project name="darwinstreamingserver" path="system/darwinstreamingserver" remote="b2g" revision="cf85968c7f85e0ec36e72c87ceb4837a943b8af6"/>
 </manifest>
--- a/b2g/config/emulator-l/sources.xml
+++ b/b2g/config/emulator-l/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="86959c405348d27ba5686956ae3a8ffc274d3db8"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="ee6d8625c9d76de2f6614c87bb82b301bc37c7a9"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ac7e9ae8a24ab4a3f3da801ca53f95f39a32b89f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="5de6856fad82857028f9f059f50680a9bea5b75c"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was git://github.com/mozilla/-->
   <remote fetch="https://git.mozilla.org/b2g" name="mozilla"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gecko and Gaia -->
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="86959c405348d27ba5686956ae3a8ffc274d3db8"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="ee6d8625c9d76de2f6614c87bb82b301bc37c7a9"/>
   <!-- Gonk-specific things and forks -->
   <project name="platform_bionic" path="bionic" remote="b2g" revision="e2b3733ba3fa5e3f404e983d2e4142b1f6b1b846"/>
   <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="android-development" path="development" remote="b2g" revision="2bdf22305b523af644e1891b4ddfd9229336d0ce"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="86959c405348d27ba5686956ae3a8ffc274d3db8"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="ee6d8625c9d76de2f6614c87bb82b301bc37c7a9"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ac7e9ae8a24ab4a3f3da801ca53f95f39a32b89f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
-        "git_revision": "86959c405348d27ba5686956ae3a8ffc274d3db8", 
+        "git_revision": "ee6d8625c9d76de2f6614c87bb82b301bc37c7a9", 
         "remote": "https://git.mozilla.org/releases/gaia.git", 
         "branch": ""
     }, 
-    "revision": "eae17e983597fd71c6a396ed63031bb552753f41", 
+    "revision": "553d04c277d58581b55701f1978b82b257990a7e", 
     "repo_path": "integration/gaia-central"
 }
--- a/b2g/config/nexus-4-kk/sources.xml
+++ b/b2g/config/nexus-4-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="86959c405348d27ba5686956ae3a8ffc274d3db8"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="ee6d8625c9d76de2f6614c87bb82b301bc37c7a9"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ac7e9ae8a24ab4a3f3da801ca53f95f39a32b89f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -13,17 +13,17 @@
   <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="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="86959c405348d27ba5686956ae3a8ffc274d3db8"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="ee6d8625c9d76de2f6614c87bb82b301bc37c7a9"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ac7e9ae8a24ab4a3f3da801ca53f95f39a32b89f"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="5de6856fad82857028f9f059f50680a9bea5b75c"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
--- a/b2g/config/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="86959c405348d27ba5686956ae3a8ffc274d3db8"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="ee6d8625c9d76de2f6614c87bb82b301bc37c7a9"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9a58f2e395da17c252f61f28900b5b09aeb813bd"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ac7e9ae8a24ab4a3f3da801ca53f95f39a32b89f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
--- a/browser/components/feeds/FeedWriter.js
+++ b/browser/components/feeds/FeedWriter.js
@@ -641,18 +641,18 @@ FeedWriter.prototype = {
    *   @param aMenuItem
    *          The menuitem on which the attributes should be set
    *   @param aFile
    *          The menuitem's associated file
    */
   _initMenuItemWithFile: function(aMenuItem, aFile) {
     var label = this._getFileDisplayName(aFile);
     var image = this._getFileIconURL(aFile);
-    aMenuitem.setAttribute('label', label);
-    aMenuitem.setAttribute('image', image);
+    aMenuItem.setAttribute('label', label);
+    aMenuItem.setAttribute('image', image);
   },
 
   /**
    * Helper method to get an element in the XBL binding where the handler
    * selection UI lives
    */
   _getUIElement: function FW__getUIElement(id) {
     return this._document.getAnonymousElementByAttribute(
--- a/browser/components/sessionstore/ContentRestore.jsm
+++ b/browser/components/sessionstore/ContentRestore.jsm
@@ -3,17 +3,16 @@
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 this.EXPORTED_SYMBOLS = ["ContentRestore"];
 
 const Cu = Components.utils;
 const Ci = Components.interfaces;
-const Cr = Components.results;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
 
 XPCOMUtils.defineLazyModuleGetter(this, "DocShellCapabilities",
   "resource:///modules/sessionstore/DocShellCapabilities.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "FormData",
   "resource://gre/modules/FormData.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PageStyle",
@@ -178,29 +177,18 @@ ContentRestoreInternal.prototype = {
    */
   restoreTabContent: function (loadArguments, finishCallback) {
     let tabData = this._tabData;
     this._tabData = null;
 
     let webNavigation = this.docShell.QueryInterface(Ci.nsIWebNavigation);
     let history = webNavigation.sessionHistory;
 
-    // Wait for the tab load to complete or fail
-    this.restoreTabContentStarted((status) => {
-      // If loadArgument is not null then we're attempting to load a new url
-      // that required us to switch process. If that load is cancelled (for
-      // example by a content handler) we want to restore the current history
-      // entry.
-      if (loadArguments && (status == Cr.NS_BINDING_ABORTED)) {
-        this._tabData = tabData;
-        this.restoreTabContent(null, finishCallback);
-      } else {
-        finishCallback();
-      }
-    });
+    // Listen for the tab to finish loading.
+    this.restoreTabContentStarted(finishCallback);
 
     // Reset the current URI to about:blank. We changed it above for
     // switch-to-tab, but now it must go back to the correct value before the
     // load happens. Don't bother doing this if we're restoring immediately
     // due to a process switch.
     if (!loadArguments) {
       webNavigation.setCurrentURI(Utils.makeURI("about:blank"));
     }
@@ -255,36 +243,32 @@ ContentRestoreInternal.prototype = {
   },
 
   /**
    * To be called after restoreHistory(). Removes all listeners needed for
    * pending tabs and makes sure to notify when the tab finished loading.
    */
   restoreTabContentStarted(finishCallback) {
     // The reload listener is no longer needed.
-    if (this._historyListener) {
-      this._historyListener.uninstall();
-      this._historyListener = null;
-    }
+    this._historyListener.uninstall();
+    this._historyListener = null;
 
     // Remove the old progress listener.
-    if (this._progressListener) {
-      this._progressListener.uninstall();
-    }
+    this._progressListener.uninstall();
 
     // We're about to start a load. This listener will be called when the load
     // has finished getting everything from the network.
     this._progressListener = new ProgressListener(this.docShell, {
-      onStopRequest: (status) => {
+      onStopRequest: () => {
         // Call resetRestore() to reset the state back to normal. The data
         // needed for restoreDocument() (which hasn't happened yet) will
         // remain in _restoringDocument.
         this.resetRestore();
 
-        finishCallback(status);
+        finishCallback();
       }
     });
   },
 
   /**
    * Finish restoring the tab by filling in form data and setting the scroll
    * position. The restore is complete when this function exits. It should be
    * called when the "load" event fires for the restoring tab.
@@ -426,17 +410,17 @@ ProgressListener.prototype = {
       return;
     }
 
     if (stateFlags & STATE_START && this.callbacks.onStartRequest) {
       this.callbacks.onStartRequest();
     }
 
     if (stateFlags & STATE_STOP && this.callbacks.onStopRequest) {
-      this.callbacks.onStopRequest(status);
+      this.callbacks.onStopRequest();
     }
   },
 
   onLocationChange: function() {},
   onProgressChange: function() {},
   onStatusChange: function() {},
   onSecurityChange: function() {},
 };
--- a/browser/components/sessionstore/test/browser_switch_remoteness.js
+++ b/browser/components/sessionstore/test/browser_switch_remoteness.js
@@ -40,58 +40,8 @@ add_task(function* () {
 
   // Check that we didn't lose any shistory entries.
   count = yield countHistoryEntries(browser);
   is(count, MAX_BACK + 3, "correct number of shistory entries");
 
   // Cleanup.
   gBrowser.removeTab(tab);
 });
-
-add_task(function* () {
-  // Add a new non-remote tab.
-  let tab = gBrowser.addTab("about:robots");
-  let browser = tab.linkedBrowser;
-  yield promiseBrowserLoaded(browser);
-  ok(!browser.isRemoteBrowser, "browser is not remote");
-
-  // Wait for the tab to change to remote before adding the progress listener
-  tab.addEventListener("TabRemotenessChange", function listener() {
-    tab.removeEventListener("TabRemotenessChange", listener);
-
-    ContentTask.spawn(browser, URL, function*(url) {
-      Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-      let wp = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
-                       .getInterface(Ci.nsIWebProgress);
-
-      wp.addProgressListener({
-        onStateChange: function(progress, request, stateFlags, status) {
-          if (!(request instanceof Ci.nsIChannel))
-            return;
-
-          if (request.URI.spec == url) {
-            request.cancel(Cr.NS_BINDING_ABORTED);
-            wp.removeProgressListener(this);
-          }
-        },
-
-        QueryInterface: XPCOMUtils.generateQI([
-          Ci.nsIWebProgressListener,
-          Ci.nsISupportsWeakReference
-        ])
-      }, Ci.nsIWebProgress.NOTIFY_ALL);
-    });
-  });
-
-  // Load a new remote URI and when we see the load start cancel it
-  browser.loadURI(URL);
-  yield promiseTabRestored(tab);
-
-  let count = yield countHistoryEntries(browser);
-  is(count, 1, "Should only be the one history entry.");
-
-  is(browser.currentURI.spec, "about:robots", "Should be back to the original URI");
-  ok(!browser.isRemoteBrowser, "Should have gone back to a remote browser");
-
-  // Cleanup.
-  gBrowser.removeTab(tab);
-});
--- a/browser/themes/shared/devedition.inc.css
+++ b/browser/themes/shared/devedition.inc.css
@@ -192,17 +192,17 @@ toolbar[brighttext] #downloads-indicator
   color: var(--chrome-color) !important; /* Make sure that the brighttext attribute is added */
 }
 
 /* URL bar and search bar*/
 #urlbar,
 #navigator-toolbox .searchbar-textbox {
   background-color: var(--url-and-searchbar-background-color) !important;
   background-image: none !important;
-  color: inherit;
+  color: inherit !important;
   border: 1px solid var(--chrome-nav-bar-controls-border-color) !important;
   box-shadow: none !important;
 }
 
 #urlbar {
   -moz-border-start: none !important;
   opacity: 1 !important;
 }
--- a/devtools/client/inspector/inspector-panel.js
+++ b/devtools/client/inspector/inspector-panel.js
@@ -27,35 +27,31 @@ loader.lazyGetter(this, "toolboxStrings"
   return Services.strings.createBundle("chrome://devtools/locale/toolbox.properties");
 });
 loader.lazyGetter(this, "clipboardHelper", () => {
   return Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
 });
 
 loader.lazyImporter(this, "CommandUtils", "resource://devtools/client/shared/DeveloperToolbar.jsm");
 
-const LAYOUT_CHANGE_TIMER = 250;
-
 /**
  * Represents an open instance of the Inspector for a tab.
  * The inspector controls the breadcrumbs, the markup view, and the sidebar
  * (computed view, rule view, font view and layout view).
  *
  * Events:
  * - ready
  *      Fired when the inspector panel is opened for the first time and ready to
  *      use
  * - new-root
  *      Fired after a new root (navigation to a new page) event was fired by
  *      the walker, and taken into account by the inspector (after the markup
  *      view has been reloaded)
  * - markuploaded
  *      Fired when the markup-view frame has loaded
- * - layout-change
- *      Fired when the layout of the inspector changes
  * - breadcrumbs-updated
  *      Fired when the breadcrumb widget updates to a new node
  * - layoutview-updated
  *      Fired when the layoutview (box model) updates to a new node
  * - markupmutation
  *      Fired after markup mutations have been processed by the markup-view
  * - computed-view-refreshed
  *      Fired when the computed rules view updates to a new node
@@ -85,17 +81,16 @@ function InspectorPanel(iframeWindow, to
   this.onNewRoot = this.onNewRoot.bind(this);
   this._setupNodeMenu = this._setupNodeMenu.bind(this);
   this._resetNodeMenu = this._resetNodeMenu.bind(this);
   this._updateSearchResultsLabel = this._updateSearchResultsLabel.bind(this);
   this.onNewSelection = this.onNewSelection.bind(this);
   this.onBeforeNewSelection = this.onBeforeNewSelection.bind(this);
   this.onDetached = this.onDetached.bind(this);
   this.onToolboxHostChanged = this.onToolboxHostChanged.bind(this);
-  this.scheduleLayoutChange = this.scheduleLayoutChange.bind(this);
   this.onPaneToggleButtonClicked = this.onPaneToggleButtonClicked.bind(this);
   this._onMarkupFrameLoad = this._onMarkupFrameLoad.bind(this);
 
   this._target.on("will-navigate", this._onBeforeNavigate);
 
   EventEmitter.decorate(this);
 }
 
@@ -165,19 +160,16 @@ InspectorPanel.prototype = {
     this.selection.on("before-new-node-front", this.onBeforeNewSelection);
     this.selection.on("detached-front", this.onDetached);
 
     this.breadcrumbs = new HTMLBreadcrumbs(this);
 
     this._toolbox.on("host-changed", this.onToolboxHostChanged);
 
     if (this.target.isLocalTab) {
-      this.browser = this.target.tab.linkedBrowser;
-      this.browser.addEventListener("resize", this.scheduleLayoutChange, true);
-
       // Show a warning when the debugger is paused.
       // We show the warning only when the inspector
       // is selected.
       this.updateDebuggerPausedWarning = () => {
         let notificationBox = this._toolbox.getNotificationBox();
         let notification = notificationBox.getNotificationWithValue("inspector-script-paused");
         if (!notification && this._toolbox.currentToolId == "inspector" &&
             this.target.isThreadPaused) {
@@ -464,18 +456,16 @@ InspectorPanel.prototype = {
   /**
    * When a new node is selected.
    */
   onNewSelection: function(event, value, reason) {
     if (reason === "selection-destroy") {
       return;
     }
 
-    this.cancelLayoutChange();
-
     // Wait for all the known tools to finish updating and then let the
     // client know.
     let selection = this.selection.nodeFront;
 
     // On any new selection made by the user, store the unique css selector
     // of the selected node so it can be restored after reload of the same page
     if (this.canGetUniqueSelector &&
         this.selection.isElementNode()) {
@@ -565,17 +555,16 @@ InspectorPanel.prototype = {
   },
 
   /**
    * When a node is deleted, select its parent node or the defaultNode if no
    * parent is found (may happen when deleting an iframe inside which the
    * node was selected).
    */
   onDetached: function(event, parentNode) {
-    this.cancelLayoutChange();
     this.breadcrumbs.cutAfter(this.breadcrumbs.indexOf(parentNode));
     this.selection.setNodeFront(parentNode ? parentNode : this._defaultNode, "detached");
   },
 
   /**
    * Destroy the inspector.
    */
   destroy: function() {
@@ -584,22 +573,16 @@ InspectorPanel.prototype = {
     }
 
     if (this.walker) {
       this.walker.off("new-root", this.onNewRoot);
       this.pageStyle = null;
     }
 
     this.cancelUpdate();
-    this.cancelLayoutChange();
-
-    if (this.browser) {
-      this.browser.removeEventListener("resize", this.scheduleLayoutChange, true);
-      this.browser = null;
-    }
 
     this.target.off("will-navigate", this._onBeforeNavigate);
 
     this.target.off("thread-paused", this.updateDebuggerPausedWarning);
     this.target.off("thread-resumed", this.updateDebuggerPausedWarning);
     this._toolbox.off("select", this.updateDebuggerPausedWarning);
     this._toolbox.off("host-changed", this.onToolboxHostChanged);
 
@@ -1387,46 +1370,10 @@ InspectorPanel.prototype = {
    * This method is here for the benefit of copying links.
    */
   copyAttributeLink: function(link) {
     // When the inspector menu was setup on click (see _setupNodeLinkMenu), we
     // already checked that resolveRelativeURL existed.
     this.inspector.resolveRelativeURL(link, this.selection.nodeFront).then(url => {
       clipboardHelper.copyString(url);
     }, console.error);
-  },
-
-  /**
-   * Trigger a high-priority layout change for things that need to be
-   * updated immediately
-   */
-  immediateLayoutChange: function() {
-    this.emit("layout-change");
-  },
-
-  /**
-   * Schedule a low-priority change event for things like paint
-   * and resize.
-   */
-  scheduleLayoutChange: function(event) {
-    // Filter out non browser window resize events (i.e. triggered by iframes)
-    if (this.browser.contentWindow === event.target) {
-      if (this._timer) {
-        return null;
-      }
-      this._timer = this.panelWin.setTimeout(() => {
-        this.emit("layout-change");
-        this._timer = null;
-      }, LAYOUT_CHANGE_TIMER);
-    }
-  },
-
-  /**
-   * Cancel a pending low-priority change event if any is
-   * scheduled.
-   */
-  cancelLayoutChange: function() {
-    if (this._timer) {
-      this.panelWin.clearTimeout(this._timer);
-      delete this._timer;
-    }
   }
 };
--- a/devtools/client/markupview/markup-view.js
+++ b/devtools/client/markupview/markup-view.js
@@ -816,18 +816,16 @@ MarkupView.prototype = {
 
     return container;
   },
 
   /**
    * Mutation observer used for included nodes.
    */
   _mutationObserver: function(aMutations) {
-    let requiresLayoutChange = false;
-
     for (let mutation of aMutations) {
       let type = mutation.type;
       let target = mutation.target;
 
       if (mutation.type === "documentUnload") {
         // Treat this as a childList change of the child (maybe the protocol
         // should do this).
         type = "childList";
@@ -840,34 +838,26 @@ MarkupView.prototype = {
       let container = this.getContainer(target);
       if (!container) {
         // Container might not exist if this came from a load event for a node
         // we're not viewing.
         continue;
       }
       if (type === "attributes" || type === "characterData") {
         container.update();
-
-        // Auto refresh style properties on selected node when they change.
-        if (type === "attributes" && container.selected) {
-          requiresLayoutChange = true;
-        }
       } else if (type === "childList" || type === "nativeAnonymousChildList") {
         container.childrenDirty = true;
         // Update the children to take care of changes in the markup view DOM.
         this._updateChildren(container, {flash: true});
       } else if (type === "pseudoClassLock") {
         container.update();
       }
     }
 
-    if (requiresLayoutChange) {
-      this._inspector.immediateLayoutChange();
-    }
-    this._waitForChildren().then((nodes) => {
+    this._waitForChildren().then(() => {
       if (this._destroyer) {
         console.warn("Could not fully update after markup mutations, " +
           "the markup-view was destroyed while waiting for children.");
         return;
       }
       this._flashMutatedNodes(aMutations);
       this._inspector.emit("markupmutation", aMutations);
 
--- a/devtools/client/responsivedesign/test/browser.ini
+++ b/devtools/client/responsivedesign/test/browser.ini
@@ -2,16 +2,14 @@
 tags = devtools
 subsuite = devtools
 support-files =
   head.js
   touch.html
 
 [browser_responsive_cmd.js]
 [browser_responsivecomputedview.js]
-skip-if = e10s # Bug ??????
 [browser_responsiveruleview.js]
-skip-if = e10s # Bug ??????
 [browser_responsiveui.js]
 skip-if = e10s && os == 'win'
 [browser_responsiveui_touch.js]
 [browser_responsiveuiaddcustompreset.js]
 [browser_responsive_devicewidth.js]
--- a/devtools/client/responsivedesign/test/browser_responsivecomputedview.js
+++ b/devtools/client/responsivedesign/test/browser_responsivecomputedview.js
@@ -1,100 +1,66 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-function test() {
-  let instance;
-
-  let computedView;
-  let inspector;
+"use strict";
 
-  waitForExplicitFinish();
-  let mgr = ResponsiveUI.ResponsiveUIManager;
-
-  gBrowser.selectedTab = gBrowser.addTab();
-  gBrowser.selectedBrowser.addEventListener("load", function onload() {
-    gBrowser.selectedBrowser.removeEventListener("load", onload, true);
-    startTest();
-  }, true);
+// Check that when the viewport is resized, the computed-view refreshes.
 
-  content.location = "data:text/html;charset=utf-8,<html><style>" +
-    "div {" +
-    "  width: 500px;" +
-    "  height: 10px;" +
-    "  background: purple;" +
-    "} " +
-    "@media screen and (max-width: 200px) {" +
-    "  div { " +
-    "    width: 100px;" +
-    "  }" +
-    "};" +
-    "</style><div></div></html>"
+const TEST_URI = "data:text/html;charset=utf-8,<html><style>" +
+                 "div {" +
+                 "  width: 500px;" +
+                 "  height: 10px;" +
+                 "  background: purple;" +
+                 "} " +
+                 "@media screen and (max-width: 200px) {" +
+                 "  div { " +
+                 "    width: 100px;" +
+                 "  }" +
+                 "};" +
+                 "</style><div></div></html>";
 
-  function computedWidth() {
-    for (let prop of computedView.propertyViews) {
-      if (prop.name === "width") {
-        return prop.valueNode.textContent;
-      }
-    }
-    return null;
-  }
+add_task(function*() {
+  yield addTab(TEST_URI);
+
+  info("Open the responsive design mode and set its size to 500x500 to start");
+  let {rdm} = yield openRDM();
+  rdm.setSize(500, 500);
 
-  function startTest() {
-    document.getElementById("Tools:ResponsiveUI").doCommand();
-    executeSoon(onUIOpen);
-  }
+  info("Open the inspector, computed-view and select the test node");
+  let {inspector, view} = yield openComputedView();
+  yield selectNode("div", inspector);
 
-  function onUIOpen() {
-    instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
-    ok(instance, "instance of the module is attached to the tab.");
+  info("Try shrinking the viewport and checking the applied styles");
+  yield testShrink(view, inspector, rdm);
 
-    instance.stack.setAttribute("notransition", "true");
-    registerCleanupFunction(function() {
-      instance.stack.removeAttribute("notransition");
-    });
+  info("Try growing the viewport and checking the applied styles");
+  yield testGrow(view, inspector, rdm);
 
-    instance.setSize(500, 500);
-
-    openComputedView().then(onInspectorUIOpen);
-  }
+  gBrowser.removeCurrentTab();
+});
 
-  function onInspectorUIOpen(args) {
-    inspector = args.inspector;
-    computedView = args.view;
-    ok(inspector, "Got inspector instance");
-
-    let div = content.document.getElementsByTagName("div")[0];
+function* testShrink(computedView, inspector, rdm) {
+  is(computedWidth(computedView), "500px", "Should show 500px initially.");
 
-    inspector.selection.setNode(div);
-    inspector.once("inspector-updated", testShrink);
-  }
+  let onRefresh = inspector.once("computed-view-refreshed");
+  rdm.setSize(100, 100);
+  yield onRefresh;
 
-  function testShrink() {
-    is(computedWidth(), "500px", "Should show 500px initially.");
+  is(computedWidth(computedView), "100px", "Should be 100px after shrinking.");
+}
 
-    inspector.once("computed-view-refreshed", function onShrink() {
-      is(computedWidth(), "100px", "div should be 100px after shrinking.");
-      testGrow();
-    });
+function* testGrow(computedView, inspector, rdm) {
+  let onRefresh = inspector.once("computed-view-refreshed");
+  rdm.setSize(500, 500);
+  yield onRefresh;
 
-    instance.setSize(100, 100);
-  }
-
-  function testGrow() {
-    inspector.once("computed-view-refreshed", function onGrow() {
-      is(computedWidth(), "500px", "Should be 500px after growing.");
-      finishUp();
-    });
+  is(computedWidth(computedView), "500px", "Should be 500px after growing.");
+}
 
-    instance.setSize(500, 500);
+function computedWidth(computedView) {
+  for (let prop of computedView.propertyViews) {
+    if (prop.name === "width") {
+      return prop.valueNode.textContent;
+    }
   }
-
-  function finishUp() {
-    document.getElementById("Tools:ResponsiveUI").doCommand();
-
-    // Menus are correctly updated?
-    is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), "false", "menu unchecked");
-
-    gBrowser.removeCurrentTab();
-    finish();
-  }
+  return null;
 }
--- a/devtools/client/responsivedesign/test/browser_responsiveruleview.js
+++ b/devtools/client/responsivedesign/test/browser_responsiveruleview.js
@@ -1,107 +1,99 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-function test() {
-  let instance;
+"use strict";
+
+// Check that when the viewport is resized, the rule-view refreshes.
+// Also test that ESC does open the split-console, and that the RDM menu item
+// gets updated correctly when needed.
+// TODO: split this test.
 
-  let ruleView;
-  let inspector;
-  let mgr = ResponsiveUI.ResponsiveUIManager;
+const TEST_URI = "data:text/html;charset=utf-8,<html><style>" +
+                 "div {" +
+                 "  width: 500px;" +
+                 "  height: 10px;" +
+                 "  background: purple;" +
+                 "} " +
+                 "@media screen and (max-width: 200px) {" +
+                 "  div { " +
+                 "    width: 100px;" +
+                 "  }" +
+                 "};" +
+                 "</style><div></div></html>";
 
-  waitForExplicitFinish();
-
-  gBrowser.selectedTab = gBrowser.addTab();
-  gBrowser.selectedBrowser.addEventListener("load", startTest, true);
+add_task(function*() {
+  yield addTab(TEST_URI);
 
-  content.location = "data:text/html;charset=utf-8,<html><style>" +
-    "div {" +
-    "  width: 500px;" +
-    "  height: 10px;" +
-    "  background: purple;" +
-    "} " +
-    "@media screen and (max-width: 200px) {" +
-    "  div { " +
-    "    width: 100px;" +
-    "  }" +
-    "};" +
-    "</style><div></div></html>"
+  info("Open the responsive design mode and set its size to 500x500 to start");
+  let {rdm, manager} = yield openRDM();
+  rdm.setSize(500, 500);
 
-  function numberOfRules() {
-    return ruleView.element.querySelectorAll(".ruleview-code").length;
-  }
+  info("Open the inspector, rule-view and select the test node");
+  let {inspector, view} = yield openRuleView();
+  yield selectNode("div", inspector);
+
+  info("Try shrinking the viewport and checking the applied styles");
+  yield testShrink(view, rdm);
 
-  function startTest() {
-    gBrowser.selectedBrowser.removeEventListener("load", startTest, true);
-    document.getElementById("Tools:ResponsiveUI").doCommand();
-    executeSoon(onUIOpen);
-  }
+  info("Try growing the viewport and checking the applied styles");
+  yield testGrow(view, rdm);
 
-  function onUIOpen() {
-    instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
-    ok(instance, "instance of the module is attached to the tab.");
+  info("Check that ESC still opens the split console");
+  yield testEscapeOpensSplitConsole(inspector);
 
-    instance.stack.setAttribute("notransition", "true");
-    registerCleanupFunction(function() {
-      instance.stack.removeAttribute("notransition");
-    });
+  info("Test the state of the RDM menu item");
+  yield testMenuItem(manager);
 
-    instance.setSize(500, 500);
-
-    openRuleView().then(onInspectorUIOpen);
-  }
+  Services.prefs.clearUserPref("devtools.toolbox.splitconsoleEnabled");
+  gBrowser.removeCurrentTab();
+});
 
-  function onInspectorUIOpen(args) {
-    inspector = args.inspector;
-    ruleView = args.view;
-    ok(inspector, "Got inspector instance");
+function* testShrink(ruleView, rdm) {
+  is(numberOfRules(ruleView), 2, "Should have two rules initially.");
 
-    let div = content.document.getElementsByTagName("div")[0];
-    inspector.selection.setNode(div);
-    inspector.once("inspector-updated", testShrink);
-  }
+  info("Resize to 100x100 and wait for the rule-view to update");
+  let onRefresh = ruleView.once("ruleview-refreshed");
+  rdm.setSize(100, 100);
+  yield onRefresh;
+
+  is(numberOfRules(ruleView), 3, "Should have three rules after shrinking.");
+}
 
-  function testShrink() {
-
-    is(numberOfRules(), 2, "Should have two rules initially.");
+function* testGrow(ruleView, rdm) {
+  info("Resize to 500x500 and wait for the rule-view to update");
+  let onRefresh = ruleView.once("ruleview-refreshed");
+  rdm.setSize(500, 500);
+  yield onRefresh;
 
-    ruleView.on("ruleview-refreshed", function refresh() {
-      ruleView.off("ruleview-refreshed", refresh, false);
-      is(numberOfRules(), 3, "Should have three rules after shrinking.");
-      testGrow();
-    }, false);
+  is(numberOfRules(ruleView), 2, "Should have two rules after growing.");
+}
 
-    instance.setSize(100, 100);
-  }
+function* testEscapeOpensSplitConsole(inspector) {
+  ok(!inspector._toolbox._splitConsole, "Console is not split.");
 
-  function testGrow() {
-    ruleView.on("ruleview-refreshed", function refresh() {
-      ruleView.off("ruleview-refreshed", refresh, false);
-      is(numberOfRules(), 2, "Should have two rules after growing.");
-      testEscapeOpensSplitConsole();
-    }, false);
+  info("Press escape");
+  let onSplit = inspector._toolbox.once("split-console");
+  EventUtils.synthesizeKey("VK_ESCAPE", {});
+  yield onSplit;
 
-    instance.setSize(500, 500);
-  }
+  ok(inspector._toolbox._splitConsole, "Console is split after pressing ESC.");
+}
 
-  function testEscapeOpensSplitConsole() {
-    is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), "true", "menu checked");
-    ok(!inspector._toolbox._splitConsole, "Console is not split.");
+function* testMenuItem(manager) {
+  is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"),
+     "true",
+     "The menu item is checked");
 
-    inspector._toolbox.once("split-console", function() {
-      mgr.once("off", function() {executeSoon(finishUp)});
-      mgr.toggle(window, gBrowser.selectedTab);
-    });
-    EventUtils.synthesizeKey("VK_ESCAPE", {});
-  }
+  info("Toggle off the RDM");
+  let onManagerOff = manager.once("off");
+  manager.toggle(window, gBrowser.selectedTab);
+  yield onManagerOff;
 
-  function finishUp() {
-    ok(inspector._toolbox._splitConsole, "Console is split after pressing escape.");
-
-    // Menus are correctly updated?
-    is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), "false", "menu unchecked");
+  is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"),
+     "false",
+     "The menu item is unchecked");
+}
 
-    Services.prefs.clearUserPref("devtools.toolbox.splitconsoleEnabled");
-    gBrowser.removeCurrentTab();
-    finish();
-  }
+function numberOfRules(ruleView) {
+  return ruleView.element.querySelectorAll(".ruleview-code").length;
 }
--- a/devtools/client/responsivedesign/test/head.js
+++ b/devtools/client/responsivedesign/test/head.js
@@ -14,16 +14,36 @@ DevToolsUtils.testing = true;
 registerCleanupFunction(() => {
   DevToolsUtils.testing = false;
   while (gBrowser.tabs.length > 1) {
     gBrowser.removeCurrentTab();
   }
 });
 
 /**
+ * Open the Responsive Design Mode
+ * @param {Tab} The browser tab to open it into (defaults to the selected tab).
+ * @return {Promise} Resolves to the instance of the responsive design mode.
+ */
+function openRDM(tab = gBrowser.selectedTab) {
+  return new Promise(resolve => {
+    let manager = ResponsiveUI.ResponsiveUIManager;
+    document.getElementById("Tools:ResponsiveUI").doCommand();
+    executeSoon(() => {
+      let rdm = manager.getResponsiveUIForTab(tab);
+      rdm.stack.setAttribute("notransition", "true");
+      registerCleanupFunction(function() {
+        rdm.stack.removeAttribute("notransition");
+      });
+      resolve({rdm, manager});
+    });
+  });
+}
+
+/**
  * Open the toolbox, with the inspector tool visible.
  * @return a promise that resolves when the inspector is ready
  */
 var openInspector = Task.async(function*() {
   info("Opening the inspector");
   let target = TargetFactory.forTab(gBrowser.selectedTab);
 
   let inspector, toolbox;
@@ -120,17 +140,16 @@ function openComputedView() {
  * sidebar tab selected.
  * @return a promise that resolves when the inspector is ready and the rule
  * view is visible and ready
  */
 function openRuleView() {
   return openInspectorSideBar("ruleview");
 }
 
-
 /**
  * Add a new test tab in the browser and load the given url.
  * @param {String} url The url to be loaded in the new tab
  * @return a promise that resolves to the tab object when the url is loaded
  */
 var addTab = Task.async(function* (url) {
   info("Adding a new tab with URL: '" + url + "'");
 
@@ -211,8 +230,41 @@ function waitForDocLoadComplete(aBrowser
     },
     QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
                                            Ci.nsISupportsWeakReference])
   };
   aBrowser.addProgressListener(progressListener);
   info("Waiting for browser load");
   return deferred.promise;
 }
+
+/**
+ * Get the NodeFront for a node that matches a given css selector, via the
+ * protocol.
+ * @param {String|NodeFront} selector
+ * @param {InspectorPanel} inspector The instance of InspectorPanel currently
+ * loaded in the toolbox
+ * @return {Promise} Resolves to the NodeFront instance
+ */
+function getNodeFront(selector, {walker}) {
+  if (selector._form) {
+    return selector;
+  }
+  return walker.querySelector(walker.rootNode, selector);
+}
+
+/**
+ * Set the inspector's current selection to the first match of the given css
+ * selector
+ * @param {String|NodeFront} selector
+ * @param {InspectorPanel} inspector The instance of InspectorPanel currently
+ * loaded in the toolbox
+ * @param {String} reason Defaults to "test" which instructs the inspector not
+ * to highlight the node upon selection
+ * @return {Promise} Resolves when the inspector is updated with the new node
+ */
+var selectNode = Task.async(function*(selector, inspector, reason = "test") {
+  info("Selecting the node for '" + selector + "'");
+  let nodeFront = yield getNodeFront(selector, inspector);
+  let updated = inspector.once("inspector-updated");
+  inspector.selection.setNodeFront(nodeFront, reason);
+  yield updated;
+});
--- a/devtools/client/styleinspector/style-inspector.js
+++ b/devtools/client/styleinspector/style-inspector.js
@@ -1,17 +1,17 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* 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/. */
 
 "use strict";
 
-const {Cc, Cu, Ci} = require("chrome");
+const {Cu} = require("chrome");
 const promise = require("promise");
 const {Tools} = require("devtools/client/main");
 Cu.import("resource://gre/modules/Services.jsm");
 const {PREF_ORIG_SOURCES} = require("devtools/client/styleeditor/utils");
 
 loader.lazyGetter(this, "gDevTools", () =>
   Cu.import("resource://devtools/client/framework/gDevTools.jsm", {}).gDevTools);
 loader.lazyGetter(this, "RuleView",
@@ -32,28 +32,31 @@ function RuleViewTool(inspector, window)
 
   this.onLinkClicked = this.onLinkClicked.bind(this);
   this.onSelected = this.onSelected.bind(this);
   this.refresh = this.refresh.bind(this);
   this.clearUserProperties = this.clearUserProperties.bind(this);
   this.onPropertyChanged = this.onPropertyChanged.bind(this);
   this.onViewRefreshed = this.onViewRefreshed.bind(this);
   this.onPanelSelected = this.onPanelSelected.bind(this);
+  this.onMutations = this.onMutations.bind(this);
+  this.onResized = this.onResized.bind(this);
 
   this.view.on("ruleview-changed", this.onPropertyChanged);
   this.view.on("ruleview-refreshed", this.onViewRefreshed);
   this.view.on("ruleview-linked-clicked", this.onLinkClicked);
 
   this.inspector.selection.on("detached", this.onSelected);
   this.inspector.selection.on("new-node-front", this.onSelected);
-  this.inspector.on("layout-change", this.refresh);
   this.inspector.selection.on("pseudoclass", this.refresh);
   this.inspector.target.on("navigate", this.clearUserProperties);
   this.inspector.sidebar.on("ruleview-selected", this.onPanelSelected);
   this.inspector.pageStyle.on("stylesheet-updated", this.refresh);
+  this.inspector.walker.on("mutations", this.onMutations);
+  this.inspector.walker.on("resize", this.onResized);
 
   this.onSelected();
 }
 
 RuleViewTool.prototype = {
   isSidebarActive: function() {
     if (!this.view) {
       return false;
@@ -142,18 +145,42 @@ RuleViewTool.prototype = {
   onPropertyChanged: function() {
     this.inspector.markDirty();
   },
 
   onViewRefreshed: function() {
     this.inspector.emit("rule-view-refreshed");
   },
 
+  /**
+   * When markup mutations occur, if an attribute of the selected node changes,
+   * we need to refresh the view as that might change the node's styles.
+   */
+  onMutations: function(mutations) {
+    for (let {type, target} of mutations) {
+      if (target === this.inspector.selection.nodeFront &&
+          type === "attributes") {
+        this.refresh();
+        break;
+      }
+    }
+  },
+
+  /**
+   * When the window gets resized, this may cause media-queries to match, and
+   * therefore, different styles may apply.
+   */
+  onResized: function() {
+    this.refresh();
+  },
+
   destroy: function() {
-    this.inspector.off("layout-change", this.refresh);
+    this.inspector.walker.off("mutations", this.onMutations);
+    this.inspector.walker.off("resize", this.onResized);
+    this.inspector.selection.off("detached", this.onSelected);
     this.inspector.selection.off("pseudoclass", this.refresh);
     this.inspector.selection.off("new-node-front", this.onSelected);
     this.inspector.target.off("navigate", this.clearUserProperties);
     this.inspector.sidebar.off("ruleview-selected", this.onPanelSelected);
     if (this.inspector.pageStyle) {
       this.inspector.pageStyle.off("stylesheet-updated", this.refresh);
     }
 
@@ -172,23 +199,26 @@ function ComputedViewTool(inspector, win
   this.document = window.document;
 
   this.view = new ComputedView.CssComputedView(this.inspector, this.document,
                                                this.inspector.pageStyle);
 
   this.onSelected = this.onSelected.bind(this);
   this.refresh = this.refresh.bind(this);
   this.onPanelSelected = this.onPanelSelected.bind(this);
+  this.onMutations = this.onMutations.bind(this);
+  this.onResized = this.onResized.bind(this);
 
   this.inspector.selection.on("detached", this.onSelected);
   this.inspector.selection.on("new-node-front", this.onSelected);
-  this.inspector.on("layout-change", this.refresh);
   this.inspector.selection.on("pseudoclass", this.refresh);
   this.inspector.sidebar.on("computedview-selected", this.onPanelSelected);
   this.inspector.pageStyle.on("stylesheet-updated", this.refresh);
+  this.inspector.walker.on("mutations", this.onMutations);
+  this.inspector.walker.on("resize", this.onResized);
 
   this.view.selectElement(null);
 
   this.onSelected();
 }
 
 ComputedViewTool.prototype = {
   isSidebarActive: function() {
@@ -238,21 +268,45 @@ ComputedViewTool.prototype = {
   onPanelSelected: function() {
     if (this.inspector.selection.nodeFront === this.view.viewedElement) {
       this.refresh();
     } else {
       this.onSelected();
     }
   },
 
+  /**
+   * When markup mutations occur, if an attribute of the selected node changes,
+   * we need to refresh the view as that might change the node's styles.
+   */
+  onMutations: function(mutations) {
+    for (let {type, target} of mutations) {
+      if (target === this.inspector.selection.nodeFront &&
+          type === "attributes") {
+        this.refresh();
+        break;
+      }
+    }
+  },
+
+  /**
+   * When the window gets resized, this may cause media-queries to match, and
+   * therefore, different styles may apply.
+   */
+  onResized: function() {
+    this.refresh();
+  },
+
   destroy: function() {
-    this.inspector.off("layout-change", this.refresh);
+    this.inspector.walker.off("mutations", this.onMutations);
+    this.inspector.walker.off("resize", this.onResized);
     this.inspector.sidebar.off("computedview-selected", this.refresh);
     this.inspector.selection.off("pseudoclass", this.refresh);
     this.inspector.selection.off("new-node-front", this.onSelected);
+    this.inspector.selection.off("detached", this.onSelected);
     this.inspector.sidebar.off("computedview-selected", this.onPanelSelected);
     if (this.inspector.pageStyle) {
       this.inspector.pageStyle.off("stylesheet-updated", this.refresh);
     }
 
     this.view.destroy();
 
     this.view = this.document = this.inspector = null;
--- a/devtools/server/actors/inspector.js
+++ b/devtools/server/actors/inspector.js
@@ -1263,39 +1263,46 @@ var traversalMethod = {
 
 /**
  * Server side of the DOM walker.
  */
 var WalkerActor = protocol.ActorClass({
   typeName: "domwalker",
 
   events: {
-    "new-mutations" : {
+    "new-mutations": {
       type: "newMutations"
     },
-    "picker-node-picked" : {
+    "picker-node-picked": {
       type: "pickerNodePicked",
       node: Arg(0, "disconnectedNode")
     },
-    "picker-node-hovered" : {
+    "picker-node-hovered": {
       type: "pickerNodeHovered",
       node: Arg(0, "disconnectedNode")
     },
-    "picker-node-canceled" : {
+    "picker-node-canceled": {
       type: "pickerNodeCanceled"
     },
-    "highlighter-ready" : {
+    "highlighter-ready": {
       type: "highlighter-ready"
     },
-    "highlighter-hide" : {
+    "highlighter-hide": {
       type: "highlighter-hide"
     },
-    "display-change" : {
+    "display-change": {
       type: "display-change",
       nodes: Arg(0, "array:domnode")
+    },
+    // The walker actor emits a useful "resize" event to its front to let
+    // clients know when the browser window gets resized. This may be useful
+    // for refreshing a DOM node's styles for example, since those may depend on
+    // media-queries.
+    "resize": {
+      type: "resize"
     }
   },
 
   /**
    * Create the WalkerActor
    * @param DebuggerServerConnection conn
    *    The server connection.
    */
@@ -1327,19 +1334,21 @@ var WalkerActor = protocol.ActorClass({
 
     events.on(tabActor, "will-navigate", this.onFrameUnload);
     events.on(tabActor, "navigate", this.onFrameLoad);
 
     // Ensure that the root document node actor is ready and
     // managed.
     this.rootNode = this.document();
 
-    this.reflowObserver = getLayoutChangesObserver(this.tabActor);
+    this.layoutChangeObserver = getLayoutChangesObserver(this.tabActor);
     this._onReflows = this._onReflows.bind(this);
-    this.reflowObserver.on("reflows", this._onReflows);
+    this.layoutChangeObserver.on("reflows", this._onReflows);
+    this._onResize = this._onResize.bind(this);
+    this.layoutChangeObserver.on("resize", this._onResize);
   },
 
   // Returns the JSON representation of this object over the wire.
   form: function() {
     return {
       actor: this.actorID,
       root: this.rootNode.form(),
       traits: {
@@ -1390,19 +1399,20 @@ var WalkerActor = protocol.ActorClass({
 
       events.off(this.tabActor, "will-navigate", this.onFrameUnload);
       events.off(this.tabActor, "navigate", this.onFrameLoad);
 
       this.onFrameLoad = null;
       this.onFrameUnload = null;
 
       this.walkerSearch.destroy();
-      this.reflowObserver.off("reflows", this._onReflows);
-      this.reflowObserver = null;
-      this._onReflows = null;
+
+      this.layoutChangeObserver.off("reflows", this._onReflows);
+      this.layoutChangeObserver.off("resize", this._onResize);
+      this.layoutChangeObserver = null;
       releaseLayoutChangesObserver(this.tabActor);
 
       this.onMutations = null;
 
       this.tabActor = null;
 
       events.emit(this, "destroyed");
     } catch(e) {
@@ -1463,16 +1473,23 @@ var WalkerActor = protocol.ActorClass({
     }
 
     if (changes.length) {
       events.emit(this, "display-change", changes);
     }
   },
 
   /**
+   * When the browser window gets resized, relay the event to the front.
+   */
+  _onResize: function() {
+    events.emit(this, "resize");
+  },
+
+  /**
    * This is kept for backward-compatibility reasons with older remote targets.
    * Targets prior to bug 916443.
    *
    * pick/cancelPick are used to pick a node on click on the content
    * document. But in their implementation prior to bug 916443, they don't allow
    * highlighting on hover.
    * The client-side now uses the highlighter actor's pick and cancelPick
    * methods instead. The client-side uses the the highlightable trait found in
@@ -3682,23 +3699,25 @@ var AttributeModificationList = Class({
 })
 
 /**
  * Server side of the inspector actor, which is used to create
  * inspector-related actors, including the walker.
  */
 var InspectorActor = exports.InspectorActor = protocol.ActorClass({
   typeName: "inspector",
+
   initialize: function(conn, tabActor) {
     protocol.Actor.prototype.initialize.call(this, conn);
     this.tabActor = tabActor;
   },
 
   destroy: function () {
     protocol.Actor.prototype.destroy.call(this);
+
     this._highlighterPromise = null;
     this._pageStylePromise = null;
     this._walkerPromise = null;
     this.walker = null;
     this.tabActor = null;
   },
 
   // Forces destruction of the actor and all its children
--- a/devtools/server/actors/layout.js
+++ b/devtools/server/actors/layout.js
@@ -6,33 +6,33 @@
 
 /**
  * About the types of objects in this file:
  *
  * - ReflowActor: the actor class used for protocol purposes.
  *   Mostly empty, just gets an instance of LayoutChangesObserver and forwards
  *   its "reflows" events to clients.
  *
- * - Observable: A utility parent class, meant at being extended by classes that
- *   need a start/stop behavior.
- *
  * - LayoutChangesObserver: extends Observable and uses the ReflowObserver, to
  *   track reflows on the page.
  *   Used by the LayoutActor, but is also exported on the module, so can be used
  *   by any other actor that needs it.
  *
+ * - Observable: A utility parent class, meant at being extended by classes that
+ *   need a to observe something on the tabActor's windows.
+ *
  * - Dedicated observers: There's only one of them for now: ReflowObserver which
  *   listens to reflow events via the docshell,
  *   These dedicated classes are used by the LayoutChangesObserver.
  */
 
 const {Ci, Cu} = require("chrome");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 const protocol = require("devtools/server/protocol");
-const {method, Arg, RetVal, types} = protocol;
+const {method, Arg} = protocol;
 const events = require("sdk/event/core");
 const Heritage = require("sdk/core/heritage");
 const {setTimeout, clearTimeout} = require("sdk/timers");
 const EventEmitter = require("devtools/shared/event-emitter");
 
 /**
  * The reflow actor tracks reflows and emits events about them.
  */
@@ -43,35 +43,35 @@ var ReflowActor = exports.ReflowActor = 
     /**
      * The reflows event is emitted when reflows have been detected. The event
      * is sent with an array of reflows that occured. Each item has the
      * following properties:
      * - start {Number}
      * - end {Number}
      * - isInterruptible {Boolean}
      */
-    "reflows" : {
+    "reflows": {
       type: "reflows",
       reflows: Arg(0, "array:json")
     }
   },
 
   initialize: function(conn, tabActor) {
     protocol.Actor.prototype.initialize.call(this, conn);
 
     this.tabActor = tabActor;
     this._onReflow = this._onReflow.bind(this);
     this.observer = getLayoutChangesObserver(tabActor);
     this._isStarted = false;
   },
 
   /**
-   * The reflow actor is the first (and last) in its hierarchy to use protocol.js
-   * so it doesn't have a parent protocol actor that takes care of its lifetime.
-   * So it needs a disconnect method to cleanup.
+   * The reflow actor is the first (and last) in its hierarchy to use
+   * protocol.js so it doesn't have a parent protocol actor that takes care of
+   * its lifetime. So it needs a disconnect method to cleanup.
    */
   disconnect: function() {
     this.destroy();
   },
 
   destroy: function() {
     this.stop();
     releaseLayoutChangesObserver(this.tabActor);
@@ -127,73 +127,108 @@ exports.ReflowFront = protocol.FrontClas
   },
 
   destroy: function() {
     protocol.Front.prototype.destroy.call(this);
   },
 });
 
 /**
- * Base class for all sorts of observers we need to create for a given window.
+ * Base class for all sorts of observers that need to listen to events on the
+ * tabActor's windows.
  * @param {TabActor} tabActor
  * @param {Function} callback Executed everytime the observer observes something
  */
 function Observable(tabActor, callback) {
   this.tabActor = tabActor;
   this.callback = callback;
+
+  this._onWindowReady = this._onWindowReady.bind(this);
+  this._onWindowDestroyed = this._onWindowDestroyed.bind(this);
+
+  events.on(this.tabActor, "window-ready", this._onWindowReady);
+  events.on(this.tabActor, "window-destroyed", this._onWindowDestroyed);
 }
 
 Observable.prototype = {
   /**
    * Is the observer currently observing
    */
-  observing: false,
+  isObserving: false,
+
+  /**
+   * Stop observing and detroy this observer instance
+   */
+  destroy: function() {
+    if (this.isDestroyed) {
+      return;
+    }
+    this.isDestroyed = true;
+
+    this.stop();
+
+    events.off(this.tabActor, "window-ready", this._onWindowReady);
+    events.off(this.tabActor, "window-destroyed", this._onWindowDestroyed);
+
+    this.callback = null;
+    this.tabActor = null;
+  },
 
   /**
    * Start observing whatever it is this observer is supposed to observe
    */
   start: function() {
-    if (!this.observing) {
-      this._start();
-      this.observing = true;
+    if (this.isObserving) {
+      return;
     }
-  },
+    this.isObserving = true;
 
-  _start: function() {
-    /* To be implemented by sub-classes */
+    this._startListeners(this.tabActor.windows);
   },
 
   /**
    * Stop observing
    */
   stop: function() {
-    if (this.observing) {
-      this._stop();
-      this.observing = false;
+    if (!this.isObserving) {
+      return;
+    }
+    this.isObserving = false;
+
+    if (this.tabActor.attached && this.tabActor.docShell) {
+      // It's only worth stopping if the tabActor is still attached
+      this._stopListeners(this.tabActor.windows);
     }
   },
 
-  _stop: function() {
-    /* To be implemented by sub-classes */
+  _onWindowReady: function({window}) {
+    if (this.isObserving) {
+      this._startListeners([window]);
+    }
+  },
+
+  _onWindowDestroyed: function({window}) {
+    if (this.isObserving) {
+      this._stopListeners([window]);
+    }
+  },
+
+  _startListeners: function(windows) {
+    // To be implemented by sub-classes.
+  },
+
+  _stopListeners: function(windows) {
+    // To be implemented by sub-classes.
   },
 
   /**
    * To be called by sub-classes when something has been observed
    */
   notifyCallback: function(...args) {
-    this.observing && this.callback && this.callback.apply(null, args);
-  },
-
-  /**
-   * Stop observing and detroy this observer instance
-   */
-  destroy: function() {
-    this.stop();
-    this.callback = null;
-    this.tabActor = null;
+    this.isObserving && this.callback && this.callback.apply(null, args);
   }
 };
 
 /**
  * The LayouChangesObserver will observe reflows as soon as it is started.
  * Some devtools actors may cause reflows and it may be wanted to "hide" these
  * reflows from the LayouChangesObserver consumers.
  * If this is the case, such actors should require this module and use this
@@ -207,17 +242,17 @@ Observable.prototype = {
  * @param {DOMNode} syncReflowNode The node to use to force a sync reflow
  */
 var gIgnoreLayoutChanges = false;
 exports.setIgnoreLayoutChanges = function(ignore, syncReflowNode) {
   if (syncReflowNode) {
     let forceSyncReflow = syncReflowNode.offsetWidth;
   }
   gIgnoreLayoutChanges = ignore;
-}
+};
 
 /**
  * The LayoutChangesObserver class is instantiated only once per given tab
  * and is used to track reflows and dom and style changes in that tab.
  * The LayoutActor uses this class to send reflow events to its clients.
  *
  * This class isn't exported on the module because it shouldn't be instantiated
  * to avoid creating several instances per tabs.
@@ -225,85 +260,118 @@ exports.setIgnoreLayoutChanges = functio
  * and `releaseLayoutChangesObserver(tabActor)`
  * which are exported to get and release instances.
  *
  * The observer loops every EVENT_BATCHING_DELAY ms and checks if layout changes
  * have happened since the last loop iteration. If there are, it sends the
  * corresponding events:
  *
  * - "reflows", with an array of all the reflows that occured,
+ * - "resizes", with an array of all the resizes that occured,
  *
  * @param {TabActor} tabActor
  */
 function LayoutChangesObserver(tabActor) {
-  Observable.call(this, tabActor);
+  this.tabActor = tabActor;
 
   this._startEventLoop = this._startEventLoop.bind(this);
+  this._onReflow = this._onReflow.bind(this);
+  this._onResize = this._onResize.bind(this);
 
   // Creating the various observers we're going to need
   // For now, just the reflow observer, but later we can add markupMutation,
   // styleSheetChanges and styleRuleChanges
-  this._onReflow = this._onReflow.bind(this);
   this.reflowObserver = new ReflowObserver(this.tabActor, this._onReflow);
+  this.resizeObserver = new WindowResizeObserver(this.tabActor, this._onResize);
 
   EventEmitter.decorate(this);
 }
 
 exports.LayoutChangesObserver = LayoutChangesObserver;
 
-LayoutChangesObserver.prototype = Heritage.extend(Observable.prototype, {
+LayoutChangesObserver.prototype = {
   /**
-   * How long does this observer waits before emitting a batched reflows event.
+   * How long does this observer waits before emitting batched events.
    * The lower the value, the more event packets will be sent to clients,
    * potentially impacting performance.
    * The higher the value, the more time we'll wait, this is better for
    * performance but has an effect on how soon changes are shown in the toolbox.
    */
   EVENT_BATCHING_DELAY: 300,
 
   /**
    * Destroying this instance of LayoutChangesObserver will stop the batched
    * events from being sent.
    */
   destroy: function() {
+    this.isObserving = false;
+
     this.reflowObserver.destroy();
     this.reflows = null;
 
-    Observable.prototype.destroy.call(this);
+    this.resizeObserver.destroy();
+    this.hasResized = false;
+
+    this.tabActor = null;
   },
 
-  _start: function() {
+  start: function() {
+    if (this.isObserving) {
+      return;
+    }
+    this.isObserving = true;
+
     this.reflows = [];
+    this.hasResized = false;
+
     this._startEventLoop();
+
     this.reflowObserver.start();
+    this.resizeObserver.start();
   },
 
-  _stop: function() {
+  stop: function() {
+    if (!this.isObserving) {
+      return;
+    }
+    this.isObserving = false;
+
     this._stopEventLoop();
+
     this.reflows = [];
+    this.hasResized = false;
+
     this.reflowObserver.stop();
+    this.resizeObserver.stop();
   },
 
   /**
    * Start the event loop, which regularly checks if there are any observer
    * events to be sent as batched events
    * Calls itself in a loop.
    */
   _startEventLoop: function() {
     // Avoid emitting events if the tabActor has been detached (may happen
     // during shutdown)
-    if (!this.tabActor.attached) {
+    if (!this.tabActor || !this.tabActor.attached) {
       return;
     }
 
     // Send any reflows we have
     if (this.reflows && this.reflows.length) {
       this.emit("reflows", this.reflows);
       this.reflows = [];
     }
+
+    // Send any resizes we have
+    if (this.hasResized) {
+      this.emit("resize");
+      this.hasResized = false;
+    }
+
     this.eventLoopTimer = this._setTimeout(this._startEventLoop,
       this.EVENT_BATCHING_DELAY);
   },
 
   _stopEventLoop: function() {
     this._clearTimeout(this.eventLoopTimer);
   },
 
@@ -330,18 +398,31 @@ LayoutChangesObserver.prototype = Herita
 
     // XXX: when/if bug 997092 gets fixed, we will be able to know which
     // elements have been reflowed, which would be a nice thing to add here.
     this.reflows.push({
       start: start,
       end: end,
       isInterruptible: isInterruptible
     });
+  },
+
+  /**
+   * Executed whenever a resize is observed. Only store a flag saying that a
+   * resize occured.
+   * The EVENT_BATCHING_DELAY loop will take care of it later.
+   */
+  _onResize: function() {
+    if (gIgnoreLayoutChanges) {
+      return;
+    }
+
+    this.hasResized = true;
   }
-});
+};
 
 /**
  * Get a LayoutChangesObserver instance for a given window. This function makes
  * sure there is only one instance per window.
  * @param {TabActor} tabActor
  * @return {LayoutChangesObserver}
  */
 var observedWindows = new Map();
@@ -350,22 +431,23 @@ function getLayoutChangesObserver(tabAct
   if (observerData) {
     observerData.refCounting ++;
     return observerData.observer;
   }
 
   let obs = new LayoutChangesObserver(tabActor);
   observedWindows.set(tabActor, {
     observer: obs,
-    refCounting: 1 // counting references allows to stop the observer when no
-                   // tabActor owns an instance
+    // counting references allows to stop the observer when no tabActor owns an
+    // instance.
+    refCounting: 1
   });
   obs.start();
   return obs;
-};
+}
 exports.getLayoutChangesObserver = getLayoutChangesObserver;
 
 /**
  * Release a LayoutChangesObserver instance that was retrieved by
  * getLayoutChangesObserver. This is required to ensure the tabActor reference
  * is removed and the observer is eventually stopped and destroyed.
  * @param {TabActor} tabActor
  */
@@ -375,95 +457,94 @@ function releaseLayoutChangesObserver(ta
     return;
   }
 
   observerData.refCounting --;
   if (!observerData.refCounting) {
     observerData.observer.destroy();
     observedWindows.delete(tabActor);
   }
-};
+}
 exports.releaseLayoutChangesObserver = releaseLayoutChangesObserver;
 
 /**
- * Instantiate and start a reflow observer on a given window's document element.
- * Will report any reflow that occurs in this window's docshell.
+ * Reports any reflow that occurs in the tabActor's docshells.
  * @extends Observable
  * @param {TabActor} tabActor
  * @param {Function} callback Executed everytime a reflow occurs
  */
 function ReflowObserver(tabActor, callback) {
   Observable.call(this, tabActor, callback);
-
-  this._onWindowReady = this._onWindowReady.bind(this);
-  events.on(this.tabActor, "window-ready", this._onWindowReady);
-  this._onWindowDestroyed = this._onWindowDestroyed.bind(this);
-  events.on(this.tabActor, "window-destroyed", this._onWindowDestroyed);
 }
 
 ReflowObserver.prototype = Heritage.extend(Observable.prototype, {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIReflowObserver,
     Ci.nsISupportsWeakReference]),
 
-  _onWindowReady: function({window}) {
-    if (this.observing) {
-      this._startListeners([window]);
-    }
-  },
-
-  _onWindowDestroyed: function({window}) {
-    if (this.observing) {
-      this._stopListeners([window]);
-    }
-  },
-
-  _start: function() {
-    this._startListeners(this.tabActor.windows);
-  },
-
-  _stop: function() {
-    if (this.tabActor.attached && this.tabActor.docShell) {
-      // It's only worth stopping if the tabActor is still attached
-      this._stopListeners(this.tabActor.windows);
-    }
-  },
-
   _startListeners: function(windows) {
     for (let window of windows) {
       let docshell = window.QueryInterface(Ci.nsIInterfaceRequestor)
                      .getInterface(Ci.nsIWebNavigation)
                      .QueryInterface(Ci.nsIDocShell);
       docshell.addWeakReflowObserver(this);
     }
   },
 
   _stopListeners: function(windows) {
     for (let window of windows) {
-      // Corner cases where a global has already been freed may happen, in which
-      // case, no need to remove the observer
       try {
         let docshell = window.QueryInterface(Ci.nsIInterfaceRequestor)
                        .getInterface(Ci.nsIWebNavigation)
                        .QueryInterface(Ci.nsIDocShell);
         docshell.removeWeakReflowObserver(this);
-      } catch (e) {}
+      } catch (e) {
+        // Corner cases where a global has already been freed may happen, in
+        // which case, no need to remove the observer.
+      }
     }
   },
 
   reflow: function(start, end) {
     this.notifyCallback(start, end, false);
   },
 
   reflowInterruptible: function(start, end) {
     this.notifyCallback(start, end, true);
+  }
+});
+
+/**
+ * Reports window resize events on the tabActor's windows.
+ * @extends Observable
+ * @param {TabActor} tabActor
+ * @param {Function} callback Executed everytime a resize occurs
+ */
+function WindowResizeObserver(tabActor, callback) {
+  Observable.call(this, tabActor, callback);
+  this.onResize = this.onResize.bind(this);
+}
+
+WindowResizeObserver.prototype = Heritage.extend(Observable.prototype, {
+  _startListeners: function() {
+    this.listenerTarget.addEventListener("resize", this.onResize);
   },
 
-  destroy: function() {
-    if (this._isDestroyed) {
-      return;
+  _stopListeners: function() {
+    this.listenerTarget.removeEventListener("resize", this.onResize);
+  },
+
+  onResize: function() {
+    this.notifyCallback();
+  },
+
+  get listenerTarget() {
+    // For the rootActor, return its window.
+    if (this.tabActor.isRootActor) {
+      return this.tabActor.window;
     }
-    this._isDestroyed = true;
 
-    events.off(this.tabActor, "window-ready", this._onWindowReady);
-    events.off(this.tabActor, "window-destroyed", this._onWindowDestroyed);
-    Observable.prototype.destroy.call(this);
+    // Otherwise, get the tabActor's chromeEventHandler.
+    return this.tabActor.window.QueryInterface(Ci.nsIInterfaceRequestor)
+                               .getInterface(Ci.nsIWebNavigation)
+                               .QueryInterface(Ci.nsIDocShell)
+                               .chromeEventHandler;
   }
 });
--- a/devtools/server/tests/mochitest/chrome.ini
+++ b/devtools/server/tests/mochitest/chrome.ini
@@ -71,16 +71,17 @@ skip-if = buildapp == 'mulet'
 [test_inspector-mutations-attr.html]
 [test_inspector-mutations-childlist.html]
 [test_inspector-mutations-frameload.html]
 [test_inspector-mutations-value.html]
 [test_inspector-pseudoclass-lock.html]
 [test_inspector-release.html]
 [test_inspector-reload.html]
 [test_inspector-remove.html]
+[test_inspector-resize.html]
 [test_inspector-resolve-url.html]
 [test_inspector-retain.html]
 [test_inspector-search.html]
 [test_inspector-search-front.html]
 [test_inspector-scroll-into-view.html]
 [test_inspector-traversal.html]
 [test_makeGlobalObjectReference.html]
 [test_memory.html]
new file mode 100644
--- /dev/null
+++ b/devtools/server/tests/mochitest/test_inspector-resize.html
@@ -0,0 +1,80 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+Test that the inspector actor emits "resize" events when the page is resized.
+https://bugzilla.mozilla.org/show_bug.cgi?id=1222409
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 1222409</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">
+  <script type="application/javascript;version=1.8" src="inspector-helpers.js"></script>
+  <script type="application/javascript;version=1.8">
+window.onload = function() {
+  const Cu = Components.utils;
+  Cu.import("resource://gre/modules/devtools/Loader.jsm");
+  const {Promise: promise} =
+    Cu.import("resource://gre/modules/Promise.jsm", {});
+  const {InspectorFront} =
+    devtools.require("devtools/server/actors/inspector");
+  const {console} =
+    Cu.import("resource://gre/modules/devtools/shared/Console.jsm", {});
+
+  SimpleTest.waitForExplicitFinish();
+
+  let win = null;
+  let inspector = null;
+
+  addAsyncTest(function* setup() {
+    info ("Setting up inspector and walker actors.");
+
+    let url = document.getElementById("inspectorContent").href;
+
+    yield new Promise(resolve => {
+      attachURL(url, function(err, client, tab, doc) {
+        win = doc.defaultView;
+        inspector = InspectorFront(client, tab);
+        resolve();
+      });
+    });
+
+    runNextTest();
+  });
+
+  addAsyncTest(function*() {
+    let walker = yield inspector.getWalker();
+
+    // We can't receive events from the walker if we haven't first executed a
+    // method on the actor to initialize it.
+    yield walker.querySelector(walker.rootNode, "img");
+
+    let {outerWidth, outerHeight} = win;
+    let onResize = new Promise(resolve => {
+      walker.once("resize", () => {
+        resolve();
+      });
+    });
+    win.resizeTo(800, 600);
+    yield onResize;
+
+    ok(true, "The resize event was emitted");
+    win.resizeTo(outerWidth, outerHeight);
+
+    runNextTest();
+  });
+
+  runNextTest();
+};
+  </script>
+</head>
+<body>
+<a id="inspectorContent" target="_blank" href="inspector-search-data.html">Test Document</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
--- a/devtools/server/tests/unit/test_layout-reflows-observer.js
+++ b/devtools/server/tests/unit/test_layout-reflows-observer.js
@@ -51,17 +51,36 @@ MockWindow.prototype = {
 
 function MockDocShell() {
   this.observer = null;
 }
 MockDocShell.prototype = {
   addWeakReflowObserver: function(observer) {
     this.observer = observer;
   },
-  removeWeakReflowObserver: function(observer) {}
+  removeWeakReflowObserver: function() {},
+  get chromeEventHandler() {
+    return {
+      addEventListener: (type, cb) => {
+        if (type === "resize") {
+          this.resizeCb = cb;
+        }
+      },
+      removeEventListener: (type, cb) => {
+        if (type === "resize" && cb === this.resizeCb) {
+          this.resizeCb = null;
+        }
+      }
+    };
+  },
+  mockResize: function() {
+    if (this.resizeCb) {
+      this.resizeCb();
+    }
+  }
 };
 
 function run_test() {
   instancesOfObserversAreSharedBetweenWindows();
   eventsAreBatched();
   noEventsAreSentWhenThereAreNoReflowsAndLoopTimeouts();
   observerIsAlreadyStarted();
   destroyStopsObserving();
@@ -105,32 +124,45 @@ function eventsAreBatched() {
   // manually
   let tabActor = new MockTabActor();
   let observer = getLayoutChangesObserver(tabActor);
 
   let reflowsEvents = [];
   let onReflows = (event, reflows) => reflowsEvents.push(reflows);
   observer.on("reflows", onReflows);
 
+  let resizeEvents = [];
+  let onResize = () => resizeEvents.push("resize");
+  observer.on("resize", onResize);
+
   do_print("Fake one reflow event");
   tabActor.window.docShell.observer.reflow();
   do_print("Checking that no batched reflow event has been emitted");
   do_check_eq(reflowsEvents.length, 0);
 
   do_print("Fake another reflow event");
   tabActor.window.docShell.observer.reflow();
   do_print("Checking that still no batched reflow event has been emitted");
   do_check_eq(reflowsEvents.length, 0);
 
-  do_print("Faking timeout expiration and checking that reflow events are sent");
+  do_print("Fake a few of resize events too");
+  tabActor.window.docShell.mockResize();
+  tabActor.window.docShell.mockResize();
+  tabActor.window.docShell.mockResize();
+  do_print("Checking that still no batched resize event has been emitted");
+  do_check_eq(resizeEvents.length, 0);
+
+  do_print("Faking timeout expiration and checking that events are sent");
   observer.eventLoopTimer();
   do_check_eq(reflowsEvents.length, 1);
   do_check_eq(reflowsEvents[0].length, 2);
+  do_check_eq(resizeEvents.length, 1);
 
   observer.off("reflows", onReflows);
+  observer.off("resize", onResize);
   releaseLayoutChangesObserver(tabActor);
 }
 
 function noEventsAreSentWhenThereAreNoReflowsAndLoopTimeouts() {
  do_print("Checking that if no reflows were detected and the event batching " +
   "loop expires, then no reflows event is sent");
 
   let tabActor = new MockTabActor();
@@ -148,59 +180,59 @@ function noEventsAreSentWhenThereAreNoRe
   releaseLayoutChangesObserver(tabActor);
 }
 
 function observerIsAlreadyStarted() {
   do_print("Checking that the observer is already started when getting it");
 
   let tabActor = new MockTabActor();
   let observer = getLayoutChangesObserver(tabActor);
-  do_check_true(observer.observing);
+  do_check_true(observer.isObserving);
 
   observer.stop();
-  do_check_false(observer.observing);
+  do_check_false(observer.isObserving);
 
   observer.start();
-  do_check_true(observer.observing);
+  do_check_true(observer.isObserving);
 
   releaseLayoutChangesObserver(tabActor);
 }
 
 function destroyStopsObserving() {
   do_print("Checking that the destroying the observer stops it");
 
   let tabActor = new MockTabActor();
   let observer = getLayoutChangesObserver(tabActor);
-  do_check_true(observer.observing);
+  do_check_true(observer.isObserving);
 
   observer.destroy();
-  do_check_false(observer.observing);
+  do_check_false(observer.isObserving);
 
   releaseLayoutChangesObserver(tabActor);
 }
 
 function stoppingAndStartingSeveralTimesWorksCorrectly() {
   do_print("Checking that the stopping and starting several times the observer" +
     " works correctly");
 
   let tabActor = new MockTabActor();
   let observer = getLayoutChangesObserver(tabActor);
 
-  do_check_true(observer.observing);
+  do_check_true(observer.isObserving);
   observer.start();
   observer.start();
   observer.start();
-  do_check_true(observer.observing);
+  do_check_true(observer.isObserving);
 
   observer.stop();
-  do_check_false(observer.observing);
+  do_check_false(observer.isObserving);
 
   observer.stop();
   observer.stop();
-  do_check_false(observer.observing);
+  do_check_false(observer.isObserving);
 
   releaseLayoutChangesObserver(tabActor);
 }
 
 function reflowsArentStackedWhenStopped() {
   do_print("Checking that when stopped, reflows aren't stacked in the observer");
 
   let tabActor = new MockTabActor();
--- a/dom/bluetooth/common/webapi/BluetoothMapRequestHandle.cpp
+++ b/dom/bluetooth/common/webapi/BluetoothMapRequestHandle.cpp
@@ -61,30 +61,18 @@ BluetoothMapRequestHandle::ReplyToFolder
   NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
 
   BluetoothService* bs = BluetoothService::Get();
   if (!bs) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  if (XRE_GetProcessType() == GeckoProcessType_Default) {
-    // In-process reply
-    bs->ReplyToMapFolderListing(aMasId, aFolderlists,
-      new BluetoothVoidReplyRunnable(nullptr, promise));
-  } else {
-    ContentChild *cc = ContentChild::GetSingleton();
-    if (!cc) {
-      aRv.Throw(NS_ERROR_FAILURE);
-      return nullptr;
-    }
-
-    bs->ReplyToMapFolderListing(aMasId, aFolderlists,
-      new BluetoothVoidReplyRunnable(nullptr, promise));
-  }
+  bs->ReplyToMapFolderListing(aMasId, aFolderlists,
+    new BluetoothVoidReplyRunnable(nullptr, promise));
 
   return promise.forget();
 }
 
 already_AddRefed<Promise>
 BluetoothMapRequestHandle::ReplyToMessagesListing(long aMasId,
                                                   Blob& aBlob,
                                                   bool aNewMessage,
--- a/dom/telephony/test/marionette/manifest.ini
+++ b/dom/telephony/test/marionette/manifest.ini
@@ -43,16 +43,17 @@ disabled = Bug 1214537
 [test_mmi_change_pin.js]
 [test_mmi_change_pin2.js]
 [test_mmi_clip.js]
 [test_mmi_clir.js]
 [test_mmi_imei.js]
 [test_mmi_unlock_puk.js]
 [test_mmi_unlock_puk2.js]
 [test_mmi_ussd.js]
+skip-if = android_version < '19'
 [test_modem_switch_tech.js]
 [test_multiple_hold.js]
 [test_outgoing_already_held.js]
 [test_outgoing_answer_hangup_oncallschanged.js]
 [test_outgoing_answer_radio_off.js]
 [test_outgoing_auto_hold.js]
 [test_outgoing_badNumber.js]
 [test_outgoing_busy.js]
--- a/dom/telephony/test/marionette/test_mmi_ussd.js
+++ b/dom/telephony/test/marionette/test_mmi_ussd.js
@@ -3,21 +3,19 @@
 
 MARIONETTE_TIMEOUT = 60000;
 MARIONETTE_HEAD_JS = "head.js";
 
 function testUSSD() {
   log("Test *#1234# ...");
 
   return gSendMMI("*#1234#").then(aResult => {
-    // Since emulator doesn't support sending USSD, so we expect the result is
-    // always failed.
-    ok(!aResult.success, "Check success");
+    ok(aResult.success, "Check success");
     is(aResult.serviceCode, "scUssd", "Check serviceCode");
-    is(aResult.statusMessage, "RequestNotSupported", "Check statusMessage");
+    is(aResult.statusMessage, "", "Check statusMessage");
     is(aResult.additionalInformation, undefined, "No additional information");
   });
 }
 
 // Start test
 startTest(function() {
   return testUSSD()
     .catch(error => ok(false, "Promise reject: " + error))
--- a/mobile/android/base/gfx/LayerView.java
+++ b/mobile/android/base/gfx/LayerView.java
@@ -7,16 +7,17 @@ package org.mozilla.gecko.gfx;
 
 import java.nio.ByteBuffer;
 import java.nio.IntBuffer;
 import java.util.ArrayList;
 
 import org.mozilla.gecko.AndroidGamepadManager;
 import org.mozilla.gecko.annotation.RobocopTarget;
 import org.mozilla.gecko.annotation.WrapForJNI;
+import org.mozilla.gecko.AppConstants;
 import org.mozilla.gecko.AppConstants.Versions;
 import org.mozilla.gecko.EventDispatcher;
 import org.mozilla.gecko.GeckoAccessibility;
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.GeckoEvent;
 import org.mozilla.gecko.PrefsHelper;
 import org.mozilla.gecko.Tab;
 import org.mozilla.gecko.Tabs;
@@ -246,16 +247,20 @@ public class LayerView extends ScrollVie
     public boolean onHoverEvent(MotionEvent event) {
         // If we get a touchscreen hover event, and accessibility is not enabled,
         // don't send it to gecko.
         if (event.getSource() == InputDevice.SOURCE_TOUCHSCREEN &&
             !GeckoAccessibility.isEnabled()) {
             return false;
         }
 
+        if (AppConstants.MOZ_ANDROID_APZ && mPanZoomController != null && mPanZoomController.onTouchEvent(event)) {
+            return true;
+        }
+
         return sendEventToGecko(event);
     }
 
     @Override
     public boolean onGenericMotionEvent(MotionEvent event) {
         if (AndroidGamepadManager.handleMotionEvent(event)) {
             return true;
         }
--- a/toolkit/components/telemetry/TelemetryEnvironment.jsm
+++ b/toolkit/components/telemetry/TelemetryEnvironment.jsm
@@ -169,16 +169,17 @@ const PREF_PARTNER_ID = "mozilla.partner
 const PREF_UPDATE_ENABLED = "app.update.enabled";
 const PREF_UPDATE_AUTODOWNLOAD = "app.update.auto";
 const PREF_SEARCH_COHORT = "browser.search.cohort";
 
 const EXPERIMENTS_CHANGED_TOPIC = "experiments-changed";
 const SEARCH_ENGINE_MODIFIED_TOPIC = "browser-search-engine-modified";
 const SEARCH_SERVICE_TOPIC = "browser-search-service";
 const COMPOSITOR_CREATED_TOPIC = "compositor:created";
+const DISTRIBUTION_CUSTOMIZATION_COMPLETE_TOPIC = "distribution-customization-complete";
 
 /**
  * Get the current browser.
  * @return a string with the locale or null on failure.
  */
 function getBrowserLocale() {
   try {
     return Cc["@mozilla.org/chrome/chrome-registry;1"].
@@ -678,16 +679,17 @@ function EnvironmentCache() {
     build: this._getBuild(),
     partner: this._getPartner(),
     system: this._getSystem(),
   };
 
   this._updateSettings();
   // Fill in the default search engine, if the search provider is already initialized.
   this._updateSearchEngine();
+  this._addObservers();
 
   // Build the remaining asynchronous parts of the environment. Don't register change listeners
   // until the initial environment has been built.
 
   let p = [];
   if (AppConstants.platform === "gonk") {
     this._addonBuilder = {
       watchForChanges: function() {}
@@ -701,17 +703,16 @@ function EnvironmentCache() {
     this._currentEnvironment.profile = {};
     p.push(this._updateProfile());
   }
 
   let setup = () => {
     this._initTask = null;
     this._startWatchingPrefs();
     this._addonBuilder.watchForChanges();
-    this._addObservers();
     this._updateGraphicsFeatures();
     return this.currentEnvironment;
   };
 
   this._initTask = Promise.all(p)
     .then(
       () => setup(),
       (err) => {
@@ -842,23 +843,27 @@ EnvironmentCache.prototype = {
     }
   },
 
   _addObservers: function () {
     // Watch the search engine change and service topics.
     Services.obs.addObserver(this, SEARCH_ENGINE_MODIFIED_TOPIC, false);
     Services.obs.addObserver(this, SEARCH_SERVICE_TOPIC, false);
     Services.obs.addObserver(this, COMPOSITOR_CREATED_TOPIC, false);
+    Services.obs.addObserver(this, DISTRIBUTION_CUSTOMIZATION_COMPLETE_TOPIC, false);
   },
 
   _removeObservers: function () {
     // Remove the search engine change and service observers.
     Services.obs.removeObserver(this, SEARCH_ENGINE_MODIFIED_TOPIC);
     Services.obs.removeObserver(this, SEARCH_SERVICE_TOPIC);
     Services.obs.removeObserver(this, COMPOSITOR_CREATED_TOPIC);
+    try {
+      Services.obs.removeObserver(this, DISTRIBUTION_CUSTOMIZATION_COMPLETE_TOPIC);
+    } catch(ex) {};
   },
 
   observe: function (aSubject, aTopic, aData) {
     this._log.trace("observe - aTopic: " + aTopic + ", aData: " + aData);
     switch (aTopic) {
       case SEARCH_ENGINE_MODIFIED_TOPIC:
         if (aData != "engine-default" && aData != "engine-current") {
           return;
@@ -874,16 +879,22 @@ EnvironmentCache.prototype = {
         this._updateSearchEngine();
         break;
       case COMPOSITOR_CREATED_TOPIC:
         // Full graphics information is not available until we have created at
         // least one off-main-thread-composited window. Thus we wait for the
         // first compositor to be created and then query nsIGfxInfo again.
         this._updateGraphicsFeatures();
         break;
+      case DISTRIBUTION_CUSTOMIZATION_COMPLETE_TOPIC:
+        // Distribution customizations are applied after final-ui-startup. query
+        // partner prefs again when they are ready.
+        this._updatePartner();
+        Services.obs.removeObserver(this, aTopic);
+        break;
     }
   },
 
   /**
    * Get the default search engine.
    * @return {String} Returns the search engine identifier, "NONE" if no default search
    *         engine is defined or "UNDEFINED" if no engine identifier or name can be found.
    */
@@ -954,16 +965,23 @@ EnvironmentCache.prototype = {
       let gfxInfo = Cc["@mozilla.org/gfx/info;1"].getService(Ci.nsIGfxInfo);
       gfxData.features = gfxInfo.getFeatures();
     } catch (e) {
       this._log.error("nsIGfxInfo.getFeatures() caught error", e);
     }
   },
 
   /**
+   * Update the partner prefs.
+   */
+  _updatePartner: function() {
+    this._currentEnvironment.partner = this._getPartner();
+  },
+
+  /**
    * Get the build data in object form.
    * @return Object containing the build data.
    */
   _getBuild: function () {
     let buildData = {
       applicationId: Services.appinfo.ID || null,
       applicationName: Services.appinfo.name || null,
       architecture: Services.sysinfo.get("arch"),
--- a/toolkit/components/telemetry/docs/environment.rst
+++ b/toolkit/components/telemetry/docs/environment.rst
@@ -58,17 +58,17 @@ Structure::
           "pref.name.url": "<user-set>" // For some privacy-sensitive prefs
             // only the fact that the value has been changed is recorded
         },
       },
       profile: { // This section is not available on Android.
         creationDate: <integer>, // integer days since UNIX epoch, e.g. 16446
         resetDate: <integer>, // integer days since UNIX epoch, e.g. 16446 - optional
       },
-      partner: {
+      partner: { // This section may not be immediately available on startup
         distributionId: <string>, // pref "distribution.id", null on failure
         distributionVersion: <string>, // pref "distribution.version", null on failure
         partnerId: <string>, // pref mozilla.partner.id, null on failure
         distributor: <string>, // pref app.distributor, null on failure
         distributorChannel: <string>, // pref app.distributor.channel, null on failure
         partnerNames: [
           // list from prefs app.partner.<name>=<name>
         ],
@@ -295,12 +295,17 @@ The following is a partial list of colle
 - ``browser.search.suggest.enabled``: The "master switch" for search suggestions everywhere in Firefox (search bar, urlbar, etc.). Defaults to true.
 
 - ``browser.urlbar.suggest.searches``: True if search suggestions are enabled in the urlbar. Defaults to false.
 
 - ``browser.urlbar.unifiedcomplete``: True if the urlbar's UnifiedComplete back-end is enabled.
 
 - ``browser.urlbar.userMadeSearchSuggestionsChoice``: True if the user has clicked Yes or No in the urlbar's opt-in notification. Defaults to false.
 
+partner
+~~~~~~~
+
+If the user is using a partner repack, this contains information identifying the repack being used, otherwise "partnerNames" will be an empty array and other entries will be null. The information may be missing when the profile just becomes available. In Firefox for desktop, the information along with other customizations defined in distribution.ini are processed later in the startup phase, and will be fully applied when "distribution-customization-complete" notification is sent.
+
 activeAddons
 ~~~~~~~~~~~~
 
 Starting from Firefox 44, the length of the following string fields: ``name``, ``description`` and ``version`` is limited to 100 characters. The same limitation applies to the same fields in ``theme`` and ``activePlugins``.
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryEnvironment.js
@@ -35,16 +35,17 @@ const APP_NAME = "XPCShell";
 const APP_HOTFIX_VERSION = "2.3.4a";
 
 const DISTRIBUTION_ID = "distributor-id";
 const DISTRIBUTION_VERSION = "4.5.6b";
 const DISTRIBUTOR_NAME = "Some Distributor";
 const DISTRIBUTOR_CHANNEL = "A Channel";
 const PARTNER_NAME = "test";
 const PARTNER_ID = "NicePartner-ID-3785";
+const DISTRIBUTION_CUSTOMIZATION_COMPLETE_TOPIC = "distribution-customization-complete";
 
 const GFX_VENDOR_ID = "0xabcd";
 const GFX_DEVICE_ID = "0x1234";
 
 // The profile reset date, in milliseconds (Today)
 const PROFILE_RESET_DATE_MS = Date.now();
 // The profile creation date, in milliseconds (Yesterday).
 const PROFILE_CREATION_DATE_MS = PROFILE_RESET_DATE_MS - MILLISECONDS_PER_DAY;
@@ -298,34 +299,39 @@ function checkProfileSection(data) {
     return;
   }
 
   Assert.ok("profile" in data, "There must be a profile section in Environment.");
   Assert.equal(data.profile.creationDate, truncateToDays(PROFILE_CREATION_DATE_MS));
   Assert.equal(data.profile.resetDate, truncateToDays(PROFILE_RESET_DATE_MS));
 }
 
-function checkPartnerSection(data) {
+function checkPartnerSection(data, isInitial) {
   const EXPECTED_FIELDS = {
     distributionId: DISTRIBUTION_ID,
     distributionVersion: DISTRIBUTION_VERSION,
     partnerId: PARTNER_ID,
     distributor: DISTRIBUTOR_NAME,
     distributorChannel: DISTRIBUTOR_CHANNEL,
   };
 
   Assert.ok("partner" in data, "There must be a partner section in Environment.");
 
   for (let f in EXPECTED_FIELDS) {
-    Assert.equal(data.partner[f], EXPECTED_FIELDS[f], f + " must have the correct value.");
+    let expected = isInitial ? null : EXPECTED_FIELDS[f];
+    Assert.strictEqual(data.partner[f], expected, f + " must have the correct value.");
   }
 
   // Check that "partnerNames" exists and contains the correct element.
   Assert.ok(Array.isArray(data.partner.partnerNames));
-  Assert.ok(data.partner.partnerNames.indexOf(PARTNER_NAME) >= 0);
+  if (isInitial) {
+    Assert.equal(data.partner.partnerNames.length, 0);
+  } else {
+    Assert.ok(data.partner.partnerNames.indexOf(PARTNER_NAME) >= 0);
+  }
 }
 
 function checkGfxAdapter(data) {
   const EXPECTED_ADAPTER_FIELDS_TYPES = {
     description: "string",
     vendorID: "string",
     deviceID: "string",
     subsysID: "string",
@@ -606,21 +612,21 @@ function checkAddonsSection(data) {
     Assert.ok(checkString(experiment.id));
     Assert.ok(checkString(experiment.branch));
   }
 
   // Check persona
   Assert.ok(checkNullOrString(data.addons.persona));
 }
 
-function checkEnvironmentData(data) {
+function checkEnvironmentData(data, isInitial = false) {
   checkBuildSection(data);
   checkSettingsSection(data);
   checkProfileSection(data);
-  checkPartnerSection(data);
+  checkPartnerSection(data, isInitial);
   checkSystemSection(data);
   checkAddonsSection(data);
 }
 
 function run_test() {
   // Load a custom manifest to provide search engine loading from JAR files.
   do_load_manifest("chrome.manifest");
   do_test_pending();
@@ -640,17 +646,16 @@ function run_test() {
   gHttpServer = new HttpServer();
   gHttpServer.start(-1);
   let port = gHttpServer.identity.primaryPort;
   gHttpRoot = "http://localhost:" + port + "/";
   gDataRoot = gHttpRoot + "data/";
   gHttpServer.registerDirectory("/data/", do_get_cwd());
   do_register_cleanup(() => gHttpServer.stop(() => {}));
 
-  spoofPartnerInfo();
   // Spoof the the hotfixVersion
   Preferences.set("extensions.hotfix.lastVersion", APP_HOTFIX_VERSION);
 
   run_next_test();
 }
 
 function isRejected(promise) {
   return new Promise((resolve, reject) => {
@@ -659,16 +664,22 @@ function isRejected(promise) {
 }
 
 add_task(function* asyncSetup() {
   yield spoofProfileReset();
 });
 
 add_task(function* test_checkEnvironment() {
   let environmentData = yield TelemetryEnvironment.onInitialized();
+  checkEnvironmentData(environmentData, true);
+
+  spoofPartnerInfo();
+  Services.obs.notifyObservers(null, DISTRIBUTION_CUSTOMIZATION_COMPLETE_TOPIC, null);
+
+  environmentData = TelemetryEnvironment.currentEnvironment;
   checkEnvironmentData(environmentData);
 });
 
 add_task(function* test_prefWatchPolicies() {
   const PREF_TEST_1 = "toolkit.telemetry.test.pref_new";
   const PREF_TEST_2 = "toolkit.telemetry.test.pref1";
   const PREF_TEST_3 = "toolkit.telemetry.test.pref2";
   const PREF_TEST_4 = "toolkit.telemetry.test.pref_old";
--- a/widget/android/AndroidJavaWrappers.cpp
+++ b/widget/android/AndroidJavaWrappers.cpp
@@ -679,25 +679,40 @@ AndroidGeckoEvent::MakeTouchEvent(nsIWid
 MultiTouchInput
 AndroidGeckoEvent::MakeMultiTouchInput(nsIWidget* widget)
 {
     MultiTouchInput::MultiTouchType type = (MultiTouchInput::MultiTouchType)-1;
     int startIndex = 0;
     int endIndex = Count();
 
     switch (Action()) {
+        case AndroidMotionEvent::ACTION_HOVER_ENTER: {
+            if (ToolTypes()[0] == AndroidMotionEvent::TOOL_TYPE_MOUSE) {
+                break;
+            }
+        }
         case AndroidMotionEvent::ACTION_DOWN:
         case AndroidMotionEvent::ACTION_POINTER_DOWN: {
             type = MultiTouchInput::MULTITOUCH_START;
             break;
         }
+        case AndroidMotionEvent::ACTION_HOVER_MOVE: {
+            if (ToolTypes()[0] == AndroidMotionEvent::TOOL_TYPE_MOUSE) {
+                break;
+            }
+        }
         case AndroidMotionEvent::ACTION_MOVE: {
             type = MultiTouchInput::MULTITOUCH_MOVE;
             break;
         }
+        case AndroidMotionEvent::ACTION_HOVER_EXIT: {
+            if (ToolTypes()[0] == AndroidMotionEvent::TOOL_TYPE_MOUSE) {
+                break;
+            }
+        }
         case AndroidMotionEvent::ACTION_UP:
         case AndroidMotionEvent::ACTION_POINTER_UP: {
             // for pointer-up events we only want the data from
             // the one pointer that went up
             startIndex = PointerIndex();
             endIndex = startIndex + 1;
             type = MultiTouchInput::MULTITOUCH_END;
             break;