Merge b-i to m-c a=merge
authorWes Kocher <wkocher@mozilla.com>
Mon, 01 Jun 2015 12:19:33 -0700
changeset 246510 a2d68ee6628cf610ad3d0d1bf4b576276c849e5c
parent 246509 06f1c9847ca1d4eb343f779a1a0eea20552f3533 (current diff)
parent 246508 abab1e9d865d16a2607d926676faf9ba2e5bf72e (diff)
child 246511 56241c1f8a3b8803e8091362dcbaec614c4db1dc
child 246513 68312661b69b35dd492144d4f02e61d5ebef5350
child 246531 a4bb8b6b0acd00d9a3c504e390b0692861e3045d
child 246592 8b61b483cfb9851be5fb1b71c52264963cec24a1
push id28833
push userkwierso@gmail.com
push dateMon, 01 Jun 2015 19:19:37 +0000
treeherdermozilla-central@a2d68ee6628c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge b-i to m-c a=merge
b2g/config/aries/sources.xml
b2g/config/dolphin/sources.xml
b2g/config/emulator-ics/sources.xml
b2g/config/emulator-jb/sources.xml
b2g/config/emulator-kk/sources.xml
b2g/config/emulator-l/sources.xml
b2g/config/emulator/sources.xml
b2g/config/flame-kk/sources.xml
b2g/config/gaia.json
b2g/config/nexus-4/sources.xml
b2g/config/nexus-5-l/sources.xml
--- a/b2g/config/aries/sources.xml
+++ b/b2g/config/aries/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="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="97c41d6839e2c5fa6962aaf9b1720adf79f219ba"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="6d477a7884273886605049b20f60af5c1583a150"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <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="4a697ec692aa762eb8cdb7812f5a051c5870020f"/>
--- 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="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="97c41d6839e2c5fa6962aaf9b1720adf79f219ba"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="6d477a7884273886605049b20f60af5c1583a150"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <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="4a697ec692aa762eb8cdb7812f5a051c5870020f"/>
--- 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="173b3104bfcbd23fc9dccd4b0035fc49aae3d444">
     <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="97c41d6839e2c5fa6962aaf9b1720adf79f219ba"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="6d477a7884273886605049b20f60af5c1583a150"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="22664edc4c73e5fe8f5095ff1d5549db78a2bc10"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="218a5637399d023f4326e12c8a486dad95403b6c"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- 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="4efd19d199ae52656604f794c5a77518400220fd">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="97c41d6839e2c5fa6962aaf9b1720adf79f219ba"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="6d477a7884273886605049b20f60af5c1583a150"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="4a697ec692aa762eb8cdb7812f5a051c5870020f"/>
   <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="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="97c41d6839e2c5fa6962aaf9b1720adf79f219ba"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="6d477a7884273886605049b20f60af5c1583a150"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <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="4a697ec692aa762eb8cdb7812f5a051c5870020f"/>
--- a/b2g/config/emulator-l/sources.xml
+++ b/b2g/config/emulator-l/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="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="97c41d6839e2c5fa6962aaf9b1720adf79f219ba"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="6d477a7884273886605049b20f60af5c1583a150"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <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="4a697ec692aa762eb8cdb7812f5a051c5870020f"/>
--- 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="173b3104bfcbd23fc9dccd4b0035fc49aae3d444">
     <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="97c41d6839e2c5fa6962aaf9b1720adf79f219ba"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="6d477a7884273886605049b20f60af5c1583a150"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="22664edc4c73e5fe8f5095ff1d5549db78a2bc10"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="218a5637399d023f4326e12c8a486dad95403b6c"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- 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="e862ab9177af664f00b4522e2350f4cb13866d73">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="97c41d6839e2c5fa6962aaf9b1720adf79f219ba"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="6d477a7884273886605049b20f60af5c1583a150"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <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="4a697ec692aa762eb8cdb7812f5a051c5870020f"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
-        "git_revision": "97c41d6839e2c5fa6962aaf9b1720adf79f219ba", 
+        "git_revision": "6d477a7884273886605049b20f60af5c1583a150", 
         "remote": "https://git.mozilla.org/releases/gaia.git", 
         "branch": ""
     }, 
-    "revision": "aa653cc24c710327fa734718ea1af94e470f77bc", 
+    "revision": "c7beef2b034d2308a85e8c866395c78245bc554f", 
     "repo_path": "integration/gaia-central"
 }
--- 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="4efd19d199ae52656604f794c5a77518400220fd">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="97c41d6839e2c5fa6962aaf9b1720adf79f219ba"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="6d477a7884273886605049b20f60af5c1583a150"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="4a697ec692aa762eb8cdb7812f5a051c5870020f"/>
   <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/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/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="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="97c41d6839e2c5fa6962aaf9b1720adf79f219ba"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="6d477a7884273886605049b20f60af5c1583a150"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <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="4a697ec692aa762eb8cdb7812f5a051c5870020f"/>
--- a/dom/bluetooth/bluedroid/BluetoothOppManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothOppManager.cpp
@@ -289,19 +289,20 @@ BluetoothOppManager::ConnectInternal(con
   mIsServer = false;
 
   BluetoothService* bs = BluetoothService::Get();
   if (!bs || sInShutdown || mSocket) {
     OnSocketConnectError(mSocket);
     return;
   }
 
-  mSocket =
-    new BluetoothSocket(this, BluetoothSocketType::RFCOMM, false, true);
-  mSocket->ConnectSocket(aDeviceAddress, kObexObjectPush, -1);
+  mSocket = new BluetoothSocket(this);
+  mSocket->Connect(aDeviceAddress, kObexObjectPush,
+                   BluetoothSocketType::RFCOMM, -1,
+                   false, true);
 }
 
 void
 BluetoothOppManager::HandleShutdown()
 {
   MOZ_ASSERT(NS_IsMainThread());
   sInShutdown = true;
   Disconnect(nullptr);
@@ -351,22 +352,24 @@ BluetoothOppManager::Listen()
    * BT stops; otherwise no more read events would be received even if
    * BT restarts.
    */
   if (mServerSocket) {
     mServerSocket->Close();
     mServerSocket = nullptr;
   }
 
-  mServerSocket =
-    new BluetoothSocket(this, BluetoothSocketType::RFCOMM, false, true);
+  mServerSocket = new BluetoothSocket(this);
 
-  if (!mServerSocket->ListenSocket(NS_LITERAL_STRING("OBEX Object Push"),
-                                   kObexObjectPush,
-                                   BluetoothReservedChannels::CHANNEL_OPUSH)) {
+  nsresult rv = mServerSocket->Listen(NS_LITERAL_STRING("OBEX Object Push"),
+                                      kObexObjectPush,
+                                      BluetoothSocketType::RFCOMM,
+                                      BluetoothReservedChannels::CHANNEL_OPUSH,
+                                      false, true);
+  if (NS_FAILED(rv)) {
     BT_WARNING("[OPP] Can't listen on RFCOMM socket!");
     mServerSocket = nullptr;
     return false;
   }
 
   mIsServer = true;
 
   return true;
--- a/dom/bluetooth/bluedroid/BluetoothPbapManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothPbapManager.cpp
@@ -156,23 +156,25 @@ BluetoothPbapManager::Listen()
    * BT stops; otherwise no more read events would be received even if
    * BT restarts.
    */
   if (mServerSocket) {
     mServerSocket->Close();
     mServerSocket = nullptr;
   }
 
-  mServerSocket =
-    new BluetoothSocket(this, BluetoothSocketType::RFCOMM, false, true);
+  mServerSocket = new BluetoothSocket(this);
 
-  if (NS_WARN_IF(!mServerSocket->ListenSocket(
-                    NS_LITERAL_STRING("OBEX Phonebook Access Server"),
-                    kPbapPSE,
-                    BluetoothReservedChannels::CHANNEL_PBAP_PSE))) {
+  nsresult rv = mServerSocket->Listen(
+    NS_LITERAL_STRING("OBEX Phonebook Access Server"),
+    kPbapPSE,
+    BluetoothSocketType::RFCOMM,
+    BluetoothReservedChannels::CHANNEL_PBAP_PSE, false, true);
+
+  if (NS_FAILED(rv)) {
     mServerSocket = nullptr;
     return false;
   }
 
   BT_LOGR("PBAP socket is listening");
   return true;
 }
 
--- a/dom/bluetooth/bluedroid/BluetoothSocket.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothSocket.cpp
@@ -574,25 +574,20 @@ DroidSocketImpl::DiscardBuffer()
 {
   // Nothing to do.
 }
 
 //
 // |BluetoothSocket|
 //
 
-BluetoothSocket::BluetoothSocket(BluetoothSocketObserver* aObserver,
-                                 BluetoothSocketType aType,
-                                 bool aAuth,
-                                 bool aEncrypt)
+BluetoothSocket::BluetoothSocket(BluetoothSocketObserver* aObserver)
   : mObserver(aObserver)
   , mCurrentRes(nullptr)
   , mImpl(nullptr)
-  , mAuth(aAuth)
-  , mEncrypt(aEncrypt)
 {
   MOZ_ASSERT(aObserver);
 
   EnsureBluetoothSocketHalLoad();
   mDeviceAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE);
 }
 
 class ConnectSocketResultHandler final : public BluetoothSocketResultHandler
@@ -637,38 +632,39 @@ public:
       mImpl->mConsumer->NotifyDisconnect();
     }
   }
 
 private:
   DroidSocketImpl* mImpl;
 };
 
-bool
-BluetoothSocket::ConnectSocket(const nsAString& aDeviceAddress,
-                               const BluetoothUuid& aServiceUuid,
-                               int aChannel)
+nsresult
+BluetoothSocket::Connect(const nsAString& aDeviceAddress,
+                         const BluetoothUuid& aServiceUuid,
+                         BluetoothSocketType aType,
+                         int aChannel,
+                         bool aAuth, bool aEncrypt)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  NS_ENSURE_FALSE(mImpl, false);
+  MOZ_ASSERT(!mImpl);
 
   SetConnectionStatus(SOCKET_CONNECTING);
 
   mImpl = new DroidSocketImpl(XRE_GetIOMessageLoop(), this);
 
   BluetoothSocketResultHandler* res = new ConnectSocketResultHandler(mImpl);
   SetCurrentResultHandler(res);
 
   sBluetoothSocketInterface->Connect(
-    aDeviceAddress,
-    BluetoothSocketType::RFCOMM,
+    aDeviceAddress, aType,
     aServiceUuid.mUuid, aChannel,
-    mEncrypt, mAuth, res);
+    aEncrypt, aAuth, res);
 
-  return true;
+  return NS_OK;
 }
 
 class ListenResultHandler final : public BluetoothSocketResultHandler
 {
 public:
   ListenResultHandler(DroidSocketImpl* aImpl)
   : mImpl(aImpl)
   {
@@ -689,37 +685,39 @@ public:
 
     BT_WARNING("Listen failed: %d", (int)aStatus);
   }
 
 private:
   DroidSocketImpl* mImpl;
 };
 
-bool
-BluetoothSocket::ListenSocket(const nsAString& aServiceName,
-                              const BluetoothUuid& aServiceUuid,
-                              int aChannel)
+nsresult
+BluetoothSocket::Listen(const nsAString& aServiceName,
+                        const BluetoothUuid& aServiceUuid,
+                        BluetoothSocketType aType,
+                        int aChannel,
+                        bool aAuth, bool aEncrypt)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  NS_ENSURE_FALSE(mImpl, false);
+  MOZ_ASSERT(!mImpl);
 
   SetConnectionStatus(SOCKET_LISTENING);
 
   mImpl = new DroidSocketImpl(XRE_GetIOMessageLoop(), this);
 
   BluetoothSocketResultHandler* res = new ListenResultHandler(mImpl);
   SetCurrentResultHandler(res);
 
   sBluetoothSocketInterface->Listen(
-    BluetoothSocketType::RFCOMM,
+    aType,
     aServiceName, aServiceUuid.mUuid, aChannel,
-    mEncrypt, mAuth, res);
+    aEncrypt, aAuth, res);
 
