Merge b2ginbound to central, a=merge CLOSED TREE
authorWes Kocher <wkocher@mozilla.com>
Mon, 21 Sep 2015 09:44:47 -0700
changeset 263531 197af2fb7e29
parent 263512 d68909e51b6e (current diff)
parent 263530 857d14f69fa3 (diff)
child 263532 2235e56c94cf
child 263539 7602a86cf4ee
child 263565 7c9f6250d9ba
child 263639 ee92eb117e92
push id29411
push userkwierso@gmail.com
push date2015-09-21 16:44 +0000
treeherdermozilla-central@197af2fb7e29 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone44.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 b2ginbound to central, a=merge CLOSED TREE
--- 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="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="2d370fa35c1a0ee2a637e3772c0843586a5f96c9"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="29991414eb94b6baa1ec2e63fdb4f6dfae05fb01"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="2782648aabf0af464dd9c4202b367b408898546d"/>
   <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="a1f9532e4157df2dc8d3e9c8100120f80117dcd4"/>
--- 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="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="2d370fa35c1a0ee2a637e3772c0843586a5f96c9"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="29991414eb94b6baa1ec2e63fdb4f6dfae05fb01"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="2782648aabf0af464dd9c4202b367b408898546d"/>
   <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="a1f9532e4157df2dc8d3e9c8100120f80117dcd4"/>
--- 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="1b0db93fb6b870b03467aff50d6419771ba0d88c">
     <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="2d370fa35c1a0ee2a637e3772c0843586a5f96c9"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="29991414eb94b6baa1ec2e63fdb4f6dfae05fb01"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="27eb2f04e149fc2c9976d881b1b5984bbe7ee089"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="067c08fb3e5744b42b68d1f861245f7d507109bc"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="2782648aabf0af464dd9c4202b367b408898546d"/>
   <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="660169a3d7e034a892359e39135e8c2785a6ad6f">
     <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="2d370fa35c1a0ee2a637e3772c0843586a5f96c9"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="29991414eb94b6baa1ec2e63fdb4f6dfae05fb01"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="2782648aabf0af464dd9c4202b367b408898546d"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a1f9532e4157df2dc8d3e9c8100120f80117dcd4"/>
   <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="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="2d370fa35c1a0ee2a637e3772c0843586a5f96c9"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="29991414eb94b6baa1ec2e63fdb4f6dfae05fb01"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="2782648aabf0af464dd9c4202b367b408898546d"/>
   <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="a1f9532e4157df2dc8d3e9c8100120f80117dcd4"/>
@@ -118,17 +118,17 @@
   <project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="fd241573c00112ca6e456b8021fb68df0349f6dd"/>
   <project name="platform/system/extras" path="system/extras" revision="5356165f67f4a81c2ef28671c13697f1657590df"/>
   <project name="platform/system/media" path="system/media" revision="be0e2fe59a8043fa5200f75697df9220a99abe9d"/>
   <project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>
   <project name="platform/system/netd" path="system/netd" revision="36704b0da24debcab8090156568ac236315036bb"/>
   <project name="platform/system/security" path="system/security" revision="583374f69f531ba68fc3dcbff1f74893d2a96406"/>
   <project name="platform/system/vold" path="system/vold" revision="d4455b8cf361f8353e8aebac15ffd64b4aedd2b9"/>
   <project name="platform/external/icu4c" path="external/icu4c" remote="aosp" revision="b4c6379528887dc25ca9991a535a8d92a61ad6b6"/>
-  <project name="platform_frameworks_av" path="frameworks/av" remote="b2g" revision="f313503b5c91aaa6fcf962d4ec9bf260e0c00bf1"/>
+  <project name="platform_frameworks_av" path="frameworks/av" remote="b2g" revision="2da3a2d5100f8afa1229bb50aa2a29ea0aaf8417"/>
   <project name="platform_system_core" path="system/core" remote="b2g" revision="8586f55fe4b015911b48e731b69c592ad82a0807"/>
   <default remote="caf" revision="refs/tags/android-4.4.2_r1" sync-j="4"/>
   <!-- Emulator specific things -->
   <project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="72ffdf71c68a96309212eb13d63560d66db14c9e"/>
   <project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="8d4018ebd33ac3f1a043b2d54bc578028656a659"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="b2d449276b015d8fe6cd9ea60c389c7e6975f841"/>
   <project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="f37bd545063039e30a92f2550ae78c0e6e4e2d08"/>
   <project name="platform_external_wpa_supplicant_8" path="external/wpa_supplicant_8" remote="b2g" revision="0c6a6547cd1fd302fa2b0f6e375654df36bf0ec4"/>
--- 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="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="2d370fa35c1a0ee2a637e3772c0843586a5f96c9"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="29991414eb94b6baa1ec2e63fdb4f6dfae05fb01"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="2782648aabf0af464dd9c4202b367b408898546d"/>
   <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="a1f9532e4157df2dc8d3e9c8100120f80117dcd4"/>
--- 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="1b0db93fb6b870b03467aff50d6419771ba0d88c">
     <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="2d370fa35c1a0ee2a637e3772c0843586a5f96c9"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="29991414eb94b6baa1ec2e63fdb4f6dfae05fb01"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="27eb2f04e149fc2c9976d881b1b5984bbe7ee089"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="067c08fb3e5744b42b68d1f861245f7d507109bc"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="2782648aabf0af464dd9c4202b367b408898546d"/>
   <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="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="2d370fa35c1a0ee2a637e3772c0843586a5f96c9"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="29991414eb94b6baa1ec2e63fdb4f6dfae05fb01"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="2782648aabf0af464dd9c4202b367b408898546d"/>
   <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="a1f9532e4157df2dc8d3e9c8100120f80117dcd4"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
-        "git_revision": "2d370fa35c1a0ee2a637e3772c0843586a5f96c9", 
+        "git_revision": "29991414eb94b6baa1ec2e63fdb4f6dfae05fb01", 
         "remote": "https://git.mozilla.org/releases/gaia.git", 
         "branch": ""
     }, 
-    "revision": "71b3fccca59c5a80c05e5ed99e1f5108c1b1ffad", 
+    "revision": "7093f7d19d1df254cb9445417e47c3557103f073", 
     "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="660169a3d7e034a892359e39135e8c2785a6ad6f">
     <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="2d370fa35c1a0ee2a637e3772c0843586a5f96c9"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="29991414eb94b6baa1ec2e63fdb4f6dfae05fb01"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="2782648aabf0af464dd9c4202b367b408898546d"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a1f9532e4157df2dc8d3e9c8100120f80117dcd4"/>
   <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="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="2d370fa35c1a0ee2a637e3772c0843586a5f96c9"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="29991414eb94b6baa1ec2e63fdb4f6dfae05fb01"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="2782648aabf0af464dd9c4202b367b408898546d"/>
   <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="a1f9532e4157df2dc8d3e9c8100120f80117dcd4"/>
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -2652,41 +2652,32 @@ nsFrameLoader::SwapRemoteBrowser(nsITabP
   }
   if (!OwnerIsBrowserOrAppFrame()) {
     NS_WARNING("Switching process for non-mozbrowser/app frame is not supported.");
     return NS_ERROR_NOT_IMPLEMENTED;
   }
   if (newParent == mRemoteBrowser) {
     return NS_OK;
   }
-  nsCOMPtr<nsIObserverService> os = services::GetObserverService();
-  if (os) {
-    os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, this),
-                        "frameloader-message-manager-will-change", nullptr);
-  }
-
   mRemoteBrowser->CacheFrameLoader(nullptr);
   mRemoteBrowser->SetOwnerElement(nullptr);
   mRemoteBrowser->Detach();
   mRemoteBrowser->Destroy();
 
-  if (mMessageManager) {
-    mMessageManager->Disconnect();
-    mMessageManager = nullptr;
-  }
-
   mRemoteBrowser = newParent;
   mRemoteBrowser->Attach(this);
   mChildID = mRemoteBrowser->Manager()->ChildID();
-  ReallyLoadFrameScripts();
-  InitializeBrowserAPI();
-
+
+  // Force the new remote frame manager to load pending scripts
+  mMessageManager->LoadPendingScripts();
+
+  nsCOMPtr<nsIObserverService> os = services::GetObserverService();
   if (os) {
     os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, this),
-                        "frameloader-message-manager-changed", nullptr);
+                        "remote-browser-swapped", nullptr);
   }
   if (!mRemoteBrowserShown) {
     ShowRemoteFrame(ScreenIntSize(0, 0));
   }
 
   return NS_OK;
 }
 
--- a/dom/base/nsFrameMessageManager.cpp
+++ b/dom/base/nsFrameMessageManager.cpp
@@ -513,26 +513,19 @@ nsFrameMessageManager::RemoveWeakMessage
 // nsIFrameScriptLoader
 
 NS_IMETHODIMP
 nsFrameMessageManager::LoadScript(const nsAString& aURL,
                                   bool aAllowDelayedLoad,
                                   bool aRunInGlobalScope)
 {
   if (aAllowDelayedLoad) {
-    if (IsGlobal() || IsBroadcaster()) {
-      // Cache for future windows or frames
-      mPendingScripts.AppendElement(aURL);
-      mPendingScriptsGlobalStates.AppendElement(aRunInGlobalScope);
-    } else if (!mCallback) {
-      // We're frame message manager, which isn't connected yet.
-      mPendingScripts.AppendElement(aURL);
-      mPendingScriptsGlobalStates.AppendElement(aRunInGlobalScope);
-      return NS_OK;
-    }
+    // Cache for future windows or frames
+    mPendingScripts.AppendElement(aURL);
+    mPendingScriptsGlobalStates.AppendElement(aRunInGlobalScope);
   }
 
   if (mCallback) {
 #ifdef DEBUG_smaug
     printf("Will load %s \n", NS_ConvertUTF16toUTF8(aURL).get());
 #endif
     NS_ENSURE_TRUE(mCallback->DoLoadMessageManagerScript(aURL, aRunInGlobalScope),
                    NS_ERROR_FAILURE);
@@ -1322,16 +1315,23 @@ nsFrameMessageManager::LoadPendingScript
   for (uint32_t i = 0; i < aManager->mPendingScripts.Length(); ++i) {
     aChildMM->LoadFrameScript(aManager->mPendingScripts[i],
                               false,
                               aManager->mPendingScriptsGlobalStates[i]);
   }
 }
 
 void
+nsFrameMessageManager::LoadPendingScripts()
+{
+  nsRefPtr<nsFrameMessageManager> kungfuDeathGrip = this;
+  LoadPendingScripts(this, this);
+}
+
+void
 nsFrameMessageManager::SetCallback(MessageManagerCallback* aCallback)
 {
   MOZ_ASSERT(!mIsBroadcaster || !mCallback,
              "Broadcasters cannot have callbacks!");
   if (aCallback && mCallback != aCallback) {
     mCallback = aCallback;
     if (mOwnsCallback) {
       mOwnedCallback = aCallback;
--- a/dom/base/nsFrameMessageManager.h
+++ b/dom/base/nsFrameMessageManager.h
@@ -243,16 +243,18 @@ public:
   }
   static void SetChildProcessManager(nsFrameMessageManager* aManager)
   {
     sChildProcessManager = aManager;
   }
 
   void SetInitialProcessData(JS::HandleValue aInitialData);
 
+  void LoadPendingScripts();
+
 private:
   nsresult SendMessage(const nsAString& aMessageName,
                        JS::Handle<JS::Value> aJSON,
                        JS::Handle<JS::Value> aObjects,
                        nsIPrincipal* aPrincipal,
                        JSContext* aCx,
                        uint8_t aArgc,
                        JS::MutableHandle<JS::Value> aRetval,
--- a/dom/base/nsGkAtomList.h
+++ b/dom/base/nsGkAtomList.h
@@ -847,16 +847,17 @@ GK_ATOM(onpairingconsentreq, "onpairingc
 GK_ATOM(onpaste, "onpaste")
 GK_ATOM(onpendingchange, "onpendingchange")
 GK_ATOM(onpichange, "onpichange")
 GK_ATOM(onpicture, "onpicture")
 GK_ATOM(onpopuphidden, "onpopuphidden")
 GK_ATOM(onpopuphiding, "onpopuphiding")
 GK_ATOM(onpopupshowing, "onpopupshowing")
 GK_ATOM(onpopupshown, "onpopupshown")
+GK_ATOM(onposter, "onposter")
 GK_ATOM(onpreviewstatechange, "onpreviewstatechange")
 GK_ATOM(onpullphonebookreq, "onpullphonebookreq")
 GK_ATOM(onpullvcardentryreq, "onpullvcardentryreq")
 GK_ATOM(onpullvcardlistingreq, "onpullvcardlistingreq")
 GK_ATOM(onpush, "onpush")
 GK_ATOM(onpushsubscriptionchange, "onpushsubscriptionchange")
 GK_ATOM(onpschange, "onpschange")
 GK_ATOM(onptychange, "onptychange")
--- a/dom/base/test/test_frameLoader_switchProcess.html
+++ b/dom/base/test/test_frameLoader_switchProcess.html
@@ -28,39 +28,33 @@
   function switchProcessAndLoadURI(iframe, url) {
     var fl = SpecialPowers.wrap(iframe)
                           .QueryInterface(Ci.nsIFrameLoaderOwner)
                           .frameLoader;
     var uri = SpecialPowers.Services.io.newURI(url, null, null);
     fl.switchProcessAndLoadURI(uri);
   }
 
-  var messageManager;
-
   function runTest() {
     ok(true, "Run Test");
     var iframe = document.createElement("iframe");
     iframe.setAttribute("mozbrowser", "true");
     iframe.setAttribute("remote", "true");
     iframe.setAttribute("src", "http://example.org");
 
     expectProcessCreated()
     .then(() => new Promise(next => {
       iframe.addEventListener("mozbrowserloadend", function loadend(e) {
         iframe.removeEventListener("mozbrowserloadend", loadend);
         ok(true, "Got mozbrowserloadend");
-        mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
         expectProcessCreated().then(next);
         switchProcessAndLoadURI(iframe, "data:text/html,%3Cscript%3Ealert(true)%3C/script%3E");
       });
     }))
     .then(() => new Promise(next => {
-      var newMessageManager = SpecialPowers.getBrowserFrameMessageManager(iframe);
-      isnot(messageManager, newMessageManager, "Got a new message manager");
-      messageManager = newMessageManager;
       iframe.addEventListener("mozbrowsershowmodalprompt", function prompt(e) {
         iframe.removeEventListener("mozbrowsershowmodalprompt", prompt);
         ok(true, "Browser API still works after process switch");
         next();
       });
     }))
     .then(SimpleTest.finish);
 
--- a/dom/bluetooth/bluedroid/BluetoothAvrcpManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothAvrcpManager.cpp
@@ -334,44 +334,77 @@ void
 BluetoothAvrcpManager::HandleShutdown()
 {
   MOZ_ASSERT(NS_IsMainThread());
   sInShutdown = true;
   Disconnect(nullptr);
   sBluetoothAvrcpManager = nullptr;
 }
 
+class BluetoothAvrcpManager::ConnectRunnable final : public nsRunnable
+{
+public:
+  ConnectRunnable(BluetoothAvrcpManager* aManager)
+    : mManager(aManager)
+  {
+    MOZ_ASSERT(mManager);
+  }
+  NS_METHOD Run() override
+  {
+    mManager->OnConnect(EmptyString());
+    return NS_OK;
+  }
+private:
+  BluetoothAvrcpManager* mManager;
+};
+
 void
 BluetoothAvrcpManager::Connect(const nsAString& aDeviceAddress,
                                BluetoothProfileController* aController)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!aDeviceAddress.IsEmpty());
   MOZ_ASSERT(aController);
 
   // AVRCP doesn't require connecting. We just set the remote address here.
   mDeviceAddress = aDeviceAddress;
   mController = aController;
+  SetConnected(true);
 
-  SetConnected(true);
-  OnConnect(EmptyString());
+  NS_DispatchToMainThread(new ConnectRunnable(this));
 }
 
+class BluetoothAvrcpManager::DisconnectRunnable final : public nsRunnable
+{
+public:
+  DisconnectRunnable(BluetoothAvrcpManager* aManager)
+    : mManager(aManager)
+  {
+    MOZ_ASSERT(mManager);
+  }
+  NS_METHOD Run() override
+  {
+    mManager->OnDisconnect(EmptyString());
+    return NS_OK;
+  }
+private:
+  BluetoothAvrcpManager* mManager;
+};
+
 void
 BluetoothAvrcpManager::Disconnect(BluetoothProfileController* aController)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!mController);
 
   mDeviceAddress.Truncate();
-
   mController = aController;
+  SetConnected(false);
 
-  SetConnected(false);
-  OnDisconnect(EmptyString());
+  NS_DispatchToMainThread(new DisconnectRunnable(this));
 }
 
 void
 BluetoothAvrcpManager::OnConnect(const nsAString& aErrorStr)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   /**
--- a/dom/bluetooth/bluedroid/BluetoothAvrcpManager.h
+++ b/dom/bluetooth/bluedroid/BluetoothAvrcpManager.h
@@ -57,18 +57,18 @@ public:
   void HandleBackendError();
 
 protected:
   virtual ~BluetoothAvrcpManager();
 
 private:
   class CleanupAvrcpResultHandler;
   class CleanupAvrcpResultHandlerRunnable;
-  class ConnectResultHandler;
-  class DisconnectResultHandler;
+  class ConnectRunnable;
+  class DisconnectRunnable;
   class InitAvrcpResultHandler;
   class OnErrorProfileResultHandlerRunnable;
 
   BluetoothAvrcpManager();
 
   void HandleShutdown();
   void NotifyConnectionStatusChanged();
 
--- a/dom/bluetooth/bluedroid/BluetoothDaemonAvrcpInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonAvrcpInterface.cpp
@@ -492,17 +492,17 @@ public:
       pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg1));
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     /* Read feature */
     rv = UnpackPDU(
       pdu,
-      UnpackConversion<BluetoothAvrcpRemoteFeature, unsigned long>(aArg2));
+      UnpackConversion<BluetoothAvrcpRemoteFeatureBits, unsigned long>(aArg2));
     if (NS_FAILED(rv)) {
       return rv;
     }
     WarnAboutTrailingData();
     return NS_OK;
   }
 };
 
--- a/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.cpp
@@ -197,34 +197,36 @@ Convert(uint8_t aIn, BluetoothAvrcpPlaye
     aOut = static_cast<BluetoothAvrcpPlayerAttribute>(0);
     return NS_ERROR_ILLEGAL_VALUE;
   }
   aOut = sAvrcpPlayerAttribute[aIn];
   return NS_OK;
 }
 
 nsresult
-Convert(uint8_t aIn, BluetoothAvrcpRemoteFeature& aOut)
+Convert(uint8_t aIn, BluetoothAvrcpRemoteFeatureBits& aOut)
 {
-  static const BluetoothAvrcpRemoteFeature sAvrcpRemoteFeature[] = {
-    [0x00] = AVRCP_REMOTE_FEATURE_NONE,
-    [0x01] = AVRCP_REMOTE_FEATURE_METADATA,
-    [0x02] = AVRCP_REMOTE_FEATURE_ABSOLUTE_VOLUME,
-    [0x03] = AVRCP_REMOTE_FEATURE_BROWSE
+  static const uint8_t sAvrcpRemoteFeatureBits[] = {
+    [0] = AVRCP_REMOTE_FEATURE_METADATA,
+    [1] = AVRCP_REMOTE_FEATURE_ABSOLUTE_VOLUME,
+    [2] = AVRCP_REMOTE_FEATURE_BROWSE
   };
+  uint8_t bits = 0;
+  size_t i;
+  for (i = 0; i < MOZ_ARRAY_LENGTH(sAvrcpRemoteFeatureBits); ++i, aIn >>= 1) {
+    if (aIn & 0x01) {
+      bits |= sAvrcpRemoteFeatureBits[i];
+    }
+  }
   if (MOZ_HAL_IPC_CONVERT_WARN_IF(
-        !aIn, uint8_t, BluetoothAvrcpRemoteFeature) ||
-      MOZ_HAL_IPC_CONVERT_WARN_IF(
-        aIn >= MOZ_ARRAY_LENGTH(sAvrcpRemoteFeature), uint8_t,
-        BluetoothAvrcpRemoteFeature)) {
-    // silences compiler warning
-    aOut = static_cast<BluetoothAvrcpRemoteFeature>(0);
+        aIn << i, 'uint8_t', BluetoothAvrcpRemoteFeatureBits)) {
+    aOut = AVRCP_REMOTE_FEATURE_NONE; // silences compiler warning
     return NS_ERROR_ILLEGAL_VALUE;
   }
-  aOut = sAvrcpRemoteFeature[aIn];
+  aOut = static_cast<BluetoothAvrcpRemoteFeatureBits>(bits);
   return NS_OK;
 }
 
 nsresult
 Convert(uint8_t aIn, BluetoothBondState& aOut)
 {
   static const BluetoothBondState sBondState[] = {
     [0x00] = BOND_STATE_NONE,
@@ -680,17 +682,17 @@ Convert(BluetoothAvrcpPlayerAttribute aI
         aIn >= MOZ_ARRAY_LENGTH(sValue), BluetoothAvrcpPlayerAttribute, uint8_t)) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
   aOut = sValue[aIn];
   return NS_OK;
 }
 
 nsresult
