Merge b2g-inbound to m-c.
authorRyan VanderMeulen <ryanvm@gmail.com>
Mon, 10 Feb 2014 15:37:54 -0500
changeset 167875 07739c5c874f
parent 167838 f5726434eedc (current diff)
parent 167874 fea1fd2679a8 (diff)
child 167907 d812f80a0f1d
push id26190
push userryanvm@gmail.com
push date2014-02-10 20:37 +0000
Treeherderresults
milestone30.0a1
Merge b2g-inbound to m-c.
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -7,23 +7,23 @@
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="59605a7c026ff06cc1613af3938579b1dddc6cfe">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="7ef494164bcd840dc23c7db106dff0a98f8ff15f"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="9fc36dde3a4a3c5ca200275b68ffb56b4173bec3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="0a8bdd0f43e2d8fc7d45b3b0d97125834c0ac72f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="eda08beb3ba9a159843c70ffde0f9660ec351eb9"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="87aa8679560ce09f6445621d6f370d9de722cdba"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="e33ea242b4328fb0d1824c951f379332b5021512"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="788d9ce293a9b44f64536130cf4ad577e8101dbe"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a314508e397c8f1814228d36259ea8708034444e"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
   <project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="425f8b5fadf5889834c5acd27d23c9e0b2129c28"/>
   <project name="device/common" path="device/common" revision="42b808b7e93d0619286ae8e59110b176b7732389"/>
   <project name="device/sample" path="device/sample" revision="237bd668d0f114d801a8d6455ef5e02cc3577587"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
   <project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="52a1a862a8bac319652b8f82d9541ba40bfa45ce"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -6,20 +6,20 @@
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="317f25e0a4cb3e8e86e2b76c37a14081372f0307">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="7ef494164bcd840dc23c7db106dff0a98f8ff15f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="9fc36dde3a4a3c5ca200275b68ffb56b4173bec3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="0a8bdd0f43e2d8fc7d45b3b0d97125834c0ac72f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="e33ea242b4328fb0d1824c951f379332b5021512"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="788d9ce293a9b44f64536130cf4ad577e8101dbe"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a314508e397c8f1814228d36259ea8708034444e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="905bfa3548eb75cf1792d0d8412b92113bbd4318"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="c3d7efc45414f1b44cd9c479bb2758c91c4707c0"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -7,23 +7,23 @@
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="59605a7c026ff06cc1613af3938579b1dddc6cfe">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="7ef494164bcd840dc23c7db106dff0a98f8ff15f"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="9fc36dde3a4a3c5ca200275b68ffb56b4173bec3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="0a8bdd0f43e2d8fc7d45b3b0d97125834c0ac72f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="eda08beb3ba9a159843c70ffde0f9660ec351eb9"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="87aa8679560ce09f6445621d6f370d9de722cdba"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="e33ea242b4328fb0d1824c951f379332b5021512"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="788d9ce293a9b44f64536130cf4ad577e8101dbe"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a314508e397c8f1814228d36259ea8708034444e"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
   <project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="425f8b5fadf5889834c5acd27d23c9e0b2129c28"/>
   <project name="device/common" path="device/common" revision="42b808b7e93d0619286ae8e59110b176b7732389"/>
   <project name="device/sample" path="device/sample" revision="237bd668d0f114d801a8d6455ef5e02cc3577587"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
   <project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="52a1a862a8bac319652b8f82d9541ba40bfa45ce"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,4 +1,4 @@
 {
-    "revision": "25b78e722d958fe667061a2d9e0733d0877607ac", 
+    "revision": "500d57309898b0514b1ad1a61a8d8274909428a4", 
     "repo_path": "/integration/gaia-central"
 }
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -6,22 +6,22 @@
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="59605a7c026ff06cc1613af3938579b1dddc6cfe">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="7ef494164bcd840dc23c7db106dff0a98f8ff15f"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="9fc36dde3a4a3c5ca200275b68ffb56b4173bec3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="0a8bdd0f43e2d8fc7d45b3b0d97125834c0ac72f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="e33ea242b4328fb0d1824c951f379332b5021512"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="788d9ce293a9b44f64536130cf4ad577e8101dbe"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a314508e397c8f1814228d36259ea8708034444e"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="746bc48f34f5060f90801925dcdd964030c1ab6d"/>
   <project name="platform/development" path="development" revision="2460485184bc8535440bb63876d4e63ec1b4770c"/>
   <project name="device/common" path="device/common" revision="0dcc1e03659db33b77392529466f9eb685cdd3c7"/>
   <project name="device/sample" path="device/sample" revision="68b1cb978a20806176123b959cb05d4fa8adaea4"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -5,17 +5,17 @@
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="59605a7c026ff06cc1613af3938579b1dddc6cfe">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="7ef494164bcd840dc23c7db106dff0a98f8ff15f"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="9fc36dde3a4a3c5ca200275b68ffb56b4173bec3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="0a8bdd0f43e2d8fc7d45b3b0d97125834c0ac72f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="e33ea242b4328fb0d1824c951f379332b5021512"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/inari/sources.xml
+++ b/b2g/config/inari/sources.xml
@@ -7,22 +7,22 @@
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="59605a7c026ff06cc1613af3938579b1dddc6cfe">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="7ef494164bcd840dc23c7db106dff0a98f8ff15f"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="9fc36dde3a4a3c5ca200275b68ffb56b4173bec3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="0a8bdd0f43e2d8fc7d45b3b0d97125834c0ac72f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="e33ea242b4328fb0d1824c951f379332b5021512"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="788d9ce293a9b44f64536130cf4ad577e8101dbe"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a314508e397c8f1814228d36259ea8708034444e"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="cd5dfce80bc3f0139a56b58aca633202ccaee7f8"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="e0a9ac010df3afaa47ba107192c05ac8b5516435"/>
   <project name="platform/development" path="development" revision="a384622f5fcb1d2bebb9102591ff7ae91fe8ed2d"/>
   <project name="device/common" path="device/common" revision="7c65ea240157763b8ded6154a17d3c033167afb7"/>
   <project name="device/sample" path="device/sample" revision="c328f3d4409db801628861baa8d279fb8855892f"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
--- a/b2g/config/leo/sources.xml
+++ b/b2g/config/leo/sources.xml
@@ -6,22 +6,22 @@
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="59605a7c026ff06cc1613af3938579b1dddc6cfe">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="7ef494164bcd840dc23c7db106dff0a98f8ff15f"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="9fc36dde3a4a3c5ca200275b68ffb56b4173bec3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="0a8bdd0f43e2d8fc7d45b3b0d97125834c0ac72f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="e33ea242b4328fb0d1824c951f379332b5021512"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="788d9ce293a9b44f64536130cf4ad577e8101dbe"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a314508e397c8f1814228d36259ea8708034444e"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="575fdbf046e966a5915b1f1e800e5d6ad0ea14c0"/>
   <project name="platform/development" path="development" revision="b1025ec93beeb480caaf3049d171283c3846461d"/>
   <project name="device/common" path="device/common" revision="0dcc1e03659db33b77392529466f9eb685cdd3c7"/>
   <project name="device/sample" path="device/sample" revision="68b1cb978a20806176123b959cb05d4fa8adaea4"/>
--- a/b2g/config/mako/sources.xml
+++ b/b2g/config/mako/sources.xml
@@ -6,20 +6,20 @@
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="317f25e0a4cb3e8e86e2b76c37a14081372f0307">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="7ef494164bcd840dc23c7db106dff0a98f8ff15f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="9fc36dde3a4a3c5ca200275b68ffb56b4173bec3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="0a8bdd0f43e2d8fc7d45b3b0d97125834c0ac72f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="e33ea242b4328fb0d1824c951f379332b5021512"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="788d9ce293a9b44f64536130cf4ad577e8101dbe"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a314508e397c8f1814228d36259ea8708034444e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="905bfa3548eb75cf1792d0d8412b92113bbd4318"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="c3d7efc45414f1b44cd9c479bb2758c91c4707c0"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -6,22 +6,22 @@
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="59605a7c026ff06cc1613af3938579b1dddc6cfe">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="7ef494164bcd840dc23c7db106dff0a98f8ff15f"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="9fc36dde3a4a3c5ca200275b68ffb56b4173bec3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="0a8bdd0f43e2d8fc7d45b3b0d97125834c0ac72f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="e33ea242b4328fb0d1824c951f379332b5021512"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="788d9ce293a9b44f64536130cf4ad577e8101dbe"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a314508e397c8f1814228d36259ea8708034444e"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="cd5dfce80bc3f0139a56b58aca633202ccaee7f8"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="e0a9ac010df3afaa47ba107192c05ac8b5516435"/>
   <project name="platform/development" path="development" revision="a384622f5fcb1d2bebb9102591ff7ae91fe8ed2d"/>
   <project name="device/common" path="device/common" revision="7c65ea240157763b8ded6154a17d3c033167afb7"/>
   <project name="device/sample" path="device/sample" revision="c328f3d4409db801628861baa8d279fb8855892f"/>