-  return true;
+  return NS_OK;
 }
 
 void
 BluetoothSocket::ReceiveSocketData(nsAutoPtr<UnixSocketBuffer>& aBuffer)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mObserver);
 
--- a/dom/bluetooth/bluedroid/BluetoothSocket.h
+++ b/dom/bluetooth/bluedroid/BluetoothSocket.h
@@ -14,28 +14,29 @@ BEGIN_BLUETOOTH_NAMESPACE
 
 class BluetoothSocketObserver;
 class BluetoothSocketResultHandler;
 class DroidSocketImpl;
 
 class BluetoothSocket final : public mozilla::ipc::DataSocket
 {
 public:
-  BluetoothSocket(BluetoothSocketObserver* aObserver,
-                  BluetoothSocketType aType,
-                  bool aAuth,
-                  bool aEncrypt);
+  BluetoothSocket(BluetoothSocketObserver* aObserver);
 
-  bool ConnectSocket(const nsAString& aDeviceAddress,
-                     const BluetoothUuid& aServiceUuid,
-                     int aChannel);
+  nsresult Connect(const nsAString& aDeviceAddress,
+                   const BluetoothUuid& aServiceUuid,
+                   BluetoothSocketType aType,
+                   int aChannel,
+                   bool aAuth, bool aEncrypt);
 
-  bool ListenSocket(const nsAString& aServiceName,
-                    const BluetoothUuid& aServiceUuid,
-                    int aChannel);
+  nsresult Listen(const nsAString& aServiceName,
+                  const BluetoothUuid& aServiceUuid,
+                  BluetoothSocketType aType,
+                  int aChannel,
+                  bool aAuth, bool aEncrypt);
 
   /**
    * Method to be called whenever data is received. This is only called on the
    * main thread.
    *
    * @param aBuffer Data received from the socket.
    */
   void ReceiveSocketData(nsAutoPtr<mozilla::ipc::UnixSocketBuffer>& aBuffer);
@@ -69,15 +70,13 @@ public:
   void OnConnectError() override;
   void OnDisconnect() override;
 
 private:
   BluetoothSocketObserver* mObserver;
   BluetoothSocketResultHandler* mCurrentRes;
   DroidSocketImpl* mImpl;
   nsString mDeviceAddress;
-  bool mAuth;
-  bool mEncrypt;
 };
 
 END_BLUETOOTH_NAMESPACE
 
 #endif
--- a/dom/bluetooth/bluez/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluez/BluetoothHfpManager.cpp
@@ -478,20 +478,17 @@ BluetoothHfpManager::Init()
   NS_ENSURE_SUCCESS(rv, false);
 
   nsRefPtr<GetVolumeTask> callback = new GetVolumeTask();
   rv = settingsLock->Get(AUDIO_VOLUME_BT_SCO_ID, callback);
   NS_ENSURE_SUCCESS(rv, false);
 
   Listen();
 
-  mScoSocket = new BluetoothSocket(this,
-                                   BluetoothSocketType::SCO,
-                                   true,
-                                   false);
+  mScoSocket = new BluetoothSocket(this);
   mScoSocketStatus = mScoSocket->GetConnectionStatus();
   ListenSco();
   return true;
 }
 
 BluetoothHfpManager::~BluetoothHfpManager()
 {
 #ifdef MOZ_B2G_RIL
@@ -1145,28 +1142,27 @@ BluetoothHfpManager::Connect(const nsASt
 
   if (NS_FAILED(bs->GetServiceChannel(aDeviceAddress, uuid, this))) {
     aController->NotifyCompletion(NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
     return;
   }
 
   // Stop listening because currently we only support one connection at a time.
   if (mHandsfreeSocket) {
-    mHandsfreeSocket->Disconnect();
+    mHandsfreeSocket->Close();
     mHandsfreeSocket = nullptr;
   }
 
   if (mHeadsetSocket) {
-    mHeadsetSocket->Disconnect();
+    mHeadsetSocket->Close();
     mHeadsetSocket = nullptr;
   }
 
   mController = aController;
-  mSocket =
-    new BluetoothSocket(this, BluetoothSocketType::RFCOMM, true, true);
+  mSocket = new BluetoothSocket(this);
 }
 
 bool
 BluetoothHfpManager::Listen()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (sInShutdown) {
@@ -1175,39 +1171,45 @@ BluetoothHfpManager::Listen()
   }
 
   if (mSocket) {
     BT_WARNING("mSocket exists. Failed to listen.");
     return false;
   }
 
   if (!mHandsfreeSocket) {
-    mHandsfreeSocket =
-      new BluetoothSocket(this, BluetoothSocketType::RFCOMM, true, true);
+    mHandsfreeSocket = new BluetoothSocket(this);
 
-    if (!mHandsfreeSocket->Listen(
-          NS_LITERAL_STRING("Handsfree Audio Gateway"),
-          kHandsfreeAG,
-          BluetoothReservedChannels::CHANNEL_HANDSFREE_AG)) {
+    nsresult rv = mHandsfreeSocket->Listen(
+      NS_LITERAL_STRING("Handsfree Audio Gateway"),
+      kHandsfreeAG,
+      BluetoothSocketType::RFCOMM,
+      BluetoothReservedChannels::CHANNEL_HANDSFREE_AG,
+      true, true);
+
+    if (NS_FAILED(rv)) {
       BT_WARNING("[HFP] Can't listen on RFCOMM socket!");
       mHandsfreeSocket = nullptr;
       return false;
     }
   }
 
   if (!mHeadsetSocket) {
-    mHeadsetSocket =
-      new BluetoothSocket(this, BluetoothSocketType::RFCOMM, true, true);
+    mHeadsetSocket = new BluetoothSocket(this);
 
-    if (!mHeadsetSocket->Listen(
-          NS_LITERAL_STRING("Headset Audio Gateway"),
-          kHeadsetAG,
-          BluetoothReservedChannels::CHANNEL_HEADSET_AG)) {
+    nsresult rv = mHeadsetSocket->Listen(
+      NS_LITERAL_STRING("Headset Audio Gateway"),
+      kHeadsetAG,
+      BluetoothSocketType::RFCOMM,
+      BluetoothReservedChannels::CHANNEL_HEADSET_AG,
+      true, true);
+
+    if (NS_FAILED(rv)) {
       BT_WARNING("[HSP] Can't listen on RFCOMM socket!");
-      mHandsfreeSocket->Disconnect();
+      mHandsfreeSocket->Close();
       mHandsfreeSocket = nullptr;
       mHeadsetSocket = nullptr;
       return false;
     }
   }
 
   return true;
 }
@@ -1222,17 +1224,17 @@ BluetoothHfpManager::Disconnect(Bluetoot
       aController->NotifyCompletion(NS_LITERAL_STRING(ERR_ALREADY_DISCONNECTED));
     }
     return;
   }
 
   MOZ_ASSERT(!mController);
 
   mController = aController;
-  mSocket->Disconnect();
+  mSocket->Close();
 }
 
 #ifdef MOZ_B2G_RIL
 void
 BluetoothHfpManager::SendCCWA(const nsAString& aNumber, int aType)
 {
   if (mCCWA) {
     nsAutoCString ccwaMsg("+CCWA: \"");
@@ -1791,24 +1793,24 @@ BluetoothHfpManager::OnSocketConnectSucc
    * connections, we do nothing since sockets have been already handled in
    * function Connect().
    */
   if (aSocket == mHandsfreeSocket) {
     MOZ_ASSERT(!mSocket);
     mIsHsp = false;
     mHandsfreeSocket.swap(mSocket);
 
-    mHeadsetSocket->Disconnect();
+    mHeadsetSocket->Close();
     mHeadsetSocket = nullptr;
   } else if (aSocket == mHeadsetSocket) {
     MOZ_ASSERT(!mSocket);
     mIsHsp = true;
     mHeadsetSocket.swap(mSocket);
 
-    mHandsfreeSocket->Disconnect();
+    mHandsfreeSocket->Close();
     mHandsfreeSocket = nullptr;
   }
 
 #ifdef MOZ_B2G_RIL
   // Enumerate current calls
   mListener->EnumerateCalls();
 
   mFirstCKPD = true;
@@ -1899,19 +1901,22 @@ BluetoothHfpManager::OnGetServiceChannel
       mIsHsp = true;
     }
 
     return;
   }
 
   MOZ_ASSERT(mSocket);
 
-  if (!mSocket->Connect(aDeviceAddress,
-                        mIsHsp? kHeadsetAG : kHandsfreeAG,
-                        aChannel)) {
+  nsresult rv = mSocket->Connect(aDeviceAddress,
+                                 mIsHsp? kHeadsetAG : kHandsfreeAG,
+                                 BluetoothSocketType::RFCOMM,
+                                 aChannel,
+                                 true, true);
+  if (NS_FAILED(rv)) {
     OnConnect(NS_LITERAL_STRING(ERR_CONNECTION_FAILED));
   }
 }
 
 void
 BluetoothHfpManager::OnScoConnectSuccess()
 {
   // For active connection request, we need to reply the DOMRequest
@@ -1985,34 +1990,36 @@ BluetoothHfpManager::ConnectSco(Bluetoot
   // established before we start to set up SCO (synchronous connection).
   if (!mSlcConnected && !mIsHsp) {
     mConnectScoRequest = true;
     BT_WARNING("ConnectSco called before Service Level Connection established");
     return false;
   }
 
   // Stop listening
-  mScoSocket->Disconnect();
+  mScoSocket->Close();
 
-  mScoSocket->Connect(mDeviceAddress, kUnknownService, -1);
+  mScoSocket->Connect(mDeviceAddress, kUnknownService,
+                      BluetoothSocketType::SCO,
+                      -1, true, false);
   mScoSocketStatus = mScoSocket->GetConnectionStatus();
 
   mScoRunnable = aRunnable;
   return true;
 }
 
 bool
 BluetoothHfpManager::DisconnectSco()
 {
   if (!IsScoConnected()) {
     BT_WARNING("SCO has been already disconnected.");
     return false;
   }
 
-  mScoSocket->Disconnect();
+  mScoSocket->Close();
   return true;
 }
 
 bool
 BluetoothHfpManager::ListenSco()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
@@ -2022,20 +2029,25 @@ BluetoothHfpManager::ListenSco()
   }
 
   if (mScoSocket->GetConnectionStatus() ==
       SocketConnectionStatus::SOCKET_LISTENING) {
     BT_WARNING("SCO socket has been already listening");
     return false;
   }
 
-  mScoSocket->Disconnect();
+  mScoSocket->Close();
 
-  if (!mScoSocket->Listen(NS_LITERAL_STRING("Handsfree Audio Gateway SCO"),
-                          kUnknownService, -1)) {
+  nsresult rv = mScoSocket->Listen(
+    NS_LITERAL_STRING("Handsfree Audio Gateway SCO"),
+    kUnknownService,
+    BluetoothSocketType::SCO,
+    -1, true, false);
+
+  if (NS_FAILED(rv)) {
     BT_WARNING("Can't listen on SCO socket!");
     return false;
   }
 
   mScoSocketStatus = mScoSocket->GetConnectionStatus();
   return true;
 }
 
--- a/dom/bluetooth/bluez/BluetoothOppManager.cpp
+++ b/dom/bluetooth/bluez/BluetoothOppManager.cpp
@@ -180,43 +180,45 @@ public:
   }
 
   void Run() override
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     if (mSocket->GetConnectionStatus() ==
         SocketConnectionStatus::SOCKET_CONNECTED) {
-      mSocket->Disconnect();
+      mSocket->Close();
     }
   }
 
 private:
   nsRefPtr<BluetoothSocket> mSocket;
 };
 