-Convert(BluetoothAvrcpRemoteFeature aIn, unsigned long& aOut)
+Convert(BluetoothAvrcpRemoteFeatureBits aIn, unsigned long& aOut)
 {
   if (MOZ_HAL_IPC_CONVERT_WARN_IF(
         aIn < std::numeric_limits<unsigned long>::min(),
         BluetoothAvrcpRemoteFeature, unsigned long) ||
       MOZ_HAL_IPC_CONVERT_WARN_IF(
         aIn > std::numeric_limits<unsigned long>::max(),
         BluetoothAvrcpRemoteFeature, unsigned long)) {
     aOut = 0; // silences compiler warning
@@ -1493,20 +1495,20 @@ UnpackPDU(DaemonSocketPDU& aPDU, Bluetoo
     if (NS_FAILED(rv)) {
       return rv;
     }
   }
   return NS_OK;
 }
 
 nsresult
-UnpackPDU(DaemonSocketPDU& aPDU, BluetoothAvrcpRemoteFeature& aOut)
+UnpackPDU(DaemonSocketPDU& aPDU, BluetoothAvrcpRemoteFeatureBits& aOut)
 {
   return UnpackPDU(
-    aPDU, UnpackConversion<uint8_t, BluetoothAvrcpRemoteFeature>(aOut));
+    aPDU, UnpackConversion<uint8_t, BluetoothAvrcpRemoteFeatureBits>(aOut));
 }
 
 nsresult
 UnpackPDU(DaemonSocketPDU& aPDU, BluetoothBondState& aOut)
 {
   return UnpackPDU(aPDU, UnpackConversion<uint8_t, BluetoothBondState>(aOut));
 }
 
