Merge b2g-inbound to m-c a=merge CLOSED TREE
authorWes Kocher <wkocher@mozilla.com>
Fri, 10 Oct 2014 18:41:41 -0700
changeset 233058 999ad2f1e1089d203811266bc3c9bfa92308f029
parent 233024 708b45d9b1b110a8c0d21fb18975e79f64772d13 (current diff)
parent 233057 b4457e42fcc9b1c164f6107459c0cdab267671b7 (diff)
child 233122 f74ad36bb97b85909f7a3430288c07d3bf8b4e50
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone35.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge b2g-inbound to m-c a=merge CLOSED TREE
--- 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="cc5da7b055e2b06fdeb46fa94970550392ee571d"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="95f580a1522ffd0f09302372b78200dab9b6f322"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
   <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="6ca2008ac50b163d31244ef9f036cb224f4f229b"/>
--- 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="84923f1940625c47ff4c1fdf01b10fde3b7d909e">
     <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="cc5da7b055e2b06fdeb46fa94970550392ee571d"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="95f580a1522ffd0f09302372b78200dab9b6f322"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
   <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="6ca2008ac50b163d31244ef9f036cb224f4f229b"/>
   <!-- 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="cc5da7b055e2b06fdeb46fa94970550392ee571d"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="95f580a1522ffd0f09302372b78200dab9b6f322"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ca2008ac50b163d31244ef9f036cb224f4f229b"/>
   <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="cc5da7b055e2b06fdeb46fa94970550392ee571d"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="95f580a1522ffd0f09302372b78200dab9b6f322"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
   <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="6ca2008ac50b163d31244ef9f036cb224f4f229b"/>
--- 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="84923f1940625c47ff4c1fdf01b10fde3b7d909e">
     <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="cc5da7b055e2b06fdeb46fa94970550392ee571d"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="95f580a1522ffd0f09302372b78200dab9b6f322"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
   <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="6ca2008ac50b163d31244ef9f036cb224f4f229b"/>
   <!-- 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="cc5da7b055e2b06fdeb46fa94970550392ee571d"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="95f580a1522ffd0f09302372b78200dab9b6f322"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
   <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="6ca2008ac50b163d31244ef9f036cb224f4f229b"/>
--- 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="cc5da7b055e2b06fdeb46fa94970550392ee571d"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="95f580a1522ffd0f09302372b78200dab9b6f322"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ca2008ac50b163d31244ef9f036cb224f4f229b"/>
   <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": "eeeae73691f91cd5042660b0f19c84747ebc7be2", 
+    "revision": "a10638edfc562e970fa6062c06edffd581c6f057", 
     "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="84923f1940625c47ff4c1fdf01b10fde3b7d909e">
     <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="cc5da7b055e2b06fdeb46fa94970550392ee571d"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="95f580a1522ffd0f09302372b78200dab9b6f322"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
   <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="6ca2008ac50b163d31244ef9f036cb224f4f229b"/>
   <!-- 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="84923f1940625c47ff4c1fdf01b10fde3b7d909e">
     <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="cc5da7b055e2b06fdeb46fa94970550392ee571d"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="95f580a1522ffd0f09302372b78200dab9b6f322"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
   <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="cc5da7b055e2b06fdeb46fa94970550392ee571d"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="95f580a1522ffd0f09302372b78200dab9b6f322"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ca2008ac50b163d31244ef9f036cb224f4f229b"/>
   <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="84923f1940625c47ff4c1fdf01b10fde3b7d909e">
     <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="cc5da7b055e2b06fdeb46fa94970550392ee571d"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="95f580a1522ffd0f09302372b78200dab9b6f322"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
   <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="6ca2008ac50b163d31244ef9f036cb224f4f229b"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