-BluetoothOppManager::BluetoothOppManager() : mConnected(false)
-                                           , mRemoteObexVersion(0)
-                                           , mRemoteConnectionFlags(0)
-                                           , mRemoteMaxPacketLength(0)
-                                           , mLastCommand(0)
-                                           , mPacketLength(0)
-                                           , mPutPacketReceivedLength(0)
-                                           , mBodySegmentLength(0)
-                                           , mAbortFlag(false)
-                                           , mNewFileFlag(false)
-                                           , mPutFinalFlag(false)
-                                           , mSendTransferCompleteFlag(false)
-                                           , mSuccessFlag(false)
-                                           , mIsServer(true)
-                                           , mWaitingForConfirmationFlag(false)
-                                           , mFileLength(0)
-                                           , mSentFileLength(0)
-                                           , mWaitingToSendPutFinal(false)
-                                           , mCurrentBlobIndex(-1)
+BluetoothOppManager::BluetoothOppManager()
+  : mConnected(false)
+  , mRemoteObexVersion(0)
+  , mRemoteConnectionFlags(0)
+  , mRemoteMaxPacketLength(0)
+  , mLastCommand(0)
+  , mPacketLength(0)
+  , mPutPacketReceivedLength(0)
+  , mBodySegmentLength(0)
+  , mAbortFlag(false)
+  , mNewFileFlag(false)
+  , mPutFinalFlag(false)
+  , mSendTransferCompleteFlag(false)
+  , mSuccessFlag(false)
+  , mIsServer(true)
+  , mWaitingForConfirmationFlag(false)
+  , mFileLength(0)
+  , mSentFileLength(0)
+  , mWaitingToSendPutFinal(false)
+  , mCurrentBlobIndex(-1)
+  , mSocketType(static_cast<BluetoothSocketType>(0))
 {
   mConnectedDeviceAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE);
 }
 
 BluetoothOppManager::~BluetoothOppManager()
 {
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   NS_ENSURE_TRUE_VOID(obs);
@@ -264,22 +266,22 @@ BluetoothOppManager::Get()
 
 void
 BluetoothOppManager::ConnectInternal(const nsAString& aDeviceAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   // Stop listening because currently we only support one connection at a time.
   if (mRfcommSocket) {
-    mRfcommSocket->Disconnect();
+    mRfcommSocket->Close();
     mRfcommSocket = nullptr;
   }
 
   if (mL2capSocket) {
-    mL2capSocket->Disconnect();
+    mL2capSocket->Close();
     mL2capSocket = nullptr;
   }
 
   mIsServer = false;
 
   BluetoothService* bs = BluetoothService::Get();
   if (!bs || sInShutdown || mSocket) {
     OnSocketConnectError(mSocket);
@@ -291,18 +293,18 @@ BluetoothOppManager::ConnectInternal(con
   nsString uuid;
   BluetoothUuidHelper::GetString(BluetoothServiceClass::OBJECT_PUSH, uuid);
 
   if (NS_FAILED(bs->GetServiceChannel(aDeviceAddress, uuid, this))) {
     OnSocketConnectError(mSocket);
     return;
   }
 
-  mSocket =
-    new BluetoothSocket(this, BluetoothSocketType::RFCOMM, true, true);
+  mSocket = new BluetoothSocket(this);
+  mSocketType = BluetoothSocketType::RFCOMM;
 }
 
 void
 BluetoothOppManager::HandleShutdown()
 {
   MOZ_ASSERT(NS_IsMainThread());
   sInShutdown = true;
   Disconnect(nullptr);
@@ -315,37 +317,45 @@ BluetoothOppManager::Listen()
   MOZ_ASSERT(NS_IsMainThread());
 
   if (mSocket) {
     BT_WARNING("mSocket exists. Failed to listen.");
     return false;
   }
 
   if (!mRfcommSocket) {
-    mRfcommSocket =
-      new BluetoothSocket(this, BluetoothSocketType::RFCOMM, true, true);
+    mRfcommSocket = new BluetoothSocket(this);
 
-    if (!mRfcommSocket->Listen(NS_LITERAL_STRING("OBEX Object Push"),
-                               kObexObjectPush,
-                               BluetoothReservedChannels::CHANNEL_OPUSH)) {
+    nsresult rv = mRfcommSocket->Listen(
+      NS_LITERAL_STRING("OBEX Object Push"),
+      kObexObjectPush,
+      BluetoothSocketType::RFCOMM,
+      BluetoothReservedChannels::CHANNEL_OPUSH,
+      true, true);
+
+    if (NS_FAILED(rv)) {
       BT_WARNING("[OPP] Can't listen on RFCOMM socket!");
       mRfcommSocket = nullptr;
       return false;
     }
   }
 
   if (!mL2capSocket) {
-    mL2capSocket =
-      new BluetoothSocket(this, BluetoothSocketType::EL2CAP, true, true);
+    mL2capSocket = new BluetoothSocket(this);
 
-    if (!mL2capSocket->Listen(NS_LITERAL_STRING("OBEX Object Push"),
-                              kObexObjectPush,
-                              BluetoothReservedChannels::CHANNEL_OPUSH_L2CAP)) {
+    nsresult rv = mL2capSocket->Listen(
+      NS_LITERAL_STRING("OBEX Object Push"),
+      kObexObjectPush,
+      BluetoothSocketType::EL2CAP,
+      BluetoothReservedChannels::CHANNEL_OPUSH_L2CAP,
+      true, true);
+
+    if (NS_FAILED(rv)) {
       BT_WARNING("[OPP] Can't listen on L2CAP socket!");
-      mRfcommSocket->Disconnect();
+      mRfcommSocket->Close();
       mRfcommSocket = nullptr;
       mL2capSocket = nullptr;
       return false;
     }
   }
 
   mIsServer = true;
 
@@ -1527,24 +1537,26 @@ BluetoothOppManager::OnSocketConnectSucc
    * If the created connection is an inbound connection, close another server
    * socket because currently only one file-transfer session is allowed. After
    * that, we need to make sure that both server socket would be nulled out.
    * As for outbound connections, we just notify the controller that it's done.
    */
   if (aSocket == mRfcommSocket) {
     MOZ_ASSERT(!mSocket);
     mRfcommSocket.swap(mSocket);
+    mSocketType = BluetoothSocketType::RFCOMM;
 
-    mL2capSocket->Disconnect();
+    mL2capSocket->Close();
     mL2capSocket = nullptr;
   } else if (aSocket == mL2capSocket) {
     MOZ_ASSERT(!mSocket);
     mL2capSocket.swap(mSocket);
+    mSocketType = BluetoothSocketType::EL2CAP;
 
-    mRfcommSocket->Disconnect();
+    mRfcommSocket->Close();
     mRfcommSocket = nullptr;
   }
 
   // Cache device address since we can't get socket address when a remote
   // device disconnect with us.
   mSocket->GetAddress(mConnectedDeviceAddress);
 
   // Start sending file if we connect as a client
@@ -1556,16 +1568,17 @@ BluetoothOppManager::OnSocketConnectSucc
 void
 BluetoothOppManager::OnSocketConnectError(BluetoothSocket* aSocket)
 {
   BT_LOGR("[%s]", (mIsServer)? "server" : "client");
 
   mRfcommSocket = nullptr;
   mL2capSocket = nullptr;
   mSocket = nullptr;
+  mSocketType = static_cast<BluetoothSocketType>(0);
 
   if (!mIsServer) {
     // Inform gaia of remaining blobs' sending failure
     DiscardBlobsToSend();
   }
 
   // Listen as a server if there's no more batch to process
   if (!ProcessNextBatch() && !mIsServer) {
@@ -1603,27 +1616,29 @@ BluetoothOppManager::OnSocketDisconnect(
     }
   }
 
   AfterOppDisconnected();
   mConnectedDeviceAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE);
   mSuccessFlag = false;
 
   mSocket = nullptr;
+  mSocketType = static_cast<BluetoothSocketType>(0);
+
   // Listen as a server if there's no more batch to process
   if (!ProcessNextBatch()) {
     Listen();
   }
 }
 
 void
 BluetoothOppManager::Disconnect(BluetoothProfileController* aController)
 {
   if (mSocket) {
-    mSocket->Disconnect();
+    mSocket->Close();
   } else {
     BT_WARNING("%s: No ongoing file transfer to stop", __FUNCTION__);
   }
 }
 
 void
 BluetoothOppManager::OnGetServiceChannel(const nsAString& aDeviceAddress,
                                          const nsAString& aServiceUuid,
@@ -1649,17 +1664,19 @@ BluetoothOppManager::OnGetServiceChannel
       } else {
         OnSocketConnectError(mSocket);
       }
     }
 
     return;
   }
 
-  if (!mSocket->Connect(aDeviceAddress, kObexObjectPush, aChannel)) {
+  nsresult rv = mSocket->Connect(aDeviceAddress, kObexObjectPush,
+                                 mSocketType, aChannel, true, true);
+  if (NS_FAILED(rv)) {
     OnSocketConnectError(mSocket);
   }
 }
 
 void
 BluetoothOppManager::OnUpdateSdpRecords(const nsAString& aDeviceAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
--- a/dom/bluetooth/bluez/BluetoothOppManager.h
+++ b/dom/bluetooth/bluez/BluetoothOppManager.h
@@ -214,16 +214,18 @@ private:
   nsRefPtr<BluetoothSocket> mSocket;
 
   // Server sockets. Once an inbound connection is established, it will hand
   // over the ownership to mSocket, and get a new server socket while Listen()
   // is called.
   nsRefPtr<BluetoothSocket> mRfcommSocket;
   nsRefPtr<BluetoothSocket> mL2capSocket;
 
+  BluetoothSocketType mSocketType;
+
   // This holds the time when OPP manager fail to get service channel and
   // prepare to refresh SDP records.
   mozilla::TimeStamp mLastServiceChannelCheck;
 };
 
 END_BLUETOOTH_NAMESPACE
 
 #endif
--- a/dom/bluetooth/bluez/BluetoothSocket.cpp
+++ b/dom/bluetooth/bluez/BluetoothSocket.cpp
@@ -552,78 +552,79 @@ public:
     XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new ConnectTask(io));
   }
 };
 
 //
 // BluetoothSocket
 //
 
-BluetoothSocket::BluetoothSocket(BluetoothSocketObserver* aObserver,
-                                 BluetoothSocketType aType,
-                                 bool aAuth,
-                                 bool aEncrypt)
+BluetoothSocket::BluetoothSocket(BluetoothSocketObserver* aObserver)
   : mObserver(aObserver)
-  , mType(aType)
-  , mAuth(aAuth)
-  , mEncrypt(aEncrypt)
   , mIO(nullptr)
 {
   MOZ_ASSERT(aObserver);
 }
 
 BluetoothSocket::~BluetoothSocket()
 {
   MOZ_ASSERT(!mIO);
 }
 
-bool
+nsresult
 BluetoothSocket::Connect(const nsAString& aDeviceAddress,
                          const BluetoothUuid& aServiceUuid,
-                         int aChannel)
+                         BluetoothSocketType aType,
+                         int aChannel,
+                         bool aAuth, bool aEncrypt)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!aDeviceAddress.IsEmpty());
 
-  nsAutoPtr<BluetoothUnixSocketConnector> c(
+  nsAutoPtr<BluetoothUnixSocketConnector> connector(
     new BluetoothUnixSocketConnector(NS_ConvertUTF16toUTF8(aDeviceAddress),
-                                     mType, aChannel, mAuth, mEncrypt));
+                                     aType, aChannel, aAuth, aEncrypt));
 
