Merge b2g-inbound to m-c. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Mon, 23 Jun 2014 10:56:03 -0400
changeset 190107 31de1a84b27f
parent 190009 4a7f4ed3f08b (current diff)
parent 190106 4d5236286724 (diff)
child 190134 8bbe0aa72547
child 190173 007a3b5039a4
child 190206 c65bf5a0595c
push id27000
push userryanvm@gmail.com
push dateMon, 23 Jun 2014 14:56:05 +0000
treeherdermozilla-central@31de1a84b27f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone33.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge b2g-inbound to m-c. a=merge
dom/apps/src/Webapps.jsm
dom/mobileconnection/tests/marionette/mobile_header.js
layout/style/CSSStyleSheet.cpp
layout/style/CSSStyleSheet.h
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,23 +14,23 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c">
     <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="bd5065ced020014df5fd45259fba1ac32d65673b"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="3326b51017252e09ccdd715dec6c5e12a7d1ecfe"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8ba14125aba912707f44761f194339e6e59701b7"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="23db533981ee2cd04fc5d946420402aed2792381"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
   <project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="425f8b5fadf5889834c5acd27d23c9e0b2129c28"/>
   <project name="device/common" path="device/common" revision="42b808b7e93d0619286ae8e59110b176b7732389"/>
   <project name="device/sample" path="device/sample" revision="237bd668d0f114d801a8d6455ef5e02cc3577587"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
   <project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="52a1a862a8bac319652b8f82d9541ba40bfa45ce"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,20 +12,20 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="cc67f31dc638c0b7edba3cf7e3d87cadf0ed52bf">
     <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="bd5065ced020014df5fd45259fba1ac32d65673b"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8ba14125aba912707f44761f194339e6e59701b7"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="23db533981ee2cd04fc5d946420402aed2792381"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
@@ -123,14 +123,14 @@
   <project name="platform/system/security" path="system/security" revision="f48ff68fedbcdc12b570b7699745abb6e7574907"/>
   <project name="platform/system/vold" path="system/vold" revision="8de05d4a52b5a91e7336e6baa4592f945a6ddbea"/>
   <default remote="caf" revision="refs/tags/android-4.3_r2.1" sync-j="4"/>
   <!-- Emulator specific things -->
   <project name="android-development" path="development" remote="b2g" revision="dab55669da8f48b6e57df95d5af9f16b4a87b0b1"/>
   <project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="3a9a17613cc685aa232432566ad6cc607eab4ec1"/>
   <project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="0e31f35a2a77301e91baa8a237aa9e9fa4076084"/>
   <project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/>
-  <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="973367035a1f2545f3dad6e40e354463dc56a7f4"/>
+  <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="346c7694b156a3933f3d87cbc077c657e2ce571f"/>
   <project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="832f4acaf481a19031e479a40b03d9ce5370ddee"/>
   <project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="d0aa65b140a45016975ed0ecf35f280dd336e1d3"/>
   <project name="android-sdk" path="sdk" remote="b2g" revision="8b1365af38c9a653df97349ee53a3f5d64fd590a"/>
 </manifest>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,25 +10,25 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="276ce45e78b09c4a4ee643646f691d22804754c1">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="bd5065ced020014df5fd45259fba1ac32d65673b"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8ba14125aba912707f44761f194339e6e59701b7"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="23db533981ee2cd04fc5d946420402aed2792381"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="1950e4760fa14688b83cdbb5acaa1af9f82ef434"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="ac6eb97a37035c09fb5ede0852f0881e9aadf9ad"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="737f591c5f95477148d26602c7be56cbea0cdeb9"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="51da9b1981be481b92a59a826d4d78dc73d0989a"/>
   <project name="device/common" path="device/common" revision="798a3664597e6041985feab9aef42e98d458bc3d"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,23 +14,23 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c">
     <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="bd5065ced020014df5fd45259fba1ac32d65673b"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="3326b51017252e09ccdd715dec6c5e12a7d1ecfe"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8ba14125aba912707f44761f194339e6e59701b7"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="23db533981ee2cd04fc5d946420402aed2792381"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
   <project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="425f8b5fadf5889834c5acd27d23c9e0b2129c28"/>
   <project name="device/common" path="device/common" revision="42b808b7e93d0619286ae8e59110b176b7732389"/>
   <project name="device/sample" path="device/sample" revision="237bd668d0f114d801a8d6455ef5e02cc3577587"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
   <project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="52a1a862a8bac319652b8f82d9541ba40bfa45ce"/>
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -12,20 +12,20 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="cc67f31dc638c0b7edba3cf7e3d87cadf0ed52bf">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="bd5065ced020014df5fd45259fba1ac32d65673b"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8ba14125aba912707f44761f194339e6e59701b7"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="23db533981ee2cd04fc5d946420402aed2792381"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="e95b4ce22c825da44d14299e1190ea39a5260bde"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="471afab478649078ad7c75ec6b252481a59e19b8"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
         "git_revision": "", 
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "387f4c0123a7e82eae4c83f88f73e81f907c00e2", 
+    "revision": "aba00cfd579caaf205e05c269f0a8100f242f39c", 
     "repo_path": "/integration/gaia-central"
 }
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -12,22 +12,22 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c">
     <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="bd5065ced020014df5fd45259fba1ac32d65673b"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8ba14125aba912707f44761f194339e6e59701b7"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="23db533981ee2cd04fc5d946420402aed2792381"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="746bc48f34f5060f90801925dcdd964030c1ab6d"/>
   <project name="platform/development" path="development" revision="2460485184bc8535440bb63876d4e63ec1b4770c"/>
   <project name="device/common" path="device/common" revision="0dcc1e03659db33b77392529466f9eb685cdd3c7"/>
   <project name="device/sample" path="device/sample" revision="68b1cb978a20806176123b959cb05d4fa8adaea4"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -10,18 +10,18 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c">
     <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="bd5065ced020014df5fd45259fba1ac32d65673b"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/>
   <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"/>
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -12,20 +12,20 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="cc67f31dc638c0b7edba3cf7e3d87cadf0ed52bf">
     <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="bd5065ced020014df5fd45259fba1ac32d65673b"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8ba14125aba912707f44761f194339e6e59701b7"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="23db533981ee2cd04fc5d946420402aed2792381"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -12,22 +12,22 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c">
     <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="bd5065ced020014df5fd45259fba1ac32d65673b"/>
-  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="44b04243e31cd16f3baf54fcd4b5fecf9deb8b94"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/>
+  <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8ba14125aba912707f44761f194339e6e59701b7"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="23db533981ee2cd04fc5d946420402aed2792381"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="cd5dfce80bc3f0139a56b58aca633202ccaee7f8"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="e0a9ac010df3afaa47ba107192c05ac8b5516435"/>
   <project name="platform/development" path="development" revision="a384622f5fcb1d2bebb9102591ff7ae91fe8ed2d"/>
   <project name="device/common" path="device/common" revision="7c65ea240157763b8ded6154a17d3c033167afb7"/>
   <project name="device/sample" path="device/sample" revision="c328f3d4409db801628861baa8d279fb8855892f"/>