new file mode 100644
--- /dev/null
+++ b/dom/mobileconnection/MobileCallForwardingOptions.cpp
@@ -0,0 +1,72 @@
+/* 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 "mozilla/dom/mobileconnection/MobileCallForwardingOptions.h"
+
+namespace mozilla {
+namespace dom {
+namespace mobileconnection {
+
+NS_IMPL_ISUPPORTS(MobileCallForwardingOptions, nsIMobileCallForwardingOptions)
+
+MobileCallForwardingOptions::MobileCallForwardingOptions(bool aActive,
+                                                         int16_t aAction,
+                                                         int16_t aReason,
+                                                         const nsAString& aNumber,
+                                                         int16_t aTimeSeconds,
+                                                         int16_t aServiceClass)
+  : mActive(aActive)
+  , mAction(aAction)
+  , mReason(aReason)
+  , mNumber(aNumber)
+  , mTimeSeconds(aTimeSeconds)
+  , mServiceClass(aServiceClass)
+{
+}
+
+NS_IMETHODIMP
+MobileCallForwardingOptions::GetActive(bool* aActive)
+{
+  *aActive = mActive;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MobileCallForwardingOptions::GetAction(int16_t* aAction)
+{
+  *aAction = mAction;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MobileCallForwardingOptions::GetReason(int16_t* aReason)
+{
+  *aReason = mReason;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MobileCallForwardingOptions::GetNumber(nsAString& aNumber)
+{
+  aNumber = mNumber;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MobileCallForwardingOptions::GetTimeSeconds(int16_t* aTimeSeconds)
+{
+  *aTimeSeconds = mTimeSeconds;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MobileCallForwardingOptions::GetServiceClass(int16_t *aServiceClass)
+{
+  *aServiceClass = mServiceClass;
+  return NS_OK;
+}
+
+} // namespace mobileconnection
+} // namespace dom
+} // namespace mozilla
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/dom/mobileconnection/MobileCallForwardingOptions.h
@@ -0,0 +1,44 @@
+/* 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/. */
+
+#ifndef mozilla_dom_MobileCallForwardingOptions_h
+#define mozilla_dom_MobileCallForwardingOptions_h
+
+#include "nsIMobileCallForwardingOptions.h"
+#include "nsString.h"
+#include "mozilla/Attributes.h"
+
+namespace mozilla {
+namespace dom {
+namespace mobileconnection {
+
+class MobileCallForwardingOptions MOZ_FINAL : public nsIMobileCallForwardingOptions
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIMOBILECALLFORWARDINGOPTIONS
+
+  MobileCallForwardingOptions(bool aActive, int16_t aAction,
+                              int16_t aReason, const nsAString& aNumber,
+                              int16_t aTimeSeconds, int16_t aServiceClass);
+
+private:
+  // Don't try to use the default constructor.
+  MobileCallForwardingOptions() {}
+
+  ~MobileCallForwardingOptions() {}
+
+  bool mActive;
+  int16_t mAction;
+  int16_t mReason;
+  nsString mNumber;
+  int16_t mTimeSeconds;
+  int16_t mServiceClass;
+};
+
+} // namespace mobileconnection
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_MobileCallForwardingOptions_h
\ No newline at end of file
--- a/dom/mobileconnection/MobileConnection.cpp
+++ b/dom/mobileconnection/MobileConnection.cpp
@@ -16,16 +16,19 @@
 #include "mozilla/Services.h"
 #include "nsIDOMDOMRequest.h"
 #include "nsIPermissionManager.h"
 #include "nsIVariant.h"
 #include "nsJSON.h"
 #include "nsJSUtils.h"
 #include "nsServiceManagerUtils.h"
 
+#define MOBILECONN_ERROR_INVALID_PARAMETER NS_LITERAL_STRING("InvalidParameter")
+#define MOBILECONN_ERROR_INVALID_PASSWORD  NS_LITERAL_STRING("InvalidPassword")
+
 #ifdef CONVERT_STRING_TO_NULLABLE_ENUM
 #undef CONVERT_STRING_TO_NULLABLE_ENUM
 #endif
 #define CONVERT_STRING_TO_NULLABLE_ENUM(_string, _enumType, _enum)      \
 {                                                                       \
   uint32_t i = 0;                                                       \
   for (const EnumEntry* entry = _enumType##Values::strings;             \
        entry->value;                                                    \
@@ -201,16 +204,94 @@ MobileConnection::UpdateData()
     return;
   }
 
   nsCOMPtr<nsIMobileConnectionInfo> info;
   mMobileConnection->GetData(getter_AddRefs(info));
   mData->Update(info);
 }
 
+nsresult
+MobileConnection::NotifyError(nsIDOMDOMRequest* aRequest, const nsAString& aMessage)
+{
+  nsCOMPtr<nsIDOMRequestService> rs = do_GetService(DOMREQUEST_SERVICE_CONTRACTID);
+  NS_ENSURE_TRUE(rs, NS_ERROR_FAILURE);
+
+  return rs->FireErrorAsync(aRequest, aMessage);
+}
+
+bool
+MobileConnection::IsValidPassword(const nsAString& aPassword)
+{
+  // Check valid PIN for supplementary services. See TS.22.004 clause 5.2.
+  if (aPassword.IsEmpty() || aPassword.Length() != 4) {
+    return false;
+  }
+
+  nsresult rv;
+  int32_t password = nsString(aPassword).ToInteger(&rv);
+  return NS_SUCCEEDED(rv) && password >= 0 && password <= 9999;
+}
+
+bool
+MobileConnection::IsValidCallForwardingReason(int32_t aReason)
+{
+  return aReason >= nsIMobileConnection::CALL_FORWARD_REASON_UNCONDITIONAL &&
+         aReason <= nsIMobileConnection::CALL_FORWARD_REASON_ALL_CONDITIONAL_CALL_FORWARDING;
+}
+
+bool
+MobileConnection::IsValidCallForwardingAction(int32_t aAction)
+{
+  return aAction >= nsIMobileConnection::CALL_FORWARD_ACTION_DISABLE &&
+         aAction <= nsIMobileConnection::CALL_FORWARD_ACTION_ERASURE &&
+         // Set operation doesn't allow "query" action.
+         aAction != nsIMobileConnection::CALL_FORWARD_ACTION_QUERY_STATUS;
+}
+
+bool
+MobileConnection::IsValidCallBarringProgram(int32_t aProgram)
+{
+  return aProgram >= nsIMobileConnection::CALL_BARRING_PROGRAM_ALL_OUTGOING &&
+         aProgram <= nsIMobileConnection::CALL_BARRING_PROGRAM_INCOMING_ROAMING;
+}
+
+bool
+MobileConnection::IsValidCallBarringOptions(const MozCallBarringOptions& aOptions,
+                                           bool isSetting)
+{
+  if (!aOptions.mServiceClass.WasPassed() || aOptions.mServiceClass.Value().IsNull() ||
+      !aOptions.mProgram.WasPassed() || aOptions.mProgram.Value().IsNull() ||
+      !IsValidCallBarringProgram(aOptions.mProgram.Value().Value())) {
+    return false;
+  }
+
+  // For setting callbarring options, |enabled| and |password| are required.
+  if (isSetting &&
+      (!aOptions.mEnabled.WasPassed() || aOptions.mEnabled.Value().IsNull() ||
+       !aOptions.mPassword.WasPassed() || aOptions.mPassword.Value().IsVoid())) {
+    return false;
+  }
+
+  return true;
+}
+
+bool
+MobileConnection::IsValidCallForwardingOptions(const MozCallForwardingOptions& aOptions)
+{
+  if (!aOptions.mReason.WasPassed() || aOptions.mReason.Value().IsNull() ||
+      !aOptions.mAction.WasPassed() || aOptions.mAction.Value().IsNull() ||
+      !IsValidCallForwardingReason(aOptions.mReason.Value().Value()) ||
+      !IsValidCallForwardingAction(aOptions.mAction.Value().Value())) {
+    return false;
+  }
+
+  return true;
+}
+
 // WebIDL interface
 
 void
 MobileConnection::GetLastKnownNetwork(nsString& aRetVal) const
 {
   aRetVal.SetIsVoid(true);
 
   if (!mMobileConnection) {
@@ -563,16 +644,26 @@ already_AddRefed<DOMRequest>
 MobileConnection::GetCallForwardingOption(uint16_t aReason, ErrorResult& aRv)
 {
   if (!mMobileConnection) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+
+  if (!IsValidCallForwardingReason(aReason)) {
+    nsresult rv = NotifyError(request, MOBILECONN_ERROR_INVALID_PARAMETER);
+    if (NS_FAILED(rv)) {
+      aRv.Throw(rv);
+      return nullptr;
+    }
+    return request.forget();
+  }
+
   nsRefPtr<MobileConnectionCallback> requestCallback =
     new MobileConnectionCallback(GetOwner(), request);
 
   nsresult rv = mMobileConnection->GetCallForwarding(aReason, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
@@ -584,34 +675,52 @@ already_AddRefed<DOMRequest>
 MobileConnection::SetCallForwardingOption(const MozCallForwardingOptions& aOptions,
                                           ErrorResult& aRv)
 {
   if (!mMobileConnection) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  AutoJSAPI jsapi;
-  if (!NS_WARN_IF(jsapi.Init(GetOwner()))) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+
+  if (!IsValidCallForwardingOptions(aOptions)) {
+    nsresult rv = NotifyError(request, MOBILECONN_ERROR_INVALID_PARAMETER);
+    if (NS_FAILED(rv)) {
+      aRv.Throw(rv);
+      return nullptr;
+    }
+    return request.forget();
   }
 
-  JSContext *cx = jsapi.cx();
-  JS::Rooted<JS::Value> options(cx);
-  if (!ToJSValue(cx, aOptions, &options)) {
-    aRv.Throw(NS_ERROR_TYPE_ERR);
-    return nullptr;
+  // Fill in optional attributes.
+  uint16_t timeSeconds = 0;
+  if (aOptions.mTimeSeconds.WasPassed() && !aOptions.mTimeSeconds.Value().IsNull()) {
+    timeSeconds = aOptions.mTimeSeconds.Value().Value();
+  }
+  uint16_t serviceClass = nsIMobileConnection::ICC_SERVICE_CLASS_NONE;
+  if (aOptions.mServiceClass.WasPassed() && !aOptions.mServiceClass.Value().IsNull()) {
+    serviceClass = aOptions.mServiceClass.Value().Value();
+  }
+  nsAutoString number;
+  if (aOptions.mNumber.WasPassed()) {
+    number = aOptions.mNumber.Value();
+  } else {
+    number.SetIsVoid(true);
   }
 
-  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
   nsRefPtr<MobileConnectionCallback> requestCallback =
     new MobileConnectionCallback(GetOwner(), request);
 
-  nsresult rv = mMobileConnection->SetCallForwarding(options, requestCallback);
+  nsresult rv = mMobileConnection->SetCallForwarding(aOptions.mAction.Value().Value(),
+                                                     aOptions.mReason.Value().Value(),
+                                                     number,
+                                                     timeSeconds,
+                                                     serviceClass,
+                                                     requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
   return request.forget();
 }
 
@@ -619,34 +728,42 @@ already_AddRefed<DOMRequest>
 MobileConnection::GetCallBarringOption(const MozCallBarringOptions& aOptions,
                                        ErrorResult& aRv)
 {
   if (!mMobileConnection) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  AutoJSAPI jsapi;
-  if (!NS_WARN_IF(jsapi.Init(GetOwner()))) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+
+  if (!IsValidCallBarringOptions(aOptions, false)) {
+    nsresult rv = NotifyError(request, MOBILECONN_ERROR_INVALID_PARAMETER);
+    if (NS_FAILED(rv)) {
+      aRv.Throw(rv);
+      return nullptr;
+    }
+    return request.forget();
   }
 
-  JSContext *cx = jsapi.cx();
-  JS::Rooted<JS::Value> options(cx);
-  if (!ToJSValue(cx, aOptions, &options)) {
-    aRv.Throw(NS_ERROR_TYPE_ERR);
-    return nullptr;
+  // Fill in optional attributes.
+  nsAutoString password;
+  if (aOptions.mPassword.WasPassed()) {
+    password = aOptions.mPassword.Value();
+  } else {
+    password.SetIsVoid(true);
   }
 
-  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
   nsRefPtr<MobileConnectionCallback> requestCallback =
     new MobileConnectionCallback(GetOwner(), request);
 
-  nsresult rv = mMobileConnection->GetCallBarring(options, requestCallback);
+  nsresult rv = mMobileConnection->GetCallBarring(aOptions.mProgram.Value().Value(),
+                                                  password,
+                                                  aOptions.mServiceClass.Value().Value(),
+                                                  requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
   return request.forget();
 }
 
@@ -654,34 +771,35 @@ already_AddRefed<DOMRequest>
 MobileConnection::SetCallBarringOption(const MozCallBarringOptions& aOptions,
                                        ErrorResult& aRv)
 {
   if (!mMobileConnection) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  AutoJSAPI jsapi;
-  if (!NS_WARN_IF(jsapi.Init(GetOwner()))) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+
+  if (!IsValidCallBarringOptions(aOptions, true)) {
+    nsresult rv = NotifyError(request, MOBILECONN_ERROR_INVALID_PARAMETER);
+    if (NS_FAILED(rv)) {
+      aRv.Throw(rv);
+      return nullptr;
+    }
+    return request.forget();
   }
 
-  JSContext *cx = jsapi.cx();
-  JS::Rooted<JS::Value> options(cx);
-  if (!ToJSValue(cx, aOptions, &options)) {
-    aRv.Throw(NS_ERROR_TYPE_ERR);
-    return nullptr;
-  }
-
-  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
   nsRefPtr<MobileConnectionCallback> requestCallback =
     new MobileConnectionCallback(GetOwner(), request);
 
-  nsresult rv = mMobileConnection->SetCallBarring(options, requestCallback);
+  nsresult rv = mMobileConnection->SetCallBarring(aOptions.mProgram.Value().Value(),
+                                                  aOptions.mEnabled.Value().Value(),
+                                                  aOptions.mPassword.Value(),
+                                                  aOptions.mServiceClass.Value().Value(),
+                                                  requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
   return request.forget();
 }
 
@@ -689,35 +807,37 @@ already_AddRefed<DOMRequest>
 MobileConnection::ChangeCallBarringPassword(const MozCallBarringOptions& aOptions,
                                             ErrorResult& aRv)
 {
   if (!mMobileConnection) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  AutoJSAPI jsapi;
-  if (!NS_WARN_IF(jsapi.Init(GetOwner()))) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+
+  if (!aOptions.mPin.WasPassed() || aOptions.mPin.Value().IsVoid() ||
+      !aOptions.mNewPin.WasPassed() || aOptions.mNewPin.Value().IsVoid() ||
+      !IsValidPassword(aOptions.mPin.Value()) ||
+      !IsValidPassword(aOptions.mNewPin.Value())) {
+    nsresult rv = NotifyError(request, MOBILECONN_ERROR_INVALID_PASSWORD);
+    if (NS_FAILED(rv)) {
+      aRv.Throw(rv);
+      return nullptr;
+    }
+    return request.forget();
   }
 
-  JSContext *cx = jsapi.cx();
-  JS::Rooted<JS::Value> options(cx);
-  if (!ToJSValue(cx, aOptions, &options)) {
-    aRv.Throw(NS_ERROR_TYPE_ERR);
-    return nullptr;
-  }
-
-  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
   nsRefPtr<MobileConnectionCallback> requestCallback =
     new MobileConnectionCallback(GetOwner(), request);
 
   nsresult rv =
-    mMobileConnection->ChangeCallBarringPassword(options, requestCallback);
+    mMobileConnection->ChangeCallBarringPassword(aOptions.mPin.Value(),
+                                                 aOptions.mNewPin.Value(),
+                                                 requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
   return request.forget();
 }
 
--- a/dom/mobileconnection/MobileConnection.h
+++ b/dom/mobileconnection/MobileConnection.h
@@ -171,14 +171,35 @@ private:
   bool
   CheckPermission(const char* aType) const;
 
   void
   UpdateVoice();
 
   void
   UpdateData();
+
+  nsresult
+  NotifyError(nsIDOMDOMRequest* aRequest, const nsAString& aMessage);
+
+  bool
+  IsValidPassword(const nsAString& aPassword);
+
+  bool
+  IsValidCallBarringOptions(const MozCallBarringOptions& aOptions, bool isSetting);
+
+  bool
+  IsValidCallForwardingOptions(const MozCallForwardingOptions& aOptions);
+
+  bool
+  IsValidCallForwardingReason(int32_t aReason);
+
+  bool
+  IsValidCallForwardingAction(int32_t aAction);
+
+  bool
+  IsValidCallBarringProgram(int32_t aProgram);
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_MobileConnection_h
--- a/dom/mobileconnection/MobileConnectionCallback.cpp
+++ b/dom/mobileconnection/MobileConnectionCallback.cpp
@@ -23,104 +23,16 @@ MobileConnectionCallback::MobileConnecti
   , mRequest(aRequest)
 {
 }
 
 /**
  * Notify Success for Send/CancelMmi.
  */
 nsresult
-MobileConnectionCallback::NotifySendCancelMmiSuccess(const nsAString& aServiceCode,
-                                                     const nsAString& aStatusMessage)
-{
-  MozMMIResult result;
-  result.mServiceCode.Assign(aServiceCode);
-  result.mStatusMessage.Assign(aStatusMessage);
-
-  return NotifySendCancelMmiSuccess(result);
-}
-
-nsresult
-MobileConnectionCallback::NotifySendCancelMmiSuccess(const nsAString& aServiceCode,
-                                                     const nsAString& aStatusMessage,
-                                                     JS::Handle<JS::Value> aAdditionalInformation)
-{
-  AutoJSAPI jsapi;
-  if (!NS_WARN_IF(jsapi.Init(mWindow))) {
-    return NS_ERROR_FAILURE;
-  }
-
-  JSContext* cx = jsapi.cx();
-  RootedDictionary<MozMMIResult> result(cx);
-
-  result.mServiceCode.Assign(aServiceCode);
-  result.mStatusMessage.Assign(aStatusMessage);
-  result.mAdditionalInformation.Construct().SetAsObject() = &aAdditionalInformation.toObject();
-
-  return NotifySendCancelMmiSuccess(result);
-}
-
-nsresult
-MobileConnectionCallback::NotifySendCancelMmiSuccess(const nsAString& aServiceCode,
-                                                     const nsAString& aStatusMessage,
-                                                     uint16_t aAdditionalInformation)
-{
-  MozMMIResult result;
-  result.mServiceCode.Assign(aServiceCode);
-  result.mStatusMessage.Assign(aStatusMessage);
-  result.mAdditionalInformation.Construct().SetAsUnsignedShort() = aAdditionalInformation;
-
-  return NotifySendCancelMmiSuccess(result);
-}
-
-nsresult
-MobileConnectionCallback::NotifySendCancelMmiSuccess(const nsAString& aServiceCode,
-                                                     const nsAString& aStatusMessage,
-                                                     const nsTArray<nsString>& aAdditionalInformation)
-{
-  AutoJSAPI jsapi;
-  if (!NS_WARN_IF(jsapi.Init(mWindow))) {
-    return NS_ERROR_FAILURE;
-  }
-
-  JSContext* cx = jsapi.cx();
-  JS::Rooted<JS::Value> additionalInformation(cx);
-
-  if (!ToJSValue(cx, aAdditionalInformation, &additionalInformation)) {
-    JS_ClearPendingException(cx);
-    return NS_ERROR_TYPE_ERR;
-  }
-
-  return NotifySendCancelMmiSuccess(aServiceCode, aStatusMessage,
-                                    additionalInformation);
-}
-
-nsresult
-MobileConnectionCallback::NotifySendCancelMmiSuccess(const nsAString& aServiceCode,
-                                                     const nsAString& aStatusMessage,
-                                                     const nsTArray<IPC::MozCallForwardingOptions>& aAdditionalInformation)
-{
-  AutoJSAPI jsapi;
-  if (!NS_WARN_IF(jsapi.Init(mWindow))) {
-    return NS_ERROR_FAILURE;
-  }
-
-  JSContext* cx = jsapi.cx();
-  JS::Rooted<JS::Value> additionalInformation(cx);
-
-  if (!ToJSValue(cx, aAdditionalInformation, &additionalInformation)) {
-    JS_ClearPendingException(cx);
-    return NS_ERROR_TYPE_ERR;
-  }
-
-  return NotifySendCancelMmiSuccess(aServiceCode, aStatusMessage,
-                                    additionalInformation);
-}
-
-nsresult
 MobileConnectionCallback::NotifySendCancelMmiSuccess(const MozMMIResult& aResult)
 {
   AutoJSAPI jsapi;
   if (!NS_WARN_IF(jsapi.Init(mWindow))) {
     return NS_ERROR_FAILURE;
   }
 
   JSContext* cx = jsapi.cx();
@@ -130,38 +42,16 @@ MobileConnectionCallback::NotifySendCanc
     JS_ClearPendingException(cx);
     return NS_ERROR_TYPE_ERR;
   }
 
   return NotifySuccess(jsResult);
 }
 
 /**
- * Notify Success for GetCallForwarding.
- */
-nsresult
-MobileConnectionCallback::NotifyGetCallForwardingSuccess(const nsTArray<IPC::MozCallForwardingOptions>& aResults)
-{
-  AutoJSAPI jsapi;
-  if (!NS_WARN_IF(jsapi.Init(mWindow))) {
-    return NS_ERROR_FAILURE;
-  }
-
-  JSContext* cx = jsapi.cx();
-  JS::Rooted<JS::Value> jsResult(cx);
-
-  if (!ToJSValue(cx, aResults, &jsResult)) {
-    JS_ClearPendingException(cx);
-    return NS_ERROR_TYPE_ERR;
-  }
-
-  return NotifySuccess(jsResult);
-}
-
-/**
  * Notify Success.
  */
 nsresult
 MobileConnectionCallback::NotifySuccess(JS::Handle<JS::Value> aResult)
 {
   nsCOMPtr<nsIDOMRequestService> rs = do_GetService(DOMREQUEST_SERVICE_CONTRACTID);
   NS_ENSURE_TRUE(rs, NS_ERROR_FAILURE);
 
@@ -225,28 +115,196 @@ MobileConnectionCallback::NotifyGetNetwo
   if (!ToJSValue(cx, results, &jsResult)) {
     JS_ClearPendingException(cx);
     return NS_ERROR_TYPE_ERR;
   }
 
   return NotifySuccess(jsResult);
 }
 
-NS_IMETHODIMP
-MobileConnectionCallback::NotifySendCancelMmiSuccess(JS::Handle<JS::Value> aResult,
-                                                     JSContext* aCx)
+nsresult
+MobileConnectionCallback::NotifySendCancelMmiSuccess(const nsAString& aServiceCode,
+                                                     const nsAString& aStatusMessage)
+{
+  MozMMIResult result;
+  result.mServiceCode.Assign(aServiceCode);
+  result.mStatusMessage.Assign(aStatusMessage);
+
+  return NotifySendCancelMmiSuccess(result);
+}
+
+nsresult
+MobileConnectionCallback::NotifySendCancelMmiSuccessWithInteger(const nsAString& aServiceCode,
+                                                                const nsAString& aStatusMessage,
+                                                                uint16_t aAdditionalInformation)
+{
+  MozMMIResult result;
+  result.mServiceCode.Assign(aServiceCode);
+  result.mStatusMessage.Assign(aStatusMessage);
+  result.mAdditionalInformation.Construct().SetAsUnsignedShort() = aAdditionalInformation;
+
+  return NotifySendCancelMmiSuccess(result);
+}
+
+nsresult
+MobileConnectionCallback::NotifySendCancelMmiSuccessWithStrings(const nsAString& aServiceCode,
+                                                                const nsAString& aStatusMessage,
+                                                                uint32_t aCount,
+                                                                const char16_t** aAdditionalInformation)
 {
-  return NotifySuccess(aResult);
+  AutoJSAPI jsapi;
+  if (!NS_WARN_IF(jsapi.Init(mWindow))) {
+    return NS_ERROR_FAILURE;
+  }
+
+  JSContext* cx = jsapi.cx();
+  RootedDictionary<MozMMIResult> result(cx);
+
+  result.mServiceCode.Assign(aServiceCode);
+  result.mStatusMessage.Assign(aStatusMessage);
+
+  nsTArray<nsString> additionalInformation;
+  for (uint32_t i = 0; i < aCount; i++) {
+    additionalInformation.AppendElement(nsDependentString(aAdditionalInformation[i]));
+  }
+
+  JS::Rooted<JS::Value> jsAdditionalInformation(cx);
+  if (!ToJSValue(cx, additionalInformation, &jsAdditionalInformation)) {
+    JS_ClearPendingException(cx);
+    return NS_ERROR_TYPE_ERR;
+  }
+
+  result.mAdditionalInformation.Construct().SetAsObject() =
+    &jsAdditionalInformation.toObject();
+
+  return NotifySendCancelMmiSuccess(result);
+}
+
+nsresult
+MobileConnectionCallback::NotifySendCancelMmiSuccessWithCallForwardingOptions(
+                                                                const nsAString& aServiceCode,
+                                                                const nsAString& aStatusMessage,
+                                                                uint32_t aCount,
+                                                                nsIMobileCallForwardingOptions** aResults)
+{
+  AutoJSAPI jsapi;
+  if (!NS_WARN_IF(jsapi.Init(mWindow))) {
+    return NS_ERROR_FAILURE;
+  }
+
+  JSContext* cx = jsapi.cx();
+  RootedDictionary<MozMMIResult> result(cx);
+
+  result.mServiceCode.Assign(aServiceCode);
+  result.mStatusMessage.Assign(aStatusMessage);
+
+  nsTArray<MozCallForwardingOptions> additionalInformation;
+  for (uint32_t i = 0; i < aCount; i++)
+  {
+    MozCallForwardingOptions options;
+    int16_t pShort;
+    nsString pString;
+    bool pBool;
+
+    aResults[i]->GetActive(&pBool);
+    options.mActive.Construct(pBool);
+
+    aResults[i]->GetAction(&pShort);
+    if (pShort != nsIMobileConnection::CALL_FORWARD_ACTION_UNKNOWN) {
+      options.mAction.Construct(pShort);
+    }
+
+    aResults[i]->GetReason(&pShort);
+    if (pShort != nsIMobileConnection::CALL_FORWARD_REASON_UNKNOWN) {
+      options.mReason.Construct(pShort);
+    }
+
+    aResults[i]->GetNumber(pString);
+    options.mNumber.Construct(pString.get());
+
+    aResults[i]->GetTimeSeconds(&pShort);
+    if (pShort >= 0) {
+      options.mTimeSeconds.Construct(pShort);
+    }
+
+    aResults[i]->GetServiceClass(&pShort);
+    if (pShort != nsIMobileConnection::ICC_SERVICE_CLASS_NONE) {
+      options.mServiceClass.Construct(pShort);
+    }
+
+    additionalInformation.AppendElement(options);
+  }
+
+  JS::Rooted<JS::Value> jsAdditionalInformation(cx);
+  if (!ToJSValue(cx, additionalInformation, &jsAdditionalInformation)) {
+    JS_ClearPendingException(cx);
+    return NS_ERROR_TYPE_ERR;
+  }
+
+  result.mAdditionalInformation.Construct().SetAsObject() =
+    &jsAdditionalInformation.toObject();
+
+  return NotifySendCancelMmiSuccess(result);
 }
 
 NS_IMETHODIMP
-MobileConnectionCallback::NotifyGetCallForwardingSuccess(JS::Handle<JS::Value> aResults,
-                                                         JSContext* aCx)
+MobileConnectionCallback::NotifyGetCallForwardingSuccess(uint32_t aCount,
+                                                         nsIMobileCallForwardingOptions** aResults)
 {
-  return NotifySuccess(aResults);
+  nsTArray<MozCallForwardingOptions> results;
+  for (uint32_t i = 0; i < aCount; i++)
+  {
+    MozCallForwardingOptions result;
+    int16_t pShort;
+    nsString pString;
+    bool pBool;
+
+    aResults[i]->GetActive(&pBool);
+    result.mActive.Construct(pBool);
+
+    aResults[i]->GetAction(&pShort);
+    if (pShort != nsIMobileConnection::CALL_FORWARD_ACTION_UNKNOWN) {
+      result.mAction.Construct(pShort);
+    }
+
+    aResults[i]->GetReason(&pShort);
+    if (pShort != nsIMobileConnection::CALL_FORWARD_REASON_UNKNOWN) {
+      result.mReason.Construct(pShort);
+    }
+
+    aResults[i]->GetNumber(pString);
+    result.mNumber.Construct(pString.get());
+
+    aResults[i]->GetTimeSeconds(&pShort);
+    if (pShort >= 0) {
+      result.mTimeSeconds.Construct(pShort);
+    }
+
+    aResults[i]->GetServiceClass(&pShort);
+    if (pShort != nsIMobileConnection::ICC_SERVICE_CLASS_NONE) {
+      result.mServiceClass.Construct(pShort);
+    }
+
+    results.AppendElement(result);
+  }
+
+  AutoJSAPI jsapi;
+  if (!NS_WARN_IF(jsapi.Init(mWindow))) {
+    return NS_ERROR_FAILURE;
+  }
+
+  JSContext* cx = jsapi.cx();
+  JS::Rooted<JS::Value> jsResult(cx);
+
+  if (!ToJSValue(cx, results, &jsResult)) {
+    JS_ClearPendingException(cx);
+    return NS_ERROR_TYPE_ERR;
+  }
+
+  return NotifySuccess(jsResult);
 }
 
 NS_IMETHODIMP
 MobileConnectionCallback::NotifyGetCallBarringSuccess(uint16_t aProgram,
                                                       bool aEnabled,
                                                       uint16_t aServiceClass)
 {
   MozCallBarringOptions result;
--- a/dom/mobileconnection/MobileConnectionCallback.h
+++ b/dom/mobileconnection/MobileConnectionCallback.h
@@ -27,53 +27,25 @@ namespace mobileconnection {
 class MobileConnectionCallback MOZ_FINAL : public nsIMobileConnectionCallback
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIMOBILECONNECTIONCALLBACK
 
   MobileConnectionCallback(nsPIDOMWindow* aWindow, DOMRequest* aRequest);
 
-  /**
-   * Notify Success for Send/CancelMmi.
-   */
-  nsresult
-  NotifySendCancelMmiSuccess(const nsAString& aServiceCode,
-                             const nsAString& aStatusMessage);
-  nsresult
-  NotifySendCancelMmiSuccess(const nsAString& aServiceCode,
-                             const nsAString& aStatusMessage,
-                             JS::Handle<JS::Value> aAdditionalInformation);
-  nsresult
-  NotifySendCancelMmiSuccess(const nsAString& aServiceCode,
-                             const nsAString& aStatusMessage,
-                             uint16_t aAdditionalInformation);
-  nsresult
-  NotifySendCancelMmiSuccess(const nsAString& aServiceCode,
-                             const nsAString& aStatusMessage,
-                             const nsTArray<nsString>& aAdditionalInformation);
-  nsresult
-  NotifySendCancelMmiSuccess(const nsAString& aServiceCode,
-                             const nsAString& aStatusMessage,
-                             const nsTArray<IPC::MozCallForwardingOptions>& aAdditionalInformation);
-  nsresult
-  NotifySendCancelMmiSuccess(const MozMMIResult& aResult);
-
-  /**
-   * Notify Success for GetCallForwarding.
-   */
-  nsresult
-  NotifyGetCallForwardingSuccess(const nsTArray<IPC::MozCallForwardingOptions>& aResults);
-
 private:
   ~MobileConnectionCallback() {}
 
   nsresult
   NotifySuccess(JS::Handle<JS::Value> aResult);
 
+  nsresult
+  NotifySendCancelMmiSuccess(const MozMMIResult& aResult);
+
   nsCOMPtr<nsPIDOMWindow> mWindow;
   nsRefPtr<DOMRequest> mRequest;
 };
 
 } // namespace mobileconnection
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/mobileconnection/gonk/MobileConnectionService.js
+++ b/dom/mobileconnection/gonk/MobileConnectionService.js
@@ -20,16 +20,18 @@ const GONK_MOBILECONNECTIONSERVICE_CONTR
 const GONK_MOBILECONNECTIONSERVICE_CID =
   Components.ID("{0c9c1a96-2c72-4c55-9e27-0ca73eb16f63}");
 const MOBILECONNECTIONINFO_CID =
   Components.ID("{8162b3c0-664b-45f6-96cd-f07b4e193b0e}");
 const MOBILENETWORKINFO_CID =
   Components.ID("{a6c8416c-09b4-46d1-bf29-6520d677d085}");
 const MOBILECELLINFO_CID =
   Components.ID("{0635d9ab-997e-4cdf-84e7-c1883752dff3}");
+const MOBILECALLFORWARDINGOPTIONS_CID =
+  Components.ID("{e0cf4463-ee63-4b05-ab2e-d94bf764836c}");
 const TELEPHONYCALLBACK_CID =
   Components.ID("{6e1af17e-37f3-11e4-aed3-60a44c237d2b}");
 
 const NS_XPCOM_SHUTDOWN_OBSERVER_ID      = "xpcom-shutdown";
 const NS_PREFBRANCH_PREFCHANGE_TOPIC_ID  = "nsPref:changed";
 const NS_NETWORK_ACTIVE_CHANGED_TOPIC_ID = "network-active-changed";
 
 const kPrefRilDebuggingEnabled = "ril.debugging.enabled";
@@ -107,60 +109,91 @@ MobileConnectionInfo.prototype = {
   roaming: false,
   network: null,
   cell: null,
   type: null,
   signalStrength: null,
   relSignalStrength: null
 };
 
-function CallForwardingOptions(aOptions) {
-  this.active = aOptions.active;
-  this.action = aOptions.action;
-  this.reason = aOptions.reason;
-  this.number = aOptions.number;
-  this.timeSeconds = aOptions.timeSeconds;
-  this.serviceClass = aOptions.serviceClass;
+function MobileCallForwardingOptions(aOptions) {
+  for (let key in aOptions) {
+    this[key] = aOptions[key];
+  }
 }
-CallForwardingOptions.prototype = {
-  __exposedProps__ : {active: 'r',
-                      action: 'r',
-                      reason: 'r',
-                      number: 'r',
-                      timeSeconds: 'r',
-                      serviceClass: 'r'},
-};
+MobileCallForwardingOptions.prototype = {
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIMobileCallForwardingOptions]),
+  classID: MOBILECALLFORWARDINGOPTIONS_CID,
+  classInfo: XPCOMUtils.generateCI({
+    classID:          MOBILECALLFORWARDINGOPTIONS_CID,
+    classDescription: "MobileCallForwardingOptions",
+    interfaces:       [Ci.nsIMobileCallForwardingOptions]
+  }),
 
-function MMIResult(aOptions) {
-  this.serviceCode = aOptions.serviceCode;
-  this.statusMessage = aOptions.statusMessage;
-  this.additionalInformation = aOptions.additionalInformation;
+  // nsIMobileForwardingOptions
+
+  active: false,
+  action: Ci.nsIMobileConnection.CALL_FORWARD_ACTION_UNKNOWN,
+  reason: Ci.nsIMobileConnection.CALL_FORWARD_REASON_UNKNOWN,
+  number: null,
+  timeSeconds: -1,
+  serviceClass: Ci.nsIMobileConnection.ICC_SERVICE_CLASS_NONE
 }
-MMIResult.prototype = {
-  __exposedProps__ : {serviceCode: 'r',
-                      statusMessage: 'r',
-                      additionalInformation: 'r'},
-};
 
 /**
  * Wrap a MobileConnectionCallback to a TelephonyCallback.
  */
 function TelephonyCallback(aCallback) {
   this.callback = aCallback;
 }
 TelephonyCallback.prototype = {
   QueryInterface:   XPCOMUtils.generateQI([Ci.nsITelephonyCallback]),
   classID:          TELEPHONYCALLBACK_CID,
 
+  _notifySendCancelMmiSuccess: function(aResult) {
+    // No additional information.
+    if (aResult.additionalInformation === undefined) {
+      this.callback.notifySendCancelMmiSuccess(aResult.serviceCode,
+                                               aResult.statusMessage);
+      return;
+    }
+
+    // Additional information is an integer.
+    if (!isNaN(parseInt(aResult.additionalInformation, 10))) {
+      this.callback.notifySendCancelMmiSuccessWithInteger(
+        aResult.serviceCode, aResult.statusMessage, aResult.additionalInformation);
+      return;
+    }
+
+    // Additional information should be an array.
+    let array = aResult.additionalInformation;
+    if (Array.isArray(array) && array.length > 0) {
+      let item = array[0];
+      if (typeof item === "string" || item instanceof String) {
+        this.callback.notifySendCancelMmiSuccessWithStrings(
+          aResult.serviceCode, aResult.statusMessage,
+          aResult.additionalInformation.length, aResult.additionalInformation);
+        return;
+      }
+
+      this.callback.notifySendCancelMmiSuccessWithCallForwardingOptions(
+        aResult.serviceCode, aResult.statusMessage,
+        aResult.additionalInformation.length, aResult.additionalInformation);
+      return;
+    }
+
+    throw Cr.NS_ERROR_UNEXPECTED;
+  },
+
   notifyDialMMI: function(mmiServiceCode) {
     this.serviceCode = mmiServiceCode;
   },
 
   notifyDialMMISuccess: function(result) {
-    this.callback.notifySendCancelMmiSuccess(result);
+    this._notifySendCancelMmiSuccess(result);
   },
 
   notifyDialMMIError: function(error) {
     this.callback.notifyError(error, "", this.serviceCode);
   },
 
   notifyDialMMIErrorWithInfo: function(error, info) {
     this.callback.notifyError(error, "", this.serviceCode, info);
@@ -251,82 +284,16 @@ MobileConnectionProvider.prototype = {
     }
     if (DEBUG) {
       this._debug("Supported Network Types: " + supportedNetworkTypes);
     }
     return supportedNetworkTypes;
   },
 
   /**
-   * Helper for guarding us against invalid reason values for call forwarding.
-   */
-  _isValidCallForwardingReason: function(aReason) {
-    switch (aReason) {
-      case Ci.nsIMobileConnection.CALL_FORWARD_REASON_UNCONDITIONAL:
-      case Ci.nsIMobileConnection.CALL_FORWARD_REASON_MOBILE_BUSY:
-      case Ci.nsIMobileConnection.CALL_FORWARD_REASON_NO_REPLY:
-      case Ci.nsIMobileConnection.CALL_FORWARD_REASON_NOT_REACHABLE:
-      case Ci.nsIMobileConnection.CALL_FORWARD_REASON_ALL_CALL_FORWARDING:
-      case Ci.nsIMobileConnection.CALL_FORWARD_REASON_ALL_CONDITIONAL_CALL_FORWARDING:
-        return true;
-      default:
-        return false;
-    }
-  },
-
-  /**
-   * Helper for guarding us against invalid action values for call forwarding.
-   */
-  _isValidCallForwardingAction: function(aAction) {
-    switch (aAction) {
-      case Ci.nsIMobileConnection.CALL_FORWARD_ACTION_DISABLE:
-      case Ci.nsIMobileConnection.CALL_FORWARD_ACTION_ENABLE:
-      case Ci.nsIMobileConnection.CALL_FORWARD_ACTION_REGISTRATION:
-      case Ci.nsIMobileConnection.CALL_FORWARD_ACTION_ERASURE:
-        return true;
-      default:
-        return false;
-    }
-  },
-
-  /**
-   * Helper for guarding us against invalid program values for call barring.
-   */
-  _isValidCallBarringProgram: function(aProgram) {
-    switch (aProgram) {
-      case Ci.nsIMobileConnection.CALL_BARRING_PROGRAM_ALL_OUTGOING:
-      case Ci.nsIMobileConnection.CALL_BARRING_PROGRAM_OUTGOING_INTERNATIONAL:
-      case Ci.nsIMobileConnection.CALL_BARRING_PROGRAM_OUTGOING_INTERNATIONAL_EXCEPT_HOME:
-      case Ci.nsIMobileConnection.CALL_BARRING_PROGRAM_ALL_INCOMING:
-      case Ci.nsIMobileConnection.CALL_BARRING_PROGRAM_INCOMING_ROAMING:
-        return true;
-      default:
-        return false;
-    }
-  },
-
-  /**
-   * Helper for guarding us against invalid options for call barring.
-   */
-  _isValidCallBarringOptions: function(aOptions, aUsedForSetting) {
-    if (!aOptions || aOptions.serviceClass == null ||
-        !this._isValidCallBarringProgram(aOptions.program)) {
-      return false;
-    }
-
-    // For setting callbarring options, |enabled| and |password| are required.
-    if (aUsedForSetting &&
-        (aOptions.enabled == null || aOptions.password == null)) {
-      return false;
-    }
-
-    return true;
-  },
-
-  /**
    * Helper for guarding us against invalid mode for clir.
    */
   _isValidClirMode: function(aMode) {
     switch (aMode) {
       case Ci.nsIMobileConnection.CLIR_DEFAULT:
       case Ci.nsIMobileConnection.CLIR_INVOCATION:
       case Ci.nsIMobileConnection.CLIR_SUPPRESSION:
         return true;
@@ -418,17 +385,17 @@ MobileConnectionProvider.prototype = {
         isUpdated = true;
         aDestInfo[key] = aSrcInfo[key];
       }
     }
     return isUpdated;
   },
 
   _rulesToCallForwardingOptions: function(aRules) {
-    return aRules.map(rule => new CallForwardingOptions(rule));
+    return aRules.map(rule => new MobileCallForwardingOptions(rule));
   },
 
   _dispatchNotifyError: function(aCallback, aErrorMsg) {
     Services.tm.currentThread.dispatch(() => aCallback.notifyError(aErrorMsg),
                                        Ci.nsIThread.DISPATCH_NORMAL);
   },
 
   registerListener: function(aListener) {
@@ -737,30 +704,23 @@ MobileConnectionProvider.prototype = {
         return false;
       }
 
       aCallback.notifySuccess();
       return false;
     }).bind(this));
   },
 
-  setCallForwarding: function(aOptions, aCallback) {
-    if (!aOptions ||
-        !this._isValidCallForwardingReason(aOptions.reason) ||
-        !this._isValidCallForwardingAction(aOptions.action)){
-      this._dispatchNotifyError(aCallback, RIL.GECKO_ERROR_INVALID_PARAMETER);
-      return;
-    }
-
+  setCallForwarding: function(aAction, aReason, aNumber, aTimeSeconds,
+                              aServiceClass, aCallback) {
     let options = {
-      active: aOptions.active,
-      action: aOptions.action,
-      reason: aOptions.reason,
-      number: aOptions.number,
-      timeSeconds: aOptions.timeSeconds,
+      action: aAction,
+      reason: aReason,
+      number: aNumber,
+      timeSeconds: aTimeSeconds,
       serviceClass: RIL.ICC_SERVICE_CLASS_VOICE
     };
 
     this._radioInterface.sendWorkerMessage("setCallForward", options,
                                            (function(aResponse) {
       if (aResponse.errorMsg) {
         aCallback.notifyError(aResponse.errorMsg);
         return false;
@@ -770,97 +730,76 @@ MobileConnectionProvider.prototype = {
                                 aResponse.number, aResponse.timeSeconds,
                                 aResponse.serviceClass);
       aCallback.notifySuccess();
       return false;
     }).bind(this));
   },
 
   getCallForwarding: function(aReason, aCallback) {
-    if (!this._isValidCallForwardingReason(aReason)){
-      this._dispatchNotifyError(aCallback, RIL.GECKO_ERROR_INVALID_PARAMETER);
-      return;
-    }
-
     this._radioInterface.sendWorkerMessage("queryCallForwardStatus",
                                            {reason: aReason},
                                            (function(aResponse) {
       if (aResponse.errorMsg) {
         aCallback.notifyError(aResponse.errorMsg);
         return false;
       }
 
-      aCallback.notifyGetCallForwardingSuccess(
-        this._rulesToCallForwardingOptions(aResponse.rules));
+      let infos = this._rulesToCallForwardingOptions(aResponse.rules);
+      aCallback.notifyGetCallForwardingSuccess(infos.length, infos);
       return false;
     }).bind(this));
   },
 
-  setCallBarring: function(aOptions, aCallback) {
-    if (!this._isValidCallBarringOptions(aOptions, true)) {
-      this._dispatchNotifyError(aCallback, RIL.GECKO_ERROR_INVALID_PARAMETER);
-      return;
-    }
-
+  setCallBarring: function(aProgram, aEnabled, aPassword, aServiceClass,
+                           aCallback) {
     let options = {
-      program: aOptions.program,
-      enabled: aOptions.enabled,
-      password: aOptions.password,
-      serviceClass: aOptions.serviceClass
+      program: aProgram,
+      enabled: aEnabled,
+      password: aPassword,
+      serviceClass: aServiceClass
     };
 
     this._radioInterface.sendWorkerMessage("setCallBarring", options,
                                            (function(aResponse) {
       if (aResponse.errorMsg) {
         aCallback.notifyError(aResponse.errorMsg);
         return false;
       }
 
       aCallback.notifySuccess();
       return false;
     }).bind(this));
   },
 
-  getCallBarring: function(aOptions, aCallback) {
-    if (!this._isValidCallBarringOptions(aOptions)) {
-      this._dispatchNotifyError(aCallback, RIL.GECKO_ERROR_INVALID_PARAMETER);
-      return;
-    }
-
+  getCallBarring: function(aProgram, aPassword, aServiceClass, aCallback) {
     let options = {
-      program: aOptions.program,
-      password: aOptions.password,
-      serviceClass: aOptions.serviceClass
+      program: aProgram,
+      password: aPassword,
+      serviceClass: aServiceClass
     };
 
     this._radioInterface.sendWorkerMessage("queryCallBarringStatus", options,
                                            (function(aResponse) {
       if (aResponse.errorMsg) {
         aCallback.notifyError(aResponse.errorMsg);
         return false;
       }
 
       aCallback.notifyGetCallBarringSuccess(aResponse.program,
                                             aResponse.enabled,
                                             aResponse.serviceClass);
       return false;
     }).bind(this));
   },
 
-  changeCallBarringPassword: function(aOptions, aCallback) {
-    // Checking valid PIN for supplementary services. See TS.22.004 clause 5.2.
-    if (aOptions.pin == null || !aOptions.pin.match(/^\d{4}$/) ||
-        aOptions.newPin == null || !aOptions.newPin.match(/^\d{4}$/)) {
-      this._dispatchNotifyError(aCallback, "InvalidPassword");
-      return;
-    }
-
+  changeCallBarringPassword: function(aPin, aNewPin, aCallback) {
     let options = {
-      pin: aOptions.pin,
-      newPin: aOptions.newPin
+      pin: aPin,
+      newPin: aNewPin
     };
 
     this._radioInterface.sendWorkerMessage("changeCallBarringPassword", options,
                                            (function(aResponse) {
       if (aResponse.errorMsg) {
         aCallback.notifyError(aResponse.errorMsg);
         return false;
       }
new file mode 100644
--- /dev/null
+++ b/dom/mobileconnection/interfaces/nsIMobileCallForwardingOptions.idl
@@ -0,0 +1,51 @@
+/* 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"
+
+[scriptable, uuid(c616ecb6-65f5-441e-b97e-c642ddef6888)]
+interface nsIMobileCallForwardingOptions : nsISupports
+{
+  /**
+   * Call forwarding rule status.
+   *
+   * It will be either not active (false), or active (true).
+   *
+   * Note: Unused for setting call forwarding options. It reports
+   *       the status of the rule when getting how the rule is
+   *       configured.
+   *
+   * @see 3GPP TS 27.007 7.11 "status".
+   */
+  readonly attribute bool active;
+
+  /**
+   * Indicates what to do with the rule. It shall be one of the
+   * nsIMobileConnection.CALL_FORWARD_ACTION_* values.
+   */
+  readonly attribute short action;
+
+  /**
+   * Indicates the reason the call is being forwarded. It shall be one of the
+   * nsIMobileConnection.CALL_FORWARD_REASON_* values.
+   */
+  readonly attribute short reason;
+
+  /**
+   * Phone number of forwarding address.
+   */
+  readonly attribute DOMString number;
+
+  /**
+   * When "no reply" is enabled or queried, this gives the time in
+   * seconds to wait before call is forwarded.
+   */
+  readonly attribute short timeSeconds;
+
+  /**
+   * Service for which the call forward is set up. It should be one of the
+   * nsIMobileConnection.ICC_SERVICE_CLASS_* values.
+   */
+  readonly attribute short serviceClass;
+};
--- a/dom/mobileconnection/interfaces/nsIMobileConnectionService.idl
+++ b/dom/mobileconnection/interfaces/nsIMobileConnectionService.idl
@@ -1,20 +1,21 @@
 /* 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"
 
+interface nsIMobileCallForwardingOptions;
 interface nsIMobileConnection;
 interface nsIMobileConnectionInfo;
 interface nsIMobileNetworkInfo;
 interface nsIVariant;
 
-[scriptable, uuid(bc0d4d76-fd3a-4593-818f-cb6ff87fbb55)]
+[scriptable, uuid(823d935e-8262-47ed-8429-8203096b2ff4)]
 interface nsIMobileConnectionListener : nsISupports
 {
   /**
    * Notify when voice info is changed.
    */
   void notifyVoiceChanged();
 
   /**
@@ -42,25 +43,25 @@ interface nsIMobileConnectionListener : 
   void notifyDataError(in DOMString message);
 
   /**
    * Notify when call forwarding state is changed.
    *
    * @param success
    *        Indicates whether the set call forwarding request is success.
    * @param action
-   *        One of the nsIMobileConnectionService.CALL_FORWARD_ACTION_* values.
+   *        One of the nsIMobileConnection.CALL_FORWARD_ACTION_* values.
    * @param reason
-   *        One of the nsIMobileConnectionService.CALL_FORWARD_REASON_* values.
+   *        One of the nsIMobileConnection.CALL_FORWARD_REASON_* values.
    * @param number
    *        Phone number of forwarding address.
    * @param timeSeconds
    *        The time in seconds should wait before call is forwarded.
    * @param serviceClass
-   *        One of the nsIMobileConnectionService.ICC_SERVICE_CLASS_* values.
+   *        One of the nsIMobileConnection.ICC_SERVICE_CLASS_* values.
    */
   void notifyCFStateChanged(in boolean success,
                             in unsigned short action,
                             in unsigned short reason,
                             in DOMString number,
                             in unsigned short timeSeconds,
                             in unsigned short serviceClass);
 
@@ -95,17 +96,17 @@ interface nsIMobileConnectionListener : 
    * Notify when radio state is changed.
    */
   void notifyRadioStateChanged();
 
   /**
    * Notify when clir mode is changed.
    *
    * @param mode
-   *        One of the nsIMobileConnectionService.CLIR_* values.
+   *        One of the nsIMobileConnection.CLIR_* values.
    */
   void notifyClirModeChanged(in unsigned long mode);
 
   /**
    * Notify when last known network is changed.
    */
   void notifyLastKnownNetworkChanged();
 
@@ -119,36 +120,51 @@ interface nsIMobileConnectionListener : 
    */
   void notifyNetworkSelectionModeChanged();
 };
 
 %{C++
 #define NO_ADDITIONAL_INFORMATION 0
 %}
 
-[scriptable, builtinclass, uuid(7f2dbbe0-42f2-11e4-916c-0800200c9a66)]
+[scriptable, builtinclass, uuid(05568ae9-9873-46c6-9acd-0f6994cde756)]
 interface nsIMobileConnectionCallback : nsISupports
 {
   /**
    * notify*Success*() will be called, when request is succeed.
    */
   void notifySuccess();
 
   void notifySuccessWithString(in DOMString result);
 
   void notifySuccessWithBoolean(in boolean result);
 
   void notifyGetNetworksSuccess(in uint32_t count,
                                 [array, size_is(count)] in nsIMobileNetworkInfo networks);
 
-  [implicit_jscontext]
-  void notifySendCancelMmiSuccess(in jsval result /* MozMMIResult */);
+  void notifySendCancelMmiSuccess(in DOMString aServiceCode,
+                                  in DOMString aStatusMessage);
+
+  void notifySendCancelMmiSuccessWithInteger(in DOMString aServiceCode,
+                                             in DOMString aStatusMessage,
+                                             in unsigned short aAdditionalInformation);
 
-  [implicit_jscontext]
-  void notifyGetCallForwardingSuccess(in jsval results /* Array of MozCallForwardingOptions */);
+  void notifySendCancelMmiSuccessWithStrings(in DOMString aServiceCode,
+                                             in DOMString aStatusMessage,
+                                             in unsigned long aLength,
+                                             [array, size_is(aLength)] in wstring aAdditionalInformation);
+
+  void notifySendCancelMmiSuccessWithCallForwardingOptions(in DOMString aServiceCode,
+                                                           in DOMString aStatusMessage,
+                                                           in unsigned long aLength,
+                                                           [array, size_is(aLength)] in nsIMobileCallForwardingOptions aAdditionalInformation);
+
+  void notifyGetCallForwardingSuccess(in uint32_t count,
+                                      [array, size_is(count)] in nsIMobileCallForwardingOptions results);
+
 
   void notifyGetCallBarringSuccess(in unsigned short program,
                                    in boolean enabled,
                                    in unsigned short serviceClass);
 
   void notifyGetClirStatusSuccess(in unsigned short n, in unsigned short m);
 
   /**
@@ -213,55 +229,62 @@ interface nsIMobileConnectionService : n
 
 %{C++
 template<typename T> struct already_AddRefed;
 
 already_AddRefed<nsIMobileConnectionService>
 NS_CreateMobileConnectionService();
 %}
 
-[scriptable, uuid(04db7331-54fe-4cf7-9347-b9481350f4c2)]
+[scriptable, uuid(1b76ccbf-dbc2-4b74-a62a-73ea91599afa)]
 interface nsIMobileConnection : nsISupports
 {
+  /*
+   * ICC service class.
+   */
+  const long ICC_SERVICE_CLASS_NONE       = 0; // not available
   const long ICC_SERVICE_CLASS_VOICE      = (1 << 0);
   const long ICC_SERVICE_CLASS_DATA       = (1 << 1);
   const long ICC_SERVICE_CLASS_FAX        = (1 << 2);
   const long ICC_SERVICE_CLASS_SMS        = (1 << 3);
   const long ICC_SERVICE_CLASS_DATA_SYNC  = (1 << 4);
   const long ICC_SERVICE_CLASS_DATA_ASYNC = (1 << 5);
   const long ICC_SERVICE_CLASS_PACKET     = (1 << 6);
   const long ICC_SERVICE_CLASS_PAD        = (1 << 7);
   const long ICC_SERVICE_CLASS_MAX        = (1 << 7);
 
   /**
    * Call forwarding action.
    *
    * @see 3GPP TS 27.007 7.11 "mode".
    */
+  const long CALL_FORWARD_ACTION_UNKNOWN      = -1; // not available
   const long CALL_FORWARD_ACTION_DISABLE      = 0;
   const long CALL_FORWARD_ACTION_ENABLE       = 1;
   const long CALL_FORWARD_ACTION_QUERY_STATUS = 2;
   const long CALL_FORWARD_ACTION_REGISTRATION = 3;
   const long CALL_FORWARD_ACTION_ERASURE      = 4;
 
   /**
    * Call forwarding reason.
    *
    * @see 3GPP TS 27.007 7.11 "reason".
    */
+  const long CALL_FORWARD_REASON_UNKNOWN                         = -1; // not available
   const long CALL_FORWARD_REASON_UNCONDITIONAL                   = 0;
   const long CALL_FORWARD_REASON_MOBILE_BUSY                     = 1;
   const long CALL_FORWARD_REASON_NO_REPLY                        = 2;
   const long CALL_FORWARD_REASON_NOT_REACHABLE                   = 3;
   const long CALL_FORWARD_REASON_ALL_CALL_FORWARDING             = 4;
   const long CALL_FORWARD_REASON_ALL_CONDITIONAL_CALL_FORWARDING = 5;
 
   /**
    * Call barring program.
    */
+  const long CALL_BARRING_PROGRAM_UNKNOWN                            = -1; // not available
   const long CALL_BARRING_PROGRAM_ALL_OUTGOING                       = 0;
   const long CALL_BARRING_PROGRAM_OUTGOING_INTERNATIONAL             = 1;
   const long CALL_BARRING_PROGRAM_OUTGOING_INTERNATIONAL_EXCEPT_HOME = 2;
   const long CALL_BARRING_PROGRAM_ALL_INCOMING                       = 3;
   const long CALL_BARRING_PROGRAM_INCOMING_ROAMING                   = 4;
 
   /**
    * Calling line identification restriction constants.
@@ -487,132 +510,156 @@ interface nsIMobileConnection : nsISuppo
    * Send a MMI message.
    *
    * @param mmi
    *        DOMString containing an MMI string that can be associated to a
    *        USSD request or other RIL functionality.
    * @param requestCallback
    *        Called when request is finished.
    *
-   * If successful, the notifySendCancelMmiSuccess() will be called. And the
+   * If successful, the notifySendCancelMmiSuccess*() will be called. And the
    * result will contain the information about the mmi operation.
    *
    * Otherwise, the notifyError() will be called.
    */
   void sendMMI(in DOMString mmi,
                in nsIMobileConnectionCallback requestCallback);
 
   /**
    * Cancel the current MMI request if one exists.
    *
    * @param requestCallback
    *        Called when request is finished.
    *
-   * If successful, the notifySendCancelMmiSuccess() will be called. And the
+   * If successful, the notifySendCancelMmiSuccess*() will be called. And the
    * result will contain the information about the mmi operation.
    *
    * Otherwise, the notifyError() will be called.
    */
   void cancelMMI(in nsIMobileConnectionCallback requestCallback);
 
   /**
    * Queries current call forwarding options.
    *
    * @param reason
    *        Indicates the reason the call is being forwarded. It shall be one of
    *        the nsIMobileConnectionService.CALL_FORWARD_REASON_* values.
    * @param requestCallback
    *        Called when request is finished.
    *
    * If successful, the notifyGetCallForwardingSuccess() will be called. And the
-   * result will be an array of MozCallForwardingOptions.
-   * @see MozCallForwardingOptions for the detail of result.
+   * result will be an array of nsIMobileCallForwardingOptions.
+   * @see nsIMobileCallForwardingOptions for the detail of result.
    *
    * Otherwise, the notifyError() will be called, and the error will be either
    * 'RadioNotAvailable', 'RequestNotSupported', 'InvalidParameter',
    * 'IllegalSIMorME', or 'GenericFailure'.
    */
   void getCallForwarding(in unsigned short reason,
                          in nsIMobileConnectionCallback requestCallback);
 
   /**
    * Configures call forwarding options.
    *
-   * @param options
-   *        An object containing the call forward rule to set.
-   * @see MozCallForwardingOptions for the detail of options.
+   * @param action
+   *        One of the nsIMobileConnection.CALL_FORWARD_ACTION_* values.
+   * @param reason
+   *        One of the nsIMobileConnection.CALL_FORWARD_REASON_* values.
+   * @param number
+   *        Phone number of forwarding address.
+   * @param timeSeconds
+   *        When "no reply" is enabled or queried, this gives the time in
+   *        seconds to wait before call is forwarded.
+   * @param serviceClass
+   *        One of the nsIMobileConnection.ICC_SERVICE_CLASS_* values.
    * @param requestCallback
    *        Called when request is finished.
    *
    * If successful, the notifySuccess() will be called.
    *
    * Otherwise, the notifyError() will be called, and the error will be either
    * 'RadioNotAvailable', 'RequestNotSupported', 'InvalidParameter',
    * 'IllegalSIMorME', or 'GenericFailure'.
    */
-  void setCallForwarding(in jsval options,
+  void setCallForwarding(in unsigned short action,
+                         in unsigned short reason,
+                         in DOMString number,
+                         in unsigned short timeSeconds,
+                         in unsigned short serviceClass,
                          in nsIMobileConnectionCallback requestCallback);
 
   /**
    * Queries current call barring status.
    *
-   * @param options
-   *        An object containing the call barring rule to query. No need to
-   *        specify 'enabled' property.
-   * @see MozCallBarringOptions for the detail of options.
+   * @param program
+   *        One of the nsIMobileConnection.CALL_BARRING_PROGRAM_* values.
+   * @param password
+   *        Call barring password. Use "" if no password specified.
+   * @param serviceClass
+   *        One of the nsIMobileConnection.ICC_SERVICE_CLASS_* values.
    * @param requestCallback
    *        Called when request is finished.
    *
    * If successful, the notifyGetCallBarringSuccess() will be called. And the
    * result will contain correct 'enabled' property indicating the status of
    * this rule.
    *
    * Otherwise, the notifyError() will be called, and the error will be either
    * 'RadioNotAvailable', 'RequestNotSupported', 'InvalidParameter',
    * 'IllegalSIMorME', or 'GenericFailure'.
    */
-  void getCallBarring(in jsval options,
+  void getCallBarring(in unsigned short program,
+                      in DOMString password,
+                      in unsigned short serviceClass,
                       in nsIMobileConnectionCallback requestCallback);
 
   /**
    * Configures call barring option.
    *
-   * @param options
-   *        An object containing the call barring rule to set.
-   * @see MozCallBarringOptions for the detail of options.
+   * @param program
+   *        One of the nsIMobileConnection.CALL_BARRING_PROGRAM_* values.
+   * @param enabled
+   *        Enable or disable the call barring program.
+   * @param password
+   *        Call barring password. Use "" if no password specified.
+   * @param serviceClass
+   *        One of the nsIMobileConnection.ICC_SERVICE_CLASS_* values.
    * @param requestCallback
    *        Called when request is finished.
    *
    * If successful, the notifySuccess() will be called.
    *
    * Otherwise, the notifyError() will be called, and the error will be either
    * 'RadioNotAvailable', 'RequestNotSupported', 'InvalidParameter',
    * 'IllegalSIMorME', or 'GenericFailure'.
    */
-  void setCallBarring(in jsval options,
+  void setCallBarring(in unsigned short program,
+                      in bool enabled,
+                      in DOMString password,
+                      in unsigned short serviceClass,
                       in nsIMobileConnectionCallback requestCallback);
 
   /**
    * Change call barring facility password.
    *
-   * @param options
-   *        An object containing information about pin and newPin, and,
-   *        this object must have both "pin" and "newPin" attributes
-   *        to change the call barring facility password.
-   * @see MozCallBarringOptions for the detail of options.
+   * @param pin
+   *        Old call barring password.
+   * @param newPin
+   *        New call barring password.
    * @param requestCallback
    *        Called when request is finished.
    *
    * If successful, the notifySuccess() will be called.
    *
    * Otherwise, the notifyError() will be called, and the error will be either
    * 'RadioNotAvailable', 'RequestNotSupported', 'InvalidParameter',
    * 'IllegalSIMorME', or 'GenericFailure'.
    */
-  void changeCallBarringPassword(in jsval options,
+  void changeCallBarringPassword(in DOMString pin,
+                                 in DOMString newPin,
                                  in nsIMobileConnectionCallback requestCallback);
 
   /**
    * Configures call waiting options.
    *
    * @param enabled
    *        Boolean indicates the desired call waiting status.
    * @param requestCallback
@@ -642,17 +689,17 @@ interface nsIMobileConnection : nsISuppo
    */
   void getCallWaiting(in nsIMobileConnectionCallback requestCallback);
 
   /**
    * Enables or disables the presentation of the calling line identity (CLI) to
    * the called party when originating a call.
    *
    * @param clirMode
-   *        One of the nsIMobileConnectionService.CLIR_* values.
+   *        One of the nsIMobileConnection.CLIR_* values.
    * @param requestCallback
    *        Called when request is finished.
    *
    * If successful, the notifySuccess() will be called.
    *
    * Otherwise, the notifyError() will be called, and the error will be either
    * 'RadioNotAvailable', 'RequestNotSupported', 'InvalidParameter',
    * 'IllegalSIMorME', or 'GenericFailure'.
--- a/dom/mobileconnection/ipc/MobileConnectionChild.cpp
+++ b/dom/mobileconnection/ipc/MobileConnectionChild.cpp
@@ -234,96 +234,69 @@ MobileConnectionChild::SendMMI(const nsA
 
 NS_IMETHODIMP
 MobileConnectionChild::CancelMMI(nsIMobileConnectionCallback* aCallback)
 {
   return SendRequest(CancelMmiRequest(), aCallback) ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
-MobileConnectionChild::SetCallForwarding(JS::Handle<JS::Value> aOptions,
+MobileConnectionChild::SetCallForwarding(uint16_t aAction, uint16_t aReason,
+                                         const nsAString& aNumber,
+                                         uint16_t aTimeSeconds, uint16_t aServiceClass,
                                          nsIMobileConnectionCallback* aCallback)
 {
-  AutoJSAPI jsapi;
-  if (!NS_WARN_IF(jsapi.Init(&aOptions.toObject()))) {
-    return NS_ERROR_FAILURE;
-  }
-
-  JSContext* cx = jsapi.cx();
-  IPC::MozCallForwardingOptions options;
-  if(!options.Init(cx, aOptions)) {
-    return NS_ERROR_TYPE_ERR;
-  }
-
-  return SendRequest(SetCallForwardingRequest(options), aCallback)
+  return SendRequest(SetCallForwardingRequest(aAction, aReason,
+                                              nsString(aNumber),
+                                              aTimeSeconds, aServiceClass),
+                     aCallback)
     ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 MobileConnectionChild::GetCallForwarding(uint16_t aReason,
                                          nsIMobileConnectionCallback* aCallback)
 {
   return SendRequest(GetCallForwardingRequest(aReason), aCallback)
     ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
-MobileConnectionChild::SetCallBarring(JS::Handle<JS::Value> aOptions,
+MobileConnectionChild::SetCallBarring(uint16_t aProgram, bool aEnabled,
+                                      const nsAString& aPassword,
+                                      uint16_t aServiceClass,
                                       nsIMobileConnectionCallback* aCallback)
 {
-  AutoJSAPI jsapi;
-  if (!NS_WARN_IF(jsapi.Init(&aOptions.toObject()))) {
-    return NS_ERROR_FAILURE;
-  }
-
-  JSContext* cx = jsapi.cx();
-  IPC::MozCallBarringOptions options;
-  if(!options.Init(cx, aOptions)) {
-    return NS_ERROR_TYPE_ERR;
-  }
-
-  return SendRequest(SetCallBarringRequest(options), aCallback)
+  return SendRequest(SetCallBarringRequest(aProgram, aEnabled,
+                                           nsString(aPassword),
+                                           aServiceClass),
+                     aCallback)
     ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
-MobileConnectionChild::GetCallBarring(JS::Handle<JS::Value> aOptions,
+MobileConnectionChild::GetCallBarring(uint16_t aProgram,
+                                      const nsAString& aPassword,
+                                      uint16_t aServiceClass,
                                       nsIMobileConnectionCallback* aCallback)
 {
-  AutoJSAPI jsapi;
-  if (!NS_WARN_IF(jsapi.Init(&aOptions.toObject()))) {
-    return NS_ERROR_FAILURE;
-  }
-
-  JSContext* cx = jsapi.cx();
-  IPC::MozCallBarringOptions options;
-  if(!options.Init(cx, aOptions)) {
-    return NS_ERROR_TYPE_ERR;
-  }
-
-  return SendRequest(GetCallBarringRequest(options), aCallback)
+  return SendRequest(GetCallBarringRequest(aProgram, nsString(aPassword),
+                                           aServiceClass),
+                     aCallback)
     ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
-MobileConnectionChild::ChangeCallBarringPassword(JS::Handle<JS::Value> aOptions,
+MobileConnectionChild::ChangeCallBarringPassword(const nsAString& aPin,
+                                                 const nsAString& aNewPin,
                                                  nsIMobileConnectionCallback* aCallback)
 {
-  AutoJSAPI jsapi;
-  if (!NS_WARN_IF(jsapi.Init(&aOptions.toObject()))) {
-    return NS_ERROR_FAILURE;
-  }
-
-  JSContext* cx = jsapi.cx();
-  IPC::MozCallBarringOptions options;
-  if(!options.Init(cx, aOptions)) {
-    return NS_ERROR_TYPE_ERR;
-  }
-
-  return SendRequest(ChangeCallBarringPasswordRequest(options), aCallback)
+  return SendRequest(ChangeCallBarringPasswordRequest(nsString(aPin),
+                                                      nsString(aNewPin)),
+                     aCallback)
     ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 MobileConnectionChild::SetCallWaiting(bool aEnabled,
                                       nsIMobileConnectionCallback* aCallback)
 {
   return SendRequest(SetCallWaitingRequest(aEnabled), aCallback)
@@ -592,49 +565,77 @@ MobileConnectionRequestChild::DoReply(co
 
 bool
 MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccessMmi& aReply)
 {
   nsAutoString serviceCode(aReply.serviceCode());
   nsAutoString statusMessage(aReply.statusMessage());
   AdditionalInformation info(aReply.additionalInformation());
 
-  nsRefPtr<MobileConnectionCallback> callback = static_cast<MobileConnectionCallback*>(mRequestCallback.get());
-
-
   // Handle union types
   switch (info.type()) {
     case AdditionalInformation::Tvoid_t:
-      return NS_SUCCEEDED(callback->NotifySendCancelMmiSuccess(serviceCode,
-                                                               statusMessage));
+      return NS_SUCCEEDED(mRequestCallback->NotifySendCancelMmiSuccess(serviceCode,
+                                                                       statusMessage));
+
     case AdditionalInformation::Tuint16_t:
-      return NS_SUCCEEDED(callback->NotifySendCancelMmiSuccess(serviceCode,
-                                                               statusMessage,
-                                                               info.get_uint16_t()));
-    case AdditionalInformation::TArrayOfnsString:
-      return NS_SUCCEEDED(callback->NotifySendCancelMmiSuccess(serviceCode,
-                                                               statusMessage,
-                                                               info.get_ArrayOfnsString()));
-    case AdditionalInformation::TArrayOfMozCallForwardingOptions:
-      return NS_SUCCEEDED(callback->NotifySendCancelMmiSuccess(serviceCode,
-                                                               statusMessage,
-                                                               info.get_ArrayOfMozCallForwardingOptions()));
+      return NS_SUCCEEDED(mRequestCallback->NotifySendCancelMmiSuccessWithInteger(
+        serviceCode, statusMessage, info.get_uint16_t()));
+
+    case AdditionalInformation::TArrayOfnsString: {
+      uint32_t count = info.get_ArrayOfnsString().Length();
+      const nsTArray<nsString>& additionalInformation = info.get_ArrayOfnsString();
+
+      nsAutoArrayPtr<const char16_t*> additionalInfoPtrs(new const char16_t*[count]);
+      for (size_t i = 0; i < count; ++i) {
+        additionalInfoPtrs[i] = additionalInformation[i].get();
+      }
+
+      return NS_SUCCEEDED(mRequestCallback->NotifySendCancelMmiSuccessWithStrings(
+        serviceCode, statusMessage, count, additionalInfoPtrs));
+    }
+
+    case AdditionalInformation::TArrayOfnsMobileCallForwardingOptions: {
+      uint32_t count = info.get_ArrayOfnsMobileCallForwardingOptions().Length();
+
+      nsTArray<nsCOMPtr<nsIMobileCallForwardingOptions>> results;
+      for (uint32_t i = 0; i < count; i++) {
+        // Use dont_AddRef here because these instances are already AddRef-ed in
+        // MobileConnectionIPCSerializer.h
+        nsCOMPtr<nsIMobileCallForwardingOptions> item = dont_AddRef(
+          info.get_ArrayOfnsMobileCallForwardingOptions()[i]);
+        results.AppendElement(item);
+      }
+
+      return NS_SUCCEEDED(mRequestCallback->NotifySendCancelMmiSuccessWithCallForwardingOptions(
+        serviceCode, statusMessage, count,
+        const_cast<nsIMobileCallForwardingOptions**>(info.get_ArrayOfnsMobileCallForwardingOptions().Elements())));
+    }
 
     default:
       MOZ_CRASH("Received invalid type!");
   }
 
   return false;
 }
 
 bool
 MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccessCallForwarding& aReply)
 {
-  nsRefPtr<MobileConnectionCallback> callback = static_cast<MobileConnectionCallback*>(mRequestCallback.get());
-  return NS_SUCCEEDED(callback->NotifyGetCallForwardingSuccess(aReply.results()));
+  uint32_t count = aReply.results().Length();
+  nsTArray<nsCOMPtr<nsIMobileCallForwardingOptions>> results;
+  for (uint32_t i = 0; i < count; i++) {
+    // Use dont_AddRef here because these instances are already AddRef-ed in
+    // MobileConnectionIPCSerializer.h
+    nsCOMPtr<nsIMobileCallForwardingOptions> item = dont_AddRef(aReply.results()[i]);
+    results.AppendElement(item);
+  }
+
+  return NS_SUCCEEDED(mRequestCallback->NotifyGetCallForwardingSuccess(
+    count, const_cast<nsIMobileCallForwardingOptions**>(aReply.results().Elements())));
 }
 
 bool
 MobileConnectionRequestChild::DoReply(const MobileConnectionReplySuccessCallBarring& aReply)
 {
   return NS_SUCCEEDED(mRequestCallback->NotifyGetCallBarringSuccess(aReply.program(),
                                                                     aReply.enabled(),
                                                                     aReply.serviceClass()));
--- a/dom/mobileconnection/ipc/MobileConnectionIPCSerializer.h
+++ b/dom/mobileconnection/ipc/MobileConnectionIPCSerializer.h
@@ -1,29 +1,32 @@
 /* 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/. */
 
 #ifndef mozilla_dom_mobileconnection_MobileConnectionIPCSerialiser_h
 #define mozilla_dom_mobileconnection_MobileConnectionIPCSerialiser_h
 
 #include "ipc/IPCMessageUtils.h"
+#include "mozilla/dom/mobileconnection/MobileCallForwardingOptions.h"
 #include "mozilla/dom/MobileCellInfo.h"
 #include "mozilla/dom/MobileConnectionInfo.h"
 #include "mozilla/dom/MobileNetworkInfo.h"
 #include "mozilla/dom/MozMobileConnectionBinding.h"
 
 using mozilla::AutoJSContext;
+using mozilla::dom::mobileconnection::MobileCallForwardingOptions;
 using mozilla::dom::MobileNetworkInfo;
 using mozilla::dom::MobileCellInfo;
 using mozilla::dom::MobileConnectionInfo;
 
 typedef nsIMobileCellInfo* nsMobileCellInfo;
 typedef nsIMobileConnectionInfo* nsMobileConnectionInfo;
 typedef nsIMobileNetworkInfo* nsMobileNetworkInfo;
+typedef nsIMobileCallForwardingOptions* nsMobileCallForwardingOptions;
 
 namespace IPC {
 
 struct MozCallForwardingOptions : public mozilla::dom::MozCallForwardingOptions
 {
   bool operator==(const MozCallForwardingOptions& aOther) const
   {
     return // Compare mActive
@@ -48,37 +51,93 @@ struct MozCallForwardingOptions : public
              mTimeSeconds.Value() == aOther.mTimeSeconds.Value())) &&
            // Compare mServiceClass
            ((!mServiceClass.WasPassed() && !aOther.mServiceClass.WasPassed()) ||
             (mServiceClass.WasPassed() && aOther.mServiceClass.WasPassed() &&
              mServiceClass.Value() == aOther.mServiceClass.Value()));
   };
 };
 
-struct MozCallBarringOptions : mozilla::dom::MozCallBarringOptions
+template <>
+struct ParamTraits<nsIMobileCallForwardingOptions*>
 {
-  bool operator==(const MozCallBarringOptions& aOther) const
+  typedef nsIMobileCallForwardingOptions* paramType;
+
+  // Function to serialize a MobileCallForwardingOptions.
+  static void Write(Message *aMsg, const paramType& aParam)
   {
-    return // Compare mEnabled
-           ((!mEnabled.WasPassed() && !aOther.mEnabled.WasPassed()) ||
-            (mEnabled.WasPassed() && aOther.mEnabled.WasPassed() &&
-             mEnabled.Value() == aOther.mEnabled.Value())) &&
-           // Compare mPassword
-           ((!mPassword.WasPassed() && !aOther.mPassword.WasPassed()) ||
-            (mPassword.WasPassed() && aOther.mPassword.WasPassed() &&
-             mPassword.Value() == aOther.mPassword.Value())) &&
-           // Compare mProgram
-           ((!mProgram.WasPassed() && !aOther.mProgram.WasPassed()) ||
-            (mProgram.WasPassed() && aOther.mProgram.WasPassed() &&
-             mProgram.Value() == aOther.mProgram.Value())) &&
-           // Compare mServiceClass
-           ((!mServiceClass.WasPassed() && !aOther.mServiceClass.WasPassed()) ||
-            (mServiceClass.WasPassed() && aOther.mServiceClass.WasPassed() &&
-             mServiceClass.Value() == aOther.mServiceClass.Value()));
-  };
+    bool isNull = !aParam;
+    WriteParam(aMsg, isNull);
+    // If it is a null object, then we are done.
+    if (isNull) {
+      return;
+    }
+
+    int16_t pShort;
+    nsString pString;
+    bool pBool;
+
+    aParam->GetActive(&pBool);
+    WriteParam(aMsg, pBool);
+
+    aParam->GetAction(&pShort);
+    WriteParam(aMsg, pShort);
+
+    aParam->GetReason(&pShort);
+    WriteParam(aMsg, pShort);
+
+    aParam->GetNumber(pString);
+    WriteParam(aMsg, pString);
+
+    aParam->GetTimeSeconds(&pShort);
+    WriteParam(aMsg, pShort);
+
+    aParam->GetServiceClass(&pShort);
+    WriteParam(aMsg, pShort);
+  }
+
+  // Function to de-serialize a MobileCallForwardingOptions.
+  static bool Read(const Message *aMsg, void **aIter, paramType* aResult)
+  {
+    // Check if is the null pointer we have transfered.
+    bool isNull;
+    if (!ReadParam(aMsg, aIter, &isNull)) {
+      return false;
+    }
+
+    if (isNull) {
+      *aResult = nullptr;
+      return true;
+    }
+
+    bool active;
+    int16_t action;
+    int16_t reason;
+    nsString number;
+    int16_t timeSeconds;
+    int16_t serviceClass;
+
+    // It's not important to us where it fails, but rather if it fails
+    if (!(ReadParam(aMsg, aIter, &active) &&
+          ReadParam(aMsg, aIter, &action) &&
+          ReadParam(aMsg, aIter, &reason) &&
+          ReadParam(aMsg, aIter, &number) &&
+          ReadParam(aMsg, aIter, &timeSeconds) &&
+          ReadParam(aMsg, aIter, &serviceClass))) {
+      return false;
+    }
+
+    *aResult = new MobileCallForwardingOptions(active, action, reason,
+                                               number, timeSeconds, serviceClass);
+
+    // We release this ref after receiver finishes processing.
+    NS_ADDREF(*aResult);
+
+    return true;
+  }
 };
 
 /**
  * nsIMobileNetworkInfo Serialize/De-serialize.
  */
 template <>
 struct ParamTraits<nsIMobileNetworkInfo*>
 {
@@ -579,171 +638,11 @@ struct ParamTraits<MozCallForwardingOpti
         }
       }
     }
 
     return true;
   }
 };
 
-/**
- * MozCallBarringOptions Serialize/De-serialize.
- */
-template <>
-struct ParamTraits<MozCallBarringOptions>
-{
-  typedef MozCallBarringOptions paramType;
-
-  // Function to serialize a MozCallBarringOptions.
-  static void Write(Message *aMsg, const paramType& aParam)
-  {
-    bool wasPassed = false;
-    bool isNull = false;
-
-    // Write mProgram
-    wasPassed = aParam.mProgram.WasPassed();
-    WriteParam(aMsg, wasPassed);
-    if (wasPassed) {
-      isNull = aParam.mProgram.Value().IsNull();
-      WriteParam(aMsg, isNull);
-      if (!isNull) {
-        WriteParam(aMsg, aParam.mProgram.Value().Value());
-      }
-    }
-
-    // Write mEnabled
-    wasPassed = aParam.mEnabled.WasPassed();
-    WriteParam(aMsg, wasPassed);
-    if (wasPassed) {
-      isNull = aParam.mEnabled.Value().IsNull();
-      WriteParam(aMsg, isNull);
-      if (!isNull) {
-        WriteParam(aMsg, aParam.mEnabled.Value().Value());
-      }
-    }
-
-    // Write mPassword
-    wasPassed = aParam.mPassword.WasPassed();
-    WriteParam(aMsg, wasPassed);
-    if (wasPassed) {
-      WriteParam(aMsg, aParam.mPassword.Value());
-    }
-
-    // Write mServiceClass
-    wasPassed = aParam.mServiceClass.WasPassed();
-    WriteParam(aMsg, wasPassed);
-    if (wasPassed) {
-      isNull = aParam.mServiceClass.Value().IsNull();
-      WriteParam(aMsg, isNull);
-      if (!isNull) {
-        WriteParam(aMsg, aParam.mServiceClass.Value().Value());
-      }
-    }
-
-    // Write mPin
-    wasPassed = aParam.mPin.WasPassed();
-    WriteParam(aMsg, wasPassed);
-    if (wasPassed) {
-      WriteParam(aMsg, aParam.mPin.Value());
-    }
-
-    // Write mNewPin
-    wasPassed = aParam.mNewPin.WasPassed();
-    WriteParam(aMsg, wasPassed);
-    if (wasPassed) {
-      WriteParam(aMsg, aParam.mNewPin.Value());
-    }
-  }
-
-  // Function to de-serialize a MozCallBarringOptions.
-  static bool Read(const Message *aMsg, void **aIter, paramType* aResult)
-  {
-    bool wasPassed = false;
-    bool isNull = false;
-
-    // Read mProgram
-    if (!ReadParam(aMsg, aIter, &wasPassed)) {
-      return false;
-    }
-    if (wasPassed) {
-      aResult->mProgram.Construct();
-      if (!ReadParam(aMsg, aIter, &isNull)) {
-        return false;
-      }
-
-      if (!isNull) {
-        if (!ReadParam(aMsg, aIter, &aResult->mProgram.Value().SetValue())) {
-          return false;
-        }
-      }
-    }
-
-    // Read mEnabled
-    if (!ReadParam(aMsg, aIter, &wasPassed)) {
-      return false;
-    }
-    if (wasPassed) {
-      aResult->mEnabled.Construct();
-      if (!ReadParam(aMsg, aIter, &isNull)) {
-        return false;
-      }
-
-      if (!isNull) {
-        if (!ReadParam(aMsg, aIter, &aResult->mEnabled.Value().SetValue())) {
-          return false;
-        }
-      }
-    }
-
-    // Read mPassword
-    if (!ReadParam(aMsg, aIter, &wasPassed)) {
-      return false;
-    }
-    if (wasPassed) {
-      if (!ReadParam(aMsg, aIter, &aResult->mPassword.Construct())) {
-        return false;
-      }
-    }
-
-    // Read mServiceClass
-    if (!ReadParam(aMsg, aIter, &wasPassed)) {
-      return false;
-    }
-    if (wasPassed) {
-      aResult->mServiceClass.Construct();
-      if (!ReadParam(aMsg, aIter, &isNull)) {
-        return false;
-      }
-
-      if (!isNull) {
-        if (!ReadParam(aMsg, aIter, &aResult->mServiceClass.Value().SetValue())) {
-          return false;
-        }
-      }
-    }
-
-    // Read mPin
-    if (!ReadParam(aMsg, aIter, &wasPassed)) {
-      return false;
-    }
-    if (wasPassed) {
-      if (!ReadParam(aMsg, aIter, &aResult->mPin.Construct())) {
-        return false;
-      }
-    }
-
-    // Read mNewPin
-    if (!ReadParam(aMsg, aIter, &wasPassed)) {
-      return false;
-    }
-    if (wasPassed) {
-      if (!ReadParam(aMsg, aIter, &aResult->mNewPin.Construct())) {
-        return false;
-      }
-    }
-
-    return true;
-  }
-};
-
 } // namespace IPC
 
 #endif // mozilla_dom_mobileconnection_MobileConnectionIPCSerialiser_h
--- a/dom/mobileconnection/ipc/MobileConnectionParent.cpp
+++ b/dom/mobileconnection/ipc/MobileConnectionParent.cpp
@@ -418,125 +418,64 @@ MobileConnectionRequestParent::DoRequest
   return NS_SUCCEEDED(mMobileConnection->CancelMMI(this));
 }
 
 bool
 MobileConnectionRequestParent::DoRequest(const SetCallForwardingRequest& aRequest)
 {
   NS_ENSURE_TRUE(mMobileConnection, false);
 
-  // There are cases (bug 1070083) where this is called with no JS on the stack.
-  // And since mobileConnectionService might be JS-Implemented, so we just
-  // create it in the System-Principaled Junk Scope. We are going to get rid of
-  // the "jsval" used in MobileConnection's interface in bug 1047196, after that
-  // we don't need these things.
-  // Note that using xpc::PrivilegedJunkScope requires explicit case-by-case
-  // approval from the XPConnect module owner (bholley).
-  AutoJSAPI jsapi;
-  if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) {
-    return false;
-  }
-
-  JSContext* cx = jsapi.cx();
-  JS::Rooted<JS::Value> options(cx);
-  if (!ToJSValue(cx, aRequest.options(), &options)) {
-    JS_ClearPendingException(cx);
-    return false;
-  }
-
-  return NS_SUCCEEDED(mMobileConnection->SetCallForwarding(options, this));
+  return NS_SUCCEEDED(mMobileConnection->SetCallForwarding(aRequest.action(),
+                                                           aRequest.reason(),
+                                                           aRequest.number(),
+                                                           aRequest.timeSeconds(),
+                                                           aRequest.serviceClass(),
+                                                           this));
 }
 
 bool
 MobileConnectionRequestParent::DoRequest(const GetCallForwardingRequest& aRequest)
 {
   NS_ENSURE_TRUE(mMobileConnection, false);
 
-  return NS_SUCCEEDED(mMobileConnection->GetCallForwarding(aRequest.reason(), this));
+  return NS_SUCCEEDED(mMobileConnection->GetCallForwarding(aRequest.reason(),
+                                                           this));
 }
 
 bool
 MobileConnectionRequestParent::DoRequest(const SetCallBarringRequest& aRequest)
 {
   NS_ENSURE_TRUE(mMobileConnection, false);
 
-  // There are cases (bug 1070083) where this is called with no JS on the stack.
-  // And since mobileConnectionService might be JS-Implemented, so we just
-  // create it in the System-Principaled Junk Scope. We are going to get rid of
-  // the "jsval" used in MobileConnection's interface in bug 1047196, after that
-  // we don't need these things.
-  // Note that using xpc::PrivilegedJunkScope requires explicit case-by-case
-  // approval from the XPConnect module owner (bholley).
-  AutoJSAPI jsapi;
-  if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) {
-    return false;
-  }
-
-  JSContext* cx = jsapi.cx();
-  JS::Rooted<JS::Value> options(cx);
-  if (!ToJSValue(cx, aRequest.options(), &options)) {
-    JS_ClearPendingException(cx);
-    return false;
-  }
-
-  return NS_SUCCEEDED(mMobileConnection->SetCallBarring(options, this));
+  return NS_SUCCEEDED(mMobileConnection->SetCallBarring(aRequest.program(),
+                                                        aRequest.enabled(),
+                                                        aRequest.password(),
+                                                        aRequest.serviceClass(),
+                                                        this));
 }
 
 bool
 MobileConnectionRequestParent::DoRequest(const GetCallBarringRequest& aRequest)
 {
   NS_ENSURE_TRUE(mMobileConnection, false);
 
-  // There are cases (bug 1070083) where this is called with no JS on the stack.
-  // And since mobileConnectionService might be JS-Implemented, so we just
-  // create it in the System-Principaled Junk Scope. We are going to get rid of
-  // the "jsval" used in MobileConnection's interface in bug 1047196, after that
-  // we don't need these things.
-  // Note that using xpc::PrivilegedJunkScope requires explicit case-by-case
-  // approval from the XPConnect module owner (bholley).
-  AutoJSAPI jsapi;
-  if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) {
-    return false;
-  }
-
-  JSContext* cx = jsapi.cx();
-  JS::Rooted<JS::Value> options(cx);
-  if (!ToJSValue(cx, aRequest.options(), &options)) {
-    JS_ClearPendingException(cx);
-    return false;
-  }
-
-  return NS_SUCCEEDED(mMobileConnection->GetCallBarring(options, this));
+  return NS_SUCCEEDED(mMobileConnection->GetCallBarring(aRequest.program(),
+                                                        aRequest.password(),
+                                                        aRequest.serviceClass(),
+                                                        this));
 }
 
 bool
 MobileConnectionRequestParent::DoRequest(const ChangeCallBarringPasswordRequest& aRequest)
 {
   NS_ENSURE_TRUE(mMobileConnection, false);
 
-  // There are cases (bug 1070083) where this is called with no JS on the stack.
-  // And since mobileConnectionService might be JS-Implemented, so we just
-  // create it in the System-Principaled Junk Scope. We are going to get rid of
-  // the "jsval" used in MobileConnection's interface in bug 1047196, after that
-  // we don't need these things.
-  // Note that using xpc::PrivilegedJunkScope requires explicit case-by-case
-  // approval from the XPConnect module owner (bholley).
-  AutoJSAPI jsapi;
-  if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) {
-    return false;
-  }
-
-  JSContext* cx = jsapi.cx();
-  JS::Rooted<JS::Value> options(cx);
-  if (!ToJSValue(cx, aRequest.options(), &options)) {
-    JS_ClearPendingException(cx);
-    return false;
-  }
-
-  return NS_SUCCEEDED(mMobileConnection->ChangeCallBarringPassword(options, this));
+  return NS_SUCCEEDED(mMobileConnection->ChangeCallBarringPassword(aRequest.pin(),
+                                                                   aRequest.newPin(),
+                                                                   this));
 }
 
 bool
 MobileConnectionRequestParent::DoRequest(const SetCallWaitingRequest& aRequest)
 {
   NS_ENSURE_TRUE(mMobileConnection, false);
 
   return NS_SUCCEEDED(mMobileConnection->SetCallWaiting(aRequest.enabled(), this));
@@ -622,114 +561,73 @@ MobileConnectionRequestParent::NotifyGet
     // We release the ref after serializing process is finished in
     // MobileConnectionIPCSerializer.
     networks.AppendElement(network.forget().take());
   }
   return SendReply(MobileConnectionReplySuccessNetworks(networks));
 }
 
 NS_IMETHODIMP
-MobileConnectionRequestParent::NotifySendCancelMmiSuccess(JS::Handle<JS::Value> aResult,
-                                                          JSContext* aCx)
+MobileConnectionRequestParent::NotifySendCancelMmiSuccess(const nsAString& aServiceCode,
+                                                          const nsAString& aStatusMessage)
 {
-  RootedDictionary<MozMMIResult> result(aCx);
-
-  if (!result.Init(aCx, aResult)) {
-    return NS_ERROR_TYPE_ERR;
-  }
-
-  // No additionInformation passed
-  if (!result.mAdditionalInformation.WasPassed()) {
-    return SendReply(MobileConnectionReplySuccessMmi(result.mServiceCode,
-                                                     result.mStatusMessage,
-                                                     AdditionalInformation(mozilla::void_t())));
-  }
-
-  OwningUnsignedShortOrObject& additionInformation = result.mAdditionalInformation.Value();
-
-  if (additionInformation.IsUnsignedShort()) {
-    return SendReply(MobileConnectionReplySuccessMmi(result.mServiceCode,
-                                                     result.mStatusMessage,
-                                                     AdditionalInformation(uint16_t(additionInformation.GetAsUnsignedShort()))));
-  }
-
-  if (additionInformation.IsObject()) {
-    uint32_t length;
-    JS::Rooted<JS::Value> value(aCx);
-    JS::Rooted<JSObject*> object(aCx, additionInformation.GetAsObject());
-
-    if (!JS_IsArrayObject(aCx, object) ||
-        !JS_GetArrayLength(aCx, object, &length) || length <= 0 ||
-        // Check first element to decide the format of array.
-        !JS_GetElement(aCx, object, 0, &value)) {
-      return NS_ERROR_TYPE_ERR;
-    }
+  return SendReply(MobileConnectionReplySuccessMmi(nsString(aServiceCode),
+                                                   nsString(aStatusMessage),
+                                                   AdditionalInformation(mozilla::void_t())));
+}
 
-    // Check first element to decide the format of array.
-    if (value.isString()) {
-      // String[]
-      nsTArray<nsString> infos;
-      for (uint32_t i = 0; i < length; i++) {
-        if (!JS_GetElement(aCx, object, i, &value) || !value.isString()) {
-          return NS_ERROR_TYPE_ERR;
-        }
-
-        nsAutoJSString str;
-        if (!str.init(aCx, value.toString())) {
-          return NS_ERROR_FAILURE;
-        }
-        infos.AppendElement(str);
-      }
-
-      return SendReply(MobileConnectionReplySuccessMmi(result.mServiceCode,
-                                                       result.mStatusMessage,
-                                                       AdditionalInformation(infos)));
-    } else {
-      // IPC::MozCallForwardingOptions[]
-      nsTArray<IPC::MozCallForwardingOptions> infos;
-      for (uint32_t i = 0; i < length; i++) {
-        IPC::MozCallForwardingOptions info;
-        if (!JS_GetElement(aCx, object, i, &value) || !info.Init(aCx, value)) {
-          return NS_ERROR_TYPE_ERR;
-        }
-
-        infos.AppendElement(info);
-      }
-
-      return SendReply(MobileConnectionReplySuccessMmi(result.mServiceCode,
-                                                       result.mStatusMessage,
-                                                       AdditionalInformation(infos)));
-    }
-  }
-
-  return NS_ERROR_TYPE_ERR;
+NS_IMETHODIMP
+MobileConnectionRequestParent::NotifySendCancelMmiSuccessWithInteger(const nsAString& aServiceCode,
+                                                                     const nsAString& aStatusMessage,
+                                                                     uint16_t aAdditionalInformation)
+{
+  return SendReply(MobileConnectionReplySuccessMmi(nsString(aServiceCode),
+                                                   nsString(aStatusMessage),
+                                                   AdditionalInformation(aAdditionalInformation)));
 }
 
 NS_IMETHODIMP
-MobileConnectionRequestParent::NotifyGetCallForwardingSuccess(JS::Handle<JS::Value> aResults,
-                                                              JSContext* aCx)
+MobileConnectionRequestParent::NotifySendCancelMmiSuccessWithStrings(const nsAString& aServiceCode,
+                                                                     const nsAString& aStatusMessage,
+                                                                     uint32_t aCount,
+                                                                     const char16_t** aAdditionalInformation)
 {
-  uint32_t length;
-  JS::Rooted<JSObject*> object(aCx, &aResults.toObject());
-  nsTArray<IPC::MozCallForwardingOptions> results;
-
-  if (!JS_IsArrayObject(aCx, object) ||
-      !JS_GetArrayLength(aCx, object, &length)) {
-    return NS_ERROR_TYPE_ERR;
+  nsTArray<nsString> additionalInformation;
+  for (uint32_t i = 0; i < aCount; i++) {
+    additionalInformation.AppendElement(nsDependentString(aAdditionalInformation[i]));
   }
 
-  for (uint32_t i = 0; i < length; i++) {
-    JS::Rooted<JS::Value> entry(aCx);
-    IPC::MozCallForwardingOptions info;
+  return SendReply(MobileConnectionReplySuccessMmi(nsString(aServiceCode),
+                                                   nsString(aStatusMessage),
+                                                   AdditionalInformation(additionalInformation)));
+}
 
-    if (!JS_GetElement(aCx, object, i, &entry) || !info.Init(aCx, entry)) {
-      return NS_ERROR_TYPE_ERR;
-    }
+NS_IMETHODIMP
+MobileConnectionRequestParent::NotifySendCancelMmiSuccessWithCallForwardingOptions(const nsAString& aServiceCode,
+                                                                                   const nsAString& aStatusMessage,
+                                                                                   uint32_t aCount,
+                                                                                   nsIMobileCallForwardingOptions** aAdditionalInformation)
+{
+  nsTArray<nsIMobileCallForwardingOptions*> additionalInformation;
+  for (uint32_t i = 0; i < aCount; i++) {
+    additionalInformation.AppendElement(aAdditionalInformation[i]);
+  }
 
-    results.AppendElement(info);
+  return SendReply(MobileConnectionReplySuccessMmi(nsString(aServiceCode),
+                                                   nsString(aStatusMessage),
+                                                   AdditionalInformation(additionalInformation)));
+}
+
+NS_IMETHODIMP
+MobileConnectionRequestParent::NotifyGetCallForwardingSuccess(uint32_t aCount,
+                                                              nsIMobileCallForwardingOptions** aResults)
+{
+  nsTArray<nsIMobileCallForwardingOptions*> results;
+  for (uint32_t i = 0; i < aCount; i++) {
+    results.AppendElement(aResults[i]);
   }
 
   return SendReply(MobileConnectionReplySuccessCallForwarding(results));
 }
 
 NS_IMETHODIMP
 MobileConnectionRequestParent::NotifyGetCallBarringSuccess(uint16_t aProgram,
                                                            bool aEnabled,
--- a/dom/mobileconnection/ipc/PMobileConnection.ipdl
+++ b/dom/mobileconnection/ipc/PMobileConnection.ipdl
@@ -104,37 +104,47 @@ struct SendMmiRequest
 };
 
 struct CancelMmiRequest
 {
 };
 
 struct SetCallForwardingRequest
 {
-  MozCallForwardingOptions options;
+  uint16_t action;
+  uint16_t reason;
+  nsString number;
+  uint16_t timeSeconds;
+  uint16_t serviceClass;
 };
 
 struct GetCallForwardingRequest
 {
-  int16_t reason;
+  uint16_t reason;
 };
 
 struct SetCallBarringRequest
 {
-  MozCallBarringOptions options;
+  uint16_t program;
+  bool enabled;
+  nsString password;
+  uint16_t serviceClass;
 };
 
 struct GetCallBarringRequest
 {
-  MozCallBarringOptions options;
+  uint16_t program;
+  nsString password;
+  uint16_t serviceClass;
 };
 
 struct ChangeCallBarringPasswordRequest
 {
-  MozCallBarringOptions options;
+  nsString pin;
+  nsString newPin;
 };
 
 struct SetCallWaitingRequest
 {
   bool enabled;
 };
 
 struct GetCallWaitingRequest
--- a/dom/mobileconnection/ipc/PMobileConnectionRequest.ipdl
+++ b/dom/mobileconnection/ipc/PMobileConnectionRequest.ipdl
@@ -49,17 +49,17 @@ struct MobileConnectionReplySuccessMmi
 {
   nsString serviceCode;
   nsString statusMessage;
   AdditionalInformation additionalInformation;
 };
 
 struct MobileConnectionReplySuccessCallForwarding
 {
-  MozCallForwardingOptions[] results;
+  nsMobileCallForwardingOptions[] results;
 };
 
 struct MobileConnectionReplySuccessCallBarring
 {
   uint16_t program;
   bool enabled;
   uint16_t serviceClass;
 };
--- a/dom/mobileconnection/ipc/PMobileConnectionTypes.ipdlh
+++ b/dom/mobileconnection/ipc/PMobileConnectionTypes.ipdlh
@@ -3,24 +3,24 @@
 /* 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/. */
 
 using nsMobileConnectionInfo from "mozilla/dom/mobileconnection/MobileConnectionIPCSerializer.h";
 using nsMobileNetworkInfo from "mozilla/dom/mobileconnection/MobileConnectionIPCSerializer.h";
 using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
 using struct IPC::MozCallForwardingOptions from "mozilla/dom/mobileconnection/MobileConnectionIPCSerializer.h";
-using struct IPC::MozCallBarringOptions from "mozilla/dom/mobileconnection/MobileConnectionIPCSerializer.h";
+using nsMobileCallForwardingOptions from "mozilla/dom/mobileconnection/MobileConnectionIPCSerializer.h";
 
 namespace mozilla {
 namespace dom {
 namespace mobileconnection {
 
 union AdditionalInformation {
   void_t;
   uint16_t;
   nsString[];
-  MozCallForwardingOptions[];
+  nsMobileCallForwardingOptions[];
 };
 
 } // namespace mobileconnection
 } // namespace dom
 } // namespace mozilla
--- a/dom/mobileconnection/moz.build
+++ b/dom/mobileconnection/moz.build
@@ -14,32 +14,35 @@ EXPORTS.mozilla.dom += [
     'MobileConnectionInfo.h',
     'MobileNetworkInfo.h',
 ]
 
 EXPORTS.mozilla.dom.mobileconnection += [
     'ipc/MobileConnectionChild.h',
     'ipc/MobileConnectionIPCSerializer.h',
     'ipc/MobileConnectionParent.h',
+    'MobileCallForwardingOptions.h',
 ]
 
 XPIDL_SOURCES += [
     'interfaces/nsICellInfo.idl',
+    'interfaces/nsIMobileCallForwardingOptions.idl',
     'interfaces/nsIMobileCellInfo.idl',
     'interfaces/nsIMobileConnectionInfo.idl',
     'interfaces/nsIMobileConnectionService.idl',
     'interfaces/nsIMobileNetworkInfo.idl',
     'interfaces/nsINeighboringCellInfo.idl',
 ]
 
 UNIFIED_SOURCES += [
     'DOMMMIError.cpp',
     'ipc/MobileConnectionChild.cpp',
     'ipc/MobileConnectionIPCService.cpp',
     'ipc/MobileConnectionParent.cpp',
+    'MobileCallForwardingOptions.cpp',
     'MobileCellInfo.cpp',
     'MobileConnection.cpp',
     'MobileConnectionArray.cpp',
     'MobileConnectionCallback.cpp',
     'MobileConnectionInfo.cpp',
     'MobileNetworkInfo.cpp',
 ]
 
--- a/dom/tests/mochitest/localstorage/mochitest.ini
+++ b/dom/tests/mochitest/localstorage/mochitest.ini
@@ -17,17 +17,17 @@ support-files =
   localStorageCommon.js
 
 [test_appIsolation.html]
 skip-if = buildapp == 'b2g' || toolkit == 'android' #bug 793211 # b2g(needs https to work) b2g-debug(needs https to work) b2g-desktop(needs https to work)
 [test_brokenUTF-16.html]
 [test_bug600307-DBOps.html]
 [test_bug746272-1.html]
 [test_bug746272-2.html]
-skip-if = os == "android" # bug 962029
+skip-if = os == "android" || toolkit == 'gonk' # bug 962029
 [test_cookieBlock.html]
 skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) # b2g-debug(bug 913706) b2g-desktop(bug 913706)
 [test_cookieSession.html]
 skip-if = toolkit=='gonk' # b2g(4 failures) b2g-debug(debug-only failure)
 [test_embededNulls.html]
 [test_keySync.html]
 [test_localStorageBase.html]
 skip-if = buildapp == 'b2g' || e10s # b2g(no storage chrome event received)
--- a/services/mobileid/MobileIdentityManager.jsm
+++ b/services/mobileid/MobileIdentityManager.jsm
@@ -412,17 +412,17 @@ this.MobileIdentityManager = {
 
   /*********************************************************
    * UI callbacks
    ********************************************************/
 
   onUICancel: function() {
     log.debug("UI cancel");
     if (this.activeVerificationFlow) {
-      this.activeVerificationFlow.cleanup(true);
+      this.rejectVerification();
     }
   },
 
   onUIResendCode: function() {
     log.debug("UI resend code");
     if (!this.activeVerificationFlow) {
       return;
     }
@@ -462,33 +462,33 @@ this.MobileIdentityManager = {
    ********************************************************/
 
   rejectVerification: function(aReason) {
     if (!this.activeVerificationDeferred) {
       return;
     }
     this.activeVerificationDeferred.reject(aReason);
     this.activeVerificationDeferred = null;
-    this.cleanupVerification(true);
+    this.cleanupVerification(true /* unregister */);
   },
 
   resolveVerification: function(aResult) {
     if (!this.activeVerificationDeferred) {
       return;
     }
     this.activeVerificationDeferred.resolve(aResult);
     this.activeVerificationDeferred = null;
     this.cleanupVerification();
   },
 
-  cleanupVerification: function() {
+  cleanupVerification: function(aUnregister = false) {
     if (!this.activeVerificationFlow) {
       return;
     }
-    this.activeVerificationFlow.cleanup();
+    this.activeVerificationFlow.cleanup(aUnregister);
     this.activeVerificationFlow = null;
   },
 
   doVerification: function() {
     this.activeVerificationFlow.doVerification()
     .then(
       (verificationResult) => {
         log.debug("onVerificationResult ");
--- a/services/mobileid/tests/xpcshell/test_mobileid_manager.js
+++ b/services/mobileid/tests/xpcshell/test_mobileid_manager.js
@@ -1454,8 +1454,59 @@ add_test(function() {
     principal: PRINCIPAL,
     target: mm,
     json: {
       promiseId: promiseId,
       options: {}
     }
   });
 });
+
+add_test(function() {
+  do_print("= Cancel verification flow =");
+
+  do_register_cleanup(cleanup);
+
+  do_test_pending();
+
+  let _sessionToken = Date.now();
+
+  let ui = new MockUi();
+  ui.verificationCodePrompt = function() {
+    MobileIdentityManager.onUICancel();
+  };
+  MobileIdentityManager.ui = ui;
+
+  let credStore = new MockCredStore();
+  MobileIdentityManager.credStore = credStore;
+
+  let client = new MockClient();
+  MobileIdentityManager.client = client;
+
+  let promiseId = Date.now();
+  let mm = {
+    sendAsyncMessage: function(aMsg, aData) {
+      do_print("sendAsyncMessage " + aMsg + " - " + JSON.stringify(aData));
+
+      // Check result.
+      do_check_eq(aMsg, GET_ASSERTION_RETURN_KO);
+      do_check_eq(typeof aData, "object");
+      do_check_eq(aData.promiseId, promiseId);
+      do_check_eq(aData.error, DIALOG_CLOSED_BY_USER);
+
+      do_test_finished();
+      run_next_test();
+    }
+  };
+
+  addPermission(Ci.nsIPermissionManager.ALLOW_ACTION);
+
+  MobileIdentityManager.receiveMessage({
+    name: GET_ASSERTION_IPC_MSG,
+    principal: PRINCIPAL,
+    target: mm,
+    json: {
+      promiseId: promiseId,
+      options: {}
+    }
+  });
+});
+
--- a/testing/marionette/client/marionette/runner/mixins/reporting.py
+++ b/testing/marionette/client/marionette/runner/mixins/reporting.py
@@ -6,16 +6,17 @@ import base64
 import cgi
 import datetime
 import json
 import os
 import pkg_resources
 import sys
 import time
 
+from mozlog.structured.structuredlog import get_default_logger
 import mozversion
 from xmlgen import html
 from xmlgen import raw
 
 
 class HTMLReportingTestRunnerMixin(object):
 
     def __init__(self, name=None, version=None, html_output=None, **kwargs):
@@ -242,24 +243,25 @@ class HTMLReportingTestResultMixin(objec
         test.debug = None
         if result_actual is not 'PASS':
             test.debug = self.gather_debug()
         return result_expected, result_actual, output, context
 
     def gather_debug(self):
         debug = {}
         try:
-            self.marionette.switch_context(self.marionette.CONTEXT_CHROME)
+            self.marionette.set_context(self.marionette.CONTEXT_CHROME)
             debug['screenshot'] = self.marionette.screenshot()
-            self.marionette.switch_context(self.marionette.CONTEXT_CONTENT)
+            self.marionette.set_context(self.marionette.CONTEXT_CONTENT)
             debug['source'] = self.marionette.page_source
             self.marionette.switch_to_frame()
             debug['settings'] = json.dumps(self.marionette.execute_async_script("""
 SpecialPowers.addPermission('settings-read', true, document);
 SpecialPowers.addPermission('settings-api-read', true, document);
 var req = window.navigator.mozSettings.createLock().get('*');
 req.onsuccess = function() {
   marionetteScriptFinished(req.result);
 }""", special_powers=True), sort_keys=True, indent=4, separators=(',', ': '))
         except:
-            pass
+            logger = get_default_logger()
+            logger.warning('Failed to gather test failure debug.', exc_info=True)
         return debug