-  if (!ConnectSocket(c.forget(),
-                     NS_ConvertUTF16toUTF8(aDeviceAddress).BeginReading())) {
+  nsresult rv = Connect(connector);
+  if (NS_FAILED(rv)) {
     nsAutoString addr;
     GetAddress(addr);
     BT_LOGD("%s failed. Current connected device address: %s",
            __FUNCTION__, NS_ConvertUTF16toUTF8(addr).get());
-    return false;
+    return rv;
   }
+  connector.forget();
 
-  return true;
+  return NS_OK;
 }
 
-bool
+nsresult
 BluetoothSocket::Listen(const nsAString& aServiceName,
                         const BluetoothUuid& aServiceUuid,
-                        int aChannel)
+                        BluetoothSocketType aType,
+                        int aChannel,
+                        bool aAuth, bool aEncrypt)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  nsAutoPtr<BluetoothUnixSocketConnector> c(
+  nsAutoPtr<BluetoothUnixSocketConnector> connector(
     new BluetoothUnixSocketConnector(NS_LITERAL_CSTRING(BLUETOOTH_ADDRESS_NONE),
-                                     mType, aChannel, mAuth, mEncrypt));
+                                     aType, aChannel, aAuth, aEncrypt));
 
-  if (!ListenSocket(c.forget())) {
+  nsresult rv = Listen(connector);
+  if (NS_FAILED(rv)) {
     nsAutoString addr;
     GetAddress(addr);
     BT_LOGD("%s failed. Current connected device address: %s",
            __FUNCTION__, NS_ConvertUTF16toUTF8(addr).get());
-    return false;
+    return rv;
   }
+  connector.forget();
 
-  return true;
+  return NS_OK;
 }
 
 void
 BluetoothSocket::ReceiveSocketData(nsAutoPtr<UnixSocketBuffer>& aBuffer)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mObserver);
 
@@ -637,75 +638,62 @@ BluetoothSocket::SendSocketData(const ns
     return false;
   }
 
   SendSocketData(new UnixSocketRawData(aStr.BeginReading(), aStr.Length()));
 
   return true;
 }
 
-void
-BluetoothSocket::GetSocketAddr(nsAString& aAddrStr)
+nsresult
+BluetoothSocket::Connect(BluetoothUnixSocketConnector* aConnector,
+                         int aDelayMs)
 {
-  aAddrStr.Truncate();
-  if (!mIO || GetConnectionStatus() != SOCKET_CONNECTED) {
-    NS_WARNING("No socket currently open!");
-    return;
-  }
-  mIO->GetSocketAddr(aAddrStr);
-}
-
-bool
-BluetoothSocket::ConnectSocket(BluetoothUnixSocketConnector* aConnector,
-                               const char* aAddress,
-                               int aDelayMs)
-{
+  MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aConnector);
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsAutoPtr<UnixSocketConnector> connector(aConnector);
-
-  if (mIO) {
-    NS_WARNING("Socket already connecting/connected!");
-    return false;
-  }
+  MOZ_ASSERT(!mIO);
 
   MessageLoop* ioLoop = XRE_GetIOMessageLoop();
-  mIO = new BluetoothSocketIO(ioLoop, this, connector.forget());
+  mIO = new BluetoothSocketIO(ioLoop, this, aConnector);
   SetConnectionStatus(SOCKET_CONNECTING);
   if (aDelayMs > 0) {
     DelayedConnectTask* connectTask = new DelayedConnectTask(mIO);
     mIO->SetDelayedConnectTask(connectTask);
     MessageLoop::current()->PostDelayedTask(FROM_HERE, connectTask, aDelayMs);
   } else {
     ioLoop->PostTask(FROM_HERE, new ConnectTask(mIO));
   }
-  return true;
+  return NS_OK;
 }
 
-bool
-BluetoothSocket::ListenSocket(BluetoothUnixSocketConnector* aConnector)
+nsresult
+BluetoothSocket::Listen(BluetoothUnixSocketConnector* aConnector)
 {
-  MOZ_ASSERT(aConnector);
   MOZ_ASSERT(NS_IsMainThread());
-
-  nsAutoPtr<UnixSocketConnector> connector(aConnector);
-
-  if (mIO) {
-    NS_WARNING("Socket already connecting/connected!");
-    return false;
-  }
+  MOZ_ASSERT(aConnector);
+  MOZ_ASSERT(!mIO);
 
   MessageLoop* ioLoop = XRE_GetIOMessageLoop();
 
-  mIO = new BluetoothSocketIO(ioLoop, this, connector.forget());
+  mIO = new BluetoothSocketIO(ioLoop, this, aConnector);
   SetConnectionStatus(SOCKET_LISTENING);
   ioLoop->PostTask(FROM_HERE, new ListenTask(mIO));
 
-  return true;
+  return NS_OK;
+}
+
+void
+BluetoothSocket::GetAddress(nsAString& aAddrStr)
+{
+  aAddrStr.Truncate();
+  if (!mIO || GetConnectionStatus() != SOCKET_CONNECTED) {
+    NS_WARNING("No socket currently open!");
+    return;
+  }
+  mIO->GetSocketAddr(aAddrStr);
 }
 
 // |DataSocket|
 
 void
 BluetoothSocket::SendSocketData(UnixSocketIOBuffer* aBuffer)
 {
   MOZ_ASSERT(NS_IsMainThread());
--- a/dom/bluetooth/bluez/BluetoothSocket.h
+++ b/dom/bluetooth/bluez/BluetoothSocket.h
@@ -19,37 +19,30 @@
 BEGIN_BLUETOOTH_NAMESPACE
 
 class BluetoothSocketObserver;
 class BluetoothUnixSocketConnector;
 
 class BluetoothSocket final : public mozilla::ipc::DataSocket
 {
 public:
-  BluetoothSocket(BluetoothSocketObserver* aObserver,
-                  BluetoothSocketType aType,
-                  bool aAuth,
-                  bool aEncrypt);
+  BluetoothSocket(BluetoothSocketObserver* aObserver);
   ~BluetoothSocket();
 
-  bool Connect(const nsAString& aDeviceAddress,
-               const BluetoothUuid& aServiceUuid,
-               int aChannel);
-  bool Listen(const nsAString& aServiceName,
-              const BluetoothUuid& aServiceUuid,
-              int aChannel);
-  inline void Disconnect()
-  {
-    Close();
-  }
+  nsresult Connect(const nsAString& aDeviceAddress,
+                   const BluetoothUuid& aServiceUuid,
+                   BluetoothSocketType aType,
+                   int aChannel,
+                   bool aAuth, bool aEncrypt);
 
-  inline void GetAddress(nsAString& aDeviceAddress)
-  {
-    GetSocketAddr(aDeviceAddress);
-  }
+  nsresult Listen(const nsAString& aServiceName,
+                  const BluetoothUuid& aServiceUuid,
+                  BluetoothSocketType aType,
+                  int aChannel,
+                  bool aAuth, bool aEncrypt);
 
   /**
    * Method to be called whenever data is received. This is only called on the
    * main thread.
    *
    * @param aBuffer Data received from the socket.
    */
   void ReceiveSocketData(nsAutoPtr<mozilla::ipc::UnixSocketBuffer>& aBuffer);
@@ -65,39 +58,37 @@ public:
    */
   bool SendSocketData(const nsACString& aMessage);
 
   /**
    * Starts a task on the socket that will try to connect to a socket in a
    * non-blocking manner.
    *
    * @param aConnector Connector object for socket type specific functions
-   * @param aAddress Address to connect to.
    * @param aDelayMs Time delay in milli-seconds.
-   *
-   * @return true on connect task started, false otherwise.
+   * @return NS_OK on success, or an XPCOM error code otherwise.
    */
-  bool ConnectSocket(BluetoothUnixSocketConnector* aConnector,
-                     const char* aAddress,
-                     int aDelayMs = 0);
+  nsresult Connect(BluetoothUnixSocketConnector* aConnector,
+                   int aDelayMs = 0);
 
   /**
    * Starts a task on the socket that will try to accept a new connection in a
    * non-blocking manner.
    *
    * @param aConnector Connector object for socket type specific functions
-   *
-   * @return true on listen started, false otherwise
+   * @return NS_OK on success, or an XPCOM error code otherwise.
    */
-  bool ListenSocket(BluetoothUnixSocketConnector* aConnector);
+  nsresult Listen(BluetoothUnixSocketConnector* aConnector);
 
   /**
-   * Get the current sockaddr for the socket
+   * Get the current socket address.
+   *
+   * @param[out] aDeviceAddress Returns the address string.
    */
-  void GetSocketAddr(nsAString& aAddrStr);
+  void GetAddress(nsAString& aDeviceAddress);
 
   // Methods for |DataSocket|
   //
 
   void SendSocketData(mozilla::ipc::UnixSocketIOBuffer* aBuffer) override;
 
   // Methods for |SocketBase|
   //
@@ -110,17 +101,14 @@ public:
 
 private:
   class BluetoothSocketIO;
   class ConnectTask;
   class DelayedConnectTask;
   class ListenTask;
 
   BluetoothSocketObserver* mObserver;
-  BluetoothSocketType mType;
-  bool mAuth;
-  bool mEncrypt;
   BluetoothSocketIO* mIO;
 };
 
 END_BLUETOOTH_NAMESPACE
 
 #endif
--- a/dom/bluetooth/bluez/BluetoothUnixSocketConnector.cpp
+++ b/dom/bluetooth/bluez/BluetoothUnixSocketConnector.cpp
@@ -73,19 +73,23 @@ BluetoothUnixSocketConnector::CreateSock
     [BluetoothSocketType::SCO] = BTPROTO_SCO,
     [BluetoothSocketType::L2CAP] = BTPROTO_L2CAP,
     [BluetoothSocketType::EL2CAP] = BTPROTO_L2CAP
   };
 
   MOZ_ASSERT(mType < MOZ_ARRAY_LENGTH(sType));
   MOZ_ASSERT(mType < MOZ_ARRAY_LENGTH(sProtocol));
 
+  BT_LOGR("mType=%d, sType=%d sProtocol=%d",
+          static_cast<int>(mType), sType[mType], sProtocol[mType]);
+
   aFd = socket(AF_BLUETOOTH, sType[mType], sProtocol[mType]);
   if (aFd < 0) {
-    BT_LOGR("Could not open Bluetooth socket!");
+    BT_LOGR("Could not open Bluetooth socket: %d(%s)",
+            errno, strerror(errno));
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
 nsresult
 BluetoothUnixSocketConnector::SetSocketFlags(int aFd) const
@@ -315,16 +319,19 @@ BluetoothUnixSocketConnector::ConvertAdd
       break;
     case BluetoothSocketType::L2CAP:
     case BluetoothSocketType::EL2CAP: {
         const struct sockaddr_l2* l2 =
           reinterpret_cast<const struct sockaddr_l2*>(&aAddress);
         b = l2->l2_bdaddr.b;
       }
       break;
+    default:
+      BT_LOGR("Unknown socket type %d", static_cast<int>(mType));
+      return NS_ERROR_ILLEGAL_VALUE;
   }
 
   char str[32];
   snprintf(str, sizeof(str), "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
            b[5], b[4], b[3], b[2], b[1], b[0]);
 
   aAddressString.Assign(str);
 