--- a/content/media/omx/RtspOmxReader.cpp
+++ b/content/media/omx/RtspOmxReader.cpp
@@ -169,16 +169,17 @@ status_t RtspMediaSource::read(MediaBuff
 class RtspExtractor: public MediaExtractor
 {
 public:
   virtual size_t countTracks() MOZ_FINAL MOZ_OVERRIDE;
   virtual sp<android::MediaSource> getTrack(size_t index)
     MOZ_FINAL MOZ_OVERRIDE;
   virtual sp<MetaData> getTrackMetaData(
     size_t index, uint32_t flag = 0) MOZ_FINAL MOZ_OVERRIDE;
+  virtual uint32_t flags() const MOZ_FINAL MOZ_OVERRIDE;
 
   RtspExtractor(RtspMediaResource *aResource)
     : mRtspResource(aResource) {
     MOZ_COUNT_CTOR(RtspExtractor);
     MOZ_ASSERT(aResource);
     mController = mRtspResource->GetMediaStreamController();
     MOZ_ASSERT(mController);
   }
@@ -251,25 +252,34 @@ sp<MetaData> RtspExtractor::getTrackMeta
     rtspMetadata->GetAvccData(tempCString);
     if (tempCString.Length()) {
       meta->setData(kKeyAVCC, 0, tempCString.get(), tempCString.Length());
     }
   }
   return meta;
 }
 