--- a/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.h
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.h
@@ -152,17 +152,17 @@ Convert(uint8_t aIn, BluetoothAvrcpEvent
 
 nsresult
 Convert(uint8_t aIn, BluetoothAvrcpMediaAttribute& aOut);
 
 nsresult
 Convert(uint8_t aIn, BluetoothAvrcpPlayerAttribute& aOut);
 
 nsresult
-Convert(uint8_t aIn, BluetoothAvrcpRemoteFeature& aOut);
+Convert(uint8_t aIn, BluetoothAvrcpRemoteFeatureBits& aOut);
 
 nsresult
 Convert(uint8_t aIn, BluetoothHandsfreeAudioState& aOut);
 
 nsresult
 Convert(uint8_t aIn, BluetoothHandsfreeCallHoldType& aOut);
 
 nsresult
@@ -224,17 +224,17 @@ Convert(BluetoothAvrcpEvent aIn, uint8_t
 
 nsresult
 Convert(BluetoothAvrcpNotification aIn, uint8_t& aOut);
 
 nsresult
 Convert(BluetoothAvrcpPlayerAttribute aIn, uint8_t& aOut);
 
 nsresult
-Convert(BluetoothAvrcpRemoteFeature aIn, unsigned long& aOut);
+Convert(BluetoothAvrcpRemoteFeatureBits aIn, unsigned long& aOut);
 
 nsresult
 Convert(BluetoothAvrcpStatus aIn, uint8_t& aOut);
 
 nsresult
 Convert(BluetoothHandsfreeAtResponse aIn, uint8_t& aOut);
 
 nsresult
@@ -438,17 +438,17 @@ UnpackPDU(DaemonSocketPDU& aPDU, Bluetoo
 
 nsresult
 UnpackPDU(DaemonSocketPDU& aPDU, BluetoothAvrcpPlayerAttribute& aOut);
 
 nsresult
 UnpackPDU(DaemonSocketPDU& aPDU, BluetoothAvrcpPlayerSettings& aOut);
 
 nsresult
-UnpackPDU(DaemonSocketPDU& aPDU, BluetoothAvrcpRemoteFeature& aOut);
+UnpackPDU(DaemonSocketPDU& aPDU, BluetoothAvrcpRemoteFeatureBits& aOut);
 
 nsresult
 UnpackPDU(DaemonSocketPDU& aPDU, BluetoothBondState& aOut);
 
 nsresult
 UnpackPDU(DaemonSocketPDU& aPDU, BluetoothTypeOfDevice& aOut);
 
 nsresult
--- a/dom/bluetooth/common/BluetoothCommon.h
+++ b/dom/bluetooth/common/BluetoothCommon.h
@@ -569,21 +569,21 @@ enum BluetoothAvrcpEvent {
   AVRCP_EVENT_APP_SETTINGS_CHANGED
 };
 
 enum BluetoothAvrcpNotification {
   AVRCP_NTF_INTERIM,
   AVRCP_NTF_CHANGED
 };
 
-enum BluetoothAvrcpRemoteFeature {
+enum BluetoothAvrcpRemoteFeatureBits {
   AVRCP_REMOTE_FEATURE_NONE,
-  AVRCP_REMOTE_FEATURE_METADATA,
-  AVRCP_REMOTE_FEATURE_ABSOLUTE_VOLUME,
-  AVRCP_REMOTE_FEATURE_BROWSE
+  AVRCP_REMOTE_FEATURE_METADATA = 0x01,
+  AVRCP_REMOTE_FEATURE_ABSOLUTE_VOLUME = 0x02,
+  AVRCP_REMOTE_FEATURE_BROWSE = 0x04
 };
 
 struct BluetoothAvrcpElementAttribute {
   uint32_t mId;
   nsString mValue;
 };
 
 struct BluetoothAvrcpNotificationParam {
--- a/dom/bluetooth/common/BluetoothInterface.cpp
+++ b/dom/bluetooth/common/BluetoothInterface.cpp
@@ -13,18 +13,18 @@
 #endif
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 //
 // Setup Interface
 //
 
-BluetoothSetupResultHandler::~BluetoothSetupResultHandler()
-{ }
+// Result handling
+//
 
 void
 BluetoothSetupResultHandler::OnError(BluetoothStatus aStatus)
 {
   BT_WARNING("Received error code %d", (int)aStatus);
 }
 
 void
@@ -38,28 +38,220 @@ BluetoothSetupResultHandler::UnregisterM
 void
 BluetoothSetupResultHandler::Configuration()
 { }
 
 //
 // Socket Interface
 //
 
+// Result handling
+//
+
+void
+BluetoothSocketResultHandler::OnError(BluetoothStatus aStatus)
+{
+  BT_WARNING("Received error code %d", (int)aStatus);
+}
+
+void
+BluetoothSocketResultHandler::Listen(int aSockFd)
+{ }
+
+void
+BluetoothSocketResultHandler::Connect(int aSockFd,
+                                      const nsAString& aBdAddress,
+                                      int aConnectionState)
+{ }
+
+void
+BluetoothSocketResultHandler::Accept(int aSockFd,
+                                     const nsAString& aBdAddress,
+                                     int aConnectionState)
+{ }
+
+// Interface
+//
+
 BluetoothSocketInterface::~BluetoothSocketInterface()
 { }
 
 //
 // Handsfree Interface
 //
 
 // Notification handling
 //
 
-BluetoothHandsfreeNotificationHandler::
-  ~BluetoothHandsfreeNotificationHandler()
+BluetoothHandsfreeNotificationHandler::BluetoothHandsfreeNotificationHandler()
+{ }
+
+BluetoothHandsfreeNotificationHandler::~BluetoothHandsfreeNotificationHandler()
+{ }
+
+void
+BluetoothHandsfreeNotificationHandler::ConnectionStateNotification(
+  BluetoothHandsfreeConnectionState aState, const nsAString& aBdAddr)
+{ }
+
+void
+BluetoothHandsfreeNotificationHandler::AudioStateNotification(
+  BluetoothHandsfreeAudioState aState, const nsAString& aBdAddr)
+{ }
+
+void
+BluetoothHandsfreeNotificationHandler::VoiceRecognitionNotification(
+  BluetoothHandsfreeVoiceRecognitionState aState, const nsAString& aBdAddr)
+{ }
+
+void
+BluetoothHandsfreeNotificationHandler::AnswerCallNotification(
+  const nsAString& aBdAddr)
+{ }
+
+void
+BluetoothHandsfreeNotificationHandler::HangupCallNotification(
+  const nsAString& aBdAddr)
+{ }
+
+void
+BluetoothHandsfreeNotificationHandler::VolumeNotification(
+  BluetoothHandsfreeVolumeType aType, int aVolume, const nsAString& aBdAddr)
+{ }
+
+void
+BluetoothHandsfreeNotificationHandler::DialCallNotification(
+  const nsAString& aNumber, const nsAString& aBdAddr)
+{ }
+
+void
+BluetoothHandsfreeNotificationHandler::DtmfNotification(
+  char aDtmf, const nsAString& aBdAddr)
+{ }
+
+void
+BluetoothHandsfreeNotificationHandler::NRECNotification(
+  BluetoothHandsfreeNRECState aNrec, const nsAString& aBdAddr)
+{ }
+
+void
+BluetoothHandsfreeNotificationHandler::WbsNotification(
+  BluetoothHandsfreeWbsConfig aWbs, const nsAString& aBdAddr)
+{ }
+
+void
+BluetoothHandsfreeNotificationHandler::CallHoldNotification(
+  BluetoothHandsfreeCallHoldType aChld, const nsAString& aBdAddr)
+{ }
+
+void
+BluetoothHandsfreeNotificationHandler::CnumNotification(
+  const nsAString& aBdAddr)
+{ }
+
+void
+BluetoothHandsfreeNotificationHandler::CindNotification(
+  const nsAString& aBdAddr)
+{ }
+
+void
+BluetoothHandsfreeNotificationHandler::CopsNotification(
+  const nsAString& aBdAddr)
+{ }
+
+void
+BluetoothHandsfreeNotificationHandler::ClccNotification(
+  const nsAString& aBdAddr)
+{ }
+
+void
+BluetoothHandsfreeNotificationHandler::UnknownAtNotification(
+  const nsACString& aAtString, const nsAString& aBdAddr)
+{ }
+
+void
+BluetoothHandsfreeNotificationHandler::KeyPressedNotification(
+  const nsAString& aBdAddr)
+{ }
+
+// Result handling
+//
+
+void
+BluetoothHandsfreeResultHandler::OnError(BluetoothStatus aStatus)
+{
+  BT_WARNING("Received error code %d", (int)aStatus);
+}
+
+void
+BluetoothHandsfreeResultHandler::Init()
+{ }
+
+void
+BluetoothHandsfreeResultHandler::Cleanup()
+{ }
+
+void
+BluetoothHandsfreeResultHandler::Connect()
+{ }
+
+void
+BluetoothHandsfreeResultHandler::Disconnect()
+{ }
+
+void
+BluetoothHandsfreeResultHandler::ConnectAudio()
+{ }
+
+void
+BluetoothHandsfreeResultHandler::DisconnectAudio()
+{ }
+
+void
+BluetoothHandsfreeResultHandler::StartVoiceRecognition()
+{ }
+
+void
+BluetoothHandsfreeResultHandler::StopVoiceRecognition()
+{ }
+
+void
+BluetoothHandsfreeResultHandler::VolumeControl()
+{ }
+
+void
+BluetoothHandsfreeResultHandler::DeviceStatusNotification()
+{ }
+
+void
+BluetoothHandsfreeResultHandler::CopsResponse()
+{ }
+
+void
+BluetoothHandsfreeResultHandler::CindResponse()
+{ }
+
+void
+BluetoothHandsfreeResultHandler::FormattedAtResponse()
+{ }
+
+void
+BluetoothHandsfreeResultHandler::AtResponse()
+{ }
+
+void
+BluetoothHandsfreeResultHandler::ClccResponse()
+{ }
+
+void
+BluetoothHandsfreeResultHandler::PhoneStateChange()
+{ }
+
+void
+BluetoothHandsfreeResultHandler::ConfigureWbs()
 { }
 
 // Interface
 //
 
 BluetoothHandsfreeInterface::BluetoothHandsfreeInterface()
 { }
 
@@ -68,76 +260,765 @@ BluetoothHandsfreeInterface::~BluetoothH
 
 //
 // Bluetooth Advanced Audio Interface
 //
 
 // Notification handling
 //
 
+BluetoothA2dpNotificationHandler::BluetoothA2dpNotificationHandler()
+{ }
+
 BluetoothA2dpNotificationHandler::~BluetoothA2dpNotificationHandler()
 { }
 
+void
+BluetoothA2dpNotificationHandler::ConnectionStateNotification(
+  BluetoothA2dpConnectionState aState, const nsAString& aBdAddr)
+{ }
+
+void
+BluetoothA2dpNotificationHandler::AudioStateNotification(
+  BluetoothA2dpAudioState aState, const nsAString& aBdAddr)
+{ }
+
+void
+BluetoothA2dpNotificationHandler::AudioConfigNotification(
+  const nsAString& aBdAddr, uint32_t aSampleRate, uint8_t aChannelCount)
+{ }
+
+// Result handling
+//
+
+void
+BluetoothA2dpResultHandler::OnError(BluetoothStatus aStatus)
+{
+  BT_WARNING("Received error code %d", (int)aStatus);
+}
+
+void
+BluetoothA2dpResultHandler::Init()
+{ }
+
+void
+BluetoothA2dpResultHandler::Cleanup()
+{ }
+
+void
+BluetoothA2dpResultHandler::Connect()
+{ }
+
+void
+BluetoothA2dpResultHandler::Disconnect()
+{ }
+
 // Interface
 //
 
 BluetoothA2dpInterface::BluetoothA2dpInterface()
 { }
 
 BluetoothA2dpInterface::~BluetoothA2dpInterface()
 { }
 
 //
 // Bluetooth AVRCP Interface
 //
 
 // Notification handling
 //
 
+BluetoothAvrcpNotificationHandler::BluetoothAvrcpNotificationHandler()
+{ }
+
 BluetoothAvrcpNotificationHandler::~BluetoothAvrcpNotificationHandler()
 { }
 
+void
+BluetoothAvrcpNotificationHandler::GetPlayStatusNotification()
+{ }
+
+void
+BluetoothAvrcpNotificationHandler::ListPlayerAppAttrNotification()
+{ }
+
+void
+BluetoothAvrcpNotificationHandler::ListPlayerAppValuesNotification(
+  BluetoothAvrcpPlayerAttribute aAttrId)
+{ }
+
+void
+BluetoothAvrcpNotificationHandler::GetPlayerAppValueNotification(
+  uint8_t aNumAttrs, const BluetoothAvrcpPlayerAttribute* aAttrs)
+{ }
+
+void
+BluetoothAvrcpNotificationHandler::GetPlayerAppAttrsTextNotification(
+  uint8_t aNumAttrs, const BluetoothAvrcpPlayerAttribute* aAttrs)
+{ }
+
+void
+BluetoothAvrcpNotificationHandler::GetPlayerAppValuesTextNotification(
+  uint8_t aAttrId, uint8_t aNumVals, const uint8_t* aValues)
+{ }
+
+void
+BluetoothAvrcpNotificationHandler::SetPlayerAppValueNotification(
+  const BluetoothAvrcpPlayerSettings& aSettings)
+{ }
+
+void
+BluetoothAvrcpNotificationHandler::GetElementAttrNotification(
+  uint8_t aNumAttrs, const BluetoothAvrcpMediaAttribute* aAttrs)
+{ }
+
+void
+BluetoothAvrcpNotificationHandler::RegisterNotificationNotification(
+  BluetoothAvrcpEvent aEvent, uint32_t aParam)
+{ }
+
+void
+BluetoothAvrcpNotificationHandler::RemoteFeatureNotification(
+  const nsAString& aBdAddr, unsigned long aFeatures)
+{ }
+
+void
+BluetoothAvrcpNotificationHandler::VolumeChangeNotification(
+  uint8_t aVolume, uint8_t aCType)
+{ }
+
+void
+BluetoothAvrcpNotificationHandler::PassthroughCmdNotification(
+  int aId, int aKeyState)
+{ }
+
+// Result handling
+//
+
+void
+BluetoothAvrcpResultHandler::OnError(BluetoothStatus aStatus)
+{
+  BT_WARNING("Received error code %d", (int)aStatus);
+}
+
+void
+BluetoothAvrcpResultHandler::Init()
+{ }
+
+void
+BluetoothAvrcpResultHandler::Cleanup()
+{ }
+
+void
+BluetoothAvrcpResultHandler::GetPlayStatusRsp()
+{ }
+
+void
+BluetoothAvrcpResultHandler::ListPlayerAppAttrRsp()
+{ }
+
+void
+BluetoothAvrcpResultHandler::ListPlayerAppValueRsp()
+{ }
+
+void
+BluetoothAvrcpResultHandler::GetPlayerAppValueRsp()
+{ }
+
+void
+BluetoothAvrcpResultHandler::GetPlayerAppAttrTextRsp()
+{ }
+
+void
+BluetoothAvrcpResultHandler::GetPlayerAppValueTextRsp()
+{ }
+
+void
+BluetoothAvrcpResultHandler::GetElementAttrRsp()
+{ }
+
+void
+BluetoothAvrcpResultHandler::SetPlayerAppValueRsp()
+{ }
+
+void
+BluetoothAvrcpResultHandler::RegisterNotificationRsp()
+{ }
+
+void
+BluetoothAvrcpResultHandler::SetVolume()
+{ }
+
 // Interface
 //
 
 BluetoothAvrcpInterface::BluetoothAvrcpInterface()
 { }
 
 BluetoothAvrcpInterface::~BluetoothAvrcpInterface()
 { }
 
 //
 // Bluetooth GATT Interface
 //
 
 // Notification handling
 //
 
+BluetoothGattNotificationHandler::BluetoothGattNotificationHandler()
+{ }
+
 BluetoothGattNotificationHandler::~BluetoothGattNotificationHandler()
 { }
 
+void
+BluetoothGattNotificationHandler::RegisterClientNotification(
+  BluetoothGattStatus aStatus, int aClientIf, const BluetoothUuid& aAppUuid)
+{ }
+
+void
+BluetoothGattNotificationHandler::ScanResultNotification(
+  const nsAString& aBdAddr, int aRssi, const BluetoothGattAdvData& aAdvData)
+{ }
+
+void
+BluetoothGattNotificationHandler::ConnectNotification(
+  int aConnId, BluetoothGattStatus aStatus, int aClientIf,
+  const nsAString& aBdAddr)
+{ }
+
+void
+BluetoothGattNotificationHandler::DisconnectNotification(
+  int aConnId, BluetoothGattStatus aStatus, int aClientIf,
+  const nsAString& aBdAddr)
+{ }
+
+void
+BluetoothGattNotificationHandler::SearchCompleteNotification(
+  int aConnId, BluetoothGattStatus aStatus)
+{ }
+
+void
+BluetoothGattNotificationHandler::SearchResultNotification(
+  int aConnId, const BluetoothGattServiceId& aServiceId)
+{ }
+
+void
+BluetoothGattNotificationHandler::GetCharacteristicNotification(
+  int aConnId, BluetoothGattStatus aStatus,
+  const BluetoothGattServiceId& aServiceId,
+  const BluetoothGattId& aCharId,
+  const BluetoothGattCharProp& aCharProperty)
+{ }
+
+void
+BluetoothGattNotificationHandler::GetDescriptorNotification(
+  int aConnId, BluetoothGattStatus aStatus,
+  const BluetoothGattServiceId& aServiceId,
+  const BluetoothGattId& aCharId,
+  const BluetoothGattId& aDescriptorId)
+{ }
+
+void
+BluetoothGattNotificationHandler::GetIncludedServiceNotification(
+  int aConnId, BluetoothGattStatus aStatus,
+  const BluetoothGattServiceId& aServiceId,
+  const BluetoothGattServiceId& aIncludedServId)
+{ }
+
+void
+BluetoothGattNotificationHandler::RegisterNotificationNotification(
+  int aConnId, int aIsRegister, BluetoothGattStatus aStatus,
+  const BluetoothGattServiceId& aServiceId, const BluetoothGattId& aCharId)
+{ }
+
+void
+BluetoothGattNotificationHandler::NotifyNotification(
+  int aConnId, const BluetoothGattNotifyParam& aNotifyParam)
+{ }
+
+void
+BluetoothGattNotificationHandler::ReadCharacteristicNotification(
+  int aConnId, BluetoothGattStatus aStatus,
+  const BluetoothGattReadParam& aReadParam)
+{ }
+
+void
+BluetoothGattNotificationHandler::WriteCharacteristicNotification(
+  int aConnId, BluetoothGattStatus aStatus,
+  const BluetoothGattWriteParam& aWriteParam)
+{ }
+
+void
+BluetoothGattNotificationHandler::ReadDescriptorNotification(
+  int aConnId, BluetoothGattStatus aStatus,
+  const BluetoothGattReadParam& aReadParam)
+{ }
+
+void
+BluetoothGattNotificationHandler::WriteDescriptorNotification(
+  int aConnId, BluetoothGattStatus aStatus,
+  const BluetoothGattWriteParam& aWriteParam)
+{ }
+
+void
+BluetoothGattNotificationHandler::ExecuteWriteNotification(
+  int aConnId, BluetoothGattStatus aStatus)
+{ }
+
+void
+BluetoothGattNotificationHandler::ReadRemoteRssiNotification(
+  int aClientIf, const nsAString& aBdAddr, int aRssi,
+  BluetoothGattStatus aStatus)
+{ }
+
+void
+BluetoothGattNotificationHandler::ListenNotification(
+  BluetoothGattStatus aStatus, int aServerIf)
+{ }
+
+void
+BluetoothGattNotificationHandler::RegisterServerNotification(
+  BluetoothGattStatus aStatus, int aServerIf, const BluetoothUuid& aAppUuid)
+{ }
+
+void
+BluetoothGattNotificationHandler::ConnectionNotification(
+  int aConnId, int aServerIf, bool aConnected, const nsAString& aBdAddr)
+{ }
+
+void
+BluetoothGattNotificationHandler::ServiceAddedNotification(
+  BluetoothGattStatus aStatus, int aServerIf,
+  const BluetoothGattServiceId& aServiceId, int aServiceHandle)
+{ }
+
+void
+BluetoothGattNotificationHandler::IncludedServiceAddedNotification(
+  BluetoothGattStatus aStatus, int aServerIf, int aServiceHandle,
+  int aIncludedServiceHandle)
+{ }
+
+void
+BluetoothGattNotificationHandler::CharacteristicAddedNotification(
+  BluetoothGattStatus aStatus, int aServerIf, const BluetoothUuid& aCharId,
+  int aServiceHandle, int aCharacteristicHandle)
+{ }
+
+void
+BluetoothGattNotificationHandler::DescriptorAddedNotification(
+  BluetoothGattStatus aStatus, int aServerIf, const BluetoothUuid& aCharId,
+  int aServiceHandle, int aDescriptorHandle)
+{ }
+
+void
+BluetoothGattNotificationHandler::ServiceStartedNotification(
+  BluetoothGattStatus aStatus, int aServerIf, int aServiceHandle)
+{ }
+
+void
+BluetoothGattNotificationHandler::ServiceStoppedNotification(
+  BluetoothGattStatus aStatus, int aServerIf, int aServiceHandle)
+{ }
+
+void
+BluetoothGattNotificationHandler::ServiceDeletedNotification(
+  BluetoothGattStatus aStatus, int aServerIf, int aServiceHandle)
+{ }
+
+void
+BluetoothGattNotificationHandler::RequestReadNotification(
+  int aConnId, int aTransId, const nsAString& aBdAddr, int aAttributeHandle,
+  int aOffset, bool aIsLong)
+{ }
+
+void
+BluetoothGattNotificationHandler::RequestWriteNotification(
+  int aConnId, int aTransId, const nsAString& aBdAddr, int aAttributeHandle,
+  int aOffset, int aLength, const uint8_t* aValue, bool aNeedResponse,
+  bool aIsPrepareWrite)
+{ }
+
+void
+BluetoothGattNotificationHandler::RequestExecuteWriteNotification(
+  int aConnId, int aTransId, const nsAString& aBdAddr, bool aExecute)
+{ }
+
+void
+BluetoothGattNotificationHandler::ResponseConfirmationNotification(
+  BluetoothGattStatus aStatus, int aHandle)
+{ }
+
+void
+BluetoothGattNotificationHandler::IndicationSentNotification(
+  int aConnId, BluetoothGattStatus aStatus)
+{ }
+
+void
+BluetoothGattNotificationHandler::CongestionNotification(int aConnId,
+                                                         bool aCongested)
+{ }
+
+void
+BluetoothGattNotificationHandler::MtuChangedNotification(int aConnId,
+                                                         int aMtu)
+{ }
+
+// Result handling
+//
+
+void
+BluetoothGattResultHandler::OnError(BluetoothStatus aStatus)
+{
+  BT_WARNING("Received error code %d", (int)aStatus);
+}
+
+void
+BluetoothGattResultHandler::Init()
+{ }
+
+void
+BluetoothGattResultHandler::Cleanup()
+{ }
+
+void
+BluetoothGattResultHandler::RegisterClient()
+{ }
+
+void
+BluetoothGattResultHandler::UnregisterClient()
+{ }
+
+void
+BluetoothGattResultHandler::Scan()
+{ }
+
+void
+BluetoothGattResultHandler::Connect()
+{ }
+
+void
+BluetoothGattResultHandler::Disconnect()
+{ }
+
+void
+BluetoothGattResultHandler::Listen()
+{ }
+
+void
+BluetoothGattResultHandler::Refresh()
+{ }
+
+void
+BluetoothGattResultHandler::SearchService()
+{ }
+
+void
+BluetoothGattResultHandler::GetIncludedService()
+{ }
+
+void
+BluetoothGattResultHandler::GetCharacteristic()
+{ }
+
+void
+BluetoothGattResultHandler::GetDescriptor()
+{ }
+
+void
+BluetoothGattResultHandler::ReadCharacteristic()
+{ }
+
+void
+BluetoothGattResultHandler::WriteCharacteristic()
+{ }
+
+void
+BluetoothGattResultHandler::ReadDescriptor()
+{ }
+
+void
+BluetoothGattResultHandler::WriteDescriptor()
+{ }
+
+void
+BluetoothGattResultHandler::ExecuteWrite()
+{ }
+
+void
+BluetoothGattResultHandler::RegisterNotification()
+{ }
+
+void
+BluetoothGattResultHandler::DeregisterNotification()
+{ }
+
+void
+BluetoothGattResultHandler::ReadRemoteRssi()
+{ }
+
+void
+BluetoothGattResultHandler::GetDeviceType(BluetoothTypeOfDevice aType)
+{ }
+
+void
+BluetoothGattResultHandler::SetAdvData()
+{ }
+
+void
+BluetoothGattResultHandler::TestCommand()
+{ }
+
+void
+BluetoothGattResultHandler::RegisterServer()
+{ }
+
+void
+BluetoothGattResultHandler::UnregisterServer()
+{ }
+
+void
+BluetoothGattResultHandler::ConnectPeripheral()
+{ }
+
+void
+BluetoothGattResultHandler::DisconnectPeripheral()
+{ }
+
+void
+BluetoothGattResultHandler::AddService()
+{ }
+
+void
+BluetoothGattResultHandler::AddIncludedService()
+{ }
+
+void
+BluetoothGattResultHandler::AddCharacteristic()
+{ }
+
+void
+BluetoothGattResultHandler::AddDescriptor()
+{ }
+
+void
+BluetoothGattResultHandler::StartService()
+{ }
+
+void
+BluetoothGattResultHandler::StopService()
+{ }
+
+void
+BluetoothGattResultHandler::DeleteService()
+{ }
+
+void
+BluetoothGattResultHandler::SendIndication()
+{ }
+
+void
+BluetoothGattResultHandler::SendResponse()
+{ }
+
 // Interface
 //
 
 BluetoothGattInterface::BluetoothGattInterface()
 { }
 
 BluetoothGattInterface::~BluetoothGattInterface()
 { }
 
 //
 // Bluetooth Core Interface
 //
 
 // Notification handling
 //
 
+BluetoothNotificationHandler::BluetoothNotificationHandler()
+{ }
+
 BluetoothNotificationHandler::~BluetoothNotificationHandler()
 { }
 
+void
+BluetoothNotificationHandler::AdapterStateChangedNotification(bool aState)
+{ }
+
+void
+BluetoothNotificationHandler::AdapterPropertiesNotification(
+  BluetoothStatus aStatus,int aNumProperties,
+  const BluetoothProperty* aProperties)
+{ }
+
+void
+BluetoothNotificationHandler::RemoteDevicePropertiesNotification(
+  BluetoothStatus aStatus, const nsAString& aBdAddr, int aNumProperties,
+  const BluetoothProperty* aProperties)
+{ }
+
+void
+BluetoothNotificationHandler::DeviceFoundNotification(
+  int aNumProperties, const BluetoothProperty* aProperties)
+{ }
+
+void
+BluetoothNotificationHandler::DiscoveryStateChangedNotification(bool aState)
+{ }
+
+void
+BluetoothNotificationHandler::PinRequestNotification(
+  const nsAString& aRemoteBdAddr, const nsAString& aBdName, uint32_t aCod)
+{ }
+
+void
+BluetoothNotificationHandler::SspRequestNotification(
+  const nsAString& aRemoteBdAddr, const nsAString& aBdName, uint32_t aCod,
+  BluetoothSspVariant aPairingVariant, uint32_t aPassKey)
+{ }
+
+void
+BluetoothNotificationHandler::BondStateChangedNotification(
+  BluetoothStatus aStatus, const nsAString& aRemoteBdAddr,
+  BluetoothBondState aState)
+{ }
+
+void
+BluetoothNotificationHandler::AclStateChangedNotification(
+  BluetoothStatus aStatus, const nsAString& aRemoteBdAddr, bool aState)
+{ }
+
+void
+BluetoothNotificationHandler::DutModeRecvNotification(uint16_t aOpcode,
+                                                      const uint8_t* aBuf,
+                                                      uint8_t aLen)
+{ }
+
+void
+BluetoothNotificationHandler::LeTestModeNotification(BluetoothStatus aStatus,
+                                                     uint16_t aNumPackets)
+{ }
+
+void
+BluetoothNotificationHandler::EnergyInfoNotification(
+  const BluetoothActivityEnergyInfo& aInfo)
+{ }
+
+void
+BluetoothNotificationHandler::BackendErrorNotification(bool aCrashed)
+{ }
+
+// Result handling
+//
+
+void
+BluetoothResultHandler::OnError(BluetoothStatus aStatus)
+{
+  BT_LOGR("Received error code %d", aStatus);
+}
+
+void
+BluetoothResultHandler::Init()
+{ }
+
+void
+BluetoothResultHandler::Cleanup()
+{ }
+
+void
+BluetoothResultHandler::Enable()
+{ }
+
+void
+BluetoothResultHandler::Disable()
+{ }
+
+void
+BluetoothResultHandler::GetAdapterProperties()
+{ }
+
+void
+BluetoothResultHandler::GetAdapterProperty()
+{ }
+
+void
+BluetoothResultHandler::SetAdapterProperty()
+{ }
+
+void
+BluetoothResultHandler::GetRemoteDeviceProperties()
+{ }
+
+void
+BluetoothResultHandler::GetRemoteDeviceProperty()
+{ }
+
+void
+BluetoothResultHandler::SetRemoteDeviceProperty()
+{ }
+
+void
+BluetoothResultHandler::GetRemoteServiceRecord()
+{ }
+
+void
+BluetoothResultHandler::GetRemoteServices()
+{ }
+
+void
+BluetoothResultHandler::StartDiscovery()
+{ }
+
+void
+BluetoothResultHandler::CancelDiscovery()
+{ }
+
+void
+BluetoothResultHandler::CreateBond()
+{ }
+
+void
+BluetoothResultHandler::RemoveBond()
+{ }
+
+void
+BluetoothResultHandler::CancelBond()
+{ }
+
+void
+BluetoothResultHandler::GetConnectionState()
+{ }
+
+void
+BluetoothResultHandler::PinReply()
+{ }
+
+void
+BluetoothResultHandler::SspReply()
+{ }
+
+void
+BluetoothResultHandler::DutModeConfigure()
+{ }
+
+void
+BluetoothResultHandler::DutModeSend()
+{ }
+
+void
+BluetoothResultHandler::LeTestMode()
+{ }
+
+void
+BluetoothResultHandler::ReadEnergyInfo()
+{ }
+
 // Interface
 //
 
 BluetoothInterface*
 BluetoothInterface::GetInstance()
 {
 #if ANDROID_VERSION >= 17
   /* We pick a default backend from the available ones. The options are
--- a/dom/bluetooth/common/BluetoothInterface.h
+++ b/dom/bluetooth/common/BluetoothInterface.h
@@ -22,37 +22,34 @@ class BluetoothSetupResultHandler
 {
 public:
   virtual void OnError(BluetoothStatus aStatus);
   virtual void RegisterModule();
   virtual void UnregisterModule();
   virtual void Configuration();
 
 protected:
-  virtual ~BluetoothSetupResultHandler();
+  virtual ~BluetoothSetupResultHandler() { }
 };
 
 //
 // Socket Interface
 //
 
 class BluetoothSocketResultHandler
   : public mozilla::ipc::DaemonSocketResultHandler
 {
 public:
-  virtual void OnError(BluetoothStatus aStatus)
-  {
-    BT_WARNING("Received error code %d", (int)aStatus);
-  }
+  virtual void OnError(BluetoothStatus aStatus);
 
-  virtual void Listen(int aSockFd) { }
+  virtual void Listen(int aSockFd);
   virtual void Connect(int aSockFd, const nsAString& aBdAddress,
-                       int aConnectionState) { }
+                       int aConnectionState);
   virtual void Accept(int aSockFd, const nsAString& aBdAddress,
-                      int aConnectionState) { }
+                      int aConnectionState);
 
 protected:
   virtual ~BluetoothSocketResultHandler() { }
 };
 
 class BluetoothSocketInterface
 {
 public:
@@ -82,132 +79,110 @@ protected:
 // Handsfree Interface
 //
 
 class BluetoothHandsfreeNotificationHandler
 {
 public:
   virtual void
   ConnectionStateNotification(BluetoothHandsfreeConnectionState aState,
-                              const nsAString& aBdAddr)
-  { }
+                              const nsAString& aBdAddr);
 
   virtual void
   AudioStateNotification(BluetoothHandsfreeAudioState aState,
-                         const nsAString& aBdAddr)
-  { }
+                         const nsAString& aBdAddr);
 
   virtual void
   VoiceRecognitionNotification(BluetoothHandsfreeVoiceRecognitionState aState,
-                               const nsAString& aBdAddr)
-  { }
+                               const nsAString& aBdAddr);
 
   virtual void
-  AnswerCallNotification(const nsAString& aBdAddr)
-  { }
+  AnswerCallNotification(const nsAString& aBdAddr);
 
   virtual void
-  HangupCallNotification(const nsAString& aBdAddr)
-  { }
+  HangupCallNotification(const nsAString& aBdAddr);
 
   virtual void
   VolumeNotification(BluetoothHandsfreeVolumeType aType,
                      int aVolume,
-                     const nsAString& aBdAddr)
-  { }
+                     const nsAString& aBdAddr);
 
   virtual void
   DialCallNotification(const nsAString& aNumber,
-                       const nsAString& aBdAddr)
-  { }
+                       const nsAString& aBdAddr);
 
   virtual void
   DtmfNotification(char aDtmf,
-                   const nsAString& aBdAddr)
-  { }
+                   const nsAString& aBdAddr);
 
   virtual void
   NRECNotification(BluetoothHandsfreeNRECState aNrec,
-                   const nsAString& aBdAddr)
-  { }
+                   const nsAString& aBdAddr);
 
   virtual void
   WbsNotification(BluetoothHandsfreeWbsConfig aWbs,
-                  const nsAString& aBdAddr)
-  { }
+                  const nsAString& aBdAddr);
 
   virtual void
   CallHoldNotification(BluetoothHandsfreeCallHoldType aChld,
-                       const nsAString& aBdAddr)
-  { }
+                       const nsAString& aBdAddr);
 
   virtual void
-  CnumNotification(const nsAString& aBdAddr)
-  { }
+  CnumNotification(const nsAString& aBdAddr);
 
   virtual void
-  CindNotification(const nsAString& aBdAddr)
-  { }
+  CindNotification(const nsAString& aBdAddr);
 
   virtual void
-  CopsNotification(const nsAString& aBdAddr)
-  { }
+  CopsNotification(const nsAString& aBdAddr);
 
   virtual void
-  ClccNotification(const nsAString& aBdAddr)
-  { }
+  ClccNotification(const nsAString& aBdAddr);
 
   virtual void
   UnknownAtNotification(const nsACString& aAtString,
-                        const nsAString& aBdAddr)
-  { }
+                        const nsAString& aBdAddr);
 
   virtual void
-  KeyPressedNotification(const nsAString& aBdAddr)
-  { }
+  KeyPressedNotification(const nsAString& aBdAddr);
 
 protected:
-  BluetoothHandsfreeNotificationHandler()
-  { }
-
+  BluetoothHandsfreeNotificationHandler();
   virtual ~BluetoothHandsfreeNotificationHandler();
 };
 
 class BluetoothHandsfreeResultHandler
   : public mozilla::ipc::DaemonSocketResultHandler
 {
 public:
-  virtual void OnError(BluetoothStatus aStatus)
-  {
-    BT_WARNING("Received error code %d", (int)aStatus);
-  }
+  virtual void OnError(BluetoothStatus aStatus);
+
+  virtual void Init();
+  virtual void Cleanup();
 
-  virtual void Init() { }
-  virtual void Cleanup() { }
+  virtual void Connect();
+  virtual void Disconnect();
+  virtual void ConnectAudio();
+  virtual void DisconnectAudio();
 
-  virtual void Connect() { }
-  virtual void Disconnect() { }
-  virtual void ConnectAudio() { }
-  virtual void DisconnectAudio() { }
+  virtual void StartVoiceRecognition();
+  virtual void StopVoiceRecognition();
 
-  virtual void StartVoiceRecognition() { }
-  virtual void StopVoiceRecognition() { }
+  virtual void VolumeControl();
 
-  virtual void VolumeControl() { }
-
-  virtual void DeviceStatusNotification() { }
+  virtual void DeviceStatusNotification();
 
-  virtual void CopsResponse() { }
-  virtual void CindResponse() { }
-  virtual void FormattedAtResponse() { }
-  virtual void AtResponse() { }
-  virtual void ClccResponse() { }
-  virtual void PhoneStateChange() { }
+  virtual void CopsResponse();
+  virtual void CindResponse();
+  virtual void FormattedAtResponse();
+  virtual void AtResponse();
+  virtual void ClccResponse();
+  virtual void PhoneStateChange();
 
-  virtual void ConfigureWbs() { }
+  virtual void ConfigureWbs();
 
 protected:
   virtual ~BluetoothHandsfreeResultHandler() { }
 };
 
 class BluetoothHandsfreeInterface
 {
 public:
@@ -292,50 +267,42 @@ protected:
 // Bluetooth Advanced Audio Interface
 //
 
 class BluetoothA2dpNotificationHandler
 {
 public:
   virtual void
   ConnectionStateNotification(BluetoothA2dpConnectionState aState,
-                              const nsAString& aBdAddr)
-  { }
+                              const nsAString& aBdAddr);
 
   virtual void
   AudioStateNotification(BluetoothA2dpAudioState aState,
-                         const nsAString& aBdAddr)
-  { }
+                         const nsAString& aBdAddr);
 
   virtual void
   AudioConfigNotification(const nsAString& aBdAddr,
                           uint32_t aSampleRate,
-                          uint8_t aChannelCount)
-  { }
+                          uint8_t aChannelCount);
 
 protected:
-  BluetoothA2dpNotificationHandler()
-  { }
-
+  BluetoothA2dpNotificationHandler();
   virtual ~BluetoothA2dpNotificationHandler();
 };
 
 class BluetoothA2dpResultHandler
   : public mozilla::ipc::DaemonSocketResultHandler
 {
 public:
-  virtual void OnError(BluetoothStatus aStatus)
-  {
-    BT_WARNING("Received error code %d", (int)aStatus);
-  }
+  virtual void OnError(BluetoothStatus aStatus);
 
-  virtual void Init() { }
-  virtual void Cleanup() { }
-  virtual void Connect() { }
-  virtual void Disconnect() { }
+  virtual void Init();
+  virtual void Cleanup();
+  virtual void Connect();
+  virtual void Disconnect();
 
 protected:
   virtual ~BluetoothA2dpResultHandler() { }
 };
 
 class BluetoothA2dpInterface
 {
 public:
@@ -356,103 +323,88 @@ protected:
 //
 // Bluetooth AVRCP Interface
 //
 
 class BluetoothAvrcpNotificationHandler
 {
 public:
   virtual void
-  GetPlayStatusNotification()
-  { }
+  GetPlayStatusNotification();
 
   virtual void
-  ListPlayerAppAttrNotification()
-  { }
+  ListPlayerAppAttrNotification();
 
   virtual void
-  ListPlayerAppValuesNotification(BluetoothAvrcpPlayerAttribute aAttrId)
-  { }
+  ListPlayerAppValuesNotification(BluetoothAvrcpPlayerAttribute aAttrId);
 
   virtual void
   GetPlayerAppValueNotification(uint8_t aNumAttrs,
-                                const BluetoothAvrcpPlayerAttribute* aAttrs)
-  { }
+                                const BluetoothAvrcpPlayerAttribute* aAttrs);
 
   virtual void
-  GetPlayerAppAttrsTextNotification(uint8_t aNumAttrs,
-                                    const BluetoothAvrcpPlayerAttribute* aAttrs)
-  { }
+  GetPlayerAppAttrsTextNotification(
+    uint8_t aNumAttrs, const BluetoothAvrcpPlayerAttribute* aAttrs);
 
   virtual void
   GetPlayerAppValuesTextNotification(uint8_t aAttrId, uint8_t aNumVals,
-                                     const uint8_t* aValues)
-  { }
+                                     const uint8_t* aValues);
 
   virtual void
-  SetPlayerAppValueNotification(const BluetoothAvrcpPlayerSettings& aSettings)
-  { }
+  SetPlayerAppValueNotification(
+    const BluetoothAvrcpPlayerSettings& aSettings);
 
   virtual void
   GetElementAttrNotification(uint8_t aNumAttrs,
-                             const BluetoothAvrcpMediaAttribute* aAttrs)
-  { }
+                             const BluetoothAvrcpMediaAttribute* aAttrs);
 
   virtual void
   RegisterNotificationNotification(BluetoothAvrcpEvent aEvent,
-                                   uint32_t aParam)
-  { }
+                                   uint32_t aParam);
 
   virtual void
-  RemoteFeatureNotification(const nsAString& aBdAddr, unsigned long aFeatures)
-  { }
+  RemoteFeatureNotification(const nsAString& aBdAddr,
+                            unsigned long aFeatures);
 
   virtual void
-  VolumeChangeNotification(uint8_t aVolume, uint8_t aCType)
-  { }
+  VolumeChangeNotification(uint8_t aVolume, uint8_t aCType);
 
   virtual void
-  PassthroughCmdNotification(int aId, int aKeyState)
-  { }
+  PassthroughCmdNotification(int aId, int aKeyState);
 
 protected:
-  BluetoothAvrcpNotificationHandler()
-  { }
-
+  BluetoothAvrcpNotificationHandler();
   virtual ~BluetoothAvrcpNotificationHandler();
 };
 
 class BluetoothAvrcpResultHandler
   : public mozilla::ipc::DaemonSocketResultHandler
 {
 public:
-  virtual void OnError(BluetoothStatus aStatus)
-  {
-    BT_WARNING("Received error code %d", (int)aStatus);
-  }
+  virtual void OnError(BluetoothStatus aStatus);
+
+  virtual void Init();
+  virtual void Cleanup();
 
-  virtual void Init() { }
-  virtual void Cleanup() { }
+  virtual void GetPlayStatusRsp();
 
-  virtual void GetPlayStatusRsp() { }
+  virtual void ListPlayerAppAttrRsp();
+  virtual void ListPlayerAppValueRsp();
 
-  virtual void ListPlayerAppAttrRsp() { }
-  virtual void ListPlayerAppValueRsp() { }
+  virtual void GetPlayerAppValueRsp();
+  virtual void GetPlayerAppAttrTextRsp();
+  virtual void GetPlayerAppValueTextRsp();
 
-  virtual void GetPlayerAppValueRsp() { }
-  virtual void GetPlayerAppAttrTextRsp() { }
-  virtual void GetPlayerAppValueTextRsp() { }
+  virtual void GetElementAttrRsp();
 
-  virtual void GetElementAttrRsp() { }
-
-  virtual void SetPlayerAppValueRsp() { }
+  virtual void SetPlayerAppValueRsp();
 
-  virtual void RegisterNotificationRsp() { }
+  virtual void RegisterNotificationRsp();
 
-  virtual void SetVolume() { }
+  virtual void SetVolume();
 
 protected:
   virtual ~BluetoothAvrcpResultHandler() { }
 };
 
 class BluetoothAvrcpInterface
 {
 public:
@@ -508,297 +460,262 @@ protected:
 //
 
 class BluetoothGattNotificationHandler
 {
 public:
   virtual void
   RegisterClientNotification(BluetoothGattStatus aStatus,
                              int aClientIf,
-                             const BluetoothUuid& aAppUuid)
-  { }
+                             const BluetoothUuid& aAppUuid);
 
   virtual void
   ScanResultNotification(const nsAString& aBdAddr,
                          int aRssi,
-                         const BluetoothGattAdvData& aAdvData)
-  { }
+                         const BluetoothGattAdvData& aAdvData);
 
   virtual void
   ConnectNotification(int aConnId,
                       BluetoothGattStatus aStatus,
                       int aClientIf,
-                      const nsAString& aBdAddr)
-  { }
+                      const nsAString& aBdAddr);
 
   virtual void
   DisconnectNotification(int aConnId,
                          BluetoothGattStatus aStatus,
                          int aClientIf,
-                         const nsAString& aBdAddr)
-  { }
+                         const nsAString& aBdAddr);
 
   virtual void
-  SearchCompleteNotification(int aConnId, BluetoothGattStatus aStatus) { }
+  SearchCompleteNotification(int aConnId, BluetoothGattStatus aStatus);
 
   virtual void
   SearchResultNotification(int aConnId,
-                           const BluetoothGattServiceId& aServiceId)
-  { }
+                           const BluetoothGattServiceId& aServiceId);
 
   virtual void
   GetCharacteristicNotification(int aConnId,
                                 BluetoothGattStatus aStatus,
                                 const BluetoothGattServiceId& aServiceId,
                                 const BluetoothGattId& aCharId,
-                                const BluetoothGattCharProp& aCharProperty)
-  { }
+                                const BluetoothGattCharProp& aCharProperty);
 
   virtual void
   GetDescriptorNotification(int aConnId,
                             BluetoothGattStatus aStatus,
                             const BluetoothGattServiceId& aServiceId,
                             const BluetoothGattId& aCharId,
-                            const BluetoothGattId& aDescriptorId)
-  { }
+                            const BluetoothGattId& aDescriptorId);
 
   virtual void
   GetIncludedServiceNotification(int aConnId,
                                  BluetoothGattStatus aStatus,
                                  const BluetoothGattServiceId& aServiceId,
-                                 const BluetoothGattServiceId& aIncludedServId)
-  { }
+                                 const BluetoothGattServiceId& aIncludedServId);
 
   virtual void
   RegisterNotificationNotification(int aConnId,
                                    int aIsRegister,
                                    BluetoothGattStatus aStatus,
                                    const BluetoothGattServiceId& aServiceId,
-                                   const BluetoothGattId& aCharId)
-  { }
+                                   const BluetoothGattId& aCharId);
 
   virtual void
-  NotifyNotification(int aConnId, const BluetoothGattNotifyParam& aNotifyParam)
-  { }
+  NotifyNotification(int aConnId,
+                     const BluetoothGattNotifyParam& aNotifyParam);
 
   virtual void
   ReadCharacteristicNotification(int aConnId,
                                  BluetoothGattStatus aStatus,
-                                 const BluetoothGattReadParam& aReadParam)
-  { }
+                                 const BluetoothGattReadParam& aReadParam);
 
   virtual void
   WriteCharacteristicNotification(int aConnId,
                                   BluetoothGattStatus aStatus,
-                                  const BluetoothGattWriteParam& aWriteParam)
-  { }
+                                  const BluetoothGattWriteParam& aWriteParam);
 
   virtual void
   ReadDescriptorNotification(int aConnId,
                              BluetoothGattStatus aStatus,
-                             const BluetoothGattReadParam& aReadParam)
-  { }
+                             const BluetoothGattReadParam& aReadParam);
 
   virtual void
   WriteDescriptorNotification(int aConnId,
                               BluetoothGattStatus aStatus,
-                              const BluetoothGattWriteParam& aWriteParam)
-  { }
+                              const BluetoothGattWriteParam& aWriteParam);
 
   virtual void
-  ExecuteWriteNotification(int aConnId, BluetoothGattStatus aStatus) { }
+  ExecuteWriteNotification(int aConnId, BluetoothGattStatus aStatus);
 
   virtual void
   ReadRemoteRssiNotification(int aClientIf,
                              const nsAString& aBdAddr,
                              int aRssi,
-                             BluetoothGattStatus aStatus)
-  { }
+                             BluetoothGattStatus aStatus);
 
   virtual void
-  ListenNotification(BluetoothGattStatus aStatus, int aServerIf) { }
+  ListenNotification(BluetoothGattStatus aStatus, int aServerIf);
 
   virtual void
   RegisterServerNotification(BluetoothGattStatus aStatus,
                              int aServerIf,
-                             const BluetoothUuid& aAppUuid)
-  { }
+                             const BluetoothUuid& aAppUuid);
 
   virtual void
   ConnectionNotification(int aConnId,
                          int aServerIf,
                          bool aConnected,
-                         const nsAString& aBdAddr)
-  { }
+                         const nsAString& aBdAddr);
 
   virtual void
   ServiceAddedNotification(BluetoothGattStatus aStatus,
                            int aServerIf,
                            const BluetoothGattServiceId& aServiceId,
-                           int aServiceHandle)
-  { }
+                           int aServiceHandle);
 
   virtual void
   IncludedServiceAddedNotification(BluetoothGattStatus aStatus,
                                    int aServerIf,
                                    int aServiceHandle,
-                                   int aIncludedServiceHandle)
-  { }
+                                   int aIncludedServiceHandle);
 
   virtual void
   CharacteristicAddedNotification(BluetoothGattStatus aStatus,
                                   int aServerIf,
                                   const BluetoothUuid& aCharId,
                                   int aServiceHandle,
-                                  int aCharacteristicHandle)
-  { }
+                                  int aCharacteristicHandle);
 
   virtual void
   DescriptorAddedNotification(BluetoothGattStatus aStatus,
                               int aServerIf,
                               const BluetoothUuid& aCharId,
                               int aServiceHandle,
-                              int aDescriptorHandle)
-  { }
+                              int aDescriptorHandle);
 
   virtual void
   ServiceStartedNotification(BluetoothGattStatus aStatus,
                              int aServerIf,
-                             int aServiceHandle)
-  { }
+                             int aServiceHandle);
 
   virtual void
   ServiceStoppedNotification(BluetoothGattStatus aStatus,
                              int aServerIf,
-                             int aServiceHandle)
-  { }
+                             int aServiceHandle);
 
   virtual void
   ServiceDeletedNotification(BluetoothGattStatus aStatus,
                              int aServerIf,
-                             int aServiceHandle)
-  { }
+                             int aServiceHandle);
 
   virtual void
   RequestReadNotification(int aConnId,
                           int aTransId,
                           const nsAString& aBdAddr,
                           int aAttributeHandle,
                           int aOffset,
-                          bool aIsLong)
-  { }
+                          bool aIsLong);
 
   virtual void
   RequestWriteNotification(int aConnId,
                            int aTransId,
                            const nsAString& aBdAddr,
                            int aAttributeHandle,
                            int aOffset,
                            int aLength,
                            const uint8_t* aValue,
                            bool aNeedResponse,
-                           bool aIsPrepareWrite)
-  { }
+                           bool aIsPrepareWrite);
 
   virtual void
   RequestExecuteWriteNotification(int aConnId,
                                   int aTransId,
                                   const nsAString& aBdAddr,
-                                  bool aExecute) /* true: execute */
-                                                 /* false: cancel */
-  { }
+                                  bool aExecute); /* true: execute */
+                                                  /* false: cancel */
 
   virtual void
   ResponseConfirmationNotification(BluetoothGattStatus aStatus,
-                                   int aHandle)
-  { }
+                                   int aHandle);
 
   virtual void
   IndicationSentNotification(int aConnId,
-                             BluetoothGattStatus aStatus)
-  { }
+                             BluetoothGattStatus aStatus);
 
   virtual void
   CongestionNotification(int aConnId,
-                         bool aCongested)
-  { }
+                         bool aCongested);
 
   virtual void
   MtuChangedNotification(int aConnId,
-                         int aMtu)
-  { }
+                         int aMtu);
 
 protected:
-  BluetoothGattNotificationHandler()
-  { }
-
+  BluetoothGattNotificationHandler();
   virtual ~BluetoothGattNotificationHandler();
 };
 
 class BluetoothGattResultHandler
   : public mozilla::ipc::DaemonSocketResultHandler
 {
 public:
-  virtual void OnError(BluetoothStatus aStatus)
-  {
-    BT_WARNING("Received error code %d", (int)aStatus);
-  }
+  virtual void OnError(BluetoothStatus aStatus);
+
+  virtual void Init();
+  virtual void Cleanup();
 
-  virtual void Init() { }
-  virtual void Cleanup() { }
+  virtual void RegisterClient();
+  virtual void UnregisterClient();
 
-  virtual void RegisterClient() { }
-  virtual void UnregisterClient() { }
+  virtual void Scan();
 
-  virtual void Scan() { }
+  virtual void Connect();
+  virtual void Disconnect();
 
-  virtual void Connect() { }
-  virtual void Disconnect() { }
-
-  virtual void Listen() { }
-  virtual void Refresh() { }
+  virtual void Listen();
+  virtual void Refresh();
 
-  virtual void SearchService() { }
-  virtual void GetIncludedService() { }
-  virtual void GetCharacteristic() { }
-  virtual void GetDescriptor() { }
+  virtual void SearchService();
+  virtual void GetIncludedService();
+  virtual void GetCharacteristic();
+  virtual void GetDescriptor();
 
-  virtual void ReadCharacteristic() { }
-  virtual void WriteCharacteristic() { }
-  virtual void ReadDescriptor() { }
-  virtual void WriteDescriptor() { }
+  virtual void ReadCharacteristic();
+  virtual void WriteCharacteristic();
+  virtual void ReadDescriptor();
+  virtual void WriteDescriptor();
 
-  virtual void ExecuteWrite() { }
+  virtual void ExecuteWrite();
 
-  virtual void RegisterNotification() { }
-  virtual void DeregisterNotification() { }
+  virtual void RegisterNotification();
+  virtual void DeregisterNotification();
 
-  virtual void ReadRemoteRssi() { }
-  virtual void GetDeviceType(BluetoothTypeOfDevice type) { }
-  virtual void SetAdvData() { }
-  virtual void TestCommand() { }
+  virtual void ReadRemoteRssi();
+  virtual void GetDeviceType(BluetoothTypeOfDevice aType);
+  virtual void SetAdvData();
+  virtual void TestCommand();
 
-  virtual void RegisterServer() { }
-  virtual void UnregisterServer() { }
+  virtual void RegisterServer();
+  virtual void UnregisterServer();
 
-  virtual void ConnectPeripheral() { }
-  virtual void DisconnectPeripheral() { }
+  virtual void ConnectPeripheral();
+  virtual void DisconnectPeripheral();
 
-  virtual void AddService() { }
-  virtual void AddIncludedService() { }
-  virtual void AddCharacteristic() { }
-  virtual void AddDescriptor() { }
+  virtual void AddService();
+  virtual void AddIncludedService();
+  virtual void AddCharacteristic();
+  virtual void AddDescriptor();
 
-  virtual void StartService() { }
-  virtual void StopService() { }
-  virtual void DeleteService() { }
+  virtual void StartService();
+  virtual void StopService();
+  virtual void DeleteService();
 
-  virtual void SendIndication() { }
+  virtual void SendIndication();
 
-  virtual void SendResponse() { }
+  virtual void SendResponse();
 
 protected:
   virtual ~BluetoothGattResultHandler() { }
 };
 
 class BluetoothGattInterface
 {
 public:
@@ -1007,107 +924,100 @@ protected:
 
 //
 // Bluetooth Core Interface
 //
 
 class BluetoothNotificationHandler
 {
 public:
-  virtual void AdapterStateChangedNotification(bool aState) { }
+  virtual void AdapterStateChangedNotification(bool aState);
   virtual void AdapterPropertiesNotification(
     BluetoothStatus aStatus, int aNumProperties,
-    const BluetoothProperty* aProperties) { }
+    const BluetoothProperty* aProperties);
 
   virtual void RemoteDevicePropertiesNotification(
     BluetoothStatus aStatus, const nsAString& aBdAddr,
-    int aNumProperties, const BluetoothProperty* aProperties) { }
+    int aNumProperties, const BluetoothProperty* aProperties);
 
   virtual void DeviceFoundNotification(
-    int aNumProperties, const BluetoothProperty* aProperties) { }
+    int aNumProperties, const BluetoothProperty* aProperties);
 