--- a/dom/icc/tests/marionette/test_icc_contact_add.js
+++ b/dom/icc/tests/marionette/test_icc_contact_add.js
@@ -1,36 +1,59 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 MARIONETTE_TIMEOUT = 90000;
 MARIONETTE_HEAD_JS = "head.js";
 
 let TEST_ADD_DATA = [{
-    name: ["add"],
+    // a contact without email and anr.
+    name: ["add1"],
     tel: [{value: "0912345678"}],
-    email:[]
+  }, {
+    // a contact over 20 digits.
+    name: ["add2"],
+    tel: [{value: "012345678901234567890123456789"}],
+  }, {
+    // a contact with email but without anr.
+    name: ["add3"],
+    tel: [{value: "01234567890123456789"}],
+    email:[{value: "test@mozilla.com"}],
+  }, {
+    // a contact with anr but without email.
+    name: ["add4"],
+    tel: [{value: "01234567890123456789"}, {value: "123456"}, {value: "123"}],
+  }, {
+    // a contact with email and anr.
+    name: ["add5"],
+    tel: [{value: "01234567890123456789"}, {value: "123456"}, {value: "123"}],
+    email:[{value: "test@mozilla.com"}],
   }];
 
 function testAddContact(aIcc, aType, aMozContact, aPin2) {
   log("testAddContact: type=" + aType + ", pin2=" + aPin2);
   let contact = new mozContact(aMozContact);
 
   return aIcc.updateContact(aType, contact, aPin2)
     .then((aResult) => {
       is(aResult.name[0], aMozContact.name[0]);
-      is(aResult.tel[0].value, aMozContact.tel[0].value);
+      // Maximum digits of the Dialling Number is 20.
+      is(aResult.tel[0].value, aMozContact.tel[0].value.substring(0, 20));
+      // We only support SIM in emulator, so we don't have anr and email field.
+      ok(aResult.tel.length == 1);
+      ok(!aResult.email);
 
       // Get ICC contact for checking new contact
       return aIcc.readContacts(aType)
         .then((aResult) => {
           let contact = aResult[aResult.length - 1];
 
           is(contact.name[0], aMozContact.name[0]);
-          is(contact.tel[0].value, aMozContact.tel[0].value);
+          // Maximum digits of the Dialling Number is 20.
+          is(contact.tel[0].value, aMozContact.tel[0].value.substring(0, 20));
           is(contact.id, aIcc.iccInfo.iccid + aResult.length);
 
           return contact.id;
         })
         .then((aContactId) => {
           // Clean up contact
           return removeContact(aIcc, aContactId, aType, aPin2);
         });
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -792,20 +792,21 @@ RilObject.prototype = {
    * Update UICC Phonebook.
    *
    * @param contactType   One of GECKO_CARDCONTACT_TYPE_*.
    * @param contact       The contact will be updated.
    * @param pin2          PIN2 is required for updating FDN.
    * @param requestId     Request id from RadioInterfaceLayer.
    */
   updateICCContact: function(options) {
-    let onsuccess = function onsuccess() {
+    let onsuccess = function onsuccess(updatedContact) {
       let recordIndex =
-        contact.pbrIndex * ICC_MAX_LINEAR_FIXED_RECORDS + contact.recordId;
-      contact.contactId = this.iccInfo.iccid + recordIndex;
+        updatedContact.pbrIndex * ICC_MAX_LINEAR_FIXED_RECORDS + updatedContact.recordId;
+      updatedContact.contactId = this.iccInfo.iccid + recordIndex;
+      options.contact = updatedContact;
       // Reuse 'options' to get 'requestId' and 'contactType'.
       this.sendChromeMessage(options);
     }.bind(this);
 
     let onerror = function onerror(errorMsg) {
       options.errorMsg = errorMsg;
       this.sendChromeMessage(options);
     }.bind(this);
@@ -9353,16 +9354,18 @@ ICCPDUHelperObject.prototype = {
   },
 
   /**
    * Write GSM 8-bit unpacked octets.
    *
    * @param numOctets   Number of total octets to be writen, including trailing
    *                    0xff.
    * @param str         String to be written. Could be null.
+   *
+   * @return The string has been written into Buf.
    */
   writeStringTo8BitUnpacked: function(numOctets, str) {
     const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
     const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
 
     let GsmPDUHelper = this.context.GsmPDUHelper;
 
     // If the character is GSM extended alphabet, two octets will be written.
@@ -9391,29 +9394,32 @@ ICCPDUHelperObject.prototype = {
       GsmPDUHelper.writeHexOctet(octet);
       j++;
     }
 
     // trailing 0xff
     while (j++ < numOctets) {
       GsmPDUHelper.writeHexOctet(0xff);
     }
+
+    return (str) ? str.substring(0, i) : null;
   },
 
   /**
    * Write UCS2 String on UICC.
    * The default choose 0x81 or 0x82 encode, otherwise use 0x80 encode.
    *
    * @see TS 102.221, Annex A.
    * @param numOctets
    *        Total number of octets to be written. This includes the length of
    *        alphaId and the length of trailing unused octets(0xff).
    * @param str
    *        String to be written.
    *
+   * @return The string has been written into Buf.
    */
   writeICCUCS2String: function(numOctets, str) {
     let GsmPDUHelper = this.context.GsmPDUHelper;
     let scheme = 0x80;
     let basePointer;
 
     if (str.length > 2) {
       let min = 0xFFFF;
@@ -9463,17 +9469,17 @@ ICCPDUHelperObject.prototype = {
           str = str.substring(0, Math.floor(numOctets / 2));
         }
         GsmPDUHelper.writeUCS2String(str);
 
         // trailing 0xff
         for (let i = str.length * 2; i < numOctets; i++) {
           GsmPDUHelper.writeHexOctet(0xff);
         }
-        return;
+        return str;
       }
       /**
        * +------+-----+--------------+-----+-----+-----+--------+------+
        * | 0x81 | len | base_pointer | Ch1 | Ch2 | ... | Ch_len | 0xff |
        * +------+-----+--------------+-----+-----+-----+--------+------+
        *
        * len: The length of characters.
        * base_pointer: 0hhh hhhh h000 0000
@@ -9536,16 +9542,17 @@ ICCPDUHelperObject.prototype = {
         }
       }
 
       // trailing 0xff
       for (let i = 0; i < numOctets - str.length; i++) {
         GsmPDUHelper.writeHexOctet(0xff);
       }
     }
+    return str;
   },
 
  /**
    * Read UCS2 String on UICC.
    *
    * @see TS 101.221, Annex A.
    * @param scheme
    *        Coding scheme for UCS2 on UICC. One of 0x80, 0x81 or 0x82.
@@ -9670,33 +9677,39 @@ ICCPDUHelperObject.prototype = {
   },
 
   /**
    * Write Alpha Identifier and Dialling number from TS 151.011 clause 10.5.1
    *
    * @param recordSize  The size of linear fixed record.
    * @param alphaId     Alpha Identifier to be written.
    * @param number      Dialling Number to be written.
+   *
+   * @return An object contains the alphaId and number
+   *         that have been written into Buf.
    */
   writeAlphaIdDiallingNumber: function(recordSize, alphaId, number) {
     let Buf = this.context.Buf;
     let GsmPDUHelper = this.context.GsmPDUHelper;
 
     // Write String length
     let strLen = recordSize * 2;
     Buf.writeInt32(strLen);
 
     let alphaLen = recordSize - ADN_FOOTER_SIZE_BYTES;
-    this.writeAlphaIdentifier(alphaLen, alphaId);
-    this.writeNumberWithLength(number);
+    let writtenAlphaId = this.writeAlphaIdentifier(alphaLen, alphaId);
+    let writtenNumber = this.writeNumberWithLength(number);
 
     // Write unused octets 0xff, CCP and EXT1.
     GsmPDUHelper.writeHexOctet(0xff);
     GsmPDUHelper.writeHexOctet(0xff);
     Buf.writeStringDelimiter(strLen);
+
+    return {alphaId: writtenAlphaId,
+            number: writtenNumber};
   },
 
   /**
    * Read Alpha Identifier.
    *
    * @see TS 131.102
    *
    * @param numOctets
@@ -9731,28 +9744,30 @@ ICCPDUHelperObject.prototype = {
    * Write Alpha Identifier.
    *
    * @param numOctets
    *        Total number of octets to be written. This includes the length of
    *        alphaId and the length of trailing unused octets(0xff).
    * @param alphaId
    *        Alpha Identifier to be written.
    *
+   * @return The Alpha Identifier has been written into Buf.
+   *
    * Unused octets will be written as 0xff.
    */
   writeAlphaIdentifier: function(numOctets, alphaId) {
     if (numOctets === 0) {
-      return;
+      return null;
     }
 
     // If alphaId is empty or it's of GSM 8 bit.
     if (!alphaId || this.context.ICCUtilsHelper.isGsm8BitAlphabet(alphaId)) {
-      this.writeStringTo8BitUnpacked(numOctets, alphaId);
+      return this.writeStringTo8BitUnpacked(numOctets, alphaId);
     } else {
-      this.writeICCUCS2String(numOctets, alphaId);
+      return this.writeICCUCS2String(numOctets, alphaId);
     }
   },
 
   /**
    * Read Dialling number.
    *
    * @see TS 131.102
    *
@@ -9829,47 +9844,55 @@ ICCPDUHelperObject.prototype = {
       Buf.seekIncoming((ADN_MAX_BCD_NUMBER_BYTES - numLen) * Buf.PDU_HEX_OCTET_SIZE);
     } else {
       Buf.seekIncoming(ADN_MAX_BCD_NUMBER_BYTES * Buf.PDU_HEX_OCTET_SIZE);
     }
 
     return number;
   },
 
+  /**
+   * Write Number with Length
+   *
+   * @param number The value to be written.
+   *
+   * @return The number has been written into Buf.
+   */
   writeNumberWithLength: function(number) {
     let GsmPDUHelper = this.context.GsmPDUHelper;
 
     if (number) {
       let numStart = number[0] == "+" ? 1 : 0;
-      number = number.substring(0, numStart) +
-               number.substring(numStart)
-                     .replace(/[^0-9*#,]/g, "")
-                     .replace(/\*/g, "a")
-                     .replace(/\#/g, "b")
-                     .replace(/\,/g, "c");
-
-      let numDigits = number.length - numStart;
+      let writtenNumber = number.substring(0, numStart) +
+                          number.substring(numStart)
+                                .replace(/[^0-9*#,]/g, "");
+
+      let numDigits = writtenNumber.length - numStart;
       if (numDigits > ADN_MAX_NUMBER_DIGITS) {
-        number = number.substring(0, ADN_MAX_NUMBER_DIGITS + numStart);
-        numDigits = number.length - numStart;
+        writtenNumber = writtenNumber.substring(0, ADN_MAX_NUMBER_DIGITS + numStart);
+        numDigits = writtenNumber.length - numStart;
       }
 
       // +1 for TON/NPI
       let numLen = Math.ceil(numDigits / 2) + 1;
       GsmPDUHelper.writeHexOctet(numLen);
-      this.writeDiallingNumber(number);
+      this.writeDiallingNumber(writtenNumber.replace(/\*/g, "a")
+                                            .replace(/\#/g, "b")
+                                            .replace(/\,/g, "c"));
       // Write trailing 0xff of Dialling Number.
       for (let i = 0; i < ADN_MAX_BCD_NUMBER_BYTES - numLen; i++) {
         GsmPDUHelper.writeHexOctet(0xff);
       }
+      return writtenNumber;
     } else {
       // +1 for numLen
       for (let i = 0; i < ADN_MAX_BCD_NUMBER_BYTES + 1; i++) {
         GsmPDUHelper.writeHexOctet(0xff);
       }
+      return null;
     }
   }
 };
 
 function StkCommandParamsFactoryObject(aContext) {
   this.context = aContext;
 }
 StkCommandParamsFactoryObject.prototype = {
@@ -12263,25 +12286,26 @@ ICCRecordHelperObject.prototype = {
    *
    * @param fileId      EF id of the ADN or FDN.
    * @param contact     The contact will be updated. (Shall have recordId property)
    * @param pin2        PIN2 is required when updating ICC_EF_FDN.
    * @param onsuccess   Callback to be called when success.
    * @param onerror     Callback to be called when error.
    */
   updateADNLike: function(fileId, contact, pin2, onsuccess, onerror) {
+    let updatedContact;
     function dataWriter(recordSize) {
-      this.context.ICCPDUHelper.writeAlphaIdDiallingNumber(recordSize,
-                                                           contact.alphaId,
-                                                           contact.number);
+      updatedContact = this.context.ICCPDUHelper.writeAlphaIdDiallingNumber(recordSize,
+                                                                            contact.alphaId,
+                                                                            contact.number);
     }
 
     function callback(options) {
       if (onsuccess) {
-        onsuccess();
+        onsuccess(updatedContact);
       }
     }
 
     if (!contact || !contact.recordId) {
       if (onerror) onerror(GECKO_ERROR_INVALID_PARAMETER);
       return;
     }
 
@@ -12506,41 +12530,48 @@ ICCRecordHelperObject.prototype = {
    * @param email        The value to be written.
    * @param adnRecordId  The record Id of ADN, only needed if the fileType of Email is TYPE2.
    * @param onsuccess    Callback to be called when success.
    * @param onerror      Callback to be called when error.
    */
   updateEmail: function(pbr, recordNumber, email, adnRecordId, onsuccess, onerror) {
     let fileId = pbr[USIM_PBR_EMAIL].fileId;
     let fileType = pbr[USIM_PBR_EMAIL].fileType;
+    let writtenEmail;
     let dataWriter = function dataWriter(recordSize) {
       let Buf = this.context.Buf;
       let GsmPDUHelper = this.context.GsmPDUHelper;
       let ICCPDUHelper = this.context.ICCPDUHelper;
 
       // Write String length
       let strLen = recordSize * 2;
       Buf.writeInt32(strLen);
 
       if (fileType == ICC_USIM_TYPE1_TAG) {
-        ICCPDUHelper.writeStringTo8BitUnpacked(recordSize, email);
+        writtenEmail = ICCPDUHelper.writeStringTo8BitUnpacked(recordSize, email);
       } else {
-        ICCPDUHelper.writeStringTo8BitUnpacked(recordSize - 2, email);
+        writtenEmail = ICCPDUHelper.writeStringTo8BitUnpacked(recordSize - 2, email);
         GsmPDUHelper.writeHexOctet(pbr.adn.sfi || 0xff);
         GsmPDUHelper.writeHexOctet(adnRecordId);
       }
 
       Buf.writeStringDelimiter(strLen);
     }.bind(this);
 
+    let callback = (options) => {
+      if (onsuccess) {
+        onsuccess(writtenEmail);
+      }
+    }
+
     this.context.ICCIOHelper.updateLinearFixedEF({
       fileId: fileId,
       recordNumber: recordNumber,
       dataWriter: dataWriter,
-      callback: onsuccess,
+      callback: callback,
       onerror: onerror
     });
   },
 
   /**
    * Cache EF_ANR record size.
    */
   _anrRecordSize: null,
@@ -12603,47 +12634,54 @@ ICCRecordHelperObject.prototype = {
    * @param number       The value to be written.
    * @param adnRecordId  The record Id of ADN, only needed if the fileType of Email is TYPE2.
    * @param onsuccess    Callback to be called when success.
    * @param onerror      Callback to be called when error.
    */
   updateANR: function(pbr, recordNumber, number, adnRecordId, onsuccess, onerror) {
     let fileId = pbr[USIM_PBR_ANR0].fileId;
     let fileType = pbr[USIM_PBR_ANR0].fileType;
+    let writtenNumber;
     let dataWriter = function dataWriter(recordSize) {
       let Buf = this.context.Buf;
       let GsmPDUHelper = this.context.GsmPDUHelper;
 
       // Write String length
       let strLen = recordSize * 2;
       Buf.writeInt32(strLen);
 
       // EF_AAS record Id. Unused for now.
       GsmPDUHelper.writeHexOctet(0xff);
 
-      this.context.ICCPDUHelper.writeNumberWithLength(number);
+      writtenNumber = this.context.ICCPDUHelper.writeNumberWithLength(number);
 
       // Write unused octets 0xff, CCP and EXT1.
       GsmPDUHelper.writeHexOctet(0xff);
       GsmPDUHelper.writeHexOctet(0xff);
 
       // For Type 2 there are two extra octets.
       if (fileType == ICC_USIM_TYPE2_TAG) {
         GsmPDUHelper.writeHexOctet(pbr.adn.sfi || 0xff);
         GsmPDUHelper.writeHexOctet(adnRecordId);
       }
 
       Buf.writeStringDelimiter(strLen);
     }.bind(this);
 
+    let callback = (options) => {
+      if (onsuccess) {
+        onsuccess(writtenNumber);
+      }
+    }
+
     this.context.ICCIOHelper.updateLinearFixedEF({
       fileId: fileId,
       recordNumber: recordNumber,
       dataWriter: dataWriter,
-      callback: onsuccess,
+      callback: callback,
       onerror: onerror
     });
   },
 
   /**
    * Cache the possible free record id for all files.
    */
   _freeRecordIds: null,
@@ -14755,34 +14793,40 @@ ICCContactHelperObject.prototype = {
    * @param pin2          PIN2 is required for FDN.
    * @param onsuccess     Callback to be called when success.
    * @param onerror       Callback to be called when error.
    */
   updateICCContact: function(appType, contactType, contact, pin2, onsuccess, onerror) {
     let ICCRecordHelper = this.context.ICCRecordHelper;
     let ICCUtilsHelper = this.context.ICCUtilsHelper;
 
+    let updateContactCb = (updatedContact) => {
+      updatedContact.pbrIndex = contact.pbrIndex;
+      updatedContact.recordId = contact.recordId;
+      onsuccess(updatedContact);
+    }
+
     switch (contactType) {
       case GECKO_CARDCONTACT_TYPE_ADN:
         if (!this.hasDfPhoneBook(appType)) {
-          ICCRecordHelper.updateADNLike(ICC_EF_ADN, contact, null, onsuccess, onerror);
+          ICCRecordHelper.updateADNLike(ICC_EF_ADN, contact, null, updateContactCb, onerror);
         } else {
-          this.updateUSimContact(contact, onsuccess, onerror);
+          this.updateUSimContact(contact, updateContactCb, onerror);
         }
         break;
       case GECKO_CARDCONTACT_TYPE_FDN:
         if (!pin2) {
           onerror(GECKO_ERROR_SIM_PIN2);
           return;
         }
         if (!ICCUtilsHelper.isICCServiceAvailable("FDN")) {
           onerror(CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED);
           break;
         }
-        ICCRecordHelper.updateADNLike(ICC_EF_FDN, contact, pin2, onsuccess, onerror);
+        ICCRecordHelper.updateADNLike(ICC_EF_FDN, contact, pin2, updateContactCb, onerror);
         break;
       default:
         if (DEBUG) {
           this.context.debug("Unsupported contactType :" + contactType);
         }
         onerror(CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED);
         break;
     }
@@ -15032,51 +15076,59 @@ ICCContactHelperObject.prototype = {
   /**
    * Update fields in Phonebook Reference File.
    *
    * @param pbr           Phonebook Reference File to be read.
    * @param onsuccess     Callback to be called when success.
    * @param onerror       Callback to be called when error.
    */
   updatePhonebookSet: function(pbr, contact, onsuccess, onerror) {
-    let updateAdnCb = function() {
-      this.updateSupportedPBRFields(pbr, contact, onsuccess, onerror);
+    let updateAdnCb = function(updatedContact) {
+      this.updateSupportedPBRFields(pbr, contact, (updatedContactField) => {
+        onsuccess(Object.assign(updatedContact, updatedContactField));
+      }, onerror);
     }.bind(this);
 
     this.context.ICCRecordHelper.updateADNLike(pbr.adn.fileId, contact, null,
                                                updateAdnCb, onerror);
   },
 
   /**
    * Update supported Phonebook fields.
    *
    * @param pbr         Phone Book Reference file.
    * @param contact     Contact to be updated.
    * @param onsuccess   Callback to be called when success.
    * @param onerror     Callback to be called when error.
    */
   updateSupportedPBRFields: function(pbr, contact, onsuccess, onerror) {
     let fieldIndex = 0;
+    let contactField = {};
+
     (function updateField() {
       let field = USIM_PBR_FIELDS[fieldIndex];
       fieldIndex += 1;
+
       if (!field) {
         if (onsuccess) {
-          onsuccess();
+          onsuccess(contactField);
         }
         return;
       }
 
       // Check if PBR has this field.
       if (!pbr[field]) {
         updateField.call(this);
         return;
       }
 
-      this.updateContactField(pbr, contact, field, updateField.bind(this), onerror);
+      this.updateContactField(pbr, contact, field, (fieldEntry) => {
+        contactField = Object.assign(contactField, fieldEntry);
+        updateField.call(this);
+      }, onerror);
     }).call(this);
   },
 
   /**
    * Update contact's field from USIM.
    *
    * @param pbr           The phonebook reference file.
    * @param contact       The contact needs to be updated.
@@ -15105,20 +15157,28 @@ ICCContactHelperObject.prototype = {
    * @param field         Phonebook field to be updated.
    * @param onsuccess     Callback to be called when success.
    * @param onerror       Callback to be called when error.
    */
   updateContactFieldType1: function(pbr, contact, field, onsuccess, onerror) {
     let ICCRecordHelper = this.context.ICCRecordHelper;
 
     if (field === USIM_PBR_EMAIL) {
-      ICCRecordHelper.updateEmail(pbr, contact.recordId, contact.email, null, onsuccess, onerror);
+      ICCRecordHelper.updateEmail(pbr, contact.recordId, contact.email, null,
+        (updatedEmail) => {
+          onsuccess({email: updatedEmail});
+      }, onerror);
     } else if (field === USIM_PBR_ANR0) {
       let anr = Array.isArray(contact.anr) ? contact.anr[0] : null;
-      ICCRecordHelper.updateANR(pbr, contact.recordId, anr, null, onsuccess, onerror);
+      ICCRecordHelper.updateANR(pbr, contact.recordId, anr, null,
+        (updatedANR) => {
+          // ANR could have multiple files. If we support more than one anr,
+          // we will save it as anr0, anr1,...etc.
+          onsuccess((updatedANR) ? {anr: [updatedANR]} : null);
+      }, onerror);
     } else {
      if (DEBUG) {
        this.context.debug("Unsupported field :" + field);
      }
      onerror(CONTACT_ERR_FIELD_NOT_SUPPORTED);
     }
   },
 
@@ -15159,20 +15219,28 @@ ICCContactHelperObject.prototype = {
             onsuccess();
           }
         }
         return;
       }
 
       // Case 2.
       if (field === USIM_PBR_EMAIL) {
-        ICCRecordHelper.updateEmail(pbr, recordId, contact.email, contact.recordId, onsuccess, onerror);
+        ICCRecordHelper.updateEmail(pbr, recordId, contact.email, contact.recordId,
+          (updatedEmail) => {
+            onsuccess({email: updatedEmail});
+        }, onerror);
       } else if (field === USIM_PBR_ANR0) {
         let anr = Array.isArray(contact.anr) ? contact.anr[0] : null;
-        ICCRecordHelper.updateANR(pbr, recordId, anr, contact.recordId, onsuccess, onerror);
+        ICCRecordHelper.updateANR(pbr, recordId, anr, contact.recordId,
+          (updatedANR) => {
+            // ANR could have multiple files. If we support more than one anr,
+            // we will save it as anr0, anr1,...etc.
+            onsuccess((updatedANR) ? {anr: [updatedANR]} : null);
+        }, onerror);
       } else {
         if (DEBUG) {
           this.context.debug("Unsupported field :" + field);
         }
         onerror(CONTACT_ERR_FIELD_NOT_SUPPORTED);
       }
 
     }.bind(this);
@@ -15186,26 +15254,36 @@ ICCContactHelperObject.prototype = {
    * @param pbr           The phonebook reference file.
    * @param contact       The contact needs to be updated.
    * @param field         Phonebook field to be updated.
    * @param onsuccess     Callback to be called when success.
    * @param onerror       Callback to be called when error.
    */
   addContactFieldType2: function(pbr, contact, field, onsuccess, onerror) {
     let ICCRecordHelper = this.context.ICCRecordHelper;
-
     let successCb = function successCb(recordId) {
-      let updateCb = function updateCb() {
-        this.updateContactFieldIndexInIAP(pbr, contact.recordId, field, recordId, onsuccess, onerror);
+
+      let updateCb = function updateCb(contactField) {
+        this.updateContactFieldIndexInIAP(pbr, contact.recordId, field, recordId, () => {
+          onsuccess(contactField);
+        }, onerror);
       }.bind(this);
 
       if (field === USIM_PBR_EMAIL) {
-        ICCRecordHelper.updateEmail(pbr, recordId, contact.email, contact.recordId, updateCb, onerror);
+        ICCRecordHelper.updateEmail(pbr, recordId, contact.email, contact.recordId,
+          (updatedEmail) => {
+          updateCb({email: updatedEmail});
+        }, onerror);
       } else if (field === USIM_PBR_ANR0) {
-        ICCRecordHelper.updateANR(pbr, recordId, contact.anr[0], contact.recordId, updateCb, onerror);
+        ICCRecordHelper.updateANR(pbr, recordId, contact.anr[0], contact.recordId,
+          (updatedANR) => {
+            // ANR could have multiple files. If we support more than one anr,
+            // we will save it as anr0, anr1,...etc.
+            updateCb((updatedANR) ? {anr: [updatedANR]} : null);
+        }, onerror);
       }
     }.bind(this);
 
     let errorCb = function errorCb(errorMsg) {
       if (DEBUG) {
         this.context.debug(errorMsg + " USIM field " + field);
       }
       onerror(errorMsg);
--- a/dom/system/gonk/tests/test_ril_worker_icc_ICCContactHelper.js
+++ b/dom/system/gonk/tests/test_ril_worker_icc_ICCContactHelper.js
@@ -442,17 +442,18 @@ add_test(function test_update_icc_contac
       if (aContactType === GECKO_CARDCONTACT_TYPE_FDN) {
         equal(fileId, ICC_EF_FDN);
       } else if (aContactType === GECKO_CARDCONTACT_TYPE_ADN) {
         equal(fileId, ICC_EF_ADN);
       }
       equal(pin2, aPin2);
       equal(contact.alphaId, aContact.alphaId);
       equal(contact.number, aContact.number);
-      onsuccess();
+      onsuccess({alphaId: contact.alphaId,
+                  number: contact.number});
     };
 
     recordHelper.readIAP = function(fileId, recordNumber, onsuccess, onerror) {
       equal(fileId, IAP_FILE_ID);
       equal(recordNumber, ADN_RECORD_ID);
       onsuccess((aHaveIapIndex) ? [EMAIL_RECORD_ID, ANR0_RECORD_ID]
                                 : [0xff, 0xff]);
     };
@@ -466,44 +467,60 @@ add_test(function test_update_icc_contac
     recordHelper.updateEmail = function(pbr, recordNumber, email, adnRecordId, onsuccess, onerror) {
       equal(pbr.email.fileId, EMAIL_FILE_ID);
       if (pbr.email.fileType === ICC_USIM_TYPE1_TAG) {
         equal(recordNumber, ADN_RECORD_ID);
       } else if (pbr.email.fileType === ICC_USIM_TYPE2_TAG) {
         equal(recordNumber, EMAIL_RECORD_ID);
       }
       equal(email, aContact.email);
-      onsuccess();
+      onsuccess(email);
     };
 
     recordHelper.updateANR = function(pbr, recordNumber, number, adnRecordId, onsuccess, onerror) {
       equal(pbr.anr0.fileId, ANR0_FILE_ID);
       if (pbr.anr0.fileType === ICC_USIM_TYPE1_TAG) {
         equal(recordNumber, ADN_RECORD_ID);
       } else if (pbr.anr0.fileType === ICC_USIM_TYPE2_TAG) {
         equal(recordNumber, ANR0_RECORD_ID);
       }
       if (Array.isArray(aContact.anr)) {
         equal(number, aContact.anr[0]);
       }
-      onsuccess();
+      onsuccess(number);
     };
 
     recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) {
       let recordId = 0;
       if (fileId === EMAIL_FILE_ID) {
         recordId = EMAIL_RECORD_ID;
       } else if (fileId === ANR0_FILE_ID) {
         recordId = ANR0_RECORD_ID;
       }
       onsuccess(recordId);
     };
 
     let isSuccess = false;
-    let onsuccess = function onsuccess() {
+    let onsuccess = function onsuccess(updatedContact) {
+      equal(ADN_RECORD_ID, updatedContact.recordId);
+      equal(aContact.alphaId, updatedContact.alphaId);
+      if ((aSimType == CARD_APPTYPE_USIM || aSimType == CARD_APPTYPE_RUIM) &&
+          (aFileType == ICC_USIM_TYPE1_TAG || aFileType == ICC_USIM_TYPE2_TAG)) {
+        if (aContact.hasOwnProperty('email')) {
+          equal(aContact.email, updatedContact.email);
+        }
+
+        if (aContact.hasOwnProperty('anr')) {
+          equal(aContact.anr[0], updatedContact.anr[0]);
+        }
+      } else {
+        equal(updatedContact.email, null);
+        equal(updatedContact.anr, null);
+      }
+
       do_print("updateICCContact success");
       isSuccess = true;
     };
 
     let onerror = function onerror(errorMsg) {
       do_print("updateICCContact failed: " + errorMsg);
     };
 
@@ -601,38 +618,39 @@ add_test(function test_update_icc_contac
   const ANR0_RECORD_ID  = 30;
 
   let worker = newUint8Worker();
   let context = worker.ContextPool._contexts[0];
   let recordHelper = context.ICCRecordHelper;
   let contactHelper = context.ICCContactHelper;
 
   recordHelper.updateADNLike = function(fileId, contact, pin2, onsuccess, onerror) {
-    onsuccess();
+    onsuccess({alphaId: contact.alphaId,
+               number: contact.number});
   };
 
   let contact = {
     pbrIndex: 0,
     recordId: ADN_RECORD_ID,
     alphaId:  "test2",
     number:   "123456",
   };
 
   recordHelper.readIAP = function(fileId, recordNumber, onsuccess, onerror) {
     onsuccess([EMAIL_RECORD_ID, ANR0_RECORD_ID]);
   };
 
   recordHelper.updateEmail = function(pbr, recordNumber, email, adnRecordId, onsuccess, onerror) {
     ok(email == null);
-    onsuccess();
+    onsuccess(email);
   };
 
   recordHelper.updateANR = function(pbr, recordNumber, number, adnRecordId, onsuccess, onerror) {
     ok(number == null);
-    onsuccess();
+    onsuccess(number);
   };
 
   function do_test(type) {
     recordHelper.readPBR = function(onsuccess, onerror) {
       if (type == ICC_USIM_TYPE1_TAG) {
         onsuccess([{
           adn:   {fileId: ICC_EF_ADN},
           email: {fileId: EMAIL_FILE_ID,
@@ -647,17 +665,19 @@ add_test(function test_update_icc_contac
                   fileType: ICC_USIM_TYPE2_TAG,
                   indexInIAP: 0},
           anr0:  {fileId: ANR0_FILE_ID,
                   fileType: ICC_USIM_TYPE2_TAG,
                   indexInIAP: 1}}]);
       }
     };
 
-    let successCb = function() {
+    let successCb = function(updatedContact) {
+      equal(updatedContact.email, null);
+      equal(updatedContact.anr, null);
       ok(true);
     };
 
     let errorCb = function(errorMsg) {
       do_print(errorMsg);
       ok(false);
     };
 
--- a/dom/system/gonk/tests/test_ril_worker_icc_ICCPDUHelper.js
+++ b/dom/system/gonk/tests/test_ril_worker_icc_ICCPDUHelper.js
@@ -88,21 +88,46 @@ add_test(function test_write_icc_ucs2_st
     }, {
       encode: 0x82,
       // 2 UCS2 character over 0x81 can encode range.
       data: "Fire \ufffd\ufffe"
     }];
 
   for (let i = 0; i < test_data.length; i++) {
     let test = test_data[i];
-    iccHelper.writeICCUCS2String(alphaLen, test.data);
+    let writtenStr = iccHelper.writeICCUCS2String(alphaLen, test.data);
+    equal(writtenStr, test.data);
     equal(helper.readHexOctet(), test.encode);
     equal(iccHelper.readICCUCS2String(test.encode, alphaLen - 1), test.data);
   }
 
+  // This string use 0x80 encoded and the maximum capacity is 17 octets.
+  // Each alphabet takes 2 octets, thus the first 8 alphabets can be written.
+  let str = "Mozilla \u82b3\u8233 On Fire";
+  let writtenStr = iccHelper.writeICCUCS2String(alphaLen, str);
+  equal(writtenStr, str.substring(0, 8));
+  equal(helper.readHexOctet(), 0x80);
+  equal(iccHelper.readICCUCS2String(0x80, alphaLen - 1), str.substring(0, 8));
+
+  // This string use 0x81 encoded and the maximum capacity is 15 octets.
+  // Each alphabet takes 1 octets, thus the first 15 alphabets can be written.
+  str = "Mozilla \u6901\u697f On Fire";
+  writtenStr = iccHelper.writeICCUCS2String(alphaLen, str);
+  equal(writtenStr, str.substring(0, 15));
+  equal(helper.readHexOctet(), 0x81);
+  equal(iccHelper.readICCUCS2String(0x81, alphaLen - 1), str.substring(0, 15));
+
+  // This string use 0x82 encoded and the maximum capacity is 14 octets.
+  // Each alphabet takes 1 octets, thus the first 14 alphabets can be written.
+  str = "Mozilla \u0514\u0593 On Fire";
+  writtenStr = iccHelper.writeICCUCS2String(alphaLen, str);
+  equal(writtenStr, str.substring(0, 14));
+  equal(helper.readHexOctet(), 0x82);
+  equal(iccHelper.readICCUCS2String(0x82, alphaLen - 1), str.substring(0, 14));
+
   run_next_test();
 });
 /**
  * Verify ICCPDUHelper#readDiallingNumber
  */
 add_test(function test_read_dialling_number() {
   let worker = newUint8Worker();
   let context = worker.ContextPool._contexts[0];
@@ -202,43 +227,44 @@ add_test(function test_write_string_to_8
   let iccHelper = context.ICCPDUHelper;
   const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
   const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
   // Length of trailing 0xff.
   let ffLen = 2;
   let str;
 
   // Test 1, write GSM alphabets.
-  iccHelper.writeStringTo8BitUnpacked(langTable.length + ffLen, langTable);
+  let writtenStr = iccHelper.writeStringTo8BitUnpacked(langTable.length + ffLen, langTable);
+  equal(writtenStr, langTable);
 
   for (let i = 0; i < langTable.length; i++) {
     equal(helper.readHexOctet(), i);
   }
 
   for (let i = 0; i < ffLen; i++) {
     equal(helper.readHexOctet(), 0xff);
   }
 
   // Test 2, write GSM extended alphabets.
   str = "\u000c\u20ac";
-  iccHelper.writeStringTo8BitUnpacked(4, str);
-
+  writtenStr = iccHelper.writeStringTo8BitUnpacked(4, str);
+  equal(writtenStr, str);
   equal(iccHelper.read8BitUnpackedToString(4), str);
 
   // Test 3, write GSM and GSM extended alphabets.
   // \u000c, \u20ac are from gsm extended alphabets.
   // \u00a3 is from gsm alphabet.
   str = "\u000c\u20ac\u00a3";
 
   // 2 octets * 2 = 4 octets for 2 gsm extended alphabets,
   // 1 octet for 1 gsm alphabet,
   // 2 octes for trailing 0xff.
   // "Totally 7 octets are to be written."
-  iccHelper.writeStringTo8BitUnpacked(7, str);
-
+  writtenStr = iccHelper.writeStringTo8BitUnpacked(7, str);
+  equal(writtenStr, str);
   equal(iccHelper.read8BitUnpackedToString(7), str);
 
   run_next_test();
 });
 
 /**
  * Verify ICCPDUHelper#writeStringTo8BitUnpacked with maximum octets written.
  */
@@ -247,38 +273,42 @@ add_test(function test_write_string_to_8
   let context = worker.ContextPool._contexts[0];
   let helper = context.GsmPDUHelper;
   let iccHelper = context.ICCPDUHelper;
   const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
   const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
 
   // The maximum of the number of octets that can be written is 3.
   // Only 3 characters shall be written even the length of the string is 4.
-  iccHelper.writeStringTo8BitUnpacked(3, langTable.substring(0, 4));
+  let writtenStr = iccHelper.writeStringTo8BitUnpacked(3, langTable.substring(0, 4));
+  equal(writtenStr, langTable.substring(0, 3));
   helper.writeHexOctet(0xff); // dummy octet.
   for (let i = 0; i < 3; i++) {
     equal(helper.readHexOctet(), i);
   }
   ok(helper.readHexOctet() != 4);
 
   // \u000c is GSM extended alphabet, 2 octets.
   // \u00a3 is GSM alphabet, 1 octet.
   let str = "\u000c\u00a3";
-  iccHelper.writeStringTo8BitUnpacked(3, str);
+  writtenStr = iccHelper.writeStringTo8BitUnpacked(3, str);
+  equal(writtenStr, str.substring(0, 2));
   equal(iccHelper.read8BitUnpackedToString(3), str);
 
   str = "\u00a3\u000c";
-  iccHelper.writeStringTo8BitUnpacked(3, str);
+  writtenStr = iccHelper.writeStringTo8BitUnpacked(3, str);
+  equal(writtenStr, str.substring(0, 2));
   equal(iccHelper.read8BitUnpackedToString(3), str);
 
   // 2 GSM extended alphabets cost 4 octets, but maximum is 3, so only the 1st
   // alphabet can be written.
   str = "\u000c\u000c";
-  iccHelper.writeStringTo8BitUnpacked(3, str);
+  writtenStr = iccHelper.writeStringTo8BitUnpacked(3, str);
   helper.writeHexOctet(0xff); // dummy octet.
+  equal(writtenStr, str.substring(0, 1));
   equal(iccHelper.read8BitUnpackedToString(4), str.substring(0, 1));
 
   run_next_test();
 });
 
 /**
  * Verify ICCPDUHelper.readAlphaIdentifier
  */
@@ -331,46 +361,52 @@ add_test(function test_write_alpha_ident
   let worker = newUint8Worker();
   let context = worker.ContextPool._contexts[0];
   let helper = context.GsmPDUHelper;
   let iccHelper = context.ICCPDUHelper;
   // Length of trailing 0xff.
   let ffLen = 2;
 
   // Removal
-  iccHelper.writeAlphaIdentifier(10, null);
+  let writenAlphaId = iccHelper.writeAlphaIdentifier(10, null);
+  equal(writenAlphaId, null);
   equal(iccHelper.readAlphaIdentifier(10), "");
 
   // GSM 8 bit
   let str = "Mozilla";
-  iccHelper.writeAlphaIdentifier(str.length + ffLen, str);
+  writenAlphaId = iccHelper.writeAlphaIdentifier(str.length + ffLen, str);
+  equal(writenAlphaId , str);
   equal(iccHelper.readAlphaIdentifier(str.length + ffLen), str);
 
   // UCS2
   str = "Mozilla\u8000";
-  iccHelper.writeAlphaIdentifier(str.length * 2 + ffLen, str);
+  writenAlphaId = iccHelper.writeAlphaIdentifier(str.length * 2 + ffLen, str);
+  equal(writenAlphaId , str);
   // * 2 for each character will be encoded to UCS2 alphabets.
   equal(iccHelper.readAlphaIdentifier(str.length * 2 + ffLen), str);
 
   // Test with maximum octets written.
   // 1 coding scheme (0x80) and 1 UCS2 character, total 3 octets.
   str = "\u694a";
-  iccHelper.writeAlphaIdentifier(3, str);
+  writenAlphaId = iccHelper.writeAlphaIdentifier(3, str);
+  equal(writenAlphaId , str);
   equal(iccHelper.readAlphaIdentifier(3), str);
 
   // 1 coding scheme (0x80) and 2 UCS2 characters, total 5 octets.
   // numOctets is limited to 4, so only 1 UCS2 character can be written.
   str = "\u694a\u69ca";
-  iccHelper.writeAlphaIdentifier(4, str);
+  writenAlphaId = iccHelper.writeAlphaIdentifier(4, str);
   helper.writeHexOctet(0xff); // dummy octet.
+  equal(writenAlphaId , str.substring(0, 1));
   equal(iccHelper.readAlphaIdentifier(5), str.substring(0, 1));
 
   // Write 0 octet.
-  iccHelper.writeAlphaIdentifier(0, "1");
+  writenAlphaId = iccHelper.writeAlphaIdentifier(0, "1");
   helper.writeHexOctet(0xff); // dummy octet.
+  equal(writenAlphaId, null);
   equal(iccHelper.readAlphaIdentifier(1), "");
 
   run_next_test();
 });
 
 /**
  * Verify ICCPDUHelper.readAlphaIdDiallingNumber
  */
@@ -421,61 +457,67 @@ add_test(function test_write_alpha_id_di
   let helper = context.ICCPDUHelper;
   const recordSize = 32;
 
   // Write a normal contact.
   let contactW = {
     alphaId: "Mozilla",
     number: "1234567890"
   };
-  helper.writeAlphaIdDiallingNumber(recordSize, contactW.alphaId,
-                                    contactW.number);
+  let writtenContact = helper.writeAlphaIdDiallingNumber(recordSize,
+                                                         contactW.alphaId,
+                                                         contactW.number);
 
   let contactR = helper.readAlphaIdDiallingNumber(recordSize);
-  equal(contactW.alphaId, contactR.alphaId);
-  equal(contactW.number, contactR.number);
+  equal(writtenContact.alphaId, contactR.alphaId);
+  equal(writtenContact.number, contactR.number);
 
   // Write a contact with alphaId encoded in UCS2 and number has '+'.
   let contactUCS2 = {
     alphaId: "火狐",
     number: "+1234567890"
   };
-  helper.writeAlphaIdDiallingNumber(recordSize, contactUCS2.alphaId,
-                                    contactUCS2.number);
+  writtenContact = helper.writeAlphaIdDiallingNumber(recordSize,
+                                                     contactUCS2.alphaId,
+                                                     contactUCS2.number);
   contactR = helper.readAlphaIdDiallingNumber(recordSize);
-  equal(contactUCS2.alphaId, contactR.alphaId);
-  equal(contactUCS2.number, contactR.number);
+  equal(writtenContact.alphaId, contactR.alphaId);
+  equal(writtenContact.number, contactR.number);
 
   // Write a null contact (Removal).
-  helper.writeAlphaIdDiallingNumber(recordSize);
+  writtenContact = helper.writeAlphaIdDiallingNumber(recordSize);
   contactR = helper.readAlphaIdDiallingNumber(recordSize);
   equal(contactR, null);
+  equal(writtenContact.alphaId, null);
+  equal(writtenContact.number, null);
 
   // Write a longer alphaId/dialling number
   // Dialling Number : Maximum 20 digits(10 octets).
   // Alpha Identifier: 32(recordSize) - 14 (10 octets for Dialling Number, 1
   //                   octet for TON/NPI, 1 for number length octet, and 2 for
   //                   Ext) = Maximum 18 octets.
   let longContact = {
     alphaId: "AAAAAAAAABBBBBBBBBCCCCCCCCC",
     number: "123456789012345678901234567890",
   };
-  helper.writeAlphaIdDiallingNumber(recordSize, longContact.alphaId,
-                                    longContact.number);
+  writtenContact = helper.writeAlphaIdDiallingNumber(recordSize,
+                                                     longContact.alphaId,
+                                                     longContact.number);
   contactR = helper.readAlphaIdDiallingNumber(recordSize);
-  equal(contactR.alphaId, "AAAAAAAAABBBBBBBBB");
-  equal(contactR.number, "12345678901234567890");
+  equal(writtenContact.alphaId, contactR.alphaId);
+  equal(writtenContact.number, contactR.number);
 
   // Add '+' to number and test again.
   longContact.number = "+123456789012345678901234567890";
-  helper.writeAlphaIdDiallingNumber(recordSize, longContact.alphaId,
-                                    longContact.number);
+  writtenContact = helper.writeAlphaIdDiallingNumber(recordSize,
+                                                     longContact.alphaId,
+                                                     longContact.number);
   contactR = helper.readAlphaIdDiallingNumber(recordSize);
-  equal(contactR.alphaId, "AAAAAAAAABBBBBBBBB");
-  equal(contactR.number, "+12345678901234567890");
+  equal(writtenContact.alphaId, contactR.alphaId);
+  equal(writtenContact.number, contactR.number);
 
   run_next_test();
 });
 
 /**
  * Verify ICCPDUHelper.writeDiallingNumber
  */
 add_test(function test_write_dialling_number() {
@@ -559,17 +601,18 @@ add_test(function test_read_number_with_
 add_test(function test_write_number_with_length() {
   let worker = newUint8Worker();
   let context = worker.ContextPool._contexts[0];
   let helper = context.GsmPDUHelper;
   let iccHelper = context.ICCPDUHelper;
 
   function test(number, expectedNumber) {
     expectedNumber = expectedNumber || number;
-    iccHelper.writeNumberWithLength(number);
+    let writeNumber = iccHelper.writeNumberWithLength(number);
+    equal(writeNumber, expectedNumber);
     let numLen = helper.readHexOctet();
     equal(expectedNumber, iccHelper.readDiallingNumber(numLen));
     for (let i = 0; i < (ADN_MAX_BCD_NUMBER_BYTES - numLen); i++) {
       equal(0xff, helper.readHexOctet());
     }
   }
 
   // without +
@@ -584,16 +627,19 @@ add_test(function test_write_number_with
   // with + and extended BCD coding
   test("+1*2#3,4*5#6,");
 
   // non-supported characters should not be written.
   test("(1)23-456+789", "123456789");
 
   test("++(01)2*3-4#5,6+7(8)9*0#1,", "+012*34#5,6789*0#1,");
 
+  // over maximum 20 digits should be truncated.
+  test("012345678901234567890123456789", "01234567890123456789");
+
   // null
   iccHelper.writeNumberWithLength(null);
   for (let i = 0; i < (ADN_MAX_BCD_NUMBER_BYTES + 1); i++) {
     equal(0xff, helper.readHexOctet());
   }
 
   run_next_test();
 });