Merge m-c to inbound a=merge
authorWes Kocher <wkocher@mozilla.com>
Fri, 24 Oct 2014 15:06:44 -0700
changeset 212323 6a37732cb6b219176e41d6e6eb60a000037da18c
parent 212322 8219d3ab06a13ecaf7da8ba5b5b23a303d20a091 (current diff)
parent 212260 c70f62375f7d496edee7ebd2535fce746500e96c (diff)
child 212324 e37231060eb490257b582c2195b3f43e2a38ad27
child 212335 1a2afa35facef964b9c8654bcb300e301695cbbc
push id27704
push userkwierso@gmail.com
push dateSat, 25 Oct 2014 01:25:30 +0000
treeherdermozilla-central@e37231060eb4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to inbound a=merge
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="29ed78a26d62b58f663437a45f273d57b9781d79"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bd7a73c1f1d8211deb95543e9e14a5eeef36d5e1"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="314f305d3163cc094e6fe7701d95a98fc180b639"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/>
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="70eb0cb0977d6295e7da8896f9efb9f3ca1c13ea">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="29ed78a26d62b58f663437a45f273d57b9781d79"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd7a73c1f1d8211deb95543e9e14a5eeef36d5e1"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="314f305d3163cc094e6fe7701d95a98fc180b639"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c058843242068d0df7c107e09da31b53d2e08fa6"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8986df0f82e15ac2798df0b6c2ee3435400677ac">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="29ed78a26d62b58f663437a45f273d57b9781d79"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bd7a73c1f1d8211deb95543e9e14a5eeef36d5e1"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="314f305d3163cc094e6fe7701d95a98fc180b639"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/>
   <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"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="29ed78a26d62b58f663437a45f273d57b9781d79"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bd7a73c1f1d8211deb95543e9e14a5eeef36d5e1"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="314f305d3163cc094e6fe7701d95a98fc180b639"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="70eb0cb0977d6295e7da8896f9efb9f3ca1c13ea">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="29ed78a26d62b58f663437a45f273d57b9781d79"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd7a73c1f1d8211deb95543e9e14a5eeef36d5e1"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="314f305d3163cc094e6fe7701d95a98fc180b639"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c058843242068d0df7c107e09da31b53d2e08fa6"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="29ed78a26d62b58f663437a45f273d57b9781d79"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bd7a73c1f1d8211deb95543e9e14a5eeef36d5e1"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="314f305d3163cc094e6fe7701d95a98fc180b639"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/>
@@ -127,17 +127,17 @@
   <remove-project name="platform/hardware/libhardware"/>
   <remove-project name="platform/external/bluetooth/bluedroid"/>
   <!--original fetch url was git://github.com/t2m-foxfone/-->
   <remote fetch="https://git.mozilla.org/external/t2m-foxfone" name="t2m"/>
   <default remote="caf" revision="LNX.LA.3.5.2.1.1" sync-j="4"/>
   <!-- Flame specific things -->
   <project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="1bb28abbc215f45220620af5cd60a8ac1be93722"/>
   <project name="device/qcom/common" path="device/qcom/common" revision="54c32c2ddef066fbdf611d29e4b7c47e0363599e"/>
-  <project name="device-flame" path="device/t2m/flame" remote="b2g" revision="dbd93c93782c9aa2306b909acdfb6ded15d49022"/>
+  <project name="device-flame" path="device/t2m/flame" remote="b2g" revision="6e51d9216901d39d192d9e6dd86a5e15b0641a89"/>
   <project name="codeaurora_kernel_msm" path="kernel" remote="b2g" revision="3c4f041e3e3dc676f2111caf20a186ec0467dbdb"/>
   <project name="kernel_lk" path="bootable/bootloader/lk" remote="b2g" revision="fda40423ffa573dc6cafd3780515010cb2a086be"/>
   <project name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="30b96dfca99cb384bf520a16b81f3aba56f09907"/>
   <project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="5b71e40213f650459e95d35b6f14af7e88d8ab62"/>
   <project name="platform_external_libnfc-nci" path="external/libnfc-nci" remote="t2m" revision="4186bdecb4dae911b39a8202252cc2310d91b0be"/>
   <project name="platform/frameworks/av" path="frameworks/av" revision="ea2f399b3ca0a23524d2828f85f69902caefc22e"/>
   <project name="platform/frameworks/base" path="frameworks/base" revision="6b58ab45e3e56c1fc20708cc39fa2264c52558df"/>
   <project name="platform/frameworks/native" path="frameworks/native" revision="a46a9f1ac0ed5662d614c277cbb14eb3f332f365"/>
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8986df0f82e15ac2798df0b6c2ee3435400677ac">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="29ed78a26d62b58f663437a45f273d57b9781d79"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bd7a73c1f1d8211deb95543e9e14a5eeef36d5e1"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="314f305d3163cc094e6fe7701d95a98fc180b639"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/>
   <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"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
         "git_revision": "", 
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "b508914e27b34f26949fddbe8963fde897ae2268", 
+    "revision": "0c0da681fe770f53931524f32098a3bbd62ddc39", 
     "repo_path": "/integration/gaia-central"
 }
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="70eb0cb0977d6295e7da8896f9efb9f3ca1c13ea">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="29ed78a26d62b58f663437a45f273d57b9781d79"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd7a73c1f1d8211deb95543e9e14a5eeef36d5e1"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="314f305d3163cc094e6fe7701d95a98fc180b639"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="70eb0cb0977d6295e7da8896f9efb9f3ca1c13ea">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="29ed78a26d62b58f663437a45f273d57b9781d79"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd7a73c1f1d8211deb95543e9e14a5eeef36d5e1"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="314f305d3163cc094e6fe7701d95a98fc180b639"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8986df0f82e15ac2798df0b6c2ee3435400677ac">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="29ed78a26d62b58f663437a45f273d57b9781d79"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bd7a73c1f1d8211deb95543e9e14a5eeef36d5e1"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="314f305d3163cc094e6fe7701d95a98fc180b639"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/>
   <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"/>
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="70eb0cb0977d6295e7da8896f9efb9f3ca1c13ea">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="29ed78a26d62b58f663437a45f273d57b9781d79"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd7a73c1f1d8211deb95543e9e14a5eeef36d5e1"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="314f305d3163cc094e6fe7701d95a98fc180b639"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1608,17 +1608,17 @@ pref("loop.enabled", true);
 pref("loop.throttled", true);
 pref("loop.soft_start_ticket_number", -1);
 pref("loop.soft_start_hostname", "soft-start.loop.services.mozilla.com");
 #endif
 
 pref("loop.server", "https://loop.services.mozilla.com");
 pref("loop.seenToS", "unseen");
 pref("loop.learnMoreUrl", "https://www.firefox.com/hello/");
-pref("loop.legal.ToS_url", "https://call.mozilla.com/legal/terms/");
+pref("loop.legal.ToS_url", "https://hello.firefox.com/legal/terms/");
 pref("loop.legal.privacy_url", "https://www.mozilla.org/privacy/");
 pref("loop.do_not_disturb", false);
 pref("loop.ringtone", "chrome://browser/content/loop/shared/sounds/Firefox-Long.ogg");
 pref("loop.retry_delay.start", 60000);
 pref("loop.retry_delay.limit", 300000);
 pref("loop.feedback.baseUrl", "https://input.mozilla.org/api/v1/feedback");
 pref("loop.feedback.product", "Loop");
 pref("loop.debug.loglevel", "Error");
--- a/browser/components/loop/LoopRooms.jsm
+++ b/browser/components/loop/LoopRooms.jsm
@@ -11,30 +11,21 @@ Cu.import("resource://gre/modules/Servic
 
 XPCOMUtils.defineLazyModuleGetter(this, "MozLoopService",
                                   "resource:///modules/loop/MozLoopService.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "LOOP_SESSION_TYPE",
                                   "resource:///modules/loop/MozLoopService.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "MozLoopPushHandler",
                                   "resource:///modules/loop/MozLoopPushHandler.jsm");
 
-// Create a new instance of the ConsoleAPI so we can control the maxLogLevel with a pref.
-XPCOMUtils.defineLazyGetter(this, "log", () => {
-  let ConsoleAPI = Cu.import("resource://gre/modules/devtools/Console.jsm", {}).ConsoleAPI;
-  let consoleOptions = {
-    maxLogLevel: Services.prefs.getCharPref(PREF_LOG_LEVEL).toLowerCase(),
-    prefix: "Loop",
-  };
-  return new ConsoleAPI(consoleOptions);
-});
-
 this.EXPORTED_SYMBOLS = ["LoopRooms", "roomsPushNotification"];
 
 let gRoomsListFetched = false;
 let gRooms = new Map();
+let gCallbacks = new Map();
 
   /**
    * Callback used to indicate changes to rooms data on the LoopServer.
    *
    * @param {Object} version Version number assigned to this change set.
    * @param {Object} channelID Notification channel identifier.
    *
    */
@@ -54,40 +45,42 @@ let LoopRoomsInternal = {
       // Fetch the rooms from the server.
       let sessionType = MozLoopService.userProfile ? LOOP_SESSION_TYPE.FXA :
                         LOOP_SESSION_TYPE.GUEST;
       let rooms = yield this.requestRoomList(sessionType);
       // Add each room to our in-memory Map using a locally unique
       // identifier.
       for (let room of rooms) {
         let id = MozLoopService.generateLocalID();
-        room.localRoomID = id;
+        room.localRoomId = id;
         // Next, request the detailed information for each room.
         // If the request fails the room data will not be added to the map.
         try {
           let details = yield this.requestRoomDetails(room.roomToken, sessionType);
           for (let attr in details) {
             room[attr] = details[attr]
           }
+          delete room.currSize; //This attribute will be eliminated in the next revision.
           gRooms.set(id, room);
         }
-        catch (error) {log.warn("failed GETing room details for roomToken = " + room.roomToken + ": ", error)}
+        catch (error) {MozLoopService.log.warn(
+          "failed GETing room details for roomToken = " + room.roomToken + ": ", error)}
       }
       callback(null, [...gRooms.values()]);
       return;
-      }.bind(this)).catch((error) => {log.error("getAll error:", error);
+      }.bind(this)).catch((error) => {MozLoopService.log.error("getAll error:", error);
                                       callback(error)});
     return;
   },
 