-  virtual void DiscoveryStateChangedNotification(bool aState) { }
+  virtual void DiscoveryStateChangedNotification(bool aState);
 
   virtual void PinRequestNotification(const nsAString& aRemoteBdAddr,
                                       const nsAString& aBdName,
-                                      uint32_t aCod) { }
+                                      uint32_t aCod);
   virtual void SspRequestNotification(const nsAString& aRemoteBdAddr,
                                       const nsAString& aBdName,
                                       uint32_t aCod,
                                       BluetoothSspVariant aPairingVariant,
-                                      uint32_t aPassKey) { }
+                                      uint32_t aPassKey);
 
   virtual void BondStateChangedNotification(BluetoothStatus aStatus,
                                             const nsAString& aRemoteBdAddr,
-                                            BluetoothBondState aState) { }
+                                            BluetoothBondState aState);
   virtual void AclStateChangedNotification(BluetoothStatus aStatus,
                                            const nsAString& aRemoteBdAddr,
-                                           bool aState) { }
+                                           bool aState);
 
   virtual void DutModeRecvNotification(uint16_t aOpcode,
-                                       const uint8_t* aBuf, uint8_t aLen) { }
+                                       const uint8_t* aBuf, uint8_t aLen);
   virtual void LeTestModeNotification(BluetoothStatus aStatus,
-                                      uint16_t aNumPackets) { }
+                                      uint16_t aNumPackets);
 
-  virtual void EnergyInfoNotification(const BluetoothActivityEnergyInfo& aInfo)
-  { }
+  virtual void EnergyInfoNotification(const BluetoothActivityEnergyInfo& aInfo);
 
-  virtual void BackendErrorNotification(bool aCrashed)
-  { }
+  virtual void BackendErrorNotification(bool aCrashed);
 
 protected:
-  BluetoothNotificationHandler()
-  { }
-
+  BluetoothNotificationHandler();
   virtual ~BluetoothNotificationHandler();
 };
 
 class BluetoothResultHandler
   : public mozilla::ipc::DaemonSocketResultHandler
 {
 public:
-  virtual void OnError(BluetoothStatus aStatus)
-  {
-    BT_LOGR("Received error code %d", aStatus);
-  }
+  virtual void OnError(BluetoothStatus aStatus);
+
+  virtual void Init();
+  virtual void Cleanup();
+  virtual void Enable();
+  virtual void Disable();
 
-  virtual void Init() { }
-  virtual void Cleanup() { }
-  virtual void Enable() { }
-  virtual void Disable() { }
+  virtual void GetAdapterProperties();
+  virtual void GetAdapterProperty();
+  virtual void SetAdapterProperty();
 
-  virtual void GetAdapterProperties() { }
-  virtual void GetAdapterProperty() { }
-  virtual void SetAdapterProperty() { }
+  virtual void GetRemoteDeviceProperties();
+  virtual void GetRemoteDeviceProperty();
+  virtual void SetRemoteDeviceProperty();
 
-  virtual void GetRemoteDeviceProperties() { }
-  virtual void GetRemoteDeviceProperty() { }
-  virtual void SetRemoteDeviceProperty() { }
+  virtual void GetRemoteServiceRecord();
+  virtual void GetRemoteServices();
 
-  virtual void GetRemoteServiceRecord() { }
-  virtual void GetRemoteServices() { }
+  virtual void StartDiscovery();
+  virtual void CancelDiscovery();
 
-  virtual void StartDiscovery() { }
-  virtual void CancelDiscovery() { }
+  virtual void CreateBond();
+  virtual void RemoveBond();
+  virtual void CancelBond();
 
-  virtual void CreateBond() { }
-  virtual void RemoveBond() { }
-  virtual void CancelBond() { }
+  virtual void GetConnectionState();
 
-  virtual void GetConnectionState() { }
-
-  virtual void PinReply() { }
-  virtual void SspReply() { }
+  virtual void PinReply();
+  virtual void SspReply();
 
-  virtual void DutModeConfigure() { }
-  virtual void DutModeSend() { }
+  virtual void DutModeConfigure();
+  virtual void DutModeSend();
 
-  virtual void LeTestMode() { }
+  virtual void LeTestMode();
 
-  virtual void ReadEnergyInfo() { }
+  virtual void ReadEnergyInfo();
 
 protected:
   virtual ~BluetoothResultHandler() { }
 };
 
 class BluetoothInterface
 {
 public:
--- a/dom/browser-element/BrowserElementParent.js
+++ b/dom/browser-element/BrowserElementParent.js
@@ -72,18 +72,16 @@ function BrowserElementParent() {
   this._pendingDOMRequests = {};
   this._pendingSetInputMethodActive = [];
   this._nextPaintListeners = [];
   this._pendingDOMFullscreen = false;
 
   Services.obs.addObserver(this, 'oop-frameloader-crashed', /* ownsWeak = */ true);
   Services.obs.addObserver(this, 'copypaste-docommand', /* ownsWeak = */ true);
   Services.obs.addObserver(this, 'ask-children-to-execute-copypaste-command', /* ownsWeak = */ true);
-  Services.obs.addObserver(this, 'frameloader-message-manager-will-change', /* ownsWeak = */ true);
-  Services.obs.addObserver(this, 'frameloader-message-manager-changed', /* ownsWeak = */ true);
 }
 
 BrowserElementParent.prototype = {
 
   classDescription: "BrowserElementAPI implementation",
   classID: Components.ID("{9f171ac4-0939-4ef8-b360-3408aedc3060}"),
   contractID: "@mozilla.org/dom/browser-element-api;1",
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIBrowserElementAPI,
@@ -1106,26 +1104,16 @@ BrowserElementParent.prototype = {
         this._sendAsyncMsg('do-command', { command: data });
       }
       break;
     case 'ask-children-to-execute-copypaste-command':
       if (this._isAlive() && this._frameElement == subject.wrappedJSObject) {
         this._sendAsyncMsg('copypaste-do-command', { command: data });
       }
       break;
-    case 'frameloader-message-manager-will-change':
-      if (this._isAlive() && subject == this._frameLoader) {
-        this._removeMessageListener();
-      }
-      break;
-    case 'frameloader-message-manager-changed':
-      if (this._isAlive() && subject == this._frameLoader) {
-        this._setupMessageListener();
-      }
-      break;
     default:
       debug('Unknown topic: ' + topic);
       break;
     };
   },
 };
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([BrowserElementParent]);
--- a/dom/camera/DOMCameraControl.cpp
+++ b/dom/camera/DOMCameraControl.cpp
@@ -126,54 +126,16 @@ StartRecordingHelper::HandleEvent(nsIDOM
   nsString eventType;
   aEvent->GetType(eventType);
   mState = eventType.EqualsLiteral("success");
   return NS_OK;
 }
 
 NS_IMPL_ISUPPORTS(mozilla::StartRecordingHelper, nsIDOMEventListener)
 
-class mozilla::RecorderPosterHelper : public nsIDOMEventListener
-{
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIDOMEVENTLISTENER
-
-  explicit RecorderPosterHelper(nsDOMCameraControl* aDOMCameraControl)
-    : mDOMCameraControl(aDOMCameraControl)
-    , mState(CameraControlListener::kPosterFailed)
-  {
-    MOZ_COUNT_CTOR(RecorderPosterHelper);
-  }
-
-protected:
-  virtual ~RecorderPosterHelper()
-  {
-    MOZ_COUNT_DTOR(RecorderPosterHelper);
-    mDOMCameraControl->OnRecorderStateChange(mState, 0, 0);
-  }
-
-protected:
-  nsRefPtr<nsDOMCameraControl> mDOMCameraControl;
-  CameraControlListener::RecorderState mState;
-};
-
-NS_IMETHODIMP
-RecorderPosterHelper::HandleEvent(nsIDOMEvent* aEvent)
-{
-  nsString eventType;
-  aEvent->GetType(eventType);
-  if (eventType.EqualsLiteral("success")) {
-    mState = CameraControlListener::kPosterCreated;
-  }
-  return NS_OK;
-}
-
-NS_IMPL_ISUPPORTS(mozilla::RecorderPosterHelper, nsIDOMEventListener)
-
 nsDOMCameraControl::DOMCameraConfiguration::DOMCameraConfiguration()
   : CameraConfiguration()
   , mMaxFocusAreas(0)
   , mMaxMeteringAreas(0)
 {
   MOZ_COUNT_CTOR(nsDOMCameraControl::DOMCameraConfiguration);
 }
 
