Merge b2g-inbound to m-c a=merge CLOSED TREE
authorWes Kocher <wkocher@mozilla.com>
Fri, 10 Oct 2014 18:41:41 -0700
changeset 209843 999ad2f1e1089d203811266bc3c9bfa92308f029
parent 209809 708b45d9b1b110a8c0d21fb18975e79f64772d13 (current diff)
parent 209842 b4457e42fcc9b1c164f6107459c0cdab267671b7 (diff)
child 209907 f74ad36bb97b85909f7a3430288c07d3bf8b4e50
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersmerge
milestone35.0a1
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