--- a/dom/apps/src/Webapps.jsm
+++ b/dom/apps/src/Webapps.jsm
@@ -1311,16 +1311,22 @@ this.DOMApplicationRegistry = {
     } else if (download.channel) {
       try {
         download.channel.cancel(Cr.NS_BINDING_ABORTED);
       } catch(e) { }
     } else {
       return;
     }
 
+    // Ensure we don't send additional errors for this download
+    app.isCanceling = true;
+
+    // Ensure this app can be downloaded again after canceling
+    app.downloading = false;
+
     this._saveApps().then(() => {
       this.broadcastMessage("Webapps:UpdateState", {
         app: {
           progress: 0,
           installState: download.previousState,
           downloading: false
         },
         error: error,
@@ -1334,16 +1340,17 @@ this.DOMApplicationRegistry = {
     AppDownloadManager.remove(aManifestURL);
   },
 
   startDownload: Task.async(function*(aManifestURL) {
     debug("startDownload for " + aManifestURL);
 
     let id = this._appIdForManifestURL(aManifestURL);
     let app = this.webapps[id];
+
     if (!app) {
       debug("startDownload: No app found for " + aManifestURL);
       throw new Error("NO_SUCH_APP");
     }
 
     if (app.downloading) {
       debug("app is already downloading. Ignoring.");
       throw new Error("APP_IS_DOWNLOADING");
@@ -2765,16 +2772,24 @@ this.DOMApplicationRegistry = {
       // We determine the app's 'installState' according to its previous
       // state. Cancelled download should remain as 'pending'. Successfully
       // installed apps should morph to 'updating'.
       oldApp.installState = aIsUpdate ? "updating" : "pending";
 
       // initialize the progress to 0 right now
       oldApp.progress = 0;
 
+      // Save the current state of the app to handle cases where we may be
+      // retrying a past download.
+      yield DOMApplicationRegistry._saveApps();
+      DOMApplicationRegistry.broadcastMessage("Webapps:UpdateState", {
+        app: oldApp,
+        manifestURL: aNewApp.manifestURL
+      });
+
       let zipFile = yield this._getPackage(requestChannel, id, oldApp, aNewApp);
       let hash = yield this._computeFileHash(zipFile.path);
 
       let responseStatus = requestChannel.responseStatus;
       let oldPackage = (responseStatus == 304 || hash == oldApp.packageHash);
 
       if (oldPackage) {
         debug("package's etag or hash unchanged; sending 'applied' event");
@@ -4078,26 +4093,34 @@ AppcacheObserver.prototype = {
         eventType: ["downloadsuccess", "downloadapplied"],
         manifestURL: app.manifestURL
       });
     }
 
     let setError = function appObs_setError(aError) {
       debug("Offlinecache setError to " + aError);
       app.downloading = false;
+      mustSave = true;
+
+      // If we are canceling the download, we already send a DOWNLOAD_CANCELED
+      // error.
+      if (app.isCanceling) {
+        delete app.isCanceling;
+        return;
+      }
+
       DOMApplicationRegistry.broadcastMessage("Webapps:UpdateState", {
         app: app,
         error: aError,
         manifestURL: app.manifestURL
       });
       DOMApplicationRegistry.broadcastMessage("Webapps:FireEvent", {
         eventType: "downloaderror",
         manifestURL: app.manifestURL
       });
-      mustSave = true;
     }
 
     switch (aState) {
       case Ci.nsIOfflineCacheUpdateObserver.STATE_ERROR:
         aUpdate.removeObserver(this);
         AppDownloadManager.remove(app.manifestURL);
         setError("APP_CACHE_DOWNLOAD_ERROR");
         break;
--- a/dom/bluetooth2/BluetoothAdapter.cpp
+++ b/dom/bluetooth2/BluetoothAdapter.cpp
@@ -694,17 +694,20 @@ BluetoothAdapter::EnableDisable(bool aEn
       promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
       return promise.forget();
     }
     methodName.AssignLiteral("Disable");
     mState = BluetoothAdapterState::Disabling;
   }
 
   nsTArray<nsString> types;
-  types.AppendElement(NS_LITERAL_STRING("State"));
+  BT_APPEND_ENUM_STRING(types,
+                        BluetoothAdapterAttribute,
+                        BluetoothAdapterAttribute::State);
+
   DispatchAttributeEvent(types);
 
   nsRefPtr<BluetoothReplyRunnable> result =
     new BluetoothVoidReplyRunnable(nullptr, /* DOMRequest */
                                    promise,
                                    methodName);
 
   if(NS_FAILED(bs->EnableDisable(aEnable, result))) {
@@ -787,17 +790,17 @@ BluetoothAdapter::HandlePropertyChanged(
     if (type == BluetoothAdapterAttribute::Unknown) {
       SetPropertyByValue(arr[i]);
       continue;
     }
 
     // BluetoothAdapterAttribute properties
     if (IsAdapterAttributeChanged(type, arr[i].value())) {
       SetPropertyByValue(arr[i]);
-      types.AppendElement(arr[i].name());
+      BT_APPEND_ENUM_STRING(types, BluetoothAdapterAttribute, type);
     }
   }
 
   DispatchAttributeEvent(types);
 }
 
 void
 BluetoothAdapter::DispatchAttributeEvent(const nsTArray<nsString>& aTypes)
--- a/dom/bluetooth2/BluetoothCommon.h
+++ b/dom/bluetooth2/BluetoothCommon.h
@@ -78,16 +78,28 @@ extern bool gBluetoothDebugFlag;
   do {                                                               \
     if (!BroadcastSystemMessage(type, parameters)) {                 \
       BT_WARNING("Failed to broadcast [%s]",                         \
                  NS_ConvertUTF16toUTF8(type).get());                 \
       return;                                                        \
     }                                                                \
   } while(0)
 
+/**
+ * Convert an enum value to string then append it to an array.
+ */
+#define BT_APPEND_ENUM_STRING(array, enumType, enumValue)            \
+  do {                                                               \
+    uint32_t index = uint32_t(enumValue);                            \
+    nsAutoString name;                                               \
+    name.AssignASCII(enumType##Values::strings[index].value,         \
+                     enumType##Values::strings[index].length);       \
+    array.AppendElement(name);                                       \
+  } while(0)                                                         \
+
 #define BEGIN_BLUETOOTH_NAMESPACE \
   namespace mozilla { namespace dom { namespace bluetooth {
 #define END_BLUETOOTH_NAMESPACE \
   } /* namespace bluetooth */ } /* namespace dom */ } /* namespace mozilla */
 #define USING_BLUETOOTH_NAMESPACE \
   using namespace mozilla::dom::bluetooth;
 
 #define KEY_LOCAL_AGENT  "/B2G/bluetooth/agent"
--- a/dom/bluetooth2/BluetoothManager.cpp
+++ b/dom/bluetooth2/BluetoothManager.cpp
@@ -255,17 +255,19 @@ BluetoothManager::DispatchAttributeEvent
   NS_ENSURE_TRUE_VOID(global);
 
   JS::Rooted<JSObject*> scope(cx, global->GetGlobalJSObject());
   NS_ENSURE_TRUE_VOID(scope);
 
   JSAutoCompartment ac(cx, scope);
 
   nsTArray<nsString> types;
-  types.AppendElement(NS_LITERAL_STRING("DefaultAdapter"));
+  BT_APPEND_ENUM_STRING(types,
+                        BluetoothManagerAttribute,
+                        BluetoothManagerAttribute::DefaultAdapter);
 
   if (!ToJSValue(cx, types, &value)) {
     JS_ClearPendingException(cx);
     return;
   }
 
   // Notify application of default adapter change
   RootedDictionary<BluetoothAttributeEventInit> init(cx);
--- a/dom/mobileconnection/tests/marionette/head.js
+++ b/dom/mobileconnection/tests/marionette/head.js
@@ -561,29 +561,77 @@ function sendMMI(aMmi) {
   return wrapDomRequestAsPromise(request)
     .then(null, () => { throw request.error });
 }
 
 /**
  * Query current voice privacy mode.
  *
  * Fulfill params:
-     A boolean indicates the current voice privacy mode.
+ *   A boolean indicates the current voice privacy mode.
  * Reject params:
  *   'RadioNotAvailable', 'RequestNotSupported', or 'GenericFailure'.
  *
  * @return A deferred promise.
  */
  function getVoicePrivacyMode() {
   let request = mobileConnection.getVoicePrivacyMode();
   return wrapDomRequestAsPromise(request)
     .then(() => request.result, () => { throw request.error });
 }
 
 /**
+ * Configures call barring options.
+ *
+ * Fulfill params: (none)
+ * Reject params:
+ *   'RadioNotAvailable', 'RequestNotSupported', 'InvalidParameter' or
+ *   'GenericFailure'.
+ *
+ * @return A deferred promise.
+ */
+ function setCallBarringOption(aOptions) {
+  let request = mobileConnection.setCallBarringOption(aOptions);
+  return wrapDomRequestAsPromise(request)
+    .then(null, () => { throw request.error });
+}
+
+/**
+ * Queries current call barring status.
+ *
+ * Fulfill params:
+ *   An object contains call barring status.
+ * Reject params:
+ *   'RadioNotAvailable', 'RequestNotSupported', 'InvalidParameter' or
+ *   'GenericFailure'.
+ *
+ * @return A deferred promise.
+ */
+ function getCallBarringOption(aOptions) {
+  let request = mobileConnection.getCallBarringOption(aOptions);
+  return wrapDomRequestAsPromise(request)
+    .then(() => request.result, () => { throw request.error });
+}
+
+/**
+ * Change call barring facility password.
+ *
+ * Fulfill params: (none)
+ * Reject params:
+ *   'RadioNotAvailable', 'RequestNotSupported', or 'GenericFailure'.
+ *
+ * @return A deferred promise.
+ */
+ function changeCallBarringPassword(aOptions) {
+  let request = mobileConnection.changeCallBarringPassword(aOptions);
+  return wrapDomRequestAsPromise(request)
+    .then(null, () => { throw request.error });
+}
+
+/**
  * Set data connection enabling state and wait for "datachange" event.
  *
  * Resolve if data connection state changed to the expected one.  Never reject.
  *
  * Fulfill params: (none)
  *
  * @param aEnabled
  *        A boolean state.
@@ -954,16 +1002,104 @@ function setEmulatorOperatorNamesAndWait
   if (aWaitData) {
     promises.push(waitForManagerEvent("datachange"));
   }
   promises.push(setEmulatorOperatorNames(aOperator, aLongName, aShortName,
                                          aMcc, aMnc));
   return Promise.all(promises);
 }
 
+/**
+ * Set GSM signal strength.
+ *
+ * Fulfill params: (none)
+ * Reject params: (none)
+ *
+ * @param aRssi
+ *
+ * @return A deferred promise.
+ */
+function setEmulatorGsmSignalStrength(aRssi) {
+  let cmd = "gsm signal " + aRssi;
+  return runEmulatorCmdSafe(cmd);
+}
+
+/**
+ * Set emulator GSM signal strength and wait for voice and/or data state change.
+ *
+ * Fulfill params: (none)
+ *
+ * @param aRssi
+ * @param aWaitVoice [optional]
+ *        A boolean value.  Default true.
+ * @param aWaitData [optional]
+ *        A boolean value.  Default false.
+ *
+ * @return A deferred promise.
+ */
+function setEmulatorGsmSignalStrengthAndWait(aRssi,
+                                             aWaitVoice = true,
+                                             aWaitData = false) {
+  let promises = [];
+  if (aWaitVoice) {
+    promises.push(waitForManagerEvent("voicechange"));
+  }
+  if (aWaitData) {
+    promises.push(waitForManagerEvent("datachange"));
+  }
+  promises.push(setEmulatorGsmSignalStrength(aRssi));
+  return Promise.all(promises);
+}
+
+/**
+ * Set LTE signal strength.
+ *
+ * Fulfill params: (none)
+ * Reject params: (none)
+ *
+ * @param aRxlev
+ * @param aRsrp
+ * @param aRssnr
+ *
+ * @return A deferred promise.
+ */
+function setEmulatorLteSignalStrength(aRxlev, aRsrp, aRssnr) {
+  let cmd = "gsm lte_signal " + aRxlev + " " + aRsrp + " " + aRssnr;
+  return runEmulatorCmdSafe(cmd);
+}
+
+/**
+ * Set emulator LTE signal strength and wait for voice and/or data state change.
+ *
+ * Fulfill params: (none)
+ *
+ * @param aRxlev
+ * @param aRsrp
+ * @param aRssnr
+ * @param aWaitVoice [optional]
+ *        A boolean value.  Default true.
+ * @param aWaitData [optional]
+ *        A boolean value.  Default false.
+ *
+ * @return A deferred promise.
+ */
+function setEmulatorLteSignalStrengthAndWait(aRxlev, aRsrp, aRssnr,
+                                             aWaitVoice = true,
+                                             aWaitData = false) {
+  let promises = [];
+  if (aWaitVoice) {
+    promises.push(waitForManagerEvent("voicechange"));
+  }
+  if (aWaitData) {
+    promises.push(waitForManagerEvent("datachange"));
+  }
+  promises.push(setEmulatorLteSignalStrength(aRxlev, aRsrp, aRssnr));
+  return Promise.all(promises);
+}
+
 let _networkManager;
 
 /**
  * Get internal NetworkManager service.
  */
 function getNetworkManager() {
   if (!_networkManager) {
     _networkManager = Cc["@mozilla.org/network/manager;1"]
deleted file mode 100644
--- a/dom/mobileconnection/tests/marionette/mobile_header.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-SpecialPowers.addPermission("mobileconnection", true, document);
-
-// In single sim scenario, there is only one mobileConnection, we can always use
-// the first instance.
-let mobileConnection = window.navigator.mozMobileConnections[0];
-ok(mobileConnection instanceof MozMobileConnection,
-   "mobileConnection is instanceof " + mobileConnection.constructor);
-
-let _pendingEmulatorCmdCount = 0;
-
-/* Remove permission and execute finish() */
-let cleanUp = function() {
-  waitFor(function() {
-    SpecialPowers.removePermission("mobileconnection", document);
-    finish();
-  }, function() {
-    return _pendingEmulatorCmdCount === 0;
-  });
-};
-
-/* Helper for tasks */
-let taskHelper = {
-  tasks: [],
-
-  push: function(task) {
-    this.tasks.push(task);
-  },
-
-  runNext: function() {
-    let task = this.tasks.shift();
-    if (!task) {
-      cleanUp();
-      return;
-    }
-
-    if (typeof task === "function") {
-      task();
-    }
-  },
-};
-
-/* Helper for emulator console command */
-let emulatorHelper = {
-  sendCommand: function(cmd, callback) {
-    _pendingEmulatorCmdCount++;
-    runEmulatorCmd(cmd, function(results) {
-      _pendingEmulatorCmdCount--;
-
-      let result = results[results.length - 1];
-      is(result, "OK", "'"+ cmd +"' returns '" + result + "'");
-
-      if (callback && typeof callback === "function") {
-        callback(results);
-      }
-    });
-  },
-};
--- a/dom/mobileconnection/tests/marionette/test_call_barring_change_password.js
+++ b/dom/mobileconnection/tests/marionette/test_call_barring_change_password.js
@@ -1,63 +1,50 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 MARIONETTE_TIMEOUT = 60000;
+MARIONETTE_HEAD_JS = "head.js";
 
-SpecialPowers.addPermission("mobileconnection", true, document);
+const TEST_DATA = [
+  // [<pin>, <new pin>, <expected error>]
 
-// Permission changes can't change existing Navigator.prototype
-// objects, so grab our objects from a new Navigator
-let ifr = document.createElement("iframe");
-let connection;
-ifr.onload = function() {
-  connection = ifr.contentWindow.navigator.mozMobileConnections[0];
+  // Test passing an invalid pin or newPin.
+  [null, "0000", "InvalidPassword"],
+  ["0000", null, "InvalidPassword"],
+  [null, null, "InvalidPassword"],
 
-  ok(connection instanceof ifr.contentWindow.MozMobileConnection,
-     "connection is instanceof " + connection.constructor);
-
-  setTimeout(testChangeCallBarringPasswordWithFailure, 0);
-};
-document.body.appendChild(ifr);
+  // Test passing mismatched newPin.
+  ["000", "0000", "InvalidPassword"],
+  ["00000", "1111", "InvalidPassword"],
+  ["abcd", "efgh", "InvalidPassword"],
 
-function testChangeCallBarringPasswordWithFailure() {
-  // Incorrect parameters, expect onerror callback.
-  let options = [
-    {pin: null, newPin: '0000'},
-    {pin: '0000', newPin: null},
-    {pin: null, newPin: null},
-    {pin: '000', newPin: '0000'},
-    {pin: '00000', newPin: '1111'},
-    {pin: 'abcd', newPin: 'efgh'},
-  ];
+  // TODO: Bug 906603 - B2G RIL: Support Change Call Barring Password on Emulator.
+  // Currently emulator doesn't support REQUEST_CHANGE_BARRING_PASSWORD, so we
+  // expect to get a 'RequestNotSupported' error here.
+  ["1234", "1234", "RequestNotSupported"]
+];
 
-  function do_test() {
-    for (let i = 0; i < options.length; i++) {
-      let request = connection.changeCallBarringPassword(options[i]);
+function testChangeCallBarringPassword(aPin, aNewPin, aExpectedError) {
+  log("Test changing call barring password to " + aPin + "/" + aNewPin);
 
-      request.onsuccess = function() {
-        ok(false, 'Unexpected result.');
-        setTimeout(cleanUp , 0);
-      };
-
-      request.onerror = function() {
-        ok(request.error.name === 'InvalidPassword', 'InvalidPassword');
-        if (i >= options.length) {
-          setTimeout(testChangeCallBarringPasswordWithSuccess, 0);
-        }
-      };
-    }
-  }
-
-  do_test();
+  let options = {
+    pin: aPin,
+    newPin: aNewPin
+  };
+  return changeCallBarringPassword(options)
+    .then(function resolve() {
+      ok(!aExpectedError, "changeCallBarringPassword success");
+    }, function reject(aError) {
+      is(aError.name, aExpectedError, "failed to changeCallBarringPassword");
+    });
 }
 
-function testChangeCallBarringPasswordWithSuccess() {
-  // TODO: Bug 906603 - B2G RIL: Support Change Call Barring Password on
-  // Emulator.
-  setTimeout(cleanUp , 0);
-}
-
-function cleanUp() {
-  SpecialPowers.removePermission("mobileconnection", document);
-  finish();
-}
+// Start tests
+startTestCommon(function() {
+  let promise = Promise.resolve();
+  for (let i = 0; i < TEST_DATA.length; i++) {
+    let data = TEST_DATA[i];
+    promise =
+      promise.then(() => testChangeCallBarringPassword(data[0], data[1], data[2]));
+  }
+  return promise;
+});
--- a/dom/mobileconnection/tests/marionette/test_call_barring_get_option.js
+++ b/dom/mobileconnection/tests/marionette/test_call_barring_get_option.js
@@ -1,39 +1,74 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 MARIONETTE_TIMEOUT = 60000;
-
-SpecialPowers.addPermission("mobileconnection", true, document);
-
-// Permission changes can't change existing Navigator.prototype
-// objects, so grab our objects from a new Navigator
-let ifr = document.createElement("iframe");
-let connection;
-ifr.onload = function() {
-  connection = ifr.contentWindow.navigator.mozMobileConnections[0];
-
-  ok(connection instanceof ifr.contentWindow.MozMobileConnection,
-     "connection is instanceof " + connection.constructor);
+MARIONETTE_HEAD_JS = "head.js";
 
-  testGetCallBarringOption();
-};
-document.body.appendChild(ifr);
+const TEST_DATA = [
+  // Test passing invalid program.
+  {
+    options: {
+      program: 5, /* Invalid program */
+      serviceClass: 0
+    },
+    expectedError: "InvalidParameter"
+  }, {
+    options: {
+      program: null,
+      serviceClass: 0
+    },
+    expectedError: "InvalidParameter"
+  }, {
+    options: {
+      /* Undefined program */
+      serviceClass: 0
+    },
+    expectedError: "InvalidParameter"
+  },
+  // Test passing invalid serviceClass.
+  {
+    options: {
+      program: MozMobileConnection.CALL_BARRING_PROGRAM_ALL_OUTGOING,
+      serviceClass: null
+    },
+    expectedError: "InvalidParameter"
+  }, {
+    options: {
+      program: MozMobileConnection.CALL_BARRING_PROGRAM_ALL_OUTGOING,
+      /* Undefined serviceClass */
+    },
+    expectedError: "InvalidParameter"
+  },
+  // TODO: Bug 1027546 - [B2G][Emulator] Support call barring
+  // Currently emulator doesn't support call barring, so we expect to get a
+  // 'RequestNotSupported' error here.
+  {
+    options: {
+      program: MozMobileConnection.CALL_BARRING_PROGRAM_ALL_OUTGOING,
+      serviceClass: 0
+    },
+    expectedError: "RequestNotSupported"
+  }
+];
 
-function testGetCallBarringOption() {
-  let option = {'program': 0, 'password': '', 'serviceClass': 0};
-  let request = connection.getCallBarringOption(option);
-  request.onsuccess = function() {
-    ok(request.result);
-    ok('enabled' in request.result, 'should have "enabled" field');
-    cleanUp();
-  };
-  request.onerror = function() {
-    // Call barring is not supported by current emulator.
-    cleanUp();
-  };
+function testGetCallBarringOption(aOptions, aExpectedError) {
+  log("Test getting call barring to " + JSON.stringify(aOptions));
+
+  return getCallBarringOption(aOptions)
+    .then(function resolve(aResult) {
+      ok(false, "should not success");
+    }, function reject(aError) {
+      is(aError.name, aExpectedError, "failed to getCallBarringOption");
+    });
 }
 
-function cleanUp() {
-  SpecialPowers.removePermission("mobileconnection", document);
-  finish();
-}
+// Start tests
+startTestCommon(function() {
+  let promise = Promise.resolve();
+  for (let i = 0; i < TEST_DATA.length; i++) {
+    let data = TEST_DATA[i];
+    promise = promise.then(() => testGetCallBarringOption(data.options,
+                                                          data.expectedError));
+  }
+  return promise;
+});
--- a/dom/mobileconnection/tests/marionette/test_call_barring_set_error.js
+++ b/dom/mobileconnection/tests/marionette/test_call_barring_set_error.js
@@ -1,74 +1,122 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 MARIONETTE_TIMEOUT = 60000;
-
-SpecialPowers.addPermission("mobileconnection", true, document);
-
-// Permission changes can't change existing Navigator.prototype
-// objects, so grab our objects from a new Navigator
-let ifr = document.createElement("iframe");
-let connection;
-ifr.onload = function() {
-  connection = ifr.contentWindow.navigator.mozMobileConnections[0];
-
-  ok(connection instanceof ifr.contentWindow.MozMobileConnection,
-     "connection is instanceof " + connection.constructor);
+MARIONETTE_HEAD_JS = "head.js";
 
-  nextTest();
-};
-document.body.appendChild(ifr);
-
-let caseId = 0;
-let options = [
-  buildOption(5, true, '0000', 0),  // invalid program.
-
-  // test null.
-  buildOption(null, true, '0000', 0),
-  buildOption(0, null, '0000', 0),
-  buildOption(0, true, null, 0),
-  buildOption(0, true, '0000', null),
-
-  // test undefined.
-  {'enabled': true, 'password': '0000', 'serviceClass': 0},
-  {'program': 0, 'password': '0000', 'serviceClass': 0},
-  {'program': 0, 'enabled': true, 'serviceClass': 0},
-  {'program': 0, 'enabled': true, 'password': '0000'},
+const TEST_DATA = [
+  // Test passing invalid program.
+  {
+    options: {
+      "program": 5, /* Invalid program */
+      "enabled": true,
+      "password": "0000",
+      "serviceClass": 0
+    },
+    expectedError: "InvalidParameter"
+  }, {
+    options: {
+      "program": null,
+      "enabled": true,
+      "password": "0000",
+      "serviceClass": 0
+    },
+    expectedError: "InvalidParameter"
+  }, {
+    options: {
+      /* Undefined program */
+      "enabled": true,
+      "password": "0000",
+      "serviceClass": 0
+    },
+    expectedError: "InvalidParameter"
+  },
+  // Test passing invalid enabled.
+  {
+    options: {
+      "program": MozMobileConnection.CALL_BARRING_PROGRAM_ALL_OUTGOING,
+      "enabled": null,
+      "password": "0000",
+      "serviceClass": 0
+    },
+    expectedError: "InvalidParameter"
+  }, {
+    options: {
+      "program": MozMobileConnection.CALL_BARRING_PROGRAM_ALL_OUTGOING,
+      /* Undefined enabled */
+      "password": "0000",
+      "serviceClass": 0
+    },
+    expectedError: "InvalidParameter"
+  },
+  // Test passing invalid password.
+  {
+    options: {
+      "program": MozMobileConnection.CALL_BARRING_PROGRAM_ALL_OUTGOING,
+      "enabled": true,
+      "password": null,
+      "serviceClass": 0
+    },
+    expectedError: "InvalidParameter"
+  }, {
+    options: {
+      "program": MozMobileConnection.CALL_BARRING_PROGRAM_ALL_OUTGOING,
+      "enabled": true,
+      /* Undefined password */
+      "serviceClass": 0
+    },
+    expectedError: "InvalidParameter"
+  },
+  // Test passing invalid serviceClass.
+  {
+    options: {
+      "program": MozMobileConnection.CALL_BARRING_PROGRAM_ALL_OUTGOING,
+      "enabled": true,
+      "password": "0000",
+      "serviceClass": null
+    },
+    expectedError: "InvalidParameter"
+  }, {
+    options: {
+      "program": MozMobileConnection.CALL_BARRING_PROGRAM_ALL_OUTGOING,
+      "enabled": true,
+      "password": "0000",
+      /* Undefined serviceClass */
+    },
+    expectedError: "InvalidParameter"
+  },
+  // TODO: Bug 1027546 - [B2G][Emulator] Support call barring
+  // Currently emulator doesn't support call barring, so we expect to get a
+  // 'RequestNotSupported' error here.
+  {
+    options: {
+      "program": MozMobileConnection.CALL_BARRING_PROGRAM_ALL_OUTGOING,
+      "enabled": true,
+      "password": "0000",
+      "serviceClass": 0
+    },
+    expectedError: "RequestNotSupported"
+  }
 ];
 
-function buildOption(program, enabled, password, serviceClass) {
-  return {
-    'program': program,
-    'enabled': enabled,
-    'password': password,
-    'serviceClass': serviceClass
-  };
+function testSetCallBarringOption(aOptions, aExpectedError) {
+  log("Test setting call barring to " + JSON.stringify(aOptions));
+
+  return setCallBarringOption(aOptions)
+    .then(function resolve() {
+      ok(false, "changeCallBarringPassword success");
+    }, function reject(aError) {
+      is(aError.name, aExpectedError, "failed to changeCallBarringPassword");
+    });
 }
 
-function testSetCallBarringOptionError(option) {
-  let request = connection.setCallBarringOption(option);
-  request.onsuccess = function() {
-    ok(false,
-       'should not fire onsuccess for invaild call barring option: '
-       + JSON.stringify(option));
-  };
-  request.onerror = function(event) {
-    is(event.target.error.name, 'InvalidParameter', JSON.stringify(option));
-    nextTest();
-  };
-}
-
-function nextTest() {
-  if (caseId >= options.length) {
-    cleanUp();
-  } else {
-    let option = options[caseId++];
-    log('test for ' + JSON.stringify(option));
-    testSetCallBarringOptionError(option);
+// Start tests
+startTestCommon(function() {
+  let promise = Promise.resolve();
+  for (let i = 0; i < TEST_DATA.length; i++) {
+    let data = TEST_DATA[i];
+    promise = promise.then(() => testSetCallBarringOption(data.options,
+                                                          data.expectedError));
   }
-}
-
-function cleanUp() {
-  SpecialPowers.removePermission("mobileconnection", document);
-  finish();
-}
+  return promise;
+});
--- a/dom/mobileconnection/tests/marionette/test_mobile_icc_change.js
+++ b/dom/mobileconnection/tests/marionette/test_mobile_icc_change.js
@@ -1,84 +1,33 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-MARIONETTE_TIMEOUT = 30000;
-
-SpecialPowers.addPermission("mobileconnection", true, document);
+MARIONETTE_TIMEOUT = 60000;
+MARIONETTE_HEAD_JS = "head.js";
 
-// Permission changes can't change existing Navigator.prototype
-// objects, so grab our objects from a new Navigator
-let ifr = document.createElement("iframe");
-let connection;
-ifr.onload = function() {
-  connection = ifr.contentWindow.navigator.mozMobileConnections[0];
-  ok(connection instanceof ifr.contentWindow.MozMobileConnection,
-     "connection is instanceof " + connection.constructor);
-
-  // The emulator's hard coded iccid value.
-  // See it here {B2G_HOME}/external/qemu/telephony/sim_card.c.
-  is(connection.iccId, 89014103211118510720);
+// The emulator's hard coded iccid value.
+const ICCID = "89014103211118510720";
 
-  runNextTest();
-};
-document.body.appendChild(ifr);
-
-function waitForIccChange(callback) {
-  connection.addEventListener("iccchange", function handler() {
-    connection.removeEventListener("iccchange", handler);
-    callback();
-  });
-}
+function setRadioEnabledAndWaitIccChange(aEnabled) {
+  let promises = [];
+  promises.push(waitForManagerEvent("iccchange"));
+  promises.push(setRadioEnabled(aEnabled));
 
-function setRadioEnabled(enabled) {
-  let request  = connection.setRadioEnabled(enabled);
-
-  request.onsuccess = function onsuccess() {
-    log('setRadioEnabled: ' + enabled);
-  };
-
-  request.onerror = function onerror() {
-    ok(false, "setRadioEnabled should be ok");
-  };
+  return Promise.all(promises);
 }
 
-function testIccChangeOnRadioPowerOff() {
-  // Turn off radio
-  setRadioEnabled(false);
-
-  waitForIccChange(function() {
-    is(connection.iccId, null);
-    runNextTest();
-  });
-}
-
-function testIccChangeOnRadioPowerOn() {
-  // Turn on radio
-  setRadioEnabled(true);
-
-  waitForIccChange(function() {
-    // The emulator's hard coded iccid value.
-    is(connection.iccId, 89014103211118510720);
-    runNextTest();
-  });
-}
+// Start tests
+startTestCommon(function() {
+  log("Test initial iccId");
+  is(mobileConnection.iccId, ICCID);
 
-let tests = [
-  testIccChangeOnRadioPowerOff,
-  testIccChangeOnRadioPowerOn
-];
+  return setRadioEnabledAndWaitIccChange(false)
+    .then(() => {
+      is(mobileConnection.iccId, null);
+    })
 
-function runNextTest() {
-  let test = tests.shift();
-  if (!test) {
-    cleanUp();
-    return;
-  }
-
-  test();
-}
-
-function cleanUp() {
-  SpecialPowers.removePermission("mobileconnection", document);
-
-  finish();
-}
+    // Restore radio state.
+    .then(() => setRadioEnabledAndWaitIccChange(true))
+    .then(() => {
+      is(mobileConnection.iccId, ICCID);
+    });
+});
--- a/dom/mobileconnection/tests/marionette/test_mobile_last_known_network.js
+++ b/dom/mobileconnection/tests/marionette/test_mobile_last_known_network.js
@@ -1,47 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-MARIONETTE_TIMEOUT = 30000;
-
-SpecialPowers.addPermission("mobilenetwork", true, document);
-
-let connection = navigator.mozMobileConnections[0];
-ok(connection instanceof MozMobileConnection,
-   "connection is instanceof " + connection.constructor);
-
+MARIONETTE_TIMEOUT = 60000;
+MARIONETTE_HEAD_JS = "head.js";
 
-function testLastKnownNetwork() {
-  log("testLastKnownNetwork: " + connection.lastKnownNetwork);
+// Start tests
+startTestCommon(function() {
   // The emulator's hard coded operatoer's mcc and mnc codes.
-  is(connection.lastKnownNetwork, "310-260");
-  runNextTest();
-}
-
-function testLastKnownHomeNetwork() {
-  log("testLastKnownHomeNetwork: " + connection.lastKnownHomeNetwork);
+  is(mobileConnection.lastKnownNetwork, "310-260");
   // The emulator's hard coded icc's mcc and mnc codes.
-  is(connection.lastKnownHomeNetwork, "310-260");
-  runNextTest();
-}
-
-let tests = [
-  testLastKnownNetwork,
-  testLastKnownHomeNetwork
-];
-
-function runNextTest() {
-  let test = tests.shift();
-  if (!test) {
-    cleanUp();
-    return;
-  }
-
-  test();
-}
-
-function cleanUp() {
-  SpecialPowers.removePermission("mobilenetwork", document);
-  finish();
-}
-
-runNextTest();
+  is(mobileConnection.lastKnownHomeNetwork, "310-260");
+});
--- a/dom/mobileconnection/tests/marionette/test_mobile_set_radio.js
+++ b/dom/mobileconnection/tests/marionette/test_mobile_set_radio.js
@@ -1,168 +1,41 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 MARIONETTE_TIMEOUT = 60000;
-
-const DATA_KEY  = "ril.data.enabled";
-const APN_KEY   = "ril.data.apnSettings";
-
-let Promise = SpecialPowers.Cu.import("resource://gre/modules/Promise.jsm").Promise;
+MARIONETTE_HEAD_JS = "head.js";
 
-SpecialPowers.setBoolPref("dom.mozSettings.enabled", true);
-SpecialPowers.addPermission("mobileconnection", true, document);
-SpecialPowers.addPermission("settings-read", true, document);
-SpecialPowers.addPermission("settings-write", true, document);
-
-let settings = window.navigator.mozSettings;
-let connection = window.navigator.mozMobileConnections[0];
-ok(connection instanceof MozMobileConnection,
-   "connection is instanceof " + connection.constructor);
-
-function setSetting(key, value) {
-  let deferred = Promise.defer();
+// Start tests
+startTestCommon(function() {
 
-  let setLock = settings.createLock();
-  let obj = {};
-  obj[key] = value;
+  let origApnSettings;
+  return getDataApnSettings()
+    .then(value => {
+      origApnSettings = value;
+    })
 
-  let setReq = setLock.set(obj);
-  setReq.addEventListener("success", function onSetSuccess() {
-    ok(true, "set '" + key + "' to " + obj[key]);
-    deferred.resolve();
-  });
-  setReq.addEventListener("error", function onSetError() {
-    ok(false, "cannot set '" + key + "'");
-    deferred.reject();
-  });
+    // Test disabling/enabling radio power.
+    .then(() => setRadioEnabledAndWait(false))
+    .then(() => setRadioEnabledAndWait(true))
 
-  return deferred.promise;
-}
-
-function setEmulatorAPN() {
-  let apn =
-    [
-      [
+    // Test disabling radio when data is connected.
+    .then(() => {
+      let apnSettings = [[
         {"carrier":"T-Mobile US",
          "apn":"epc.tmobile.com",
          "mmsc":"http://mms.msg.eng.t-mobile.com/mms/wapenc",
-         "types":["default","supl","mms"]}
-      ]
-    ];
-  return setSetting(APN_KEY, apn);
-}
-
-function enableData() {
-  log("Turn data on.");
-
-  let deferred = Promise.defer();
-
-  connection.addEventListener("datachange", function ondatachange() {
-    if (connection.data.connected === true) {
-      connection.removeEventListener("datachange", ondatachange);
-      log("mobileConnection.data.connected is now '"
-          + connection.data.connected + "'.");
-      deferred.resolve();
-    }
-  });
-
-  setEmulatorAPN()
-    .then(() => setSetting(DATA_KEY, true));
-
-  return deferred.promise;
-}
-
-function receivedPending(received, pending, nextAction) {
-  let index = pending.indexOf(received);
-  if (index != -1) {
-    pending.splice(index, 1);
-  }
-  if (pending.length === 0) {
-    nextAction();
-  }
-}
-
-function waitRadioState(state) {
-  let deferred = Promise.defer();
-
-  waitFor(function() {
-    deferred.resolve();
-  }, function() {
-    return connection.radioState == state;
-  });
-
-  return deferred.promise;
-}
-
-function setRadioEnabled(enabled, transientState, finalState) {
-  log("setRadioEnabled to " + enabled);
-
-  let deferred = Promise.defer();
-  let done = function() {
-    deferred.resolve();
-  };
-
-  let pending = ["onradiostatechange", "onsuccess"];
-
-  let receivedTransient = false;
-  connection.onradiostatechange = function() {
-    let state = connection.radioState;
-    log("Received 'radiostatechange' event, radioState: " + state);
-
-    if (state == transientState) {
-      receivedTransient = true;
-    } else if (state == finalState) {
-      ok(receivedTransient);
-      receivedPending("onradiostatechange", pending, done);
-    }
-  };
-
-  let req = connection.setRadioEnabled(enabled);
-
-  req.onsuccess = function() {
-    log("setRadioEnabled success");
-    receivedPending("onsuccess", pending, done);
-  };
-
-  req.onerror = function() {
-    ok(false, "setRadioEnabled should not fail");
-    deferred.reject();
-  };
-
-  return deferred.promise;
-}
-
-function testSwitchRadio() {
-  log("= testSwitchRadio =");
-  return waitRadioState("enabled")
-    .then(setRadioEnabled.bind(null, false, "disabling", "disabled"))
-    .then(setRadioEnabled.bind(null, true, "enabling", "enabled"));
-}
-
-function testDisableRadioWhenDataConnected() {
-  log("= testDisableRadioWhenDataConnected =");
-  return waitRadioState("enabled")
-    .then(enableData)
-    .then(setRadioEnabled.bind(null, false, "disabling", "disabled"))
+         "types":["default","supl","mms"]}]];
+      return setDataApnSettings(apnSettings);
+    })
+    .then(() => setDataEnabledAndWait(true))
+    .then(() => setRadioEnabledAndWait(false))
     .then(() => {
       // Data should be disconnected.
-      is(connection.data.connected, false);
+      is(mobileConnection.data.connected, false);
     })
-    .then(setRadioEnabled.bind(null, true, "enabling", "enabled"))
-    // Disable data
-    .then(setSetting.bind(null, DATA_KEY, false));
-}
 
-function cleanUp() {
-  SpecialPowers.removePermission("mobileconnection", document);
-  SpecialPowers.removePermission("settings-write", document);
-  SpecialPowers.removePermission("settings-read", document);
-  SpecialPowers.clearUserPref("dom.mozSettings.enabled");
-  finish();
-}
+    // Restore test environment.
+    .then(() => setDataApnSettings(origApnSettings))
+    .then(() => setDataEnabled(false))
+    .then(() => setRadioEnabledAndWait(true));
 
-testSwitchRadio()
-  .then(testDisableRadioWhenDataConnected)
-  .then(null, () => {
-    ok(false, "promise reject somewhere");
-  })
-  .then(cleanUp);
+}, ["settings-read", "settings-write"]);
--- a/dom/mobileconnection/tests/marionette/test_mobile_signal_strength.js
+++ b/dom/mobileconnection/tests/marionette/test_mobile_signal_strength.js
@@ -1,132 +1,98 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-MARIONETTE_TIMEOUT = 30000;
-MARIONETTE_HEAD_JS = "mobile_header.js";
+MARIONETTE_TIMEOUT = 60000;
+MARIONETTE_HEAD_JS = "head.js";
 
-/* Emulator command for GSM/UMTS signal strength */
-function setEmulatorGsmSignalStrength(rssi) {
-  emulatorHelper.sendCommand("gsm signal " + rssi);
-}
+// Emulator uses rssi = 7 as default value.
+const DEFAULT_RSSI = 7;
 
-/* Emulator command for LTE signal strength */
-function setEmulatorLteSignalStrength(rxlev, rsrp, rssnr) {
-  let lteSignal = rxlev + " " + rsrp + " " + rssnr;
-  emulatorHelper.sendCommand("gsm lte_signal " + lteSignal);
-}
+const TEST_DATA = [
+  // All invalid case.
+  {
+    input: {
+      rxlev: 99,
+      rsrp: 65535,
+      rssnr: 65535
+    },
+    expect: {
+      signalStrength: null,
+      relSignalStrength: null
+    }
+  },
+  // Valid rxlev with max value.
+  {
+    input: {
+      rxlev: 63,
+      rsrp: 65535,
+      rssnr: 65535
+    },
+    expect: {
+      signalStrength: -48,
+      relSignalStrength: 100
+    }
+  },
+  // Valid rxlev.
+  {
+    input: {
+      rxlev: 12,
+      rsrp: 65535,
+      rssnr: 65535
+    },
+    expect: {
+      signalStrength: -99,
+      relSignalStrength: 100
+    }
+  },
+  // Valid rxlev with min value.
+  {
+    input: {
+      rxlev: 0,
+      rsrp: 65535,
+      rssnr: 65535
+    },
+    expect: {
+      signalStrength: -111,
+      relSignalStrength: 0
+    }
+  }
+];
 
-function waitForVoiceChangeEvent(callback) {
-  mobileConnection.addEventListener("voicechange", function onvoicechange() {
-    mobileConnection.removeEventListener("voicechange", onvoicechange);
-
-    if (callback && typeof callback === "function") {
-      callback();
-    }
-  });
-}
-
-/* Test Initial Signal Strength Info */
-taskHelper.push(function testInitialSignalStrengthInfo() {
+function testInitialSignalStrengthInfo() {
   log("Test initial signal strength info");
 
   let voice = mobileConnection.voice;
   // Android emulator initializes the signal strength to -99 dBm
   is(voice.signalStrength, -99, "check voice.signalStrength");
   is(voice.relSignalStrength, 44, "check voice.relSignalStrength");
-
-  taskHelper.runNext();
-});
+}
 
-/* Test Unsolicited Signal Strength Events for LTE */
-taskHelper.push(function testLteSignalStrength() {
-  // Set emulator's LTE signal strength and wait for 'onvoicechange' event.
-  function doTestLteSignalStrength(input, expect, callback) {
-    log("Test LTE signal info with data : " + JSON.stringify(input));
+function testLteSignalStrength(aInput, aExpect) {
+  log("Test setting LTE signal strength to " + JSON.stringify(aInput));
 
-    waitForVoiceChangeEvent(function() {
+  return setEmulatorLteSignalStrengthAndWait(aInput.rxlev, aInput.rsrp, aInput.rssnr)
+    .then(() => {
       let voice = mobileConnection.voice;
-      is(voice.signalStrength, expect.signalStrength,
+      is(voice.signalStrength, aExpect.signalStrength,
          "check voice.signalStrength");
-      is(voice.relSignalStrength, expect.relSignalStrength,
+      is(voice.relSignalStrength, aExpect.relSignalStrength,
          "check voice.relSignalStrength");
+    });
+}
 
-      if (callback && typeof callback === "function") {
-        callback();
-      }
-    });
+// Start tests
+startTestCommon(function() {
+  // Test initial status
+  testInitialSignalStrengthInfo();
 
-    setEmulatorLteSignalStrength(input.rxlev, input.rsrp, input.rssnr);
+  // Test Unsolicited Signal Strength Events for LTE
+  let promise = Promise.resolve();
+  for (let i = 0; i < TEST_DATA.length; i++) {
+    let data = TEST_DATA[i];
+    promise = promise.then(() => testLteSignalStrength(data.input,
+                                                       data.expect));
   }
 
-  let testData = [
-    // All invalid case.
-    {input: {
-      rxlev: 99,
-      rsrp: 65535,
-      rssnr: 65535},
-     expect: {
-      signalStrength: null,
-      relSignalStrength: null}
-    },
-    // Valid rxlev with max value.
-    {input: {
-      rxlev: 63,
-      rsrp: 65535,
-      rssnr: 65535},
-     expect: {
-      signalStrength: -48,
-      relSignalStrength: 100}
-    },
-    // Valid rxlev.
-    {input: {
-      rxlev: 12,
-      rsrp: 65535,
-      rssnr: 65535},
-     expect: {
-      signalStrength: -99,
-      relSignalStrength: 100}
-    },
-    // Valid rxlev with min value.
-    {input: {
-      rxlev: 0,
-      rsrp: 65535,
-      rssnr: 65535},
-     expect: {
-      signalStrength: -111,
-      relSignalStrength: 0}
-    }
-  ];
-
-  // Run all test data.
-  (function do_call() {
-    let next = testData.shift();
-    if (!next) {
-      taskHelper.runNext();
-      return;
-    }
-    doTestLteSignalStrength(next.input, next.expect, do_call);
-  })();
+  // Reset Signal Strength Info to default
+  return promise.then(() => setEmulatorGsmSignalStrengthAndWait(DEFAULT_RSSI));
 });
-
-/* Reset Signal Strength Info to default, and finsih the test */
-taskHelper.push(function testResetSignalStrengthInfo() {
-  // Reset emulator's signal strength and wait for 'onvoicechange' event.
-  function doResetSignalStrength(rssi) {
-    waitForVoiceChangeEvent(function() {
-      let voice = mobileConnection.voice;
-      is(voice.signalStrength, -99, "check voice.signalStrength");
-      is(voice.relSignalStrength, 44, "check voice.relSignalStrength");
-
-      taskHelper.runNext();
-    });
-
-    setEmulatorGsmSignalStrength(rssi);
-  }
-
-  // Emulator uses rssi = 7 as default value, and we need to reset it after
-  // finishing test in case other test cases need those values for testing.
-  doResetSignalStrength(7);
-});
-
-// Start test
-taskHelper.runNext();
--- a/ipc/glue/CrossProcessMutex_posix.cpp
+++ b/ipc/glue/CrossProcessMutex_posix.cpp
@@ -14,16 +14,34 @@ struct MutexData {
   pthread_mutex_t mMutex;
   mozilla::Atomic<int32_t> mCount;
 };
 
 }
 
 namespace mozilla {
 
+static void
+InitMutex(pthread_mutex_t* mMutex)
+{
+  pthread_mutexattr_t mutexAttributes;
+  pthread_mutexattr_init(&mutexAttributes);
+  // Make the mutex reentrant so it behaves the same as a win32 mutex
+  if (pthread_mutexattr_settype(&mutexAttributes, PTHREAD_MUTEX_RECURSIVE)) {
+    MOZ_CRASH();
+  }
+  if (pthread_mutexattr_setpshared(&mutexAttributes, PTHREAD_PROCESS_SHARED)) {
+    MOZ_CRASH();
+  }
+
+  if (pthread_mutex_init(mMutex, &mutexAttributes)) {
+    MOZ_CRASH();
+  }
+}
+
 CrossProcessMutex::CrossProcessMutex(const char*)
     : mSharedBuffer(nullptr)
     , mMutex(nullptr)
     , mCount(nullptr)
 {
   mSharedBuffer = new ipc::SharedMemoryBasic;
   if (!mSharedBuffer->Create(sizeof(MutexData))) {
     MOZ_CRASH();
@@ -38,30 +56,17 @@ CrossProcessMutex::CrossProcessMutex(con
   if (!data) {
     MOZ_CRASH();
   }
 
   mMutex = &(data->mMutex);
   mCount = &(data->mCount);
 
   *mCount = 1;
-
-  pthread_mutexattr_t mutexAttributes;
-  pthread_mutexattr_init(&mutexAttributes);
-  // Make the mutex reentrant so it behaves the same as a win32 mutex
-  if (pthread_mutexattr_settype(&mutexAttributes, PTHREAD_MUTEX_RECURSIVE)) {
-    MOZ_CRASH();
-  }
-  if (pthread_mutexattr_setpshared(&mutexAttributes, PTHREAD_PROCESS_SHARED)) {
-    MOZ_CRASH();
-  }
-
-  if (pthread_mutex_init(mMutex, &mutexAttributes)) {
-    MOZ_CRASH();
-  }
+  InitMutex(mMutex);
 
   MOZ_COUNT_CTOR(CrossProcessMutex);
 }
 
 CrossProcessMutex::CrossProcessMutex(CrossProcessMutexHandle aHandle)
     : mSharedBuffer(nullptr)
     , mMutex(nullptr)
     , mCount(nullptr)
@@ -79,17 +84,23 @@ CrossProcessMutex::CrossProcessMutex(Cro
   MutexData* data = static_cast<MutexData*>(mSharedBuffer->memory());
 
   if (!data) {
     MOZ_CRASH();
   }
 
   mMutex = &(data->mMutex);
   mCount = &(data->mCount);
-  (*mCount)++;
+  int32_t count = (*mCount)++;
+
+  if (count == 0) {
+    // The other side has already let go of their CrossProcessMutex, so now
+    // mMutex is garbage. We need to re-initialize it.
+    InitMutex(mMutex);
+  }
 
   MOZ_COUNT_CTOR(CrossProcessMutex);
 }
 
 CrossProcessMutex::~CrossProcessMutex()
 {
   int32_t count = --(*mCount);