merge b2g-inbound to mozilla-central a=merge
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Tue, 16 Dec 2014 12:54:14 +0100
changeset 219854 a3030140d5df8385b6c0dee0faa54c13a3dd1368
parent 219807 b836016d82b50d46630cc22013a5d925b1615cac (current diff)
parent 219853 e68ddb7c5b3d42b9c4c2ba38b952976d141f73c0 (diff)
child 219913 365c02fb0c5fe829a1ddfc50d3dd3080a90d792f
push id10419
push usercbook@mozilla.com
push dateTue, 16 Dec 2014 12:45:27 +0000
treeherderfx-team@ec87657146eb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone37.0a1
merge b2g-inbound to mozilla-central a=merge
--- a/b2g/chrome/content/desktop.js
+++ b/b2g/chrome/content/desktop.js
@@ -48,16 +48,46 @@ function setupButtons() {
     rotateButton.classList.add('active');
   });
   rotateButton.addEventListener('touchend', function() {
     GlobalSimulatorScreen.flipScreen();
     rotateButton.classList.remove('active');
   });
 }
 
+function setupStorage() {
+  let directory = null;
+
+  // Get the --storage-path argument from the command line.
+  try {
+    let service = Cc['@mozilla.org/commandlinehandler/general-startup;1?type=b2gcmds'].getService(Ci.nsISupports);
+    let args = service.wrappedJSObject.cmdLine;
+    if (args) {
+      let path = args.handleFlagWithParam('storage-path', false);
+      directory = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
+      directory.initWithPath(path);
+    }
+  } catch(e) {
+    directory = null;
+  }
+
+  // Otherwise, default to 'storage' folder within current profile.
+  if (!directory) {
+    directory = Services.dirsvc.get('ProfD', Ci.nsIFile);
+    directory.append('storage');
+    if (!directory.exists()) {
+      directory.create(Ci.nsIFile.DIRECTORY_TYPE, parseInt("755", 8));
+    }
+  }
+  dump("Set storage path to: " + directory.path + "\n");
+
+  // This is the magic, where we override the default location for the storages.
+  Services.prefs.setCharPref('device.storage.overrideRootDir', directory.path);
+}
+
 function checkDebuggerPort() {
   // XXX: To be removed once bug 942756 lands.
   // We are hacking 'unix-domain-socket' pref by setting a tcp port (number).
   // SocketListener.open detects that it isn't a file path (string), and starts
   // listening on the tcp port given here as command line argument.
 
   // Get the command line arguments that were passed to the b2g client
   let args;
@@ -136,15 +166,16 @@ function openDevtools() {
 
 window.addEventListener('ContentStart', function() {
   // On Firefox Mulet, touch events are enabled within the responsive mode
   if (!isMulet) {
     enableTouch();
   }
   setupButtons();
   checkDebuggerPort();
+  setupStorage();
   // On Firefox mulet, we automagically enable the responsive mode
   // and show the devtools
   if (isMulet) {
     initResponsiveDesign(browserWindow);
     openDevtools();
   }
 });
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -10,25 +10,25 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="c5b01c018e79a36d7ca1e466c143c76fac7da705"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="af3d2f89f391c92667e04676fc0ac971e6021bb7"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="09519af2056879ce0ea59f7085ac4b282c7d01d0"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="83760d213fb3bec7b4117d266fcfbf6fe2ba14ab"/>
   <project name="device/common" path="device/common" revision="6a2995683de147791e516aae2ccb31fdfbe2ad30"/>
@@ -134,12 +134,12 @@
   <project name="platform/frameworks/av" path="frameworks/av" revision="4387fe988e5a1001f29ce05fcfda03ed2d32137b"/>
   <project name="platform/hardware/akm" path="hardware/akm" revision="6d3be412647b0eab0adff8a2768736cf4eb68039"/>
   <project groups="invensense" name="platform/hardware/invensense" path="hardware/invensense" revision="e6d9ab28b4f4e7684f6c07874ee819c9ea0002a2"/>
   <project name="platform/hardware/ril" path="hardware/ril" revision="865ce3b4a2ba0b3a31421ca671f4d6c5595f8690"/>
   <project name="kernel/common" path="kernel" revision="6c6f012cea17fb8b3263605737816cf6663432f1"/>
   <project name="platform/system/core" path="system/core" revision="53d584d4a4b4316e4de9ee5f210d662f89b44e7e"/>
   <project name="u-boot" path="u-boot" revision="982c1fd67b89d5573317c1796cf5b0143de44e8a"/>
   <project name="vendor/sprd/gps" path="vendor/sprd/gps" revision="6974f8e771d4d8e910357a6739ab124768891e8f"/>
-  <project name="vendor/sprd/open-source" path="vendor/sprd/open-source" revision="1d4697b16ed039fd1de0a23bda150523e743e2ad"/>
+  <project name="vendor/sprd/open-source" path="vendor/sprd/open-source" revision="8ecfad58dfca5def20c7f7a51d251a89023c8c7c"/>
   <project name="vendor/sprd/partner" path="vendor/sprd/partner" revision="8649c7145972251af11b0639997edfecabfc7c2e"/>
   <project name="vendor/sprd/proprietories" path="vendor/sprd/proprietories" revision="d2466593022f7078aaaf69026adf3367c2adb7bb"/>
 </manifest>
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,23 +14,23 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="df362ace56338da8173d30d3e09e08c42c1accfa">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="c5b01c018e79a36d7ca1e466c143c76fac7da705"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="af3d2f89f391c92667e04676fc0ac971e6021bb7"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="6fa7a4936414ceb4055fd27f7a30e76790f834fb"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="09519af2056879ce0ea59f7085ac4b282c7d01d0"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
   <project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="425f8b5fadf5889834c5acd27d23c9e0b2129c28"/>
   <project name="device/common" path="device/common" revision="42b808b7e93d0619286ae8e59110b176b7732389"/>
   <project name="device/sample" path="device/sample" revision="237bd668d0f114d801a8d6455ef5e02cc3577587"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
   <project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="52a1a862a8bac319652b8f82d9541ba40bfa45ce"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,20 +12,20 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="0e94c080bee081a50aa2097527b0b40852f9143f">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="c5b01c018e79a36d7ca1e466c143c76fac7da705"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="af3d2f89f391c92667e04676fc0ac971e6021bb7"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="09519af2056879ce0ea59f7085ac4b282c7d01d0"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
   <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"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,25 +10,25 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="c5b01c018e79a36d7ca1e466c143c76fac7da705"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="af3d2f89f391c92667e04676fc0ac971e6021bb7"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="09519af2056879ce0ea59f7085ac4b282c7d01d0"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="1950e4760fa14688b83cdbb5acaa1af9f82ef434"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="ac6eb97a37035c09fb5ede0852f0881e9aadf9ad"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="737f591c5f95477148d26602c7be56cbea0cdeb9"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="51da9b1981be481b92a59a826d4d78dc73d0989a"/>
   <project name="device/common" path="device/common" revision="798a3664597e6041985feab9aef42e98d458bc3d"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,23 +14,23 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="df362ace56338da8173d30d3e09e08c42c1accfa">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="c5b01c018e79a36d7ca1e466c143c76fac7da705"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="af3d2f89f391c92667e04676fc0ac971e6021bb7"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="6fa7a4936414ceb4055fd27f7a30e76790f834fb"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="09519af2056879ce0ea59f7085ac4b282c7d01d0"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
   <project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="425f8b5fadf5889834c5acd27d23c9e0b2129c28"/>
   <project name="device/common" path="device/common" revision="42b808b7e93d0619286ae8e59110b176b7732389"/>
   <project name="device/sample" path="device/sample" revision="237bd668d0f114d801a8d6455ef5e02cc3577587"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
   <project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="52a1a862a8bac319652b8f82d9541ba40bfa45ce"/>
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -10,25 +10,25 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="c5b01c018e79a36d7ca1e466c143c76fac7da705"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="af3d2f89f391c92667e04676fc0ac971e6021bb7"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="09519af2056879ce0ea59f7085ac4b282c7d01d0"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="a32003194f707f66a2d8cdb913ed1869f1926c5d"/>
   <project name="device/common" path="device/common" revision="96d4d2006c4fcb2f19a3fa47ab10cb409faa017b"/>
@@ -132,17 +132,17 @@
   <remove-project name="platform/system/media"/>
   <project name="platform/system/media" path="system/media" revision="c1332c21c608f4932a6d7e83450411cde53315ef"/>
   <!--original fetch url was git://github.com/t2m-foxfone/-->
   <remote fetch="https://git.mozilla.org/external/t2m-foxfone" name="t2m"/>
   <default remote="caf" revision="LNX.LA.3.5.2.1.1" sync-j="4"/>
   <!-- Flame specific things -->
   <project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="1bb28abbc215f45220620af5cd60a8ac1be93722"/>
   <project name="device/qcom/common" path="device/qcom/common" revision="54c32c2ddef066fbdf611d29e4b7c47e0363599e"/>
-  <project name="device-flame" path="device/t2m/flame" remote="b2g" revision="263b5f41f7733c5577fb101eb4dc8ac5c11cfa8d"/>
+  <project name="device-flame" path="device/t2m/flame" remote="b2g" revision="e5c6b275d77ca95fb0f2051c3d2242e6e0d0e442"/>
   <project name="codeaurora_kernel_msm" path="kernel" remote="b2g" revision="48b6a2c9fde18f2f7d9abddf05261c498c2bb2ba"/>
   <project name="kernel_lk" path="bootable/bootloader/lk" remote="b2g" revision="fda40423ffa573dc6cafd3780515010cb2a086be"/>
   <project name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="30b96dfca99cb384bf520a16b81f3aba56f09907"/>
   <project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="5b71e40213f650459e95d35b6f14af7e88d8ab62"/>
   <project name="platform_external_libnfc-nci" path="external/libnfc-nci" remote="t2m" revision="4186bdecb4dae911b39a8202252cc2310d91b0be"/>
   <project name="platform/frameworks/av" path="frameworks/av" revision="c00de33ebfad57ae79ad5f93c2819ee2c40c8bcd"/>
   <project name="platform/frameworks/base" path="frameworks/base" revision="6b58ab45e3e56c1fc20708cc39fa2264c52558df"/>
   <project name="platform/frameworks/native" path="frameworks/native" revision="a46a9f1ac0ed5662d614c277cbb14eb3f332f365"/>
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -12,20 +12,20 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="0e94c080bee081a50aa2097527b0b40852f9143f">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="c5b01c018e79a36d7ca1e466c143c76fac7da705"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="af3d2f89f391c92667e04676fc0ac971e6021bb7"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="09519af2056879ce0ea59f7085ac4b282c7d01d0"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="e95b4ce22c825da44d14299e1190ea39a5260bde"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="471afab478649078ad7c75ec6b252481a59e19b8"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
         "git_revision": "", 
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "9607d52833bfa08f7aededcb384cf2be5b707b6b", 
+    "revision": "7d6f0979c4f3f3c5702033739561ba8d4159b409", 
     "repo_path": "integration/gaia-central"
 }
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -12,21 +12,21 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="df362ace56338da8173d30d3e09e08c42c1accfa">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="c5b01c018e79a36d7ca1e466c143c76fac7da705"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="af3d2f89f391c92667e04676fc0ac971e6021bb7"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="09519af2056879ce0ea59f7085ac4b282c7d01d0"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="746bc48f34f5060f90801925dcdd964030c1ab6d"/>
   <project name="platform/development" path="development" revision="2460485184bc8535440bb63876d4e63ec1b4770c"/>
   <project name="device/common" path="device/common" revision="0dcc1e03659db33b77392529466f9eb685cdd3c7"/>
   <project name="device/sample" path="device/sample" revision="68b1cb978a20806176123b959cb05d4fa8adaea4"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="df362ace56338da8173d30d3e09e08c42c1accfa">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="c5b01c018e79a36d7ca1e466c143c76fac7da705"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="af3d2f89f391c92667e04676fc0ac971e6021bb7"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -12,20 +12,20 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="0e94c080bee081a50aa2097527b0b40852f9143f">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="c5b01c018e79a36d7ca1e466c143c76fac7da705"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="af3d2f89f391c92667e04676fc0ac971e6021bb7"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="09519af2056879ce0ea59f7085ac4b282c7d01d0"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
   <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"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -12,22 +12,22 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="df362ace56338da8173d30d3e09e08c42c1accfa">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="c5b01c018e79a36d7ca1e466c143c76fac7da705"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="af3d2f89f391c92667e04676fc0ac971e6021bb7"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="09519af2056879ce0ea59f7085ac4b282c7d01d0"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="cd5dfce80bc3f0139a56b58aca633202ccaee7f8"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="e0a9ac010df3afaa47ba107192c05ac8b5516435"/>
   <project name="platform/development" path="development" revision="a384622f5fcb1d2bebb9102591ff7ae91fe8ed2d"/>
   <project name="device/common" path="device/common" revision="7c65ea240157763b8ded6154a17d3c033167afb7"/>
   <project name="device/sample" path="device/sample" revision="c328f3d4409db801628861baa8d279fb8855892f"/>
--- a/dom/icc/Assertions.cpp
+++ b/dom/icc/Assertions.cpp
@@ -2,20 +2,27 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/MozIccBinding.h"
 #include "nsIIccProvider.h"
 
 namespace mozilla {
 namespace dom {
+namespace icc {
 
+#define ASSERT_EQUALITY(webidlType, webidlState, xpidlState) \
+  static_assert(static_cast<uint32_t>(webidlType::webidlState) == nsIIccProvider::xpidlState, \
+  #webidlType "::" #webidlState " should equal to nsIIccProvider::" #xpidlState)
+
+/**
+ * Enum IccCardState
+ */
 #define ASSERT_ICC_CARD_STATE_EQUALITY(webidlState, xpidlState) \
-  static_assert(static_cast<uint32_t>(IccCardState::webidlState) == nsIIccProvider::xpidlState, \
-                "IccCardState::" #webidlState " should equal to nsIIccProvider::" #xpidlState)
+  ASSERT_EQUALITY(IccCardState, webidlState, xpidlState)
 
 ASSERT_ICC_CARD_STATE_EQUALITY(Unknown, CARD_STATE_UNKNOWN);
 ASSERT_ICC_CARD_STATE_EQUALITY(Ready, CARD_STATE_READY);
 ASSERT_ICC_CARD_STATE_EQUALITY(PinRequired, CARD_STATE_PIN_REQUIRED);
 ASSERT_ICC_CARD_STATE_EQUALITY(PukRequired, CARD_STATE_PUK_REQUIRED);
 ASSERT_ICC_CARD_STATE_EQUALITY(PermanentBlocked, CARD_STATE_PERMANENT_BLOCKED);
 ASSERT_ICC_CARD_STATE_EQUALITY(PersonalizationInProgress, CARD_STATE_PERSONALIZATION_IN_PROGRESS);
 ASSERT_ICC_CARD_STATE_EQUALITY(PersonalizationReady, CARD_STATE_PERSONALIZATION_READY);
@@ -40,10 +47,43 @@ ASSERT_ICC_CARD_STATE_EQUALITY(Network2P
 ASSERT_ICC_CARD_STATE_EQUALITY(HrpdNetworkPukRequired, CARD_STATE_HRPD_NETWORK_PUK_REQUIRED);
 ASSERT_ICC_CARD_STATE_EQUALITY(RuimCorporatePukRequired, CARD_STATE_RUIM_CORPORATE_PUK_REQUIRED);
 ASSERT_ICC_CARD_STATE_EQUALITY(RuimServiceProviderPukRequired, CARD_STATE_RUIM_SERVICE_PROVIDER_PUK_REQUIRED);
 ASSERT_ICC_CARD_STATE_EQUALITY(RuimPersonalizationPukRequired, CARD_STATE_RUIM_PUK_REQUIRED);
 ASSERT_ICC_CARD_STATE_EQUALITY(Illegal, CARD_STATE_ILLEGAL);
 
 #undef ASSERT_ICC_CARD_STATE_EQUALITY
 
+/**
+ * Enum IccLockType
+ */
+#define ASSERT_ICC_LOCK_TYPE_EQUALITY(webidlState, xpidlState) \
+  ASSERT_EQUALITY(IccLockType, webidlState, xpidlState)
+
+ASSERT_ICC_LOCK_TYPE_EQUALITY(Pin, CARD_LOCK_TYPE_PIN);
+ASSERT_ICC_LOCK_TYPE_EQUALITY(Pin2, CARD_LOCK_TYPE_PIN2);
+ASSERT_ICC_LOCK_TYPE_EQUALITY(Puk, CARD_LOCK_TYPE_PUK);
+ASSERT_ICC_LOCK_TYPE_EQUALITY(Puk2, CARD_LOCK_TYPE_PUK2);
+ASSERT_ICC_LOCK_TYPE_EQUALITY(Nck, CARD_LOCK_TYPE_NCK);
+ASSERT_ICC_LOCK_TYPE_EQUALITY(Nck1, CARD_LOCK_TYPE_NCK1);
+ASSERT_ICC_LOCK_TYPE_EQUALITY(Nck2, CARD_LOCK_TYPE_NCK2);
+ASSERT_ICC_LOCK_TYPE_EQUALITY(Hnck, CARD_LOCK_TYPE_HNCK);
+ASSERT_ICC_LOCK_TYPE_EQUALITY(Cck, CARD_LOCK_TYPE_CCK);
+ASSERT_ICC_LOCK_TYPE_EQUALITY(Spck, CARD_LOCK_TYPE_SPCK);
+ASSERT_ICC_LOCK_TYPE_EQUALITY(Rcck, CARD_LOCK_TYPE_RCCK);
+ASSERT_ICC_LOCK_TYPE_EQUALITY(Rspck, CARD_LOCK_TYPE_RSPCK);
+ASSERT_ICC_LOCK_TYPE_EQUALITY(NckPuk, CARD_LOCK_TYPE_NCK_PUK);
+ASSERT_ICC_LOCK_TYPE_EQUALITY(Nck1Puk, CARD_LOCK_TYPE_NCK1_PUK);
+ASSERT_ICC_LOCK_TYPE_EQUALITY(Nck2Puk, CARD_LOCK_TYPE_NCK2_PUK);
+ASSERT_ICC_LOCK_TYPE_EQUALITY(HnckPuk, CARD_LOCK_TYPE_HNCK_PUK);
+ASSERT_ICC_LOCK_TYPE_EQUALITY(CckPuk, CARD_LOCK_TYPE_CCK_PUK);
+ASSERT_ICC_LOCK_TYPE_EQUALITY(SpckPuk, CARD_LOCK_TYPE_SPCK_PUK);
+ASSERT_ICC_LOCK_TYPE_EQUALITY(RcckPuk, CARD_LOCK_TYPE_RCCK_PUK);
+ASSERT_ICC_LOCK_TYPE_EQUALITY(RspckPuk, CARD_LOCK_TYPE_RSPCK_PUK);
+ASSERT_ICC_LOCK_TYPE_EQUALITY(Fdn, CARD_LOCK_TYPE_FDN);
+
+#undef ASSERT_ICC_LOCK_TYPE_EQUALITY
+
+#undef ASSERT_EQUALITY
+
+} // namespace icc
 } // namespace dom
 } // namespace mozilla
--- a/dom/icc/Icc.cpp
+++ b/dom/icc/Icc.cpp
@@ -9,17 +9,42 @@
 #include "mozilla/dom/MozStkCommandEvent.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "nsIIccInfo.h"
 #include "nsIIccProvider.h"
 #include "nsJSON.h"
 #include "nsRadioInterfaceLayer.h"
 #include "nsServiceManagerUtils.h"
 
-using namespace mozilla::dom;
+namespace mozilla {
+namespace dom {
+
+namespace {
+
+bool
+IsPukCardLockType(IccLockType aLockType)
+{
+  switch(aLockType) {
+    case IccLockType::Puk:
+    case IccLockType::Puk2:
+    case IccLockType::NckPuk:
+    case IccLockType::Nck1Puk:
+    case IccLockType::Nck2Puk:
+    case IccLockType::HnckPuk:
+    case IccLockType::CckPuk:
+    case IccLockType::SpckPuk:
+    case IccLockType::RcckPuk:
+    case IccLockType::RspckPuk:
+      return true;
+  }
+
+  return false;
+}
+
+} // anonymous namespace
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(Icc, DOMEventTargetHelper, mIccInfo)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(Icc)
 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(Icc, DOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(Icc, DOMEventTargetHelper)
@@ -212,86 +237,105 @@ Icc::SendStkEventDownload(const JSContex
 
   nsresult rv = mProvider->SendStkEventDownload(mClientId, GetOwner(), aEvent);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
   }
 }
 
 already_AddRefed<DOMRequest>
-Icc::GetCardLock(const nsAString& aLockType, ErrorResult& aRv)
+Icc::GetCardLock(IccLockType aLockType, ErrorResult& aRv)
 {
   if (!mProvider) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   nsRefPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->GetCardLockState(mClientId, GetOwner(), aLockType,
-                                            getter_AddRefs(request));
+  nsresult rv = mProvider->GetCardLockEnabled(mClientId, GetOwner(),
+                                              static_cast<uint32_t>(aLockType),
+                                              getter_AddRefs(request));
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
   return request.forget().downcast<DOMRequest>();
 }
 
 already_AddRefed<DOMRequest>
-Icc::UnlockCardLock(const JSContext* aCx, JS::Handle<JS::Value> aInfo,
-                    ErrorResult& aRv)
+Icc::UnlockCardLock(const IccUnlockCardLockOptions& aOptions, ErrorResult& aRv)
 {
   if (!mProvider) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   nsRefPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->UnlockCardLock(mClientId, GetOwner(), aInfo,
+  const nsString& password = IsPukCardLockType(aOptions.mLockType)
+                           ? aOptions.mPuk : aOptions.mPin;
+  nsresult rv = mProvider->UnlockCardLock(mClientId, GetOwner(),
+                                          static_cast<uint32_t>(aOptions.mLockType),
+                                          password, aOptions.mNewPin,
                                           getter_AddRefs(request));
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
   return request.forget().downcast<DOMRequest>();
 }
 
 already_AddRefed<DOMRequest>
-Icc::SetCardLock(const JSContext* aCx, JS::Handle<JS::Value> aInfo,
-                 ErrorResult& aRv)
+Icc::SetCardLock(const IccSetCardLockOptions& aOptions, ErrorResult& aRv)
 {
   if (!mProvider) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
+  nsresult rv;
   nsRefPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->SetCardLock(mClientId, GetOwner(), aInfo,
+
+  if (aOptions.mEnabled.WasPassed()) {
+    // Enable card lock.
+    const nsString& password = (aOptions.mLockType == IccLockType::Fdn) ?
+                               aOptions.mPin2 : aOptions.mPin;
+
+    rv = mProvider->SetCardLockEnabled(mClientId, GetOwner(),
+                                       static_cast<uint32_t>(aOptions.mLockType),
+                                       password, aOptions.mEnabled.Value(),
                                        getter_AddRefs(request));
+  } else {
+    // Change card lock password.
+    rv = mProvider->ChangeCardLockPassword(mClientId, GetOwner(),
+                                           static_cast<uint32_t>(aOptions.mLockType),
+                                           aOptions.mPin, aOptions.mNewPin,
+                                           getter_AddRefs(request));
+  }
+
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
   return request.forget().downcast<DOMRequest>();
 }
 
 already_AddRefed<DOMRequest>
-Icc::GetCardLockRetryCount(const nsAString& aLockType, ErrorResult& aRv)
+Icc::GetCardLockRetryCount(IccLockType aLockType, ErrorResult& aRv)
 {
   if (!mProvider) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   nsRefPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->GetCardLockRetryCount(mClientId,
-                                                 GetOwner(),
-                                                 aLockType,
+  nsresult rv = mProvider->GetCardLockRetryCount(mClientId, GetOwner(),
+                                                 static_cast<uint32_t>(aLockType),
                                                  getter_AddRefs(request));
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
   return request.forget().downcast<DOMRequest>();
 }
@@ -353,8 +397,11 @@ Icc::MatchMvno(const nsAString& aMvnoTyp
                                      getter_AddRefs(request));
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
   return request.forget().downcast<DOMRequest>();
 }
+
+} // namespace dom
+} // namespace mozilla
--- a/dom/icc/Icc.h
+++ b/dom/icc/Icc.h
@@ -1,16 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_Icc_h
 #define mozilla_dom_Icc_h
 
-#include "mozilla/dom/MozIccBinding.h" // For IccCardState
+#include "mozilla/dom/MozIccBinding.h"
 #include "mozilla/DOMEventTargetHelper.h"
 
 class nsIIccInfo;
 class nsIIccProvider;
 
 namespace mozilla {
 namespace dom {
 
@@ -73,28 +73,26 @@ public:
   SendStkTimerExpiration(const JSContext* aCx, JS::Handle<JS::Value> aTimer,
                          ErrorResult& aRv);
 
   void
   SendStkEventDownload(const JSContext* aCx, JS::Handle<JS::Value> aEvent,
                        ErrorResult& aRv);
 
   already_AddRefed<DOMRequest>
-  GetCardLock(const nsAString& aLockType, ErrorResult& aRv);
+  GetCardLock(IccLockType aLockType, ErrorResult& aRv);
 
   already_AddRefed<DOMRequest>
-  UnlockCardLock(const JSContext* aCx, JS::Handle<JS::Value> aInfo,
-                 ErrorResult& aRv);
+  UnlockCardLock(const IccUnlockCardLockOptions& aOptions, ErrorResult& aRv);
 
   already_AddRefed<DOMRequest>
-  SetCardLock(const JSContext* aCx, JS::Handle<JS::Value> aInfo,
-              ErrorResult& aRv);
+  SetCardLock(const IccSetCardLockOptions& aOptions, ErrorResult& aRv);
 
   already_AddRefed<DOMRequest>
-  GetCardLockRetryCount(const nsAString& aLockType, ErrorResult& aRv);
+  GetCardLockRetryCount(IccLockType aLockType, ErrorResult& aRv);
 
   already_AddRefed<DOMRequest>
   ReadContacts(const nsAString& aContactType, ErrorResult& aRv);
 
   already_AddRefed<DOMRequest>
   UpdateContact(const JSContext* aCx, const nsAString& aContactType,
                 JS::Handle<JS::Value> aContact, const nsAString& aPin2,
                 ErrorResult& aRv);
--- a/dom/icc/interfaces/nsIIccProvider.idl
+++ b/dom/icc/interfaces/nsIIccProvider.idl
@@ -15,17 +15,17 @@ interface nsIIccListener : nsISupports
   void notifyStkSessionEnd();
   void notifyCardStateChanged();
   void notifyIccInfoChanged();
 };
 
 /**
  * XPCOM component (in the content process) that provides the ICC information.
  */
-[scriptable, uuid(bf802bf0-4df2-11e4-916c-0800200c9a66)]
+[scriptable, uuid(38bbc600-76ac-11e4-82f8-0800200c9a66)]
 interface nsIIccProvider : nsISupports
 {
   // MUST match enum IccCardState in MozIcc.webidl!
   const unsigned long CARD_STATE_UNKNOWN = 0;
   const unsigned long CARD_STATE_READY = 1;
   const unsigned long CARD_STATE_PIN_REQUIRED = 2;
   const unsigned long CARD_STATE_PUK_REQUIRED = 3;
   const unsigned long CARD_STATE_PERMANENT_BLOCKED = 4;
@@ -52,16 +52,39 @@ interface nsIIccProvider : nsISupports
   const unsigned long CARD_STATE_HRPD_NETWORK_PUK_REQUIRED = 25;
   const unsigned long CARD_STATE_RUIM_CORPORATE_PUK_REQUIRED = 26;
   const unsigned long CARD_STATE_RUIM_SERVICE_PROVIDER_PUK_REQUIRED = 27;
   const unsigned long CARD_STATE_RUIM_PUK_REQUIRED = 28;
   const unsigned long CARD_STATE_ILLEGAL = 29;
 
   const unsigned long CARD_STATE_UNDETECTED = 4294967295; // UINT32_MAX
 
+  // MUST match with enum IccLockType in MozIcc.webidl
+  const unsigned long CARD_LOCK_TYPE_PIN = 0;
+  const unsigned long CARD_LOCK_TYPE_PIN2 = 1;
+  const unsigned long CARD_LOCK_TYPE_PUK = 2;
+  const unsigned long CARD_LOCK_TYPE_PUK2 = 3;
+  const unsigned long CARD_LOCK_TYPE_NCK = 4;
+  const unsigned long CARD_LOCK_TYPE_NCK1 = 5;
+  const unsigned long CARD_LOCK_TYPE_NCK2 = 6;
+  const unsigned long CARD_LOCK_TYPE_HNCK = 7;
+  const unsigned long CARD_LOCK_TYPE_CCK = 8;
+  const unsigned long CARD_LOCK_TYPE_SPCK = 9;
+  const unsigned long CARD_LOCK_TYPE_RCCK = 10;
+  const unsigned long CARD_LOCK_TYPE_RSPCK = 11;
+  const unsigned long CARD_LOCK_TYPE_NCK_PUK = 12;
+  const unsigned long CARD_LOCK_TYPE_NCK1_PUK = 13;
+  const unsigned long CARD_LOCK_TYPE_NCK2_PUK = 14;
+  const unsigned long CARD_LOCK_TYPE_HNCK_PUK = 15;
+  const unsigned long CARD_LOCK_TYPE_CCK_PUK = 16;
+  const unsigned long CARD_LOCK_TYPE_SPCK_PUK = 17;
+  const unsigned long CARD_LOCK_TYPE_RCCK_PUK = 18;
+  const unsigned long CARD_LOCK_TYPE_RSPCK_PUK = 19;
+  const unsigned long CARD_LOCK_TYPE_FDN = 20;
+
   /**
    * Called when a content process registers receiving unsolicited messages from
    * RadioInterfaceLayer in the chrome process. Only a content process that has
    * the 'mobileconnection' permission is allowed to register.
    */
   void registerIccMsg(in unsigned long clientId, in nsIIccListener listener);
   void unregisterIccMsg(in unsigned long clientId, in nsIIccListener listener);
 
@@ -93,28 +116,37 @@ interface nsIIccProvider : nsISupports
                               in jsval timer);
   void sendStkEventDownload(in unsigned long clientId,
                             in nsIDOMWindow window,
                             in jsval event);
 
   /**
    * Card lock interfaces.
    */
-  nsIDOMDOMRequest getCardLockState(in unsigned long clientId,
-                                    in nsIDOMWindow window,
-                                    in DOMString lockType);
+  nsIDOMDOMRequest getCardLockEnabled(in unsigned long clientId,
+                                      in nsIDOMWindow window,
+                                      in unsigned long lockType);
   nsIDOMDOMRequest unlockCardLock(in unsigned long clientId,
                                   in nsIDOMWindow window,
-                                  in jsval info);
-  nsIDOMDOMRequest setCardLock(in unsigned long clientId,
-                               in nsIDOMWindow window,
-                               in jsval info);
+                                  in unsigned long lockType,
+                                  in DOMString password,
+                                  [optional] in DOMString newPin);
+  nsIDOMDOMRequest setCardLockEnabled(in unsigned long clientId,
+                                      in nsIDOMWindow window,
+                                      in unsigned long lockType,
+                                      in DOMString password,
+                                      in boolean enabled);
+  nsIDOMDOMRequest changeCardLockPassword(in unsigned long clientId,
+                                          in nsIDOMWindow window,
+                                          in unsigned long lockType,
+                                          in DOMString password,
+                                          in DOMString newPassword);
   nsIDOMDOMRequest getCardLockRetryCount(in unsigned long clientId,
                                          in nsIDOMWindow window,
-                                         in DOMString lockType);
+                                         in unsigned long lockType);
 
   /**
    * Phonebook interfaces.
    */
   nsIDOMDOMRequest readContacts(in unsigned long clientId,
                                 in nsIDOMWindow window,
                                 in DOMString contactType);
 
--- a/dom/icc/tests/marionette/test_icc_card_lock_get_retry_count.js
+++ b/dom/icc/tests/marionette/test_icc_card_lock_get_retry_count.js
@@ -1,34 +1,37 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 MARIONETTE_TIMEOUT = 60000;
 MARIONETTE_HEAD_JS = "head.js";
 
 function testGetCardLockRetryCount(aIcc, aLockType, aRetryCount) {
   log("testGetCardLockRetryCount for " + aLockType);
-  return aIcc.getCardLockRetryCount(aLockType)
-    .then((aResult) => {
-      if (!aRetryCount) {
-        ok(false, "getCardLockRetryCount(" + aLockType + ") should not success");
-        return;
-      }
+
+  try {
+    return aIcc.getCardLockRetryCount(aLockType)
+      .then((aResult) => {
+        if (!aRetryCount) {
+          ok(false, "getCardLockRetryCount(" + aLockType + ") should not success");
+          return;
+        }
 
-      // Check the request result.
-      is(aResult.retryCount, aRetryCount, "result.retryCount");
-    }, (aError) => {
-      if (aRetryCount) {
-        ok(false, "getCardLockRetryCount(" + aLockType + ") should not fail");
-        return;
-      }
-
-      // Check the error.
-      is(aError.name, "GenericFailure", "error.name");
-    });
+        // Check the request result.
+        is(aResult.retryCount, aRetryCount, "result.retryCount");
+      }, (aError) => {
+        if (aRetryCount) {
+          ok(false, "getCardLockRetryCount(" + aLockType + ") should not fail" +
+                    aError.name);
+        }
+      });
+  } catch (e) {
+    ok(!aRetryCount, "caught an exception: " + e);
+    return Promise.resolve();
+  }
 }
 
 // Start tests
 startTestCommon(function() {
   let icc = getMozIcc();
 
   // Read PIN-lock retry count.
   // The default PIN-lock retry count hard coded in emulator is 3.
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -2102,16 +2102,25 @@ TabChild::RecvHandleSingleTap(const CSSP
     return true;
   }
 
   if (mTouchEndCancelled) {
     return true;
   }
 
   LayoutDevicePoint currentPoint = APZCCallbackHelper::ApplyCallbackTransform(aPoint, aGuid) * mWidget->GetDefaultScale();;
+  if (!mActiveElementManager->ActiveElementUsesStyle()) {
+    // If the active element isn't visually affected by the :active style, we
+    // have no need to wait the extra sActiveDurationMs to make the activation
+    // visually obvious to the user.
+    FireSingleTapEvent(currentPoint);
+    return true;
+  }
+
+  TABC_LOG("Active element uses style, scheduling timer for click event\n");
   nsCOMPtr<nsITimer> timer = do_CreateInstance(NS_TIMER_CONTRACTID);
   nsRefPtr<DelayedFireSingleTapEvent> callback =
     new DelayedFireSingleTapEvent(this, currentPoint, timer);
   nsresult rv = timer->InitWithCallback(callback,
                                         sActiveDurationMs,
                                         nsITimer::TYPE_ONE_SHOT);
   if (NS_FAILED(rv)) {
     // Make |callback| not hold the timer, so they will both be destructed when
--- a/dom/mobileconnection/tests/marionette/head.js
+++ b/dom/mobileconnection/tests/marionette/head.js
@@ -4,16 +4,21 @@
 const {Cc: Cc, Ci: Ci, Cr: Cr, Cu: Cu} = SpecialPowers;
 
 const SETTINGS_KEY_DATA_ENABLED = "ril.data.enabled";
 const SETTINGS_KEY_DATA_ROAMING_ENABLED = "ril.data.roaming_enabled";
 const SETTINGS_KEY_DATA_APN_SETTINGS = "ril.data.apnSettings";
 
 const PREF_KEY_RIL_DEBUGGING_ENABLED = "ril.debugging.enabled";
 
+// The pin code hard coded in emulator is "0000".
+const DEFAULT_PIN = "0000";
+// The puk code hard coded in emulator is "12345678".
+const DEFAULT_PUK = "12345678";
+
 // Emulate Promise.jsm semantics.
 Promise.defer = function() { return new Deferred(); };
 function Deferred() {
   this.promise = new Promise(function(resolve, reject) {
     this.resolve = resolve;
     this.reject = reject;
   }.bind(this));
   Object.freeze(this);
@@ -296,43 +301,94 @@ function getMozMobileConnectionByService
   if (aServiceId !== undefined) {
     mobileConn =
       workingFrame.contentWindow.navigator.mozMobileConnections[aServiceId];
   }
   return mobileConn;
 }
 
 /**
+ * Get MozIccManager
+ *
+ * @return a MozIccManager
+ */
+function getMozIccManager() {
+  return workingFrame.contentWindow.navigator.mozIccManager;
+}
+
+/**
+ * Get MozIcc by IccId
+ *
+ * @param aIccId [optional]
+ *        Default: The first item of |mozIccManager.iccIds|.
+ *
+ * @return A MozIcc.
+ */
+function getMozIccByIccId(aIccId) {
+  let iccManager = getMozIccManager();
+
+  aIccId = aIccId || iccManager.iccIds[0];
+  if (!aIccId) {
+    ok(true, "iccManager.iccIds[0] is " + aIccId);
+    return null;
+  }
+
+  return iccManager.getIccById(aIccId);
+}
+
+/**
+ * Wait for one named event.
+ *
+ * Resolve if that named event occurs.  Never reject.
+ *
+ * Fulfill params: the DOMEvent passed.
+ *
+ * @param aEventTarget
+ *        An EventTarget object.
+ * @param aEventName
+ *        A string event name.
+ * @param aMatchFun [optional]
+ *        A matching function returns true or false to filter the event.
+ *
+ * @return A deferred promise.
+ */
+function waitForTargetEvent(aEventTarget, aEventName, aMatchFun) {
+  let deferred = Promise.defer();
+
+  aEventTarget.addEventListener(aEventName, function onevent(aEvent) {
+    if (!aMatchFun || aMatchFun(aEvent)) {
+      aEventTarget.removeEventListener(aEventName, onevent);
+      ok(true, "Event '" + aEventName + "' got.");
+      deferred.resolve(aEvent);
+    }
+  });
+
+  return deferred.promise;
+}
+
+/**
  * Wait for one named MobileConnection event.
  *
  * Resolve if that named event occurs.  Never reject.
  *
  * Fulfill params: the DOMEvent passed.
  *
  * @param aEventName
  *        A string event name.
  * @param aServiceId [optional]
  *        A numeric DSDS service id. Default: the one indicated in
  *        start*TestCommon() or 0 if not indicated.
+ * @param aMatchFun [optional]
+ *        A matching function returns true or false to filter the event.
  *
  * @return A deferred promise.
  */
-function waitForManagerEvent(aEventName, aServiceId) {
-  let deferred = Promise.defer();
-
+function waitForManagerEvent(aEventName, aServiceId, aMatchFun) {
   let mobileConn = getMozMobileConnectionByServiceId(aServiceId);
-
-  mobileConn.addEventListener(aEventName, function onevent(aEvent) {
-    mobileConn.removeEventListener(aEventName, onevent);
-
-    ok(true, "MobileConnection event '" + aEventName + "' got.");
-    deferred.resolve(aEvent);
-  });
-
-  return deferred.promise;
+  return waitForTargetEvent(mobileConn, aEventName, aMatchFun);
 }
 
 /**
  * Get available networks.
  *
  * Fulfill params:
  *   An array of MozMobileNetworkInfo.
  * Reject params:
@@ -673,36 +729,25 @@ function setRadioEnabled(aEnabled, aServ
  *        A boolean state.
  * @param aServiceId [optional]
  *        A numeric DSDS service id. Default: the one indicated in
  *        start*TestCommon() or 0 if not indicated.
  *
  * @return A deferred promise.
  */
 function setRadioEnabledAndWait(aEnabled, aServiceId) {
-  let deferred = Promise.defer();
+  let promises = [];
 
-  let promises = [];
-  promises.push(waitForManagerEvent("radiostatechange", aServiceId));
-  promises.push(setRadioEnabled(aEnabled, aServiceId));
-  Promise.all(promises).then(function keepWaiting() {
+  promises.push(waitForManagerEvent("radiostatechange", aServiceId, function() {
     let mobileConn = getMozMobileConnectionByServiceId(aServiceId);
-    // To ignore some transient states, we only resolve that deferred promise
-    // when |radioState| equals to the expected one and never rejects.
-    let state = mobileConn.radioState;
-    aEnabled = aEnabled ? "enabled" : "disabled";
-    if (state == aEnabled) {
-      deferred.resolve();
-      return;
-    }
+    return mobileConn.radioState === aEnabled ? "enabled" : "disabled";
+  }));
+  promises.push(setRadioEnabled(aEnabled, aServiceId));
 
-    return waitForManagerEvent("radiostatechange", aServiceId).then(keepWaiting);
-  });
-
-  return deferred.promise;
+  return Promise.all(promises);
 }
 
 /**
  * Set CLIR (calling line id restriction).
  *
  * Fulfill params: (none)
  * Reject params:
  *   'RadioNotAvailable', 'RequestNotSupported', or 'GenericFailure'
@@ -1118,26 +1163,26 @@ function cleanUp() {
  * @param aTestCaseMain
  *        A function that takes no parameter.
  */
 function startTestBase(aTestCaseMain) {
   // Turn on debugging pref.
   let debugPref = SpecialPowers.getBoolPref(PREF_KEY_RIL_DEBUGGING_ENABLED);
   SpecialPowers.setBoolPref(PREF_KEY_RIL_DEBUGGING_ENABLED, true);
 
-  Promise.resolve()
+  return Promise.resolve()
     .then(aTestCaseMain)
+    .catch((aError) => {
+      ok(false, "promise rejects during test: " + aError);
+    })
     .then(() => {
       // Restore debugging pref.
       SpecialPowers.setBoolPref(PREF_KEY_RIL_DEBUGGING_ENABLED, debugPref);
+      cleanUp();
     })
-    .then(cleanUp, function() {
-      ok(false, 'promise rejects during test.');
-      cleanUp();
-    });
 }
 
 /**
  * Common test routine helper for mobile connection tests.
  *
  * This function ensures global |mobileConnection| variable is available during
  * the process and performs clean-ups as well.
  *
--- a/dom/mobileconnection/tests/marionette/manifest.ini
+++ b/dom/mobileconnection/tests/marionette/manifest.ini
@@ -12,16 +12,17 @@ qemu = true
 [test_mobile_preferred_network_type.js]
 [test_mobile_preferred_network_type_radio_off.js]
 [test_mobile_data_connection.js]
 [test_mobile_data_location.js]
 [test_mobile_data_state.js]
 [test_mobile_mmi.js]
 [test_mobile_mmi_change_pin.js]
 [test_mobile_mmi_call_forwarding.js]
+[test_mobile_mmi_unlock_puk.js]
 [test_mobile_roaming_preference.js]
 [test_call_barring_get_option.js]
 [test_call_barring_set_error.js]
 [test_call_barring_change_password.js]
 [test_mobile_set_radio.js]
 [test_mobile_last_known_network.js]
 [test_mobile_icc_change.js]
 [test_mobile_connections_array_uninitialized.js]
new file mode 100644
--- /dev/null
+++ b/dom/mobileconnection/tests/marionette/test_mobile_mmi_unlock_puk.js
@@ -0,0 +1,122 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+MARIONETTE_TIMEOUT = 60000;
+MARIONETTE_HEAD_JS = "head.js";
+
+function restartRadioAndWait(aCardState) {
+  let iccManager = getMozIccManager();
+  return setRadioEnabledAndWait(false).then(() => {
+    let promises = [];
+
+    promises.push(waitForTargetEvent(iccManager, "iccdetected")
+      .then((aEvent) => {
+        let icc = getMozIccByIccId(aEvent.iccId);
+        if (icc.cardState !== aCardState) {
+          return waitForTargetEvent(icc, "cardstatechange", function() {
+            return icc.cardState === aCardState;
+          });
+        }
+      }));
+    promises.push(setRadioEnabledAndWait(true));
+
+    return Promise.all(promises);
+  });
+}
+
+function passingWrongPinAndWait(aIcc) {
+  return aIcc.getCardLockRetryCount("pin").then((aResult) => {
+    let promises = [];
+    let retryCount = aResult.retryCount;
+
+    ok(true, "pin retryCount is " + retryCount);
+
+    promises.push(waitForTargetEvent(aIcc, "cardstatechange", function() {
+      return aIcc.cardState === "pukRequired";
+    }));
+
+    for (let i = 0; i < retryCount; i++) {
+      promises.push(aIcc.unlockCardLock({ lockType: "pin", pin: "1111" })
+        .then(() => {
+          ok(false, "unlocking pin should not success");
+        }, (aError) => {
+          ok(true, "pin retryCount = " + aError.retryCount);
+        }));
+    }
+
+    return Promise.all(promises);
+  });
+}
+
+function sendUnlockPukMmi(aPuk, aNewPin, aNewPinAgain) {
+  let MMI_CODE = "**05*" + aPuk + "*" + aNewPin + "*" + aNewPinAgain + "#";
+  log("Test " + MMI_CODE);
+
+  return sendMMI(MMI_CODE);
+}
+
+function testUnlockPukMmiError(aPuk, aNewPin, aNewPinAgain, aErrorName,
+                               aRetryCount = null) {
+  return sendUnlockPukMmi(aPuk, aNewPin, aNewPinAgain)
+    .then(() => {
+      ok(false, "unlocking puk should not success");
+    }, (aError) => {
+      is(aError.name, aErrorName, "Check name");
+      is(aError.message, "", "Check message");
+      is(aError.serviceCode, "scPuk", "Check service code");
+      is(aError.additionalInformation, aRetryCount,
+         "Check additional information");
+    });
+}
+
+function testUnlockPukAndWait(aIcc, aCardState) {
+  let promises = [];
+
+  promises.push(waitForTargetEvent(aIcc, "cardstatechange", function() {
+    return aIcc.cardState === aCardState;
+  }));
+  promises.push(sendUnlockPukMmi(DEFAULT_PUK, DEFAULT_PIN, DEFAULT_PIN));
+
+  return Promise.all(promises);
+}
+
+// Start test
+startTestCommon(function() {
+  let icc = getMozIccByIccId();
+  let retryCount;
+
+  // Enable PIN-lock.
+  return icc.setCardLock({lockType: "pin", enabled: true, pin: DEFAULT_PIN})
+    // Reset card state to "pinRequired" by restarting radio.
+    .then(() => restartRadioAndWait("pinRequired"))
+    .then(() => { icc = getMozIccByIccId(); })
+    // Switch card state to "pukRequired" by entering wrong pin.
+    .then(() => passingWrongPinAndWait(icc))
+
+    // Get current PUK-lock retry count.
+    .then(() => icc.getCardLockRetryCount("puk"))
+    .then((aResult) => {
+      retryCount = aResult.retryCount;
+      ok(true, "puk retryCount is " + retryCount);
+    })
+
+    // Test passing no puk.
+    .then(() => testUnlockPukMmiError("", "1111", "2222", "emMmiError"))
+    // Test passing no newPin.
+    .then(() => testUnlockPukMmiError("11111111", "", "", "emMmiError"))
+    // Test passing mismatched newPin.
+    .then(() => testUnlockPukMmiError("11111111", "1111", "2222",
+                                      "emMmiErrorMismatchPin"))
+    // Test passing invalid puk (> 8 digit).
+    .then(() => testUnlockPukMmiError("123456789", DEFAULT_PIN, DEFAULT_PIN,
+                                      "emMmiErrorInvalidPin"))
+    // Test passing incorrect puk.
+    .then(() => testUnlockPukMmiError("11111111", DEFAULT_PIN, DEFAULT_PIN,
+                                      "emMmiErrorBadPuk", retryCount - 1))
+
+    // Test unlock PUK-lock success.
+    .then(() => testUnlockPukAndWait(icc, "ready"))
+
+    // Restore pin state.
+    .then(() => icc.setCardLock({lockType: "pin", enabled: false, pin: DEFAULT_PIN}));
+});
--- a/dom/system/gonk/RILContentHelper.js
+++ b/dom/system/gonk/RILContentHelper.js
@@ -246,63 +246,99 @@ RILContentHelper.prototype = {
         requestId: requestId,
         mvnoType: mvnoType,
         mvnoData: mvnoData
       }
     });
     return request;
   },
 
-  getCardLockState: function(clientId, window, lockType) {
+  getCardLockEnabled: function(clientId, window, lockType) {
     if (window == null) {
       throw Components.Exception("Can't get window object",
                                   Cr.NS_ERROR_UNEXPECTED);
     }
+
     let request = Services.DOMRequest.createRequest(window);
     let requestId = this.getRequestId(request);
     this._windowsMap[requestId] = window;
 
-    cpmm.sendAsyncMessage("RIL:GetCardLockState", {
+    cpmm.sendAsyncMessage("RIL:GetCardLockEnabled", {
       clientId: clientId,
       data: {
         lockType: lockType,
         requestId: requestId
       }
     });
     return request;
   },
 
-  unlockCardLock: function(clientId, window, info) {
+  unlockCardLock: function(clientId, window, lockType, password, newPin) {
+    if (window == null) {
+      throw Components.Exception("Can't get window object",
+                                  Cr.NS_ERROR_UNEXPECTED);
+    }
+
+    let request = Services.DOMRequest.createRequest(window);
+    let requestId = this.getRequestId(request);
+    this._windowsMap[requestId] = window;
+
+    cpmm.sendAsyncMessage("RIL:UnlockCardLock", {
+      clientId: clientId,
+      data: {
+        lockType: lockType,
+        password: password,
+        newPin: newPin,
+        requestId: requestId
+      }
+    });
+    return request;
+  },
+
+  setCardLockEnabled: function(clientId, window, lockType, password, enabled) {
     if (window == null) {
       throw Components.Exception("Can't get window object",
                                   Cr.NS_ERROR_UNEXPECTED);
     }
+
     let request = Services.DOMRequest.createRequest(window);
-    info.requestId = this.getRequestId(request);
-    this._windowsMap[info.requestId] = window;
+    let requestId = this.getRequestId(request);
+    this._windowsMap[requestId] = window;
 
-    cpmm.sendAsyncMessage("RIL:UnlockCardLock", {
+    cpmm.sendAsyncMessage("RIL:SetCardLockEnabled", {
       clientId: clientId,
-      data: info
+      data: {
+        lockType: lockType,
+        password: password,
+        enabled: enabled,
+        requestId: requestId
+      }
     });
     return request;
   },
 
-  setCardLock: function(clientId, window, info) {
+  changeCardLockPassword: function(clientId, window, lockType, password,
+                                   newPassword) {
     if (window == null) {
       throw Components.Exception("Can't get window object",
                                   Cr.NS_ERROR_UNEXPECTED);
     }
+
     let request = Services.DOMRequest.createRequest(window);
-    info.requestId = this.getRequestId(request);
-    this._windowsMap[info.requestId] = window;
+    let requestId = this.getRequestId(request);
+    this._windowsMap[requestId] = window;
 
-    cpmm.sendAsyncMessage("RIL:SetCardLock", {
+    cpmm.sendAsyncMessage("RIL:ChangeCardLockPassword", {
       clientId: clientId,
-      data: info
+      data: {
+        lockType: lockType,
+        password: password,
+        newPassword: newPassword,
+        requestId: requestId
+      }
     });
     return request;
   },
 
   getCardLockRetryCount: function(clientId, window, lockType) {
     if (window == null) {
       throw Components.Exception("Can't get window object",
                                   Cr.NS_ERROR_UNEXPECTED);
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -98,19 +98,20 @@ const NETWORK_TYPE_MOBILE_IMS  = Ci.nsIN
 const NETWORK_TYPE_MOBILE_DUN  = Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN;
 
 const RIL_IPC_ICCMANAGER_MSG_NAMES = [
   "RIL:GetRilContext",
   "RIL:SendStkResponse",
   "RIL:SendStkMenuSelection",
   "RIL:SendStkTimerExpiration",
   "RIL:SendStkEventDownload",
-  "RIL:GetCardLockState",
+  "RIL:GetCardLockEnabled",
   "RIL:UnlockCardLock",
-  "RIL:SetCardLock",
+  "RIL:SetCardLockEnabled",
+  "RIL:ChangeCardLockPassword",
   "RIL:GetCardLockRetryCount",
   "RIL:IccOpenChannel",
   "RIL:IccExchangeAPDU",
   "RIL:IccCloseChannel",
   "RIL:ReadIccContacts",
   "RIL:UpdateIccContact",
   "RIL:RegisterIccMsg",
   "RIL:MatchMvno"
@@ -1826,26 +1827,30 @@ RadioInterface.prototype = {
   /**
    * Process a message from the content process.
    */
   receiveMessage: function(msg) {
     switch (msg.name) {
       case "RIL:GetRilContext":
         // This message is sync.
         return this.rilContext;
-      case "RIL:GetCardLockState":
-        this.workerMessenger.sendWithIPCMessage(msg, "iccGetCardLockState",
+      case "RIL:GetCardLockEnabled":
+        this.workerMessenger.sendWithIPCMessage(msg, "iccGetCardLockEnabled",
                                                 "RIL:GetCardLockResult");
         break;
       case "RIL:UnlockCardLock":
         this.workerMessenger.sendWithIPCMessage(msg, "iccUnlockCardLock",
                                                 "RIL:SetUnlockCardLockResult");
         break;
-      case "RIL:SetCardLock":
-        this.workerMessenger.sendWithIPCMessage(msg, "iccSetCardLock",
+      case "RIL:SetCardLockEnabled":
+        this.workerMessenger.sendWithIPCMessage(msg, "iccSetCardLockEnabled",
+                                                "RIL:SetUnlockCardLockResult");
+        break;
+      case "RIL:ChangeCardLockPassword":
+        this.workerMessenger.sendWithIPCMessage(msg, "iccChangeCardLockPassword",
                                                 "RIL:SetUnlockCardLockResult");
         break;
       case "RIL:GetCardLockRetryCount":
         this.workerMessenger.sendWithIPCMessage(msg, "iccGetCardLockRetryCount",
                                                 "RIL:CardLockRetryCount");
         break;
       case "RIL:SendStkResponse":
         this.workerMessenger.send("sendStkTerminalResponse", msg.json.data);
--- a/dom/system/gonk/ril_consts.js
+++ b/dom/system/gonk/ril_consts.js
@@ -2550,37 +2550,51 @@ this.GECKO_CARDSTATE_RUIM_LOCKED = 22;
 this.GECKO_CARDSTATE_NETWORK1_PUK_REQUIRED = 23;
 this.GECKO_CARDSTATE_NETWORK2_PUK_REQUIRED = 24;
 this.GECKO_CARDSTATE_HRPD_NETWORK_PUK_REQUIRED = 25;
 this.GECKO_CARDSTATE_RUIM_CORPORATE_PUK_REQUIRED = 26;
 this.GECKO_CARDSTATE_RUIM_SERVICE_PROVIDER_PUK_REQUIRED = 27;
 this.GECKO_CARDSTATE_RUIM_PUK_REQUIRED = 28;
 this.GECKO_CARDSTATE_ILLEGAL = 29;
 
-this.GECKO_CARDLOCK_PIN      = "pin";
-this.GECKO_CARDLOCK_PIN2     = "pin2";
-this.GECKO_CARDLOCK_PUK      = "puk";
-this.GECKO_CARDLOCK_PUK2     = "puk2";
-this.GECKO_CARDLOCK_FDN      = "fdn";
-this.GECKO_CARDLOCK_NCK      = "nck";
-this.GECKO_CARDLOCK_NCK1     = "nck1";
-this.GECKO_CARDLOCK_NCK2     = "nck2";
-this.GECKO_CARDLOCK_HNCK     = "hnck";
-this.GECKO_CARDLOCK_CCK      = "cck";
-this.GECKO_CARDLOCK_SPCK     = "spck";
-this.GECKO_CARDLOCK_RCCK     = "rcck";
-this.GECKO_CARDLOCK_RSPCK    = "rspck";
-this.GECKO_CARDLOCK_NCK_PUK  = "nckPuk";
-this.GECKO_CARDLOCK_NCK1_PUK = "nck1Puk";
-this.GECKO_CARDLOCK_NCK2_PUK = "nck2Puk";
-this.GECKO_CARDLOCK_HNCK_PUK = "hnckPuk";
-this.GECKO_CARDLOCK_CCK_PUK  = "cckPuk";
-this.GECKO_CARDLOCK_SPCK_PUK = "spckPuk";
-this.GECKO_CARDLOCK_RCCK_PUK = "rcckPuk";
-this.GECKO_CARDLOCK_RSPCK_PUK = "rspckPuk";
+// See nsIIccProvider::CARD_LOCK_TYPE_*
+this.GECKO_CARDLOCK_PIN = 0;
+this.GECKO_CARDLOCK_PIN2 = 1;
+this.GECKO_CARDLOCK_PUK = 2;
+this.GECKO_CARDLOCK_PUK2 = 3;
+this.GECKO_CARDLOCK_NCK = 4;
+this.GECKO_CARDLOCK_NCK1 = 5;
+this.GECKO_CARDLOCK_NCK2 = 6;
+this.GECKO_CARDLOCK_HNCK = 7;
+this.GECKO_CARDLOCK_CCK = 8;
+this.GECKO_CARDLOCK_SPCK = 9;
+this.GECKO_CARDLOCK_RCCK = 10;
+this.GECKO_CARDLOCK_RSPCK = 11;
+this.GECKO_CARDLOCK_NCK_PUK = 12;
+this.GECKO_CARDLOCK_NCK1_PUK = 13;
+this.GECKO_CARDLOCK_NCK2_PUK = 14;
+this.GECKO_CARDLOCK_HNCK_PUK = 15;
+this.GECKO_CARDLOCK_CCK_PUK = 16;
+this.GECKO_CARDLOCK_SPCK_PUK = 17;
+this.GECKO_CARDLOCK_RCCK_PUK = 18;
+this.GECKO_CARDLOCK_RSPCK_PUK = 19;
+this.GECKO_CARDLOCK_FDN = 20;
+
+this.GECKO_CARDLOCK_TO_FACILITY = {};
+GECKO_CARDLOCK_TO_FACILITY[GECKO_CARDLOCK_PIN] = ICC_CB_FACILITY_SIM;
+GECKO_CARDLOCK_TO_FACILITY[GECKO_CARDLOCK_FDN] = ICC_CB_FACILITY_FDN;
+
+this.GECKO_CARDLOCK_TO_SEL_CODE = {};
+GECKO_CARDLOCK_TO_SEL_CODE[GECKO_CARDLOCK_PIN] = ICC_SEL_CODE_SIM_PIN;
+GECKO_CARDLOCK_TO_SEL_CODE[GECKO_CARDLOCK_PIN2] = ICC_SEL_CODE_SIM_PIN2;
+GECKO_CARDLOCK_TO_SEL_CODE[GECKO_CARDLOCK_PUK] = ICC_SEL_CODE_SIM_PUK;
+GECKO_CARDLOCK_TO_SEL_CODE[GECKO_CARDLOCK_PUK2] = ICC_SEL_CODE_SIM_PUK2;
+GECKO_CARDLOCK_TO_SEL_CODE[GECKO_CARDLOCK_NCK] = ICC_SEL_CODE_PH_NET_PIN;
+GECKO_CARDLOCK_TO_SEL_CODE[GECKO_CARDLOCK_CCK] = ICC_SEL_CODE_PH_CORP_PIN;
+GECKO_CARDLOCK_TO_SEL_CODE[GECKO_CARDLOCK_SPCK] = ICC_SEL_CODE_PH_SP_PIN;
 
 // See ril.h RIL_PersoSubstate
 this.PERSONSUBSTATE = {};
 PERSONSUBSTATE[CARD_PERSOSUBSTATE_UNKNOWN] = GECKO_CARDSTATE_UNKNOWN;
 PERSONSUBSTATE[CARD_PERSOSUBSTATE_IN_PROGRESS] = GECKO_CARDSTATE_PERSONALIZATION_IN_PROGRESS;
 PERSONSUBSTATE[CARD_PERSOSUBSTATE_READY] = GECKO_CARDSTATE_PERSONALIZATION_READY;
 PERSONSUBSTATE[CARD_PERSOSUBSTATE_SIM_NETWORK] = GECKO_CARDSTATE_NETWORK_LOCKED;
 PERSONSUBSTATE[CARD_PERSOSUBSTATE_SIM_NETWORK_SUBSET] = GECKO_CARDSTATE_NETWORK_SUBSET_LOCKED;
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -610,237 +610,227 @@ RilObject.prototype = {
         this.enterICCPUK2(options);
         break;
       case GECKO_CARDLOCK_NCK:
       case GECKO_CARDLOCK_NCK1:
       case GECKO_CARDLOCK_NCK2:
       case GECKO_CARDLOCK_HNCK:
       case GECKO_CARDLOCK_CCK:
       case GECKO_CARDLOCK_SPCK:
-      case GECKO_CARDLOCK_RCCK: // Fall through.
-      case GECKO_CARDLOCK_RSPCK: {
-        let type = GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[options.lockType];
-        this.enterDepersonalization(type, options.pin, options);
-        break;
-      }
+      case GECKO_CARDLOCK_RCCK:
+      case GECKO_CARDLOCK_RSPCK:
       case GECKO_CARDLOCK_NCK_PUK:
       case GECKO_CARDLOCK_NCK1_PUK:
       case GECKO_CARDLOCK_NCK2_PUK:
       case GECKO_CARDLOCK_HNCK_PUK:
       case GECKO_CARDLOCK_CCK_PUK:
       case GECKO_CARDLOCK_SPCK_PUK:
       case GECKO_CARDLOCK_RCCK_PUK: // Fall through.
-      case GECKO_CARDLOCK_RSPCK_PUK: {
-        let type = GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[options.lockType];
-        this.enterDepersonalization(type, options.puk, options);
-        break;
-      }
+      case GECKO_CARDLOCK_RSPCK_PUK:
+        options.personlization =
+          GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[options.lockType];
+        this.enterDepersonalization(options);
+        break;
       default:
-        options.errorMsg = "Unsupported Card Lock.";
-        options.success = false;
+        options.errorMsg = GECKO_ERROR_REQUEST_NOT_SUPPORTED;
         this.sendChromeMessage(options);
     }
   },
 
   /**
    * Enter a PIN to unlock the ICC.
    *
-   * @param pin
+   * @param password
    *        String containing the PIN.
    * @param [optional] aid
    *        AID value.
    */
   enterICCPIN: function(options) {
     let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_ENTER_SIM_PIN, options);
     Buf.writeInt32(this.v5Legacy ? 1 : 2);
-    Buf.writeString(options.pin);
+    Buf.writeString(options.password);
     if (!this.v5Legacy) {
       Buf.writeString(options.aid || this.aid);
     }
     Buf.sendParcel();
   },
 
   /**
    * Enter a PIN2 to unlock the ICC.
    *
-   * @param pin
+   * @param password
    *        String containing the PIN2.
    * @param [optional] aid
    *        AID value.
    */
   enterICCPIN2: function(options) {
     let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_ENTER_SIM_PIN2, options);
     Buf.writeInt32(this.v5Legacy ? 1 : 2);
-    Buf.writeString(options.pin);
+    Buf.writeString(options.password);
     if (!this.v5Legacy) {
       Buf.writeString(options.aid || this.aid);
     }
     Buf.sendParcel();
   },
 
   /**
    * Requests a network personalization be deactivated.
    *
-   * @param type
-   *        Integer indicating the network personalization be deactivated.
+   * @param personlization
+   *        One of CARD_PERSOSUBSTATE_*
    * @param password
    *        String containing the password.
    */
-  enterDepersonalization: function(type, password, options) {
+  enterDepersonalization: function(options) {
     let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_ENTER_NETWORK_DEPERSONALIZATION_CODE, options);
-    Buf.writeInt32(type);
-    Buf.writeString(password);
+    Buf.writeInt32(options.personlization);
+    Buf.writeString(options.password);
     Buf.sendParcel();
   },
 
   /**
-   * Helper function for changing ICC locks.
-   */
-  iccSetCardLock: function(options) {
-    if (options.newPin !== undefined) { // Change PIN lock.
-      switch (options.lockType) {
-        case GECKO_CARDLOCK_PIN:
-          this.changeICCPIN(options);
-          break;
-        case GECKO_CARDLOCK_PIN2:
-          this.changeICCPIN2(options);
-          break;
-        default:
-          options.errorMsg = "Unsupported Card Lock.";
-          options.success = false;
-          this.sendChromeMessage(options);
-      }
-    } else { // Enable/Disable lock.
-      switch (options.lockType) {
-        case GECKO_CARDLOCK_PIN:
-          options.facility = ICC_CB_FACILITY_SIM;
-          options.password = options.pin;
-          break;
-        case GECKO_CARDLOCK_FDN:
-          options.facility = ICC_CB_FACILITY_FDN;
-          options.password = options.pin2;
-          break;
-        default:
-          options.errorMsg = "Unsupported Card Lock.";
-          options.success = false;
-          this.sendChromeMessage(options);
-          return;
-      }
-      options.enabled = options.enabled;
-      options.serviceClass = ICC_SERVICE_CLASS_VOICE |
-                             ICC_SERVICE_CLASS_DATA  |
-                             ICC_SERVICE_CLASS_FAX;
-      this.setICCFacilityLock(options);
-    }
-  },
-
-  /**
    * Change the current ICC PIN number.
    *
-   * @param pin
+   * @param password
    *        String containing the old PIN value
-   * @param newPin
+   * @param newPassword
    *        String containing the new PIN value
    * @param [optional] aid
    *        AID value.
    */
   changeICCPIN: function(options) {
     let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_CHANGE_SIM_PIN, options);
     Buf.writeInt32(this.v5Legacy ? 2 : 3);
-    Buf.writeString(options.pin);
-    Buf.writeString(options.newPin);
+    Buf.writeString(options.password);
+    Buf.writeString(options.newPassword);
     if (!this.v5Legacy) {
       Buf.writeString(options.aid || this.aid);
     }
     Buf.sendParcel();
   },
 
   /**
    * Change the current ICC PIN2 number.
    *
-   * @param pin
+   * @param password
    *        String containing the old PIN2 value
-   * @param newPin
+   * @param newPassword
    *        String containing the new PIN2 value
    * @param [optional] aid
    *        AID value.
    */
   changeICCPIN2: function(options) {
     let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_CHANGE_SIM_PIN2, options);
     Buf.writeInt32(this.v5Legacy ? 2 : 3);
-    Buf.writeString(options.pin);
-    Buf.writeString(options.newPin);
+    Buf.writeString(options.password);
+    Buf.writeString(options.newPassword);
     if (!this.v5Legacy) {
       Buf.writeString(options.aid || this.aid);
     }
     Buf.sendParcel();
   },
+
   /**
    * Supplies ICC PUK and a new PIN to unlock the ICC.
    *
-   * @param puk
+   * @param password
    *        String containing the PUK value.
-   * @param newPin
+   * @param newPassword
    *        String containing the new PIN value.
    * @param [optional] aid
    *        AID value.
    */
    enterICCPUK: function(options) {
      let Buf = this.context.Buf;
      Buf.newParcel(REQUEST_ENTER_SIM_PUK, options);
      Buf.writeInt32(this.v5Legacy ? 2 : 3);
-     Buf.writeString(options.puk);
+     Buf.writeString(options.password);
      Buf.writeString(options.newPin);
      if (!this.v5Legacy) {
        Buf.writeString(options.aid || this.aid);
      }
      Buf.sendParcel();
    },
 
   /**
    * Supplies ICC PUK2 and a new PIN2 to unlock the ICC.
    *
-   * @param puk
+   * @param password
    *        String containing the PUK2 value.
-   * @param newPin
+   * @param newPassword
    *        String containing the new PIN2 value.
    * @param [optional] aid
    *        AID value.
    */
    enterICCPUK2: function(options) {
      let Buf = this.context.Buf;
      Buf.newParcel(REQUEST_ENTER_SIM_PUK2, options);
      Buf.writeInt32(this.v5Legacy ? 2 : 3);
-     Buf.writeString(options.puk);
+     Buf.writeString(options.password);
      Buf.writeString(options.newPin);
      if (!this.v5Legacy) {
        Buf.writeString(options.aid || this.aid);
      }
      Buf.sendParcel();
    },
 
   /**
-   * Helper function for fetching the state of ICC locks.
-   */
-  iccGetCardLockState: function(options) {
+   * Helper function for changing ICC locks.
+   */
+  iccChangeCardLockPassword: function(options) {
     switch (options.lockType) {
       case GECKO_CARDLOCK_PIN:
-        options.facility = ICC_CB_FACILITY_SIM;
-        break;
+        this.changeICCPIN(options);
+        break;
+      case GECKO_CARDLOCK_PIN2:
+        this.changeICCPIN2(options);
+        break;
+      default:
+        options.errorMsg = GECKO_ERROR_REQUEST_NOT_SUPPORTED;
+        this.sendChromeMessage(options);
+    }
+  },
+
+  /**
+   * Helper function for setting the state of ICC locks.
+   */
+  iccSetCardLockEnabled: function(options) {
+    switch (options.lockType) {
+      case GECKO_CARDLOCK_PIN: // Fall through.
       case GECKO_CARDLOCK_FDN:
-        options.facility = ICC_CB_FACILITY_FDN;
+        options.facility = GECKO_CARDLOCK_TO_FACILITY[options.lockType];
         break;
       default:
-        options.errorMsg = "Unsupported Card Lock.";
-        options.success = false;
+        options.errorMsg = GECKO_ERROR_REQUEST_NOT_SUPPORTED;
+        this.sendChromeMessage(options);
+        return;
+    }
+
+    options.serviceClass = ICC_SERVICE_CLASS_VOICE |
+                           ICC_SERVICE_CLASS_DATA  |
+                           ICC_SERVICE_CLASS_FAX;
+    this.setICCFacilityLock(options);
+  },
+
+  /**
+   * Helper function for fetching the state of ICC locks.
+   */
+  iccGetCardLockEnabled: function(options) {
+    switch (options.lockType) {
+      case GECKO_CARDLOCK_PIN: // Fall through.
+      case GECKO_CARDLOCK_FDN:
+        options.facility = GECKO_CARDLOCK_TO_FACILITY[options.lockType];
+        break;
+      default:
+        options.errorMsg = GECKO_ERROR_REQUEST_NOT_SUPPORTED;
         this.sendChromeMessage(options);
         return;
     }
 
     options.password = ""; // For query no need to provide pin.
     options.serviceClass = ICC_SERVICE_CLASS_VOICE |
                            ICC_SERVICE_CLASS_DATA  |
                            ICC_SERVICE_CLASS_FAX;
@@ -849,44 +839,40 @@ RilObject.prototype = {
 
   /**
    * Helper function for fetching the number of unlock retries of ICC locks.
    *
    * We only query the retry count when we're on the emulator. The phones do
    * not support the request id and their rild doesn't return an error.
    */
   iccGetCardLockRetryCount: function(options) {
-    var selCode = {
-      pin: ICC_SEL_CODE_SIM_PIN,
-      puk: ICC_SEL_CODE_SIM_PUK,
-      pin2: ICC_SEL_CODE_SIM_PIN2,
-      puk2: ICC_SEL_CODE_SIM_PUK2,
-      nck: ICC_SEL_CODE_PH_NET_PIN,
-      cck: ICC_SEL_CODE_PH_CORP_PIN,
-      spck: ICC_SEL_CODE_PH_SP_PIN
-    };
-
-    if (typeof(selCode[options.lockType]) === 'undefined') {
-      /* unknown lock type */
-      options.errorMsg = GECKO_ERROR_GENERIC_FAILURE;
-      options.success = false;
+    if (!RILQUIRKS_HAVE_QUERY_ICC_LOCK_RETRY_COUNT) {
+      // Only the emulator supports this request.
+      options.errorMsg = GECKO_ERROR_REQUEST_NOT_SUPPORTED;
       this.sendChromeMessage(options);
       return;
     }
 
-    if (RILQUIRKS_HAVE_QUERY_ICC_LOCK_RETRY_COUNT) {
-      /* Only the emulator supports this request, ... */
-      options.selCode = selCode[options.lockType];
-      this.queryICCLockRetryCount(options);
-    } else {
-      /* ... while the phones do not. */
-      options.errorMsg = GECKO_ERROR_REQUEST_NOT_SUPPORTED;
-      options.success = false;
-      this.sendChromeMessage(options);
-    }
+    switch (options.lockType) {
+      case GECKO_CARDLOCK_PIN:
+      case GECKO_CARDLOCK_PIN2:
+      case GECKO_CARDLOCK_PUK:
+      case GECKO_CARDLOCK_PUK2:
+      case GECKO_CARDLOCK_NCK:
+      case GECKO_CARDLOCK_CCK: // Fall through.
+      case GECKO_CARDLOCK_SPCK:
+        options.selCode = GECKO_CARDLOCK_TO_SEL_CODE[options.lockType];
+        break;
+      default:
+        options.errorMsg = GECKO_ERROR_REQUEST_NOT_SUPPORTED;
+        this.sendChromeMessage(options);
+        return;
+    }
+
+    this.queryICCLockRetryCount(options);
   },
 
   /**
    * Query ICC lock retry count.
    *
    * @param selCode
    *        One of ICC_SEL_CODE_*.
    * @param serviceClass
@@ -2468,62 +2454,62 @@ RilObject.prototype = {
         // As defined in TS.122.030 6.6.2 to change the ICC PIN we should expect
         // an MMI code of the form **04*OLD_PIN*NEW_PIN*NEW_PIN#, where old PIN
         // should be entered as the SIA parameter and the new PIN as SIB and
         // SIC.
         if (!_isRadioAvailable() || !_isValidPINPUKRequest()) {
           return;
         }
 
-        options.pin = mmi.sia;
-        options.newPin = mmi.sib;
+        options.password = mmi.sia;
+        options.newPassword = mmi.sib;
         this.changeICCPIN(options);
         return;
 
       // Change the current ICC PIN2 number.
       case MMI_SC_PIN2:
         // As defined in TS.122.030 6.6.2 to change the ICC PIN2 we should
         // enter and MMI code of the form **042*OLD_PIN2*NEW_PIN2*NEW_PIN2#,
         // where the old PIN2 should be entered as the SIA parameter and the
         // new PIN2 as SIB and SIC.
         if (!_isRadioAvailable() || !_isValidPINPUKRequest()) {
           return;
         }
 
-        options.pin = mmi.sia;
-        options.newPin = mmi.sib;
+        options.password = mmi.sia;
+        options.newPassword = mmi.sib;
         this.changeICCPIN2(options);
         return;
 
       // Unblock ICC PIN.
       case MMI_SC_PUK:
         // As defined in TS.122.030 6.6.3 to unblock the ICC PIN we should
         // enter an MMI code of the form **05*PUK*NEW_PIN*NEW_PIN#, where PUK
         // should be entered as the SIA parameter and the new PIN as SIB and
         // SIC.
         if (!_isRadioAvailable() || !_isValidPINPUKRequest()) {
           return;
         }
 
-        options.puk = mmi.sia;
+        options.password = mmi.sia;
         options.newPin = mmi.sib;
         this.enterICCPUK(options);
         return;
 
       // Unblock ICC PIN2.
       case MMI_SC_PUK2:
         // As defined in TS.122.030 6.6.3 to unblock the ICC PIN2 we should
         // enter an MMI code of the form **052*PUK2*NEW_PIN2*NEW_PIN2#, where
         // PUK2 should be entered as the SIA parameter and the new PIN2 as SIB
         // and SIC.
         if (!_isRadioAvailable() || !_isValidPINPUKRequest()) {
           return;
         }
 
-        options.puk = mmi.sia;
+        options.password = mmi.sia;
         options.newPin = mmi.sib;
         this.enterICCPUK2(options);
         return;
 
       // IMEI
       case MMI_SC_IMEI:
         // A device's IMEI can't change, so we only need to request it once.
         if (this.IMEI == null) {
--- a/dom/system/gonk/tests/test_ril_worker_icc_CardLock.js
+++ b/dom/system/gonk/tests/test_ril_worker_icc_CardLock.js
@@ -1,56 +1,58 @@
 /* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
 
 function run_test() {
   run_next_test();
 }
 
 /**
- * Verify RIL.iccGetCardLockState("fdn")
+ * Verify RIL.iccGetCardLockEnabled
  */
-add_test(function test_icc_get_card_lock_state_fdn() {
+add_test(function test_icc_get_card_lock_enabled() {
   let worker = newUint8Worker();
   let context = worker.ContextPool._contexts[0];
+  let buf = context.Buf;
   let ril = context.RIL;
-  let buf = context.Buf;
-
-  buf.sendParcel = function() {
-    // Request Type.
-    do_check_eq(this.readInt32(), REQUEST_QUERY_FACILITY_LOCK)
+  ril.aid = "123456789";
+  ril.v5Legacy = false;
 
-    // Token : we don't care.
-    this.readInt32();
+  function do_test(aLock) {
+    const serviceClass = ICC_SERVICE_CLASS_VOICE |
+                         ICC_SERVICE_CLASS_DATA  |
+                         ICC_SERVICE_CLASS_FAX;
 
-    // String Array Length.
-    do_check_eq(this.readInt32(), ril.v5Legacy ? 3 : 4);
+    buf.sendParcel = function fakeSendParcel() {
+      // Request Type.
+      do_check_eq(this.readInt32(), REQUEST_QUERY_FACILITY_LOCK)
 
-    // Facility.
-    do_check_eq(this.readString(), ICC_CB_FACILITY_FDN);
+      // Token : we don't care.
+      this.readInt32();
 
-    // Password.
-    do_check_eq(this.readString(), "");
-
-    // Service class.
-    do_check_eq(this.readString(), (ICC_SERVICE_CLASS_VOICE |
-                                    ICC_SERVICE_CLASS_DATA  |
-                                    ICC_SERVICE_CLASS_FAX).toString());
+      // Data
+      let parcel = this.readStringList();
+      do_check_eq(parcel.length, ril.v5Legacy ? 3 : 4);
+      do_check_eq(parcel[0], GECKO_CARDLOCK_TO_FACILITY[aLock]);
+      do_check_eq(parcel[1], "");
+      do_check_eq(parcel[2], serviceClass.toString());
+      if (!ril.v5Legacy) {
+        do_check_eq(parcel[3], ril.aid);
+      }
+    };
 
-    if (!ril.v5Legacy) {
-      // AID. Ignore because it's from modem.
-      this.readInt32();
-    }
+    ril.iccGetCardLockEnabled({lockType: aLock});
+  }
 
-    run_next_test();
-  };
+  do_test(GECKO_CARDLOCK_PIN)
+  do_test(GECKO_CARDLOCK_FDN)
 
-  ril.iccGetCardLockState({lockType: "fdn"});
+  run_next_test();
 });
 
 add_test(function test_path_id_for_spid_and_spn() {
   let worker = newWorker({
     postRILMessage: function(data) {
       // Do nothing
     },
     postMessage: function(message) {
@@ -72,138 +74,237 @@ add_test(function test_path_id_for_spid_
   do_check_eq(ICCFileHelper.getEFPath(ICC_EF_SPDI),
               EF_PATH_MF_SIM + EF_PATH_ADF_USIM);
   do_check_eq(ICCFileHelper.getEFPath(ICC_EF_SPDI),
               EF_PATH_MF_SIM + EF_PATH_ADF_USIM);
   run_next_test();
 });
 
 /**
- * Verify iccSetCardLock - Facility Lock.
+ * Verify RIL.iccSetCardLockEnabled
  */
-add_test(function test_set_icc_card_lock_facility_lock() {
+add_test(function test_icc_set_card_lock_enabled() {
   let worker = newUint8Worker();
   let context = worker.ContextPool._contexts[0];
-  let aid = "123456789";
+  let buf = context.Buf;
   let ril = context.RIL;
-  ril.aid = aid;
+  ril.aid = "123456789";
   ril.v5Legacy = false;
-  let buf = context.Buf;
-
-  let GECKO_CARDLOCK_TO_FACILITIY_LOCK = {};
-  GECKO_CARDLOCK_TO_FACILITIY_LOCK[GECKO_CARDLOCK_PIN] = ICC_CB_FACILITY_SIM;
-  GECKO_CARDLOCK_TO_FACILITIY_LOCK[GECKO_CARDLOCK_FDN] = ICC_CB_FACILITY_FDN;
-
-  let GECKO_CARDLOCK_TO_PASSWORD_TYPE = {};
-  GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_PIN] = "pin";
-  GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_FDN] = "pin2";
-
-  const pin = "1234";
-  const pin2 = "4321";
-  let GECKO_CARDLOCK_TO_PASSWORD = {};
-  GECKO_CARDLOCK_TO_PASSWORD[GECKO_CARDLOCK_PIN] = pin;
-  GECKO_CARDLOCK_TO_PASSWORD[GECKO_CARDLOCK_FDN] = pin2;
-
-  const serviceClass = ICC_SERVICE_CLASS_VOICE |
-                       ICC_SERVICE_CLASS_DATA  |
-                       ICC_SERVICE_CLASS_FAX;
 
   function do_test(aLock, aPassword, aEnabled) {
-    buf.sendParcel = function fakeSendParcel () {
+    const serviceClass = ICC_SERVICE_CLASS_VOICE |
+                         ICC_SERVICE_CLASS_DATA  |
+                         ICC_SERVICE_CLASS_FAX;
+
+    buf.sendParcel = function fakeSendParcel() {
       // Request Type.
       do_check_eq(this.readInt32(), REQUEST_SET_FACILITY_LOCK);
 
       // Token : we don't care
       this.readInt32();
 
+      // Data
       let parcel = this.readStringList();
-      do_check_eq(parcel.length, 5);
-      do_check_eq(parcel[0], GECKO_CARDLOCK_TO_FACILITIY_LOCK[aLock]);
+      do_check_eq(parcel.length, ril.v5Legacy ? 4 : 5);
+      do_check_eq(parcel[0], GECKO_CARDLOCK_TO_FACILITY[aLock]);
       do_check_eq(parcel[1], aEnabled ? "1" : "0");
-      do_check_eq(parcel[2], GECKO_CARDLOCK_TO_PASSWORD[aLock]);
+      do_check_eq(parcel[2], aPassword);
       do_check_eq(parcel[3], serviceClass.toString());
-      do_check_eq(parcel[4], aid);
+      if (!ril.v5Legacy) {
+        do_check_eq(parcel[4], ril.aid);
+      }
     };
 
-    let lock = {lockType: aLock,
-                enabled: aEnabled};
-    lock[GECKO_CARDLOCK_TO_PASSWORD_TYPE[aLock]] = aPassword;
-
-    ril.iccSetCardLock(lock);
+    ril.iccSetCardLockEnabled({
+      lockType: aLock,
+      enabled: aEnabled,
+      password: aPassword});
   }
 
-  do_test(GECKO_CARDLOCK_PIN, pin, true);
-  do_test(GECKO_CARDLOCK_PIN, pin, false);
-  do_test(GECKO_CARDLOCK_FDN, pin2, true);
-  do_test(GECKO_CARDLOCK_FDN, pin2, false);
+  do_test(GECKO_CARDLOCK_PIN, "1234", true);
+  do_test(GECKO_CARDLOCK_PIN, "1234", false);
+  do_test(GECKO_CARDLOCK_FDN, "4321", true);
+  do_test(GECKO_CARDLOCK_FDN, "4321", false);
+
+  run_next_test();
+});
+
+/**
+ * Verify RIL.iccChangeCardLockPassword
+ */
+add_test(function test_icc_change_card_lock_password() {
+  let worker = newUint8Worker();
+  let context = worker.ContextPool._contexts[0];
+  let buf = context.Buf;
+  let ril = context.RIL;
+
+
+  function do_test(aLock, aPassword, aNewPassword) {
+    let GECKO_CARDLOCK_TO_REQUEST = {};
+    GECKO_CARDLOCK_TO_REQUEST[GECKO_CARDLOCK_PIN] = REQUEST_CHANGE_SIM_PIN;
+    GECKO_CARDLOCK_TO_REQUEST[GECKO_CARDLOCK_PIN2] = REQUEST_CHANGE_SIM_PIN2;
+
+    buf.sendParcel = function fakeSendParcel() {
+      // Request Type.
+      do_check_eq(this.readInt32(), GECKO_CARDLOCK_TO_REQUEST[aLock]);
+
+      // Token : we don't care
+      this.readInt32();
+
+      // Data
+      let parcel = this.readStringList();
+      do_check_eq(parcel.length, ril.v5Legacy ? 2 : 3);
+      do_check_eq(parcel[0], aPassword);
+      do_check_eq(parcel[1], aNewPassword);
+      if (!ril.v5Legacy) {
+        do_check_eq(parcel[2], ril.aid);
+      }
+    };
+
+    ril.iccChangeCardLockPassword({
+      lockType: aLock,
+      password: aPassword,
+      newPassword: aNewPassword});
+  }
+
+  do_test(GECKO_CARDLOCK_PIN, "1234", "4321");
+  do_test(GECKO_CARDLOCK_PIN2, "1234", "4321");
 
   run_next_test();
 });
 
 /**
- * Verify iccUnlockCardLock.
+ * Verify RIL.iccUnlockCardLock - PIN
  */
-add_test(function test_unlock_card_lock_corporateLocked() {
+add_test(function test_icc_unlock_card_lock_pin() {
   let worker = newUint8Worker();
   let context = worker.ContextPool._contexts[0];
   let ril = context.RIL;
   let buf = context.Buf;
-  const pin = "12345678";
-  const puk = "12345678";
-
-  let GECKO_CARDLOCK_TO_PASSWORD_TYPE = {};
-  GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_NCK] = "pin";
-  GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_NCK1] = "pin";
-  GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_NCK2] = "pin";
-  GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_HNCK] = "pin";
-  GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_CCK] = "pin";
-  GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_SPCK] = "pin";
-  GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_RCCK] = "pin";
-  GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_RSPCK] = "pin";
-  GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_NCK_PUK] = "puk";
-  GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_NCK1_PUK] = "puk";
-  GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_NCK2_PUK] = "puk";
-  GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_HNCK_PUK] = "puk";
-  GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_CCK_PUK] = "puk";
-  GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_SPCK_PUK] = "puk";
-  GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_RCCK_PUK] = "puk";
-  GECKO_CARDLOCK_TO_PASSWORD_TYPE[GECKO_CARDLOCK_RSPCK_PUK] = "puk";
+  ril.aid = "123456789";
+  ril.v5Legacy = false;
 
   function do_test(aLock, aPassword) {
-    buf.sendParcel = function fakeSendParcel () {
+    let GECKO_CARDLOCK_TO_REQUEST = {};
+    GECKO_CARDLOCK_TO_REQUEST[GECKO_CARDLOCK_PIN] = REQUEST_ENTER_SIM_PIN;
+    GECKO_CARDLOCK_TO_REQUEST[GECKO_CARDLOCK_PIN2] = REQUEST_ENTER_SIM_PIN2;
+
+    buf.sendParcel = function fakeSendParcel() {
+      // Request Type.
+      do_check_eq(this.readInt32(), GECKO_CARDLOCK_TO_REQUEST[aLock]);
+
+      // Token : we don't care
+      this.readInt32();
+
+      // Data
+      let parcel = this.readStringList();
+      do_check_eq(parcel.length, ril.v5Legacy ? 1 : 2);
+      do_check_eq(parcel[0], aPassword);
+      if (!ril.v5Legacy) {
+        do_check_eq(parcel[1], ril.aid);
+      }
+    };
+
+    ril.iccUnlockCardLock({
+      lockType: aLock,
+      password: aPassword
+    });
+  }
+
+  do_test(GECKO_CARDLOCK_PIN, "1234");
+  do_test(GECKO_CARDLOCK_PIN2, "1234");
+
+  run_next_test();
+});
+
+/**
+ * Verify RIL.iccUnlockCardLock - PUK
+ */
+add_test(function test_icc_unlock_card_lock_puk() {
+  let worker = newUint8Worker();
+  let context = worker.ContextPool._contexts[0];
+  let ril = context.RIL;
+  let buf = context.Buf;
+  ril.aid = "123456789";
+  ril.v5Legacy = false;
+
+  function do_test(aLock, aPassword, aNewPin) {
+    let GECKO_CARDLOCK_TO_REQUEST = {};
+    GECKO_CARDLOCK_TO_REQUEST[GECKO_CARDLOCK_PUK] = REQUEST_ENTER_SIM_PUK;
+    GECKO_CARDLOCK_TO_REQUEST[GECKO_CARDLOCK_PUK2] = REQUEST_ENTER_SIM_PUK2;
+
+    buf.sendParcel = function fakeSendParcel() {
+      // Request Type.
+      do_check_eq(this.readInt32(), GECKO_CARDLOCK_TO_REQUEST[aLock]);
+
+      // Token : we don't care
+      this.readInt32();
+
+      // Data
+      let parcel = this.readStringList();
+      do_check_eq(parcel.length, ril.v5Legacy ? 2 : 3);
+      do_check_eq(parcel[0], aPassword);
+      do_check_eq(parcel[1], aNewPin);
+      if (!ril.v5Legacy) {
+        do_check_eq(parcel[2], ril.aid);
+      }
+    };
+
+    ril.iccUnlockCardLock({
+      lockType: aLock,
+      password: aPassword,
+      newPin: aNewPin
+    });
+  }
+
+  do_test(GECKO_CARDLOCK_PUK, "12345678", "1234");
+  do_test(GECKO_CARDLOCK_PUK2, "12345678", "1234");
+
+  run_next_test();
+});
+
+/**
+ * Verify RIL.iccUnlockCardLock - Depersonalization
+ */
+add_test(function test_icc_unlock_card_lock_depersonalization() {
+  let worker = newUint8Worker();
+  let context = worker.ContextPool._contexts[0];
+  let ril = context.RIL;
+  let buf = context.Buf;
+
+  function do_test(aLock, aPassword) {
+    buf.sendParcel = function fakeSendParcel() {
       // Request Type.
       do_check_eq(this.readInt32(), REQUEST_ENTER_NETWORK_DEPERSONALIZATION_CODE);
 
       // Token : we don't care
       this.readInt32();
 
-      let lockType = GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[aLock];
-      // Lock Type
-      do_check_eq(this.readInt32(), lockType);
-
-      // Pin/Puk.
+      // Data
+      do_check_eq(this.readInt32(), GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[aLock]);
       do_check_eq(this.readString(), aPassword);
     };
 
-    let lock = {lockType: aLock};
-    lock[GECKO_CARDLOCK_TO_PASSWORD_TYPE[aLock]] = aPassword;
-    ril.iccUnlockCardLock(lock);
+    ril.iccUnlockCardLock({
+      lockType: aLock,
+      password: aPassword
+    });
   }
 
-  do_test(GECKO_CARDLOCK_NCK, pin);
-  do_test(GECKO_CARDLOCK_NCK1, pin);
-  do_test(GECKO_CARDLOCK_NCK2, pin);
-  do_test(GECKO_CARDLOCK_HNCK, pin);
-  do_test(GECKO_CARDLOCK_CCK, pin);
-  do_test(GECKO_CARDLOCK_SPCK, pin);
-  do_test(GECKO_CARDLOCK_RCCK, pin);
-  do_test(GECKO_CARDLOCK_RSPCK, pin);
-  do_test(GECKO_CARDLOCK_NCK_PUK, puk);
-  do_test(GECKO_CARDLOCK_NCK1_PUK, puk);
-  do_test(GECKO_CARDLOCK_NCK2_PUK, puk);
-  do_test(GECKO_CARDLOCK_HNCK_PUK, puk);
-  do_test(GECKO_CARDLOCK_CCK_PUK, puk);
-  do_test(GECKO_CARDLOCK_SPCK_PUK, puk);
-  do_test(GECKO_CARDLOCK_RCCK_PUK, puk);
-  do_test(GECKO_CARDLOCK_RSPCK_PUK, puk);
+  do_test(GECKO_CARDLOCK_NCK, "12345678");
+  do_test(GECKO_CARDLOCK_NCK1, "12345678");
+  do_test(GECKO_CARDLOCK_NCK2, "12345678");
+  do_test(GECKO_CARDLOCK_HNCK, "12345678");
+  do_test(GECKO_CARDLOCK_CCK, "12345678");
+  do_test(GECKO_CARDLOCK_SPCK, "12345678");
+  do_test(GECKO_CARDLOCK_RCCK, "12345678");
+  do_test(GECKO_CARDLOCK_RSPCK, "12345678");
+  do_test(GECKO_CARDLOCK_NCK_PUK, "12345678");
+  do_test(GECKO_CARDLOCK_NCK1_PUK, "12345678");
+  do_test(GECKO_CARDLOCK_NCK2_PUK, "12345678");
+  do_test(GECKO_CARDLOCK_HNCK_PUK, "12345678");
+  do_test(GECKO_CARDLOCK_CCK_PUK, "12345678");
+  do_test(GECKO_CARDLOCK_SPCK_PUK, "12345678");
+  do_test(GECKO_CARDLOCK_RCCK_PUK, "12345678");
+  do_test(GECKO_CARDLOCK_RSPCK_PUK, "12345678");
 
   run_next_test();
 });
--- a/dom/telephony/test/marionette/manifest.ini
+++ b/dom/telephony/test/marionette/manifest.ini
@@ -62,11 +62,12 @@ disabled = Bug 821958
 [test_outgoing_when_two_calls_on_line.js]
 [test_call_presentation.js]
 [test_temporary_clir.js]
 [test_outgoing_error_state.js]
 [test_outgoing_auto_hold.js]
 [test_mmi.js]
 [test_mmi_change_pin.js]
 [test_mmi_call_forwarding.js]
+[test_mmi_unlock_puk.js]
 [test_incall_mmi_call_waiting.js]
 [test_incall_mmi_call_hold.js]
 [test_incall_mmi_conference.js]
new file mode 100644
--- /dev/null
+++ b/dom/telephony/test/marionette/test_mmi_unlock_puk.js
@@ -0,0 +1,157 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+MARIONETTE_TIMEOUT = 60000;
+MARIONETTE_HEAD_JS = "head.js";
+
+const DEFAULT_PIN = "0000";
+const DEFAULT_PUK = "12345678";
+
+function getMozIcc() {
+  let iccId = navigator.mozMobileConnections[0].iccId;
+  return navigator.mozIccManager.getIccById(iccId);
+}
+
+function waitForTargetEvent(aEventTarget, aEventName, aMatchFun) {
+  let deferred = Promise.defer();
+
+  aEventTarget.addEventListener(aEventName, function onevent(aEvent) {
+    if (!aMatchFun || aMatchFun(aEvent)) {
+      aEventTarget.removeEventListener(aEventName, onevent);
+      ok(true, "Event '" + aEventName + "' got.");
+      deferred.resolve(aEvent);
+    }
+  });
+
+  return deferred.promise;
+}
+
+function setRadioEnabledAndWait(aEnabled) {
+  let promises = [];
+  let connection = navigator.mozMobileConnections[0];
+
+  promises.push(waitForTargetEvent(connection, "radiostatechange", function() {
+    return connection.radioState === aEnabled ? "enabled" : "disabled";
+  }));
+  promises.push(connection.setRadioEnabled(aEnabled));
+
+  return Promise.all(promises);
+}
+
+function restartRadioAndWait(aCardState) {
+  let iccManager = navigator.mozIccManager;
+
+  return setRadioEnabledAndWait(false).then(() => {
+    let promises = [];
+
+    promises.push(waitForTargetEvent(iccManager, "iccdetected")
+      .then((aEvent) => {
+        let icc = iccManager.getIccById(aEvent.iccId);
+        if (icc.cardState !== aCardState) {
+          return waitForTargetEvent(icc, "cardstatechange", function() {
+            return icc.cardState === aCardState;
+          });
+        }
+      }));
+    promises.push(setRadioEnabledAndWait(true));
+
+    return Promise.all(promises);
+  });
+}
+
+function passingWrongPinAndWait(aIcc) {
+  return aIcc.getCardLockRetryCount("pin").then((aResult) => {
+    let promises = [];
+    let retryCount = aResult.retryCount;
+
+    ok(true, "pin retryCount is " + retryCount);
+
+    promises.push(waitForTargetEvent(aIcc, "cardstatechange", function() {
+      return aIcc.cardState === "pukRequired";
+    }));
+
+    for (let i = 0; i < retryCount; i++) {
+      promises.push(aIcc.unlockCardLock({ lockType: "pin", pin: "1111" })
+        .then(() => {
+          ok(false, "unlocking pin should not success");
+        }, (aError) => {
+          ok(true, "pin retryCount = " + aError.retryCount);
+        }));
+    }
+
+    return Promise.all(promises);
+  });
+}
+
+function sendUnlockPukMmi(aPuk, aNewPin, aNewPinAgain) {
+  let MMI_CODE = "**05*" + aPuk + "*" + aNewPin + "*" + aNewPinAgain + "#";
+  log("Test " + MMI_CODE);
+
+  return gSendMMI(MMI_CODE);
+}
+
+function testUnlockPukMmiError(aPuk, aNewPin, aNewPinAgain, aErrorName,
+                               aRetryCount = null) {
+  return sendUnlockPukMmi(aPuk, aNewPin, aNewPinAgain)
+    .then((aResult) => {
+      ok(!aResult.success, "check success");
+      is(aResult.serviceCode, "scPuk", "Check service code");
+      is(aResult.statusMessage, aErrorName, "Check statusMessage");
+      is(aResult.additionalInformation, aRetryCount,
+         "Check additional information");
+    });
+}
+
+function testUnlockPukAndWait(aIcc, aCardState) {
+  let promises = [];
+
+  promises.push(waitForTargetEvent(aIcc, "cardstatechange", function() {
+    return aIcc.cardState === aCardState;
+  }));
+  promises.push(sendUnlockPukMmi(DEFAULT_PUK, DEFAULT_PIN, DEFAULT_PIN));
+
+  return Promise.all(promises);
+}
+
+// Start tests
+startTestWithPermissions(['mobileconnection'], function() {
+  let icc = getMozIcc();
+  let retryCount;
+
+  // Enable PIN-lock.
+  return icc.setCardLock({lockType: "pin", enabled: true, pin: DEFAULT_PIN})
+    // Reset card state to "pinRequired" by restarting radio.
+    .then(() => restartRadioAndWait("pinRequired"))
+    .then(() => { icc = getMozIcc(); })
+    // Switch card state to "pukRequired" by entering wrong pin.
+    .then(() => passingWrongPinAndWait(icc))
+
+    // Get current PUK-lock retry count.
+    .then(() => icc.getCardLockRetryCount("puk"))
+    .then((aResult) => {
+      retryCount = aResult.retryCount;
+      ok(true, "puk retryCount is " + retryCount);
+    })
+
+    // Test passing no puk.
+    .then(() => testUnlockPukMmiError("", "1111", "2222", "emMmiError"))
+    // Test passing no newPin.
+    .then(() => testUnlockPukMmiError("11111111", "", "", "emMmiError"))
+    // Test passing mismatched newPin.
+    .then(() => testUnlockPukMmiError("11111111", "1111", "2222",
+                                      "emMmiErrorMismatchPin"))
+    // Test passing invalid puk (> 8 digit).
+    .then(() => testUnlockPukMmiError("123456789", DEFAULT_PIN, DEFAULT_PIN,
+                                      "emMmiErrorInvalidPin"))
+    // Test passing incorrect puk.
+    .then(() => testUnlockPukMmiError("11111111", DEFAULT_PIN, DEFAULT_PIN,
+                                      "emMmiErrorBadPuk", retryCount - 1))
+
+    // Test unlock PUK-lock success.
+    .then(() => testUnlockPukAndWait(icc, "ready"))
+
+    // Restore pin state.
+    .then(() => icc.setCardLock({lockType: "pin", enabled: false, pin: DEFAULT_PIN}))
+    .catch((aError) => ok(false, "Promise reject " + aError))
+    .then(finish);
+});
--- a/dom/webidl/MozIcc.webidl
+++ b/dom/webidl/MozIcc.webidl
@@ -1,13 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-enum IccCardState {
+enum IccCardState
+{
   "unknown", // ICC card state is either not yet reported from modem or in an
              // unknown state.
   "ready",
   "pinRequired",
   "pukRequired",
   "permanentBlocked",
 
   /**
@@ -44,16 +45,72 @@ enum IccCardState {
 
   /**
    * Additional States.
    */
   "illegal" // See Bug 916000. An owed pay card will be rejected by the network
             // and fall in this state.
 };
 
+enum IccLockType
+{
+  "pin",
+  "pin2",
+  "puk",
+  "puk2",
+  "nck",      // Network depersonalization -- network control key (NCK).
+  "nck1",     // Network type 1 depersonalization -- network type 1 control key (NCK1).
+  "nck2",     // Network type 2 depersonalization -- network type 2 control key (NCK2).
+  "hnck",     // HRPD network depersonalization -- HRPD network control key (HNCK).
+  "cck",      // Corporate depersonalization -- corporate control key (CCK).
+  "spck",     // Service provider depersonalization -- service provider control key (SPCK).
+  "rcck",     // RUIM corporate depersonalization -- RUIM corporate control key (RCCK).
+  "rspck",    // RUIM service provider depersonalization -- RUIM service provider control key (RSPCK).
+  "nckPuk",   // Network PUK depersonalization -- network control key (NCK).
+  "nck1Puk",  // Network type 1 PUK depersonalization -- network type 1 control key (NCK1).
+  "nck2Puk",  // Network type 2 PUK depersonalization -- Network type 2 control key (NCK2).
+  "hnckPuk",  // HRPD network PUK depersonalization -- HRPD network control key (HNCK).
+  "cckPuk",   // Corporate PUK depersonalization -- corporate control key (CCK).
+  "spckPuk",  // Service provider PUK depersonalization -- service provider control key (SPCK).
+  "rcckPuk",  // RUIM corporate PUK depersonalization -- RUIM corporate control key (RCCK).
+  "rspckPuk", // RUIM service provider PUK depersonalization -- service provider control key (SPCK).
+  "fdn"
+};
+
+dictionary IccUnlockCardLockOptions
+{
+  required IccLockType lockType;
+
+  DOMString? pin = null; // Necessary for lock types: "pin", "pin2", "nck",
+                         // "nck1", "nck2", "hnck", "cck", "spck", "rcck",
+                         // "rspck".
+
+  DOMString? puk = null; // Necessary for lock types: "puk", "puk2", "nckPuk",
+                         // "nck1Puk", "nck2Puk", "hnckPuk", "cckPuk",
+                         // "spckPuk", "rcckPuk", "rspckPuk".
+
+  DOMString? newPin = null; // Necessary for lock types: "puk", "puk2".
+};
+
+dictionary IccSetCardLockOptions
+{
+ required IccLockType lockType;
+
+ DOMString? pin = null; // Necessary for lock types: "pin", "pin2"
+
+ DOMString? pin2 = null; // Used for enabling/disabling operation.
+                         // Necessary for lock types: "fdn".
+
+ DOMString? newPin = null; // Used for changing password operation.
+                           // Necessary for lock types: "pin", "pin2"
+
+ boolean enabled; // Used for enabling/disabling operation.
+                  // Necessary for lock types: "pin", "fdn"
+};
+
 [Pref="dom.icc.enabled"]
 interface MozIcc : EventTarget
 {
   // Integrated Circuit Card Information.
 
   /**
    * Information stored in the device's ICC.
    *
@@ -154,203 +211,69 @@ interface MozIcc : EventTarget
   attribute EventHandler onstksessionend;
 
   // Integrated Circuit Card Lock interfaces.
 
   /**
    * Find out about the status of an ICC lock (e.g. the PIN lock).
    *
    * @param lockType
-   *        Identifies the lock type, e.g. "pin" for the PIN lock, "fdn" for
-   *        the FDN lock.
+   *        Identifies the lock type.
    *
    * @return a DOMRequest.
    *         The request's result will be an object containing
    *         information about the specified lock's status.
    *         e.g. {enabled: true}.
    */
   [Throws]
-  DOMRequest getCardLock(DOMString lockType);
+  DOMRequest getCardLock(IccLockType lockType);
 
   /**
    * Unlock a card lock.
    *
    * @param info
    *        An object containing the information necessary to unlock
-   *        the given lock. At a minimum, this object must have a
-   *        "lockType" attribute which specifies the type of lock, e.g.
-   *        "pin" for the PIN lock. Other attributes are dependent on
-   *        the lock type.
-   *
-   * Examples:
-   *
-   * (1) Unlocking the PIN:
-   *
-   *   unlockCardLock({lockType: "pin",
-   *                   pin: "..."});
-   *
-   * (2) Unlocking the PUK and supplying a new PIN:
-   *
-   *   unlockCardLock({lockType: "puk",
-   *                   puk: "...",
-   *                   newPin: "..."});
-   *
-   * (3) Network depersonalization. Unlocking the network control key (NCK).
-   *
-   *   unlockCardLock({lockType: "nck",
-   *                   pin: "..."});
-   *
-   * (4) Network type 1 depersonalization. Unlocking the network type 1 control
-   *     key (NCK1).
-   *
-   *   unlockCardLock({lockType: "nck1",
-   *                   pin: "..."});
-   *
-   * (5) Network type 2 depersonalization. Unlocking the network type 2 control
-   *     key (NCK2).
-   *
-   *   unlockCardLock({lockType: "nck2",
-   *                   pin: "..."});
-   *
-   * (6) HRPD network depersonalization. Unlocking the HRPD network control key
-   *     (HNCK).
-   *
-   *   unlockCardLock({lockType: "hnck",
-   *                   pin: "..."});
-   *
-   * (7) Corporate depersonalization. Unlocking the corporate control key (CCK).
-   *
-   *   unlockCardLock({lockType: "cck",
-   *                   pin: "..."});
-   *
-   * (8) Service provider depersonalization. Unlocking the service provider
-   *     control key (SPCK).
-   *
-   *   unlockCardLock({lockType: "spck",
-   *                   pin: "..."});
-   *
-   * (9) RUIM corporate depersonalization. Unlocking the RUIM corporate control
-   *     key (RCCK).
-   *
-   *   unlockCardLock({lockType: "rcck",
-   *                   pin: "..."});
-   *
-   * (10) RUIM service provider depersonalization. Unlocking the RUIM service
-   *      provider control key (RSPCK).
-   *
-   *   unlockCardLock({lockType: "rspck",
-   *                   pin: "..."});
-   *
-   * (11) Network PUK depersonalization. Unlocking the network control key (NCK).
-   *
-   *   unlockCardLock({lockType: "nckPuk",
-   *                   puk: "..."});
-   *
-   * (12) Network type 1 PUK depersonalization. Unlocking the network type 1
-   *      control key (NCK1).
-   *
-   *   unlockCardLock({lockType: "nck1Puk",
-   *                   puk: "..."});
-   *
-   * (13) Network type 2 PUK depersonalization. Unlocking the Network type 2
-   *      control key (NCK2).
-   *
-   *   unlockCardLock({lockType: "nck2Puk",
-   *                   puk: "..."});
-   *
-   * (14) HRPD network PUK depersonalization. Unlocking the HRPD network control
-   *      key (HNCK).
-   *
-   *   unlockCardLock({lockType: "hnckPuk",
-   *                   puk: "..."});
-   *
-   * (15) Corporate PUK depersonalization. Unlocking the corporate control key
-   *      (CCK).
-   *
-   *   unlockCardLock({lockType: "cckPuk",
-   *                   puk: "..."});
-   *
-   * (16) Service provider PUK depersonalization. Unlocking the service provider
-   *      control key (SPCK).
-   *
-   *   unlockCardLock({lockType: "spckPuk",
-   *                   puk: "..."});
-   *
-   * (17) RUIM corporate PUK depersonalization. Unlocking the RUIM corporate
-   *      control key (RCCK).
-   *
-   *   unlockCardLock({lockType: "rcckPuk",
-   *                   puk: "..."});
-   *
-   * (18) RUIM service provider PUK depersonalization. Unlocking the service
-   *      provider control key (SPCK).
-   *
-   *   unlockCardLock({lockType: "rspckPuk",
-   *                   puk: "..."});
+   *        the given lock.
    *
    * @return a DOMRequest.
    *         The request's error will be an object containing the number of
    *         remaining retries
    *         @see IccCardLockError.
    */
   [Throws]
-  DOMRequest unlockCardLock(any info);
+  DOMRequest unlockCardLock(optional IccUnlockCardLockOptions info);
 
   /**
    * Modify the state of a card lock.
    *
    * @param info
    *        An object containing information about the lock and
-   *        how to modify its state. At a minimum, this object
-   *        must have a "lockType" attribute which specifies the
-   *        type of lock, e.g. "pin" for the PIN lock. Other
-   *        attributes are dependent on the lock type.
-   *
-   * Examples:
-   *
-   * (1a) Disabling the PIN lock:
-   *
-   *   setCardLock({lockType: "pin",
-   *                pin: "...",
-   *                enabled: false});
-   *
-   * (1b) Disabling the FDN lock:
-   *
-   *   setCardLock({lockType: "fdn",
-   *                pin2: "...",
-   *                enabled: false});
-   *
-   * (2) Changing the PIN:
-   *
-   *   setCardLock({lockType: "pin",
-   *                pin: "...",
-   *                newPin: "..."});
+   *        how to modify its state.
    *
    * @return a DOMRequest.
    *         The request's error will be an object containing the number of
    *         remaining retries.
    *         @see IccCardLockError.
    */
   [Throws]
-  DOMRequest setCardLock(any info);
+  DOMRequest setCardLock(optional IccSetCardLockOptions info);
 
   /**
    * Retrieve the number of remaining tries for unlocking the card.
    *
    * @param lockType
-   *        Identifies the lock type, e.g. "pin" for the PIN lock, "puk" for
-   *        the PUK lock.
+   *        Identifies the lock type.
    *
    * @return a DOMRequest.
    *         The request's result will be an object containing the number of
    *         remaining retries.
    *         e.g. {retryCount: 3}.
    */
   [Throws]
-  DOMRequest getCardLockRetryCount(DOMString lockType);
+  DOMRequest getCardLockRetryCount(IccLockType lockType);
 
   // Integrated Circuit Card Phonebook Interfaces.
 
   /**
    * Read ICC contacts.
    *
    * @param contactType
    *        One of type as below,
--- a/gfx/layers/apz/util/ActiveElementManager.cpp
+++ b/gfx/layers/apz/util/ActiveElementManager.cpp
@@ -1,37 +1,37 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ActiveElementManager.h"
+#include "mozilla/EventStateManager.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/Preferences.h"
-#include "mozilla/Services.h"
-#include "inIDOMUtils.h"
 #include "base/message_loop.h"
 #include "base/task.h"
 #include "mozilla/dom/Element.h"
 #include "nsIDocument.h"
+#include "nsStyleSet.h"
 
 #define AEM_LOG(...)
 // #define AEM_LOG(...) printf_stderr("AEM: " __VA_ARGS__)
 
 namespace mozilla {
 namespace layers {
 
 static int32_t sActivationDelayMs = 100;
 static bool sActivationDelayMsSet = false;
 
 ActiveElementManager::ActiveElementManager()
-  : mDomUtils(services::GetInDOMUtils()),
-    mCanBePan(false),
+  : mCanBePan(false),
     mCanBePanSet(false),
-    mSetActiveTask(nullptr)
+    mSetActiveTask(nullptr),
+    mActiveElementUsesStyle(false)
 {
   if (!sActivationDelayMsSet) {
     Preferences::AddIntVarCache(&sActivationDelayMs,
                                 "ui.touch_activation.delay_ms",
                                 sActivationDelayMs);
     sActivationDelayMsSet = true;
   }
 }
@@ -124,23 +124,61 @@ ActiveElementManager::HandleTouchEnd(boo
     // so we set the element active right away. Now it turns out the
     // action was not a click so we need to reset the active element.
     ResetActive();
   }
 
   ResetTouchBlockState();
 }
 
+bool
+ActiveElementManager::ActiveElementUsesStyle() const
+{
+  return mActiveElementUsesStyle;
+}
+
+static nsPresContext*
+GetPresContextFor(nsIContent* aContent)
+{
+  if (!aContent) {
+    return nullptr;
+  }
+  nsIPresShell* shell = aContent->OwnerDoc()->GetShell();
+  if (!shell) {
+    return nullptr;
+  }
+  return shell->GetPresContext();
+}
+
+static bool
+ElementHasActiveStyle(dom::Element* aElement)
+{
+  nsPresContext* pc = GetPresContextFor(aElement);
+  if (!pc) {
+    return false;
+  }
+  nsStyleSet* styleSet = pc->StyleSet();
+  for (dom::Element* e = aElement; e; e = e->GetParentElement()) {
+    if (styleSet->HasStateDependentStyle(pc, e, NS_EVENT_STATE_ACTIVE)) {
+      AEM_LOG("Element %p's style is dependent on the active state\n", e);
+      return true;
+    }
+  }
+  AEM_LOG("Element %p doesn't use active styles\n", aElement);
+  return false;
+}
+
 void
 ActiveElementManager::SetActive(dom::Element* aTarget)
 {
   AEM_LOG("Setting active %p\n", aTarget);
-  if (mDomUtils) {
-    nsCOMPtr<nsIDOMElement> target = do_QueryInterface(aTarget);
-    mDomUtils->SetContentState(target, NS_EVENT_STATE_ACTIVE.GetInternalValue());
+
+  if (nsPresContext* pc = GetPresContextFor(aTarget)) {
+    pc->EventStateManager()->SetContentState(aTarget, NS_EVENT_STATE_ACTIVE);
+    mActiveElementUsesStyle = ElementHasActiveStyle(aTarget);
   }
 }
 
 void
 ActiveElementManager::ResetActive()
 {
   AEM_LOG("Resetting active from %p\n", mTarget.get());
 
--- a/gfx/layers/apz/util/ActiveElementManager.h
+++ b/gfx/layers/apz/util/ActiveElementManager.h
@@ -48,18 +48,23 @@ public:
    * Handle the start of panning.
    */
   void HandlePanStart();
   /**
    * Handle a touch-end or touch-cancel event.
    * @param aWasClick whether the touch was a click
    */
   void HandleTouchEnd(bool aWasClick);
+  /**
+   * @return true iff the currently active element (or one of its ancestors)
+   * actually had a style for the :active pseudo-class. The currently active
+   * element is the root element if no other elements are active.
+   */
+  bool ActiveElementUsesStyle() const;
 private:
-  nsCOMPtr<inIDOMUtils> mDomUtils;
   /**
    * The target of the first touch point in the current touch block.
    */
   nsCOMPtr<dom::Element> mTarget;
   /**
    * Whether the current touch block can be a pan. Set in HandleTouchStart().
    */
   bool mCanBePan;
@@ -68,16 +73,20 @@ private:
    * We need to keep track of this to allow HandleTouchStart() and
    * SetTargetElement() to be called in either order.
    */
   bool mCanBePanSet;
   /**
    * A task for calling SetActive() after a timeout.
    */
   CancelableTask* mSetActiveTask;
+  /**
+   * See ActiveElementUsesStyle() documentation.
+   */
+  bool mActiveElementUsesStyle;
 
   // Helpers
   void TriggerElementActivation();
   void SetActive(dom::Element* aTarget);
   void ResetActive();
   void ResetTouchBlockState();
   void SetActiveTask(dom::Element* aTarget);
   void CancelTask();
--- a/gfx/tests/gtest/TestRegion.cpp
+++ b/gfx/tests/gtest/TestRegion.cpp
@@ -365,51 +365,51 @@ TEST(Gfx, RegionContains)
 #define REGION_VALUE 0xff
 
 struct RegionBitmap {
   RegionBitmap(unsigned char *bitmap, int width, int height) : bitmap(bitmap), width(width), height(height) {}
 
   void clear() {
     for (int y = 0; y < height; y++) {
       for (int x = 0; x < width; x++) {
-	bitmap[x + y * width] = 0;
+        bitmap[x + y * width] = 0;
       }
     }
   }
 
   void set(nsRegion &region) {
     clear();
     nsRegionRectIterator iter(region);
     for (const nsRect* r = iter.Next(); r; r = iter.Next()) {
       for (int y = r->y; y < r->YMost(); y++) {
         for (int x = r->x; x < r->XMost(); x++) {
-	  bitmap[x + y * width] = REGION_VALUE;
-	}
+          bitmap[x + y * width] = REGION_VALUE;
+        }
       }
     }
   }
 
   void dilate() {
     for (int y = 0; y < height; y++) {
       for (int x = 0; x < width; x++) {
-	if (bitmap[x + y * width] == REGION_VALUE) {
-	  for (int yn = max(y - 1, 0); yn <= min(y + 1, height - 1); yn++) {
-	    for (int xn = max(x - 1, 0); xn <= min(x + 1, width - 1); xn++) {
-	      if (bitmap[xn + yn * width] == 0)
-		bitmap[xn + yn * width] = DILATE_VALUE;
-	    }
-	  }
-	}
+        if (bitmap[x + y * width] == REGION_VALUE) {
+          for (int yn = max(y - 1, 0); yn <= min(y + 1, height - 1); yn++) {
+            for (int xn = max(x - 1, 0); xn <= min(x + 1, width - 1); xn++) {
+              if (bitmap[xn + yn * width] == 0)
+                bitmap[xn + yn * width] = DILATE_VALUE;
+            }
+          }
+        }
       }
     }
   }
   void compare(RegionBitmap &reference) {
     for (int y = 0; y < height; y++) {
       for (int x = 0; x < width; x++) {
-	EXPECT_EQ(bitmap[x + y * width], reference.bitmap[x + y * width]);
+        EXPECT_EQ(bitmap[x + y * width], reference.bitmap[x + y * width]);
       }
     }
   }
 
   unsigned char *bitmap;
   int width;
   int height;
 };
--- a/xpcom/glue/nsCRTGlue.cpp
+++ b/xpcom/glue/nsCRTGlue.cpp
@@ -16,16 +16,17 @@
 
 #ifdef XP_WIN
 #include <io.h>
 #include <windows.h>
 #endif
 
 #ifdef ANDROID
 #include <android/log.h>
+#include <unistd.h>
 #endif
 
 const char*
 NS_strspnp(const char* aDelims, const char* aStr)
 {
   const char* d;
   do {
     for (d = aDelims; *d != '\0'; ++d) {
@@ -288,16 +289,39 @@ NS_MakeRandomString(char* aBuf, int32_t 
 static StderrCallback sStderrCallback = nullptr;
 
 void
 set_stderr_callback(StderrCallback aCallback)
 {
   sStderrCallback = aCallback;
 }
 
+#if defined(ANDROID) && !defined(RELEASE_BUILD)
+static FILE* sStderrCopy = nullptr;
+
+void
+stderr_to_file(const char* aFmt, va_list aArgs)
+{
+  vfprintf(sStderrCopy, aFmt, aArgs);
+}
+
+void
+copy_stderr_to_file(const char* aFile)
+{
+  if (sStderrCopy) {
+    return;
+  }
+  char* buf = (char*)malloc(strlen(aFile) + 16);
+  sprintf(buf, "%s.%u", aFile, (uint32_t)getpid());
+  sStderrCopy = fopen(buf, "w");
+  free(buf);
+  set_stderr_callback(stderr_to_file);
+}
+#endif
+
 #ifdef HAVE_VA_COPY
 #define VARARGS_ASSIGN(foo, bar)        VA_COPY(foo,bar)
 #elif defined(HAVE_VA_LIST_AS_ARRAY)
 #define VARARGS_ASSIGN(foo, bar)     foo[0] = bar[0]
 #else
 #define VARARGS_ASSIGN(foo, bar)     (foo) = (bar)
 #endif
 
--- a/xpcom/glue/nsDebug.h
+++ b/xpcom/glue/nsDebug.h
@@ -435,13 +435,40 @@ void vprintf_stderr(const char* aFmt, va
  * (Producing multiple lines at once is fine.)
  */
 void fprintf_stderr(FILE* aFile, const char* aFmt, ...) MOZ_FORMAT_PRINTF(2, 3);
 
 // used by the profiler to log stderr in the profiler for more
 // advanced performance debugging and display/layers visualization.
 void set_stderr_callback(StderrCallback aCallback);
 
+#if defined(ANDROID) && !defined(RELEASE_BUILD)
+// Call this if you want a copy of stderr logging sent to a file. This is
+// useful to get around logcat overflow problems on android devices, which use
+// a circular logcat buffer and can intermittently drop messages if there's too
+// much spew.
+//
+// This is intended for local debugging only, DO NOT USE IN PRODUCTION CODE.
+// (This is ifndef RELEASE_BUILD to catch uses of it that accidentally get
+// checked in). Using this will also prevent the profiler from getting a copy of
+// the stderr messages which it uses for various visualization features.
+//
+// This function can be called from any thread, but if it is called multiple
+// times all invocations must be on the same thread. Invocations after the
+// first one are ignored, so you can safely put it inside a loop, for example.
+// Once this is called there is no way to turn it off; all stderr output from
+// that point forward will go to the file. Note that the output is subject to
+// buffering so make sure you have enough output to flush the messages you care
+// about before you terminate the process.
+//
+// The file passed in should be writable, so on Android devices a path like
+// "/data/local/tmp/blah" is a good one to use as it is world-writable and will
+// work even in B2G child processes which have reduced privileges. Note that the
+// actual file created will have the PID appended to the path you pass in, so
+// that on B2G the output from each process goes to a separate file.
+void copy_stderr_to_file(const char* aFile);
+#endif
+
 #ifdef __cplusplus
 }
 #endif
 
 #endif /* nsDebug_h___ */