-  getRoomData: function(roomID, callback) {
-    if (gRooms.has(roomID)) {
-      callback(null, gRooms.get(roomID));
+  getRoomData: function(localRoomId, callback) {
+    if (gRooms.has(localRoomId)) {
+      callback(null, gRooms.get(localRoomId));
     } else {
-      callback(new Error("Room data not found or not fetched yet for room with ID " + roomID));
+      callback(new Error("Room data not found or not fetched yet for room with ID " + localRoomId));
     }
     return;
   },
 
   /**
    * Request list of all rooms associated with this account.
    *
    * @param {String} sessionType Indicates which hawkRequest endpoint to use.
@@ -125,16 +118,160 @@ let LoopRoomsInternal = {
    *
    * @param {Object} version Version number assigned to this change set.
    * @param {Object} channelID Notification channel identifier.
    *
    */
   onNotification: function(version, channelID) {
     return;
   },
+
+  createRoom: function(props, callback) {
+    // Always create a basic room record and launch the window, attaching
+    // the localRoomId. Later errors will be returned via the registered callback.
+    let localRoomId = MozLoopService.generateLocalID((id) => {gRooms.has(id)})
+    let room = {localRoomId : localRoomId};
+    for (let prop in props) {
+      room[prop] = props[prop]
+    }
+
+    gRooms.set(localRoomId, room);
+    this.addCallback(localRoomId, "RoomCreated", callback);
+    MozLoopService.openChatWindow(null, "", "about:loopconversation#room/" + localRoomId);
+
+    if (!"roomName" in props ||
+        !"expiresIn" in props ||
+        !"roomOwner" in props ||
+        !"maxSize" in props) {
+      this.postCallback(localRoomId, "RoomCreated",
+                        new Error("missing required room create property"));
+      return localRoomId;
+    }
+
+    let sessionType = MozLoopService.userProfile ? LOOP_SESSION_TYPE.FXA :
+                                                   LOOP_SESSION_TYPE.GUEST;
+
+    MozLoopService.hawkRequest(sessionType, "/rooms", "POST", props).then(
+      (response) => {
+        let data = JSON.parse(response.body);
+        for (let attr in data) {
+          room[attr] = data[attr]
+        }
+        delete room.expiresIn; //Do not keep this value - it is a request to the server
+        this.postCallback(localRoomId, "RoomCreated", null, room);
+      },
+      (error) => {
+        this.postCallback(localRoomId, "RoomCreated", error);
+      });
+
+    return localRoomId;
+  },
+
+  /**
+   * Send an update to the callbacks registered for a specific localRoomId
+   * for a callback type.
+   *
+   * The result set is always saved. Then each
+   * callback function that has been registered when this function is
+   * called will be called with the result set. Any new callback that
+   * is regsitered via addCallback will receive a copy of the last
+   * saved result set when registered. This allows the posting operation
+   * to complete before the callback is registered in an asynchronous
+   * operation.
+   *
+   * Callbacsk must be of the form:
+   *    function (error, success) {...}
+   *
+   * @param {String} localRoomId Local room identifier.
+   * @param {String} callbackName callback type
+   * @param {?Error} error result or null.
+   * @param {?Object} success result if error argument is null.
+   */
+  postCallback: function(localRoomId, callbackName, error, success) {
+    let roomCallbacks = gCallbacks.get(localRoomId);
+    if (!roomCallbacks) {
+      // No callbacks have been registered or results posted for this room.
+      // Initialize a record for this room and callbackName, saving the
+      // result set.
+      gCallbacks.set(localRoomId, new Map([[
+        callbackName,
+        { callbackList: [], result: { error: error, success: success } }]]));
+      return;
+    }
+
+    let namedCallback = roomCallbacks.get(callbackName);
+    // A callback of this name has not been registered.
+    if (!namedCallback) {
+      roomCallbacks.set(
+        callbackName,
+        {callbackList: [], result: {error: error, success: success}});
+      return;
+    }
+
+    // Record the latest result set.
+    namedCallback.result = {error: error, success: success};
+
+    // Call each registerd callback passing the new result posted.
+    namedCallback.callbackList.forEach((callback) => {
+      callback(error, success);
+    });
+  },
+
+  addCallback: function(localRoomId, callbackName, callback) {
+    let roomCallbacks = gCallbacks.get(localRoomId);
+    if (!roomCallbacks) {
+      // No callbacks have been registered or results posted for this room.
+      // Initialize a record for this room and callbackName.
+      gCallbacks.set(localRoomId, new Map([[
+        callbackName,
+        {callbackList: [callback]}]]));
+      return;
+    }
+
+    let namedCallback = roomCallbacks.get(callbackName);
+    // A callback of this name has not been registered.
+    if (!namedCallback) {
+      roomCallbacks.set(
+        callbackName,
+        {callbackList: [callback]});
+      return;
+    }
+
+    // Add this callback if not already in the array
+    if (namedCallback.callbackList.indexOf(callback) >= 0) {
+      return;
+    }
+    namedCallback.callbackList.push(callback);
+
+    // If a result has been posted for this callback
+    // send it using this new callback function.
+    let result = namedCallback.result;
+    if (result) {
+      callback(result.error, result.success);
+    }
+  },
+
+  deleteCallback: function(localRoomId, callbackName, callback) {
+    let roomCallbacks = gCallbacks.get(localRoomId);
+    if (!roomCallbacks) {
+      return;
+    }
+
+    let namedCallback = roomCallbacks.get(callbackName);
+    if (!namedCallback) {
+      return;
+    }
+
+    let i = namedCallback.callbackList.indexOf(callback);
+    if (i >= 0) {
+      namedCallback.callbackList.splice(i, 1);
+    }
+
+    return;
+  },
 };
 Object.freeze(LoopRoomsInternal);
 
 /**
  * The LoopRooms class.
  *
  * Each method that is a member of this class requires the last argument to be a
  * callback Function. MozLoopAPI will cause things to break if this invariant is
@@ -151,20 +288,56 @@ this.LoopRooms = {
    */
   getAll: function(callback) {
     return LoopRoomsInternal.getAll(callback);
   },
 
   /**
    * Return the current stored version of the data for the indicated room.
    *
-   * @param {String} roomID Local room identifier
+   * @param {String} localRoomId Local room identifier
    * @param {Function} callback Function that will be invoked once the operation
    *                            finished. The first argument passed will be an
    *                            `Error` object or `null`. The second argument will
    *                            be the list of rooms, if it was fetched successfully.
    */
-  getRoomData: function(roomID, callback) {
-    return LoopRoomsInternal.getRoomData(roomID, callback);
+  getRoomData: function(localRoomId, callback) {
+    return LoopRoomsInternal.getRoomData(localRoomId, callback);
+  },
+
+  /**
+   * Create a room. Will both open a chat window for the new room
+   * and perform an exchange with the LoopServer to create the room.
+   * for a callback type. Callback must be of the form:
+   *    function (error, success) {...}
+   *
+   * @param {Object} room properties to be sent to the LoopServer
+   * @param {Function} callback Must be of the form: function (error, success) {...}
+   *
+   * @returns {String} localRoomId assigned to this new room.
+   */
+  createRoom: function(roomProps, callback) {
+    return LoopRoomsInternal.createRoom(roomProps, callback);
+  },
+
+  /**
+   * Register a callback of a specified type with a localRoomId.
+   *
+   * @param {String} localRoomId Local room identifier.
+   * @param {String} callbackName callback type
+   * @param {Function} callback Must be of the form: function (error, success) {...}
+   */
+  addCallback: function(localRoomId, callbackName, callback) {
+    return LoopRoomsInternal.addCallback(localRoomId, callbackName, callback);
+  },
+
+  /**
+   * Un-register and delete a callback of a specified type for a localRoomId.
+   *
+   * @param {String} localRoomId Local room identifier.
+   * @param {String} callbackName callback type
+   * @param {Function} callback Previously passed to addCallback().
+   */
+  deleteCallback: function(localRoomId, callbackName, callback) {
+    return LoopRoomsInternal.deleteCallback(localRoomId, callbackName, callback);
   },
 };
 Object.freeze(LoopRooms);
-
--- a/browser/components/loop/content/js/conversation.js
+++ b/browser/components/loop/content/js/conversation.js
@@ -174,16 +174,45 @@ loop.conversation = (function(mozL10n) {
           )
         )
         /* jshint ignore:end */
       );
     }
   });
 
   /**
+   * Incoming Call failed view. Displayed when a call fails.
+   *
+   * XXX Based on CallFailedView, but built specially until we flux-ify the
+   * incoming call views (bug 1088672).
+   */
+  var IncomingCallFailedView = React.createClass({displayName: 'IncomingCallFailedView',
+    propTypes: {
+      cancelCall: React.PropTypes.func.isRequired
+    },
+
+    render: function() {
+      document.title = mozL10n.get("generic_failure_title");
+
+      return (
+        React.DOM.div({className: "call-window"}, 
+          React.DOM.h2(null, mozL10n.get("generic_failure_title")), 
+
+          React.DOM.div({className: "btn-group call-action-group"}, 
+            React.DOM.button({className: "btn btn-cancel", 
+                    onClick: this.props.cancelCall}, 
+              mozL10n.get("cancel_button")
+            )
+          )
+        )
+      );
+    }
+  });
+
+  /**
    * This view manages the incoming conversation views - from
    * call initiation through to the actual conversation and call end.
    *
    * At the moment, it does more than that, these parts need refactoring out.
    */
   var IncomingConversationView = React.createClass({displayName: 'IncomingConversationView',
     propTypes: {
       client: React.PropTypes.instanceOf(loop.Client).isRequired,
@@ -249,21 +278,23 @@ loop.conversation = (function(mozL10n) {
               model: this.props.conversation, 
               video: {enabled: callType !== "audio"}}
             )
           );
         }
         case "end": {
           // XXX To be handled with the "failed" view state when bug 1047410 lands
           if (this.state.callFailed) {
-            document.title = mozL10n.get("generic_failure_title");
-          } else {
-            document.title = mozL10n.get("conversation_has_ended");
+            return IncomingCallFailedView({
+              cancelCall: this.closeWindow.bind(this)}
+            )
           }
 
+          document.title = mozL10n.get("conversation_has_ended");
+
           var feebackAPIBaseUrl = navigator.mozLoop.getLoopCharPref(
             "feedback.baseUrl");
 
           var appVersionInfo = navigator.mozLoop.appVersionInfo;
 
           var feedbackClient = new loop.FeedbackAPIClient(feebackAPIBaseUrl, {
             product: navigator.mozLoop.getLoopCharPref("feedback.product"),
             platform: appVersionInfo.OS,
@@ -389,37 +420,42 @@ loop.conversation = (function(mozL10n) {
      * @param {Object} progressData The progress data from the websocket.
      * @param {String} previousState The previous state from the websocket.
      */
     _handleWebSocketProgress: function(progressData, previousState) {
       // We only care about the terminated state at the moment.
       if (progressData.state !== "terminated")
         return;
 
-      if (progressData.reason === "cancel" ||
-          progressData.reason === "closed") {
+      // XXX This would be nicer in the _abortIncomingCall function, but we need to stop
+      // it here for now due to server-side issues that are being fixed in bug 1088351.
+      // This is before the abort call to ensure that it happens before the window is
+      // closed.
+      navigator.mozLoop.stopAlerting();
+
+      // If we hit any of the termination reasons, and the user hasn't accepted
+      // then it seems reasonable to close the window/abort the incoming call.
+      //
+      // If the user has accepted the call, and something's happened, display
+      // the call failed view.
+      //
+      // https://wiki.mozilla.org/Loop/Architecture/MVP#Termination_Reasons
+      if (previousState === "init" || previousState === "alerting") {
         this._abortIncomingCall();
-        return;
+      } else {
+        this.setState({callFailed: true, callStatus: "end"});
       }
 
-      if (progressData.reason === "timeout") {
-        if (previousState === "init" || previousState === "alerting") {
-          this._abortIncomingCall();
-        } else {
-          this.setState({callFailed: true, callStatus: "end"});
-        }
-      }
     },
 
     /**
      * Silently aborts an incoming call - stops the alerting, and
      * closes the websocket.
      */
     _abortIncomingCall: function() {
-      navigator.mozLoop.stopAlerting();
       this._websocket.close();
       // Having a timeout here lets the logging for the websocket complete and be
       // displayed on the console if both are on.
       setTimeout(this.closeWindow, 0);
     },
 
     closeWindow: function() {
       window.close();
@@ -639,13 +675,14 @@ loop.conversation = (function(mozL10n) {
       outgoing: outgoing
     }));
   }
 
   return {
     AppControllerView: AppControllerView,
     IncomingConversationView: IncomingConversationView,
     IncomingCallView: IncomingCallView,
+    IncomingCallFailedView: IncomingCallFailedView,
     init: init
   };
 })(document.mozL10n);
 
 document.addEventListener('DOMContentLoaded', loop.conversation.init);
--- a/browser/components/loop/content/js/conversation.jsx
+++ b/browser/components/loop/content/js/conversation.jsx
@@ -174,16 +174,45 @@ loop.conversation = (function(mozL10n) {
           </div>
         </div>
         /* jshint ignore:end */
       );
     }
   });
 
   /**
+   * Incoming Call failed view. Displayed when a call fails.
+   *
+   * XXX Based on CallFailedView, but built specially until we flux-ify the
+   * incoming call views (bug 1088672).
+   */
+  var IncomingCallFailedView = React.createClass({
+    propTypes: {
+      cancelCall: React.PropTypes.func.isRequired
+    },
+
+    render: function() {
+      document.title = mozL10n.get("generic_failure_title");
+
+      return (
+        <div className="call-window">
+          <h2>{mozL10n.get("generic_failure_title")}</h2>
+
+          <div className="btn-group call-action-group">
+            <button className="btn btn-cancel"
+                    onClick={this.props.cancelCall}>
+              {mozL10n.get("cancel_button")}
+            </button>
+          </div>
+        </div>
+      );
+    }
+  });
+
+  /**
    * This view manages the incoming conversation views - from
    * call initiation through to the actual conversation and call end.
    *
    * At the moment, it does more than that, these parts need refactoring out.
    */
   var IncomingConversationView = React.createClass({
     propTypes: {
       client: React.PropTypes.instanceOf(loop.Client).isRequired,
@@ -249,21 +278,23 @@ loop.conversation = (function(mozL10n) {
               model={this.props.conversation}
               video={{enabled: callType !== "audio"}}
             />
           );
         }
         case "end": {
           // XXX To be handled with the "failed" view state when bug 1047410 lands
           if (this.state.callFailed) {
-            document.title = mozL10n.get("generic_failure_title");
-          } else {
-            document.title = mozL10n.get("conversation_has_ended");
+            return <IncomingCallFailedView
+              cancelCall={this.closeWindow.bind(this)}
+            />
           }
 
+          document.title = mozL10n.get("conversation_has_ended");
+
           var feebackAPIBaseUrl = navigator.mozLoop.getLoopCharPref(
             "feedback.baseUrl");
 
           var appVersionInfo = navigator.mozLoop.appVersionInfo;
 
           var feedbackClient = new loop.FeedbackAPIClient(feebackAPIBaseUrl, {
             product: navigator.mozLoop.getLoopCharPref("feedback.product"),
             platform: appVersionInfo.OS,
@@ -389,37 +420,42 @@ loop.conversation = (function(mozL10n) {
      * @param {Object} progressData The progress data from the websocket.
      * @param {String} previousState The previous state from the websocket.
      */
     _handleWebSocketProgress: function(progressData, previousState) {
       // We only care about the terminated state at the moment.
       if (progressData.state !== "terminated")
         return;
 
-      if (progressData.reason === "cancel" ||
-          progressData.reason === "closed") {
+      // XXX This would be nicer in the _abortIncomingCall function, but we need to stop
+      // it here for now due to server-side issues that are being fixed in bug 1088351.
+      // This is before the abort call to ensure that it happens before the window is
+      // closed.
+      navigator.mozLoop.stopAlerting();
+
+      // If we hit any of the termination reasons, and the user hasn't accepted
+      // then it seems reasonable to close the window/abort the incoming call.
+      //
+      // If the user has accepted the call, and something's happened, display
+      // the call failed view.
+      //
+      // https://wiki.mozilla.org/Loop/Architecture/MVP#Termination_Reasons
+      if (previousState === "init" || previousState === "alerting") {
         this._abortIncomingCall();
-        return;
+      } else {
+        this.setState({callFailed: true, callStatus: "end"});
       }
 
-      if (progressData.reason === "timeout") {
-        if (previousState === "init" || previousState === "alerting") {
-          this._abortIncomingCall();
-        } else {
-          this.setState({callFailed: true, callStatus: "end"});
-        }
-      }
     },
 
     /**
      * Silently aborts an incoming call - stops the alerting, and
      * closes the websocket.
      */
     _abortIncomingCall: function() {
-      navigator.mozLoop.stopAlerting();
       this._websocket.close();
       // Having a timeout here lets the logging for the websocket complete and be
       // displayed on the console if both are on.
       setTimeout(this.closeWindow, 0);
     },
 
     closeWindow: function() {
       window.close();
@@ -639,13 +675,14 @@ loop.conversation = (function(mozL10n) {
       outgoing: outgoing
     }));
   }
 
   return {
     AppControllerView: AppControllerView,
     IncomingConversationView: IncomingConversationView,
     IncomingCallView: IncomingCallView,
+    IncomingCallFailedView: IncomingCallFailedView,
     init: init
   };
 })(document.mozL10n);
 
 document.addEventListener('DOMContentLoaded', loop.conversation.init);
--- a/browser/components/loop/test/desktop-local/conversation_test.js
+++ b/browser/components/loop/test/desktop-local/conversation_test.js
@@ -426,151 +426,83 @@ describe("loop.conversation", function()
                 resolve();
               });
 
               sandbox.stub(loop.CallConnectionWebSocket.prototype, "promiseConnect").returns(promise);
               sandbox.stub(loop.CallConnectionWebSocket.prototype, "close");
               sandbox.stub(window, "close");
             });
 
-            describe("progress - terminated - cancel", function() {
-              it("should stop alerting", function(done) {
-                promise.then(function() {
-                  icView._websocket.trigger("progress", {
-                    state: "terminated",
-                    reason: "cancel"
-                  });
-
-                  sinon.assert.calledOnce(navigator.mozLoop.stopAlerting);
-                  done();
-                });
-              });
-
-              it("should close the websocket", function(done) {
-                promise.then(function() {
-                  icView._websocket.trigger("progress", {
-                    state: "terminated",
-                    reason: "cancel"
-                  });
-
-                  sinon.assert.calledOnce(icView._websocket.close);
-                  done();
-                });
-              });
-
-              it("should close the window", function(done) {
-                promise.then(function() {
-                  icView._websocket.trigger("progress", {
-                    state: "terminated",
-                    reason: "cancel"
-                  });
-
-                  sandbox.clock.tick(1);
-
-                  sinon.assert.calledOnce(window.close);
-                  done();
-                });
-              });
-            });
-
-            describe("progress - terminated - closed", function() {
-              it("should stop alerting", function(done) {
-                promise.then(function() {
-                  icView._websocket.trigger("progress", {
-                    state: "terminated",
-                    reason: "closed"
-                  });
-
-                  sinon.assert.calledOnce(navigator.mozLoop.stopAlerting);
-                  done();
-                });
-              });
-
-              it("should close the websocket", function(done) {
-                promise.then(function() {
-                  icView._websocket.trigger("progress", {
-                    state: "terminated",
-                    reason: "closed"
-                  });
-
-                  sinon.assert.calledOnce(icView._websocket.close);
-                  done();
-                });
-              });
-
-              it("should close the window", function(done) {
-                promise.then(function() {
-                  icView._websocket.trigger("progress", {
-                    state: "terminated",
-                    reason: "closed"
-                  });
-
-                  sandbox.clock.tick(1);
-
-                  sinon.assert.calledOnce(window.close);
-                  done();
-                });
-              });
-            });
-
-            describe("progress - terminated - timeout (previousState = alerting)", function() {
+            describe("progress - terminated (previousState = alerting)", function() {
               it("should stop alerting", function(done) {
                 promise.then(function() {
                   icView._websocket.trigger("progress", {
                     state: "terminated",
                     reason: "timeout"
                   }, "alerting");
 
                   sinon.assert.calledOnce(navigator.mozLoop.stopAlerting);
                   done();
                 });
               });
 
               it("should close the websocket", function(done) {
                 promise.then(function() {
                   icView._websocket.trigger("progress", {
                     state: "terminated",
-                    reason: "timeout"
+                    reason: "closed"
                   }, "alerting");
 
                   sinon.assert.calledOnce(icView._websocket.close);
                   done();
                 });
               });
 
               it("should close the window", function(done) {
                 promise.then(function() {
                   icView._websocket.trigger("progress", {
                     state: "terminated",
-                    reason: "timeout"
+                    reason: "answered-elsewhere"
                   }, "alerting");
 
                   sandbox.clock.tick(1);
 
                   sinon.assert.calledOnce(window.close);
                   done();
                 });
               });
             });
 
-            describe("progress - terminated - timeout (previousState not init" +
+            describe("progress - terminated (previousState not init" +
                      " nor alerting)",
               function() {
                 it("should set the state to end", function(done) {
                   promise.then(function() {
                     icView._websocket.trigger("progress", {
                       state: "terminated",
-                      reason: "timeout"
+                      reason: "media-fail"
                     }, "connecting");
 
                     expect(icView.state.callStatus).eql("end");
                     done();
                   });
                 });
-              });
+
+                it("should stop alerting", function(done) {
+                  promise.then(function() {
+                    icView._websocket.trigger("progress", {
+                      state: "terminated",
+                      reason: "media-fail"
+                    }, "connecting");
+
+                    sinon.assert.calledOnce(navigator.mozLoop.stopAlerting);
+                    done();
+                  });
+                });
+            });
           });
         });
       });
 
       describe("#accept", function() {
         beforeEach(function() {
           icView = mountTestComponent();
           conversation.setIncomingSessionData({
@@ -756,22 +688,22 @@ describe("loop.conversation", function()
             conversation.trigger("session:peer-hungup");
 
               TestUtils.findRenderedComponentWithType(icView,
                 sharedView.FeedbackView);
           });
       });
 
       describe("session:network-disconnected", function() {
-        it("should navigate to call/feedback when network disconnects",
+        it("should navigate to call failed when network disconnects",
           function() {
             conversation.trigger("session:network-disconnected");
 
               TestUtils.findRenderedComponentWithType(icView,
-                sharedView.FeedbackView);
+                loop.conversation.IncomingCallFailedView);
           });
 
         it("should update the conversation window toolbar title",
           function() {
             conversation.trigger("session:network-disconnected");
 
             expect(document.title).eql("generic_failure_title");
           });
new file mode 100644
--- /dev/null
+++ b/browser/components/loop/test/xpcshell/test_rooms_create.js
@@ -0,0 +1,103 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+Cu.import("resource://services-common/utils.js");
+
+XPCOMUtils.defineLazyModuleGetter(this, "Chat",
+                                  "resource:///modules/Chat.jsm");
+let hasTheseProps = function(a, b) {
+  for (let prop in a) {
+    if (a[prop] != b[prop]) {
+      return false;
+    }
+  }
+  return true;
+}
+
+let openChatOrig = Chat.open;
+
+add_test(function test_openRoomsWindow() {
+  let roomProps = {roomName: "UX Discussion",
+                   expiresIn: 5,
+                   roomOwner: "Alexis",
+                   maxSize: 2}
+
+  let roomData = {roomToken: "_nxD4V4FflQ",
+                  roomUrl: "http://localhost:3000/rooms/_nxD4V4FflQ",
+                  expiresAt: 1405534180}
+
+  loopServer.registerPathHandler("/rooms", (request, response) => {
+    if (!request.bodyInputStream) {
+      do_throw("empty request body");
+    }
+    let body = CommonUtils.readBytesFromInputStream(request.bodyInputStream);
+    let data = JSON.parse(body);
+    do_check_true(hasTheseProps(roomProps, data));
+
+    response.setStatusLine(null, 200, "OK");
+    response.write(JSON.stringify(roomData));
+    response.processAsync();
+    response.finish();
+  });
+
+  MozLoopService.register(mockPushHandler).then(() => {
+    let opened = false;
+    let created = false;
+    let urlPieces = [];
+
+    Chat.open = function(contentWindow, origin, title, url) {
+      urlPieces = url.split('/');
+      do_check_eq(urlPieces[0], "about:loopconversation#room");
+      opened = true;
+    };
+
+    let returnedID = LoopRooms.createRoom(roomProps, (error, data) => {
+      do_check_false(error);
+      do_check_true(data);
+      do_check_true(hasTheseProps(roomData, data));
+      do_check_eq(data.localRoomId, urlPieces[1]);
+      created = true;
+    });
+
+    waitForCondition(function() created && opened).then(() => {
+      do_check_true(opened, "should open a chat window");
+      do_check_eq(returnedID, urlPieces[1]);
+
+      // Verify that a delayed callback, when attached,
+      // received the same data.
+      LoopRooms.addCallback(
+        urlPieces[1], "RoomCreated",
+        (error, data) => {
+          do_check_false(error);
+          do_check_true(data);
+          do_check_true(hasTheseProps(roomData, data));
+          do_check_eq(data.localRoomId, urlPieces[1]);
+        });
+
+      run_next_test();
+    }, () => {
+      do_throw("should have opened a chat window");
+    });
+
+  });
+});
+
+function run_test()
+{
+  setupFakeLoopServer();
+  mockPushHandler.registrationPushURL = kEndPointUrl;
+
+  loopServer.registerPathHandler("/registration", (request, response) => {
+    response.setStatusLine(null, 200, "OK");
+    response.processAsync();
+    response.finish();
+  });
+
+  do_register_cleanup(function() {
+    // Revert original Chat.open implementation
+    Chat.open = openChatOrig;
+  });
+
+  run_next_test();
+}
--- a/browser/components/loop/test/xpcshell/test_rooms_getdata.js
+++ b/browser/components/loop/test/xpcshell/test_rooms_getdata.js
@@ -89,24 +89,26 @@ add_test(function test_getAllRooms() {
       do_check_false(error);
       do_check_true(rooms);
       do_check_eq(rooms.length, 3);
       do_check_eq(rooms[0].roomName, "First Room Name");
       do_check_eq(rooms[1].roomName, "Second Room Name");
       do_check_eq(rooms[2].roomName, "Third Room Name");
 
       let room = rooms[0];
-      do_check_true(room.localRoomID);
+      do_check_true(room.localRoomId);
+      do_check_false(room.currSize);
+      delete roomList[0].currSize;
       do_check_true(hasTheseProps(roomList[0], room));
       delete roomDetail.roomName;
       delete room.participants;
       delete roomDetail.participants;
       do_check_true(hasTheseProps(roomDetail, room));
 
-      LoopRooms.getRoomData(room.localRoomID, (error, roomData) => {
+      LoopRooms.getRoomData(room.localRoomId, (error, roomData) => {
         do_check_false(error);
         do_check_true(hasTheseProps(room, roomData));
 
         run_next_test();
       });
     });
   });
 });
--- a/browser/components/loop/test/xpcshell/xpcshell.ini
+++ b/browser/components/loop/test/xpcshell/xpcshell.ini
@@ -17,8 +17,9 @@ skip-if = toolkit == 'gonk'
 [test_loopservice_registration.js]
 [test_loopservice_restart.js]
 [test_loopservice_token_invalid.js]
 [test_loopservice_token_save.js]
 [test_loopservice_token_send.js]
 [test_loopservice_token_validation.js]
 [test_loopservice_busy.js]
 [test_rooms_getdata.js]
+[test_rooms_create.js]
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1618,21 +1618,35 @@ BrowserGlue.prototype = {
         } catch (ex) {}
       }
     }
 
     if (currentUIVersion < 24) {
       // Reset homepage pref for users who have it set to start.mozilla.org
       // or google.com/firefox.
       const HOMEPAGE_PREF = "browser.startup.homepage";
-      let uri = Services.prefs.getComplexValue(HOMEPAGE_PREF,
-                                               Ci.nsIPrefLocalizedString).data;
-      if (uri && (uri.startsWith("http://start.mozilla.org") ||
-                  /^https?:\/\/(www\.)?google\.[a-z.]+\/firefox/i.test(uri))) {
-        Services.prefs.clearUserPref(HOMEPAGE_PREF);
+      if (Services.prefs.prefHasUserValue(HOMEPAGE_PREF)) {
+        const DEFAULT =
+          Services.prefs.getDefaultBranch(HOMEPAGE_PREF)
+                        .getComplexValue("", Ci.nsIPrefLocalizedString).data;
+        let value =
+          Services.prefs.getComplexValue(HOMEPAGE_PREF, Ci.nsISupportsString);
+        let updated =
+          value.data.replace(/https?:\/\/start\.mozilla\.org[^|]*/i, DEFAULT)
+                    .replace(/https?:\/\/(www\.)?google\.[a-z.]+\/firefox[^|]*/i,
+                             DEFAULT);
+        if (updated != value.data) {
+          if (updated == DEFAULT) {
+            Services.prefs.clearUserPref(HOMEPAGE_PREF);
+          } else {
+            value.data = updated;
+            Services.prefs.setComplexValue(HOMEPAGE_PREF,
+                                           Ci.nsISupportsString, value);
+          }
+        }
       }
     }
 
     if (currentUIVersion < 25) {
       // Make sure the doNotTrack value conforms to the conversion from
       // three-state to two-state. (This reverts a setting of "please track me"
       // to the default "don't say anything").
       try {
--- a/browser/devtools/styleinspector/css-parsing-utils.js
+++ b/browser/devtools/styleinspector/css-parsing-utils.js
@@ -87,16 +87,17 @@ function parseDeclarations(inputString) 
           current += "#" + token.value;
           break;
         case "URL":
           current += "url(" + quoteString(token.value) + ")";
           break;
         case "FUNCTION":
           current += token.value + "(";
           break;
+        case "(":
         case ")":
           current += token.tokenType;
           break;
         case "EOF":
           break;
         case "DELIM":
           if (token.value === "!") {
             hasBang = true;
--- a/browser/devtools/styleinspector/test/unit/test_parseDeclarations.js
+++ b/browser/devtools/styleinspector/test/unit/test_parseDeclarations.js
@@ -158,17 +158,19 @@ const TEST_DATA = [
   {input: "content: 'this \\' is a \" really strange string'", expected: [{name: "content", value: '"this \' is a \" really strange string"', priority: ""}]},
   {
     input: "content: \"a not s\\\
           o very long title\"",
     expected: [
       {name: "content", value: '"a not s\
           o very long title"', priority: ""}
     ]
-  }
+  },
+  // Test calc with nested parentheses
+  {input: "width: calc((100% - 3em) / 2)", expected: [{name: "width", value: "calc((100% - 3em) / 2)", priority: ""}]},
 ];
 
 function run_test() {
   for (let test of TEST_DATA) {
     do_print("Test input string " + test.input);
     let output;
     try {
       output = parseDeclarations(test.input);
--- a/build/appini_header.py
+++ b/build/appini_header.py
@@ -18,33 +18,34 @@ def main(file):
     except: pass
     try:
         if config.getint('Crash Reporter', 'Enabled') == 1:
             flags.add('NS_XRE_ENABLE_CRASH_REPORTER')
     except: pass
     appdata = dict(("%s:%s" % (s, o), config.get(s, o)) for s in config.sections() for o in config.options(s))
     appdata['flags'] = ' | '.join(flags) if flags else '0'
     appdata['App:profile'] = '"%s"' % appdata['App:profile'] if 'App:profile' in appdata else 'NULL'
-    expected = ('App:vendor', 'App:name', 'App:version', 'App:buildid',
+    expected = ('App:vendor', 'App:name', 'App:remotingname', 'App:version', 'App:buildid',
                 'App:id', 'Gecko:minversion', 'Gecko:maxversion')
     missing = [var for var in expected if var not in appdata]
     if missing:
         print >>sys.stderr, \
             "Missing values in %s: %s" % (file, ', '.join(missing))
         sys.exit(1)
 
     if not 'Crash Reporter:serverurl' in appdata:
         appdata['Crash Reporter:serverurl'] = ''
 
     print '''#include "nsXREAppData.h"
              static const nsXREAppData sAppData = {
                  sizeof(nsXREAppData),
                  NULL, // directory
                  "%(App:vendor)s",
                  "%(App:name)s",
+                 "%(App:remotingname)s",
                  "%(App:version)s",
                  "%(App:buildid)s",
                  "%(App:id)s",
                  NULL, // copyright
                  %(flags)s,
                  NULL, // xreDirectory
                  "%(Gecko:minversion)s",
                  "%(Gecko:maxversion)s",
--- a/build/application.ini
+++ b/build/application.ini
@@ -13,16 +13,17 @@
 ; This Source Code Form is subject to the terms of the Mozilla Public
 ; License, v. 2.0. If a copy of the MPL was not distributed with this
 ; file, You can obtain one at http://mozilla.org/MPL/2.0/.
 #endif
 #filter substitution
 [App]
 Vendor=@MOZ_APP_VENDOR@
 Name=@MOZ_APP_BASENAME@
+RemotingName=@MOZ_APP_REMOTINGNAME@
 #ifdef MOZ_APP_DISPLAYNAME
 CodeName=@MOZ_APP_DISPLAYNAME@
 #endif
 Version=@MOZ_APP_VERSION@
 #ifdef MOZ_APP_PROFILE
 Profile=@MOZ_APP_PROFILE@
 #endif
 BuildID=@APP_BUILDID@
--- a/build/moz.build
+++ b/build/moz.build
@@ -22,17 +22,17 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'andr
         'mobile/sutagent/android/watcher',
         'mobile/sutagent/android/ffxcp',
         'mobile/sutagent/android/fencp',
         'mobile/robocop',
     ]
 
 for var in ('GRE_MILESTONE', 'MOZ_APP_VERSION', 'MOZ_APP_BASENAME',
             'MOZ_APP_VENDOR', 'MOZ_APP_ID', 'MAR_CHANNEL_ID',
-            'ACCEPTED_MAR_CHANNEL_IDS'):
+            'ACCEPTED_MAR_CHANNEL_IDS', 'MOZ_APP_REMOTINGNAME'):
     DEFINES[var] = CONFIG[var]
 
 if CONFIG['MOZ_APP_DISPLAYNAME'] != CONFIG['MOZ_APP_BASENAME']:
     DEFINES['MOZ_APP_DISPLAYNAME'] = CONFIG['MOZ_APP_DISPLAYNAME']
 
 if CONFIG['MOZ_BUILD_APP'] == 'browser':
     DEFINES['MOZ_BUILD_APP_IS_BROWSER'] = True
 
--- a/configure.in
+++ b/configure.in
@@ -8678,26 +8678,32 @@ AC_SUBST(MOZ_CHILD_PROCESS_BUNDLE)
 # the absence of a "Profile" field (see below), and various system
 # integration hooks (Unix remoting, Windows MessageWindow name, etc.)
 # - MOZ_APP_DISPLAYNAME: Used in user-visible fields (DLL properties,
 # Mac Bundle name, Updater, Installer), it is typically used for nightly
 # builds (e.g. Aurora for Firefox).
 # - MOZ_APP_VERSION: Defines the application version number.
 # - MOZ_APP_NAME: Used for e.g. the binary program file name. If not set,
 # defaults to a lowercase form of MOZ_APP_BASENAME.
+# - MOZ_APP_REMOTINGNAME: Used for the internal program name, which affects
+# profile name and remoting. If not set, defaults to MOZ_APP_NAME.
 # - MOZ_APP_PROFILE: When set, used for application.ini's
 # "Profile" field, which controls profile location.
 # - MOZ_APP_ID: When set, used for application.ini's "ID" field, and
 # crash reporter server url.
 # - MOZ_PROFILE_MIGRATOR: When set, enables profile migrator.
 
 if test -z "$MOZ_APP_NAME"; then
    MOZ_APP_NAME=`echo $MOZ_APP_BASENAME | tr A-Z a-z`
 fi
 
+if test -z "$MOZ_APP_REMOTINGNAME"; then
+   MOZ_APP_REMOTINGNAME=$MOZ_APP_NAME
+fi
+
 # For extensions and langpacks, we require a max version that is compatible
 # across security releases. MOZ_APP_MAXVERSION is our method for doing that.
 # 24.0a1 and 24.0a2 aren't affected
 # 24.0 becomes 24.*
 # 24.1.1 becomes 24.*
 IS_ALPHA=`echo $MOZ_APP_VERSION | grep a`
 if test -z "$IS_ALPHA"; then
   changequote(,)
@@ -8707,16 +8713,17 @@ else
   MOZ_APP_MAXVERSION=$MOZ_APP_VERSION
 fi
 
 MOZ_B2G_VERSION=${MOZ_B2G_VERSION:-"1.0.0"}
 AC_DEFINE_UNQUOTED(MOZ_B2G_VERSION,"$MOZ_B2G_VERSION")
 AC_DEFINE_UNQUOTED(MOZ_B2G_OS_NAME,"$MOZ_B2G_OS_NAME")
 
 AC_SUBST(MOZ_APP_NAME)
+AC_SUBST(MOZ_APP_REMOTINGNAME)
 AC_SUBST(MOZ_APP_DISPLAYNAME)
 AC_SUBST(MOZ_APP_BASENAME)
 AC_SUBST(MOZ_APP_VENDOR)
 AC_SUBST(MOZ_APP_PROFILE)
 AC_SUBST(MOZ_APP_ID)
 AC_SUBST(MAR_CHANNEL_ID)
 AC_SUBST(ACCEPTED_MAR_CHANNEL_IDS)
 AC_SUBST(MOZ_PROFILE_MIGRATOR)
@@ -8999,16 +9006,20 @@ if test "$ACCESSIBILITY" -a "$MOZ_ENABLE
     ATK_MAJOR_VERSION=`echo ${ATK_FULL_VERSION} | $AWK -F\. '{ print $1 }'`
     ATK_MINOR_VERSION=`echo ${ATK_FULL_VERSION} | $AWK -F\. '{ print $2 }'`
     ATK_REV_VERSION=`echo ${ATK_FULL_VERSION} | $AWK -F\. '{ print $3 }'`
     AC_DEFINE_UNQUOTED(ATK_MAJOR_VERSION, $ATK_MAJOR_VERSION)
     AC_DEFINE_UNQUOTED(ATK_MINOR_VERSION, $ATK_MINOR_VERSION)
     AC_DEFINE_UNQUOTED(ATK_REV_VERSION, $ATK_REV_VERSION)
 fi
 
+if test "$MOZ_UPDATE_CHANNEL" = "aurora"; then
+    AC_DEFINE(MOZ_DEV_EDITION)
+fi
+
 if test "$MOZ_DEBUG"; then
     A11Y_LOG=1
 fi
 case "$MOZ_UPDATE_CHANNEL" in
 aurora|beta|release|esr)
     ;;
 *)
     A11Y_LOG=1
@@ -9303,16 +9314,17 @@ if test -n "$MOZ_GLUE_PROGRAM_LDFLAGS"; 
 fi
 if test -n "$ZLIB_IN_MOZGLUE"; then
    MOZ_ZLIB_LIBS=
 fi
 export MOZ_NATIVE_ZLIB
 export MOZ_ZLIB_CFLAGS
 export MOZ_ZLIB_LIBS
 export MOZ_APP_NAME
+export MOZ_APP_REMOTINGNAME
 export DONT_POPULATE_VIRTUALENV=1
 export PYTHON
 export MOZILLA_CENTRAL_PATH=$_topsrcdir
 export STLPORT_CPPFLAGS
 export STLPORT_LIBS
 export JS_STANDALONE=no
 export MOZ_LINKER
 export ZLIB_IN_MOZGLUE
--- a/content/base/test/mochitest.ini
+++ b/content/base/test/mochitest.ini
@@ -584,16 +584,17 @@ skip-if = e10s
 skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s #bug 775227
 [test_getElementById.html]
 [test_html_colors_quirks.html]
 [test_html_colors_standards.html]
 [test_html_in_xhr.html]
 [test_htmlcopyencoder.html]
 [test_htmlcopyencoder.xhtml]
 [test_ipc_messagemanager_blob.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 936226
 [test_meta_viewport0.html]
 [test_meta_viewport1.html]
 [test_meta_viewport2.html]
 [test_meta_viewport3.html]
 [test_meta_viewport4.html]
 [test_meta_viewport5.html]
 [test_meta_viewport6.html]
 [test_mixed_content_blocker.html]
--- a/content/html/content/test/forms/mochitest.ini
+++ b/content/html/content/test/forms/mochitest.ini
@@ -53,16 +53,17 @@ skip-if = buildapp == 'mulet' || os == "
 [test_input_range_key_events.html]
 skip-if = buildapp == 'mulet' || (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
 [test_input_range_mouse_and_touch_events.html]
 skip-if = (toolkit == 'gonk' && debug) #debug-only failure; bug 926546
 [test_input_range_rounding.html]
 skip-if = buildapp == 'mulet' || (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
 [test_input_sanitization.html]
 [test_input_textarea_set_value_no_scroll.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
 [test_input_typing_sanitization.html]
 skip-if = buildapp == 'mulet'
 [test_input_untrusted_key_events.html]
 [test_input_url.html]
 [test_label_control_attribute.html]
 [test_label_input_controls.html]
 [test_max_attribute.html]
 skip-if = e10s
--- a/content/media/test/mochitest.ini
+++ b/content/media/test/mochitest.ini
@@ -301,46 +301,54 @@ support-files =
   wavedata_u8.wav
   wavedata_u8.wav^headers^
 
 [test_access_control.html]
 skip-if = buildapp == 'b2g' && toolkit != 'gonk' # bug 1082984
 [test_aspectratio_mp4.html]
 [test_audio1.html]
 [test_audio2.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_audioDocumentTitle.html]
 skip-if = true # bug 475110 - disabled since we don't play Wave files standalone
 [test_autoplay.html]
 [test_autoplay_contentEditable.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
 [test_buffered.html]
 [test_bug448534.html]
-skip-if = buildapp == 'mulet' || os == 'win' # bug 894922
+skip-if = buildapp == 'mulet' || os == 'win' || (toolkit == 'android' && processor == 'x86') # bug 894922 #x86 only bug 914439
 [test_bug463162.xhtml]
 [test_bug465498.html]
+skip-if = (toolkit == 'android' && processor == 'x86')
 [test_bug493187.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_bug495145.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_bug495300.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_bug654550.html]
 [test_bug686942.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_bug726904.html]
 [test_bug874897.html]
 [test_bug883173.html]
 [test_bug895091.html]
 [test_bug895305.html]
 [test_bug919265.html]
 [test_bug957847.html]
 [test_bug1018933.html]
 [test_can_play_type.html]
 [test_can_play_type_mpeg.html]
-skip-if = buildapp == 'b2g' # bug 1021675
+skip-if = buildapp == 'b2g' || (toolkit == 'android' && processor == 'x86') # bug 1021675 #x86 only bug 914439
 [test_can_play_type_no_ogg.html]
 [test_can_play_type_ogg.html]
 [test_chaining.html]
 skip-if = toolkit == 'gonk' && debug
 [test_clone_media_element.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_closing_connections.html]
 [test_constants.html]
 [test_contentDuration1.html]
 [test_contentDuration2.html]
 [test_contentDuration3.html]
 [test_contentDuration4.html]
 [test_contentDuration5.html]
 [test_contentDuration6.html]
@@ -353,29 +361,36 @@ skip-if = toolkit == 'gonk' && debug
 [test_delay_load.html]
 skip-if = buildapp == 'b2g' && toolkit != 'gonk' # bug 1082984
 [test_encryptedMediaExtensions.html]
 skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # bug 1043403, bug 1057908
 [test_error_in_video_document.html]
 skip-if = toolkit == 'android' # bug 608634
 [test_error_on_404.html]
 [test_fastSeek.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_fastSeek-forwards.html]
 [test_imagecapture.html]
 [test_info_leak.html]
 [test_invalid_reject.html]
 [test_invalid_reject_play.html]
 [test_invalid_seek.html]
 [test_load.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_load_candidates.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_load_same_resource.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_load_source.html]
 [test_loop.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_media_selection.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_media_sniffer.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_mediarecorder_avoid_recursion.html]
 [test_mediarecorder_creation.html]
 [test_mediarecorder_creation_fail.html]
 [test_mediarecorder_getencodeddata.html]
 [test_mediarecorder_record_4ch_audiocontext.html]
 [test_mediarecorder_record_audiocontext.html]
 [test_mediarecorder_record_audiocontext_mlk.html]
 [test_mediarecorder_record_audionode.html]
@@ -403,84 +418,103 @@ skip-if = toolkit == 'gonk' && debug # b
 [test_mediatrack_parsing_ogg.html]
 [test_mediatrack_replay_from_end.html]
 [test_metadata.html]
 [test_mixed_principals.html]
 skip-if = true # bug 567954 and intermittent leaks
 [test_mozHasAudio.html]
 [test_networkState.html]
 [test_new_audio.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_no_load_event.html]
 [test_paused.html]
 [test_paused_after_ended.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_play_events.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_play_events_2.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_play_twice.html]
 # Seamonkey: Bug 598252, B2G: Bug 982100, Android: Bug 758476, bug 981086
 skip-if = appname == "seamonkey" || toolkit == 'gonk' || toolkit == 'android'
 [test_playback.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_playback_errors.html]
 [test_playback_rate.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #bug 845162
 [test_playback_rate_playpause.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_played.html]
 skip-if = true # bug 1021794
 [test_preload_actions.html]
 [test_preload_attribute.html]
 [test_preload_suspend.html]
 skip-if = true # bug 493692
 [test_progress.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_reactivate.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_readyState.html]
 [test_referer.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
 [test_replay_metadata.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_reset_events_async.html]
 [test_reset_src.html]
 [test_resume.html]
 skip-if = true # bug 1021673
 [test_seek_out_of_range.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_seek-1.html]
 [test_seek-2.html]
 [test_seek-3.html]
 [test_seek-4.html]
 [test_seek-5.html]
 [test_seek-6.html]
 [test_seek-7.html]
 [test_seek-8.html]
 [test_seek-9.html]
 [test_seek-10.html]
 [test_seek-11.html]
 [test_seek-12.html]
 [test_seek-13.html]
 [test_seekable1.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #timeout x86 only bug 914439
 [test_seekable2.html]
 [test_seekable3.html]
 [test_seekLies.html]
 [test_source.html]
 [test_source_media.html]
 [test_source_null.html]
 [test_source_write.html]
 [test_standalone.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_streams_autoplay.html]
 [test_streams_element_capture.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_streams_element_capture_createObjectURL.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_streams_element_capture_playback.html]
 [test_streams_element_capture_reset.html]
 [test_streams_gc.html]
 skip-if = buildapp == 'b2g' # bug 1021682
 [test_streams_srcObject.html]
 [test_streams_tracks.html]
 [test_texttrack.html]
 [test_texttrackcue.html]
 [test_texttracklist.html]
 [test_texttrackregion.html]
 [test_timeupdate_small_files.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_trackelementevent.html]
 [test_trackevent.html]
 [test_unseekable.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
 [test_video_to_canvas.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439
 [test_video_in_audio_element.html]
 [test_videoDocumentTitle.html]
 [test_VideoPlaybackQuality.html]
 [test_VideoPlaybackQuality_disabled.html]
 [test_volume.html]
 [test_vttparser.html]
 [test_webvtt_disabled.html]
 
--- a/content/media/webaudio/test/mochitest.ini
+++ b/content/media/webaudio/test/mochitest.ini
@@ -30,16 +30,17 @@ support-files =
 [test_AudioBuffer.html]
 [test_audioBufferSourceNode.html]
 [test_audioBufferSourceNodeEnded.html]
 [test_audioBufferSourceNodeLazyLoopParam.html]
 [test_audioBufferSourceNodeLoop.html]
 [test_audioBufferSourceNodeLoopStartEnd.html]
 [test_audioBufferSourceNodeLoopStartEndSame.html]
 [test_audioBufferSourceNodeNeutered.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
 [test_audioBufferSourceNodeNoStart.html]
 [test_audioBufferSourceNodeNullBuffer.html]
 [test_audioBufferSourceNodeOffset.html]
 skip-if = (toolkit == 'gonk') || (toolkit == 'android') || debug #bug 906752
 [test_audioBufferSourceNodePassThrough.html]
 [test_AudioContext.html]
 [test_audioDestinationNode.html]
 [test_AudioListener.html]
--- a/docshell/test/navigation/mochitest.ini
+++ b/docshell/test/navigation/mochitest.ini
@@ -33,17 +33,17 @@ skip-if = buildapp == 'mulet' || (builda
 [test_bug386782.html]
 skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug))
 [test_bug430624.html]
 [test_bug430723.html]
 skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) || toolkit == 'android' #TIMED_OUT # b2g-debug(bug 874423) b2g-desktop(Bug 931116, b2g desktop specific, initial triage)
 [test_child.html]
 [test_grandchild.html]
 [test_not-opener.html]
-skip-if = buildapp == 'b2g'
+skip-if = buildapp == 'b2g' || (toolkit == 'android' && processor == 'x86') #x86 only
 [test_opener.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
 [test_popup-navigates-children.html]
 skip-if = buildapp == 'b2g' # b2g(Needs multiple window.open support, also uses docshelltreenode) b2g-debug(Needs multiple window.open support, also uses docshelltreenode) b2g-desktop(Needs multiple window.open support, also uses docshelltreenode)
 [test_reserved.html]
 skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug))
 [test_sessionhistory.html]
 skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) || toolkit == 'android' #RANDOM # b2g-debug(Perma-orange on debug emulator builds) b2g-desktop(Bug 931116, b2g desktop specific, initial triage)
--- a/dom/apps/tests/mochitest.ini
+++ b/dom/apps/tests/mochitest.ini
@@ -26,14 +26,16 @@ support-files =
 [test_app_update.html]
 [test_bug_795164.html]
 [test_import_export.html]
 [test_install_multiple_apps_origin.html]
 [test_install_receipts.html]
 [test_marketplace_pkg_install.html]
 skip-if = buildapp == "b2g" || toolkit == "android" # see bug 989806
 [test_packaged_app_install.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
 [test_packaged_app_update.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
 [test_receipt_operations.html]
 [test_signed_pkg_install.html]
 [test_uninstall_errors.html]
 [test_theme_role.html]
 [test_widget.html]
--- a/dom/browser-element/mochitest/mochitest.ini
+++ b/dom/browser-element/mochitest/mochitest.ini
@@ -148,16 +148,17 @@ skip-if = buildapp == 'b2g'
 [test_browserElement_inproc_Download.html]
 disabled = bug 1022281
 [test_browserElement_inproc_ExposableURI.html]
 [test_browserElement_inproc_FirstPaint.html]
 [test_browserElement_inproc_ForwardName.html]
 [test_browserElement_inproc_FrameWrongURI.html]
 skip-if = (toolkit == 'gonk' && !debug)
 [test_browserElement_inproc_GetScreenshot.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
 [test_browserElement_inproc_GetScreenshotDppx.html]
 [test_browserElement_inproc_Iconchange.html]
 [test_browserElement_inproc_KeyEvents.html]
 skip-if = (toolkit == 'gonk' && !debug)
 [test_browserElement_inproc_LoadEvents.html]
 [test_browserElement_inproc_Manifestchange.html]
 [test_browserElement_inproc_Metachange.html]
 [test_browserElement_inproc_NextPaint.html]
@@ -195,15 +196,16 @@ skip-if = (toolkit == 'gonk' && !debug)
 [test_browserElement_inproc_Titlechange.html]
 [test_browserElement_inproc_TopBarrier.html]
 [test_browserElement_inproc_VisibilityChange.html]
 [test_browserElement_inproc_XFrameOptions.html]
 [test_browserElement_inproc_XFrameOptionsAllowFrom.html]
 [test_browserElement_inproc_XFrameOptionsDeny.html]
 [test_browserElement_inproc_XFrameOptionsSameOrigin.html]
 [test_browserElement_oop_NextPaint.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 936226
 # Disabled due to https://bugzilla.mozilla.org/show_bug.cgi?id=774100
 [test_browserElement_inproc_Reload.html]
 disabled = bug 774100
 # Disabled due to focus issues (no bug that I'm aware of)
 [test_browserElement_oop_KeyEvents.html]
 disabled =
 [test_browserElement_inproc_GetContentDimensions.html]
--- a/dom/canvas/test/mochitest.ini
+++ b/dom/canvas/test/mochitest.ini
@@ -20,37 +20,59 @@ support-files =
   image_transparent.png
   image_transparent50.png
   image_yellow.png
   image_yellow75.png
 
 [test_2d.clearRect.image.offscreen.html]
 [test_2d.clip.winding.html]
 [test_2d.composite.canvas.color-burn.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 913662
 [test_2d.composite.canvas.color-dodge.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 913662
 [test_2d.composite.canvas.color.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 913662
 [test_2d.composite.canvas.darken.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 913662
 [test_2d.composite.canvas.destination-atop.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 913662
 [test_2d.composite.canvas.destination-in.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 913662
 [test_2d.composite.canvas.difference.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 913662
 [test_2d.composite.canvas.exclusion.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 913662
 [test_2d.composite.canvas.hard-light.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 913662
 [test_2d.composite.canvas.hue.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 913662
 [test_2d.composite.canvas.lighten.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 913662
 [test_2d.composite.canvas.luminosity.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 913662
 [test_2d.composite.canvas.multiply.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 913662
 [test_2d.composite.canvas.overlay.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 913662
 [test_2d.composite.canvas.saturation.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 913662
 [test_2d.composite.canvas.screen.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 913662
 [test_2d.composite.canvas.soft-light.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 913662
 [test_2d.composite.canvas.source-in.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 913662
 [test_2d.composite.canvas.source-out.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 913662
 [test_2d.composite.image.destination-atop.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 913662
 [test_2d.composite.image.destination-in.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 913662
 [test_2d.composite.image.source-in.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 913662
 [test_2d.composite.image.source-out.html]
 # xor and lighter aren't well handled by cairo; they mostly work, but we don't want
 # to test that
 [test_2d.composite.solid.xor.html]
 disabled =
 [test_2d.composite.solid.lighter.html]
 disabled =
 [test_2d.composite.transparent.xor.html]
@@ -107,18 +129,21 @@ skip-if = os == 'linux' && buildapp == '
 skip-if = toolkit != 'cocoa'
 [test_2d.composite.uncovered.fill.destination-in.html]
 skip-if = toolkit != 'cocoa'
 [test_2d.composite.uncovered.fill.source-out.html]
 skip-if = toolkit != 'cocoa'
 [test_2d.composite.uncovered.fill.destination-atop.html]
 skip-if = toolkit != 'cocoa'
 [test_2d.composite.uncovered.image.destination-in.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 913662
 [test_2d.composite.uncovered.image.source-in.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 913662
 [test_2d.composite.uncovered.image.source-out.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 913662
 # Tests that fail on non-Mac (bug 407107)
 [test_2d.composite.uncovered.pattern.source-in.html]
 skip-if = toolkit != 'cocoa'
 [test_2d.composite.uncovered.pattern.destination-in.html]
 skip-if = toolkit != 'cocoa'
 [test_2d.composite.uncovered.pattern.source-out.html]
 skip-if = toolkit != 'cocoa'
 [test_2d.composite.uncovered.pattern.destination-atop.html]
--- a/dom/datastore/tests/mochitest.ini
+++ b/dom/datastore/tests/mochitest.ini
@@ -30,22 +30,25 @@ support-files =
   file_basic_common.js
   file_sync_common.js
   file_bug1008044.html
   file_bug957086.html
   file_notify_system_message.html
 
 [test_app_install.html]
 [test_readonly.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 936226
 [test_basic.html]
 [test_basic_worker.html]
 [test_changes.html]
 [test_arrays.html]
 [test_oop.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 936226
 [test_sync.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 936226
 [test_sync_worker.html]
 [test_bug924104.html]
 [test_certifiedApp.html]
 [test_keys.html]
 [test_duplicate.html]
 [test_bug976311.html]
 [test_bug986056.html]
 [test_oop_events.html]
--- a/dom/icc/tests/marionette/test_stk_display_text.js
+++ b/dom/icc/tests/marionette/test_stk_display_text.js
@@ -60,51 +60,135 @@ let tests = [
             text: "This command instructs the ME to display a text message. It allows the SIM to define the priority of that message, and the text string format. Two types of prio",
             userClear: true}},
   {command: "d01a8103012180820281028d0f043c474f2d4241434b57415244533e",
    func: testDisplayText,
    expect: {name: "display_text_cmd_6",
             commandQualifier: 0x80,
             text: "<GO-BACKWARDS>",
             userClear: true}},
-   {command: "d0248103012180820281028d1908041704140420041004120421042204120423041904220415",
-    func: testDisplayText,
-    expect: {name: "display_text_cmd_7",
-             commandQualifier: 0x80,
-             text: "ЗДРАВСТВУЙТЕ",
-             userClear: true}},
-   {command: "d0108103012180820281028d05084f60597d",
-    func: testDisplayText,
-    expect: {name: "display_text_cmd_8",
-             commandQualifier: 0x80,
-             text: "你好",
-             userClear: true}},
-   {command: "d0128103012180820281028d07080038003030eb",
-    func: testDisplayText,
-    expect: {name: "display_text_cmd_9",
-             commandQualifier: 0x80,
-             text: "80ル",
-             userClear: true}},
-   {command: "d0288103012180820281020d1d00d3309bfc06c95c301aa8e80259c3ec34b9ac07c9602f58ed159bb940",
-    func: testDisplayText,
-    expect: {name: "display_text_cmd_10",
-             commandQualifier: 0x80,
-             text: "Saldo 2.04 E. Validez 20/05/13. ",
-             userClear: true}},
+  {command: "d0248103012180820281028d1908041704140420041004120421042204120423041904220415",
+   func: testDisplayText,
+   expect: {name: "display_text_cmd_7",
+            commandQualifier: 0x80,
+            text: "ЗДРАВСТВУЙТЕ",
+            userClear: true}},
+  {command: "d0108103012180820281028d05084f60597d",
+   func: testDisplayText,
+   expect: {name: "display_text_cmd_8",
+            commandQualifier: 0x80,
+            text: "你好",
+            userClear: true}},
+  {command: "d0128103012180820281028d07080038003030eb",
+   func: testDisplayText,
+   expect: {name: "display_text_cmd_9",
+            commandQualifier: 0x80,
+            text: "80ル",
+            userClear: true}},
+  {command: "d0288103012180820281020d1d00d3309bfc06c95c301aa8e80259c3ec34b9ac07c9602f58ed159bb940",
+   func: testDisplayText,
+   expect: {name: "display_text_cmd_10",
+            commandQualifier: 0x80,
+            text: "Saldo 2.04 E. Validez 20/05/13. ",
+            userClear: true}},
   {command: "d0198103012180820281028D0A043130205365636F6E648402010A",
    func: testDisplayText,
    expect: {name: "display_text_cmd_11",
             commandQualifier: 0x80,
             text: "10 Second",
             userClear: true,
             duration: {timeUnit: iccManager.STK_TIME_UNIT_SECOND,
                        timeInterval: 0x0A}}},
   {command: "d01a8103012180820281028d0b0442617369632049636f6e9e020001",
-    func: testDisplayText,
-    expect: {name: "display_text_cmd_12",
-             commandQualifier: 0x80,
-             text: "Basic Icon",
-             userClear: true,
-             iconSelfExplanatory: true,
-             icons: [basicIcon]}},
+   func: testDisplayText,
+   expect: {name: "display_text_cmd_12",
+            commandQualifier: 0x80,
+            text: "Basic Icon",
+            userClear: true,
+            iconSelfExplanatory: true,
+            icons: [basicIcon]}},
+  {command: "D026810301210082028102" +
+            "8D" +
+            "1B" +
+            "00" + // 7BIT
+            "D4F79BBD4ED341D4F29C0E3A4A9F55A8" +
+            "0E8687C158A09B304905",
+   func: testDisplayText,
+   expect: {name: "display_text_cmd_13",
+            commandQualifier: 0x00,
+            text: "Toolkit Test GROUP:0x00, 7BIT"}},
+  {command: "D029810301210082028102" +
+            "8D" +
+            "1E" +
+            "04" + // 8BIT
+            "546F6F6C6B697420546573742047524F" +
+            "55503A307830302C2038424954",
+   func: testDisplayText,
+   expect: {name: "display_text_cmd_14",
+            commandQualifier: 0x00,
+            text: "Toolkit Test GROUP:0x00, 8BIT"}},
+  {command: "D046810301210082028102" +
+            "8D" +
+            "3B" +
+            "08" + // UCS2
+            "0054006F006F006C006B006900740020" +
+            "0054006500730074002000470052004F" +
+            "00550050003A0030007800300030002C" +
+            "00200055004300530032",
+   func: testDisplayText,
+   expect: {name: "display_text_cmd_15",
+            commandQualifier: 0x00,
+            text: "Toolkit Test GROUP:0x00, UCS2"}},
+  {command: "D026810301210082028102" +
+            "8D" +
+            "1B" +
+            "12" + // 7BIT + Class 2
+            "D4F79BBD4ED341D4F29C0E3A4A9F55A8" +
+            "0E868FC158A09B304905",
+   func: testDisplayText,
+   expect: {name: "display_text_cmd_16",
+            commandQualifier: 0x00,
+            text: "Toolkit Test GROUP:0x10, 7BIT"}},
+  {command: "D029810301210082028102" +
+            "8D" +
+            "1E" +
+            "16" + // 8BIT + Class 2
+            "546F6F6C6B697420546573742047524F" +
+            "55503A307831302C2038424954",
+   func: testDisplayText,
+   expect: {name: "display_text_cmd_17",
+            commandQualifier: 0x00,
+            text: "Toolkit Test GROUP:0x10, 8BIT"}},
+  {command: "D046810301210082028102" +
+            "8D" +
+            "3B" +
+            "1A" + // UCS2 + Class 2
+            "0054006F006F006C006B006900740020" +
+            "0054006500730074002000470052004F" +
+            "00550050003A0030007800310030002C" +
+            "00200055004300530032",
+   func: testDisplayText,
+   expect: {name: "display_text_cmd_18",
+            commandQualifier: 0x00,
+            text: "Toolkit Test GROUP:0x10, UCS2"}},
+  {command: "D026810301210082028102" +
+            "8D" +
+            "1B" +
+            "F2" + // 7BIT + Class 2
+            "D4F79BBD4ED341D4F29C0E3A4A9F55A8" +
+            "0E8637C258A09B304905",
+   func: testDisplayText,
+   expect: {name: "display_text_cmd_19",
+            commandQualifier: 0x00,
+            text: "Toolkit Test GROUP:0xF0, 7BIT"}},
+  {command: "D029810301210082028102" +
+            "8D" +
+            "1E" +
+            "F6" + // 8BIT + Class 2
+            "546F6F6C6B697420546573742047524F" +
+            "55503A307846302C2038424954",
+   func: testDisplayText,
+   expect: {name: "display_text_cmd_20",
+            commandQualifier: 0x00,
+            text: "Toolkit Test GROUP:0xF0, 8BIT"}},
 ];
 
 runNextTest();
--- a/dom/system/gonk/ril_consts.js
+++ b/dom/system/gonk/ril_consts.js
@@ -2483,16 +2483,17 @@ this.CALL_FAIL_FACILITY_REJECTED = 29;
 this.CALL_FAIL_CONGESTION = 34;
 this.CALL_FAIL_NETWORK_OUT_OF_ORDER = 38;
 this.CALL_FAIL_NETWORK_TEMP_FAILURE = 41;
 this.CALL_FAIL_ACM_LIMIT_EXCEEDED = 68;
 this.CALL_FAIL_CALL_BARRED = 240;
 this.CALL_FAIL_FDN_BLOCKED = 241;
 this.CALL_FAIL_IMSI_UNKNOWN_IN_VLR = 242;
 this.CALL_FAIL_IMEI_NOT_ACCEPTED = 243;
+this.CALL_FAIL_DIAL_MODIFIED_TO_DIAL = 246;
 this.CALL_FAIL_ERROR_UNSPECIFIED = 0xffff;
 
 // See nsIMobileConnection::MOBILE_RADIO_STATE_*
 this.GECKO_RADIOSTATE_UNKNOWN   = -1;
 this.GECKO_RADIOSTATE_ENABLING  = 0;
 this.GECKO_RADIOSTATE_ENABLED   = 1;
 this.GECKO_RADIOSTATE_DISABLING = 2;
 this.GECKO_RADIOSTATE_DISABLED  = 3;
@@ -2619,58 +2620,60 @@ NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_
 NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_UNKNOWN] = GECKO_MOBILE_CONNECTION_STATE_UNKNOWN;
 NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_REGISTERED_ROAMING] = GECKO_MOBILE_CONNECTION_STATE_REGISTERED;
 NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_NOT_SEARCHING_EMERGENCY_CALLS] = GECKO_MOBILE_CONNECTION_STATE_NOTSEARCHING;
 NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_SEARCHING_EMERGENCY_CALLS] = GECKO_MOBILE_CONNECTION_STATE_SEARCHING;
 NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_DENIED_EMERGENCY_CALLS] = GECKO_MOBILE_CONNECTION_STATE_DENIED;
 NETWORK_CREG_TO_GECKO_MOBILE_CONNECTION_STATE[NETWORK_CREG_STATE_UNKNOWN_EMERGENCY_CALLS] = GECKO_MOBILE_CONNECTION_STATE_UNKNOWN;
 
 
-this.GECKO_CALL_ERROR_BAD_NUMBER             = "BadNumberError";
-this.GECKO_CALL_ERROR_NORMAL_CALL_CLEARING   = "NormalCallClearingError";
-this.GECKO_CALL_ERROR_BUSY                   = "BusyError";
-this.GECKO_CALL_ERROR_NO_USER_RESPONDING     = "NoUserRespondingError";
-this.GECKO_CALL_ERROR_USER_ALERTING          = "UserAlertingNoAnswerError";
-this.GECKO_CALL_ERROR_REJECTED               = "CallRejectedError";
-this.GECKO_CALL_ERROR_NUMBER_CHANGED         = "NumberChangedError";
-this.GECKO_CALL_ERROR_PRE_EMPTION            = "PreEmptionError";
-this.GECKO_CALL_ERROR_DEST_OUT_OF_ORDER      = "DestinationOutOfOrderError";
-this.GECKO_CALL_ERROR_INVALID_NUMBER_FORMAT  = "InvalidNumberFormatError";
-this.GECKO_CALL_ERROR_FACILITY_REJECTED      = "FacilityRejectedError";
-this.GECKO_CALL_ERROR_CONGESTION             = "CongestionError";
-this.GECKO_CALL_ERROR_NETWORK_OUT_OF_ORDER   = "NetworkOutOfOrderError";
-this.GECKO_CALL_ERROR_NETWORK_TEMP_FAILURE   = "NetworkTempFailureError";
-this.GECKO_CALL_ERROR_INCOMING_CALL_EXCEEDED = "IncomingCallExceededError";
-this.GECKO_CALL_ERROR_BARRED                 = "BarredError";
-this.GECKO_CALL_ERROR_FDN_BLOCKED            = "FDNBlockedError";
-this.GECKO_CALL_ERROR_SUBSCRIBER_UNKNOWN     = "SubscriberUnknownError";
-this.GECKO_CALL_ERROR_DEVICE_NOT_ACCEPTED    = "DeviceNotAcceptedError";
-this.GECKO_CALL_ERROR_UNSPECIFIED            = "UnspecifiedError";
+this.GECKO_CALL_ERROR_BAD_NUMBER              = "BadNumberError";
+this.GECKO_CALL_ERROR_NORMAL_CALL_CLEARING    = "NormalCallClearingError";
+this.GECKO_CALL_ERROR_BUSY                    = "BusyError";
+this.GECKO_CALL_ERROR_NO_USER_RESPONDING      = "NoUserRespondingError";
+this.GECKO_CALL_ERROR_USER_ALERTING           = "UserAlertingNoAnswerError";
+this.GECKO_CALL_ERROR_REJECTED                = "CallRejectedError";
+this.GECKO_CALL_ERROR_NUMBER_CHANGED          = "NumberChangedError";
+this.GECKO_CALL_ERROR_PRE_EMPTION             = "PreEmptionError";
+this.GECKO_CALL_ERROR_DEST_OUT_OF_ORDER       = "DestinationOutOfOrderError";
+this.GECKO_CALL_ERROR_INVALID_NUMBER_FORMAT   = "InvalidNumberFormatError";
+this.GECKO_CALL_ERROR_FACILITY_REJECTED       = "FacilityRejectedError";
+this.GECKO_CALL_ERROR_CONGESTION              = "CongestionError";
+this.GECKO_CALL_ERROR_NETWORK_OUT_OF_ORDER    = "NetworkOutOfOrderError";
+this.GECKO_CALL_ERROR_NETWORK_TEMP_FAILURE    = "NetworkTempFailureError";
+this.GECKO_CALL_ERROR_INCOMING_CALL_EXCEEDED  = "IncomingCallExceededError";
+this.GECKO_CALL_ERROR_BARRED                  = "BarredError";
+this.GECKO_CALL_ERROR_FDN_BLOCKED             = "FDNBlockedError";
+this.GECKO_CALL_ERROR_SUBSCRIBER_UNKNOWN      = "SubscriberUnknownError";
+this.GECKO_CALL_ERROR_DEVICE_NOT_ACCEPTED     = "DeviceNotAcceptedError";
+this.GECKO_CALL_ERROR_MODIFIED_TO_DIAL_FAILED = "ModifiedDialError";
+this.GECKO_CALL_ERROR_UNSPECIFIED             = "UnspecifiedError";
 
 this.RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR = {};
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_UNOBTAINABLE_NUMBER] = GECKO_CALL_ERROR_BAD_NUMBER;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_NORMAL]              = GECKO_CALL_ERROR_NORMAL_CALL_CLEARING;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_BUSY]                = GECKO_CALL_ERROR_BUSY;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_NO_USER_RESPONDING]  = GECKO_CALL_ERROR_NO_USER_RESPONDING;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_USER_ALERTING]       = GECKO_CALL_ERROR_USER_ALERTING;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CALL_REJECTED]       = GECKO_CALL_ERROR_REJECTED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_NUMBER_CHANGED]      = GECKO_CALL_ERROR_NUMBER_CHANGED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CALL_PRE_EMPTION]    = GECKO_CALL_ERROR_PRE_EMPTION;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_DEST_OUT_OF_ORDER]   = GECKO_CALL_ERROR_DEST_OUT_OF_ORDER;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_INVALID_FORMAT]      = GECKO_CALL_ERROR_INVALID_NUMBER_FORMAT;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_FACILITY_REJECTED]   = GECKO_CALL_ERROR_FACILITY_REJECTED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CONGESTION]          = GECKO_CALL_ERROR_CONGESTION;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_NETWORK_OUT_OF_ORDER]= GECKO_CALL_ERROR_NETWORK_OUT_OF_ORDER;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_NETWORK_TEMP_FAILURE]= GECKO_CALL_ERROR_NETWORK_TEMP_FAILURE;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_ACM_LIMIT_EXCEEDED]  = GECKO_CALL_ERROR_INCOMING_CALL_EXCEEDED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CALL_BARRED]         = GECKO_CALL_ERROR_BARRED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_FDN_BLOCKED]         = GECKO_CALL_ERROR_FDN_BLOCKED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_IMSI_UNKNOWN_IN_VLR] = GECKO_CALL_ERROR_SUBSCRIBER_UNKNOWN;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_IMEI_NOT_ACCEPTED]   = GECKO_CALL_ERROR_DEVICE_NOT_ACCEPTED;
-RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_ERROR_UNSPECIFIED]   = GECKO_CALL_ERROR_UNSPECIFIED;
+RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_UNOBTAINABLE_NUMBER]   = GECKO_CALL_ERROR_BAD_NUMBER;
+RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_NORMAL]                = GECKO_CALL_ERROR_NORMAL_CALL_CLEARING;
+RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_BUSY]                  = GECKO_CALL_ERROR_BUSY;
+RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_NO_USER_RESPONDING]    = GECKO_CALL_ERROR_NO_USER_RESPONDING;
+RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_USER_ALERTING]         = GECKO_CALL_ERROR_USER_ALERTING;
+RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CALL_REJECTED]         = GECKO_CALL_ERROR_REJECTED;
+RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_NUMBER_CHANGED]        = GECKO_CALL_ERROR_NUMBER_CHANGED;
+RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CALL_PRE_EMPTION]      = GECKO_CALL_ERROR_PRE_EMPTION;
+RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_DEST_OUT_OF_ORDER]     = GECKO_CALL_ERROR_DEST_OUT_OF_ORDER;
+RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_INVALID_FORMAT]        = GECKO_CALL_ERROR_INVALID_NUMBER_FORMAT;
+RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_FACILITY_REJECTED]     = GECKO_CALL_ERROR_FACILITY_REJECTED;
+RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CONGESTION]            = GECKO_CALL_ERROR_CONGESTION;
+RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_NETWORK_OUT_OF_ORDER]  = GECKO_CALL_ERROR_NETWORK_OUT_OF_ORDER;
+RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_NETWORK_TEMP_FAILURE]  = GECKO_CALL_ERROR_NETWORK_TEMP_FAILURE;
+RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_ACM_LIMIT_EXCEEDED]    = GECKO_CALL_ERROR_INCOMING_CALL_EXCEEDED;
+RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CALL_BARRED]           = GECKO_CALL_ERROR_BARRED;
+RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_FDN_BLOCKED]           = GECKO_CALL_ERROR_FDN_BLOCKED;
+RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_IMSI_UNKNOWN_IN_VLR]   = GECKO_CALL_ERROR_SUBSCRIBER_UNKNOWN;
+RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_IMEI_NOT_ACCEPTED]     = GECKO_CALL_ERROR_DEVICE_NOT_ACCEPTED;
+RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_DIAL_MODIFIED_TO_DIAL] = GECKO_CALL_ERROR_MODIFIED_TO_DIAL_FAILED;
+RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_ERROR_UNSPECIFIED]     = GECKO_CALL_ERROR_UNSPECIFIED;
 
 this.GECKO_DATACALL_ERROR_OPERATOR_BARRED               = "OperatorBarredError";
 this.GECKO_DATACALL_ERROR_INSUFFICIENT_RESOURCES        = "InsufficientResourcesError";
 this.GECKO_DATACALL_ERROR_MISSING_UKNOWN_APN            = "MissingUnknownAPNError";
 this.GECKO_DATACALL_ERROR_UNKNOWN_PDP_ADDRESS_TYPE      = "UnknownPDPAddressTypeError";
 this.GECKO_DATACALL_ERROR_USER_AUTHENTICATION           = "UserAuthenticationError";
 this.GECKO_DATACALL_ERROR_ACTIVATION_REJECT_GGSN        = "ActivationRejectGGSNError";
 this.GECKO_DATACALL_ERROR_ACTIVATION_REJECT_UNSPECIFIED = "ActivationRejectUnspecifiedError";
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -11254,17 +11254,17 @@ StkProactiveCmdHelperObject.prototype = 
     }
 
     let GsmPDUHelper = this.context.GsmPDUHelper;
     let text = {
       codingScheme: GsmPDUHelper.readHexOctet()
     };
 
     length--; // -1 for the codingScheme.
-    switch (text.codingScheme & 0x0f) {
+    switch (text.codingScheme & 0x0c) {
       case STK_TEXT_CODING_GSM_7BIT_PACKED:
         text.textString = GsmPDUHelper.readSeptetsToString(length * 8 / 7, 0, 0, 0);
         break;
       case STK_TEXT_CODING_GSM_8BIT:
         text.textString =
           this.context.ICCPDUHelper.read8BitUnpackedToString(length);
         break;
       case STK_TEXT_CODING_UCS2:
--- a/image/test/mochitest/mochitest.ini
+++ b/image/test/mochitest/mochitest.ini
@@ -61,30 +61,36 @@ support-files =
 [test_bug399925.html]
 # [test_bug435296.html]
 # disabled - See bug 578591
 [test_bug466586.html]
 [test_bug468160.html]
 # [test_bug478398.html]
 # disabled - See bug 579139
 [test_bug490949.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
 [test_bug496292.html]
 [test_bug497665.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
 [test_bug512435.html]
 [test_bug552605-1.html]
 [test_bug552605-2.html]
 [test_bug553982.html]
 [test_bug601470.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
 [test_bug614392.html]
 [test_bug657191.html]
 [test_bug671906.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
 [test_bug733553.html]
 [test_bug767779.html]
 [test_bug865919.html]
 [test_bug89419-1.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
 [test_bug89419-2.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
 [test_animation_operators.html]
 [test_drawDiscardedImage.html]
 skip-if = toolkit == "gonk" #Bug 997034 - canvas.toDataURL() often causes lost connection to device.
 [test_error_events.html]
 [test_short_gif_header.html]
 [test_image_buffer_limit.html]
 run-if = toolkit == "gonk" #Image buffer limit is only set for Firefox OS currently.
--- a/python/mozbuild/mozbuild/backend/templates/android_eclipse/project.properties
+++ b/python/mozbuild/mozbuild/backend/templates/android_eclipse/project.properties
@@ -4,11 +4,11 @@
 #
 # This file must be checked in Version Control Systems.
 #
 # To customize properties used by the Ant build system edit
 # "ant.properties", and override values to adapt the script to your
 # project structure.
 
 # Project target.
-target=@ANDROID_TARGET_SDK@
+target=android-@ANDROID_TARGET_SDK@
 @IDE_PROJECT_LIBRARY_SETTING@
 @IDE_PROJECT_LIBRARY_REFERENCES@
--- a/testing/mochitest/androidx86.json
+++ b/testing/mochitest/androidx86.json
@@ -1,113 +1,32 @@
 {
 "runtests": {},
 "excludetests": {
-  "content/base/test/test_ipc_messagemanager_blob.html": "x86 only bug 936226",
   "content/base/test/test_copypaste.xul": "bug 904183",
-  "content/html/content/test/forms/test_input_textarea_set_value_no_scroll.html": "x86 only",
-  "content/media/test/test_clone_media_element.html": "x86 only bug 914439",
-  "content/media/test/test_fastSeek.html": "x86 only bug 914439",
-  "content/media/test/test_media_selection.html": "x86 only bug 914439",
-  "content/media/test/test_bug495300.html": "x86 only bug 914439",
-  "content/media/test/test_new_audio.html": "x86 only bug 914439",
   "content/media/test/test_seeked.html": "x86 only bug 914439",
   "content/media/test/test_played.html": "bug 751539",
-  "content/media/test/test_playback_rate.html": "bug 845162",
-  "content/media/test/test_playback_rate_playpause.html": "x86 only bug 914439",
-  "content/media/test/test_loop.html": "x86 only bug 914439",
   "content/media/test/test_play_twice.html": "x86 only bug 914439",
-  "content/media/test/test_bug495145.html": "x86 only bug 914439",
-  "content/media/test/test_bug465498.html": "",
-  "content/media/test/test_play_events_2.html": "x86 only bug 914439",
-  "content/media/test/test_media_sniffer.html": "x86 only bug 914439",
-  "content/media/test/test_seek_out_of_range.html": "x86 only bug 914439",
-  "content/media/test/test_load_same_resource.html": "x86 only bug 914439",
-  "content/media/test/test_bug493187.html": "x86 only bug 914439",
-  "content/media/test/test_autoplay_contentEditable.html": "x86 only",
-  "content/media/test/test_audio2.html": "x86 only bug 914439",
-  "content/media/test/test_can_play_type_mpeg.html": "x86 only bug 914439",
-  "content/media/test/test_bug686942.html": "x86 only bug 914439",
-  "content/media/test/test_standalone.html": "x86 only bug 914439",
-  "content/media/test/test_bug448534.html": "x86 only bug 914439",
-  "content/media/test/test_video_to_canvas.html": "x86 only bug 914439",
-  "content/media/test/test_load_candidates.html": "x86 only bug 914439",
-  "content/media/test/test_streams_element_capture_createObjectURL.html": "x86 only bug 914439",
-  "content/media/test/test_progress.html": "x86 only bug 914439",
-  "content/media/test/test_seekable1.html": "timeout x86 only bug 914439",
-  "content/media/test/test_play_events.html": "x86 only bug 914439",
-  "content/media/test/test_reactivate.html": "x86 only bug 914439",
-  "content/media/test/test_referer.html": "x86 only",
-  "content/media/webaudio/test/test_audioBufferSourceNodeNeutered.html": "x86 only",
-  "content/media/test/test_load.html": "x86 only bug 914439",
-  "content/media/test/test_streams_element_capture.html": "x86 only bug 914439",
-  "content/media/test/test_replay_metadata.html": "x86 only bug 914439",
-  "content/media/test/test_unseekable.html": "x86 only",
-  "content/media/test/test_paused_after_ended.html": "x86 only bug 914439",
-  "content/media/test/test_timeupdate_small_files.html": "x86 only bug 914439",
-  "content/media/test/test_playback.html": "x86 only bug 914439",
-  "docshell/test/navigation/test_not-opener.html": "x86 only",
-  "dom/apps/tests/test_packaged_app_update.html": "x86 only",
-  "dom/apps/tests/test_packaged_app_install.html": "x86 only",
-  "dom/browser-element/mochitest/test_browserElement_oop_NextPaint.html": "x86 only bug 936226",
-  "dom/browser-element/mochitest/test_browserElement_inproc_GetScreenshot.html": "x86 only",
   "dom/browser-element/mochitest/test_browserElement_NoWhitelist.html": "x86 only bug 936226",
   "dom/browser-element/mochitest/test_browserElement_oop_SecurityChange.html": "TIMED_OUT, bug 766586",
   "dom/canvas/test/webgl-conformance": "bug 865443 - separate suite -- mochitest-gl",
-  "dom/canvas/test/test_2d.composite.canvas.luminosity.html": "x86 only bug 913662",
-  "dom/canvas/test/test_2d.composite.canvas.source-in.html": "x86 only bug 913662",
   "dom/canvas/test/test_2d.composite.uncovered.image.destination-atop.html": "x86 only bug 913662",
-  "dom/canvas/test/test_2d.composite.image.source-in.html": "x86 only bug 913662",
-  "dom/canvas/test/test_2d.composite.canvas.multiply.html": "x86 only bug 913662",
-  "dom/canvas/test/test_2d.composite.canvas.lighten.html": "x86 only bug 913662",
-  "dom/canvas/test/test_2d.composite.canvas.color-dodge.html": "x86 only bug 913662",
-  "dom/canvas/test/test_2d.composite.canvas.destination-in.html": "x86 only bug 913662",
-  "dom/canvas/test/test_2d.composite.canvas.screen.html": "x86 only bug 913662",
   "dom/canvas/test/test_2d.composite.image.source-out.html": "x86 only bug 913662",
-  "dom/canvas/test/test_2d.composite.canvas.exclusion.html": "x86 only bug 913662",
-  "dom/canvas/test/test_2d.composite.canvas.source-out.html": "x86 only bug 913662",
-  "dom/canvas/test/test_2d.composite.canvas.soft-light.html": "x86 only bug 913662",
-  "dom/canvas/test/test_2d.composite.canvas.destination-atop.html": "x86 only bug 913662",
   "dom/canvas/test/test_canvas.html": "x86 only bug 913662",
-  "dom/canvas/test/test_2d.composite.canvas.overlay.html": "x86 only bug 913662",
-  "dom/canvas/test/test_2d.composite.canvas.darken.html": "x86 only bug 913662",
-  "dom/canvas/test/test_2d.composite.uncovered.image.source-in.html": "x86 only bug 913662",
-  "dom/canvas/test/test_2d.composite.canvas.saturation.html": "x86 only bug 913662",
-  "dom/canvas/test/test_2d.composite.image.destination-atop.html": "x86 only bug 913662",
-  "dom/canvas/test/test_2d.composite.uncovered.image.source-out.html": "x86 only bug 913662",
-  "dom/canvas/test/test_2d.composite.canvas.color.html": "x86 only bug 913662",
-  "dom/canvas/test/test_2d.composite.image.destination-in.html": "x86 only bug 913662",
-  "dom/canvas/test/test_2d.composite.canvas.hue.html": "x86 only bug 913662",
-  "dom/canvas/test/test_2d.composite.canvas.difference.html": "x86 only bug 913662",
-  "dom/canvas/test/test_2d.composite.canvas.color-burn.html": "x86 only bug 913662",
-  "dom/canvas/test/test_2d.composite.uncovered.image.destination-in.html": "x86 only bug 913662",
-  "dom/canvas/test/test_2d.composite.canvas.hard-light.html": "x86 only bug 913662",
   "dom/contacts/tests/test_contacts_getall.html": "x86 only",
-  "dom/datastore/tests/test_oop.html": "x86 only bug 936226",
-  "dom/datastore/tests/test_sync.html": "x86 only bug 936226",
-  "dom/datastore/tests/test_readonly.html": "x86 only bug 936226",
   "dom/devicestorage": "bug 781789 & bug 782275",
   "dom/imptests/editing/selecttest/test_addRange.html": "bug 775227",
   "dom/imptests/editing/conformancetest/test_runtest.html": "",
   "dom/imptests/webapps/WebStorage/tests/submissions/Infraware/test_storage_local_key.html": "bug 775227",
   "dom/imptests/html/webgl": "WebGL",
   "dom/inputmethod": "Not supported on Android",
   "dom/tests/mochitest/geolocation/test_timeoutWatch.html": "TIMED_OUT",
   "editor/libeditor/tests/test_bug569988.html": "TIMED_OUT",
   "editor/libeditor/tests/test_texteditor_keyevent_handling.html": "",
-  "Harness_sanity/test_sanityWindowSnapshot.html": "x86 only",
-  "image/test/mochitest/test_bug671906.html": "x86 only",
-  "image/test/mochitest/test_bug89419-2.html": "x86 only",
-  "image/test/mochitest/test_bug490949.html": "x86 only",
-  "image/test/mochitest/test_bug497665.html": "x86 only",
-  "image/test/mochitest/test_bug601470.html": "x86 only",
-  "image/test/mochitest/test_bug89419-1.html": "x86 only",
   "layout/generic": "CRASH_DUMP, RANDOM, ONLY IN CHUNK 10",
-  "MochiKit-1.4.2/tests/test_MochiKit-Async.html": "x86 only",
   "robocop": "TIMED_OUT",
   "toolkit/components/satchel/test/test_form_autocomplete.html": "TIMED_OUT",
-  "toolkit/components/alerts/test/test_alerts_noobserve.html": "x86 only",
   "toolkit/components/places/tests/test_bug_411966.html": "RANDOM",
   "toolkit/components/passwordmgr/test/test_privbrowsing_perwindowpb.html": "",
   "toolkit/content/tests/widgets/test_menubar.xul": "W/SharedBufferStack(21799",
   "toolkit/content/tests/widgets/test_contextmenu_nested.xul": ""
   }
 }
--- a/testing/mochitest/tests/Harness_sanity/mochitest.ini
+++ b/testing/mochitest/tests/Harness_sanity/mochitest.ini
@@ -2,16 +2,17 @@
 skip-if = buildapp == 'mulet' || buildapp == 'b2g'
 [test_TestsRunningAfterSimpleTestFinish.html]
 skip-if = true #depends on fix for bug 1048446
 [test_sanity.html]
 [test_sanityException.html]
 [test_sanityException2.html]
 [test_sanityParams.html]
 [test_sanityWindowSnapshot.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
 [test_SpecialPowersExtension.html]
 [test_SpecialPowersExtension2.html]
 support-files = file_SpecialPowersFrame1.html
 [test_SpecialPowersPushPermissions.html]
 [test_SpecialPowersPushPrefEnv.html]
 [test_SimpletestGetTestFileURL.html]
 [test_SpecialPowersLoadChromeScript.html]
 support-files = SpecialPowersLoadChromeScript.js
--- a/testing/mochitest/tests/MochiKit-1.4.2/tests/mochitest.ini
+++ b/testing/mochitest/tests/MochiKit-1.4.2/tests/mochitest.ini
@@ -8,16 +8,17 @@ support-files =
   test_DragAndDrop.js
   test_Format.js
   test_Iter.js
   test_Logging.js
   test_MochiKit-Async.json
   test_Signal.js
 
 [test_MochiKit-Async.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
 [test_MochiKit-Base.html]
 [test_MochiKit-Color.html]
 [test_MochiKit-DateTime.html]
 [test_MochiKit-DOM.html]
 [test_MochiKit-DOM-Safari.html]
 [test_MochiKit-DragAndDrop.html]
 [test_MochiKit-Format.html]
 [test_MochiKit-Iter.html]
--- a/toolkit/components/alerts/test/mochitest.ini
+++ b/toolkit/components/alerts/test/mochitest.ini
@@ -1,9 +1,10 @@
 [DEFAULT]
 skip-if = buildapp == 'b2g' || e10s
 
 # Synchronous tests like test_alerts.html must come before
 # asynchronous tests like test_alerts_noobserve.html!
 [test_alerts.html]
 skip-if = toolkit == 'android'
 [test_alerts_noobserve.html]
+skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
 [test_multiple_alerts.html]
--- a/toolkit/components/places/History.jsm
+++ b/toolkit/components/places/History.jsm
@@ -9,21 +9,21 @@
  *
  *
  * The API makes use of `PageInfo` and `VisitInfo` objects, defined as follows.
  *
  * A `PageInfo` object is any object that contains A SUBSET of the
  * following properties:
  * - guid: (string)
  *     The globally unique id of the page.
- * - uri: (URL)
+ * - url: (URL)
  *     or (nsIURI)
  *     or (string)
  *     The full URI of the page. Note that `PageInfo` values passed as
- *     argument may hold `nsIURI` or `string` values for property `uri`,
+ *     argument may hold `nsIURI` or `string` values for property `url`,
  *     but `PageInfo` objects returned by this module always hold `URL`
  *     values.
  * - title: (string)
  *     The title associated with the page, if any.
  * - frecency: (number)
  *     The frecency of the page, if any.
  *     See https://developer.mozilla.org/en-US/docs/Mozilla/Tech/Places/Frecency_algorithm
  *     Note that this property may not be used to change the actualy frecency
@@ -70,17 +70,43 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
                                   "resource://gre/modules/NetUtil.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Promise",
                                   "resource://gre/modules/Promise.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Task",
                                   "resource://gre/modules/Task.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Sqlite",
                                   "resource://gre/modules/Sqlite.jsm");
+XPCOMUtils.defineLazyServiceGetter(this, "gNotifier",
+                                   "@mozilla.org/browser/nav-history-service;1",
+                                   Ci.nsPIPlacesHistoryListenersNotifier);
+XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
+                                  "resource://gre/modules/PlacesUtils.jsm");
+Cu.importGlobalProperties(["URL"]);
 
+/**
+ * Shared connection
+ */
+XPCOMUtils.defineLazyGetter(this, "DBConnPromised",
+  () => new Promise((resolve) => {
+    Sqlite.wrapStorageConnection({ connection: PlacesUtils.history.DBConnection } )
+          .then(db => {
+      try {
+        Sqlite.shutdown.addBlocker("Places History.jsm: Closing database wrapper",
+                                   () => db.close());
+      } catch (ex) {
+        // It's too late to block shutdown of Sqlite, so close the connection
+        // immediately.
+        db.close();
+        throw ex;
+      }
+      resolve(db);
+    });
+  })
+);
 
 this.History = Object.freeze({
   /**
    * Fetch the available information for one page.
    *
    * @param guidOrURI: (URL or nsIURI)
    *      The full URI of the page.
    *            or (string)
@@ -106,17 +132,17 @@ this.History = Object.freeze({
    * Any change may be observed through nsINavHistoryObserver
    *
    * @note This function recomputes the frecency of the page automatically,
    * regardless of the value of property `frecency` passed as argument.
    * @note If there is no entry for the page, the entry is created.
    *
    * @param infos: (PageInfo)
    *      Information on a page. This `PageInfo` MUST contain
-   *        - either a property `guid` or a property `uri`, as specified
+   *        - either a property `guid` or a property `url`, as specified
    *          by the definition of `PageInfo`;
    *        - a property `visits`, as specified by the definition of
    *          `PageInfo`, which MUST contain at least one visit.
    *      If a property `title` is provided, the title of the page
    *      is updated.
    *      If the `visitDate` of a visit is not provided, it defaults
    *      to now.
    *            or (Array<PageInfo>)
@@ -130,24 +156,24 @@ this.History = Object.freeze({
    * @return (Promise)
    *      A promise resolved once the operation is complete, including
    *      all calls to `onResult`.
    * @resolves (bool)
    *      `true` if at least one page entry was created, `false` otherwise
    *       (i.e. if page entries were updated but not created).
    *
    * @throws (Error)
-   *      If the `uri` specified was for a protocol that should not be
+   *      If the `url` specified was for a protocol that should not be
    *      stored (e.g. "chrome:", "mailbox:", "about:", "imap:", "news:",
    *      "moz-anno:", "view-source:", "resource:", "data:", "wyciwyg:",
    *      "javascript:", "blob:").
    * @throws (Error)
    *      If `infos` has an unexpected type.
    * @throws (Error)
-   *      If a `PageInfo` has neither `guid` nor `uri`,
+   *      If a `PageInfo` has neither `guid` nor `url`.
    * @throws (Error)
    *      If a `guid` property provided is not a valid GUID.
    * @throws (Error)
    *      If a `PageInfo` does not have a `visits` property or if the
    *      value of `visits` is ill-typed or is an empty array.
    * @throws (Error)
    *      If an element of `visits` has an invalid `date`.
    * @throws (Error)
@@ -172,22 +198,52 @@ this.History = Object.freeze({
    *      An array of the above, to batch requests.
    * @param onResult: (function(PageInfo))
    *      A callback invoked for each page found.
    *
    * @return (Promise)
    *      A promise resoled once the operation is complete.
    * @resolve (bool)
    *      `true` if at least one page was removed, `false` otherwise.
-   * @throws (Error)
+   * @throws (TypeError)
    *       If `pages` has an unexpected type or if a string provided
-   *       is neither a valid GUID nor a valid URI.
+   *       is neither a valid GUID nor a valid URI or if `pages`
+   *       is an empty array.
    */
-  remove: function (pages, onResult) {
-    throw new Error("Method not implemented");
+  remove: function (pages, onResult = null) {
+    // Normalize and type-check arguments
+    if (Array.isArray(pages)) {
+      if (pages.length == 0) {
+        throw new TypeError("Expected at least one page");
+      }
+    } else {
+      pages = [pages];
+    }
+
+    let guids = [];
+    let urls = [];
+    for (let page of pages) {
+      // Normalize to URL or GUID, or throw if `page` cannot
+      // be normalized.
+      let normalized = normalizeToURLOrGUID(page);
+      if (typeof normalized === "string") {
+        guids.push(normalized);
+      } else {
+        urls.push(normalized.href);
+      }
+    }
+    // At this stage, we know that either `guids` is not-empty
+    // or `urls` is not-empty.
+
+    if (onResult && typeof onResult != "function") {
+      throw new TypeError("Invalid function: " + onResult);
+    }
+
+    // Now perform queries
+    return remove({guids: guids, urls: urls}, onResult);
   },
 
   /**
    * Determine if a page has been visited.
    *
    * @param pages: (URL or nsIURI)
    *      The full URI of the page.
    *            or (string)
@@ -252,8 +308,159 @@ this.History = Object.freeze({
   TRANSITION_DOWNLOAD: Ci.nsINavHistoryService.TRANSITION_REDIRECT_DOWNLOAD,
 
   /**
    * The user followed a link and got a visit in a frame.
    */
   TRANSITION_FRAMED_LINK: Ci.nsINavHistoryService.TRANSITION_FRAMED_LINK,
 });
 
+
+/**
+ * Normalize a key to either a string (if it is a valid GUID) or an
+ * instance of `URL` (if it is a `URL`, `nsIURI`, or a string
+ * representing a valid url).
+ *
+ * @throws (TypeError)
+ *         If the key is neither a valid guid nor a valid url.
+ */
+function normalizeToURLOrGUID(key) {
+  if (typeof key === "string") {
+    // A string may be a URL or a guid
+    if (/^[a-zA-Z0-9\-_]{12}$/.test(key)) {
+      return key;
+    }
+    return new URL(key);
+  }
+  if (key instanceof URL) {
+    return key;
+  }
+  if (key instanceof Ci.nsIURI) {
+    return new URL(key.spec);
+  }
+  throw new TypeError("Invalid url or guid: " + key);
+}
+
+/**
+ * Convert a list of strings or numbers to its SQL
+ * representation as a string.
+ */
+function sqlList(list) {
+  return list.map(JSON.stringify).join();
+}
+
+/**
+ * Invalidate and recompute the frecency of a list of pages,
+ * informing frecency observers.
+ *
+ * @param db: (Sqlite connection)
+ * @param idList: (Array)
+ *      The `moz_places` identifiers for the places to invalidate.
+ * @return (Promise)
+ */
+let invalidateFrecencies = Task.async(function*(db, idList) {
+  if (idList.length == 0) {
+    return;
+  }
+  let ids = sqlList(idList);
+  yield db.execute(
+    `UPDATE moz_places
+     SET frecency = NOTIFY_FRECENCY(
+       CALCULATE_FRECENCY(id), url, guid, hidden, last_visit_date
+     ) WHERE id in (${ ids })`
+  );
+  yield db.execute(
+    `UPDATE moz_places
+     SET hidden = 0
+     WHERE id in (${ ids })
+     AND frecency <> 0`
+  );
+});
+
+
+// Inner implementation of History.remove.
+let remove = Task.async(function*({guids, urls}, onResult = null) {
+  let db = yield DBConnPromised;
+
+  // 1. Find out what needs to be removed
+  let query =
+    `SELECT id, url, guid, foreign_count, title, frecency FROM moz_places
+     WHERE guid IN (${ sqlList(guids) })
+        OR url  IN (${ sqlList(urls)  })
+     `;
+
+  let pages = [];
+  let hasPagesToKeep = false;
+  let hasPagesToRemove = false;
+  yield db.execute(query, null, Task.async(function*(row) {
+    let toRemove = row.getResultByName("foreign_count") == 0;
+    if (toRemove) {
+      hasPagesToRemove = true;
+    } else {
+      hasPagesToKeep = true;
+    }
+    let id = row.getResultByName("id");
+    let guid = row.getResultByName("guid");
+    let url = row.getResultByName("url");
+    let page = {
+      id: id,
+      guid: guid,
+      toRemove: toRemove,
+      uri: NetUtil.newURI(url),
+    };
+    pages.push(page);
+    if (onResult) {
+      let pageInfo = {
+        guid: guid,
+        title: row.getResultByName("title"),
+        frecency: row.getResultByName("frecency"),
+        url: new URL(url)
+      };
+      try {
+        yield onResult(pageInfo);
+      } catch (ex) {
+        // Errors should be reported but should not stop `remove`.
+        Promise.reject(ex);
+      }
+    }
+  }));
+
+  if (pages.length == 0) {
+    // Nothing to do
+    return false;
+  }
+
+  yield db.executeTransaction(function*() {
+    // 2. Remove all visits to these pages.
+    yield db.execute(`DELETE FROM moz_historyvisits
+                      WHERE place_id IN (${ sqlList([p.id for (p of pages)]) })
+                     `);
+
+     // 3. For pages that should not be removed, invalidate frecencies.
+    if (hasPagesToKeep) {
+      yield invalidateFrecencies(db, [p.id for (p of pages) if (!p.toRemove)]);
+    }
+
+    // 4. For pages that should be removed, remove page.
+    if (hasPagesToRemove) {
+      let ids = [p.id for (p of pages) if (p.toRemove)];
+      yield db.execute(`DELETE FROM moz_places
+                        WHERE id IN (${ sqlList(ids) })
+                       `);
+    }
+
+    // 5. Notify observers.
+    for (let {guid, uri, toRemove} of pages) {
+      gNotifier.notifyOnPageExpired(
+        uri, // uri
+        0, // visitTime - There are no more visits
+        toRemove, // wholeEntry
+        guid, // guid
+        Ci.nsINavHistoryObserver.REASON_DELETED, // reason
+        -1 // transition
+      );
+    }
+  });
+
+  PlacesUtils.history.clearEmbedVisits();
+
+  return hasPagesToRemove;
+});
--- a/toolkit/components/places/nsINavHistoryService.idl
+++ b/toolkit/components/places/nsINavHistoryService.idl
@@ -1171,17 +1171,17 @@ interface nsINavHistoryQueryOptions : ns
   attribute boolean asyncEnabled;
 
   /**
    * Creates a new options item with the same parameters of this one.
    */
   nsINavHistoryQueryOptions clone();
 };
 
-[scriptable, uuid(4b6963bf-763a-4f39-9fec-25670d354dd9)]
+[scriptable, uuid(47f7b08b-71e0-492e-a2be-9a9fbfc75250)]
 interface nsINavHistoryService : nsISupports
 {
   /**
    * System Notifications:
    *
    * places-init-complete - Sent once the History service is completely
    *                        initialized successfully.
    * places-database-locked - Sent if initialization of the History service
@@ -1386,16 +1386,21 @@ interface nsINavHistoryService : nsISupp
   void runInBatchMode(in nsINavHistoryBatchCallback aCallback,
                       in nsISupports aClosure);
 
   /** 
    * True if history is disabled. currently, 
    * history is disabled if the places.history.enabled pref is false.
    */
   readonly attribute boolean historyDisabled;
+
+  /**
+   * Clear all TRANSITION_EMBED visits.
+   */
+  void clearEmbedVisits();
 };
 
 /**
  * @see runInBatchMode of nsINavHistoryService/nsINavBookmarksService
  */
 [scriptable, uuid(5143f2bb-be0a-4faf-9acb-b0ed3f82952c)]
 interface nsINavHistoryBatchCallback : nsISupports {
   void runBatched(in nsISupports aUserData);
--- a/toolkit/components/places/nsNavHistory.cpp
+++ b/toolkit/components/places/nsNavHistory.cpp
@@ -3752,16 +3752,22 @@ nsNavHistory::hasEmbedVisit(nsIURI* aURI
 
 void
 nsNavHistory::clearEmbedVisits() {
   NS_ASSERTION(NS_IsMainThread(), "This can only be called on the main thread");
 
   mEmbedVisits.Clear();
 }
 
+NS_IMETHODIMP
+nsNavHistory::ClearEmbedVisits() {
+  clearEmbedVisits();
+  return NS_OK;
+}
+
 // nsNavHistory::CheckIsRecentEvent
 //
 //    Sees if this URL happened "recently."
 //
 //    It is always removed from our recent list no matter what. It only counts
 //    as "recent" if the event happened more recently than our event
 //    threshold ago.
 
--- a/toolkit/components/places/tests/moz.build
+++ b/toolkit/components/places/tests/moz.build
@@ -11,16 +11,17 @@ XPCSHELL_TESTS_MANIFESTS += [
     'bookmarks/xpcshell.ini',
     'expiration/xpcshell.ini',
     'favicons/xpcshell.ini',
     'inline/xpcshell.ini',
     'migration/xpcshell.ini',
     'network/xpcshell.ini',
     'queries/xpcshell.ini',
     'unifiedcomplete/xpcshell.ini',
+    'unit/history/xpcshell.ini',
     'unit/xpcshell.ini',
     'xpcshell.ini',
 ]
 
 BROWSER_CHROME_MANIFESTS += ['browser/browser.ini']
 MOCHITEST_CHROME_MANIFESTS += [
     'chrome.ini',
     'chrome/chrome.ini',
new file mode 100644
--- /dev/null
+++ b/toolkit/components/places/tests/unit/history/head_history.js
@@ -0,0 +1,19 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const Ci = Components.interfaces;
+const Cc = Components.classes;
+const Cr = Components.results;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/Services.jsm");
+
+// Import common head.
+let (commonFile = do_get_file("../../head_common.js", false)) {
+  let uri = Services.io.newFileURI(commonFile);
+  Services.scriptloader.loadSubScript(uri.spec, this);
+};
+
new file mode 100644
--- /dev/null
+++ b/toolkit/components/places/tests/unit/history/test_remove.js
@@ -0,0 +1,342 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Tests for `History.remove`, as implemented in History.jsm
+
+"use strict";
+
+Cu.importGlobalProperties(["URL"]);
+
+
+// Test removing a single page
+add_task(function* test_remove_single() {
+  let WITNESS_URI = NetUtil.newURI("http://mozilla.com/test_browserhistory/test_remove/" + Math.random());
+  yield promiseAddVisits(WITNESS_URI);
+  Assert.ok(page_in_database(WITNESS_URI));
+
+  let remover = Task.async(function*(name, filter, options) {
+    do_print(name);
+    do_print(JSON.stringify(options));
+    do_print("Setting up visit");
+
+    let uri = NetUtil.newURI("http://mozilla.com/test_browserhistory/test_remove/" + Math.random());
+    let title = "Visit " + Math.random();
+    yield promiseAddVisits({uri: uri, title: title});
+    Assert.ok(visits_in_database(uri), "History entry created");
+
+    let removeArg = yield filter(uri);
+
+    if (options.addBookmark) {
+      PlacesUtils.bookmarks.insertBookmark(
+        PlacesUtils.unfiledBookmarksFolderId,
+        uri,
+        PlacesUtils.bookmarks.DEFAULT_INDEX,
+        "test bookmark");
+    }
+
+    let shouldRemove = !options.addBookmark;
+    let observer;
+    let promiseObserved = new Promise((resolve, reject) => {
+      observer = {
+        onBeginUpdateBatch: function() {},
+        onEndUpdateBatch: function() {},
+        onVisit: function(uri) {
+          reject(new Error("Unexpected call to onVisit " + uri.spec));
+        },
+        onTitleChanged: function(uri) {
+          reject(new Error("Unexpected call to onTitleChanged " + uri.spec));
+        },
+        onClearHistory: function() {
+          reject("Unexpected call to onClearHistory");
+        },
+        onPageChanged: function(uri) {
+          reject(new Error("Unexpected call to onPageChanged " + uri.spec));
+        },
+        onFrecencyChanged: function(aURI) {
+          try {
+            Assert.ok(!shouldRemove, "Observing onFrecencyChanged");
+            Assert.equal(aURI.spec, uri.spec, "Observing effect on the right uri");
+          } finally {
+            resolve();
+          }
+        },
+        onManyFrecenciesChanged: function() {
+          try {
+            Assert.ok(!shouldRemove, "Observing onManyFrecenciesChanged");
+          } finally {
+            resolve();
+          }
+        },
+        onDeleteURI: function(aURI) {
+          try {
+            Assert.ok(shouldRemove, "Observing onDeleteURI");
+            Assert.equal(aURI.spec, uri.spec, "Observing effect on the right uri");
+          } finally {
+            resolve();
+          }
+        },
+        onDeleteVisits: function(aURI) {
+          Assert.equal(aURI.spec, uri.spec, "Observing onDeleteVisits on the right uri");
+        }
+      };
+    });
+    PlacesUtils.history.addObserver(observer, false);
+
+    do_print("Performing removal");
+    let removed = false;
+    if (options.useCallback) {
+      let onRowCalled = false;
+      removed = yield PlacesUtils.history.remove(removeArg, page => {
+        Assert.equal(onRowCalled, false, "Callback has not been called yet");
+        onRowCalled = true;
+        Assert.equal(page.url.href, uri.spec, "Callback provides the correct url");
+        Assert.equal(page.guid, do_get_guid_for_uri(uri), "Callback provides the correct guid");
+        Assert.equal(page.title, title, "Callback provides the correct title");
+        Assert.equal(page.frecency, frecencyForUrl(uri), "Callback provides the correct frecency");
+      });
+      Assert.ok(onRowCalled, "Callback has been called");
+    } else {
+      removed = yield PlacesUtils.history.remove(removeArg);
+    }
+
+    yield promiseObserved;
+    PlacesUtils.history.removeObserver(observer);
+
+    Assert.equal(visits_in_database(uri), 0, "History entry has disappeared");
+    Assert.notEqual(visits_in_database(WITNESS_URI), 0, "Witness URI still has visits");
+    Assert.notEqual(page_in_database(WITNESS_URI), 0, "Witness URI is still here");
+    if (shouldRemove) {
+      Assert.ok(removed, "Something was removed");
+      Assert.equal(page_in_database(uri), 0, "Page has disappeared");
+    } else {
+      Assert.ok(!removed, "The page was not removed, as there was a bookmark");
+      Assert.notEqual(page_in_database(uri), 0, "The page is still present");
+    }
+  });
+
+  try {
+    for (let useCallback of [false, true]) {
+      for (let addBookmark of [false, true]) {
+        let options = { useCallback: useCallback, addBookmark: addBookmark };
+        yield remover("Testing History.remove() with a single URI", x => x, options);
+        yield remover("Testing History.remove() with a single string url", x => x.spec, options);
+        yield remover("Testing History.remove() with a single string guid", x => do_get_guid_for_uri(x), options);
+        yield remover("Testing History.remove() with a single URI in an array", x => [x], options);
+        yield remover("Testing History.remove() with a single string url in an array", x => [x.spec], options);
+        yield remover("Testing History.remove() with a single string guid in an array", x => [do_get_guid_for_uri(x)], options);
+      }
+    }
+  } finally {
+    yield promiseClearHistory();
+  }
+  return;
+});
+
+// Test removing a list of pages
+add_task(function* test_remove_many() {
+  const SIZE = 10;
+
+  do_print("Adding a witness page");
+  let WITNESS_URI = NetUtil.newURI("http://mozilla.com/test_browserhistory/test_remove/" + Math.random());;
+  yield promiseAddVisits(WITNESS_URI);
+  Assert.ok(page_in_database(WITNESS_URI), "Witness page added");
+
+  do_print("Generating samples");
+  let pages = [];
+  for (let i = 0; i < SIZE; ++i) {
+    let uri = NetUtil.newURI("http://mozilla.com/test_browserhistory/test_remove?sample=" + i + "&salt=" + Math.random());
+    let title = "Visit " + i + ", " + Math.random();
+    let hasBookmark = i % 3 == 0;
+    let resolve;
+    let page = {
+      uri: uri,
+      title: title,
+      hasBookmark: hasBookmark,
+      // `true` once `onResult` has been called for this page
+      onResultCalled: false,
+      // `true` once `onDeleteVisits` has been called for this page
+      onDeleteVisitsCalled: false,
+      // `true` once `onFrecencyChangedCalled` has been called for this page
+      onFrecencyChangedCalled: false,
+      // `true` once `onDeleteURI` has been called for this page
+      onDeleteURICalled: false,
+    };
+    do_print("Pushing: " + uri.spec);
+    pages.push(page);
+
+    yield promiseAddVisits(page);
+    page.guid = do_get_guid_for_uri(uri);
+    if (hasBookmark) {
+      PlacesUtils.bookmarks.insertBookmark(
+        PlacesUtils.unfiledBookmarksFolderId,
+        uri,
+        PlacesUtils.bookmarks.DEFAULT_INDEX,
+        "test bookmark " + i);
+    }
+    Assert.ok(page_in_database(uri), "Page added");
+  }
+
+  do_print("Mixing key types and introducing dangling keys");
+  let keys = [];
+  for (let i = 0; i < SIZE; ++i) {
+    if (i % 4 == 0) {
+      keys.push(pages[i].uri);
+      keys.push(NetUtil.newURI("http://example.org/dangling/nsIURI/" + i));
+    } else if (i % 4 == 1) {
+      keys.push(new URL(pages[i].uri.spec));
+      keys.push(new URL("http://example.org/dangling/URL/" + i));
+    } else if (i % 4 == 2) {
+      keys.push(pages[i].uri.spec);
+      keys.push("http://example.org/dangling/stringuri/" + i);
+    } else {
+      keys.push(pages[i].guid);
+      keys.push(("guid_" + i + "_01234567890").substr(0, 12));
+    }
+  }
+
+  let observer = {
+    onBeginUpdateBatch: function() {},
+    onEndUpdateBatch: function() {},
+    onVisit: function(aURI) {
+      Assert.ok(false, "Unexpected call to onVisit " + aURI.spec);
+    },
+    onTitleChanged: function(aURI) {
+      Assert.ok(false, "Unexpected call to onTitleChanged " + aURI.spec);
+    },
+    onClearHistory: function() {
+      Assert.ok(false, "Unexpected call to onClearHistory");
+    },
+    onPageChanged: function(aURI) {
+      Assert.ok(false, "Unexpected call to onPageChanged " + aURI.spec);
+    },
+    onFrecencyChanged: function(aURI) {
+      let origin = pages.find(x =>  x.uri.spec == aURI.spec);
+      Assert.ok(origin);
+      Assert.ok(origin.hasBookmark, "Observing onFrecencyChanged on a page with a bookmark");
+      origin.onFrecencyChangedCalled = true;
+      // We do not make sure that `origin.onFrecencyChangedCalled` is `false`, as 
+    },
+    onManyFrecenciesChanged: function() {
+      Assert.ok(false, "Observing onManyFrecenciesChanges, this is most likely correct but not covered by this test");
+    },
+    onDeleteURI: function(aURI) {
+      let origin = pages.find(x => x.uri.spec == aURI.spec);
+      Assert.ok(origin);
+      Assert.ok(!origin.hasBookmark, "Observing onDeleteURI on a page without a bookmark");
+      Assert.ok(!origin.onDeleteURICalled, "Observing onDeleteURI for the first time");
+      origin.onDeleteURICalled = true;
+    },
+    onDeleteVisits: function(aURI) {
+      let origin = pages.find(x => x.uri.spec == aURI.spec);
+      Assert.ok(origin);
+      Assert.ok(!origin.onDeleteVisitsCalled, "Observing onDeleteVisits for the first time");
+      origin.onDeleteVisitsCalled = true;
+    }
+  };
+  PlacesUtils.history.addObserver(observer, false);
+
+  do_print("Removing the pages and checking the callbacks");
+  let removed = yield PlacesUtils.history.remove(keys, page => {
+    let origin = pages.find(candidate => candidate.uri.spec == page.url.href);
+
+    Assert.ok(origin, "onResult has a valid page");
+    Assert.ok(!origin.onResultCalled, "onResult has not seen this page yet");
+    origin.onResultCalled = true;
+    Assert.equal(page.guid, origin.guid, "onResult has the right guid");
+    Assert.equal(page.title, origin.title, "onResult has the right title");
+  });
+  Assert.ok(removed, "Something was removed");
+
+  PlacesUtils.history.removeObserver(observer);
+
+  do_print("Checking out results");
+  // By now the observers should have been called.
+  for (let i = 0; i < pages.length; ++i) {
+    let page = pages[i];
+    do_print("Page: " + i);
+    Assert.ok(page.onResultCalled, "We have reached the page from the callback");
+    Assert.ok(visits_in_database(page.uri) == 0, "History entry has disappeared");
+    Assert.equal(page_in_database(page.uri) != 0, page.hasBookmark, "Page is present only if it also has bookmarks");
+    Assert.equal(page.onFrecencyChangedCalled, page.onDeleteVisitsCalled, "onDeleteVisits was called iff onFrecencyChanged was called");
+    Assert.ok(page.onFrecencyChangedCalled ^ page.onDeleteURICalled, "Either onFrecencyChanged or onDeleteURI was called");
+  }
+
+  Assert.notEqual(visits_in_database(WITNESS_URI), 0, "Witness URI still has visits");
+  Assert.notEqual(page_in_database(WITNESS_URI), 0, "Witness URI is still here");
+
+  do_print("Cleaning up");
+  yield promiseClearHistory();
+
+});
+
+// Test the various error cases
+add_task(function* test_error_cases() {
+  Assert.throws(
+    () =>  PlacesUtils.history.remove(),
+    /TypeError: Invalid url/,
+    "History.remove with no argument should throw a TypeError"
+  );
+  Assert.throws(
+    () =>  PlacesUtils.history.remove(null),
+    /TypeError: Invalid url/,
+    "History.remove with `null` should throw a TypeError"
+  );
+  Assert.throws(
+    () =>  PlacesUtils.history.remove(undefined),
+    /TypeError: Invalid url/,
+    "History.remove with `undefined` should throw a TypeError"
+  );
+  Assert.throws(
+    () => PlacesUtils.history.remove("not a guid, obviously"),
+    /TypeError: .* is not a valid URL/,
+    "History.remove with an ill-formed guid/url argument should throw a TypeError"
+  );
+  Assert.throws(
+    () => PlacesUtils.history.remove({"not the kind of object we know how to handle": true}),
+    /TypeError: Invalid url/,
+    "History.remove with an unexpected object should throw a TypeError"
+  );
+  Assert.throws(
+    () => PlacesUtils.history.remove([]),
+    /TypeError: Expected at least one page/,
+    "History.remove with an empty array should throw a TypeError"
+  );
+  Assert.throws(
+    () => PlacesUtils.history.remove([null]),
+    /TypeError: Invalid url or guid/,
+    "History.remove with an array containing null should throw a TypeError"
+  );
+  Assert.throws(
+    () => PlacesUtils.history.remove(["http://example.org", "not a guid, obviously"]),
+    /TypeError: .* is not a valid URL/,
+    "History.remove with an array containing an ill-formed guid/url argument should throw a TypeError"
+  );
+  Assert.throws(
+    () => PlacesUtils.history.remove(["0123456789ab"/*valid guid*/, null]),
+    /TypeError: Invalid url or guid: null/,
+    "History.remove with an array containing a guid and a second argument that is null should throw a TypeError"
+  );
+  Assert.throws(
+    () => PlacesUtils.history.remove(["http://example.org", {"not the kind of object we know how to handle": true}]),
+    /TypeError: Invalid url/,
+    "History.remove with an array containing an unexpected objecgt should throw a TypeError"
+  );
+  Assert.throws(
+    () => PlacesUtils.history.remove("http://example.org", "not a function, obviously"),
+    /TypeError: Invalid function/,
+    "History.remove with a second argument that is not a function argument should throw a TypeError"
+  );
+  try {
+    PlacesUtils.history.remove("http://example.org/I/have/clearly/not/been/added", null);
+    Assert.ok(true, "History.remove should ignore `null` as a second argument");
+  } catch (ex) {
+    Assert.ok(false, "History.remove should ignore `null` as a second argument");
+  }
+});
+
+function run_test() {
+  run_next_test();
+}
new file mode 100644
--- /dev/null
+++ b/toolkit/components/places/tests/unit/history/xpcshell.ini
@@ -0,0 +1,5 @@
+[DEFAULT]
+head = head_history.js
+tail =
+
+[test_remove.js]
--- a/toolkit/profile/nsIToolkitProfileService.idl
+++ b/toolkit/profile/nsIToolkitProfileService.idl
@@ -13,19 +13,31 @@ interface nsIProfileLock;
 [scriptable, uuid(b81c33a6-1ce8-4695-856b-02b7f15cc114)]
 interface nsIToolkitProfileService : nsISupports
 {
     attribute boolean startWithLastProfile;
     attribute boolean startOffline;
 
     readonly attribute nsISimpleEnumerator /*nsIToolkitProfile*/ profiles;
 
+    /**
+     * The currently selected profile (the one used or about to be used by the
+     * browser).
+     */
     attribute nsIToolkitProfile selectedProfile;
 
     /**
+     * The default profile (the one used or about to be used by the
+     * browser if no other profile is specified at runtime). This is the profile
+     * marked with Default=1 in profiles.ini and is usually the same as
+     * selectedProfile, except on Developer Edition.
+     */
+    attribute nsIToolkitProfile defaultProfile;
+
+    /**
      * Get a profile by name. This is mainly for use by the -P
      * commandline flag.
      *
      * @param aName The profile name to find.
      */
     nsIToolkitProfile getProfileByName(in AUTF8String aName);
 
     /**
--- a/toolkit/profile/nsToolkitProfileService.cpp
+++ b/toolkit/profile/nsToolkitProfileService.cpp
@@ -134,16 +134,17 @@ private:
                                    const nsACString* aAppName,
                                    const nsACString* aVendorName,
                                    /*in*/ nsIFile** aProfileDefaultsDir,
                                    bool aForExternalApp,
                                    nsIToolkitProfile** aResult);
 
     nsRefPtr<nsToolkitProfile>  mFirst;
     nsCOMPtr<nsIToolkitProfile> mChosen;
+    nsCOMPtr<nsIToolkitProfile> mDefault;
     nsCOMPtr<nsIFile>           mAppData;
     nsCOMPtr<nsIFile>           mTempData;
     nsCOMPtr<nsIFile>           mListFile;
     bool mDirty;
     bool mStartWithLast;
     bool mStartOffline;
 
     static nsToolkitProfileService *gService;
@@ -419,16 +420,17 @@ nsToolkitProfileService::Init()
     nsAutoCString buffer;
     rv = parser.GetString("General", "StartWithLastProfile", buffer);
     if (NS_SUCCEEDED(rv) && buffer.EqualsLiteral("0"))
         mStartWithLast = false;
 
     nsToolkitProfile* currentProfile = nullptr;
 
     unsigned int c = 0;
+    bool foundAuroraDefault = false;
     for (c = 0; true; ++c) {
         nsAutoCString profileID("Profile");
         profileID.AppendInt(c);
 
         rv = parser.GetString(profileID.get(), "IsRelative", buffer);
         if (NS_FAILED(rv)) break;
 
         bool isRelative = buffer.EqualsLiteral("1");
@@ -436,17 +438,19 @@ nsToolkitProfileService::Init()
         nsAutoCString filePath;
 
         rv = parser.GetString(profileID.get(), "Path", filePath);
         if (NS_FAILED(rv)) {
             NS_ERROR("Malformed profiles.ini: Path= not found");
             continue;
         }
 
-        rv = parser.GetString(profileID.get(), "Name", buffer);
+        nsAutoCString name;
+
+        rv = parser.GetString(profileID.get(), "Name", name);
         if (NS_FAILED(rv)) {
             NS_ERROR("Malformed profiles.ini: Name= not found");
             continue;
         }
 
         nsCOMPtr<nsIFile> rootDir;
         rv = NS_NewNativeLocalFile(EmptyCString(), true,
                                    getter_AddRefs(rootDir));
@@ -465,25 +469,58 @@ nsToolkitProfileService::Init()
                                        getter_AddRefs(localDir));
             NS_ENSURE_SUCCESS(rv, rv);
 
             rv = localDir->SetRelativeDescriptor(mTempData, filePath);
         } else {
             localDir = rootDir;
         }
 
-        currentProfile = new nsToolkitProfile(buffer,
+        currentProfile = new nsToolkitProfile(name,
                                               rootDir, localDir,
                                               currentProfile, false);
         NS_ENSURE_TRUE(currentProfile, NS_ERROR_OUT_OF_MEMORY);
 
         rv = parser.GetString(profileID.get(), "Default", buffer);
-        if (NS_SUCCEEDED(rv) && buffer.EqualsLiteral("1"))
+        if (NS_SUCCEEDED(rv) && buffer.EqualsLiteral("1") && !foundAuroraDefault) {
+            mChosen = currentProfile;
+            this->SetDefaultProfile(currentProfile);
+        }
+#ifdef MOZ_DEV_EDITION
+        // Use the dev-edition-default profile if this is an Aurora build.
+        if (name.EqualsLiteral("dev-edition-default")) {
             mChosen = currentProfile;
+            foundAuroraDefault = true;
+        }
+#endif
     }
+
+#ifdef MOZ_DEV_EDITION
+    // Check if we are running Firefox, as we don't want to create a profile
+    // on webapprt.
+    bool isFirefox = strcmp(gAppData->ID,
+                            "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}") == 0;
+    if (!foundAuroraDefault && isFirefox) {
+        // If a single profile exists, it may not be already marked as default.
+        // Do it now to avoid problems when we create the dev-edition-default profile.
+        if (!mChosen && mFirst && !mFirst->mNext)
+            this->SetDefaultProfile(mFirst);
+
+        // Create a default profile for aurora, if none was found.
+        nsCOMPtr<nsIToolkitProfile> profile;
+        rv = CreateProfile(nullptr,
+                           NS_LITERAL_CSTRING("dev-edition-default"),
+                           getter_AddRefs(profile));
+        if (NS_FAILED(rv)) return rv;
+        mChosen = profile;
+        rv = Flush();
+        if (NS_FAILED(rv)) return rv;
+    }
+#endif
+
     if (!mChosen && mFirst && !mFirst->mNext) // only one profile
         mChosen = mFirst;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsToolkitProfileService::SetStartWithLastProfile(bool aValue)
 {
@@ -565,16 +602,35 @@ nsToolkitProfileService::SetSelectedProf
     if (mChosen != aProfile) {
         mChosen = aProfile;
         mDirty = true;
     }
     return NS_OK;
 }
 
 NS_IMETHODIMP
+nsToolkitProfileService::GetDefaultProfile(nsIToolkitProfile* *aResult)
+{
+    if (!mDefault) return NS_ERROR_FAILURE;
+
+    NS_ADDREF(*aResult = mDefault);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsToolkitProfileService::SetDefaultProfile(nsIToolkitProfile* aProfile)
+{
+    if (mDefault != aProfile) {
+        mDefault = aProfile;
+        mDirty = true;
+    }
+    return NS_OK;
+}
+
+NS_IMETHODIMP
 nsToolkitProfileService::GetProfileByName(const nsACString& aName,
                                           nsIToolkitProfile* *aResult)
 {
     nsToolkitProfile* curP = mFirst;
     while (curP) {
         if (curP->mName.Equals(aName)) {
             NS_ADDREF(*aResult = curP);
             return NS_OK;
@@ -927,17 +983,19 @@ nsToolkitProfileService::Flush()
         end += sprintf(end,
                        "[Profile%u]\n"
                        "Name=%s\n"
                        "IsRelative=%s\n"
                        "Path=%s\n",
                        pCount, cur->mName.get(),
                        isRelative ? "1" : "0", path.get());
 
-        if (mChosen == cur) {
+        nsCOMPtr<nsIToolkitProfile> profile;
+        rv = this->GetDefaultProfile(getter_AddRefs(profile));
+        if (NS_SUCCEEDED(rv) && profile == cur) {
             end += sprintf(end, "Default=1\n");
         }
 
         end += sprintf(end, "\n");
 
         cur = cur->mNext;
         ++pCount;
     }
--- a/toolkit/xre/CreateAppData.cpp
+++ b/toolkit/xre/CreateAppData.cpp
@@ -96,23 +96,24 @@ XRE_ParseAppData(nsIFile* aINIFile, nsXR
   nsINIParser parser;
   rv = parser.Init(aINIFile);
   if (NS_FAILED(rv))
     return rv;
 
   nsCString str;
 
   ReadString strings[] = {
-    { "App", "Vendor",    &aAppData->vendor },
-    { "App", "Name",      &aAppData->name },
-    { "App", "Version",   &aAppData->version },
-    { "App", "BuildID",   &aAppData->buildID },
-    { "App", "ID",        &aAppData->ID },
-    { "App", "Copyright", &aAppData->copyright },
-    { "App", "Profile",   &aAppData->profile },
+    { "App", "Vendor",        &aAppData->vendor },
+    { "App", "Name",          &aAppData->name },
+    { "App", "RemotingName",  &aAppData->remotingName },
+    { "App", "Version",       &aAppData->version },
+    { "App", "BuildID",       &aAppData->buildID },
+    { "App", "ID",            &aAppData->ID },
+    { "App", "Copyright",     &aAppData->copyright },
+    { "App", "Profile",       &aAppData->profile },
     { nullptr }
   };
   ReadStrings(parser, strings);
 
   ReadFlag flags[] = {
     { "XRE", "EnableProfileMigrator", NS_XRE_ENABLE_PROFILE_MIGRATOR },
     { nullptr }
   };
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -1589,17 +1589,17 @@ DumpVersion()
 
 #ifdef MOZ_ENABLE_XREMOTE
 static RemoteResult
 RemoteCommandLine(const char* aDesktopStartupID)
 {
   nsresult rv;
   ArgResult ar;
 
-  nsAutoCString program(gAppData->name);
+  nsAutoCString program(gAppData->remotingName);
   ToLowerCase(program);
   const char *username = getenv("LOGNAME");
 
   const char *temp = nullptr;
   ar = CheckArg("a", true, &temp);
   if (ar == ARG_BAD) {
     PR_fprintf(PR_STDERR, "Error: argument -a requires an application name\n");
     return REMOTE_ARG_BAD;
@@ -4073,17 +4073,17 @@ XREMain::XRE_mainRun()
 
   if (!mShuttingDown) {
 #ifdef MOZ_ENABLE_XREMOTE
     // if we have X remote support, start listening for requests on the
     // proxy window.
     if (!mDisableRemote)
       mRemoteService = do_GetService("@mozilla.org/toolkit/remote-service;1");
     if (mRemoteService)
-      mRemoteService->Startup(mAppData->name, mProfileName.get());
+      mRemoteService->Startup(mAppData->remotingName, mProfileName.get());
 #endif /* MOZ_ENABLE_XREMOTE */
 
     mNativeApp->Enable();
   }
 
 #ifdef MOZ_INSTRUMENT_EVENT_LOOP
   if (PR_GetEnv("MOZ_INSTRUMENT_EVENT_LOOP")) {
     bool logToConsole = true;
@@ -4121,16 +4121,19 @@ XREMain::XRE_main(int argc, char* argv[]
   gArgc = argc;
   gArgv = argv;
 
   NS_ENSURE_TRUE(aAppData, 2);
 
   mAppData = new ScopedAppData(aAppData);
   if (!mAppData)
     return 1;
+  if (!mAppData->remotingName) {
+    SetAllocatedString(mAppData->remotingName, mAppData->name);
+  }
   // used throughout this file
   gAppData = mAppData;
 
   ScopedLogging log;
 
   mozilla::IOInterposerInit ioInterposerGuard;
 
 #if defined(MOZ_WIDGET_GTK)
--- a/toolkit/xre/nsNativeAppSupportWin.cpp
+++ b/toolkit/xre/nsNativeAppSupportWin.cpp
@@ -479,17 +479,17 @@ struct MessageWindow {
     // Class name: appName + "MessageWindow"
     static const wchar_t *className() {
         static wchar_t classNameBuffer[128];
         static wchar_t *mClassName = 0;
         if ( !mClassName ) {
             ::_snwprintf(classNameBuffer,
                          128,   // size of classNameBuffer in PRUnichars
                          L"%s%s",
-                         NS_ConvertUTF8toUTF16(gAppData->name).get(),
+                         NS_ConvertUTF8toUTF16(gAppData->remotingName).get(),
                          L"MessageWindow" );
             mClassName = classNameBuffer;
         }
         return mClassName;
     }
 
     // Create: Register class and create window.
     NS_IMETHOD Create() {
--- a/xpcom/build/nsXREAppData.h
+++ b/xpcom/build/nsXREAppData.h
@@ -42,16 +42,23 @@ struct nsXREAppData
   /**
    * The name of the application. This must be ASCII, and is normally
    * mixed-case, e.g. "Firefox". Required (must not be null or an empty
    * string).
    */
   const char* name;
 
   /**
+   * The internal name of the application for remoting purposes. When left
+   * unspecified, "name" is used instead. This must be ASCII, and is normally
+   * lowercase, e.g. "firefox". Optional (may be null but not an empty string).
+   */
+  const char* remotingName;
+
+  /**
    * The major version, e.g. "0.8.0+". Optional (may be null), but
    * required for advanced application features such as the extension
    * manager and update service. Must not be the empty string.
    */
   const char* version;
 
   /**
    * The application's build identifier, e.g. "2004051604"
--- a/xpcom/glue/AppData.cpp
+++ b/xpcom/glue/AppData.cpp
@@ -38,16 +38,17 @@ SetAllocatedString(const char*& aStr, co
 ScopedAppData::ScopedAppData(const nsXREAppData* aAppData)
 {
   Zero();
 
   this->size = aAppData->size;
 
   SetAllocatedString(this->vendor, aAppData->vendor);
   SetAllocatedString(this->name, aAppData->name);
+  SetAllocatedString(this->remotingName, aAppData->remotingName);
   SetAllocatedString(this->version, aAppData->version);
   SetAllocatedString(this->buildID, aAppData->buildID);
   SetAllocatedString(this->ID, aAppData->ID);
   SetAllocatedString(this->copyright, aAppData->copyright);
   SetAllocatedString(this->profile, aAppData->profile);
   SetStrongPtr(this->directory, aAppData->directory);
   this->flags = aAppData->flags;
 
@@ -65,16 +66,17 @@ ScopedAppData::ScopedAppData(const nsXRE
     SetAllocatedString(this->UAName, aAppData->UAName);
   }
 }
 
 ScopedAppData::~ScopedAppData()
 {
   SetAllocatedString(this->vendor, nullptr);
   SetAllocatedString(this->name, nullptr);
+  SetAllocatedString(this->remotingName, nullptr);
   SetAllocatedString(this->version, nullptr);
   SetAllocatedString(this->buildID, nullptr);
   SetAllocatedString(this->ID, nullptr);
   SetAllocatedString(this->copyright, nullptr);
   SetAllocatedString(this->profile, nullptr);
 
   NS_IF_RELEASE(this->directory);