merge b2g-inbound to mozilla-central a=merge
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Mon, 24 Nov 2014 14:13:25 +0100
changeset 241449 b8240bb9ae4f5ccfe3382369305e9a4a26528ca0
parent 241418 9ef1aa3df47437b35526a427bd008d42f492f3cb (current diff)
parent 241448 7f4b599c6dc83af3b84c0dff0f1b4e6ea477e1c6 (diff)
child 241489 4aa4ae7a26c8f82bf7bd6e03aac0ebd873319737
child 241509 22f4453a4f9803ba6db9afdc7cf9ad275f01fcd6
child 241544 bf907199961227ce892a4f3f2de9aa236928b6d5
push id4311
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 19:37:41 +0000
treeherdermozilla-beta@150c9fed433b [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 b2g-inbound to mozilla-central 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="3ab0d9c70f0b2e1ededc679112c392303f037361">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="c5bad6d78c5fe168e3bb894fc5cb70902c9b19b1"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="3b4c64b5a05d106568dae3f88d38bdbb3d5bc29e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <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="0870da2b5a71b6f48be8222e3f056498fea66e10"/>
--- 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="df362ace56338da8173d30d3e09e08c42c1accfa">
     <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="c5bad6d78c5fe168e3bb894fc5cb70902c9b19b1"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="3b4c64b5a05d106568dae3f88d38bdbb3d5bc29e"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="a47dd04f8f66e42fd331711140f2c3e2fed0767d"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0870da2b5a71b6f48be8222e3f056498fea66e10"/>
   <!-- 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="0e94c080bee081a50aa2097527b0b40852f9143f">
     <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="c5bad6d78c5fe168e3bb894fc5cb70902c9b19b1"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="3b4c64b5a05d106568dae3f88d38bdbb3d5bc29e"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0870da2b5a71b6f48be8222e3f056498fea66e10"/>
   <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="3ab0d9c70f0b2e1ededc679112c392303f037361">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="c5bad6d78c5fe168e3bb894fc5cb70902c9b19b1"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="3b4c64b5a05d106568dae3f88d38bdbb3d5bc29e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <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="0870da2b5a71b6f48be8222e3f056498fea66e10"/>
--- 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="df362ace56338da8173d30d3e09e08c42c1accfa">
     <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="c5bad6d78c5fe168e3bb894fc5cb70902c9b19b1"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="3b4c64b5a05d106568dae3f88d38bdbb3d5bc29e"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="a47dd04f8f66e42fd331711140f2c3e2fed0767d"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0870da2b5a71b6f48be8222e3f056498fea66e10"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/flame-kk/releng-flame-kk.tt
+++ b/b2g/config/flame-kk/releng-flame-kk.tt
@@ -1,8 +1,9 @@
 [
 {
-"size": 91247216,
-"digest": "2b4be549f98695488ea7288d9e7f8ac0fa45112bedefa485a6e016c4af73fa21bb6b3992beda516f268417207c5deb57afad3959d3b1fbd07d5269b3a6be6a27",
+"size": 120750384,
+"digest": "0e0a0b0dcca020e3283ce8deb33d0eed48fab16ef2fd919120bd7b5abba00713210be17f466d11bf77cca3c9e3b663805be61774476cc669f0a75736d901edfd",
 "algorithm": "sha512",
-"filename": "backup-flame.tar.xz"
+"filename": "backup-flame.tar.xz",
+"comment": "v188-1"
 }
 ]
--- 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="3ab0d9c70f0b2e1ededc679112c392303f037361">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="c5bad6d78c5fe168e3bb894fc5cb70902c9b19b1"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="3b4c64b5a05d106568dae3f88d38bdbb3d5bc29e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <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="0870da2b5a71b6f48be8222e3f056498fea66e10"/>
--- 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="0e94c080bee081a50aa2097527b0b40852f9143f">
     <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="c5bad6d78c5fe168e3bb894fc5cb70902c9b19b1"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="3b4c64b5a05d106568dae3f88d38bdbb3d5bc29e"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0870da2b5a71b6f48be8222e3f056498fea66e10"/>
   <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": "bf8bc38f28bda6ccddffbbedd40693ed8a10322c", 
+    "revision": "8f61e7de9914bb7f66ac2faf0bc256dda628a679", 
     "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="df362ace56338da8173d30d3e09e08c42c1accfa">
     <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="c5bad6d78c5fe168e3bb894fc5cb70902c9b19b1"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="3b4c64b5a05d106568dae3f88d38bdbb3d5bc29e"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0870da2b5a71b6f48be8222e3f056498fea66e10"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="746bc48f34f5060f90801925dcdd964030c1ab6d"/>
--- 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="df362ace56338da8173d30d3e09e08c42c1accfa">
     <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="c5bad6d78c5fe168e3bb894fc5cb70902c9b19b1"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="3b4c64b5a05d106568dae3f88d38bdbb3d5bc29e"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <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="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <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="0e94c080bee081a50aa2097527b0b40852f9143f">
     <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="c5bad6d78c5fe168e3bb894fc5cb70902c9b19b1"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="3b4c64b5a05d106568dae3f88d38bdbb3d5bc29e"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0870da2b5a71b6f48be8222e3f056498fea66e10"/>
   <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="df362ace56338da8173d30d3e09e08c42c1accfa">
     <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="c5bad6d78c5fe168e3bb894fc5cb70902c9b19b1"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="3b4c64b5a05d106568dae3f88d38bdbb3d5bc29e"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
   <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="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0870da2b5a71b6f48be8222e3f056498fea66e10"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
--- a/dom/nfc/NfcContentHelper.js
+++ b/dom/nfc/NfcContentHelper.js
@@ -134,102 +134,88 @@ NfcContentHelper.prototype = {
     let val = cpmm.sendSyncMessage("NFC:CheckSessionToken", {
       sessionToken: sessionToken,
       isP2P: isP2P
     });
     return (val[0] === NFC.NFC_GECKO_SUCCESS);
   },
 
   // NFCTag interface
-  readNDEF: function readNDEF(sessionToken) {
-    let request = Services.DOMRequest.createRequest(this._window);
-    let requestId = btoa(this.getRequestId(request));
-    this._requestMap[requestId] = this._window;
+  readNDEF: function readNDEF(sessionToken, callback) {
+    let requestId = callback.getCallbackId();
+    this._requestMap[requestId] = callback;
 
     cpmm.sendAsyncMessage("NFC:ReadNDEF", {
       requestId: requestId,
       sessionToken: sessionToken
     });
-    return request;
   },
 
-  writeNDEF: function writeNDEF(records, sessionToken) {
-    let request = Services.DOMRequest.createRequest(this._window);
-    let requestId = btoa(this.getRequestId(request));
-    this._requestMap[requestId] = this._window;
+  writeNDEF: function writeNDEF(records, sessionToken, callback) {
+    let requestId = callback.getCallbackId();
+    this._requestMap[requestId] = callback;
 
     let encodedRecords = this.encodeNDEFRecords(records);
     cpmm.sendAsyncMessage("NFC:WriteNDEF", {
       requestId: requestId,
       sessionToken: sessionToken,
       records: encodedRecords
     });
-    return request;
   },
 
-  makeReadOnlyNDEF: function makeReadOnlyNDEF(sessionToken) {
-    let request = Services.DOMRequest.createRequest(this._window);
-    let requestId = btoa(this.getRequestId(request));
-    this._requestMap[requestId] = this._window;
+  makeReadOnly: function makeReadOnly(sessionToken, callback) {
+    let requestId = callback.getCallbackId();
+    this._requestMap[requestId] = callback;
 
     cpmm.sendAsyncMessage("NFC:MakeReadOnly", {
       requestId: requestId,
       sessionToken: sessionToken
     });
-    return request;
   },
 
-  format: function format(sessionToken) {
-    let request = Services.DOMRequest.createRequest(this._window);
-    let requestId = btoa(this.getRequestId(request));
-    this._requestMap[requestId] = this._window;
+  format: function format(sessionToken, callback) {
+    let requestId = callback.getCallbackId();
+    this._requestMap[requestId] = callback;
 
     cpmm.sendAsyncMessage("NFC:Format", {
       requestId: requestId,
       sessionToken: sessionToken
     });
-    return request;
   },
 
-  connect: function connect(techType, sessionToken) {
-    let request = Services.DOMRequest.createRequest(this._window);
-    let requestId = btoa(this.getRequestId(request));
-    this._requestMap[requestId] = this._window;
+  connect: function connect(techType, sessionToken, callback) {
+    let requestId = callback.getCallbackId();
+    this._requestMap[requestId] = callback;
 
     cpmm.sendAsyncMessage("NFC:Connect", {
       requestId: requestId,
       sessionToken: sessionToken,
       techType: techType
     });
-    return request;
   },
 
-  close: function close(sessionToken) {
-    let request = Services.DOMRequest.createRequest(this._window);
-    let requestId = btoa(this.getRequestId(request));
-    this._requestMap[requestId] = this._window;
+  close: function close(sessionToken, callback) {
+    let requestId = callback.getCallbackId();
+    this._requestMap[requestId] = callback;
 
     cpmm.sendAsyncMessage("NFC:Close", {
       requestId: requestId,
       sessionToken: sessionToken
     });
-    return request;
   },
 
-  sendFile: function sendFile(data, sessionToken) {
-    let request = Services.DOMRequest.createRequest(this._window);
-    let requestId = btoa(this.getRequestId(request));
-    this._requestMap[requestId] = this._window;
+  sendFile: function sendFile(data, sessionToken, callback) {
+    let requestId = callback.getCallbackId();
+    this._requestMap[requestId] = callback;
 
     cpmm.sendAsyncMessage("NFC:SendFile", {
       requestId: requestId,
       sessionToken: sessionToken,
       blob: data.blob
     });
-    return request;
   },
 
   notifySendFileStatus: function notifySendFileStatus(status, requestId) {
     cpmm.sendAsyncMessage("NFC:NotifySendFileStatus", {
       status: status,
       requestId: requestId
     });
   },
@@ -242,44 +228,39 @@ NfcContentHelper.prototype = {
   registerTargetForPeerReady: function registerTargetForPeerReady(appId) {
     cpmm.sendAsyncMessage("NFC:RegisterPeerReadyTarget", { appId: appId });
   },
 
   unregisterTargetForPeerReady: function unregisterTargetForPeerReady(appId) {
     cpmm.sendAsyncMessage("NFC:UnregisterPeerReadyTarget", { appId: appId });
   },
 
-  checkP2PRegistration: function checkP2PRegistration(appId) {
-    let request = Services.DOMRequest.createRequest(this._window);
-    let requestId = btoa(this.getRequestId(request));
-    this._requestMap[requestId] = this._window;
+  checkP2PRegistration: function checkP2PRegistration(appId, callback) {
+    let requestId = callback.getCallbackId();
+    this._requestMap[requestId] = callback;
 
     cpmm.sendAsyncMessage("NFC:CheckP2PRegistration", {
       appId: appId,
       requestId: requestId
     });
-    return request;
   },
 
   notifyUserAcceptedP2P: function notifyUserAcceptedP2P(appId) {
     cpmm.sendAsyncMessage("NFC:NotifyUserAcceptedP2P", {
       appId: appId
     });
   },
 
-  changeRFState: function changeRFState(rfState) {
-    let request = Services.DOMRequest.createRequest(this._window);
-    let requestId = btoa(this.getRequestId(request));
-    this._requestMap[requestId] = this._window;
+  changeRFState: function changeRFState(rfState, callback) {
+    let requestId = callback.getCallbackId();
+    this._requestMap[requestId] = callback;
 
     cpmm.sendAsyncMessage("NFC:ChangeRFState",
                           {requestId: requestId,
                            rfState: rfState});
-    return request;
-
   },
 
   // nsIObserver
   observe: function observe(subject, topic, data) {
     if (topic == "xpcom-shutdown") {
       this.destroyDOMRequestHelper();
       Services.obs.removeObserver(this, NFC.TOPIC_MOZSETTINGS_CHANGED);
       Services.obs.removeObserver(this, "xpcom-shutdown");
@@ -290,41 +271,16 @@ NfcContentHelper.prototype = {
       }
       if (subject) {
         this.handle(subject.key, subject.value);
       }
     }
   },
 
   // nsIMessageListener
-
-  fireRequestSuccess: function fireRequestSuccess(requestId, result) {
-    let request = this.takeRequest(requestId);
-    if (!request) {
-      debug("not firing success for id: " + requestId);
-      return;
-    }
-
-    debug("fire request success, id: " + requestId);
-    Services.DOMRequest.fireSuccess(request, result);
-  },
-
-  fireRequestError: function fireRequestError(requestId, errorMsg) {
-    let request = this.takeRequest(requestId);
-    if (!request) {
-      debug("not firing error for id: " + requestId +
-            ", errormsg: " + errorMsg);
-      return;
-    }
-
-    debug("fire request error, id: " + requestId +
-          ", errormsg: " + errorMsg);
-    Services.DOMRequest.fireError(request, errorMsg);
-  },
-
   receiveMessage: function receiveMessage(message) {
     DEBUG && debug("Message received: " + JSON.stringify(message));
     let result = message.json;
 
     switch (message.name) {
       case "NFC:ReadNDEFResponse":
         this.handleReadNDEFResponse(result);
         break;
@@ -333,21 +289,17 @@ NfcContentHelper.prototype = {
         break;
       case "NFC:ConnectResponse": // Fall through.
       case "NFC:CloseResponse":
       case "NFC:WriteNDEFResponse":
       case "NFC:MakeReadOnlyResponse":
       case "NFC:FormatResponse":
       case "NFC:NotifySendFileStatusResponse":
       case "NFC:ChangeRFStateResponse":
-        if (result.errorMsg) {
-          this.fireRequestError(atob(result.requestId), result.errorMsg);
-        } else {
-          this.fireRequestSuccess(atob(result.requestId), result);
-        }
+        this.handleGeneralResponse(result);
         break;
       case "NFC:DOMEvent":
         switch (result.event) {
           case NFC.PEER_EVENT_READY:
             this.eventListener.notifyPeerFound(result.sessionToken, /* isPeerReady */ true);
             break;
           case NFC.PEER_EVENT_FOUND:
             this.eventListener.notifyPeerFound(result.sessionToken);
@@ -376,47 +328,70 @@ NfcContentHelper.prototype = {
     switch (name) {
       case NFC.SETTING_NFC_DEBUG:
         DEBUG = result;
         updateDebug();
         break;
     }
   },
 
-  handleReadNDEFResponse: function handleReadNDEFResponse(result) {
-    let requester = this._requestMap[result.requestId];
-    if (!requester) {
-      debug("Response Invalid requestId=" + result.requestId);
+  handleGeneralResponse: function handleReadNDEFResponse(result) {
+    let requestId = result.requestId;
+    let callback = this._requestMap[requestId];
+    if (!callback) {
+      debug("not firing message " + result.type + " for id: " + requestId);
       return;
     }
-    delete this._requestMap[result.requestId];
+    delete this._requestMap[requestId];
 
     if (result.errorMsg) {
-      this.fireRequestError(atob(result.requestId), result.errorMsg);
+      callback.notifyError(result.errorMsg);
+    } else {
+      callback.notifySuccess();
+    }
+  },
+
+  handleReadNDEFResponse: function handleReadNDEFResponse(result) {
+    let requestId = result.requestId;
+    let callback = this._requestMap[requestId];
+    if (!callback) {
+      debug("not firing message handleReadNDEFResponse for id: " + requestId);
+      return;
+    }
+    delete this._requestMap[requestId];
+
+    if (result.errorMsg) {
+      callback.notifyError(result.errorMsg);
       return;
     }
 
-    let requestId = atob(result.requestId);
     let ndefMsg = [];
     let records = result.records;
     for (let i = 0; i < records.length; i++) {
       let record = records[i];
-      ndefMsg.push(new requester.MozNDEFRecord({tnf: record.tnf,
-                                                type: record.type,
-                                                id: record.id,
-                                                payload: record.payload}));
+      ndefMsg.push(new this._window.MozNDEFRecord({tnf: record.tnf,
+                                                   type: record.type,
+                                                   id: record.id,
+                                                   payload: record.payload}));
     }
-    this.fireRequestSuccess(requestId, ndefMsg);
+    callback.notifySuccessWithNDEFRecords(ndefMsg);
   },
 
   handleCheckP2PRegistrationResponse: function handleCheckP2PRegistrationResponse(result) {
+    let requestId = result.requestId;
+    let callback = this._requestMap[requestId];
+    if (!callback) {
+      debug("not firing message handleCheckP2PRegistrationResponse for id: " + requestId);
+      return;
+    }
+    delete this._requestMap[requestId];
+
     // Privilaged status API. Always fire success to avoid using exposed props.
     // The receiver must check the boolean mapped status code to handle.
-    let requestId = atob(result.requestId);
-    this.fireRequestSuccess(requestId, !result.errorMsg);
+    callback.notifySuccessWithBoolean(!result.errorMsg);
   },
 };
 
 function NfcTagEvent(techList, tagType, maxNDEFSize, isReadOnly, isFormatable) {
   this.techList = techList;
   this.tagType = tagType;
   this.maxNDEFSize = maxNDEFSize;
   this.isReadOnly = isReadOnly;
--- a/dom/nfc/nsINfcContentHelper.idl
+++ b/dom/nfc/nsINfcContentHelper.idl
@@ -1,16 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
-#include "nsIDOMDOMRequest.idl"
 
 interface nsIVariant;
+interface nsIDOMWindow;
 
 [scriptable, uuid(9b43bdda-52f4-4712-b28c-ad7cba736e14)]
 interface nsINfcTagEvent : nsISupports
 {
   readonly attribute nsIVariant techList;
 
   // one of NFCTagType defined in MozNFCTag.webidl.
   readonly attribute DOMString tagType;
@@ -60,47 +60,134 @@ interface nsINfcEventListener : nsISuppo
    * Callback function used to notify peerlost.
    *
    * @param sessionToken
    *        SessionToken received from parent process
    */
   void notifyPeerLost(in DOMString sessionToken);
 };
 
-[scriptable, uuid(9343ae1a-6e2f-11e4-b5c4-fbb166b38b62)]
+[scriptable, uuid(a8ef3590-d853-4766-b54a-a4547da4dde4)]
+interface nsINfcRequestCallback : nsISupports
+{
+  DOMString getCallbackId();
+
+  void notifySuccess();
+
+  void notifySuccessWithBoolean(in boolean result);
+
+  void notifySuccessWithNDEFRecords(in nsIVariant records);
+
+  void notifyError(in DOMString errorMsg);
+};
+
+[scriptable, uuid(9da02537-c4d0-4b2d-b294-d3250ff1720e)]
 interface nsINfcContentHelper : nsISupports
 {
   void init(in nsIDOMWindow window);
 
   boolean checkSessionToken(in DOMString sessionToken, in boolean isP2P);
 
-  nsIDOMDOMRequest readNDEF(in DOMString sessionToken);
-  nsIDOMDOMRequest writeNDEF(in nsIVariant records, in DOMString sessionToken);
-  nsIDOMDOMRequest makeReadOnly(in DOMString sessionToken);
-  nsIDOMDOMRequest format(in DOMString sessionToken);
+  /**
+   * Read current NDEF data on the tag.
+   *
+   * @param sessionToken
+   *        Current token
+   *
+   * @param callback
+   *        Called when request is finished
+   */
+  void readNDEF(in DOMString sessionToken,
+                in nsINfcRequestCallback callback);
+
+  /**
+   * Write NDEF data to a peer device or a tag.
+   *
+   * @param records
+   *        NDEF records to be written
+   *
+   * @param sessionToken
+   *        Current token
+   *
+   * @param callback
+   *        Called when request is finished
+   */
+  void writeNDEF(in nsIVariant records,
+                 in DOMString sessionToken,
+                 in nsINfcRequestCallback callback);
+
+  /**
+   * Make a tag read-only
+   *
+   * @param sessionToken
+   *        Current token
+   *
+   * @param callback
+   *        Called when request is finished
+   */
+  void makeReadOnly(in DOMString sessionToken,
+                    in nsINfcRequestCallback callback);
 
-  nsIDOMDOMRequest connect(in unsigned long techType, in DOMString sessionToken);
-  nsIDOMDOMRequest close(in DOMString sessionToken);
+  /**
+   * Format a tag as NDEF
+   *
+   * @param sessionToken
+   *        Current token
+   *
+   * @param callback
+   *        Called when request is finished
+   */
+  void format(in DOMString sessionToken,
+              in nsINfcRequestCallback callback);
+
+  /**
+   * Enable I/O operations to the tag
+   *
+   * @param techType
+   *        Interface to a technology in a Tag
+   *
+   * @param sessionToken
+   *        Current token
+   *
+   * @param callback
+   *        Called when request is finished
+   */
+  void connect(in unsigned long techType,
+               in DOMString sessionToken,
+               in nsINfcRequestCallback callback);
+
+  /**
+   * Disable I/O operations to the tag
+   *
+   * @param sessionToken
+   *        Current token
+   *
+   * @param callback
+   *        Called when request is finished
+   */
+  void close(in DOMString sessionToken,
+             in nsINfcRequestCallback callback);
 
   /**
    * Initiate send file operation.
    *
    * @param blob
    *        Raw data of the file to be sent. This object represents a file-like
    *        (nsIDOMFile) object of immutable, raw data. The blob data needs
    *        to be 'object wrapped' before calling this interface.
    *
    * @param sessionToken
    *        Current token
    *
-   * Returns DOMRequest, if initiation of send file operation is successful
-   * then 'onsuccess' is called else 'onerror'
+   * @param callback
+   *        Called when request is finished
    */
-  nsIDOMDOMRequest sendFile(in jsval blob,
-                            in DOMString sessionToken);
+  void sendFile(in jsval blob,
+                in DOMString sessionToken,
+                in nsINfcRequestCallback callback);
 
   /**
    * Add the event listener.
    *
    * @param listener
    *        An instance of the nsINfcEventListener.
    */
   void addEventListener(in nsINfcEventListener listener);
@@ -122,19 +209,21 @@ interface nsINfcContentHelper : nsISuppo
   void unregisterTargetForPeerReady(in unsigned long appId);
 
   /**
    * Checks if the given application's id is a registered peer target (with the parent process)
    *
    * @param appId
    *        Application ID to be updated with parent process
    *
-   * Returns DOMRequest, if appId is registered then 'onsuccess' is called else 'onerror'
+   * @param callback
+   *        Called when request is finished
    */
-  nsIDOMDOMRequest checkP2PRegistration(in unsigned long appId);
+  void checkP2PRegistration(in unsigned long appId,
+                            in nsINfcRequestCallback callback);
 
   /**
    * Notify the parent process that user has accepted to share nfc message on P2P UI
    *
    * @param appId
    *        Application ID that is capable of handling NFC_EVENT_PEER_READY event
    */
   void notifyUserAcceptedP2P(in unsigned long appId);
@@ -150,11 +239,15 @@ interface nsINfcContentHelper : nsISuppo
    */
   void notifySendFileStatus(in octet status,
                             in DOMString requestId);
 
   /**
    * Change RF state.
    *
    * @param rfState. Possible values are 'idle', 'listen' and 'discovery'.
+   *
+   * @param callback
+   *        Called when request is finished
    */
-  nsIDOMDOMRequest changeRFState(in DOMString rfState);
+  void changeRFState(in DOMString rfState,
+                     in nsINfcRequestCallback callback);
 };
--- a/dom/nfc/nsNfc.js
+++ b/dom/nfc/nsNfc.js
@@ -12,22 +12,88 @@ function debug(s) {
 }
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this,
                                    "appsService",
                                    "@mozilla.org/AppsService;1",
                                    "nsIAppsService");
 
+function NfcCallback(aWindow) {
+  this.initDOMRequestHelper(aWindow, null);
+  this._createPromise();
+}
+NfcCallback.prototype = {
+  __proto__: DOMRequestIpcHelper.prototype,
+
+  promise: null,
+  _requestId: null,
+
+  _createPromise: function _createPromise() {
+    this.promise = this.createPromise((aResolve, aReject) => {
+      this._requestId = btoa(this.getPromiseResolverId({
+        resolve: aResolve,
+        reject: aReject
+      }));
+    });
+  },
+
+  getCallbackId: function getCallbackId() {
+    return this._requestId;
+  },
+
+  notifySuccess: function notifySuccess() {
+    let resolver = this.takePromiseResolver(atob(this._requestId));
+    if (!resolver) {
+      debug("can not find promise resolver for id: " + this._requestId);
+      return;
+    }
+    resolver.resolve();
+  },
+
+  notifySuccessWithBoolean: function notifySuccessWithBoolean(aResult) {
+    let resolver = this.takePromiseResolver(atob(this._requestId));
+    if (!resolver) {
+      debug("can not find promise resolver for id: " + this._requestId);
+      return;
+    }
+    resolver.resolve(aResult);
+  },
+
+  notifySuccessWithNDEFRecords: function notifySuccessWithNDEFRecords(aRecords) {
+    let resolver = this.takePromiseResolver(atob(this._requestId));
+    if (!resolver) {
+      debug("can not find promise resolver for id: " + this._requestId);
+      return;
+    }
+    resolver.resolve(aRecords);
+  },
+
+  notifyError: function notifyError(aErrorMsg) {
+    let resolver = this.takePromiseResolver(atob(this._requestId));
+    if (!resolver) {
+      debug("can not find promise resolver for id: " + this._requestId +
+           ", errormsg: " + aErrorMsg);
+      return;
+    }
+    resolver.reject(aErrorMsg);
+  },
+
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference,
+                                         Ci.nsIObserver,
+                                         Ci.nsINfcRequestCallback]),
+};
+
 /**
  * Implementation of NFCTag.
  *
  * @param window  global window object.
  * @param sessionToken  session token received from parent process.
  * @parem event   type of nsINfcTagEvent received from parent process.
  */
 function MozNFCTagImpl(window, sessionToken, event) {
@@ -59,17 +125,19 @@ MozNFCTagImpl.prototype = {
   isLost: false,
 
   // NFCTag interface:
   readNDEF: function readNDEF() {
     if (this.isLost) {
       throw new this._window.DOMError("InvalidStateError", "NFCTag object is invalid");
     }
 
-    return this._nfcContentHelper.readNDEF(this.session);
+    let callback = new NfcCallback(this._window);
+    this._nfcContentHelper.readNDEF(this.session, callback);
+    return callback.promise;
   },
 
   writeNDEF: function writeNDEF(records) {
     if (this.isLost) {
       throw new this._window.DOMError("InvalidStateError", "NFCTag object is invalid");
     }
 
     if (this.isReadOnly) {
@@ -80,43 +148,49 @@ MozNFCTagImpl.prototype = {
     for (let record of records) {
       ndefLen += record.size;
     }
 
     if (ndefLen > this.maxNDEFSize) {
       throw new this._window.DOMError("NotSupportedError", "Exceed max NDEF size");
     }
 
-    return this._nfcContentHelper.writeNDEF(records, this.session);
+    let callback = new NfcCallback(this._window);
+    this._nfcContentHelper.writeNDEF(records, this.session, callback);
+    return callback.promise;
   },
 
   makeReadOnly: function makeReadOnly() {
     if (this.isLost) {
       throw new this._window.DOMError("InvalidStateError", "NFCTag object is invalid");
     }
 
     if (!this.canBeMadeReadOnly) {
       throw new this._window.DOMError("InvalidAccessError",
                                       "NFCTag object cannot be made read-only");
     }
 
-    return this._nfcContentHelper.makeReadOnly(this.session);
+    let callback = new NfcCallback(this._window);
+    this._nfcContentHelper.makeReadOnly(this.session, callback);
+    return callback.promise;
   },
 
   format: function format() {
     if (this.isLost) {
       throw new this._window.DOMError("InvalidStateError", "NFCTag object is invalid");
     }
 
     if (!this.isFormatable) {
       throw new this._window.DOMError("InvalidAccessError",
                                       "NFCTag object is not formatable");
     }
 
-    return this._nfcContentHelper.format(this.session);
+    let callback = new NfcCallback(this._window);
+    this._nfcContentHelper.format(this.session, callback);
+    return callback.promise;
   },
 
   classID: Components.ID("{4e1e2e90-3137-11e3-aa6e-0800200c9a66}"),
   contractID: "@mozilla.org/nfc/NFCTag;1",
   QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
                                          Ci.nsIDOMGlobalPropertyInitializer]),
 };
 
@@ -141,29 +215,34 @@ MozNFCPeerImpl.prototype = {
 
   // NFCPeer interface:
   sendNDEF: function sendNDEF(records) {
     if (this.isLost) {
       throw new this._window.DOMError("InvalidStateError", "NFCPeer object is invalid");
     }
 
     // Just forward sendNDEF to writeNDEF
-    return this._nfcContentHelper.writeNDEF(records, this.session);
+    let callback = new NfcCallback(this._window);
+    this._nfcContentHelper.writeNDEF(records, this.session, callback);
+    return callback.promise;
   },
 
   sendFile: function sendFile(blob) {
     if (this.isLost) {
       throw new this._window.DOMError("InvalidStateError", "NFCPeer object is invalid");
     }
 
     let data = {
       "blob": blob
     };
-    return this._nfcContentHelper.sendFile(Cu.cloneInto(data, this._window),
-                                           this.session);
+
+    let callback = new NfcCallback(this._window);
+    this._nfcContentHelper.sendFile(Cu.cloneInto(data, this._window),
+                                    this.session, callback);
+    return callback.promise;
   },
 
   classID: Components.ID("{c1b2bcf0-35eb-11e3-aa6e-0800200c9a66}"),
   contractID: "@mozilla.org/nfc/NFCPeer;1",
   QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
                                          Ci.nsIDOMGlobalPropertyInitializer]),
 };
 
@@ -174,23 +253,26 @@ function MozNFCImpl() {
   debug("In MozNFCImpl Constructor");
   try {
     this._nfcContentHelper = Cc["@mozilla.org/nfc/content-helper;1"]
                                .getService(Ci.nsINfcContentHelper);
   } catch(e) {
     debug("No NFC support.")
   }
 
+  this.eventService = Cc["@mozilla.org/eventlistenerservice;1"]
+                        .getService(Ci.nsIEventListenerService);
   this._nfcContentHelper.addEventListener(this);
 }
 MozNFCImpl.prototype = {
   _nfcContentHelper: null,
   _window: null,
   nfcPeer: null,
   nfcTag: null,
+  eventService: null,
 
   // Should be mapped to the RFState defined in WebIDL.
   rfState: {
     IDLE: "idle",
     LISTEN: "listen",
     DISCOVERY: "discovery"
   },
 
@@ -209,39 +291,48 @@ MozNFCImpl.prototype = {
   },
 
   // Only apps which have nfc-manager permission can call the following interfaces
   // 'checkP2PRegistration' , 'notifyUserAcceptedP2P' , 'notifySendFileStatus',
   // 'startPoll', 'stopPoll', and 'powerOff'.
   checkP2PRegistration: function checkP2PRegistration(manifestUrl) {
     // Get the AppID and pass it to ContentHelper
     let appID = appsService.getAppLocalIdByManifestURL(manifestUrl);
-    return this._nfcContentHelper.checkP2PRegistration(appID);
+
+    let callback = new NfcCallback(this._window);
+    this._nfcContentHelper.checkP2PRegistration(appID, callback);
+    return callback.promise;
   },
 
   notifyUserAcceptedP2P: function notifyUserAcceptedP2P(manifestUrl) {
     let appID = appsService.getAppLocalIdByManifestURL(manifestUrl);
     // Notify chrome process of user's acknowledgement
     this._nfcContentHelper.notifyUserAcceptedP2P(appID);
   },
 
   notifySendFileStatus: function notifySendFileStatus(status, requestId) {
     this._nfcContentHelper.notifySendFileStatus(status, requestId);
   },
 
   startPoll: function startPoll() {
-    return this._nfcContentHelper.changeRFState(this.rfState.DISCOVERY);
+    let callback = new NfcCallback(this._window);
+    this._nfcContentHelper.changeRFState(this.rfState.DISCOVERY, callback);
+    return callback.promise;
   },
 
   stopPoll: function stopPoll() {
-    return this._nfcContentHelper.changeRFState(this.rfState.LISTEN);
+    let callback = new NfcCallback(this._window);
+    this._nfcContentHelper.changeRFState(this.rfState.LISTEN, callback);
+    return callback.promise;
   },
 
   powerOff: function powerOff() {
-    return this._nfcContentHelper.changeRFState(this.rfState.IDLE);
+    let callback = new NfcCallback(this._window);
+    this._nfcContentHelper.changeRFState(this.rfState.IDLE, callback);
+    return callback.promise;
   },
 
   _createNFCPeer: function _createNFCPeer(sessionToken) {
     let peer = new MozNFCPeerImpl(this._window, sessionToken);
     return this._window.MozNFCPeer._create(this._window, peer);
   },
 
   getNFCPeer: function getNFCPeer(sessionToken) {
@@ -286,20 +377,28 @@ MozNFCImpl.prototype = {
   },
 
   notifyTagFound: function notifyTagFound(sessionToken, event, records) {
     if (this.hasDeadWrapper()) {
       dump("this._window or this.__DOM_IMPL__ is a dead wrapper.");
       return;
     }
 
+    if (!this.eventService.hasListenersFor(this.__DOM_IMPL__, "tagfound")) {
+      debug("ontagfound is not registered.");
+      return;
+    }
+
     if (!this.checkPermissions(["nfc-read", "nfc-write"])) {
       return;
     }
 
+    this.eventService.addSystemEventListener(this._window, "visibilitychange",
+      this, /* useCapture */false);
+
     let tagImpl = new MozNFCTagImpl(this._window, sessionToken, event);
     let tag = this._window.MozNFCTag._create(this._window, tagImpl);
     this.nfcTag = tag;
 
     let length = records ? records.length : 0;
     let ndefRecords = records ? [] : null;
     for (let i = 0; i < length; i++) {
       let record = records[i];
@@ -324,37 +423,54 @@ MozNFCImpl.prototype = {
       dump("this._window or this.__DOM_IMPL__ is a dead wrapper.");
       return;
     }
 
     if (!this.checkPermissions(["nfc-read", "nfc-write"])) {
       return;
     }
 
-    if (this.nfcTag && (this.nfcTag.session == sessionToken)) {
-      this.nfcTag.isLost = true;
-      this.nfcTag = null;
+    if (!this.nfcTag) {
+      debug("No NFCTag object existing.");
+      return;
     }
 
+    // Remove system event listener only when tag and peer are both lost.
+    if (!this.nfcPeer) {
+      this.eventService.removeSystemEventListener(this._window, "visibilitychange",
+        this, /* useCapture */false);
+    }
+
+    this.nfcTag.isLost = true;
+    this.nfcTag = null;
+
     debug("fire ontaglost " + sessionToken);
     let event = new this._window.Event("taglost");
     this.__DOM_IMPL__.dispatchEvent(event);
   },
 
   notifyPeerFound: function notifyPeerFound(sessionToken, isPeerReady) {
     if (this.hasDeadWrapper()) {
       dump("this._window or this.__DOM_IMPL__ is a dead wrapper.");
       return;
     }
 
+    if (!isPeerReady &&
+        !this.eventService.hasListenersFor(this.__DOM_IMPL__, "peerfound")) {
+      debug("onpeerfound is not registered.");
+      return;
+    }
+
     if (!this.checkPermissions(["nfc-write"])) {
       return;
     }
 
-    this.session = sessionToken;
+    this.eventService.addSystemEventListener(this._window, "visibilitychange",
+      this, /* useCapture */false);
+
     this.nfcPeer = this._createNFCPeer(sessionToken);
     let eventData = { "peer": this.nfcPeer };
     let type = (isPeerReady) ? "peerready" : "peerfound";
 
     debug("fire on" + type + " " + sessionToken);
     let event = new this._window.MozNFCPeerEvent(type, eventData);
     this.__DOM_IMPL__.dispatchEvent(event);
   },
@@ -364,33 +480,51 @@ MozNFCImpl.prototype = {
       dump("this._window or this.__DOM_IMPL__ is a dead wrapper.");
       return;
     }
 
     if (!this.checkPermissions(["nfc-write"])) {
       return;
     }
 
-    if (sessionToken != this.session) {
-      dump("Unpaired session for notifyPeerLost." + sessionToken);
+    if (!this.nfcPeer) {
+      debug("No NFCPeer object existing.");
       return;
     }
 
-    if (this.nfcPeer && (this.nfcPeer.session == sessionToken)) {
-      this.nfcPeer.isLost = true;
-      this.nfcPeer = null;
+    // Remove system event listener only when tag and peer are both lost.
+    if (!this.nfcTag) {
+      this.eventService.removeSystemEventListener(this._window, "visibilitychange",
+        this, /* useCapture */false);
     }
 
-    this.session = null;
+    this.nfcPeer.isLost = true;
+    this.nfcPeer = null;
 
     debug("fire onpeerlost");
     let event = new this._window.Event("peerlost");
     this.__DOM_IMPL__.dispatchEvent(event);
   },
 
+  handleEvent: function handleEvent (event) {
+    if (!this._window.document.hidden) {
+      return;
+    }
+
+    if (this.nfcTag) {
+      debug("handleEvent notifyTagLost");
+      this.notifyTagLost(this.nfcTag.session);
+    }
+
+    if (this.nfcPeer) {
+      debug("handleEvent notifyPeerLost");
+      this.notifyPeerLost(this.nfcPeer.session);
+    }
+  },
+
   checkPermissions: function checkPermissions(perms) {
     let principal = this._window.document.nodePrincipal;
     for (let perm of perms) {
       let permValue =
         Services.perms.testExactPermissionFromPrincipal(principal, perm);
       if (permValue == Ci.nsIPermissionManager.ALLOW_ACTION) {
         return true;
       } else {
@@ -404,13 +538,14 @@ MozNFCImpl.prototype = {
   hasDeadWrapper: function hasDeadWrapper() {
     return Cu.isDeadWrapper(this._window) || Cu.isDeadWrapper(this.__DOM_IMPL__);
   },
 
   classID: Components.ID("{6ff2b290-2573-11e3-8224-0800200c9a66}"),
   contractID: "@mozilla.org/navigatorNfc;1",
   QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
                                          Ci.nsIDOMGlobalPropertyInitializer,
-                                         Ci.nsINfcEventListener]),
+                                         Ci.nsINfcEventListener,
+                                         Ci.nsIDOMEventListener]),
 };
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([MozNFCTagImpl,
   MozNFCPeerImpl, MozNFCImpl]);
--- a/dom/nfc/tests/marionette/head.js
+++ b/dom/nfc/tests/marionette/head.js
@@ -189,32 +189,30 @@ let SNEP = (function() {
     put: put,
     SAP_NDEF: 4
   };
 }());
 
 function toggleNFC(enabled) {
   let deferred = Promise.defer();
 
-  let req;
+  let promise;
   if (enabled) {
-    req = nfc.startPoll();
+    promise = nfc.startPoll();
   } else {
-    req = nfc.powerOff();
+    promise = nfc.powerOff();
   }
 
-  req.onsuccess = function() {
+  promise.then(() => {
     deferred.resolve();
-  };
-
-  req.onerror = function() {
+  }).catch(() => {
     ok(false, 'operation failed, error ' + req.error.name);
     deferred.reject();
     finish();
-  };
+  });
 
   return deferred.promise;
 }
 
 function clearPendingMessages(type) {
   if (!window.navigator.mozHasPendingMessage(type)) {
     return;
   }
--- a/dom/nfc/tests/marionette/test_nfc_checkP2PRegistration.js
+++ b/dom/nfc/tests/marionette/test_nfc_checkP2PRegistration.js
@@ -106,26 +106,24 @@ function registerOnpeerready() {
   let d = Promise.defer();
   d.resolve();
   return d.promise;
 }
 
 function fireCheckP2PReg(manifestUrl) {
   let deferred = Promise.defer();
 
-  let request = nfc.checkP2PRegistration(manifestUrl);
-  request.onsuccess = function() {
+  let promise = nfc.checkP2PRegistration(manifestUrl);
+  promise.then(() => {
     ok(true, 'checkP2PRegistration allways results in success');
     deferred.resolve(request.result);
-  };
-
-  request.onerror = function() {
+  }).catch(() => {
     ok(false, 'see NfcContentHelper.handleCheckP2PRegistrationResponse');
     deferred.reject();
-  };
+  });
 
   return deferred.promise;
 }
 
 function handleRejectedPromise() {
    ok(false, 'Promise rejected. This should not happen');
    nfc.onpeerready = null;
    runNextTest();
--- a/dom/nfc/tests/marionette/test_nfc_enabled.js
+++ b/dom/nfc/tests/marionette/test_nfc_enabled.js
@@ -1,51 +1,48 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 MARIONETTE_TIMEOUT = 30000;
 MARIONETTE_HEAD_JS = 'head.js';
 
 function testEnableNFC() {
   log('Running \'testEnableNFC\'');
-  let req = nfc.startPoll();
-  req.onsuccess = function () {
+  let promise = nfc.startPoll();
+  promise.then(() => {
     ok(true);
     runNextTest();
-  };
-  req.onerror = function () {
+  }).catch(() => {
     ok(false, "startPoll failed");
     runNextTest();
-  };
+  });
 }
 
 function testDisableNFC() {
   log('Running \'testDisableNFC\'');
-  let req = nfc.powerOff();
-  req.onsuccess = function () {
+  let promise = nfc.powerOff();
+  promise.then(() => {
     ok(true);
     runNextTest();
-  };
-  req.onerror = function () {
+  }).catch(() => {
     ok(false, "powerOff failed");
     runNextTest();
-  };
+  });
 }
 
 function testStopPollNFC() {
   log('Running \'testStopPollNFC\'');
-  let req = nfc.stopPoll();
-  req.onsuccess = function () {
+  let promise = nfc.stopPoll();
+  promise.then(() => {
     ok(true);
     runNextTest();
-  };
-  req.onerror = function () {
+  }).catch(() => {
     ok(false, "stopPoll failed");
     runNextTest();
-  };
+  });
 }
 
 let tests = [
   testEnableNFC,
   testStopPollNFC,
   testDisableNFC
 ];
 
--- a/dom/nfc/tests/marionette/test_nfc_peer.js
+++ b/dom/nfc/tests/marionette/test_nfc_peer.js
@@ -39,30 +39,28 @@ function handleTechnologyDiscoveredRE0(m
 
 function handleTechnologyDiscoveredRE0ForP2PRegFailure(msg) {
   log("Received \'nfc-manager-tech-discovered\'");
   is(msg.type, "techDiscovered", "check for correct message type");
   is(msg.techList[0], "P2P", "check for correct tech type");
 
   nfc.onpeerready = peerReadyCb;
 
-  let request = nfc.checkP2PRegistration(INCORRECT_MANIFEST_URL);
-  request.onsuccess = function (evt) {
+  let promise = nfc.checkP2PRegistration(INCORRECT_MANIFEST_URL);
+  promise.then(evt => {
     is(request.result, false, "check for P2P registration result");
 
     nfc.onpeerready = null;
     NCI.deactivate().then(() => toggleNFC(false)).then(runNextTest);
-  }
-
-  request.onerror = function () {
+  }).catch(() => {
     ok(false, "checkP2PRegistration failed.");
 
     nfc.onpeerready = null;
     NCI.deactivate().then(() => toggleNFC(false)).then(runNextTest);
-  }
+  });
 }
 
 function testPeerReady() {
   sysMsgHelper.waitForTechDiscovered(handleTechnologyDiscoveredRE0);
 
   toggleNFC(true).then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0));
 }
 
--- a/dom/nfc/tests/marionette/test_nfc_peer_sendndef.js
+++ b/dom/nfc/tests/marionette/test_nfc_peer_sendndef.js
@@ -8,32 +8,31 @@ let url = "https://www.example.com";
 
 function sendNDEF(techType, sessionToken) {
   let tnf = NDEF.TNF_WELL_KNOWN;
   let type = new Uint8Array(NfcUtils.fromUTF8("U"));
   let payload = new Uint8Array(NfcUtils.fromUTF8(url));
   let ndef = [new MozNDEFRecord({tnf: tnf, type: type, payload: payload})];
 
   let peer = window.navigator.mozNfc.getNFCPeer(sessionToken);
-  let req = peer.sendNDEF(ndef);
-  req.onsuccess = function() {
+  let promise = peer.sendNDEF(ndef);
+  promise.then(() => {
     log("Successfully sent NDEF message");
 
     let cmd = "nfc snep put -1 -1"; /* read last SNEP PUT from emulator */
     log("Executing \'" + cmd + "\'");
     emulator.run(cmd, function(result) {
       is(result.pop(), "OK", "check SNEP PUT result");
       NDEF.compare(ndef, NDEF.parseString(result.pop()));
       toggleNFC(false).then(runNextTest);
     });
-  };
-  req.onerror = function() {
+  }).catch(() => {
     ok(false, "Failed to send NDEF message, error \'" + this.error + "\'");
     toggleNFC(false).then(runNextTest);
-  };
+  });
 }
 
 function handleTechnologyDiscoveredRE0(msg) {
   log("Received \'nfc-manager-tech-discovered\' " + JSON.stringify(msg));
   is(msg.type, "techDiscovered", "check for correct message type");
   let index = msg.techList.indexOf("P2P");
   isnot(index, -1, "check for \'P2P\' in tech list");
   sendNDEF(msg.techList[index], msg.sessionToken);
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -82,16 +82,18 @@ const DOM_MOBILE_MESSAGE_DELIVERY_RECEIV
 const DOM_MOBILE_MESSAGE_DELIVERY_SENDING  = "sending";
 const DOM_MOBILE_MESSAGE_DELIVERY_SENT     = "sent";
 const DOM_MOBILE_MESSAGE_DELIVERY_ERROR    = "error";
 
 const RADIO_POWER_OFF_TIMEOUT = 30000;
 const SMS_HANDLED_WAKELOCK_TIMEOUT = 5000;
 const HW_DEFAULT_CLIENT_ID = 0;
 
+const INT32_MAX = 2147483647;
+
 const RIL_IPC_ICCMANAGER_MSG_NAMES = [
   "RIL:GetRilContext",
   "RIL:SendStkResponse",
   "RIL:SendStkMenuSelection",
   "RIL:SendStkTimerExpiration",
   "RIL:SendStkEventDownload",
   "RIL:GetCardLockState",
   "RIL:UnlockCardLock",
@@ -771,23 +773,22 @@ XPCOMUtils.defineLazyGetter(this, "gData
         newConnHandler.updateRILNetworkInterface();
       }).bind(this);
 
       if (this._dataEnabled) {
         oldSettings.oldEnabled = oldSettings.enabled;
         oldSettings.enabled = false;
       }
 
-      if (oldConnHandler.anyDataConnected()) {
+      if (oldConnHandler.deactivateDataCalls()) {
         this._pendingDataCallRequest = applyPendingDataSettings;
         if (DEBUG) {
           this.debug("_handleDataClientIdChange: existing data call(s) active" +
                      ", wait for them to get disconnected.");
         }
-        oldConnHandler.deactivateDataCalls();
         return;
       }
 
       applyPendingDataSettings();
     },
 
     _shutdown: function() {
       for (let handler of this._connectionHandlers) {
@@ -1140,28 +1141,16 @@ DataConnectionHandler.prototype = {
       if (dataCall.state != RIL.GECKO_NETWORK_STATE_UNKNOWN &&
           dataCall.state != RIL.GECKO_NETWORK_STATE_DISCONNECTED) {
         return false;
       }
     }
     return true;
   },
 
-  /**
-   * Check if there is any activated data connection.
-   */
-  anyDataConnected: function() {
-    for (let i = 0; i < this._dataCalls.length; i++) {
-      if (this._dataCalls[i].state == RIL.GECKO_NETWORK_STATE_CONNECTED) {
-        return true;
-      }
-    }
-    return false;
-  },
-
   updateApnSettings: function(newApnSettings) {
     if (!newApnSettings) {
       return;
     }
     if (this._pendingApnSettings) {
       // Change of apn settings in process, just update to the newest.
       this._pengingApnSettings = newApnSettings;
       return;
@@ -1330,27 +1319,31 @@ DataConnectionHandler.prototype = {
     }
 
     networkInterface.disconnect();
   },
 
   deactivateDataCalls: function() {
     let dataDisconnecting = false;
     this.dataNetworkInterfaces.forEach(function(networkInterface) {
-      if (networkInterface.state == RIL.GECKO_NETWORK_STATE_CONNECTED) {
+      if (networkInterface.enabled) {
+        if (networkInterface.state == RIL.GECKO_NETWORK_STATE_CONNECTED) {
+          dataDisconnecting = true;
+        }
         networkInterface.disconnect();
-        dataDisconnecting = true;
       }
     });
 
     // No data calls exist. It's safe to proceed the pending radio power off
     // request.
     if (gRadioEnabledController.isDeactivatingDataCalls() && !dataDisconnecting) {
       gRadioEnabledController.finishDeactivatingDataCalls(this.clientId);
     }
+
+    return dataDisconnecting;
   },
 
   /**
    * Handle data errors.
    */
   handleDataCallError: function(message) {
     // Notify data call error only for data APN
     let networkInterface = this.dataNetworkInterfaces.get("default");
@@ -3807,19 +3800,36 @@ DataCall.prototype = {
 
   // Holds the pdp type sent to ril worker.
   pdptype: null,
 
   // Holds the authentication type sent to ril worker.
   chappap: null,
 
   dataCallError: function(message) {
-    if (DEBUG) this.debug("Data call error on APN: " + message.apn);
+    if (DEBUG) {
+      this.debug("Data call error on APN " + message.apn + ": " +
+                 message.errorMsg + " (" + message.status + "), retry time: " +
+                 message.suggestedRetryTime);
+    }
     this.state = RIL.GECKO_NETWORK_STATE_DISCONNECTED;
-    this.retry();
+
+    if (this.requestedNetworkIfaces.length === 0) {
+      if (DEBUG) this.debug("This DataCall is not requested anymore.");
+      return;
+    }
+
+    // For suggestedRetryTime, the value of INT32_MAX(0x7fffffff) means no retry.
+    if (message.suggestedRetryTime === INT32_MAX ||
+        this.isPermanentFail(message.status, message.errorMsg)) {
+      if (DEBUG) this.debug("Data call error: no retry needed.");
+      return;
+    }
+
+    this.retry(message.suggestedRetryTime);
   },
 
   dataCallStateChanged: function(datacall) {
     if (DEBUG) {
       this.debug("Data call ID: " + datacall.cid + ", interface name: " +
                  datacall.ifname + ", APN name: " + datacall.apn + ", state: " +
                  datacall.state);
     }
@@ -3827,16 +3837,17 @@ DataCall.prototype = {
     if (this.state == datacall.state &&
         datacall.state != RIL.GECKO_NETWORK_STATE_CONNECTED) {
       return;
     }
 
     switch (datacall.state) {
       case RIL.GECKO_NETWORK_STATE_CONNECTED:
         if (this.state == RIL.GECKO_NETWORK_STATE_CONNECTING) {
+          this.apnRetryCounter = 0;
           this.linkInfo.cid = datacall.cid;
 
           if (this.requestedNetworkIfaces.length === 0) {
             if (DEBUG) {
               this.debug("State is connected, but no network interface requested" +
                          " this DataCall");
             }
             this.deactivate();
@@ -3914,16 +3925,39 @@ DataCall.prototype = {
     dump("-*- DataCall[" + this.clientId + ":" + this.apnProfile.apn + "]: " +
       s + "\n");
   },
 
   get connected() {
     return this.state == RIL.GECKO_NETWORK_STATE_CONNECTED;
   },
 
+  isPermanentFail: function(dataFailCause, errorMsg) {
+    // Check ril.h for 'no retry' data call fail causes.
+    if (errorMsg === RIL.GECKO_ERROR_RADIO_NOT_AVAILABLE ||
+        errorMsg === RIL.GECKO_ERROR_INVALID_PARAMETER ||
+        dataFailCause === RIL.DATACALL_FAIL_OPERATOR_BARRED ||
+        dataFailCause === RIL.DATACALL_FAIL_MISSING_UKNOWN_APN ||
+        dataFailCause === RIL.DATACALL_FAIL_UNKNOWN_PDP_ADDRESS_TYPE ||
+        dataFailCause === RIL.DATACALL_FAIL_USER_AUTHENTICATION ||
+        dataFailCause === RIL.DATACALL_FAIL_ACTIVATION_REJECT_GGSN ||
+        dataFailCause === RIL.DATACALL_FAIL_SERVICE_OPTION_NOT_SUPPORTED ||
+        dataFailCause === RIL.DATACALL_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED ||
+        dataFailCause === RIL.DATACALL_FAIL_NSAPI_IN_USE ||
+        dataFailCause === RIL.DATACALL_FAIL_ONLY_IPV4_ALLOWED ||
+        dataFailCause === RIL.DATACALL_FAIL_ONLY_IPV6_ALLOWED ||
+        dataFailCause === RIL.DATACALL_FAIL_PROTOCOL_ERRORS ||
+        dataFailCause === RIL.DATACALL_FAIL_RADIO_POWER_OFF ||
+        dataFailCause === RIL.DATACALL_FAIL_TETHERED_CALL_ACTIVE) {
+      return true;
+    }
+
+    return false;
+  },
+
   inRequestedTypes: function(type) {
     for (let i = 0; i < this.requestedNetworkIfaces.length; i++) {
       if (this.requestedNetworkIfaces[i].type == type) {
         return true;
       }
     }
     return false;
   },
@@ -4040,31 +4074,36 @@ DataCall.prototype = {
       user: this.apnProfile.user,
       passwd: this.apnProfile.password,
       chappap: authType,
       pdptype: pdpType
     });
     this.state = RIL.GECKO_NETWORK_STATE_CONNECTING;
   },
 
-  retry: function() {
+  retry: function(suggestedRetryTime) {
     let apnRetryTimer;
 
     // We will retry the connection in increasing times
     // based on the function: time = A * numer_of_retries^2 + B
     if (this.apnRetryCounter >= this.NETWORK_APNRETRY_MAXRETRIES) {
       this.apnRetryCounter = 0;
       this.timer = null;
       if (DEBUG) this.debug("Too many APN Connection retries - STOP retrying");
       return;
     }
 
-    apnRetryTimer = this.NETWORK_APNRETRY_FACTOR *
-                    (this.apnRetryCounter * this.apnRetryCounter) +
-                    this.NETWORK_APNRETRY_ORIGIN;
+    // If there is a valid suggestedRetryTime, override the retry timer.
+    if (suggestedRetryTime !== undefined && suggestedRetryTime >= 0) {
+      apnRetryTimer = suggestedRetryTime / 1000;
+    } else {
+      apnRetryTimer = this.NETWORK_APNRETRY_FACTOR *
+                      (this.apnRetryCounter * this.apnRetryCounter) +
+                      this.NETWORK_APNRETRY_ORIGIN;
+    }
     this.apnRetryCounter++;
     if (DEBUG) {
       this.debug("Data call - APN Connection Retry Timer (secs-counter): " +
                  apnRetryTimer + "-" + this.apnRetryCounter);
     }
 
     if (this.timer == null) {
       // Event timer for connection retries
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -4136,16 +4136,20 @@ RilObject.prototype = {
     return "identical";
   },
 
   _processDataCallList: function(datacalls, newDataCallOptions) {
     // Check for possible PDP errors: We check earlier because the datacall
     // can be removed if is the same as the current one.
     for each (let newDataCall in datacalls) {
       if (newDataCall.status != DATACALL_FAIL_NONE) {
+        if (newDataCallOptions) {
+          newDataCallOptions.status = newDataCall.status;
+          newDataCallOptions.suggestedRetryTime = newDataCall.suggestedRetryTime;
+        }
         this._sendDataCallError(newDataCallOptions || newDataCall,
                                 newDataCall.status);
       }
     }
 
     for each (let currentDataCall in this.currentDataCalls) {
       let updatedDataCall;
       if (datacalls) {
--- a/dom/webidl/MozNFC.webidl
+++ b/dom/webidl/MozNFC.webidl
@@ -37,17 +37,17 @@ interface MozNFCManager {
   /**
    * API to check if the given application's manifest
    * URL is registered with the Chrome Process or not.
    *
    * Returns success if given manifestUrl is registered for 'onpeerready',
    * otherwise error
    */
   [CheckPermissions="nfc-manager"]
-  DOMRequest checkP2PRegistration(DOMString manifestUrl);
+  Promise<boolean> checkP2PRegistration(DOMString manifestUrl);
 
   /**
    * Notify that user has accepted to share nfc message on P2P UI
    */
   [CheckPermissions="nfc-manager"]
   void notifyUserAcceptedP2P(DOMString manifestUrl);
 
   /**
@@ -55,29 +55,29 @@ interface MozNFCManager {
    */
   [CheckPermissions="nfc-manager"]
   void notifySendFileStatus(octet status, DOMString requestId);
 
   /**
    * Power on the NFC hardware and start polling for NFC tags or devices.
    */
   [CheckPermissions="nfc-manager"]
-  DOMRequest startPoll();
+  Promise<void> startPoll();
 
   /**
    * Stop polling for NFC tags or devices. i.e. enter low power mode.
    */
   [CheckPermissions="nfc-manager"]
-  DOMRequest stopPoll();
+  Promise<void> stopPoll();
 
   /**
    * Power off the NFC hardware.
    */
   [CheckPermissions="nfc-manager"]
-  DOMRequest powerOff();
+  Promise<void> powerOff();
 };
 
 [JSImplementation="@mozilla.org/navigatorNfc;1",
  NavigatorProperty="mozNfc",
  Func="Navigator::HasNFCSupport",
  CheckPermissions="nfc-read nfc-write",
  AvailableIn="CertifiedApps"]
 interface MozNFC : EventTarget {
--- a/dom/webidl/MozNFCPeer.webidl
+++ b/dom/webidl/MozNFCPeer.webidl
@@ -5,20 +5,27 @@
  * Part of this IDL file is from:
  * http://w3c.github.io/nfc/proposals/common/nfc.html#idl-def-NFCPeer
  *
  * Copyright © 2013 Deutsche Telekom, Inc.
  */
 
 [JSImplementation="@mozilla.org/nfc/NFCPeer;1", AvailableIn="CertifiedApps"]
 interface MozNFCPeer {
+  /**
+   * Send NDEF data to peer device.
+   */
   [Throws]
-  DOMRequest sendNDEF(sequence<MozNDEFRecord> records);
+  Promise<void> sendNDEF(sequence<MozNDEFRecord> records);
+
+  /**
+   * Send file to peer device.
+   */
   [Throws]
-  DOMRequest sendFile(Blob blob);
+  Promise<void> sendFile(Blob blob);
 };
 
 // Mozilla Only
 partial interface MozNFCPeer {
   [ChromeOnly]
   attribute DOMString session;
 
   /**
--- a/dom/webidl/MozNFCTag.webidl
+++ b/dom/webidl/MozNFCTag.webidl
@@ -61,27 +61,39 @@ interface MozNFCTag {
    */
   readonly attribute boolean? isFormatable;
 
   /**
    * Indicate if this tag could be made Read-Only, null if unknown.
    */
   readonly attribute boolean? canBeMadeReadOnly;
 
+  /**
+   * Read current NDEF data on the tag.
+   */
   [Throws]
-  DOMRequest readNDEF();
+  Promise<sequence<MozNDEFRecord>> readNDEF();
 
+  /**
+   * Write NDEF data to the tag.
+   */
   [Throws]
-  DOMRequest writeNDEF(sequence<MozNDEFRecord> records);
+  Promise<void> writeNDEF(sequence<MozNDEFRecord> records);
 
+  /**
+   * Make a tag read-only.
+   */
   [Throws]
-  DOMRequest makeReadOnly();
+  Promise<void> makeReadOnly();
 
+  /**
+   * Format a tag as NDEF.
+   */
   [Throws]
-  DOMRequest format();
+  Promise<void> format();
 };
 
 // Mozilla Only
 partial interface MozNFCTag {
   [ChromeOnly]
   attribute DOMString session;
 
   /**