+uint32_t RtspExtractor::flags() const
+{
+  if (mRtspResource->IsRealTime()) {
+    return 0;
+  } else {
+    return MediaExtractor::CAN_SEEK;
+  }
+}
+
 nsresult RtspOmxReader::InitOmxDecoder()
 {
   if (!mOmxDecoder.get()) {
     NS_ASSERTION(mDecoder, "RtspOmxReader mDecoder is null.");
     NS_ASSERTION(mDecoder->GetResource(),
                  "RtspOmxReader mDecoder->GetResource() is null.");
-    sp<MediaExtractor> extractor = new RtspExtractor(mRtspResource);
+    mExtractor = new RtspExtractor(mRtspResource);
     mOmxDecoder = new OmxDecoder(mDecoder->GetResource(), mDecoder);
-    if (!mOmxDecoder->Init(extractor)) {
+    if (!mOmxDecoder->Init(mExtractor)) {
       return NS_ERROR_FAILURE;
     }
   }
   return NS_OK;
 }
 
 nsresult RtspOmxReader::Seek(int64_t aTime, int64_t aStartTime,
                              int64_t aEndTime, int64_t aCurrentTime)
--- a/content/media/test/test_new_audio.html
+++ b/content/media/test/test_new_audio.html
@@ -20,21 +20,21 @@ https://bugzilla.mozilla.org/show_bug.cg
 
 /** Test for Bug 528566 **/
 
 var manager = new MediaTestManager;
 
 var player = new Audio();
 
 function startTest(test, token) {
-  if (!player.canPlayType(test.type))
+  if (!player.canPlayType(test.type)) {
     return;
+  }
   manager.started(token);
   var a = new Audio(test.name);
-  a.setAttribute("autoplay", false);
   a.addEventListener("canplaythrough",
                      function(e){ e.target.play(); },
                       false);
   a.addEventListener("ended",
                      function(e){
                         ok(true, "We should get to the end. Oh look we did.");
                         manager.finished(token);
                      },
--- a/dom/network/src/NetworkStatsDB.jsm
+++ b/dom/network/src/NetworkStatsDB.jsm
@@ -11,17 +11,17 @@ function debug(s) { dump("-*- NetworkSta
 
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/IndexedDBHelper.jsm");
 Cu.importGlobalProperties(["indexedDB"]);
 
 const DB_NAME = "net_stats";
-const DB_VERSION = 6;
+const DB_VERSION = 7;
 const DEPRECATED_STORE_NAME = "net_stats";
 const STATS_STORE_NAME = "net_stats_store";
 const ALARMS_STORE_NAME = "net_alarm";
 
 // Constant defining the maximum values allowed per interface. If more, older
 // will be erased.
 const VALUES_MAX_LENGTH = 6 * 30;
 
@@ -208,16 +208,104 @@ NetworkStatsDB.prototype = {
           newStats.serviceType = "";
           newObjectStore.put(newStats);
           cursor.continue();
         };
 
         if (DEBUG) {
           debug("Added new key 'serviceType' for version 6");
         }
+      } else if (currVersion == 6) {
+        // Replace threshold attribute of alarm index by relativeThreshold in alarms DB.
+        // Now alarms are indexed by relativeThreshold, which is the threshold relative
+        // to current system stats.
+        let alarmsStore = aTransaction.objectStore(ALARMS_STORE_NAME);
+
+        // Delete "alarm" index.
+        if (alarmsStore.indexNames.contains("alarm")) {
+          alarmsStore.deleteIndex("alarm");
+        }
+
+        // Create new "alarm" index.
+        alarmsStore.createIndex("alarm", ['networkId','relativeThreshold'], { unique: false });
+
+        // Populate new "alarm" index attributes.
+        alarmsStore.openCursor().onsuccess = function(event) {
+          let cursor = event.target.result;
+          if (!cursor) {
+            return;
+          }
+
+          cursor.value.relativeThreshold = cursor.value.threshold;
+          cursor.value.absoluteThreshold = cursor.value.threshold;
+          delete cursor.value.threshold;
+
+          cursor.update(cursor.value);
+          cursor.continue();
+        }
+
+        // Previous versions save accumulative totalBytes, increasing althought the system
+        // reboots or resets stats. But is necessary to reset the total counters when reset
+        // through 'clearInterfaceStats'.
+        let statsStore = aTransaction.objectStore(STATS_STORE_NAME);
+        let networks = [];
+        // Find networks stored in the database.
+        statsStore.index("network").openKeyCursor(null, "nextunique").onsuccess = function(event) {
+          let cursor = event.target.result;
+          if (cursor) {
+            networks.push(cursor.key);
+            cursor.continue();
+            return;
+          }
+
+          networks.forEach(function(network) {
+            let lowerFilter = [0, "", network, 0];
+            let upperFilter = [0, "", network, ""];
+            let range = IDBKeyRange.bound(lowerFilter, upperFilter, false, false);
+
+            // Find number of samples for a given network.
+            statsStore.count(range).onsuccess = function(event) {
+              // If there are more samples than the max allowed, there is no way to know
+              // when does reset take place.
+              if (event.target.result >= VALUES_MAX_LENGTH) {
+                return;
+              }
+
+              let last = null;
+              // Reset detected if the first sample totalCounters are different than bytes
+              // counters. If so, the total counters should be recalculated.
+              statsStore.openCursor(range).onsuccess = function(event) {
+                let cursor = event.target.result;
+                if (!cursor) {
+                  return;
+                }
+                if (!last) {
+                  if (cursor.value.rxTotalBytes == cursor.value.rxBytes &&
+                      cursor.value.txTotalBytes == cursor.value.txBytes) {
+                    return;
+                  }
+
+                  cursor.value.rxTotalBytes = cursor.value.rxBytes;
+                  cursor.value.txTotalBytes = cursor.value.txBytes;
+                  cursor.update(cursor.value);
+                  last = cursor.value;
+                  cursor.continue();
+                  return;
+                }
+
+                // Recalculate the total counter for last / current sample
+                cursor.value.rxTotalBytes = last.rxTotalBytes + cursor.value.rxBytes;
+                cursor.value.txTotalBytes = last.txTotalBytes + cursor.value.txBytes;
+                cursor.update(cursor.value);
+                last = cursor.value;
+                cursor.continue();
+              }
+            }
+          }, this);
+        };
       }
     }
   },
 
   importData: function importData(aStats) {
     let stats = { appId:         aStats.appId,
                   serviceType:   aStats.serviceType,
                   network:       [aStats.networkId, aStats.networkType],
@@ -510,16 +598,18 @@ NetworkStatsDB.prototype = {
         if (sample) {
           let timestamp = new Date();
           timestamp = self.normalizeDate(timestamp);
           sample.timestamp = timestamp;
           sample.appId = 0;
           sample.serviceType = "";
           sample.rxBytes = 0;
           sample.txBytes = 0;
+          sample.rxTotalBytes = 0;
+          sample.txTotalBytes = 0;
 
           self._saveStats(aTxn, aStore, sample);
         }
       };
     }, aResultCb);
   },
 
   clearStats: function clearStats(aNetworks, aResultCb) {
@@ -545,34 +635,88 @@ NetworkStatsDB.prototype = {
     this.clearInterfaceStats(aNetworks[index], callback);
   },
 
   getCurrentStats: function getCurrentStats(aNetwork, aDate, aResultCb) {
     if (DEBUG) {
       debug("Get current stats for " + JSON.stringify(aNetwork) + " since " + aDate);
     }
 
+    let network = [aNetwork.id, aNetwork.type];
+    if (aDate) {
+      this._getCurrentStatsFromDate(network, aDate, aResultCb);
+      return;
+    }
+
+    this._getCurrentStats(network, aResultCb);
+  },
+
+  _getCurrentStats: function _getCurrentStats(aNetwork, aResultCb) {
     this.dbNewTxn(STATS_STORE_NAME, "readonly", function(txn, store) {
       let request = null;
-      let network = [aNetwork.id, aNetwork.type];
-      if (aDate) {
-        let start = this.normalizeDate(aDate);
-        let lowerFilter = [0, network, start];
-        let range = this.dbGlobal.IDBKeyRange.lowerBound(lowerFilter, false);
-        request = store.openCursor(range);
-      } else {
-        request = store.index("network").openCursor(network, "prev");
-      }
+      let upperFilter = [0, "", aNetwork, Date.now()];
+      let range = IDBKeyRange.upperBound(upperFilter, false);
+      request = store.openCursor(range, "prev");
+
+      let result = { rxBytes:      0, txBytes:      0,
+                     rxTotalBytes: 0, txTotalBytes: 0 };
 
       request.onsuccess = function onsuccess(event) {
-        txn.result = null;
         let cursor = event.target.result;
         if (cursor) {
-          txn.result = cursor.value;
+          result.rxBytes = result.rxTotalBytes = cursor.value.rxTotalBytes;
+          result.txBytes = result.txTotalBytes = cursor.value.txTotalBytes;
         }
+
+        txn.result = result;
+      };
+    }.bind(this), aResultCb);
+  },
+
+  _getCurrentStatsFromDate: function _getCurrentStatsFromDate(aNetwork, aDate, aResultCb) {
+    aDate = new Date(aDate);
+    this.dbNewTxn(STATS_STORE_NAME, "readonly", function(txn, store) {
+      let request = null;
+      let start = this.normalizeDate(aDate);
+      let lowerFilter = [0, "", aNetwork, start];
+      let upperFilter = [0, "", aNetwork, Date.now()];
+
+      let range = IDBKeyRange.upperBound(upperFilter, false);
+
+      let result = { rxBytes:      0, txBytes:      0,
+                     rxTotalBytes: 0, txTotalBytes: 0 };
+
+      request = store.openCursor(range, "prev");
+
+      request.onsuccess = function onsuccess(event) {
+        let cursor = event.target.result;
+        if (cursor) {
+          result.rxBytes = result.rxTotalBytes = cursor.value.rxTotalBytes;
+          result.txBytes = result.txTotalBytes = cursor.value.txTotalBytes;
+        }
+
+        let timestamp = cursor.value.timestamp;
+        let range = IDBKeyRange.lowerBound(lowerFilter, false);
+        request = store.openCursor(range);
+
+        request.onsuccess = function onsuccess(event) {
+          let cursor = event.target.result;
+          if (cursor) {
+            if (cursor.value.timestamp == timestamp) {
+              // There is one sample only.
+              result.rxBytes = cursor.value.rxBytes;
+              result.txBytes = cursor.value.txBytes;
+            } else {
+              result.rxBytes -= cursor.value.rxTotalBytes;
+              result.txBytes -= cursor.value.txTotalBytes;
+            }
+          }
+
+          txn.result = result;
+        };
       };
     }.bind(this), aResultCb);
   },
 
   find: function find(aResultCb, aAppId, aServiceType, aNetwork,
                       aStart, aEnd, aAppManifestURL) {
     let offset = (new Date()).getTimezoneOffset() * 60 * 1000;
     let start = this.normalizeDate(aStart);
@@ -666,17 +810,17 @@ NetworkStatsDB.prototype = {
   },
 
   isNetworkAvailable: function isNetworkAvailable(aNetwork, aResultCb) {
     this.dbNewTxn(STATS_STORE_NAME, "readonly", function(aTxn, aStore) {
       if (!aTxn.result) {
         aTxn.result = false;
       }
 
-      var network = [aNetwork.id, aNetwork.type];
+      let network = [aNetwork.id, aNetwork.type];
       let request = aStore.index("network").openKeyCursor(IDBKeyRange.only(network));
       request.onsuccess = function onsuccess(event) {
         if (event.target.result) {
           aTxn.result = true;
         }
       };
     }, aResultCb);
   },
@@ -712,31 +856,33 @@ NetworkStatsDB.prototype = {
       aStore.mozGetAll().onsuccess = function onsuccess(event) {
         aTxn.result = event.target.result;
       };
     }, aResultCb);
   },
 
   alarmToRecord: function alarmToRecord(aAlarm) {
     let record = { networkId: aAlarm.networkId,
-                   threshold: aAlarm.threshold,
+                   absoluteThreshold: aAlarm.absoluteThreshold,
+                   relativeThreshold: aAlarm.relativeThreshold,
                    data: aAlarm.data,
                    manifestURL: aAlarm.manifestURL,
                    pageURL: aAlarm.pageURL };
 
     if (aAlarm.id) {
       record.id = aAlarm.id;
     }
 
     return record;
   },
 
   recordToAlarm: function recordToalarm(aRecord) {
     let alarm = { networkId: aRecord.networkId,
-                  threshold: aRecord.threshold,
+                  absoluteThreshold: aRecord.absoluteThreshold,
+                  relativeThreshold: aRecord.relativeThreshold,
                   data: aRecord.data,
                   manifestURL: aRecord.manifestURL,
                   pageURL: aRecord.pageURL };
 
     if (aRecord.id) {
       alarm.id = aRecord.id;
     }
 
@@ -832,35 +978,31 @@ NetworkStatsDB.prototype = {
           cursor.update(record);
           txn.result = true;
         }
       }
     }, aResultCb);
   },
 
   getAlarms: function getAlarms(aNetworkId, aManifestURL, aResultCb) {
+    let self = this;
     this.dbNewTxn(ALARMS_STORE_NAME, "readonly", function(txn, store) {
       if (DEBUG) {
         debug("Get alarms for " + aManifestURL);
       }
 
       txn.result = [];
       store.index("manifestURL").openCursor(aManifestURL)
                                 .onsuccess = function onsuccess(event) {
         let cursor = event.target.result;
         if (!cursor) {
           return;
         }
 
         if (!aNetworkId || cursor.value.networkId == aNetworkId) {
-          let alarm = { id: cursor.value.id,
-                        networkId: cursor.value.networkId,
-                        threshold: cursor.value.threshold,
-                        data: cursor.value.data };
-
-          txn.result.push(alarm);
+          txn.result.push(self.recordToAlarm(cursor.value));
         }
 
         cursor.continue();
       }
     }, aResultCb);
   }
 };
