--- 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 ®ion) {
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___ */