@@ -792,28 +754,21 @@ nsDOMCameraControl::StartRecording(const
 {
   DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
 
   nsRefPtr<Promise> promise = CreatePromise(aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
-  // Must supply both the poster path and storage area or neither
-  if (aOptions.mPosterFilepath.IsEmpty() ==
-      static_cast<bool>(aOptions.mPosterStorageArea.get())) {
-    promise->MaybeReject(NS_ERROR_ILLEGAL_VALUE);
-    return promise.forget();
-  }
-
   // If we are trying to start recording, already recording or are still
   // waiting for a poster to be created/fail, we need to wait
   if (mStartRecordingPromise || mRecording ||
       mRecordingStoppedDeferred ||
-      !mOptions.mPosterFilepath.IsEmpty()) {
+      mOptions.mCreatePoster) {
     promise->MaybeReject(NS_ERROR_IN_PROGRESS);
     return promise.forget();
   }
 
   aRv = NotifyRecordingStatusChange(NS_LITERAL_STRING("starting"));
   if (aRv.Failed()) {
     return nullptr;
   }
@@ -846,26 +801,25 @@ nsDOMCameraControl::OnCreatedFileDescrip
   nsresult rv = NS_ERROR_FAILURE;
 
   if (!mCameraControl) {
     rv = NS_ERROR_NOT_AVAILABLE;
   } else if (!mRecording) {
     // Race condition where StopRecording comes in before we issue
     // the start recording request to Gonk
     rv = NS_ERROR_ABORT;
-    mOptions.mPosterFilepath.Truncate();
-    mOptions.mPosterStorageArea = nullptr;
+    mOptions.mCreatePoster = false;
   } else if (aSucceeded && mDSFileDescriptor->mFileDescriptor.IsValid()) {
     ICameraControl::StartRecordingOptions o;
 
     o.rotation = mOptions.mRotation;
     o.maxFileSizeBytes = mOptions.mMaxFileSizeBytes;
     o.maxVideoLengthMs = mOptions.mMaxVideoLengthMs;
     o.autoEnableLowLightTorch = mOptions.mAutoEnableLowLightTorch;
-    o.createPoster = !mOptions.mPosterFilepath.IsEmpty();
+    o.createPoster = mOptions.mCreatePoster;
     rv = mCameraControl->StartRecording(mDSFileDescriptor.get(), &o);
     if (NS_SUCCEEDED(rv)) {
       return;
     }
   }
 
   OnUserError(CameraControlListener::kInStartRecording, rv);
 
@@ -1341,41 +1295,33 @@ nsDOMCameraControl::OnPreviewStateChange
   DispatchPreviewStateEvent(aState);
 }
 
 void
 nsDOMCameraControl::OnPoster(BlobImpl* aPoster)
 {
   DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(!mOptions.mPosterFilepath.IsEmpty());
-
-  // Destructor will trigger an error notification if any step fails
-  nsRefPtr<RecorderPosterHelper> listener = new RecorderPosterHelper(this);
-  if (NS_WARN_IF(!aPoster)) {
-    return;
-  }
+  MOZ_ASSERT(mOptions.mCreatePoster);
 
   nsRefPtr<Blob> blob = Blob::Create(GetParentObject(), aPoster);
   if (NS_WARN_IF(!blob)) {
+    OnRecorderStateChange(CameraControlListener::kPosterFailed, 0, 0);
     return;
   }
 
-  if (NS_WARN_IF(!mOptions.mPosterStorageArea)) {
-    return;
-  }
+  BlobEventInit eventInit;
+  eventInit.mData = blob;
 
-  ErrorResult rv;
-  nsRefPtr<DOMRequest> request =
-    mOptions.mPosterStorageArea->AddNamed(blob, mOptions.mPosterFilepath, rv);
-  if (NS_WARN_IF(rv.Failed())) {
-    return;
-  }
+  nsRefPtr<BlobEvent> event = BlobEvent::Constructor(this,
+                                                     NS_LITERAL_STRING("poster"),
+                                                     eventInit);
 
-  RegisterStorageRequestEvents(request, listener);
+  DispatchTrustedEvent(event);
+  OnRecorderStateChange(CameraControlListener::kPosterCreated, 0, 0);
 }
 
 void
 nsDOMCameraControl::OnRecorderStateChange(CameraControlListener::RecorderState aState,
                                           int32_t aArg, int32_t aTrackNum)
 {
   // For now, we do nothing with 'aStatus' and 'aTrackNum'.
   DOM_CAMERA_LOGT("%s:%d : this=%p, state=%u\n", __func__, __LINE__, this, aState);
@@ -1392,35 +1338,33 @@ nsDOMCameraControl::OnRecorderStateChang
           promise->MaybeResolve(JS::UndefinedHandleValue);
         }
 
         state = NS_LITERAL_STRING("Started");
       }
       break;
 
     case CameraControlListener::kRecorderStopped:
-      if (!mOptions.mPosterFilepath.IsEmpty()) {
+      if (mOptions.mCreatePoster) {
         mRecordingStoppedDeferred = true;
         return;
       }
 
       NotifyRecordingStatusChange(NS_LITERAL_STRING("shutdown"));
       state = NS_LITERAL_STRING("Stopped");
       break;
 
     case CameraControlListener::kPosterCreated:
       state = NS_LITERAL_STRING("PosterCreated");
-      mOptions.mPosterFilepath.Truncate();
-      mOptions.mPosterStorageArea = nullptr;
+      mOptions.mCreatePoster = false;
       break;
 
     case CameraControlListener::kPosterFailed:
       state = NS_LITERAL_STRING("PosterFailed");
-      mOptions.mPosterFilepath.Truncate();
-      mOptions.mPosterStorageArea = nullptr;
+      mOptions.mCreatePoster = false;
       break;
 
     case CameraControlListener::kRecorderPaused:
       state = NS_LITERAL_STRING("Paused");
       break;
 
     case CameraControlListener::kRecorderResumed:
       state = NS_LITERAL_STRING("Resumed");
@@ -1454,17 +1398,17 @@ nsDOMCameraControl::OnRecorderStateChang
 
     default:
       MOZ_ASSERT_UNREACHABLE("Unanticipated video recorder error");
       return;
   }
 
   DispatchStateEvent(NS_LITERAL_STRING("recorderstatechange"), state);
 
-  if (mRecordingStoppedDeferred && mOptions.mPosterFilepath.IsEmpty()) {
+  if (mRecordingStoppedDeferred && !mOptions.mCreatePoster) {
     mRecordingStoppedDeferred = false;
     OnRecorderStateChange(CameraControlListener::kRecorderStopped, 0, 0);
   }
 }
 
 void
 nsDOMCameraControl::OnConfigurationChange(DOMCameraConfiguration* aConfiguration)
 {
--- a/dom/camera/DOMCameraControl.h
+++ b/dom/camera/DOMCameraControl.h
@@ -138,16 +138,17 @@ public:
   IMPL_EVENT_HANDLER(facesdetected)
   IMPL_EVENT_HANDLER(shutter)
   IMPL_EVENT_HANDLER(close)
   IMPL_EVENT_HANDLER(recorderstatechange)
   IMPL_EVENT_HANDLER(previewstatechange)
   IMPL_EVENT_HANDLER(focus)
   IMPL_EVENT_HANDLER(picture)
   IMPL_EVENT_HANDLER(configurationchange)
+  IMPL_EVENT_HANDLER(poster)
 
 protected:
   virtual ~nsDOMCameraControl();
 
   class DOMCameraConfiguration final : public dom::CameraConfiguration
   {
   public:
     NS_INLINE_DECL_REFCOUNTING(DOMCameraConfiguration)
--- a/dom/icc/tests/marionette/manifest.ini
+++ b/dom/icc/tests/marionette/manifest.ini
@@ -1,15 +1,16 @@
 [DEFAULT]
 b2g = true
 browser = false
 qemu = true
 
 [test_icc_contact_read.js]
 [test_icc_contact_add.js]
+[test_icc_contact_update.js]
 [test_icc_card_lock_get_retry_count.js]
 [test_icc_card_lock_change_pin.js]
 [test_icc_card_lock_enable_pin.js]
 [test_icc_card_lock_unlock_pin.js]
 [test_icc_card_lock_unlock_puk.js]
 [test_icc_card_state.js]
 [test_icc_info.js]
 [test_stk_refresh.js]
--- a/dom/icc/tests/marionette/test_icc_contact_add.js
+++ b/dom/icc/tests/marionette/test_icc_contact_add.js
@@ -1,60 +1,63 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
-MARIONETTE_TIMEOUT = 90000;
+MARIONETTE_TIMEOUT = 120000;
 MARIONETTE_HEAD_JS = "head.js";
 
 var TEST_ADD_DATA = [{
     // a contact without email and anr.
     name: ["add1"],
     tel: [{value: "0912345678"}],
   }, {
     // a contact over 20 digits.
     name: ["add2"],
     tel: [{value: "012345678901234567890123456789"}],
   }, {
+    // a contact over 40 digits.
+    name: ["add3"],
+    tel: [{value: "01234567890123456789012345678901234567890123456789"}],
+  }, {
     // a contact with email but without anr.
-    name: ["add3"],
+    name: ["add4"],
     tel: [{value: "01234567890123456789"}],
     email:[{value: "test@mozilla.com"}],
   }, {
     // a contact with anr but without email.
-    name: ["add4"],
+    name: ["add5"],
     tel: [{value: "01234567890123456789"}, {value: "123456"}, {value: "123"}],
   }, {
     // a contact with email and anr.
-    name: ["add5"],
+    name: ["add6"],
     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]);
-      // Maximum digits of the Dialling Number is 20.
-      is(aResult.tel[0].value, aMozContact.tel[0].value.substring(0, 20));
+      // Maximum digits of the Dialling Number is 20, and maximum digits of Extension is 20.
+      is(aResult.tel[0].value, aMozContact.tel[0].value.substring(0, 40));
       // 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]);
-          // 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);
+          // Maximum digits of the Dialling Number is 20, and maximum digits of Extension is 20.
+          is(contact.tel[0].value, aMozContact.tel[0].value.substring(0, 40));
+          is(contact.id.substring(0, aIcc.iccInfo.iccid.length), aIcc.iccInfo.iccid);
 
           return contact.id;
         })
         .then((aContactId) => {
           // Clean up contact
           return removeContact(aIcc, aContactId, aType, aPin2);
         });
     }, (aError) => {
@@ -75,19 +78,20 @@ function removeContact(aIcc, aContactId,
   contact.id = aContactId;
 
   return aIcc.updateContact(aType, contact, aPin2);
 }
 
 // Start tests
 startTestCommon(function() {
   let icc = getMozIcc();
-
+  let promise = Promise.resolve();
   for (let i = 0; i < TEST_ADD_DATA.length; i++) {
     let test_data = TEST_ADD_DATA[i];
     // Test add adn contacts
-    return testAddContact(icc, "adn", test_data)
+    promise = promise.then(() => testAddContact(icc, "adn", test_data))
       // Test add fdn contacts
       .then(() => testAddContact(icc, "fdn", test_data, "0000"))
       // Test add fdn contacts without passing pin2
       .then(() => testAddContact(icc, "fdn", test_data));
   }
+  return promise;
 });
--- a/dom/icc/tests/marionette/test_icc_contact_read.js
+++ b/dom/icc/tests/marionette/test_icc_contact_read.js
@@ -4,18 +4,19 @@
 MARIONETTE_TIMEOUT = 60000;
 MARIONETTE_HEAD_JS = "head.js";
 
 function testReadContacts(aIcc, aType) {
   log("testReadContacts: type=" + aType);
   let iccId = aIcc.iccInfo.iccid;
   return aIcc.readContacts(aType)
     .then((aResult) => {
+
       is(Array.isArray(aResult), true);
-      is(aResult.length, 4, "Check contact number.");
+      is(aResult.length, 6, "Check contact number.");
 
       // Alpha Id(Encoded with GSM 8 bit): "Mozilla", Dialling Number: 15555218201
       is(aResult[0].name[0], "Mozilla");
       is(aResult[0].tel[0].value, "15555218201");
       is(aResult[0].id, iccId + "1");
 
       // Alpha Id(Encoded with UCS2 0x80: "Saßê\u9ec3", Dialling Number: 15555218202
       is(aResult[1].name[0], "Saßê黃");
@@ -26,16 +27,28 @@ function testReadContacts(aIcc, aType) {
       is(aResult[2].name[0], "Fire 火");
       is(aResult[2].tel[0].value, "15555218203");
       is(aResult[2].id, iccId + "3");
 
       // Alpha Id(Encoded with UCS2 0x82): "Huang \u9ec3", Dialling Number: 15555218204
       is(aResult[3].name[0], "Huang 黃");
       is(aResult[3].tel[0].value, "15555218204");
       is(aResult[3].id, iccId + "4");
+
+      // Alpha Id(Encoded with GSM 8 bit): "Contact001",
+      // Dialling Number: 9988776655443322110001234567890123456789
+      is(aResult[4].name[0], "Contact001");
+      is(aResult[4].tel[0].value, "9988776655443322110001234567890123456789");
+      is(aResult[4].id, iccId + "5");
+
+      // Alpha Id(Encoded with GSM 8 bit): "Contact002",
+      // Dialling Number: 0123456789012345678999887766554433221100
+      is(aResult[5].name[0], "Contact002");
+      is(aResult[5].tel[0].value, "0123456789012345678999887766554433221100");
+      is(aResult[5].id, iccId + "6");
     }, (aError) => {
       ok(false, "Cannot get " + aType + " contacts");
     });
 }
 
 
 // Start tests
 startTestCommon(function() {
new file mode 100644
--- /dev/null
+++ b/dom/icc/tests/marionette/test_icc_contact_update.js
@@ -0,0 +1,122 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+MARIONETTE_TIMEOUT = 120000;
+MARIONETTE_HEAD_JS = "head.js";
+
+const TEST_UPDATE_DATA = [{
+    id: 1,
+    data: {
+      name: ["Mozilla"],
+      tel: [{value: "9876543210987654321001234"}]},
+    expect: {
+      number: "9876543210987654321001234"}
+  }, {
+    id:2,
+    data: {
+      name: ["Saßê黃"],
+      tel: [{value: "98765432109876543210998877665544332211001234"}]},
+    expect: {
+      // We don't support extension chain now.
+      number: "9876543210987654321099887766554433221100"}
+  }, {
+    id: 3,
+    data: {
+      name: ["Fire 火"],
+      tel: [{value: ""}]},
+    expect: {
+      number: null}
+  }, {
+    id: 5,
+    data: {
+      name: ["Contact001"],
+      tel: [{value: "9988776655443322110098765432109876543210"}]},
+    expect: {
+      number: "9988776655443322110098765432109876543210"}
+  }, {
+    id: 6,
+    data: {
+      name: ["Contact002"],
+      tel: [{value: "+99887766554433221100"}]},
+    expect: {
+      number: "+99887766554433221100"}
+  }];
+
+function testUpdateContact(aIcc, aType, aContactId, aMozContact, aExpect, aPin2) {
+  log("testUpdateContact: type=" + aType +
+      ", mozContact=" + JSON.stringify(aMozContact) +
+      ", expect=" + aExpect.number + ", pin2=" + aPin2);
+
+  let contact = new mozContact(aMozContact);
+  contact.id = aIcc.iccInfo.iccid + aContactId;
+
+  return aIcc.updateContact(aType, contact, aPin2)
+    .then((aResult) => {
+      // Get ICC contact for checking expect contact
+      return aIcc.readContacts(aType)
+        .then((aResult) => {
+          let contact = aResult[aContactId - 1];
+
+          is(contact.name[0], aMozContact.name[0]);
+
+          if (aExpect.number == null) {
+            is(contact.tel, null);
+          } else {
+            is(contact.tel[0].value, aExpect.number);
+          }
+
+          is(contact.id, aIcc.iccInfo.iccid + aContactId);
+        });
+      }, (aError) => {
+        if (aType === "fdn" && aPin2 === undefined) {
+          ok(aError.name === "SimPin2",
+             "expected error when pin2 is not provided");
+        } else {
+          ok(false, "Cannot update " + aType + " contact: " + aError.name);
+        }
+      });
+}
+
+function revertContact(aIcc, aContact, aType, aPin2) {
+  log("revertContact: contact:" + JSON.stringify(aContact) +
+      ", type=" + aType + ", pin2=" + aPin2);
+
+  return aIcc.updateContact(aType, aContact, aPin2);
+}
+
+// Start tests
+startTestCommon(function() {
+  let icc = getMozIcc();
+  let adnContacts;
+  let fdnContacts;
+
+  return icc.readContacts("adn")
+    .then((aResult) => {
+      adnContacts = aResult;
+    })
+    .then(() => icc.readContacts("fdn"))
+    .then((aResult) => {
+      fdnContacts = aResult;
+    })
+    .then(() => {
+      let promise = Promise.resolve();
+      for (let i = 0; i < TEST_UPDATE_DATA.length; i++) {
+        let test_data = TEST_UPDATE_DATA[i];
+        let adnContact = adnContacts[test_data.id - 1];
+        let fdnContact = fdnContacts[test_data.id - 1];
+
+        // Test update adn contacts
+        promise = promise.then(() => testUpdateContact(icc, "adn", test_data.id,
+                                                       test_data.data, test_data.expect))
+          // Test update fdn contacts
+          .then(() => testUpdateContact(icc, "fdn", test_data.id, test_data.data,
+                                        test_data.expect))
+          // Test update fdn contacts without passing pin2
+          .then(() => testUpdateContact(icc, "fdn", test_data.id, test_data.data,
+                                        test_data.expect, "0000"))
+          .then(() => revertContact(icc, adnContact, "adn"))
+          .then(() => revertContact(icc, fdnContact, "fdn", "0000"));
+      }
+      return promise;
+    });
+});
--- a/dom/system/gonk/ril_consts.js
+++ b/dom/system/gonk/ril_consts.js
@@ -569,16 +569,22 @@ this.EFSMS_STATUS_TO_BE_SENT = 0x07;
 // See TS 151.011 clause 10.5.1 EF_ADN.
 this.ADN_FOOTER_SIZE_BYTES = 14;
 // Maximum size of BCD numbers in ADN.
 // See TS 151.011 clause 10.5.1 EF_ADN, 'Length of BCD number/SSC contents'.
 this.ADN_MAX_BCD_NUMBER_BYTES = 11;
 // Maximum digits of the Dialling Number in ADN.
 // See TS 151.011 clause 10.5.1 EF_ADN, 'Dialling Number'.
 this.ADN_MAX_NUMBER_DIGITS = 20;
+// Maximum size of BCD numbers in EXT.
+// See TS 151.011 clause 10.5.10 EF_EXT1, 'Extension data'.
+this.EXT_MAX_BCD_NUMBER_BYTES = 10;
+// Maximum digits of the Dialling Number in EXT.
+// See TS 151.011 clause 10.5.10 EF_EXT1, 'Extension data'.
+this.EXT_MAX_NUMBER_DIGITS = 20;
 
 // READ_RECORD mode,  TS 102.221
 this.READ_RECORD_ABSOLUTE_MODE = 4;
 
 // TS 102.221 Table 11.2, return FCP template
 this.GET_RESPONSE_FCP_TEMPLATE = 4;
 
 // GET_RESPONSE mandatory response size for EF, see TS 51.011 clause 9,
@@ -1257,35 +1263,40 @@ this.STK_SUPPORTED_TERMINAL_PROFILE = [
  */
 this.GECKO_ICC_SERVICES = {
   // @see 3GPP TS 51.011 10.3.7 (SIM).
   sim: {
     ADN: 2,
     FDN: 3,
     PLMNSEL: 7,
     MSISDN: 9,
+    EXT1: 10,
+    EXT2: 11,
     CBMI: 14,
     GID1: 15,
     SPN: 17,
     SDN: 18,
+    EXT3: 19,
     DATA_DOWNLOAD_SMS_CB: 25,
     DATA_DOWNLOAD_SMS_PP: 26,
     CBMIR: 30,
     BDN: 31,
     IMG: 39,
     PNN: 51,
     OPL: 52,
     MDN: 53,
     MWIS: 54,
     SPDI: 56
   },
   // @see 3GPP TS 31.102 4.2.8 (USIM).
   usim: {
     FDN: 2,
+    EXT2: 3,
     SDN: 4,
+    EXT3: 5,
     BDN: 6,
     CBMI: 15,
     CBMIR: 16,
     GID1: 17,
     SPN: 19,
     MSISDN: 21,
     IMG: 22,
     DATA_DOWNLOAD_SMS_PP: 28,
@@ -1295,18 +1306,21 @@ this.GECKO_ICC_SERVICES = {
     MDN: 47,
     MWIS: 48,
     SPDI: 51
   },
   // @see 3GPP2 C.S0023-D 3.4.18 (RUIM).
   ruim: {
     FDN: 3,
     ENHANCED_PHONEBOOK: 6,
+    EXT1: 10,
+    EXT2: 11,
     SPN: 17,
-    SDN: 18
+    SDN: 18,
+    EXT3: 19,
   },
   // @see B.3.1.1 CPHS Information in CPHS Phase 2:
   // Indicates which of the CPHS 'optional' data-fields are present in the SIM card:
   //   EF_CPHS_CSP, EF_CPHS_SST, EF_CPHS_MBN, EF_CPHS_ONSF, EF_CPHS_INFO_NUM
   // Note: Mandatory EFs are: (B.3.1 Enhanced SIM Requirements)
   //   EF_CPHS_CFF, EF_CPHS_VMI, EF_CPHS_ONS, EF_CPHS_INFO
   cphs: {
     CSP: 1,
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -5560,16 +5560,26 @@ GsmPDUHelperObject.prototype = {
         throw new RangeError();
       }
     }
 
     return this.extendedBcdChars.charAt(semiOctet);
   },
 
   /**
+   * Convert string to a GSM extended BCD string
+   */
+  stringToExtendedBcd: function(string) {
+    return string.replace(/[^0-9*#,]/g, "")
+                 .replace(/\*/g, "a")
+                 .replace(/\#/g, "b")
+                 .replace(/\,/g, "c");
+  },
+
+  /**
    * Read a *swapped nibble* binary coded decimal (BCD)
    *
    * @param pairs
    *        Number of nibble *pairs* to read.
    *
    * @return the decimal as a number.
    */
   readSwappedNibbleBcdNum: function(pairs) {
@@ -8972,53 +8982,59 @@ ICCPDUHelperObject.prototype = {
     let Buf = this.context.Buf;
     let length = Buf.readInt32();
 
     let alphaLen = recordSize - ADN_FOOTER_SIZE_BYTES;
     let alphaId = this.readAlphaIdentifier(alphaLen);
 
     let number = this.readNumberWithLength();
 
-    // Skip 2 unused octets, CCP and EXT1.
-    Buf.seekIncoming(2 * Buf.PDU_HEX_OCTET_SIZE);
+    // Skip unused octet, CCP
+    Buf.seekIncoming(Buf.PDU_HEX_OCTET_SIZE);
+
+    let extRecordNumber = this.context.GsmPDUHelper.readHexOctet();
     Buf.readStringDelimiter(length);
 
     let contact = null;
     if (alphaId || number) {
       contact = {alphaId: alphaId,
-                 number: number};
-    }
+                 number: number,
+                 extRecordNumber: extRecordNumber};
+    }
+
     return contact;
   },
 
   /**
    * 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.
+   * @param recordSize       The size of linear fixed record.
+   * @param alphaId          Alpha Identifier to be written.
+   * @param number           Dialling Number to be written.
+   * @param extRecordNumber  The record identifier of the EXT.
    *
    * @return An object contains the alphaId and number
    *         that have been written into Buf.
    */
-  writeAlphaIdDiallingNumber: function(recordSize, alphaId, number) {
+  writeAlphaIdDiallingNumber: function(recordSize, alphaId, number, extRecordNumber) {
     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;
     let writtenAlphaId = this.writeAlphaIdentifier(alphaLen, alphaId);
     let writtenNumber = this.writeNumberWithLength(number);
 
-    // Write unused octets 0xff, CCP and EXT1.
+    // Write unused CCP octet 0xff.
     GsmPDUHelper.writeHexOctet(0xff);
-    GsmPDUHelper.writeHexOctet(0xff);
+    GsmPDUHelper.writeHexOctet((extRecordNumber != null) ? extRecordNumber : 0xff);
+
     Buf.writeStringDelimiter(strLen);
 
     return {alphaId: writtenAlphaId,
             number: writtenNumber};
   },
 
   /**
    * Read Alpha Identifier.
@@ -9172,18 +9188,18 @@ ICCPDUHelperObject.prototype = {
   writeNumberWithLength: function(number) {
     let GsmPDUHelper = this.context.GsmPDUHelper;
 
     if (number) {
       let numStart = number[0] == "+" ? 1 : 0;
       let writtenNumber = number.substring(0, numStart) +
                           number.substring(numStart)
                                 .replace(/[^0-9*#,]/g, "");
-
       let numDigits = writtenNumber.length - numStart;
+
       if (numDigits > ADN_MAX_NUMBER_DIGITS) {
         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);
@@ -11103,16 +11119,19 @@ ICCFileHelperObject.prototype = {
   /**
    * This function handles EFs for SIM.
    */
   getSimEFPath: function(fileId) {
     switch (fileId) {
       case ICC_EF_FDN:
       case ICC_EF_MSISDN:
       case ICC_EF_SMS:
+      case ICC_EF_EXT1:
+      case ICC_EF_EXT2:
+      case ICC_EF_EXT3:
         return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM;
       case ICC_EF_AD:
       case ICC_EF_MBDN:
       case ICC_EF_MWIS:
       case ICC_EF_PLMNsel:
       case ICC_EF_SPN:
       case ICC_EF_SPDI:
       case ICC_EF_SST:
@@ -11172,16 +11191,19 @@ ICCFileHelperObject.prototype = {
   getRuimEFPath: function(fileId) {
     switch(fileId) {
       case ICC_EF_CSIM_IMSI_M:
       case ICC_EF_CSIM_CDMAHOME:
       case ICC_EF_CSIM_CST:
       case ICC_EF_CSIM_SPN:
         return EF_PATH_MF_SIM + EF_PATH_DF_CDMA;
       case ICC_EF_FDN:
+      case ICC_EF_EXT1:
+      case ICC_EF_EXT2:
+      case ICC_EF_EXT3:
         return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM;
       default:
         return null;
     }
   },
 
   /**
    * Helper function for getting the pathId for the specific ICC record
@@ -11577,67 +11599,87 @@ ICCRecordHelperObject.prototype = {
       fileId: ICC_EF_ICCID,
       callback: callback.bind(this)
     });
   },
 
   /**
    * Read ICC ADN like EF, i.e. EF_ADN, EF_FDN.
    *
-   * @param fileId      EF id of the ADN or FDN.
+   * @param fileId      EF id of the ADN, FDN or SDN.
+   * @param extFileId   EF id of the EXT.
    * @param onsuccess   Callback to be called when success.
    * @param onerror     Callback to be called when error.
    */
-  readADNLike: function(fileId, onsuccess, onerror) {
+  readADNLike: function(fileId, extFileId, onsuccess, onerror) {
     let ICCIOHelper = this.context.ICCIOHelper;
 
     function callback(options) {
-      let contact =
-        this.context.ICCPDUHelper.readAlphaIdDiallingNumber(options.recordSize);
-      if (contact) {
-        contact.recordId = options.p1;
-        contacts.push(contact);
-      }
-
-      if (options.p1 < options.totalRecords) {
-        ICCIOHelper.loadNextRecord(options);
-      } else {
+      let loadNextContactRecord = () => {
+        if (options.p1 < options.totalRecords) {
+          ICCIOHelper.loadNextRecord(options);
+          return;
+        }
         if (DEBUG) {
           for (let i = 0; i < contacts.length; i++) {
             this.context.debug("contact [" + i + "] " +
                                JSON.stringify(contacts[i]));
           }
         }
         if (onsuccess) {
           onsuccess(contacts);
         }
-      }
+      };
+
+      let contact =
+        this.context.ICCPDUHelper.readAlphaIdDiallingNumber(options.recordSize);
+      if (contact) {
+        let record = {
+          recordId: options.p1,
+          alphaId: contact.alphaId,
+          number: contact.number
+        };
+        contacts.push(record);
+
+        if (extFileId && contact.extRecordNumber != 0xff) {
+          this.readExtension(extFileId, contact.extRecordNumber, (number) => {
+            if (number) {
+              record.number += number;
+            }
+            loadNextContactRecord();
+          }, () => loadNextContactRecord());
+          return;
+        }
+      }
+      loadNextContactRecord();
     }
 
     let contacts = [];
     ICCIOHelper.loadLinearFixedEF({fileId: fileId,
                                    callback: callback.bind(this),
                                    onerror: onerror});
   },
 
   /**
    * Update ICC ADN like EFs, like EF_ADN, EF_FDN.
    *
-   * @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) {
+   * @param fileId          EF id of the ADN or FDN.
+   * @param extRecordNumber The record identifier of the EXT.
+   * @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, extRecordNumber, contact, pin2, onsuccess, onerror) {
     let updatedContact;
     function dataWriter(recordSize) {
       updatedContact = this.context.ICCPDUHelper.writeAlphaIdDiallingNumber(recordSize,
                                                                             contact.alphaId,
-                                                                            contact.number);
+                                                                            contact.number,
+                                                                            extRecordNumber);
     }
 
     function callback(options) {
       if (onsuccess) {
         onsuccess(updatedContact);
       }
     }
 
@@ -12079,16 +12121,181 @@ ICCRecordHelperObject.prototype = {
 
     // Start searching free records from the possible one.
     let recordNumber = this._freeRecordIds[fileId] || 1;
     ICCIOHelper.loadLinearFixedEF({fileId: fileId,
                                    recordNumber: recordNumber,
                                    callback: callback.bind(this),
                                    onerror: onerror});
   },
+
+  /**
+   * Read Extension Number from TS 151.011 clause 10.5.10, TS 31.102, clause 4.4.2.4
+   *
+   * @param fileId        EF Extension id
+   * @param recordNumber  The number of the record shall be loaded.
+   * @param onsuccess     Callback to be called when success.
+   * @param onerror       Callback to be called when error.
+   */
+  readExtension: function(fileId, recordNumber, onsuccess, onerror) {
+    let callback = (options) => {
+      let Buf = this.context.Buf;
+      let length = Buf.readInt32();
+      let recordType = this.context.GsmPDUHelper.readHexOctet();
+      let number = "";
+
+      // TS 31.102, clause 4.4.2.4 EFEXT1
+      // Case 1, Extension1 record is additional data
+      if (recordType & 0x02) {
+        let numLen = this.context.GsmPDUHelper.readHexOctet();
+        if (numLen != 0xff) {
+          if (numLen > EXT_MAX_BCD_NUMBER_BYTES) {
+            if (DEBUG) {
+              this.context.debug(
+              "Error: invalid length of BCD number/SSC contents - " + numLen);
+            }
+            // +1 to skip Identifier
+            Buf.seekIncoming((EXT_MAX_BCD_NUMBER_BYTES + 1) * Buf.PDU_HEX_OCTET_SIZE);
+            Buf.readStringDelimiter(length);
+            onerror();
+            return;
+          }
+
+          number = this.context.GsmPDUHelper.readSwappedNibbleExtendedBcdString(numLen);
+          if (DEBUG) this.context.debug("Contact Extension Number: "+ number);
+          Buf.seekIncoming((EXT_MAX_BCD_NUMBER_BYTES - numLen) * Buf.PDU_HEX_OCTET_SIZE);
+        } else {
+          Buf.seekIncoming(EXT_MAX_BCD_NUMBER_BYTES * Buf.PDU_HEX_OCTET_SIZE);
+        }
+      } else {
+        // Don't support Case 2, Extension1 record is Called Party Subaddress.
+        // +1 skip numLen
+        Buf.seekIncoming((EXT_MAX_BCD_NUMBER_BYTES + 1) * Buf.PDU_HEX_OCTET_SIZE);
+      }
+
+      // Skip Identifier
+      Buf.seekIncoming(Buf.PDU_HEX_OCTET_SIZE);
+      Buf.readStringDelimiter(length);
+      onsuccess(number);
+    }
+
+    this.context.ICCIOHelper.loadLinearFixedEF({
+      fileId: fileId,
+      recordNumber: recordNumber,
+      callback: callback,
+      onerror: onerror
+    });
+  },
+
+  /**
+   * Update Extension.
+   *
+   * @param fileId       EF id of the EXT.
+   * @param recordNumber The number of the record shall be updated.
+   * @param number       Dialling Number to be written.
+   * @param onsuccess    Callback to be called when success.
+   * @param onerror      Callback to be called when error.
+   */
+  updateExtension: function(fileId, recordNumber, number, onsuccess, onerror) {
+    let dataWriter = (recordSize) => {
+      let GsmPDUHelper = this.context.GsmPDUHelper;
+      // Write String length
+      let strLen = recordSize * 2;
+      let Buf = this.context.Buf;
+      Buf.writeInt32(strLen);
+
+      // We don't support extension chain.
+      if (number.length > EXT_MAX_NUMBER_DIGITS) {
+        number = number.substring(0, EXT_MAX_NUMBER_DIGITS);
+      }
+
+      let numLen = Math.ceil(number.length / 2);
+      // Write Extension record
+      GsmPDUHelper.writeHexOctet(0x02);
+      GsmPDUHelper.writeHexOctet(numLen);
+      GsmPDUHelper.writeSwappedNibbleBCD(number);
+      // Write trailing 0xff of Extension data.
+      for (let i = 0; i < EXT_MAX_BCD_NUMBER_BYTES - numLen; i++) {
+        GsmPDUHelper.writeHexOctet(0xff);
+      }
+      // Write trailing 0xff for Identifier.
+      GsmPDUHelper.writeHexOctet(0xff);
+      Buf.writeStringDelimiter(strLen);
+    };
+
+    this.context.ICCIOHelper.updateLinearFixedEF({
+      fileId: fileId,
+      recordNumber: recordNumber,
+      dataWriter: dataWriter,
+      callback: onsuccess,
+      onerror: onerror
+    });
+  },
+
+  /**
+   * Clean an EF record.
+   *
+   * @param fileId       EF id.
+   * @param recordNumber The number of the record shall be updated.
+   * @param onsuccess    Callback to be called when success.
+   * @param onerror      Callback to be called when error.
+   */
+  cleanEFRecord: function(fileId, recordNumber, onsuccess, onerror) {
+    let dataWriter = (recordSize) => {
+      let GsmPDUHelper = this.context.GsmPDUHelper;
+      let Buf = this.context.Buf;
+      // Write String length
+      let strLen = recordSize * 2;
+
+      Buf.writeInt32(strLen);
+      // Write record to 0xff
+      for (let i = 0; i < recordSize; i++) {
+        GsmPDUHelper.writeHexOctet(0xff);
+      }
+      Buf.writeStringDelimiter(strLen);
+    }
+
+    this.context.ICCIOHelper.updateLinearFixedEF({
+     fileId: fileId,
+     recordNumber: recordNumber,
+     dataWriter: dataWriter,
+     callback: onsuccess,
+     onerror: onerror
+    });
+  },
+
+  /**
+   * Get ADNLike extension record number.
+   *
+   * @param  fileId       EF id of the ADN or FDN.
+   * @param  recordNumber EF record id of the ADN or FDN.
+   * @param  onsuccess    Callback to be called when success.
+   * @param  onerror      Callback to be called when error.
+   */
+  getADNLikeExtensionRecordNumber: function(fileId, recordNumber, onsuccess, onerror) {
+    let callback = (options) => {
+      let Buf = this.context.Buf;
+      let length = Buf.readInt32();
+
+      // Skip alphaLen, numLen, BCD Number, CCP octets.
+      Buf.seekIncoming((options.recordSize -1) * Buf.PDU_HEX_OCTET_SIZE);
+
+      let extRecordNumber = this.context.GsmPDUHelper.readHexOctet();
+      Buf.readStringDelimiter(length);
+
+      onsuccess(extRecordNumber);
+    }
+
+    this.context.ICCIOHelper.loadLinearFixedEF({
+      fileId: fileId,
+      recordNumber: recordNumber,
+      callback: callback,
+      onerror: onerror
+    });
+  },
 };
 
 /**
  * Helper for (U)SIM Records.
  */
 function SimRecordHelperObject(aContext) {
   this.context = aContext;
 }
@@ -13989,35 +14196,41 @@ ICCContactHelperObject.prototype = {
    */
   readICCContacts: function(appType, contactType, onsuccess, onerror) {
     let ICCRecordHelper = this.context.ICCRecordHelper;
     let ICCUtilsHelper = this.context.ICCUtilsHelper;
 
     switch (contactType) {
       case GECKO_CARDCONTACT_TYPE_ADN:
         if (!this.hasDfPhoneBook(appType)) {
-          ICCRecordHelper.readADNLike(ICC_EF_ADN, onsuccess, onerror);
+          ICCRecordHelper.readADNLike(ICC_EF_ADN,
+            (ICCUtilsHelper.isICCServiceAvailable("EXT1")) ? ICC_EF_EXT1 : null,
+            onsuccess, onerror);
         } else {
           this.readUSimContacts(onsuccess, onerror);
         }
         break;
       case GECKO_CARDCONTACT_TYPE_FDN:
         if (!ICCUtilsHelper.isICCServiceAvailable("FDN")) {
           onerror(CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED);
           break;
         }
-        ICCRecordHelper.readADNLike(ICC_EF_FDN, onsuccess, onerror);
+        ICCRecordHelper.readADNLike(ICC_EF_FDN,
+          (ICCUtilsHelper.isICCServiceAvailable("EXT2")) ? ICC_EF_EXT2 : null,
+          onsuccess, onerror);
         break;
       case GECKO_CARDCONTACT_TYPE_SDN:
         if (!ICCUtilsHelper.isICCServiceAvailable("SDN")) {
           onerror(CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED);
           break;
         }
 
-        ICCRecordHelper.readADNLike(ICC_EF_SDN, onsuccess, onerror);
+        ICCRecordHelper.readADNLike(ICC_EF_SDN,
+          (ICCUtilsHelper.isICCServiceAvailable("EXT3")) ? ICC_EF_EXT3 : null,
+          onsuccess, onerror);
         break;
       default:
         if (DEBUG) {
           this.context.debug("Unsupported contactType :" + contactType);
         }
         onerror(CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED);
         break;
     }
@@ -14139,31 +14352,48 @@ ICCContactHelperObject.prototype = {
       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, updateContactCb, onerror);
+          if (ICCUtilsHelper.isICCServiceAvailable("EXT1")) {
+            this.updateADNLikeWithExtension(ICC_EF_ADN, ICC_EF_EXT1,
+                                            contact, null,
+                                            updateContactCb, onerror);
+          } else {
+            ICCRecordHelper.updateADNLike(ICC_EF_ADN, 0xff,
+                                          contact, null,
+                                          updateContactCb, onerror);
+          }
         } else {
           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, updateContactCb, onerror);
+        if (ICCUtilsHelper.isICCServiceAvailable("EXT2")) {
+          this.updateADNLikeWithExtension(ICC_EF_FDN, ICC_EF_EXT2,
+                                          contact, pin2,
+                                          updateContactCb, onerror);
+        } else {
+          ICCRecordHelper.updateADNLike(ICC_EF_FDN,
+                                        0xff,
+                                        contact, pin2,
+                                        updateContactCb, onerror);
+        }
         break;
       default:
         if (DEBUG) {
           this.context.debug("Unsupported contactType :" + contactType);
         }
         onerror(CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED);
         break;
     }
@@ -14219,21 +14449,23 @@ ICCContactHelperObject.prototype = {
   /**
    * Read from 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.
    */
   readPhonebookSet: function(pbr, onsuccess, onerror) {
+    let ICCRecordHelper = this.context.ICCRecordHelper;
     let gotAdnCb = function gotAdnCb(contacts) {
       this.readSupportedPBRFields(pbr, contacts, onsuccess, onerror);
     }.bind(this);
 
-    this.context.ICCRecordHelper.readADNLike(pbr.adn.fileId, gotAdnCb, onerror);
+    ICCRecordHelper.readADNLike(pbr.adn.fileId,
+      (pbr.ext1) ? pbr.ext1.fileId : null, gotAdnCb, onerror);
   },
 
   /**
    * Read supported Phonebook fields.
    *
    * @param pbr         Phone Book Reference file.
    * @param contacts    Contacts stored on ICC.
    * @param onsuccess   Callback to be called when success.
@@ -14419,18 +14651,23 @@ ICCContactHelperObject.prototype = {
    */
   updatePhonebookSet: function(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);
+    if (pbr.ext1) {
+      this.updateADNLikeWithExtension(pbr.adn.fileId, pbr.ext1.fileId,
+                                      contact, null, updateAdnCb, onerror);
+    } else {
+      this.context.ICCRecordHelper.updateADNLike(pbr.adn.fileId, 0xff, 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.
@@ -14653,16 +14890,84 @@ ICCContactHelperObject.prototype = {
     let ICCRecordHelper = this.context.ICCRecordHelper;
 
     let gotIAPCb = function gotIAPCb(iap) {
       iap[pbr[field].indexInIAP] = value;
       ICCRecordHelper.updateIAP(pbr.iap.fileId, recordNumber, iap, onsuccess, onerror);
     }.bind(this);
     ICCRecordHelper.readIAP(pbr.iap.fileId, recordNumber, gotIAPCb, onerror);
   },
+
+  /**
+   * Update ICC ADN like EFs with Extension, like EF_ADN, EF_FDN.
+   *
+   * @param  fileId    EF id of the ADN or FDN.
+   * @param  extFileId EF id of the EXT.
+   * @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.
+   */
+  updateADNLikeWithExtension: function(fileId, extFileId, contact, pin2, onsuccess, onerror) {
+    let ICCRecordHelper = this.context.ICCRecordHelper;
+    let extNumber;
+
+    if (contact.number) {
+      let numStart = contact.number[0] == "+" ? 1 : 0;
+      let number = contact.number.substring(0, numStart) +
+                   this.context.GsmPDUHelper.stringToExtendedBcd(
+                    contact.number.substring(numStart));
+      extNumber = number.substr(numStart + ADN_MAX_NUMBER_DIGITS,
+                                EXT_MAX_NUMBER_DIGITS);
+    }
+
+    ICCRecordHelper.getADNLikeExtensionRecordNumber(fileId, contact.recordId,
+                                                    (extRecordNumber) => {
+        let updateADNLike = (extRecordNumber) => {
+          ICCRecordHelper.updateADNLike(fileId, extRecordNumber, contact,
+                                        pin2, (updatedContact) => {
+            if (extNumber && extRecordNumber != 0xff) {
+              updatedContact.number = updatedContact.number.concat(extNumber);
+            }
+            onsuccess(updatedContact);
+          }, onerror);
+        };
+
+        let updateExtension = (extRecordNumber) => {
+          ICCRecordHelper.updateExtension(extFileId, extRecordNumber,  extNumber,
+                                          () => updateADNLike(extRecordNumber),
+                                          () => updateADNLike(0xff));
+        };
+
+        if (extNumber) {
+          if (extRecordNumber != 0xff) {
+            updateExtension(extRecordNumber);
+            return;
+          }
+
+          ICCRecordHelper.findFreeRecordId(extFileId,
+            (extRecordNumber) => updateExtension(extRecordNumber),
+            (errorMsg) => {
+              if (DEBUG) {
+                this.context.debug("Couldn't find free extension record Id for " + extFileId + ": " + errorMsg);
+              }
+              updateADNLike(0xff);
+            });
+          return;
+        }
+
+        if (extRecordNumber != 0xff) {
+          ICCRecordHelper.cleanEFRecord(extFileId, extRecordNumber,
+            () => updateADNLike(0xff), onerror);
+          return;
+        }
+
+        updateADNLike(0xff);
+      }, onerror);
+  },
 };
 
 function IconLoaderObject(aContext) {
   this.context = aContext;
 }
 IconLoaderObject.prototype = {
   context: null,
 
--- a/dom/system/gonk/tests/test_ril_worker_icc_ICCContactHelper.js
+++ b/dom/system/gonk/tests/test_ril_worker_icc_ICCContactHelper.js
@@ -347,17 +347,17 @@ add_test(function test_read_icc_contacts
     contactHelper.getContactFieldRecordId = function(pbr, contact, field, onsuccess, onerror) {
       onsuccess(1);
     };
 
     record.readPBR = function readPBR(onsuccess, onerror) {
       onsuccess(JSON.parse(JSON.stringify(aTestData.pbrs)));
     };
 
-    record.readADNLike = function readADNLike(fileId, onsuccess, onerror) {
+    record.readADNLike = function readADNLike(fileId, extFileId, onsuccess, onerror) {
       onsuccess(JSON.parse(JSON.stringify(aTestData.adnLike)));
     };
 
     record.readEmail = function readEmail(fileId, fileType, recordNumber, onsuccess, onerror) {
       onsuccess(aTestData.email);
     };
 
     record.readANR = function readANR(fileId, fileType, recordNumber, onsuccess, onerror) {
@@ -393,69 +393,96 @@ add_test(function test_read_icc_contacts
 add_test(function test_update_icc_contact() {
   const ADN_RECORD_ID   = 100;
   const ADN_SFI         = 1;
   const IAP_FILE_ID     = 0x4f17;
   const EMAIL_FILE_ID   = 0x4f50;
   const EMAIL_RECORD_ID = 20;
   const ANR0_FILE_ID    = 0x4f11;
   const ANR0_RECORD_ID  = 30;
+  const EXT_RECORD_ID  = 0x01;
 
   let worker = newUint8Worker();
   let context = worker.ContextPool._contexts[0];
   let recordHelper = context.ICCRecordHelper;
   let contactHelper = context.ICCContactHelper;
   let ril = context.RIL;
 
   function do_test(aSimType, aContactType, aContact, aPin2, aFileType, aHaveIapIndex, aEnhancedPhoneBook) {
     ril.appType = aSimType;
     ril._isCdma = (aSimType === CARD_APPTYPE_RUIM);
-    ril.iccInfoPrivate.cst = (aEnhancedPhoneBook) ? [0x20, 0x0C, 0x0, 0x0, 0x0]
-                                                  : [0x20, 0x00, 0x0, 0x0, 0x0];
+    ril.iccInfoPrivate.cst = (aEnhancedPhoneBook) ? [0x20, 0x0C, 0x28, 0x0, 0x20]
+                                                  : [0x20, 0x0, 0x28, 0x0, 0x20];
     ril.iccInfoPrivate.sst = (aSimType === CARD_APPTYPE_SIM)?
-                                    [0x20, 0x0, 0x0, 0x0, 0x0]:
-                                    [0x2, 0x0, 0x0, 0x0, 0x0];
+                                    [0x20, 0x0, 0x28, 0x0, 0x20]:
+                                    [0x16, 0x0, 0x0, 0x0, 0x0];
 
     recordHelper.readPBR = function(onsuccess, onerror) {
       if (aFileType === ICC_USIM_TYPE1_TAG) {
         onsuccess([{
           adn:   {fileId: ICC_EF_ADN},
           email: {fileId: EMAIL_FILE_ID,
                   fileType: ICC_USIM_TYPE1_TAG},
           anr0:  {fileId: ANR0_FILE_ID,
-                  fileType: ICC_USIM_TYPE1_TAG}
+                  fileType: ICC_USIM_TYPE1_TAG},
+          ext1:  {fileId: ICC_EF_EXT1}
+
         }]);
       } else if (aFileType === ICC_USIM_TYPE2_TAG) {
         onsuccess([{
           adn:   {fileId: ICC_EF_ADN,
                   sfi: ADN_SFI},
           iap:   {fileId: IAP_FILE_ID},
           email: {fileId: EMAIL_FILE_ID,
                   fileType: ICC_USIM_TYPE2_TAG,
                   indexInIAP: 0},
           anr0:  {fileId: ANR0_FILE_ID,
                   fileType: ICC_USIM_TYPE2_TAG,
-                  indexInIAP: 1}
+                  indexInIAP: 1},
+          ext1:  {fileId: ICC_EF_EXT1}
         }]);
       }
     };
 
-    recordHelper.updateADNLike = function(fileId, contact, pin2, onsuccess, onerror) {
+    recordHelper.updateADNLike = function(fileId, extRecordNumber, contact, pin2, onsuccess, onerror) {
       if (aContactType === GECKO_CARDCONTACT_TYPE_FDN) {
         equal(fileId, ICC_EF_FDN);
       } else if (aContactType === GECKO_CARDCONTACT_TYPE_ADN) {
         equal(fileId, ICC_EF_ADN);
       }
+
+      if (aContact.number.length > ADN_MAX_NUMBER_DIGITS) {
+        equal(extRecordNumber, EXT_RECORD_ID);
+      } else {
+        equal(extRecordNumber, 0xff);
+      }
+
       equal(pin2, aPin2);
       equal(contact.alphaId, aContact.alphaId);
       equal(contact.number, aContact.number);
       onsuccess({alphaId: contact.alphaId,
-                  number: contact.number});
+                  number: contact.number.substring(0, ADN_MAX_NUMBER_DIGITS)});
+    };
+
+    recordHelper.getADNLikeExtensionRecordNumber = function(fileId, recordNumber, onsuccess, onerror) {
+      onsuccess(EXT_RECORD_ID);
     };
 
+    recordHelper.updateExtension = function(fileId, recordNumber, number, onsuccess, onerror) {
+      onsuccess();
+    };
+
+    recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) {
+      onsuccess(EXT_RECORD_ID);
+    };
+
+    recordHelper.cleanEFRecord = function(fileId, recordNumber, onsuccess, onerror) {
+      onsuccess();
+    }
+
     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]);
     };
 
     recordHelper.updateIAP = function(fileId, recordNumber, iap, onsuccess, onerror) {
@@ -497,16 +524,18 @@ add_test(function test_update_icc_contac
       }
       onsuccess(recordId);
     };
 
     let isSuccess = false;
     let onsuccess = function onsuccess(updatedContact) {
       equal(ADN_RECORD_ID, updatedContact.recordId);
       equal(aContact.alphaId, updatedContact.alphaId);
+      equal(aContact.number.substring(0, ADN_MAX_NUMBER_DIGITS + EXT_MAX_NUMBER_DIGITS),
+            updatedContact.number);
       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]);
@@ -554,16 +583,32 @@ add_test(function test_update_icc_contac
     },
     // a contact with anr but no email.
     {
       pbrIndex: 0,
       recordId: ADN_RECORD_ID,
       alphaId:  "test4",
       number:   "123456",
       anr:      ["+654321"]
+    },
+    // a contact number over 20 digits.
+    {
+      pbrIndex: 0,
+      recordId: ADN_RECORD_ID,
+      alphaId:  "test4",
+      number:   "0123456789012345678901234567890123456789",
+      anr:      ["+654321"]
+    },
+    // a contact number over 40 digits.
+    {
+      pbrIndex: 0,
+      recordId: ADN_RECORD_ID,
+      alphaId:  "test5",
+      number:   "01234567890123456789012345678901234567890123456789",
+      anr:      ["+654321"]
     }];
 
   for (let i = 0; i < contacts.length; i++) {
     let contact = contacts[i];
     // SIM
     do_print("Test update SIM adn contacts");
     do_test(CARD_APPTYPE_SIM, GECKO_CARDCONTACT_TYPE_ADN, contact);
 
@@ -638,17 +683,17 @@ 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}
       }]);
     };
 
-    recordHelper.updateADNLike = function(fileId, contact, pin2, onsuccess, onerror) {
+    recordHelper.updateADNLike = function(fileId, extRecordNumber, contact, pin2, onsuccess, onerror) {
       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({alphaId: contact.alphaId,
                   number: contact.number});
@@ -722,17 +767,17 @@ add_test(function test_update_icc_contac
   const ANR0_FILE_ID    = 0x4f11;
   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) {
+  recordHelper.updateADNLike = function(fileId, extRecordNumber, contact, pin2, onsuccess, onerror) {
     onsuccess({alphaId: contact.alphaId,
                number: contact.number});
   };
 
   let contact = {
     pbrIndex: 0,
     recordId: ADN_RECORD_ID,
     alphaId:  "test2",
@@ -902,8 +947,96 @@ add_test(function test_find_free_icc_con
     equal(recordId, 1);
   }
   contactHelper.findFreeICCContact(CARD_APPTYPE_USIM,
                                    GECKO_CARDCONTACT_TYPE_ADN,
                                    successCb, errorCb);
 
   run_next_test();
 });
+
+/**
+ *  Verify ICCContactHelper.updateADNLikeWithExtension
+ */
+add_test(function test_update_adn_like_with_extension() {
+  let worker = newUint8Worker();
+  let context = worker.ContextPool._contexts[0];
+  let ril = context.RIL;
+  let record = context.ICCRecordHelper;
+  let contactHelper = context.ICCContactHelper;
+  ril.appType = CARD_APPTYPE_SIM;
+  // Correct record Id starts from 1, so put a null element at index 0.
+  // ext_records contains data at index 1, and it only has 1 free record at index 2.
+  let notFree = 0x01;
+  let ext_records = [null, notFree, null];
+
+  function do_test(contact, extRecordNumber, expectedExtRecordNumber, expectedNumber, expectedCleanEFRecord) {
+    // Override some functions to test.
+    record.getADNLikeExtensionRecordNumber = function(fileId, recordNumber, onsuccess, onerror) {
+      onsuccess(extRecordNumber);
+    }
+
+    record.updateADNLike = function(fileId, extRecordNumber, contact, pin2, onsuccess, onerror) {
+      equal(extRecordNumber, expectedExtRecordNumber);
+      onsuccess({alphaId: contact.alphaId,
+                 number: contact.number.substring(0, ADN_MAX_NUMBER_DIGITS)});
+    }
+
+    record.updateExtension = function(fileId, recordNumber, number, onsuccess, onerror) {
+      if (recordNumber > ext_records.length) {
+        onerror("updateExtension failed.");
+        return;
+      }
+      ext_records[recordNumber] = number;
+      onsuccess();
+    }
+
+    record.findFreeRecordId = function(fileId, onsuccess, onerror) {
+      for (let i = 1; i < ext_records.length; i++) {
+        if (!ext_records[i]) {
+          onsuccess(i);
+          return;
+        }
+      }
+
+      onerror("No free record found.");
+    }
+
+    let isCleanEFRecord = false;
+    record.cleanEFRecord = function(fileId, recordNumber, onsuccess, onerror) {
+      if (recordNumber > ext_records.length) {
+        onerror("cleanEFRecord failed.");
+        return;
+      }
+      ext_records[recordNumber] = null;
+      isCleanEFRecord = true;
+      onsuccess();
+    }
+
+    let successCb = function successCb(updatedContact) {
+      equal(updatedContact.number, expectedNumber);
+    };
+
+    let errorCb = function errorCb(errorMsg) {
+      do_print("updateADNLikeWithExtension failed, msg = " + errorMsg);
+      ok(false);
+    };
+
+    contactHelper.updateADNLikeWithExtension(ICC_EF_ADN, ICC_EF_EXT1, contact, null, successCb, errorCb);
+
+    if (expectedCleanEFRecord) {
+      ok(isCleanEFRecord);
+    }
+  }
+
+  // Update extension record with previous extension record number.
+  do_test({recordId: 1, alphaId: "test", number: "001122334455667788991234"}, 0x01, 0x01, "001122334455667788991234");
+  // Update extension record and find a free record.
+  do_test({recordId: 1, alphaId: "test", number: "001122334455667788995678"}, 0xff, 0x02, "001122334455667788995678");
+  // Update extension record with no free extension record.
+  do_test({recordId: 1, alphaId: "test", number: "001122334455667788994321"}, 0xff, 0xff, "00112233445566778899");
+  // Update extension record with clean previous extension record.
+  do_test({recordId: 1, alphaId: "test", number: "00112233445566778899"}, 0x01, 0xff, "00112233445566778899", true);
+  // Update extension record with no extension record and previous extension record.
+  do_test({recordId: 1, alphaId: "test", number: "00112233445566778899"}, 0xff, 0xff, "00112233445566778899");
+
+  run_next_test();
+});
\ No newline at end of file
--- a/dom/system/gonk/tests/test_ril_worker_icc_ICCPDUHelper.js
+++ b/dom/system/gonk/tests/test_ril_worker_icc_ICCPDUHelper.js
@@ -457,35 +457,39 @@ 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"
   };
+
   let writtenContact = helper.writeAlphaIdDiallingNumber(recordSize,
                                                          contactW.alphaId,
-                                                         contactW.number);
+                                                         contactW.number, 0xff);
 
   let contactR = helper.readAlphaIdDiallingNumber(recordSize);
   equal(writtenContact.alphaId, contactR.alphaId);
   equal(writtenContact.number, contactR.number);
+  equal(0xff, contactR.extRecordNumber);
 
   // Write a contact with alphaId encoded in UCS2 and number has '+'.
   let contactUCS2 = {
     alphaId: "火狐",
     number: "+1234567890"
   };
+
   writtenContact = helper.writeAlphaIdDiallingNumber(recordSize,
                                                      contactUCS2.alphaId,
-                                                     contactUCS2.number);
+                                                     contactUCS2.number, 0xff);
   contactR = helper.readAlphaIdDiallingNumber(recordSize);
   equal(writtenContact.alphaId, contactR.alphaId);
   equal(writtenContact.number, contactR.number);
+  equal(0xff, contactR.extRecordNumber);
 
   // Write a null contact (Removal).
   writtenContact = helper.writeAlphaIdDiallingNumber(recordSize);
   contactR = helper.readAlphaIdDiallingNumber(recordSize);
   equal(contactR, null);
   equal(writtenContact.alphaId, null);
   equal(writtenContact.number, null);
 
@@ -493,31 +497,34 @@ add_test(function test_write_alpha_id_di
   // 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",
   };
+
   writtenContact = helper.writeAlphaIdDiallingNumber(recordSize,
                                                      longContact.alphaId,
-                                                     longContact.number);
+                                                     longContact.number, 0xff);
   contactR = helper.readAlphaIdDiallingNumber(recordSize);
   equal(writtenContact.alphaId, contactR.alphaId);
   equal(writtenContact.number, contactR.number);
+  equal(0xff, contactR.extRecordNumber);
 
   // Add '+' to number and test again.
   longContact.number = "+123456789012345678901234567890";
   writtenContact = helper.writeAlphaIdDiallingNumber(recordSize,
                                                      longContact.alphaId,
-                                                     longContact.number);
+                                                     longContact.number, 0xff);
   contactR = helper.readAlphaIdDiallingNumber(recordSize);
   equal(writtenContact.alphaId, contactR.alphaId);
   equal(writtenContact.number, contactR.number);
+  equal(0xff, contactR.extRecordNumber);
 
   run_next_test();
 });
 
 /**
  * Verify ICCPDUHelper.writeDiallingNumber
  */
 add_test(function test_write_dialling_number() {
--- a/dom/system/gonk/tests/test_ril_worker_icc_ICCRecordHelper.js
+++ b/dom/system/gonk/tests/test_ril_worker_icc_ICCRecordHelper.js
@@ -490,16 +490,84 @@ add_test(function test_update_iap() {
     };
     recordHelper.updateIAP(fileId, recordNumber, expectedIAP);
   }
 
   do_test([1, 2]);
 });
 
 /**
+ * Verify ICCRecordHelper.readADNLike.
+ */
+add_test(function test_read_adn_like() {
+  const RECORD_SIZE = 0x20;
+
+  let worker = newUint8Worker();
+  let context = worker.ContextPool._contexts[0];
+  let helper = context.GsmPDUHelper;
+  let record = context.ICCRecordHelper;
+  let buf = context.Buf;
+  let io = context.ICCIOHelper;
+  let ril = context.RIL;
+
+  function do_test(extFileId, rawEF, expectedExtRecordNumber, expectedNumber) {
+    io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
+      // Write data size
+      buf.writeInt32(rawEF.length * 2);
+
+      // Write adn
+      for (let i = 0; i < rawEF.length; i += 2) {
+        helper.writeHexOctet(parseInt(rawEF.substr(i, 2), 16));
+      }
+
+      // Write string delimiter
+      buf.writeStringDelimiter(rawEF.length * 2);
+
+      options.p1 = 1;
+      options.recordSize = RECORD_SIZE;
+      options.totalRecords = 1;
+      if (options.callback) {
+        options.callback(options);
+      }
+    };
+
+    record.readExtension = function(fileId, recordNumber, onsuccess, onerror) {
+      onsuccess("1234");
+    }
+
+    let successCb = function successCb(contacts) {
+      ok(contacts[0].number == expectedNumber);
+    };
+
+    let errorCb = function errorCb(errorMsg) {
+      do_print("Reading ADNLike failed, msg = " + errorMsg);
+      ok(false);
+    };
+
+    record.readADNLike(ICC_EF_ADN, extFileId, successCb, errorCb);
+  }
+
+  ril.appType = CARD_APPTYPE_SIM;
+  // Valid extension
+  do_test(ICC_EF_EXT1,"436f6e74616374303031ffffffffffffffff0b8199887766554433221100ff01",
+          0x01,"998877665544332211001234");
+  // Empty extension
+  do_test(ICC_EF_EXT1,"436f6e74616374303031ffffffffffffffff0b8199887766554433221100ffff",
+          0xff, "99887766554433221100");
+  // Unsupport extension
+  do_test(null,"436f6e74616374303031ffffffffffffffff0b8199887766554433221100ffff",
+          0xff, "99887766554433221100");
+  // Empty dialling number contact
+  do_test(null,"436f6e74616374303031ffffffffffffffffffffffffffffffffffffffffffff",
+          0xff, "");
+
+  run_next_test();
+});
+
+/**
  * Verify ICCRecordHelper.updateADNLike.
  */
 add_test(function test_update_adn_like() {
   let worker = newUint8Worker();
   let context = worker.ContextPool._contexts[0];
   let ril = context.RIL;
   let record = context.ICCRecordHelper;
   let io = context.ICCIOHelper;
@@ -544,16 +612,17 @@ add_test(function test_update_adn_like()
 
     // p3.
     equal(this.readInt32(), 0x20);
 
     // data.
     let contact = pdu.readAlphaIdDiallingNumber(0x20);
     equal(contact.alphaId, "test");
     equal(contact.number, "123456");
+    equal(contact.extRecordNumber, "0xff");
 
     // pin2.
     if (fileId == ICC_EF_ADN) {
       equal(this.readString(), null);
     } else {
       equal(this.readString(), "1111");
     }
 
@@ -561,21 +630,21 @@ add_test(function test_update_adn_like()
     this.readInt32();
 
     if (fileId == ICC_EF_FDN) {
       run_next_test();
     }
   };
 
   fileId = ICC_EF_ADN;
-  record.updateADNLike(fileId,
+  record.updateADNLike(fileId, 0xff,
                        {recordId: 1, alphaId: "test", number: "123456"});
 
   fileId = ICC_EF_FDN;
-  record.updateADNLike(fileId,
+  record.updateADNLike(fileId, 0xff,
                        {recordId: 1, alphaId: "test", number: "123456"},
                        "1111");
 });
 
 /**
  * Verify ICCRecordHelper.findFreeRecordId.
  */
 add_test(function test_find_free_record_id() {
@@ -716,8 +785,296 @@ add_test(function test_handling_iccid() 
   do_test("986800B2909090001519", "8986002090909005191");
   // Invalid value 0xA at low nibbile.
   do_test("986800A2909090001519", "8986002090909005191");
   // Valid ICCID.
   do_test("98101430121181157002", "89014103211118510720");
 
   run_next_test();
 });
+
+/**
+ *  Verify ICCRecordHelper.readExtension
+ */
+add_test(function test_read_extension() {
+  let worker = newUint8Worker();
+  let context = worker.ContextPool._contexts[0];
+  let helper = context.GsmPDUHelper;
+  let record = context.ICCRecordHelper;
+  let buf = context.Buf;
+  let io = context.ICCIOHelper;
+
+  function do_test(rawExtension, expectedExtensionNumber) {
+    io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
+      // Write data size
+      buf.writeInt32(rawExtension.length * 2);
+
+      // Write ext
+      for (let i = 0; i < rawExtension.length; i += 2) {
+        helper.writeHexOctet(parseInt(rawExtension.substr(i, 2), 16));
+      }
+
+      // Write string delimiter
+      buf.writeStringDelimiter(rawExtension.length);
+
+      if (options.callback) {
+        options.callback(options);
+      }
+    };
+
+    let successCb = function successCb(number) {
+      do_print("extension number:" + number);
+      equal(number, expectedExtensionNumber);
+    };
+
+    let errorCb = function errorCb() {
+      ok(expectedExtensionNumber == null);
+    };
+
+    record.readExtension(0x6f4a, 1, successCb, errorCb);
+  }
+
+  // Test unsupported record type 0x01
+  do_test("010a10325476981032547698ff", "");
+  // Test invalid length 0xc1
+  do_test("020c10325476981032547698ff", null);
+  // Test extension chain which we don't support
+  do_test("020a1032547698103254769802", "01234567890123456789");
+  // Test valid Extension
+  do_test("020a10325476981032547698ff", "01234567890123456789");
+  // Test valid Extension
+  do_test("0209103254769810325476ffff", "012345678901234567");
+  // Test empty Extension
+  do_test("02ffffffffffffffffffffffff", "");
+
+  run_next_test();
+});
+
+/**
+ *  Verify ICCRecordHelper.updateExtension
+ */
+add_test(function test_update_extension() {
+  const RECORD_SIZE = 13;
+  const RECORD_NUMBER = 1;
+
+  let worker = newUint8Worker();
+  let context = worker.ContextPool._contexts[0];
+  let pduHelper = context.GsmPDUHelper;
+  let ril = context.RIL;
+  let recordHelper = context.ICCRecordHelper;
+  let buf = context.Buf;
+  let ioHelper = context.ICCIOHelper;
+
+  // Override.
+  ioHelper.updateLinearFixedEF = function(options) {
+    options.pathId = context.ICCFileHelper.getEFPath(options.fileId);
+    options.command = ICC_COMMAND_UPDATE_RECORD;
+    options.p1 = options.recordNumber;
+    options.p2 = READ_RECORD_ABSOLUTE_MODE;
+    options.p3 = RECORD_SIZE;
+    ril.iccIO(options);
+  };
+
+  function do_test(fileId, number, expectedNumber) {
+    buf.sendParcel = function() {
+      // Request Type.
+      equal(this.readInt32(), REQUEST_SIM_IO);
+
+      // Token : we don't care
+      this.readInt32();
+
+      // command.
+      equal(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
+
+      // fileId.
+      equal(this.readInt32(), fileId);
+
+      // pathId.
+      if (ril.appType == CARD_APPTYPE_SIM || ril.appType == CARD_APPTYPE_RUIM) {
+        equal(this.readString(),
+              EF_PATH_MF_SIM + EF_PATH_DF_TELECOM);
+      } else{
+        equal(this.readString(),
+              EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK);
+      }
+
+      // p1.
+      equal(this.readInt32(), RECORD_NUMBER);
+
+      // p2.
+      equal(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
+
+      // p3.
+      equal(this.readInt32(), RECORD_SIZE);
+
+      // data.
+      let strLen = this.readInt32();
+      // Extension record
+      let recordType = pduHelper.readHexOctet();
+
+      equal(recordType, 0x02);
+      equal(pduHelper.readHexOctet(), 10);
+      equal(
+        pduHelper.readSwappedNibbleExtendedBcdString(EXT_MAX_NUMBER_DIGITS - 1),
+        expectedNumber);
+
+      this.readStringDelimiter(strLen);
+
+      // pin2.
+      equal(this.readString(), null);
+
+      // AID. Ignore because it's from modem.
+      this.readInt32();
+    };
+
+    recordHelper.updateExtension(fileId, RECORD_NUMBER, number);
+  }
+
+  ril.appType = CARD_APPTYPE_SIM;
+  do_test(ICC_EF_EXT1, "01234567890123456789", "01234567890123456789");
+  // We don't support extension chain.
+  do_test(ICC_EF_EXT1, "012345678901234567891234", "01234567890123456789");
+
+  ril.appType = CARD_APPTYPE_USIM;
+  do_test(ICC_EF_EXT1, "01234567890123456789", "01234567890123456789");
+
+  ril.appType = CARD_APPTYPE_RUIM;
+  do_test(ICC_EF_EXT1, "01234567890123456789", "01234567890123456789");
+
+  run_next_test();
+});
+
+/**
+ *  Verify ICCRecordHelper.cleanEFRecord
+ */
+add_test(function test_clean_ef_record() {
+  const RECORD_SIZE = 13;
+  const RECORD_NUMBER = 1;
+
+  let worker = newUint8Worker();
+  let context = worker.ContextPool._contexts[0];
+  let pduHelper = context.GsmPDUHelper;
+  let ril = context.RIL;
+  let recordHelper = context.ICCRecordHelper;
+  let buf = context.Buf;
+  let ioHelper = context.ICCIOHelper;
+
+  // Override.
+  ioHelper.updateLinearFixedEF = function(options) {
+    options.pathId = context.ICCFileHelper.getEFPath(options.fileId);
+    options.command = ICC_COMMAND_UPDATE_RECORD;
+    options.p1 = options.recordNumber;
+    options.p2 = READ_RECORD_ABSOLUTE_MODE;
+    options.p3 = RECORD_SIZE;
+    ril.iccIO(options);
+  };
+
+  function do_test(fileId) {
+    buf.sendParcel = function() {
+      // Request Type.
+      equal(this.readInt32(), REQUEST_SIM_IO);
+
+      // Token : we don't care
+      this.readInt32();
+
+      // command.
+      equal(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
+
+      // fileId.
+      equal(this.readInt32(), fileId);
+
+      // pathId.
+      if (ril.appType == CARD_APPTYPE_SIM || ril.appType == CARD_APPTYPE_RUIM) {
+        equal(this.readString(),
+              EF_PATH_MF_SIM + EF_PATH_DF_TELECOM);
+      } else{
+        equal(this.readString(),
+              EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK);
+      }
+
+      // p1.
+      equal(this.readInt32(), RECORD_NUMBER);
+
+      // p2.
+      equal(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
+
+      // p3.
+      equal(this.readInt32(), RECORD_SIZE);
+
+      // data.
+      let strLen = this.readInt32();
+      // Extension record
+      for (let i = 0; i < RECORD_SIZE; i++) {
+        equal(pduHelper.readHexOctet(), 0xff);
+      }
+
+      this.readStringDelimiter(strLen);
+
+      // pin2.
+      equal(this.readString(), null);
+
+      // AID. Ignore because it's from modem.
+      this.readInt32();
+    };
+
+    recordHelper.cleanEFRecord(fileId, RECORD_NUMBER);
+  }
+
+  ril.appType = CARD_APPTYPE_SIM;
+  do_test(ICC_EF_EXT1);
+
+  run_next_test();
+});
+
+/**
+ *  Verify ICCRecordHelper.getADNLikeExtensionRecordNumber
+ */
+add_test(function test_get_adn_like_extension_record_number() {
+  const RECORD_SIZE = 0x20;
+
+  let worker = newUint8Worker();
+  let context = worker.ContextPool._contexts[0];
+  let helper = context.GsmPDUHelper;
+  let record = context.ICCRecordHelper;
+  let buf    = context.Buf;
+  let io     = context.ICCIOHelper;
+
+  function do_test(rawEF, expectedRecordNumber) {
+    io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) {
+      // Write data size
+      buf.writeInt32(rawEF.length * 2);
+
+      // Write ext
+      for (let i = 0; i < rawEF.length; i += 2) {
+        helper.writeHexOctet(parseInt(rawEF.substr(i, 2), 16));
+      }
+
+      // Write string delimiter
+      buf.writeStringDelimiter(rawEF.length);
+      options.recordSize = RECORD_SIZE;
+      if (options.callback) {
+        options.callback(options);
+      }
+    };
+
+    let isSuccess = false;
+    let successCb = function successCb(number) {
+      equal(number, expectedRecordNumber);
+      isSuccess = true;
+    };
+
+    let errorCb = function errorCb(errorMsg) {
+      do_print("Reading ADNLike failed, msg = " + errorMsg);
+      ok(false);
+    };
+
+    record.getADNLikeExtensionRecordNumber(ICC_EF_ADN, 1, successCb, errorCb);
+    ok(isSuccess);
+  }
+
+  // Valid Extension, Alpha Id(Encoded with GSM 8 bit): "Contact001",
+  // Dialling Number: 99887766554433221100, Ext1: 0x01
+  do_test("436f6e74616374303031ffffffffffffffff0b8199887766554433221100ff01", 0x01);
+  // Empty Extension, Alpha Id(Encoded with GSM 8 bit): "Contact001", Ext1: 0xff
+  do_test("436f6e74616374303031ffffffffffffffffffffffffffffffffffffffffffff", 0xff);
+
+  run_next_test();
+});
--- a/dom/webidl/CameraControl.webidl
+++ b/dom/webidl/CameraControl.webidl
@@ -105,21 +105,20 @@ dictionary CameraStartRecordingOptions
      camera has determined that the scene is poorly lit, the flash mode
      will be automatically changed to "torch" until stopRecording() is
      called. During this time, flashMode will reflect the new setting. If
      flashMode is changed while recording is in progress, the new setting
      will be left as-is on stopRecording(). If the camera does not
      support this setting, it will be ignored. */
   boolean autoEnableLowLightTorch = false;
 
-  /* If given, a poster JPG will be created from the recording and saved
-     at the given path. PosterCreated or PosterFailed recording state
+  /* If true, a poster JPG will be created from the recording and issued
+     via the poster event. PosterCreated or PosterFailed recording state
      changes will indicate whether or not it was created. */
-  DOMString posterFilepath = "";
-  DeviceStorage? posterStorageArea = null;
+  boolean createPoster = false;
 };
 
 /*
     attributes here affect the preview, any pictures taken, and/or
     any video recorded by the camera.
 */
 [Func="nsDOMCameraControl::HasSupport"]
 interface CameraControl : MediaStream
@@ -259,16 +258,20 @@ interface CameraControl : MediaStream
              'FileSizeLimitReached' if stopped due to file size limit
              'VideoLengthLimitReached' if stopped due to a time limit
              'TrackCompleted' if audio or video track complete when stopping
              'TrackFailed' if audio or video track incomplete when stopping
              'MediaRecorderFailed' if failed due to local error
              'MediaServerFailed' if failed due to media server */
   attribute EventHandler    onrecorderstatechange;
 
+  /* the event dispatched when a poster is successfully captured; it is of the
+     type BlobEvent, where the data attribute contains the poster. */
+  attribute EventHandler    onposter;
+
   /* the event dispatched when the viewfinder stops or starts,
      useful for synchronizing other UI elements.
 
      event type is CameraStateChangeEvent where:
          'newState' is the new preview state */
   attribute EventHandler    onpreviewstatechange;
 
   /* the size of the picture to be returned by a call to takePicture();