--- a/dom/network/src/NetworkStatsManager.js
+++ b/dom/network/src/NetworkStatsManager.js
@@ -232,16 +232,20 @@ NetworkStatsManager.prototype = {
 
   addAlarm: function addAlarm(aNetwork, aThreshold, aOptions) {
     this.checkPrivileges();
 
     if (!aOptions) {
       aOptions = Object.create(null);
     }
 
+    if (aOptions.startTime && aOptions.startTime.constructor.name !== "Date") {
+      throw Components.results.NS_ERROR_INVALID_ARG;
+    }
+
     let request = this.createRequest();
     cpmm.sendAsyncMessage("NetworkStats:SetAlarm",
                           {id: this.getRequestId(request),
                            data: {network: aNetwork,
                                   threshold: aThreshold,
                                   startTime: aOptions.startTime,
                                   data: aOptions.data,
                                   manifestURL: this.manifestURL,
--- a/dom/network/src/NetworkStatsService.jsm
+++ b/dom/network/src/NetworkStatsService.jsm
@@ -326,20 +326,21 @@ this.NetworkStatsService = {
     // Check if network is available in the DB.
     this._db.isNetworkAvailable(aNetwork, function(aError, aResult) {
       if (aResult) {
         this._networks[netId] = Object.create(null);
         this._networks[netId].network = aNetwork;
         this._networks[netId].status = NETWORK_STATUS_AWAY;
         this._currentAlarms[netId] = Object.create(null);
         aCallback(netId);
+        return;
       }
 
       aCallback(null);
-    });
+    }.bind(this));
   },
 
   getAvailableNetworks: function getAvailableNetworks(mm, msg) {
     let self = this;
     let rilNetworks = this.getRilNetworks();
     this._db.getAvailableNetworks(function onGetNetworks(aError, aResult) {
 
       // Also return the networks that are valid but have not
@@ -858,17 +859,17 @@ this.NetworkStatsService = {
       }
 
       let alarms = []
       // NetworkStatsManager must return the network instead of the networkId.
       for (let i = 0; i < result.length; i++) {
         let alarm = result[i];
         alarms.push({ id: alarm.id,
                       network: self._networks[alarm.networkId].network,
-                      threshold: alarm.threshold,
+                      threshold: alarm.absoluteThreshold,
                       data: alarm.data });
       }
 
       mm.sendAsyncMessage("NetworkStats:GetAlarms:Return",
                           { id: msg.id, error: null, result: alarms });
     });
   },
 
@@ -926,32 +927,31 @@ this.NetworkStatsService = {
         mm.sendAsyncMessage("NetworkStats:SetAlarm:Return",
                             { id: msg.id, error: "InvalidiConnectionType", result: null });
         return;
       }
 
       let newAlarm = {
         id: null,
         networkId: aNetId,
-        threshold: threshold,
-        absoluteThreshold: null,
+        absoluteThreshold: threshold,
+        relativeThreshold: null,
         startTime: options.startTime,
         data: options.data,
         pageURL: options.pageURL,
         manifestURL: options.manifestURL
       };
 
-      self._updateThreshold(newAlarm, function onUpdate(error, _threshold) {
+      self._getAlarmQuota(newAlarm, function onUpdate(error, quota) {
         if (error) {
           mm.sendAsyncMessage("NetworkStats:SetAlarm:Return",
                               { id: msg.id, error: error, result: null });
           return;
         }
 
-        newAlarm.absoluteThreshold = _threshold.absoluteThreshold;
         self._db.addAlarm(newAlarm, function addSuccessCb(error, newId) {
           if (error) {
             mm.sendAsyncMessage("NetworkStats:SetAlarm:Return",
                                 { id: msg.id, error: error, result: null });
             return;
           }
 
           newAlarm.id = newId;
@@ -966,25 +966,25 @@ this.NetworkStatsService = {
         });
       });
     });
   },
 
   _setAlarm: function _setAlarm(aAlarm, aCallback) {
     let currentAlarm = this._currentAlarms[aAlarm.networkId];
     if ((Object.getOwnPropertyNames(currentAlarm).length !== 0 &&
-         aAlarm.absoluteThreshold > currentAlarm.alarm.absoluteThreshold) ||
+         aAlarm.relativeThreshold > currentAlarm.alarm.relativeThreshold) ||
         this._networks[aAlarm.networkId].status != NETWORK_STATUS_READY) {
       aCallback(null, true);
       return;
     }
 
     let self = this;
 
-    this._updateThreshold(aAlarm, function onUpdate(aError, aThreshold) {
+    this._getAlarmQuota(aAlarm, function onUpdate(aError, aQuota) {
       if (aError) {
         aCallback(aError, null);
         return;
       }
 
       let callback = function onAlarmSet(aError) {
         if (aError) {
           debug("Set alarm error: " + aError);
@@ -996,60 +996,51 @@ this.NetworkStatsService = {
 
         aCallback(null, true);
       };
 
       debug("Set alarm " + JSON.stringify(aAlarm));
       let interfaceName = self._networks[aAlarm.networkId].interfaceName;
       if (interfaceName) {
         networkService.setNetworkInterfaceAlarm(interfaceName,
-                                                aThreshold.systemThreshold,
+                                                aQuota,
                                                 callback);
         return;
       }
 
       aCallback(null, true);
     });
   },
 
-  _updateThreshold: function _updateThreshold(aAlarm, aCallback) {
+  _getAlarmQuota: function _getAlarmQuota(aAlarm, aCallback) {
     let self = this;
     this.updateStats(aAlarm.networkId, function onStatsUpdated(aResult, aMessage) {
       self._db.getCurrentStats(self._networks[aAlarm.networkId].network,
                                aAlarm.startTime,
                                function onStatsFound(error, result) {
         if (error) {
           debug("Error getting stats for " +
                 JSON.stringify(self._networks[aAlarm.networkId]) + ": " + error);
           aCallback(error, result);
           return;
         }
 
-        if (!result) {
-          // There are no stats for the network of the alarm, set them to default 0 in
-          // order to be able to calculate the offset, systemThreshold and
-          // absoluteThreshold.
-          result = { rxTotalBytes:  0, txTotalBytes:  0,
-                     rxSystemBytes: 0, txSystemBytes: 0 };
-        }
-
-        let offset = aAlarm.threshold - result.rxTotalBytes - result.txTotalBytes;
+        let quota = aAlarm.absoluteThreshold - result.rxBytes - result.txBytes;
 
         // Alarm set to a threshold lower than current rx/tx bytes.
-        if (offset <= 0) {
+        if (quota <= 0) {
           aCallback("InvalidStateError", null);
           return;
         }
 
-        let threshold = {
-          systemThreshold: result.rxSystemBytes + result.txSystemBytes + offset,
-          absoluteThreshold: result.rxTotalBytes + result.txTotalBytes + offset
-        };
+        aAlarm.relativeThreshold = aAlarm.startTime
+                                 ? result.rxTotalBytes + result.txTotalBytes + quota
+                                 : aAlarm.absoluteThreshold;
 
-        aCallback(null, threshold);
+        aCallback(null, quota);
       });
     });
   },
 
   _fireAlarm: function _fireAlarm(aAlarm) {
     debug("Fire alarm");
 
     let self = this;
@@ -1091,15 +1082,15 @@ this.NetworkStatsService = {
 
   _fireSystemMessage: function _fireSystemMessage(aAlarm) {
     debug("Fire system message: " + JSON.stringify(aAlarm));
 
     let manifestURI = Services.io.newURI(aAlarm.manifestURL, null, null);
     let pageURI = Services.io.newURI(aAlarm.pageURL, null, null);
 
     let alarm = { "id":        aAlarm.id,
-                  "threshold": aAlarm.threshold,
+                  "threshold": aAlarm.absoluteThreshold,
                   "data":      aAlarm.data };
     messenger.sendMessage("networkstats-alarm", alarm, pageURI, manifestURI);
   }
 };
 
 NetworkStatsService.init();
--- a/dom/network/tests/unit_stats/test_networkstats_db.js
+++ b/dom/network/tests/unit_stats/test_networkstats_db.js
@@ -729,55 +729,60 @@ var networkWifi = '00';
 var networkMobile = '11';
 
 var examplePageURL = "http://example.com/index.html";
 var exampleManifestURL = "http://example.com/manifest.webapp";
 
 var testPageURL = "http://test.com/index.html";
 var testManifestURL = "http://test.com/manifest.webapp";
 
-var alarms = [{ id:             null,
-                networkId:      networkWifi,
-                threshold:      10000,
-                data:           {foo: "something"},
-                pageURL:        examplePageURL,
-                manifestURL:    exampleManifestURL },
-              { id:             null,
-                networkId:      networkWifi,
-                threshold:      1000,
-                data:           {foo: "else"},
-                pageURL:        examplePageURL,
-                manifestURL:    exampleManifestURL },
-              { id:             null,
-                networkId:      networkMobile,
-                threshold:      100,
-                data:           {foo: "to"},
-                pageURL:        examplePageURL,
-                manifestURL:    exampleManifestURL },
-              { id:             null,
-                networkId:      networkMobile,
-                threshold:      10,
-                data:           {foo: "test"},
-                pageURL:        testPageURL,
-                manifestURL:    testManifestURL }];
+var alarms = [{ id:                null,
+                networkId:         networkWifi,
+                absoluteThreshold: 10000,
+                relativeThreshold: 10000,
+                data:              {foo: "something"},
+                pageURL:           examplePageURL,
+                manifestURL:       exampleManifestURL },
+              { id:                null,
+                networkId:         networkWifi,
+                absoluteThreshold: 1000,
+                relativeThreshold: 1000,
+                data:              {foo: "else"},
+                pageURL:           examplePageURL,
+                manifestURL:       exampleManifestURL },
+              { id:                null,
+                networkId:         networkMobile,
+                absoluteThreshold: 100,
+                relativeThreshold: 100,
+                data:              {foo: "to"},
+                pageURL:           examplePageURL,
+                manifestURL:       exampleManifestURL },
+              { id:                null,
+                networkId:         networkMobile,
+                absoluteThreshold: 10,
+                relativeThreshold: 10,
+                data:              {foo: "test"},
+                pageURL:           testPageURL,
+                manifestURL:       testManifestURL }];
 
 var alarmsDbId = 1;
 
 add_test(function test_addAlarm() {
   // Add alarms[0] -> DB: [ alarms[0] (id: 1) ]
   // Check the insertion is OK.
   netStatsDb.addAlarm(alarms[0], function(error, result) {
     do_check_eq(error, null);
     alarmsDbId = result;
     netStatsDb.getAlarms(Ci.nsINetworkInterface.NETWORK_TYPE_WIFI, exampleManifestURL, function(error, result) {
       do_check_eq(error, null);
       do_check_eq(result.length, 1);
       do_check_eq(result[0].id, alarmsDbId);
       do_check_eq(result[0].networkId, alarms[0].networkId);
-      do_check_eq(result[0].threshold, alarms[0].threshold);
+      do_check_eq(result[0].absoluteThreshold, alarms[0].absoluteThreshold);
+      do_check_eq(result[0].relativeThreshold, alarms[0].relativeThreshold);
       do_check_eq(result[0].data.foo, alarms[0].data.foo);
       run_next_test();
     });
   });
 });
 
 add_test(function test_getFirstAlarm() {
   // Add alarms[1] -> DB: [ alarms[0] (id: 1), alarms[1] (id: 2) ]
@@ -785,17 +790,18 @@ add_test(function test_getFirstAlarm() {
   alarmsDbId += 1;
   netStatsDb.addAlarm(alarms[1], function (error, result) {
     do_check_eq(error, null);
     do_check_eq(result, alarmsDbId);
     netStatsDb.getFirstAlarm(networkWifi, function(error, result) {
       do_check_eq(error, null);
       do_check_eq(result.id, alarmsDbId);
       do_check_eq(result.networkId, alarms[1].networkId);
-      do_check_eq(result.threshold, alarms[1].threshold);
+      do_check_eq(result.absoluteThreshold, alarms[1].absoluteThreshold);
+      do_check_eq(result.relativeThreshold, alarms[1].relativeThreshold);
       do_check_eq(result.data.foo, alarms[1].data.foo);
       do_check_eq(result.pageURL, alarms[1].pageURL);
       do_check_eq(result.manifestURL, alarms[1].manifestURL);
       run_next_test();
     });
   });
 });
 
@@ -803,17 +809,18 @@ add_test(function test_removeAlarm() {
   // Remove alarms[1] (id: 2) -> DB: [ alarms[0] (id: 1) ]
   // Check get first return alarms[0].
   netStatsDb.removeAlarm(alarmsDbId, alarms[0].manifestURL, function (error, result) {
     do_check_eq(error, null);
     netStatsDb.getFirstAlarm(networkWifi, function(error, result) {
       do_check_eq(error, null);
       do_check_eq(result.id, alarmsDbId - 1);
       do_check_eq(result.networkId, alarms[0].networkId);
-      do_check_eq(result.threshold, alarms[0].threshold);
+      do_check_eq(result.absoluteThreshold, alarms[0].absoluteThreshold);
+      do_check_eq(result.relativeThreshold, alarms[0].relativeThreshold);
       do_check_eq(result.data.foo, alarms[0].data.foo);
       do_check_eq(result.pageURL, alarms[0].pageURL);
       do_check_eq(result.manifestURL, alarms[0].manifestURL);
       run_next_test();
     });
   });
 });
 
@@ -892,17 +899,18 @@ add_test(function test_updateAlarm() {
   updatedAlarm.threshold = 10;
 
   netStatsDb.updateAlarm(updatedAlarm, function (error, result) {
     do_check_eq(error, null);
     netStatsDb.getFirstAlarm(networkWifi, function(error, result) {
       do_check_eq(error, null);
       do_check_eq(result.id, updatedAlarm.id);
       do_check_eq(result.networkId, updatedAlarm.networkId);
-      do_check_eq(result.threshold, updatedAlarm.threshold);
+      do_check_eq(result.absoluteThreshold, updatedAlarm.absoluteThreshold);
+      do_check_eq(result.relativeThreshold, updatedAlarm.relativeThreshold);
       do_check_eq(result.data.foo, updatedAlarm.data.foo);
       do_check_eq(result.pageURL, updatedAlarm.pageURL);
       do_check_eq(result.manifestURL, updatedAlarm.manifestURL);
       run_next_test();
     });
   });
 });
 
--- a/dom/network/tests/unit_stats/test_networkstats_service.js
+++ b/dom/network/tests/unit_stats/test_networkstats_service.js
@@ -2,16 +2,18 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 const NETWORK_STATUS_READY   = 0;
 const NETWORK_STATUS_STANDBY = 1;
 const NETWORK_STATUS_AWAY    = 2;
 
+var wifiId = '00';
+
 function getNetworks(callback) {
   NetworkStatsService._db.getAvailableNetworks(function onGetNetworks(aError, aResult) {
     callback(aError, aResult);
   });
 }
 
 add_test(function test_clearDB() {
   getNetworks(function onGetNetworks(error, result) {
@@ -117,61 +119,87 @@ add_test(function test_updateStats_ok() 
 
 add_test(function test_updateStats_failure() {
   NetworkStatsService.updateStats(-1, function(success, msg){
     do_check_eq(success, false);
     run_next_test();
   });
 });
 
+// Define Mockup function to simulate a request to netd
+function MockNetdRequest(aCallback) {
+  var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+  var event = {
+    notify: function (timer) {
+      aCallback();
+    }
+  };
+
+  timer.initWithCallback(event, 100, Ci.nsITimer.TYPE_ONE_SHOT);
+}
+
 add_test(function test_queue() {
-  // Fill networks with fake network interfaces
-  // to enable netd async requests
+
+  // Overwrite update function of NetworkStatsService to avoid netd errors due to use
+  // fake interfaces. First, original function is stored to restore it at the end of the
+  // test.
+  var updateFunctionBackup = NetworkStatsService.update;
+
+  NetworkStatsService.update = function update(aNetId, aCallback) {
+    MockNetdRequest(function () {
+      if (aCallback) {
+        aCallback(true, "ok");
+      }
+    });
+  };
+
+  // Fill networks with fake network interfaces to enable netd async requests.
   var network = {id: "1234", type: Ci.nsIDOMMozNetworkStatsManager.MOBILE};
   var netId1 = NetworkStatsService.getNetworkId(network.id, network.type);
   NetworkStatsService._networks[netId1] = { network: network,
                                             interfaceName: "net1" };
 
   network = {id: "5678", type: Ci.nsIDOMMozNetworkStatsManager.MOBILE};
   var netId2 = NetworkStatsService.getNetworkId(network.id, network.type);
   NetworkStatsService._networks[netId2] = { network: network,
                                             interfaceName: "net2" };
 
   NetworkStatsService.updateStats(netId1);
   NetworkStatsService.updateStats(netId2);
   do_check_eq(NetworkStatsService.updateQueue.length, 2);
   do_check_eq(NetworkStatsService.updateQueue[0].callbacks.length, 1);
 
+  var i = 0;
+  var updateCount = 0;
   var callback = function(success, msg) {
-    return;
+    i++;
+    if (i >= updateCount) {
+      NetworkStatsService.update = updateFunctionBackup;
+      run_next_test();
+    }
   };
 
   NetworkStatsService.updateStats(netId1, callback);
+  updateCount++;
   NetworkStatsService.updateStats(netId2, callback);
+  updateCount++;
 
   do_check_eq(NetworkStatsService.updateQueue.length, 2);
   do_check_eq(NetworkStatsService.updateQueue[0].callbacks.length, 2);
   do_check_eq(NetworkStatsService.updateQueue[0].callbacks[0], null);
   do_check_neq(NetworkStatsService.updateQueue[0].callbacks[1], null);
-
-  // Clear queue because in test environment requests for mobile networks
-  // can not be handled.
-  NetworkStatsService.updateQueue =  [];
-  run_next_test();
 });
 
-var wifiId = '00';
+add_test(function test_getAlarmQuota() {
+  let alarm = { networkId: wifiId, absoluteThreshold: 10000 };
 
-add_test(function test_updateThreshold() {
-  let alarm = { networkId: wifiId, threshold: 10000 };
-
-  NetworkStatsService._updateThreshold(alarm, function onSet(error, threshold){
+  NetworkStatsService._getAlarmQuota(alarm, function onSet(error, quota){
     do_check_eq(error, null);
-    do_check_neq(threshold.systemThreshold, undefined);
-    do_check_neq(threshold.absoluteThreshold, undefined);
+    do_check_neq(quota, undefined);
+    do_check_eq(alarm.absoluteThreshold, alarm.relativeThreshold);
     run_next_test();
   });
 });
 
 var testPageURL = "http://test.com";
 var testManifestURL = "http://test.com/manifest.webapp";
 
 add_test(function test_setAlarm() {
@@ -217,16 +245,19 @@ add_test(function test_fireAlarm() {
                 threshold: 10000,
                 absoluteThreshold: null,
                 alarmStart: null,
                 alarmEnd: null,
                 data: null,
                 pageURL: testPageURL,
                 manifestURL: testManifestURL };
 
+  // Set wifi status to standby to avoid connecting to netd when adding an alarm.
+  NetworkStatsService._networks[wifiId].status = NETWORK_STATUS_STANDBY;
+
   NetworkStatsService._db.addAlarm(alarm, function addSuccessCb(error, newId) {
     NetworkStatsService._db.getAlarms(Ci.nsINetworkInterface.NETWORK_TYPE_WIFI,
                                       testManifestURL, function onGet(error, result) {
       do_check_eq(error, null);
       do_check_eq(result.length, 1);
 
       // Result of getAlarms is based on expected child's data format, so
       // some changes are needed to be able to use it.
--- a/gfx/layers/LayerScope.cpp
+++ b/gfx/layers/LayerScope.cpp
@@ -5,16 +5,17 @@
 
 /* This must occur *after* layers/PLayers.h to avoid typedefs conflicts. */
 #include "LayerScope.h"
 
 #include "Composer2D.h"
 #include "Effects.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/Endian.h"
 #include "TexturePoolOGL.h"
 #include "mozilla/layers/TextureHostOGL.h"
 
 #include "gfxColor.h"
 #include "gfxContext.h"
 #include "gfxUtils.h"
 #include "gfxPlatform.h"
 #include "nsIWidget.h"
@@ -24,21 +25,26 @@
 #include "GLReadTexImageHelper.h"
 
 #include "nsIServiceManager.h"
 #include "nsIConsoleService.h"
 
 #include <memory>
 #include "mozilla/Compression.h"
 #include "mozilla/LinkedList.h"
+#include "mozilla/Base64.h"
+#include "mozilla/SHA1.h"
+#include "mozilla/StaticPtr.h"
 #include "nsThreadUtils.h"
 #include "nsISocketTransport.h"
 #include "nsIServerSocket.h"
+#include "nsReadLine.h"
 #include "nsNetCID.h"
 #include "nsIOutputStream.h"
+#include "nsIAsyncInputStream.h"
 #include "nsIEventTarget.h"
 #include "nsProxyRelease.h"
 
 #ifdef __GNUC__
 #define PACKED_STRUCT __attribute__((packed))
 #else
 #define PACKED_STRUCT
 #endif
@@ -47,23 +53,277 @@ namespace mozilla {
 namespace layers {
 
 using namespace mozilla::Compression;
 using namespace mozilla::gfx;
 using namespace mozilla::gl;
 using namespace mozilla;
 
 class DebugDataSender;
+class DebugGLData;
 
-static bool gDebugConnected = false;
-static nsCOMPtr<nsIServerSocket> gDebugServerSocket;
-static nsCOMPtr<nsIThread> gDebugSenderThread;
-static nsCOMPtr<nsISocketTransport> gDebugSenderTransport;
-static nsCOMPtr<nsIOutputStream> gDebugStream;
-static nsCOMPtr<DebugDataSender> gCurrentSender;
+/* This class handle websocket protocol which included
+ * handshake and data frame's header
+ */
+class LayerScopeWebSocketHandler : public nsIInputStreamCallback {
+public:
+    NS_DECL_THREADSAFE_ISUPPORTS
+
+    enum SocketStateType {
+        NoHandshake,
+        HandshakeSuccess,
+        HandshakeFailed
+    };
+
+    LayerScopeWebSocketHandler()
+        : mState(NoHandshake)
+    { }
+
+    virtual ~LayerScopeWebSocketHandler()
+    {
+        if (mTransport) {
+            mTransport->Close(NS_OK);
+        }
+    }
+
+    void OpenStream(nsISocketTransport* aTransport) {
+        MOZ_ASSERT(aTransport);
+
+        mTransport = aTransport;
+        mTransport->OpenOutputStream(nsITransport::OPEN_BLOCKING,
+                                     0,
+                                     0,
+                                     getter_AddRefs(mOutputStream));
+
+        nsCOMPtr<nsIInputStream> debugInputStream;
+        mTransport->OpenInputStream(0,
+                                    0,
+                                    0,
+                                    getter_AddRefs(debugInputStream));
+        mInputStream = do_QueryInterface(debugInputStream);
+        mInputStream->AsyncWait(this, 0, 0, NS_GetCurrentThread());
+    }
+
+    bool WriteToStream(void *ptr, uint32_t size) {
+        if (mState == NoHandshake) {
+            // Not yet handshake, just return true in case of
+            // LayerScope remove this handle
+            return true;
+        } else if (mState == HandshakeFailed) {
+            return false;
+        }
+
+        // Generate WebSocket header
+        uint8_t wsHeader[10];
+        int wsHeaderSize = 0;
+        const uint8_t opcode = 0x2;
+        wsHeader[0] = 0x80 | (opcode & 0x0f); // FIN + opcode;
+        if (size <= 125) {
+            wsHeaderSize = 2;
+            wsHeader[1] = size;
+        } else if (size < 65536) {
+            wsHeaderSize = 4;
+            wsHeader[1] = 0x7E;
+            NetworkEndian::writeUint16(wsHeader + 2, size);
+        } else {
+            wsHeaderSize = 10;
+            wsHeader[1] = 0x7F;
+            NetworkEndian::writeUint64(wsHeader + 2, size);
+        }
+
+        // Send WebSocket header
+        nsresult rv;
+        uint32_t cnt;
+        rv = mOutputStream->Write(reinterpret_cast<char*>(wsHeader),
+                                 wsHeaderSize, &cnt);
+        if (NS_FAILED(rv))
+            return false;
+
+        uint32_t written = 0;
+        while (written < size) {
+            uint32_t cnt;
+            rv = mOutputStream->Write(reinterpret_cast<char*>(ptr) + written,
+                                     size - written, &cnt);
+            if (NS_FAILED(rv))
+                return false;
+
+            written += cnt;
+        }
+
+        return true;
+    }
+
+    // nsIInputStreamCallback
+    NS_IMETHODIMP OnInputStreamReady(nsIAsyncInputStream *stream) MOZ_OVERRIDE
+    {
+        nsTArray<nsCString> protocolString;
+        ReadInputStreamData(protocolString);
+
+        if (WebSocketHandshake(protocolString)) {
+            mState = HandshakeSuccess;
+        } else {
+            mState = HandshakeFailed;
+        }
+        return NS_OK;
+    }
+private:
+    void ReadInputStreamData(nsTArray<nsCString>& aProtocolString)
+    {
+        nsLineBuffer<char> lineBuffer;
+        nsCString line;
+        bool more = true;
+        do {
+            NS_ReadLine(mInputStream.get(), &lineBuffer, line, &more);
+
+            if (line.Length() > 0) {
+                aProtocolString.AppendElement(line);
+            }
+        } while (more && line.Length() > 0);
+    }
+
+    bool WebSocketHandshake(nsTArray<nsCString>& aProtocolString)
+    {
+        nsresult rv;
+        bool isWebSocket = false;
+        nsCString version;
+        nsCString wsKey;
+        nsCString protocol;
+
+        // Validate WebSocket client request.
+        if (aProtocolString.Length() == 0)
+            return false;
+
+        // Check that the HTTP method is GET
+        const char* HTTP_METHOD = "GET ";
+        if (strncmp(aProtocolString[0].get(), HTTP_METHOD, strlen(HTTP_METHOD)) != 0) {
+            return false;
+        }
+
+        for (uint32_t i = 1; i < aProtocolString.Length(); ++i) {
+            const char* line = aProtocolString[i].get();
+            const char* prop_pos = strchr(line, ':');
+            if (prop_pos != nullptr) {
+                nsCString key(line, prop_pos - line);
+                nsCString value(prop_pos + 2);
+                if (key.EqualsIgnoreCase("upgrade") &&
+                    value.EqualsIgnoreCase("websocket")) {
+                    isWebSocket = true;
+                } else if (key.EqualsIgnoreCase("sec-websocket-version")) {
+                    version = value;
+                } else if (key.EqualsIgnoreCase("sec-websocket-key")) {
+                    wsKey = value;
+                } else if (key.EqualsIgnoreCase("sec-websocket-protocol")) {
+                    protocol = value;
+                }
+            }
+        }
+
+        if (!isWebSocket) {
+            return false;
+        }
+
+        if (!(version.Equals("7") || version.Equals("8") || version.Equals("13"))) {
+            return false;
+        }
+
+        if (!(protocol.EqualsIgnoreCase("binary"))) {
+            return false;
+        }
+
+        // Client request is valid. Start to generate and send server response.
+        nsAutoCString guid("258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
+        nsAutoCString res;
+        SHA1Sum sha1;
+        nsCString combined(wsKey + guid);
+        sha1.update(combined.get(), combined.Length());
+        uint8_t digest[SHA1Sum::HashSize]; // SHA1 digests are 20 bytes long.
+        sha1.finish(digest);
+        nsCString newString(reinterpret_cast<char*>(digest), SHA1Sum::HashSize);
+        Base64Encode(newString, res);
+
+        nsCString response("HTTP/1.1 101 Switching Protocols\r\n");
+        response.Append("Upgrade: websocket\r\n");
+        response.Append("Connection: Upgrade\r\n");
+        response.Append(nsCString("Sec-WebSocket-Accept: ") + res + nsCString("\r\n"));
+        response.Append("Sec-WebSocket-Protocol: binary\r\n\r\n");
+        uint32_t written = 0;
+        uint32_t size = response.Length();
+        while (written < size) {
+            uint32_t cnt;
+            rv = mOutputStream->Write(const_cast<char*>(response.get()) + written,
+                                     size - written, &cnt);
+            if (NS_FAILED(rv))
+                return false;
+
+            written += cnt;
+        }
+        mOutputStream->Flush();
+
+        return true;
+    }
+
+    nsCOMPtr<nsIOutputStream> mOutputStream;
+    nsCOMPtr<nsIAsyncInputStream> mInputStream;
+    nsCOMPtr<nsISocketTransport> mTransport;
+    SocketStateType mState;
+};
+
+NS_IMPL_ISUPPORTS1(LayerScopeWebSocketHandler, nsIInputStreamCallback);
+
+class LayerScopeWebSocketManager {
+public:
+    LayerScopeWebSocketManager();
+    ~LayerScopeWebSocketManager();
+
+    void AddConnection(nsISocketTransport *aTransport)
+    {
+        MOZ_ASSERT(aTransport);
+        nsRefPtr<LayerScopeWebSocketHandler> temp = new LayerScopeWebSocketHandler();
+        temp->OpenStream(aTransport);
+        mHandlers.AppendElement(temp.get());
+    }
+
+    void RemoveConnection(uint32_t aIndex)
+    {
+        MOZ_ASSERT(aIndex < mHandlers.Length());
+        mHandlers.RemoveElementAt(aIndex);
+    }
+
+    void RemoveAllConnections()
+    {
+        mHandlers.Clear();
+    }
+
+    bool WriteAll(void *ptr, uint32_t size)
+    {
+        for (int32_t i = mHandlers.Length() - 1; i >= 0; --i) {
+            if (!mHandlers[i]->WriteToStream(ptr, size)) {
+                // Send failed, remove this handler
+                RemoveConnection(i);
+            }
+        }
+
+        return true;
+    }
+
+    bool IsConnected()
+    {
+        return (mHandlers.Length() != 0) ? true : false;
+    }
+
+    void AppendDebugData(DebugGLData *aDebugData);
+    void DispatchDebugData();
+private:
+    nsTArray<nsRefPtr<LayerScopeWebSocketHandler> > mHandlers;
+    nsCOMPtr<nsIThread> mDebugSenderThread;
+    nsCOMPtr<DebugDataSender> mCurrentSender;
+    nsCOMPtr<nsIServerSocket> mServerSocket;
+};
+
+static StaticAutoPtr<LayerScopeWebSocketManager> gLayerScopeWebSocketManager;
 
 class DebugGLData : public LinkedListElement<DebugGLData> {
 public:
     typedef enum {
         FrameStart,
         FrameEnd,
         TextureData,
         ColorData
@@ -106,29 +366,19 @@ public:
         packet.type = mDataType;
         packet.ptr = static_cast<uint64_t>(mContextAddress);
         packet.value = mValue;
 
         return WriteToStream(&packet, sizeof(packet));
     }
 
     static bool WriteToStream(void *ptr, uint32_t size) {
-        uint32_t written = 0;
-        nsresult rv;
-        while (written < size) {
-            uint32_t cnt;
-            rv = gDebugStream->Write(reinterpret_cast<char*>(ptr) + written,
-                                     size - written, &cnt);
-            if (NS_FAILED(rv))
-                return false;
-
-            written += cnt;
-        }
-
-        return true;
+        if (!gLayerScopeWebSocketManager)
+            return true;
+        return gLayerScopeWebSocketManager->WriteAll(ptr, size);
     }
 
 protected:
     DataType mDataType;
     intptr_t mContextAddress;
     int64_t mValue;
 
 public:
@@ -279,51 +529,44 @@ protected:
     void *mLayerRef;
     uint32_t mColor;
     nsIntSize mSize;
 };
 
 static bool
 CheckSender()
 {
-    if (!gDebugConnected)
+    if (!gLayerScopeWebSocketManager)
         return false;
 
-    // At some point we may want to support sending
-    // data in between frames.
-#if 1
-    if (!gCurrentSender)
+    if (!gLayerScopeWebSocketManager->IsConnected())
         return false;
-#else
-    if (!gCurrentSender)
-        gCurrentSender = new DebugDataSender();
-#endif
 
     return true;
 }
 
-
 class DebugListener : public nsIServerSocketListener
 {
 public:
 
     NS_DECL_THREADSAFE_ISUPPORTS
 
     DebugListener() { }
     virtual ~DebugListener() { }
 
     /* nsIServerSocketListener */
 
     NS_IMETHODIMP OnSocketAccepted(nsIServerSocket *aServ,
                                    nsISocketTransport *aTransport)
     {
+        if (!gLayerScopeWebSocketManager)
+            return NS_OK;
+
         printf_stderr("*** LayerScope: Accepted connection\n");
-        gDebugConnected = true;
-        gDebugSenderTransport = aTransport;
-        aTransport->OpenOutputStream(nsITransport::OPEN_BLOCKING, 0, 0, getter_AddRefs(gDebugStream));
+        gLayerScopeWebSocketManager->AddConnection(aTransport);
         return NS_OK;
     }
 
     NS_IMETHODIMP OnStopListening(nsIServerSocket *aServ,
                                   nsresult aStatus)
     {
         return NS_OK;
     }
@@ -363,38 +606,28 @@ public:
     }
 
     /* nsIRunnable impl; send the data */
 
     NS_IMETHODIMP Run() {
         DebugGLData *d;
         nsresult rv = NS_OK;
 
-        // If we got closed while trying to write some stuff earlier, just
-        // throw away everything.
-        if (!gDebugStream) {
-            Cleanup();
-            return NS_OK;
-        }
-
         while ((d = mList->popFirst()) != nullptr) {
             std::auto_ptr<DebugGLData> cleaner(d);
             if (!d->Write()) {
                 rv = NS_ERROR_FAILURE;
                 break;
             }
         }
 
         Cleanup();
 
         if (NS_FAILED(rv)) {
-            gDebugSenderTransport->Close(rv);
-            gDebugConnected = false;
-            gDebugStream = nullptr;
-            gDebugServerSocket = nullptr;
+            LayerScope::DestroyServerSocket();
         }
 
         return NS_OK;
     }
 
 protected:
     LinkedList<DebugGLData> *mList;
 };
@@ -403,72 +636,66 @@ NS_IMPL_ISUPPORTS1(DebugDataSender, nsIR
 
 void
 LayerScope::CreateServerSocket()
 {
     if (!Preferences::GetBool("gfx.layerscope.enabled", false)) {
         return;
     }
 
-    if (!gDebugSenderThread) {
-        NS_NewThread(getter_AddRefs(gDebugSenderThread));
-    }
-
-    if (!gDebugServerSocket) {
-        gDebugServerSocket = do_CreateInstance(NS_SERVERSOCKET_CONTRACTID);
-        int port = Preferences::GetInt("gfx.layerscope.port", 23456);
-        gDebugServerSocket->Init(port, false, -1);
-        gDebugServerSocket->AsyncListen(new DebugListener);
+    if (!gLayerScopeWebSocketManager) {
+        gLayerScopeWebSocketManager = new LayerScopeWebSocketManager();
     }
 }
 
 void
 LayerScope::DestroyServerSocket()
 {
-    gDebugConnected = false;
-    gDebugStream = nullptr;
-    gDebugServerSocket = nullptr;
+    if (gLayerScopeWebSocketManager) {
+        gLayerScopeWebSocketManager->RemoveAllConnections();
+    }
 }
 
 void
 LayerScope::BeginFrame(GLContext* aGLContext, int64_t aFrameStamp)
 {
-    if (!gDebugConnected)
+    if (!gLayerScopeWebSocketManager)
+        return;
+
+    if (!gLayerScopeWebSocketManager->IsConnected())
         return;
 
 #if 0
     // if we're sending data in between frames, flush the list down the socket,
     // and start a new one
     if (gCurrentSender) {
         gDebugSenderThread->Dispatch(gCurrentSender, NS_DISPATCH_NORMAL);
     }
 #endif
 
-    gCurrentSender = new DebugDataSender();
-    gCurrentSender->Append(new DebugGLData(DebugGLData::FrameStart, aGLContext, aFrameStamp));
+    gLayerScopeWebSocketManager->AppendDebugData(new DebugGLData(DebugGLData::FrameStart, aGLContext, aFrameStamp));
 }
 
 void
 LayerScope::EndFrame(GLContext* aGLContext)
 {
     if (!CheckSender())
         return;
 
-    gCurrentSender->Append(new DebugGLData(DebugGLData::FrameEnd, aGLContext));
-    gDebugSenderThread->Dispatch(gCurrentSender, NS_DISPATCH_NORMAL);
-    gCurrentSender = nullptr;
+    gLayerScopeWebSocketManager->AppendDebugData(new DebugGLData(DebugGLData::FrameEnd, aGLContext));
+    gLayerScopeWebSocketManager->DispatchDebugData();
 }
 
 static void
 SendColor(void* aLayerRef, const gfxRGBA& aColor, int aWidth, int aHeight)
 {
     if (!CheckSender())
         return;
 
-    gCurrentSender->Append(
+    gLayerScopeWebSocketManager->AppendDebugData(
         new DebugGLColorData(aLayerRef, aColor, aWidth, aHeight));
 }
 
 static void
 SendTextureSource(GLContext* aGLContext,
                   void* aLayerRef,
                   TextureSourceOGL* aSource,
                   bool aFlipY)
@@ -495,17 +722,17 @@ SendTextureSource(GLContext* aGLContext,
 
     // By sending 0 to ReadTextureImage rely upon aSource->BindTexture binding
     // texture correctly. textureId is used for tracking in DebugGLTextureData.
     nsRefPtr<gfxImageSurface> img =
         aGLContext->ReadTexImageHelper()->ReadTexImage(0, textureTarget,
                                                        gfxIntSize(size.width, size.height),
                                                        shaderProgram, aFlipY);
 
-    gCurrentSender->Append(
+    gLayerScopeWebSocketManager->AppendDebugData(
         new DebugGLTextureData(aGLContext, aLayerRef, textureTarget,
                                textureId, img));
 }
 
 static void
 SendTexturedEffect(GLContext* aGLContext,
                    void* aLayerRef,
                    const TexturedEffect* aEffect)
@@ -580,10 +807,39 @@ LayerScope::SendEffectChain(GLContext* a
     default:
         break;
     }
 
     //const Effect* secondaryEffect = aEffectChain.mSecondaryEffects[EFFECT_MASK];
     // TODO:
 }
 
+LayerScopeWebSocketManager::LayerScopeWebSocketManager()
+{
+    NS_NewThread(getter_AddRefs(mDebugSenderThread));
+
+    mServerSocket = do_CreateInstance(NS_SERVERSOCKET_CONTRACTID);
+    int port = Preferences::GetInt("gfx.layerscope.port", 23456);
+    mServerSocket->Init(port, false, -1);
+    mServerSocket->AsyncListen(new DebugListener);
+}
+
+LayerScopeWebSocketManager::~LayerScopeWebSocketManager()
+{
+}
+
+void LayerScopeWebSocketManager::AppendDebugData(DebugGLData *aDebugData)
+{
+    if (!mCurrentSender) {
+        mCurrentSender = new DebugDataSender();
+    }
+
+    mCurrentSender->Append(aDebugData);
+}
+
+void LayerScopeWebSocketManager::DispatchDebugData()
+{
+    mDebugSenderThread->Dispatch(mCurrentSender, NS_DISPATCH_NORMAL);
+    mCurrentSender = nullptr;
+}
+
 } /* layers */
 } /* mozilla */
--- a/mozglue/build/Nuwa.cpp
+++ b/mozglue/build/Nuwa.cpp
@@ -10,16 +10,17 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <setjmp.h>
 #include <signal.h>
 #include <poll.h>
 #include <pthread.h>
 #include <alloca.h>
 #include <sys/epoll.h>
+#include <sys/mman.h>
 #include <sys/prctl.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/syscall.h>
 #include <vector>
 
 #include "mozilla/LinkedList.h"
@@ -136,17 +137,19 @@ typedef std::vector<std::pair<pthread_ke
 TLSInfoList;
 
 /**
  * The stack size is chosen carefully so the frozen threads doesn't consume too
  * much memory in the Nuwa process. The threads shouldn't run deep recursive
  * methods or do large allocations on the stack to avoid stack overflow.
  */
 #ifndef NUWA_STACK_SIZE
-#define NUWA_STACK_SIZE (1024 * 32)
+#define PAGE_SIZE 4096
+#define PAGE_ALIGN_MASK 0xfffff000
+#define NUWA_STACK_SIZE (1024 * 128)
 #endif
 
 #define NATIVE_THREAD_NAME_LENGTH 16
 
 struct thread_info : public mozilla::LinkedListElement<thread_info> {
   pthread_t origThreadID;
   pthread_t recreatedThreadID;
   pthread_attr_t threadAttr;
@@ -484,17 +487,28 @@ thread_info_new(void) {
   /* link tinfo to sAllThreads */
   thread_info_t *tinfo = new thread_info_t();
   tinfo->flags = 0;
   tinfo->recrFunc = nullptr;
   tinfo->recrArg = nullptr;
   tinfo->recreatedThreadID = 0;
   tinfo->recreatedNativeThreadID = 0;
   tinfo->reacquireMutex = nullptr;
-  tinfo->stk = malloc(NUWA_STACK_SIZE);
+  tinfo->stk = malloc(NUWA_STACK_SIZE + PAGE_SIZE);
+
+  // We use a smaller stack size. Add protection to stack overflow: mprotect()
+  // stack top (the page at the lowest address) so we crash instead of corrupt
+  // other content that is malloc()'d.
+  unsigned long long pageGuard = ((unsigned long long)tinfo->stk);
+  pageGuard &= PAGE_ALIGN_MASK;
+  if (pageGuard != (unsigned long long) tinfo->stk) {
+    pageGuard += PAGE_SIZE; // Round up to be page-aligned.
+  }
+  mprotect((void*)pageGuard, PAGE_SIZE, PROT_READ);
+
   pthread_attr_init(&tinfo->threadAttr);
 
   REAL(pthread_mutex_lock)(&sThreadCountLock);
   // Insert to the tail.
   sAllThreads.insertBack(tinfo);
 
   sThreadCount++;
   pthread_cond_signal(&sThreadChangeCond);