author | Wes Kocher <wkocher@mozilla.com> |
Mon, 23 Jun 2014 18:55:45 -0700 | |
changeset 190252 | e86b84998b186642cb162adb265af423f7f4555a |
parent 190185 | fa6a7a2f476c7dddd2d3dfc218512cd3ca187acb (current diff) |
parent 190251 | 9130ef564653c2a496df65022bdfed2cfd77fd37 (diff) |
child 190378 | 40dee680339e53ea4a993e1edd939568b77665ad |
child 190434 | 6ff5173e1a859b094a8bdc62b5a31da3c852a364 |
child 190471 | cc4602e0c1d89622c7be5da0555c42f323ae43e4 |
push id | 27003 |
push user | kwierso@gmail.com |
push date | Tue, 24 Jun 2014 01:56:11 +0000 |
treeherder | mozilla-central@e86b84998b18 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | merge |
milestone | 33.0a1 |
first release with | nightly linux32
e86b84998b18
/
33.0a1
/
20140624030200
/
files
nightly linux64
e86b84998b18
/
33.0a1
/
20140624030200
/
files
nightly mac
e86b84998b18
/
33.0a1
/
20140624030200
/
files
nightly win32
e86b84998b18
/
33.0a1
/
20140624030200
/
files
nightly win64
e86b84998b18
/
33.0a1
/
20140624030200
/
files
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
33.0a1
/
20140624030200
/
pushlog to previous
nightly linux64
33.0a1
/
20140624030200
/
pushlog to previous
nightly mac
33.0a1
/
20140624030200
/
pushlog to previous
nightly win32
33.0a1
/
20140624030200
/
pushlog to previous
nightly win64
33.0a1
/
20140624030200
/
pushlog to previous
|
--- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -906,19 +906,16 @@ pref("gfx.canvas.azure.accelerated", tru pref("gfx.canvas.skiagl.dynamic-cache", true); // Limit skia to canvases the size of the device screen or smaller pref("gfx.canvas.max-size-for-skia-gl", -1); // enable fence with readpixels for SurfaceStream pref("gfx.gralloc.fence-with-readpixels", true); -// Cell Broadcast API -pref("ril.cellbroadcast.disabled", false); - // The url of the page used to display network error details. pref("b2g.neterror.url", "app://system.gaiamobile.org/net_error.html"); // Enable Web Speech synthesis API pref("media.webspeech.synth.enabled", true); // Downloads API pref("dom.mozDownloads.enabled", true);
--- a/b2g/chrome/content/settings.js +++ b/b2g/chrome/content/settings.js @@ -659,23 +659,23 @@ let settingsToObserve = { prefName: 'layers.offmainthreadcomposition.log-animations', defaultValue: false }, 'debug.paint-flashing.enabled': { prefName: 'nglayout.debug.paint_flashing', defaultValue: false }, 'devtools.eventlooplag.threshold': 100, + 'dom.mozApps.use_reviewer_certs': false, 'layers.draw-borders': false, 'layers.draw-tile-borders': false, 'layers.dump': false, 'layers.enable-tiles': true, 'layers.simple-tiles': false, 'privacy.donottrackheader.enabled': false, - 'ril.cellbroadcast.disabled': false, 'ril.radio.disabled': false, 'ril.mms.requestReadReport.enabled': { prefName: 'dom.mms.requestReadReport', defaultValue: true }, 'ril.mms.requestStatusReport.enabled': { prefName: 'dom.mms.requestStatusReport', defaultValue: false
--- a/b2g/components/B2GComponents.manifest +++ b/b2g/components/B2GComponents.manifest @@ -35,16 +35,17 @@ contract @mozilla.org/dom/messages/syste # ProcessGlobal.js component {1a94c87a-5ece-4d11-91e1-d29c29f21b28} ProcessGlobal.js contract @mozilla.org/b2g-process-global;1 {1a94c87a-5ece-4d11-91e1-d29c29f21b28} category app-startup ProcessGlobal service,@mozilla.org/b2g-process-global;1 # OMAContentHandler.js component {a6b2ab13-9037-423a-9897-dde1081be323} OMAContentHandler.js contract @mozilla.org/uriloader/content-handler;1?type=application/vnd.oma.drm.message {a6b2ab13-9037-423a-9897-dde1081be323} +contract @mozilla.org/uriloader/content-handler;1?type=application/vnd.oma.dd+xml {a6b2ab13-9037-423a-9897-dde1081be323} # PaymentGlue.js component {8b83eabc-7929-47f4-8b48-4dea8d887e4b} PaymentGlue.js contract @mozilla.org/payment/ui-glue;1 {8b83eabc-7929-47f4-8b48-4dea8d887e4b} # TelProtocolHandler.js component {782775dd-7351-45ea-aff1-0ffa872cfdd2} TelProtocolHandler.js contract @mozilla.org/network/protocol;1?name=tel {782775dd-7351-45ea-aff1-0ffa872cfdd2}
--- 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="2a165bebfa19b11b697837409f9550dd2917c46c"> <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="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/> + <project name="gaia.git" path="gaia" remote="mozillaorg" revision="45479c07cb6ba8c733093d6ee32c767c090c9a28"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/> <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="3326b51017252e09ccdd715dec6c5e12a7d1ecfe"/> <project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="23db533981ee2cd04fc5d946420402aed2792381"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="c2544b1797eb5c59f484c442a24c4dc14c37e68c"/> <!-- 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="cc67f31dc638c0b7edba3cf7e3d87cadf0ed52bf"> <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="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="45479c07cb6ba8c733093d6ee32c767c090c9a28"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/> <project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="23db533981ee2cd04fc5d946420402aed2792381"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="c2544b1797eb5c59f484c442a24c4dc14c37e68c"/> <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="276ce45e78b09c4a4ee643646f691d22804754c1"> <copyfile dest="Makefile" src="core/root.mk"/> </project> - <project name="gaia" path="gaia" remote="mozillaorg" revision="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="45479c07cb6ba8c733093d6ee32c767c090c9a28"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/> <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="23db533981ee2cd04fc5d946420402aed2792381"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="c2544b1797eb5c59f484c442a24c4dc14c37e68c"/> <!-- 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="2a165bebfa19b11b697837409f9550dd2917c46c"> <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="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/> + <project name="gaia.git" path="gaia" remote="mozillaorg" revision="45479c07cb6ba8c733093d6ee32c767c090c9a28"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/> <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="3326b51017252e09ccdd715dec6c5e12a7d1ecfe"/> <project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="23db533981ee2cd04fc5d946420402aed2792381"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="c2544b1797eb5c59f484c442a24c4dc14c37e68c"/> <!-- 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/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="cc67f31dc638c0b7edba3cf7e3d87cadf0ed52bf"> <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="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="45479c07cb6ba8c733093d6ee32c767c090c9a28"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/> <project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="23db533981ee2cd04fc5d946420402aed2792381"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="c2544b1797eb5c59f484c442a24c4dc14c37e68c"/> <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"/> @@ -109,29 +109,31 @@ <project name="platform/prebuilts/qemu-kernel" path="prebuilts/qemu-kernel" revision="ec4a882d411d0d4ceadc5912ab4ce6fd4df23ab7"/> <project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="b86c0ecb186ffdbfb85d9c65b8a4b084b3ee9514"/> <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="31ec211efafde89ab39472d7bd040f00d1b71945"/> <project name="platform/system/extras" path="system/extras" revision="4d4bc6e7777887d93340f577d9b46de4a7c75f26"/> <project name="platform/system/media" path="system/media" revision="df2cdd433738a891102873710bdd3c3db7adb0cc"/> <project name="platform/system/netd" path="system/netd" revision="ea8103eae5642621ca8202e00620f4ca954ed413"/> <project name="platform/system/security" path="system/security" revision="360f51f7af191316cd739f229db1c5f7233be063"/> <project name="platform/system/vold" path="system/vold" revision="153df4d067a4149c7d78f1c92fed2ce2bd6a272e"/> + <!--original fetch url was git://github.com/t2m-foxfone/--> + <remote fetch="https://git.mozilla.org/external/t2m-foxfone" name="t2m"/> <default remote="caf" revision="jb_3.2" sync-j="4"/> <!-- Flame specific things --> <project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="e8a318f7690092e639ba88891606f4183e846d3f"/> <project name="device/qcom/common" path="device/qcom/common" revision="34ed8345250bb97262d70a052217a92e83444ede"/> - <project name="device-flame" path="device/t2m/flame" remote="b2g" revision="243b6f3d219592a84c7318e9446cde397233ae39"/> + <project name="device-flame" path="device/t2m/flame" remote="b2g" revision="33faca8033c6f8cda0c383ab40d69c7a45e6db38"/> <project name="codeaurora_kernel_msm" path="kernel" remote="b2g" revision="30a441fb7275fc5bc347f84ccb29e977a7eca34e"/> <project name="kernel_lk" path="bootable/bootloader/lk" remote="b2g" revision="2b1d8b5b7a760230f4c94c02e733e3929f44253a"/> <project name="platform_bootable_recovery" path="bootable/recovery" remote="b2g" revision="e81502511cda303c803e63f049574634bc96f9f2"/> <project name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="81c4a859d75d413ad688067829d21b7ba9205f81"/> <project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="f0689ac1914cdbc59e53bdc9edd9013dc157c299"/> <project name="platform/external/bluetooth/glib" path="external/bluetooth/glib" revision="dd925f76e4f149c3d5571b80e12f7e24bbe89c59"/> <project name="platform/external/dbus" path="external/dbus" revision="ea87119c843116340f5df1d94eaf8275e1055ae8"/> - <project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="494c177966fdc31183a5f7af82dc9130f523da4b"/> + <project name="platform_external_libnfc-nci" path="external/libnfc-nci" remote="t2m" revision="4186bdecb4dae911b39a8202252cc2310d91b0be"/> <project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="320b05a5761eb2a4816f7529c91ea49422979b55"/> <project name="platform/frameworks/av" path="frameworks/av" revision="5b934dc57dae25f286b0e7210dc6ff47f3244927"/> <project name="platform/frameworks/base" path="frameworks/base" revision="af3e4fbdc9369643a92015ea2657361f3b1b46fe"/> <project name="platform/frameworks/native" path="frameworks/native" revision="33a2b51f78416536e1bfba0c0b7776db307f3a4f"/> <project name="platform/hardware/libhardware" path="hardware/libhardware" revision="484802559ed106bac4811bd01c024ca64f741e60"/> <project name="platform/hardware/qcom/audio" path="hardware/qcom/audio" revision="83f363a26069e9c188d2aaef5b9ef63e84ad1511"/> <project name="platform/hardware/qcom/camera" path="hardware/qcom/camera" revision="5e110615212302c5d798a3c223dcee458817651c"/> <project name="platform/hardware/qcom/display" path="hardware/qcom/display" revision="280d29203b2aa30d713c5a6cc63d626e5a7df822"/>
--- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { "git_revision": "", "remote": "", "branch": "" }, - "revision": "aba00cfd579caaf205e05c269f0a8100f242f39c", + "revision": "8ac363347c96715adf6bec5fc30a975a2cfbaafd", "repo_path": "/integration/gaia-central" }
--- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/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="b2g/ics_strawberry" sync-j="4"/> <!-- Gonk specific things and forks --> <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c"> <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="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/> + <project name="gaia.git" path="gaia" remote="mozillaorg" revision="45479c07cb6ba8c733093d6ee32c767c090c9a28"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/> <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="c510babaf88dfa2cfe2c202afb2649ee124569af"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="23db533981ee2cd04fc5d946420402aed2792381"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="c2544b1797eb5c59f484c442a24c4dc14c37e68c"/> <!-- 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="2a165bebfa19b11b697837409f9550dd2917c46c"> <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="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/> + <project name="gaia.git" path="gaia" remote="mozillaorg" revision="45479c07cb6ba8c733093d6ee32c767c090c9a28"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/> <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="c510babaf88dfa2cfe2c202afb2649ee124569af"/> <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="cc67f31dc638c0b7edba3cf7e3d87cadf0ed52bf"> <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="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/> + <project name="gaia" path="gaia" remote="mozillaorg" revision="45479c07cb6ba8c733093d6ee32c767c090c9a28"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/> <project name="moztt" path="external/moztt" remote="b2g" revision="c510babaf88dfa2cfe2c202afb2649ee124569af"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="23db533981ee2cd04fc5d946420402aed2792381"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="c2544b1797eb5c59f484c442a24c4dc14c37e68c"/> <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="2a165bebfa19b11b697837409f9550dd2917c46c"> <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="41cc1de26e4edbe12add0009cdc0bd292f2e94fe"/> + <project name="gaia.git" path="gaia" remote="mozillaorg" revision="45479c07cb6ba8c733093d6ee32c767c090c9a28"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="bbb7659d8ea2afb396f99b3dc971ab3c42da3778"/> <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="c510babaf88dfa2cfe2c202afb2649ee124569af"/> - <project name="apitrace" path="external/apitrace" remote="apitrace" revision="23db533981ee2cd04fc5d946420402aed2792381"/> + <project name="apitrace" path="external/apitrace" remote="apitrace" revision="c2544b1797eb5c59f484c442a24c4dc14c37e68c"/> <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/alarm/AlarmDB.jsm +++ b/dom/alarm/AlarmDB.jsm @@ -31,55 +31,52 @@ AlarmDB.prototype = { __proto__: IndexedDBHelper.prototype, init: function init() { debug("init()"); this.initDBHelper(ALARMDB_NAME, ALARMDB_VERSION, [ALARMSTORE_NAME]); }, - upgradeSchema: function upgradeSchema(aTransaction, aDb, aOldVersion, aNewVersion) { + upgradeSchema: function upgradeSchema(aTransaction, aDb, + aOldVersion, aNewVersion) { debug("upgradeSchema()"); - let objectStore = aDb.createObjectStore(ALARMSTORE_NAME, { keyPath: "id", autoIncrement: true }); + let objStore = + aDb.createObjectStore(ALARMSTORE_NAME, + { keyPath: "id", autoIncrement: true }); - objectStore.createIndex("date", "date", { unique: false }); - objectStore.createIndex("ignoreTimezone", "ignoreTimezone", { unique: false }); - objectStore.createIndex("timezoneOffset", "timezoneOffset", { unique: false }); - objectStore.createIndex("data", "data", { unique: false }); - objectStore.createIndex("pageURL", "pageURL", { unique: false }); - objectStore.createIndex("manifestURL", "manifestURL", { unique: false }); + objStore.createIndex("date", "date", { unique: false }); + objStore.createIndex("ignoreTimezone", "ignoreTimezone", { unique: false }); + objStore.createIndex("timezoneOffset", "timezoneOffset", { unique: false }); + objStore.createIndex("data", "data", { unique: false }); + objStore.createIndex("pageURL", "pageURL", { unique: false }); + objStore.createIndex("manifestURL", "manifestURL", { unique: false }); debug("Created object stores and indexes"); }, /** * @param aAlarm * The record to be added. * @param aSuccessCb * Callback function to invoke with result ID. * @param aErrorCb [optional] * Callback function to invoke when there was an error. */ add: function add(aAlarm, aSuccessCb, aErrorCb) { debug("add()"); - this.newTxn( - "readwrite", - ALARMSTORE_NAME, - function txnCb(aTxn, aStore) { - debug("Going to add " + JSON.stringify(aAlarm)); - aStore.put(aAlarm).onsuccess = function setTxnResult(aEvent) { - aTxn.result = aEvent.target.result; - debug("Request successful. New record ID: " + aTxn.result); - }; - }, - aSuccessCb, - aErrorCb - ); + this.newTxn("readwrite", ALARMSTORE_NAME, function txnCb(aTxn, aStore) { + debug("Going to add " + JSON.stringify(aAlarm)); + aStore.put(aAlarm).onsuccess = function setTxnResult(aEvent) { + aTxn.result = aEvent.target.result; + debug("Request successful. New record ID: " + aTxn.result); + }; + }, aSuccessCb, aErrorCb); }, /** * @param aId * The ID of record to be removed. * @param aManifestURL * The manifest URL of the app that alarm belongs to. * If null, directly remove the ID record; otherwise, @@ -87,69 +84,57 @@ AlarmDB.prototype = { * @param aSuccessCb * Callback function to invoke with result. * @param aErrorCb [optional] * Callback function to invoke when there was an error. */ remove: function remove(aId, aManifestURL, aSuccessCb, aErrorCb) { debug("remove()"); - this.newTxn( - "readwrite", - ALARMSTORE_NAME, - function txnCb(aTxn, aStore) { - debug("Going to remove " + aId); + this.newTxn("readwrite", ALARMSTORE_NAME, function txnCb(aTxn, aStore) { + debug("Going to remove " + aId); - // Look up the existing record and compare the manifestURL - // to see if the alarm to be removed belongs to this app. - aStore.get(aId).onsuccess = function doRemove(aEvent) { - let alarm = aEvent.target.result; + // Look up the existing record and compare the manifestURL + // to see if the alarm to be removed belongs to this app. + aStore.get(aId).onsuccess = function doRemove(aEvent) { + let alarm = aEvent.target.result; - if (!alarm) { - debug("Alarm doesn't exist. No need to remove it."); - return; - } + if (!alarm) { + debug("Alarm doesn't exist. No need to remove it."); + return; + } - if (aManifestURL && aManifestURL != alarm.manifestURL) { - debug("Cannot remove the alarm added by other apps."); - return; - } + if (aManifestURL && aManifestURL != alarm.manifestURL) { + debug("Cannot remove the alarm added by other apps."); + return; + } - aStore.delete(aId); - }; - }, - aSuccessCb, - aErrorCb - ); + aStore.delete(aId); + }; + }, aSuccessCb, aErrorCb); }, /** * @param aManifestURL * The manifest URL of the app that alarms belong to. * If null, directly return all alarms; otherwise, * only return the alarms that belong to this app. * @param aSuccessCb * Callback function to invoke with result array. * @param aErrorCb [optional] * Callback function to invoke when there was an error. */ getAll: function getAll(aManifestURL, aSuccessCb, aErrorCb) { debug("getAll()"); - this.newTxn( - "readonly", - ALARMSTORE_NAME, - function txnCb(aTxn, aStore) { - if (!aTxn.result) { - aTxn.result = []; - } + this.newTxn("readonly", ALARMSTORE_NAME, function txnCb(aTxn, aStore) { + if (!aTxn.result) { + aTxn.result = []; + } - let index = aStore.index("manifestURL"); - index.mozGetAll(aManifestURL).onsuccess = function setTxnResult(aEvent) { - aTxn.result = aEvent.target.result; - debug("Request successful. Record count: " + aTxn.result.length); - }; - }, - aSuccessCb, - aErrorCb - ); + let index = aStore.index("manifestURL"); + index.mozGetAll(aManifestURL).onsuccess = function setTxnResult(aEvent) { + aTxn.result = aEvent.target.result; + debug("Request successful. Record count: " + aTxn.result.length); + }; + }, aSuccessCb, aErrorCb); } };
--- a/dom/alarm/AlarmService.jsm +++ b/dom/alarm/AlarmService.jsm @@ -24,45 +24,47 @@ XPCOMUtils.defineLazyGetter(this, "appsS return Cc["@mozilla.org/AppsService;1"].getService(Ci.nsIAppsService); }); XPCOMUtils.defineLazyServiceGetter(this, "ppmm", "@mozilla.org/parentprocessmessagemanager;1", "nsIMessageListenerManager"); XPCOMUtils.defineLazyGetter(this, "messenger", function() { - return Cc["@mozilla.org/system-message-internal;1"].getService(Ci.nsISystemMessagesInternal); + return Cc["@mozilla.org/system-message-internal;1"] + .getService(Ci.nsISystemMessagesInternal); }); XPCOMUtils.defineLazyGetter(this, "powerManagerService", function() { - return Cc["@mozilla.org/power/powermanagerservice;1"].getService(Ci.nsIPowerManagerService); + return Cc["@mozilla.org/power/powermanagerservice;1"] + .getService(Ci.nsIPowerManagerService); }); /** * AlarmService provides an API to schedule alarms using the device's RTC. * * AlarmService is primarily used by the mozAlarms API (navigator.mozAlarms) * which uses IPC to communicate with the service. * * AlarmService can also be used by Gecko code by importing the module and then * using AlarmService.add() and AlarmService.remove(). Only Gecko code running * in the parent process should do this. */ this.AlarmService = { init: function init() { debug("init()"); + Services.obs.addObserver(this, "profile-change-teardown", false); Services.obs.addObserver(this, "webapps-clear-data",false); this._currentTimezoneOffset = (new Date()).getTimezoneOffset(); - let alarmHalService = - this._alarmHalService = Cc["@mozilla.org/alarmHalService;1"] - .getService(Ci.nsIAlarmHalService); + let alarmHalService = this._alarmHalService = + Cc["@mozilla.org/alarmHalService;1"].getService(Ci.nsIAlarmHalService); alarmHalService.setAlarmFiredCb(this._onAlarmFired.bind(this)); alarmHalService.setTimezoneChangedCb(this._onTimezoneChanged.bind(this)); // Add the messages to be listened to. this._messages = ["AlarmsManager:GetAll", "AlarmsManager:Add", "AlarmsManager:Remove"]; @@ -104,54 +106,52 @@ this.AlarmService = { // To prevent the hacked child process from sending commands to parent // to schedule alarms, we need to check its permission and manifest URL. if (this._messages.indexOf(aMessage.name) != -1) { if (!aMessage.target.assertPermission("alarms")) { debug("Got message from a child process with no 'alarms' permission."); return null; } + if (!aMessage.target.assertContainApp(json.manifestURL)) { debug("Got message from a child process containing illegal manifest URL."); return null; } } let mm = aMessage.target.QueryInterface(Ci.nsIMessageSender); + switch (aMessage.name) { case "AlarmsManager:GetAll": - this._db.getAll( - json.manifestURL, + this._db.getAll(json.manifestURL, function getAllSuccessCb(aAlarms) { debug("Callback after getting alarms from database: " + JSON.stringify(aAlarms)); + this._sendAsyncMessage(mm, "GetAll", true, json.requestId, aAlarms); }.bind(this), function getAllErrorCb(aErrorMsg) { this._sendAsyncMessage(mm, "GetAll", false, json.requestId, aErrorMsg); - }.bind(this) - ); + }.bind(this)); break; case "AlarmsManager:Add": // Prepare a record for the new alarm to be added. - let newAlarm = { - date: json.date, - ignoreTimezone: json.ignoreTimezone, - data: json.data, - pageURL: json.pageURL, - manifestURL: json.manifestURL - }; + let newAlarm = { date: json.date, + ignoreTimezone: json.ignoreTimezone, + data: json.data, + pageURL: json.pageURL, + manifestURL: json.manifestURL }; this.add(newAlarm, null, // Receives the alarm ID as the last argument. this._sendAsyncMessage.bind(this, mm, "Add", true, json.requestId), // Receives the error message as the last argument. - this._sendAsyncMessage.bind(this, mm, "Add", false, json.requestId) - ); + this._sendAsyncMessage.bind(this, mm, "Add", false, json.requestId)); break; case "AlarmsManager:Remove": this.remove(json.id, json.manifestURL); break; default: throw Components.results.NS_ERROR_NOT_IMPLEMENTED; @@ -164,18 +164,17 @@ this.AlarmService = { debug("_sendAsyncMessage()"); if (!aMessageManager) { debug("Invalid message manager: null"); throw Components.results.NS_ERROR_FAILURE; } let json = null; - switch (aMessageName) - { + switch (aMessageName) { case "Add": json = aSuccess ? { requestId: aRequestId, id: aData } : { requestId: aRequestId, errorMsg: aData }; break; case "GetAll": json = aSuccess ? @@ -184,66 +183,63 @@ this.AlarmService = { break; default: throw Components.results.NS_ERROR_NOT_IMPLEMENTED; break; } aMessageManager.sendAsyncMessage("AlarmsManager:" + aMessageName + - ":Return:" + (aSuccess ? "OK" : "KO"), json); + ":Return:" + (aSuccess ? "OK" : "KO"), + json); }, _removeAlarmFromDb: function _removeAlarmFromDb(aId, aManifestURL, aRemoveSuccessCb) { debug("_removeAlarmFromDb()"); // If the aRemoveSuccessCb is undefined or null, set a dummy callback for // it which is needed for _db.remove(). if (!aRemoveSuccessCb) { aRemoveSuccessCb = function removeSuccessCb() { debug("Remove alarm from DB successfully."); }; } - this._db.remove( - aId, - aManifestURL, - aRemoveSuccessCb, - function removeErrorCb(aErrorMsg) { - throw Components.results.NS_ERROR_NOT_IMPLEMENTED; - } - ); + this._db.remove(aId, aManifestURL, aRemoveSuccessCb, + function removeErrorCb(aErrorMsg) { + throw Components.results.NS_ERROR_NOT_IMPLEMENTED; + }); }, /** * Create a copy of the alarm that does not expose internal fields to * receivers and sticks to the public |respectTimezone| API rather than the * boolean |ignoreTimezone| field. */ _publicAlarm: function _publicAlarm(aAlarm) { - let alarm = { - "id": aAlarm.id, - "date": aAlarm.date, - "respectTimezone": aAlarm.ignoreTimezone ? - "ignoreTimezone" : "honorTimezone", - "data": aAlarm.data - }; + let alarm = { "id": aAlarm.id, + "date": aAlarm.date, + "respectTimezone": aAlarm.ignoreTimezone ? + "ignoreTimezone" : "honorTimezone", + "data": aAlarm.data }; return alarm; }, _fireSystemMessage: function _fireSystemMessage(aAlarm) { debug("Fire system message: " + JSON.stringify(aAlarm)); let manifestURI = Services.io.newURI(aAlarm.manifestURL, null, null); let pageURI = Services.io.newURI(aAlarm.pageURL, null, null); - messenger.sendMessage("alarm", this._publicAlarm(aAlarm), - pageURI, manifestURI); + messenger.sendMessage("alarm", + this._publicAlarm(aAlarm), + pageURI, + manifestURI); }, _notifyAlarmObserver: function _notifyAlarmObserver(aAlarm) { debug("_notifyAlarmObserver()"); if (aAlarm.manifestURL) { this._fireSystemMessage(aAlarm); } else if (typeof aAlarm.alarmFiredCb === "function") { @@ -271,31 +267,31 @@ this.AlarmService = { if (nextAlarmTime <= Date.now()) { this._removeAlarmFromDb(nextAlarm.id, null); this._notifyAlarmObserver(nextAlarm); } else { this._currentAlarm = nextAlarm; break; } } + this._debugCurrentAlarm(); }, _onTimezoneChanged: function _onTimezoneChanged(aTimezoneOffset) { debug("_onTimezoneChanged()"); this._currentTimezoneOffset = aTimezoneOffset; this._restoreAlarmsFromDb(); }, _restoreAlarmsFromDb: function _restoreAlarmsFromDb() { debug("_restoreAlarmsFromDb()"); - this._db.getAll( - null, + this._db.getAll(null, function getAllSuccessCb(aAlarms) { debug("Callback after getting alarms from database: " + JSON.stringify(aAlarms)); // Clear any alarms set or queued in the cache. let alarmQueue = this._alarmQueue; alarmQueue.length = 0; this._currentAlarm = null; @@ -306,28 +302,27 @@ this.AlarmService = { if (this._getAlarmTime(aAlarm) > Date.now()) { alarmQueue.push(aAlarm); } else { this._removeAlarmFromDb(aAlarm.id, null); this._notifyAlarmObserver(aAlarm); } }.bind(this)); - // Set the next alarm from queue. + // Set the next alarm from the queue. if (alarmQueue.length) { alarmQueue.sort(this._sortAlarmByTimeStamps.bind(this)); this._currentAlarm = alarmQueue.shift(); } this._debugCurrentAlarm(); }.bind(this), function getAllErrorCb(aErrorMsg) { throw Components.results.NS_ERROR_NOT_IMPLEMENTED; - } - ); + }); }, _getAlarmTime: function _getAlarmTime(aAlarm) { // Avoid casting a Date object to a Date again to // preserve milliseconds. See bug 810973. let alarmTime; if (aAlarm.date instanceof Date) { alarmTime = aAlarm.date.getTime(); @@ -336,17 +331,18 @@ this.AlarmService = { } // For an alarm specified with "ignoreTimezone", it must be fired respect // to the user's timezone. Supposing an alarm was set at 7:00pm at Tokyo, // it must be gone off at 7:00pm respect to Paris' local time when the user // is located at Paris. We can adjust the alarm UTC time by calculating // the difference of the orginal timezone and the current timezone. if (aAlarm.ignoreTimezone) { - alarmTime += (this._currentTimezoneOffset - aAlarm.timezoneOffset) * 60000; + alarmTime += + (this._currentTimezoneOffset - aAlarm.timezoneOffset) * 60000; } return alarmTime; }, _sortAlarmByTimeStamps: function _sortAlarmByTimeStamps(aAlarm1, aAlarm2) { return this._getAlarmTime(aAlarm1) - this._getAlarmTime(aAlarm2); }, @@ -397,18 +393,17 @@ this.AlarmService = { if (!aNewAlarm.date) { aErrorCb("alarm.date is null"); return; } aNewAlarm['timezoneOffset'] = this._currentTimezoneOffset; - this._db.add( - aNewAlarm, + this._db.add(aNewAlarm, function addSuccessCb(aNewId) { debug("Callback after adding alarm in database."); aNewAlarm['id'] = aNewId; // Now that the alarm has been added to the database, we can tack on // the non-serializable callback to the in-memory object. aNewAlarm['alarmFiredCb'] = aAlarmFiredCb; @@ -417,17 +412,17 @@ this.AlarmService = { if (this._currentAlarm == null) { this._currentAlarm = aNewAlarm; this._debugCurrentAlarm(); aSuccessCb(aNewId); return; } // If the new alarm is earlier than the current alarm, swap them and - // push the previous alarm back to queue. + // push the previous alarm back to the queue. let alarmQueue = this._alarmQueue; let aNewAlarmTime = this._getAlarmTime(aNewAlarm); let currentAlarmTime = this._getAlarmTime(this._currentAlarm); if (aNewAlarmTime < currentAlarmTime) { alarmQueue.unshift(this._currentAlarm); this._currentAlarm = aNewAlarm; this._debugCurrentAlarm(); aSuccessCb(aNewId); @@ -437,34 +432,32 @@ this.AlarmService = { // Push the new alarm in the queue. alarmQueue.push(aNewAlarm); alarmQueue.sort(this._sortAlarmByTimeStamps.bind(this)); this._debugCurrentAlarm(); aSuccessCb(aNewId); }.bind(this), function addErrorCb(aErrorMsg) { aErrorCb(aErrorMsg); - }.bind(this) - ); + }.bind(this)); }, /* * Remove the alarm associated with an ID. * * @param number aAlarmId * The ID of the alarm to be removed. * @param string aManifestURL * Manifest URL for application which added the alarm. (Optional) * @returns void */ remove: function(aAlarmId, aManifestURL) { debug("remove(" + aAlarmId + ", " + aManifestURL + ")"); - this._removeAlarmFromDb( - aAlarmId, - aManifestURL, + + this._removeAlarmFromDb(aAlarmId, aManifestURL, function removeSuccessCb() { debug("Callback after removing alarm from database."); // If there are no alarms set, nothing to do. if (!this._currentAlarm) { debug("No alarms set."); return; } @@ -483,35 +476,37 @@ this.AlarmService = { break; } } this._debugCurrentAlarm(); return; } // The alarm to be removed is the current alarm reset the next alarm - // from queue if any. + // from the queue if any. if (alarmQueue.length) { this._currentAlarm = alarmQueue.shift(); this._debugCurrentAlarm(); return; } // No alarm waiting to be set in the queue. this._currentAlarm = null; this._debugCurrentAlarm(); - }.bind(this) - ); + }.bind(this)); }, observe: function(aSubject, aTopic, aData) { + debug("observe(): " + aTopic); + switch (aTopic) { case "profile-change-teardown": this.uninit(); break; + case "webapps-clear-data": let params = aSubject.QueryInterface(Ci.mozIApplicationClearPrivateDataParams); if (!params) { debug("Error! Fail to remove alarms for an uninstalled app."); return; } @@ -521,33 +516,32 @@ this.AlarmService = { } let manifestURL = appsService.getManifestURLByLocalId(params.appId); if (!manifestURL) { debug("Error! Fail to remove alarms for an uninstalled app."); return; } - this._db.getAll( - manifestURL, + this._db.getAll(manifestURL, function getAllSuccessCb(aAlarms) { aAlarms.forEach(function removeAlarm(aAlarm) { this.remove(aAlarm.id, manifestURL); }, this); }.bind(this), function getAllErrorCb(aErrorMsg) { throw Components.results.NS_ERROR_NOT_IMPLEMENTED; - } - ); + }); break; } }, uninit: function uninit() { debug("uninit()"); + Services.obs.removeObserver(this, "profile-change-teardown"); Services.obs.removeObserver(this, "webapps-clear-data"); this._messages.forEach(function(aMsgName) { ppmm.removeMessageListener(aMsgName, this); }.bind(this)); ppmm = null;
--- a/dom/alarm/AlarmsManager.js +++ b/dom/alarm/AlarmsManager.js @@ -13,23 +13,21 @@ function debug(aStr) { } const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/DOMRequestHelper.jsm"); -function AlarmsManager() -{ +function AlarmsManager() { debug("Constructor"); } AlarmsManager.prototype = { - __proto__: DOMRequestIpcHelper.prototype, contractID : "@mozilla.org/alarmsManager;1", classID : Components.ID("{fea1e884-9b05-11e1-9b64-87a7016c3860}"), QueryInterface : XPCOMUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer, Ci.nsISupportsWeakReference, @@ -43,60 +41,56 @@ AlarmsManager.prototype = { throw Components.results.NS_ERROR_FAILURE; } if (!aDate) { throw Components.results.NS_ERROR_INVALID_ARG; } let isIgnoreTimezone = true; + switch (aRespectTimezone) { case "honorTimezone": isIgnoreTimezone = false; break; case "ignoreTimezone": isIgnoreTimezone = true; break; default: throw Components.results.NS_ERROR_INVALID_ARG; break; } let request = this.createRequest(); - this._cpmm.sendAsyncMessage( - "AlarmsManager:Add", - { requestId: this.getRequestId(request), - date: aDate, - ignoreTimezone: isIgnoreTimezone, - data: aData, - pageURL: this._pageURL, - manifestURL: this._manifestURL } - ); + this._cpmm.sendAsyncMessage("AlarmsManager:Add", + { requestId: this.getRequestId(request), + date: aDate, + ignoreTimezone: isIgnoreTimezone, + data: aData, + pageURL: this._pageURL, + manifestURL: this._manifestURL }); return request; }, remove: function remove(aId) { debug("remove()"); - this._cpmm.sendAsyncMessage( - "AlarmsManager:Remove", - { id: aId, manifestURL: this._manifestURL } - ); + this._cpmm.sendAsyncMessage("AlarmsManager:Remove", + { id: aId, manifestURL: this._manifestURL }); }, getAll: function getAll() { debug("getAll()"); let request = this.createRequest(); - this._cpmm.sendAsyncMessage( - "AlarmsManager:GetAll", - { requestId: this.getRequestId(request), manifestURL: this._manifestURL } - ); + this._cpmm.sendAsyncMessage("AlarmsManager:GetAll", + { requestId: this.getRequestId(request), + manifestURL: this._manifestURL }); return request; }, receiveMessage: function receiveMessage(aMessage) { debug("receiveMessage(): " + aMessage.name); let json = aMessage.json; let request = this.getRequest(json.requestId); @@ -110,39 +104,41 @@ AlarmsManager.prototype = { case "AlarmsManager:Add:Return:OK": Services.DOMRequest.fireSuccess(request, json.id); break; case "AlarmsManager:GetAll:Return:OK": // We don't need to expose everything to the web content. let alarms = []; json.alarms.forEach(function trimAlarmInfo(aAlarm) { - let alarm = { "id": aAlarm.id, - "date": aAlarm.date, + let alarm = { "id": aAlarm.id, + "date": aAlarm.date, "respectTimezone": aAlarm.ignoreTimezone ? "ignoreTimezone" : "honorTimezone", - "data": aAlarm.data }; + "data": aAlarm.data }; alarms.push(alarm); }); + Services.DOMRequest.fireSuccess(request, Cu.cloneInto(alarms, this._window)); break; case "AlarmsManager:Add:Return:KO": Services.DOMRequest.fireError(request, json.errorMsg); break; case "AlarmsManager:GetAll:Return:KO": Services.DOMRequest.fireError(request, json.errorMsg); break; default: debug("Wrong message: " + aMessage.name); break; } + this.removeRequest(json.requestId); }, // nsIDOMGlobalPropertyInitializer implementation init: function init(aWindow) { debug("init()"); this._cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
--- a/dom/cellbroadcast/interfaces/nsIDOMMozCellBroadcastMessage.idl +++ b/dom/cellbroadcast/interfaces/nsIDOMMozCellBroadcastMessage.idl @@ -6,20 +6,25 @@ #include "nsISupports.idl" interface nsIDOMMozCellBroadcastEtwsInfo; /** * MozCellBroadcastMessage encapsulates Cell Broadcast short message service * (CBS) messages. */ -[scriptable, uuid(701e74a9-5fc4-4e2d-a324-9b7693395159)] +[scriptable, uuid(dc729df4-f1d8-11e3-b00d-d3332542c557)] interface nsIDOMMozCellBroadcastMessage : nsISupports { /** + * The Service Id in the device where the message is received from. + */ + readonly attribute unsigned long serviceId; + + /** * Indication of the geographical area over which the Message Code is unique, * and the display mode. * * Possible values are: "cell-immediate", "plmn", "location-area" and "cell". */ readonly attribute DOMString gsmGeographicalScope; /**
new file mode 100644 --- /dev/null +++ b/dom/cellbroadcast/tests/marionette/head.js @@ -0,0 +1,229 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +const {Cc: Cc, Ci: Ci, Cr: Cr, Cu: Cu} = SpecialPowers; + +let Promise = Cu.import("resource://gre/modules/Promise.jsm").Promise; + +/** + * Push required permissions and test if |navigator.mozCellBroadcast| exists. + * Resolve if it does, reject otherwise. + * + * Fulfill params: + * cbManager -- an reference to navigator.mozCellBroadcast. + * + * Reject params: (none) + * + * @return A deferred promise. + */ +let cbManager; +function ensureCellBroadcast() { + let deferred = Promise.defer(); + + let permissions = [{ + "type": "cellbroadcast", + "allow": 1, + "context": document, + }]; + SpecialPowers.pushPermissions(permissions, function() { + ok(true, "permissions pushed: " + JSON.stringify(permissions)); + + cbManager = window.navigator.mozCellBroadcast; + if (cbManager) { + log("navigator.mozCellBroadcast is instance of " + cbManager.constructor); + } else { + log("navigator.mozCellBroadcast is undefined."); + } + + if (cbManager instanceof window.MozCellBroadcast) { + deferred.resolve(cbManager); + } else { + deferred.reject(); + } + }); + + return deferred.promise; +} + +/** + * Send emulator command with safe guard. + * + * We should only call |finish()| after all emulator command transactions + * end, so here comes with the pending counter. Resolve when the emulator + * gives positive response, and reject otherwise. + * + * Fulfill params: + * result -- an array of emulator response lines. + * + * Reject params: + * result -- an array of emulator response lines. + * + * @return A deferred promise. + */ +let pendingEmulatorCmdCount = 0; +function runEmulatorCmdSafe(aCommand) { + let deferred = Promise.defer(); + + ++pendingEmulatorCmdCount; + runEmulatorCmd(aCommand, function(aResult) { + --pendingEmulatorCmdCount; + + ok(true, "Emulator response: " + JSON.stringify(aResult)); + if (Array.isArray(aResult) && aResult[aResult.length - 1] === "OK") { + deferred.resolve(aResult); + } else { + deferred.reject(aResult); + } + }); + + return deferred.promise; +} + +/** + * Send raw CBS PDU to emulator. + * + * @param: aPdu + * A hex string representing the whole CBS PDU. + * + * Fulfill params: + * result -- an array of emulator response lines. + * + * Reject params: + * result -- an array of emulator response lines. + * + * @return A deferred promise. + */ +function sendRawCbsToEmulator(aPdu) { + let command = "cbs pdu " + aPdu; + return runEmulatorCmdSafe(command); +} + +/** + * Wait for one named Cellbroadcast event. + * + * Resolve if that named event occurs. Never reject. + * + * Fulfill params: the DOMEvent passed. + * + * @param aEventName + * A string event name. + * + * @return A deferred promise. + */ +function waitForManagerEvent(aEventName) { + let deferred = Promise.defer(); + + cbManager.addEventListener(aEventName, function onevent(aEvent) { + cbManager.removeEventListener(aEventName, onevent); + + ok(true, "Cellbroadcast event '" + aEventName + "' got."); + deferred.resolve(aEvent); + }); + + return deferred.promise; +} + +/** + * Send multiple raw CB PDU to emulator and wait + * + * @param: aPdus + * A array of hex strings. Each represents a CB PDU. + * These PDUs are expected to be concatenated into single CB Message. + * + * Fulfill params: + * result -- array of resolved Promise, where + * result[0].message representing the received message. + * result[1-n] represents the response of sent emulator command. + * + * Reject params: + * result -- an array of emulator response lines. + * + * @return A deferred promise. + */ +function sendMultipleRawCbsToEmulatorAndWait(aPdus) { + let promises = []; + + promises.push(waitForManagerEvent("received")); + for (let pdu of aPdus) { + promises.push(sendRawCbsToEmulator(pdu)); + } + + return Promise.all(promises); +} + +/** + * Flush permission settings and call |finish()|. + */ +function cleanUp() { + waitFor(function() { + SpecialPowers.flushPermissions(function() { + // Use ok here so that we have at least one test run. + ok(true, "permissions flushed"); + + finish(); + }); + }, function() { + return pendingEmulatorCmdCount === 0; + }); +} + +/** + * Switch modem for receving upcoming emulator commands. + * + * @param: aServiceId + * The id of the modem to be switched to. + * + * Fulfill params: + * result -- an array of emulator response lines. + * + * Reject params: + * result -- an array of emulator response lines. + * + * @return A deferred promise. + */ +function selectModem(aServiceId) { + let command = "mux modem " + aServiceId; + return runEmulatorCmdSafe(command); +} + +/** + * Helper to run the test case only needed in Multi-SIM environment. + * + * @param aTest + * A function which will be invoked w/o parameter. + * @return a Promise object. + */ +function runIfMultiSIM(aTest) { + let numRIL; + try { + numRIL = SpecialPowers.getIntPref("ril.numRadioInterfaces"); + } catch (ex) { + numRIL = 1; // Pref not set. + } + + if (numRIL > 1) { + return aTest(); + } else { + log("Not a Multi-SIM environment. Test is skipped."); + return Promise.resolve(); + } +} + +/** + * Common test routine helper for cell broadcast tests. + * + * This function ensures global |cbManager| variable is available during the + * process and performs clean-ups as well. + * + * @param aTestCaseMain + * A function that takes no parameter. + */ +function startTestCommon(aTestCaseMain) { + Promise.resolve() + .then(ensureCellBroadcast) + .then(aTestCaseMain) + .then(cleanUp, function() { + ok(false, 'promise rejects during test.'); + cleanUp(); + }); +}
--- a/dom/cellbroadcast/tests/marionette/manifest.ini +++ b/dom/cellbroadcast/tests/marionette/manifest.ini @@ -1,7 +1,8 @@ [DEFAULT] b2g = true browser = false qemu = true [test_cellbroadcast_etws.js] [test_cellbroadcast_gsm.js] +[test_cellbroadcast_multi_sim.js] \ No newline at end of file
new file mode 100644 --- /dev/null +++ b/dom/cellbroadcast/tests/marionette/test_cellbroadcast_multi_sim.js @@ -0,0 +1,34 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +MARIONETTE_TIMEOUT = 60000; +MARIONETTE_HEAD_JS = 'head.js'; + +const BODY_7BITS = "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" + + "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" + + "@@@@@@@@@@@@@"; // 93 ascii chars. +const CB_PDU_SIZE = 88; + +function testReceivingMultiSIM() { + let CB_PDU = ""; + while (CB_PDU.length < CB_PDU_SIZE * 2) { + CB_PDU += "00"; + } + + let verifyCBMessage = (aMessage, aServiceId) => { + log("Verify CB message received from serviceId: " + aServiceId); + is(aMessage.body, BODY_7BITS, "Checking message body."); + is(aMessage.serviceId, aServiceId, "Checking serviceId."); + }; + + return selectModem(1) + .then(() => sendMultipleRawCbsToEmulatorAndWait([CB_PDU])) + .then((results) => verifyCBMessage(results[0].message, 1)) + .then(() => selectModem(0)) + .then(() => sendMultipleRawCbsToEmulatorAndWait([CB_PDU])) + .then((results) => verifyCBMessage(results[0].message, 0)); +} + +startTestCommon(function testCaseMain() { + return runIfMultiSIM(testReceivingMultiSIM); +});
--- a/dom/inputmethod/MozKeyboard.js +++ b/dom/inputmethod/MozKeyboard.js @@ -569,17 +569,17 @@ MozInputContext.prototype = { setComposition: function ic_setComposition(text, cursor, clauses) { let self = this; return this._sendPromise(function(resolverId) { cpmm.sendAsyncMessage('Keyboard:SetComposition', { contextId: self._contextId, requestId: resolverId, text: text, - cursor: cursor || text.length, + cursor: (typeof cursor !== 'undefined') ? cursor : text.length, clauses: clauses || null }); }); }, endComposition: function ic_endComposition(text) { let self = this; return this._sendPromise(function(resolverId) {
--- a/dom/system/gonk/RILContentHelper.js +++ b/dom/system/gonk/RILContentHelper.js @@ -300,17 +300,18 @@ MobileCallForwardingInfo.prototype = { __exposedProps__ : {active: 'r', action: 'r', reason: 'r', number: 'r', timeSeconds: 'r', serviceClass: 'r'} }; -function CellBroadcastMessage(pdu) { +function CellBroadcastMessage(clientId, pdu) { + this.serviceId = clientId; this.gsmGeographicalScope = RIL.CB_GSM_GEOGRAPHICAL_SCOPE_NAMES[pdu.geographicalScope]; this.messageCode = pdu.messageCode; this.messageId = pdu.messageId; this.language = pdu.language; this.body = pdu.fullBody; this.messageClass = pdu.messageClass; this.timestamp = pdu.timestamp; @@ -326,16 +327,17 @@ CellBroadcastMessage.prototype = { classInfo: XPCOMUtils.generateCI({ classID: CELLBROADCASTMESSAGE_CID, classDescription: "CellBroadcastMessage", flags: Ci.nsIClassInfo.DOM_OBJECT, interfaces: [Ci.nsIDOMMozCellBroadcastMessage] }), // nsIDOMMozCellBroadcastMessage + serviceId: -1, gsmGeographicalScope: null, messageCode: null, messageId: null, language: null, body: null, messageClass: null, timestamp: null, @@ -1539,23 +1541,27 @@ RILContentHelper.prototype = { // To follow the listener unregistration scheme, we add a dummy clientId 0. // All voicemail events are routed to listener for client id 0. // See |handleVoicemailNotification|. this.unregisterListener("_voicemailListeners", 0, listener); }, registerCellBroadcastMsg: function(listener) { if (DEBUG) debug("Registering for Cell Broadcast related messages"); - //TODO: Bug 921326 - Cellbroadcast API: support multiple sim cards + // Instead of registering multiple listeners for Multi-SIM, we reuse + // clientId 0 to route all CBS messages to single listener and provide the + // |clientId| info by |CellBroadcastMessage.serviceId|. this.registerListener("_cellBroadcastListeners", 0, listener); cpmm.sendAsyncMessage("RIL:RegisterCellBroadcastMsg"); }, unregisterCellBroadcastMsg: function(listener) { - //TODO: Bug 921326 - Cellbroadcast API: support multiple sim cards + // Instead of unregistering multiple listeners for Multi-SIM, we reuse + // clientId 0 to route all CBS messages to single listener and provide the + // |clientId| info by |CellBroadcastMessage.serviceId|. this.unregisterListener("_cellBroadcastListeners", 0, listener); }, registerIccMsg: function(clientId, listener) { if (DEBUG) debug("Registering for ICC related messages"); this.registerListener("_iccListeners", clientId, listener); cpmm.sendAsyncMessage("RIL:RegisterIccMsg"); }, @@ -1819,18 +1825,20 @@ RILContentHelper.prototype = { break; case "RIL:GetCallingLineIdRestriction": this.handleGetCallingLineIdRestriction(data); break; case "RIL:SetCallingLineIdRestriction": this.handleSimpleRequest(data.requestId, data.errorMsg, null); break; case "RIL:CellBroadcastReceived": { - let message = new CellBroadcastMessage(data); - this._deliverEvent(clientId, + // All CBS messages are to routed the listener for clientId 0 and + // provide the |clientId| info by |CellBroadcastMessage.serviceId|. + let message = new CellBroadcastMessage(clientId, data); + this._deliverEvent(0, // route to clientId 0. "_cellBroadcastListeners", "notifyMessageReceived", [message]); break; } case "RIL:SetRoamingPreference": this.handleSimpleRequest(data.requestId, data.errorMsg, null); break;
--- a/dom/system/gonk/RadioInterfaceLayer.js +++ b/dom/system/gonk/RadioInterfaceLayer.js @@ -66,25 +66,25 @@ const kSmsSentObserverTopic const kSmsFailedObserverTopic = "sms-failed"; const kSmsDeliverySuccessObserverTopic = "sms-delivery-success"; const kSmsDeliveryErrorObserverTopic = "sms-delivery-error"; const kMozSettingsChangedObserverTopic = "mozsettings-changed"; const kSysMsgListenerReadyObserverTopic = "system-message-listener-ready"; const kSysClockChangeObserverTopic = "system-clock-change"; const kScreenStateChangedTopic = "screen-state-changed"; +const kSettingsCellBroadcastDisabled = "ril.cellbroadcast.disabled"; const kSettingsCellBroadcastSearchList = "ril.cellbroadcast.searchlist"; const kSettingsClockAutoUpdateEnabled = "time.clock.automatic-update.enabled"; const kSettingsClockAutoUpdateAvailable = "time.clock.automatic-update.available"; const kSettingsTimezoneAutoUpdateEnabled = "time.timezone.automatic-update.enabled"; const kSettingsTimezoneAutoUpdateAvailable = "time.timezone.automatic-update.available"; const NS_PREFBRANCH_PREFCHANGE_TOPIC_ID = "nsPref:changed"; -const kPrefCellBroadcastDisabled = "ril.cellbroadcast.disabled"; const kPrefRilNumRadioInterfaces = "ril.numRadioInterfaces"; const kPrefRilDebuggingEnabled = "ril.debugging.enabled"; const DOM_MOBILE_MESSAGE_DELIVERY_RECEIVED = "received"; const DOM_MOBILE_MESSAGE_DELIVERY_SENDING = "sending"; const DOM_MOBILE_MESSAGE_DELIVERY_SENT = "sent"; const DOM_MOBILE_MESSAGE_DELIVERY_ERROR = "error"; @@ -1586,17 +1586,16 @@ WorkerMessenger.prototype = { token: 1, // Maps tokens we send out with messages to the message callback. tokenCallbackMap: null, init: function() { let options = { debug: DEBUG, - cellBroadcastDisabled: false, quirks: { callstateExtraUint32: libcutils.property_get("ro.moz.ril.callstate_extra_int", "false") === "true", v5Legacy: libcutils.property_get("ro.moz.ril.v5_legacy", "true") === "true", requestUseDialEmergencyCall: libcutils.property_get("ro.moz.ril.dial_emergency_call", "false") === "true", simAppStateExtraFields: @@ -1609,21 +1608,16 @@ WorkerMessenger.prototype = { libcutils.property_get("ro.moz.ril.send_stk_profile_dl", "false") == "true", dataRegistrationOnDemand: RILQUIRKS_DATA_REGISTRATION_ON_DEMAND, subscriptionControl: RILQUIRKS_SUBSCRIPTION_CONTROL }, rilEmergencyNumbers: libcutils.property_get("ril.ecclist") || libcutils.property_get("ro.ril.ecclist") }; - try { - options.cellBroadcastDisabled = - Services.prefs.getBoolPref(kPrefCellBroadcastDisabled); - } catch(e) {} - this.send(null, "setInitialOptions", options); }, setDebugFlag: function(aDebug) { let options = { debug: aDebug }; this.send(null, "setDebugFlag", options); }, @@ -1810,27 +1804,48 @@ function RadioInterface(aClientId, aWork lock.get(kSettingsTimezoneAutoUpdateEnabled, this); // Set "time.clock.automatic-update.available" to false when starting up. this.setClockAutoUpdateAvailable(false); // Set "time.timezone.automatic-update.available" to false when starting up. this.setTimezoneAutoUpdateAvailable(false); - // Read the Cell Broadcast Search List setting, string of integers or integer - // ranges separated by comma, to set listening channels. + /** + * Read the settings of the toggle of Cellbroadcast Service: + * + * Simple Format: Boolean + * true if CBS is disabled. The value is applied to all RadioInterfaces. + * Enhanced Format: Array of Boolean + * Each element represents the toggle of CBS per RadioInterface. + */ + lock.get(kSettingsCellBroadcastDisabled, this); + + /** + * Read the Cell Broadcast Search List setting to set listening channels: + * + * Simple Format: + * String of integers or integer ranges separated by comma. + * For example, "1, 2, 4-6" + * Enhanced Format: + * Array of Objects with search lists specified in gsm/cdma network. + * For example, [{'gsm' : "1, 2, 4-6", 'cdma' : "1, 50, 99"}, + * {'cdma' : "3, 6, 8-9"}] + * This provides the possibility to + * 1. set gsm/cdma search list individually for CDMA+LTE device. + * 2. set search list per RadioInterface. + */ lock.get(kSettingsCellBroadcastSearchList, this); Services.obs.addObserver(this, kMozSettingsChangedObserverTopic, false); Services.obs.addObserver(this, kSysClockChangeObserverTopic, false); Services.obs.addObserver(this, kScreenStateChangedTopic, false); Services.obs.addObserver(this, kNetworkConnStateChangedTopic, false); Services.obs.addObserver(this, kNetworkActiveChangedTopic, false); - Services.prefs.addObserver(kPrefCellBroadcastDisabled, this, false); this.portAddressedSmsApps = {}; this.portAddressedSmsApps[WAP.WDP_PORT_PUSH] = this.handleSmsWdpPortPush.bind(this); this._receivedSmsSegmentsMap = {}; this._sntp = new Sntp(this.setClockBySntp.bind(this), Services.prefs.getIntPref("network.sntp.maxRetryCount"), @@ -2488,33 +2503,40 @@ RadioInterface.prototype = { this._selectingNetwork = null; target.sendAsyncMessage("RIL:SelectNetworkAuto", { clientId: this.clientId, data: response }); }).bind(this)); }, - setCellBroadcastSearchList: function(newSearchList) { - if ((newSearchList == this._cellBroadcastSearchList) || - (newSearchList && this._cellBroadcastSearchList && - newSearchList.gsm == this._cellBroadcastSearchList.gsm && - newSearchList.cdma == this._cellBroadcastSearchList.cdma)) { + setCellBroadcastSearchList: function(settings) { + let newSearchList = + Array.isArray(settings) ? settings[this.clientId] : settings; + let oldSearchList = + Array.isArray(this._cellBroadcastSearchList) ? + this._cellBroadcastSearchList[this.clientId] : + this._cellBroadcastSearchList; + + if ((newSearchList == oldSearchList) || + (newSearchList && oldSearchList && + newSearchList.gsm == oldSearchList.gsm && + newSearchList.cdma == oldSearchList.cdma)) { return; } this.workerMessenger.send("setCellBroadcastSearchList", { searchList: newSearchList }, (function callback(response) { if (!response.success) { let lock = gSettingsService.createLock(); lock.set(kSettingsCellBroadcastSearchList, this._cellBroadcastSearchList, null); } else { - this._cellBroadcastSearchList = response.searchList; + this._cellBroadcastSearchList = settings; } return false; }).bind(this)); }, /** * Handle signal strength changes. @@ -3299,26 +3321,16 @@ RadioInterface.prototype = { // nsIObserver observe: function(subject, topic, data) { switch (topic) { case kMozSettingsChangedObserverTopic: let setting = JSON.parse(data); this.handleSettingsChange(setting.key, setting.value, setting.message); break; - case NS_PREFBRANCH_PREFCHANGE_TOPIC_ID: - if (data === kPrefCellBroadcastDisabled) { - let value = false; - try { - value = Services.prefs.getBoolPref(kPrefCellBroadcastDisabled); - } catch(e) {} - this.workerMessenger.send("setCellBroadcastDisabled", - { disabled: value }); - } - break; case kSysClockChangeObserverTopic: let offset = parseInt(data, 10); if (this._lastNitzMessage) { this._lastNitzMessage.receiveTimeInMS += offset; } this._sntp.updateOffset(offset); break; case kNetworkConnStateChangedTopic: @@ -3470,19 +3482,29 @@ RadioInterface.prototype = { } } break; case kSettingsCellBroadcastSearchList: if (DEBUG) { this.debug("'" + kSettingsCellBroadcastSearchList + "' is now " + JSON.stringify(aResult)); } - // TODO: Set searchlist for Multi-SIM. See Bug 921326. - let result = Array.isArray(aResult) ? aResult[0] : aResult; - this.setCellBroadcastSearchList(result); + + this.setCellBroadcastSearchList(aResult); + break; + case kSettingsCellBroadcastDisabled: + if (DEBUG) { + this.debug("'" + kSettingsCellBroadcastDisabled + + "' is now " + JSON.stringify(aResult)); + } + + let setCbsDisabled = + Array.isArray(aResult) ? aResult[this.clientId] : aResult; + this.workerMessenger.send("setCellBroadcastDisabled", + { disabled: setCbsDisabled }); break; } }, handleError: function(aErrorMessage) { if (DEBUG) { this.debug("There was an error while reading RIL settings."); }
--- a/dom/system/gonk/ril_worker.js +++ b/dom/system/gonk/ril_worker.js @@ -47,17 +47,16 @@ let GLOBAL = this; if (!this.debug) { // Debugging stub that goes nowhere. this.debug = function debug(message) { dump("RIL Worker: " + message + "\n"); }; } -let RIL_CELLBROADCAST_DISABLED; let RIL_EMERGENCY_NUMBERS; const DEFAULT_EMERGENCY_NUMBERS = ["112", "911"]; // Timeout value for emergency callback mode. const EMERGENCY_CB_MODE_TIMEOUT_MS = 300000; // 5 mins = 300000 ms. const ICC_MAX_LINEAR_FIXED_RECORDS = 0xfe; @@ -348,17 +347,16 @@ function RilObject(aContext) { this.currentDataCalls = {}; this._pendingSentSmsMap = {}; this.pendingNetworkType = {}; this._receivedSmsCbPagesMap = {}; this._getCurrentCallsRetryCount = 0; // Init properties that are only initialized once. this.v5Legacy = RILQUIRKS_V5_LEGACY; - this.cellBroadcastDisabled = RIL_CELLBROADCAST_DISABLED; this.pendingMO = null; } RilObject.prototype = { context: null, v5Legacy: null, @@ -6445,17 +6443,21 @@ RilObject.prototype[REQUEST_CDMA_SMS_ACK RilObject.prototype[REQUEST_GSM_GET_BROADCAST_SMS_CONFIG] = null; RilObject.prototype[REQUEST_GSM_SET_BROADCAST_SMS_CONFIG] = function REQUEST_GSM_SET_BROADCAST_SMS_CONFIG(length, options) { if (options.rilRequestError == ERROR_SUCCESS) { this.setSmsBroadcastActivation(true); } }; RilObject.prototype[REQUEST_GSM_SMS_BROADCAST_ACTIVATION] = null; RilObject.prototype[REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG] = null; -RilObject.prototype[REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG] = null; +RilObject.prototype[REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG] = function REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG(length, options) { + if (options.rilRequestError == ERROR_SUCCESS) { + this.setSmsBroadcastActivation(true); + } +}; RilObject.prototype[REQUEST_CDMA_SMS_BROADCAST_ACTIVATION] = null; RilObject.prototype[REQUEST_CDMA_SUBSCRIPTION] = function REQUEST_CDMA_SUBSCRIPTION(length, options) { if (options.rilRequestError) { return; } let result = this.context.Buf.readStringList(); @@ -13929,18 +13931,18 @@ ICCUtilsHelperObject.prototype = { break; } } iccInfo.isDisplaySpnRequired = inHomeArea; } } } else { // GSM family display rule. - let operatorMnc = RIL.operator.mnc; - let operatorMcc = RIL.operator.mcc; + let operatorMnc = RIL.operator ? RIL.operator.mnc : -1; + let operatorMcc = RIL.operator ? RIL.operator.mcc : -1; // First detect if we are on HPLMN or one of the PLMN // specified by the SIM card. let isOnMatchingPlmn = false; // If the current network is the one defined as mcc/mnc // in SIM card, it's okay. if (iccInfo.mcc == operatorMcc && iccInfo.mnc == operatorMnc) { @@ -14895,17 +14897,16 @@ let ContextPool = { return; } method.call(this, aMessage); }, setInitialOptions: function(aOptions) { DEBUG = DEBUG_WORKER || aOptions.debug; RIL_EMERGENCY_NUMBERS = aOptions.rilEmergencyNumbers; - RIL_CELLBROADCAST_DISABLED = aOptions.cellBroadcastDisabled; let quirks = aOptions.quirks; RILQUIRKS_CALLSTATE_EXTRA_UINT32 = quirks.callstateExtraUint32; RILQUIRKS_V5_LEGACY = quirks.v5Legacy; RILQUIRKS_REQUEST_USE_DIAL_EMERGENCY_CALL = quirks.requestUseDialEmergencyCall; RILQUIRKS_SIM_APP_STATE_EXTRA_FIELDS = quirks.simAppStateExtraFields; RILQUIRKS_EXTRA_UINT32_2ND_CALL = quirks.extraUint2ndCall; RILQUIRKS_HAVE_QUERY_ICC_LOCK_RETRY_COUNT = quirks.haveQueryIccLockRetryCount;
--- a/dom/system/gonk/tests/header_helpers.js +++ b/dom/system/gonk/tests/header_helpers.js @@ -74,16 +74,70 @@ function newWorker(custom_ns) { // Register at least one client. worker_ns.ContextPool.registerClient({ clientId: 0 }); return worker_ns; } /** + * Create a buffered RIL worker. + * + * @return A worker object that stores sending octets in a internal buffer. + */ +function newUint8Worker() { + let worker = newWorker(); + let index = 0; // index for read + let buf = []; + + let context = worker.ContextPool._contexts[0]; + context.Buf.writeUint8 = function(value) { + buf.push(value); + }; + + context.Buf.readUint8 = function() { + return buf[index++]; + }; + + context.Buf.seekIncoming = function(offset) { + index += offset; + }; + + context.Buf.getReadAvailable = function() { + return buf.length - index; + }; + + worker.debug = do_print; + + return worker; +} + +/** + * Create a worker that keeps posted chrome message. + */ +function newInterceptWorker() { + let postedMessage; + let worker = newWorker({ + postRILMessage: function(data) { + }, + postMessage: function(message) { + postedMessage = message; + } + }); + return { + get postedMessage() { + return postedMessage; + }, + get worker() { + return worker; + } + }; +} + +/** * Create a parcel suitable for postRILMessage(). * * @param fakeParcelSize * Value to be written to parcel size field for testing * incorrect/incomplete parcel reading. Replaced with correct * one determined length of data if negative. * @param response * Response code of the incoming parcel.
--- a/dom/system/gonk/tests/test_ril_worker_barring_password.js +++ b/dom/system/gonk/tests/test_ril_worker_barring_password.js @@ -5,42 +5,16 @@ subscriptLoader.loadSubScript("resource: function run_test() { run_next_test(); } const PIN = "0000"; const NEW_PIN = "1234"; -/** - * Helper function. - */ -function newUint8Worker() { - let worker = newWorker(); - let context = worker.ContextPool._contexts[0]; - let index = 0; // index for read - let buf = []; - - context.Buf.writeUint8 = function(value) { - buf.push(value); - }; - - context.Buf.readUint8 = function() { - return buf[index++]; - }; - - context.Buf.seekIncoming = function(offset) { - index += offset; - }; - - worker.debug = do_print; - - return worker; -} - add_test(function test_change_call_barring_password() { let worker = newUint8Worker(); let context = worker.ContextPool._contexts[0]; let buf = context.Buf; function do_test(facility, pin, newPin) { buf.sendParcel = function fakeSendParcel () { // Request Type.
--- a/dom/system/gonk/tests/test_ril_worker_cf.js +++ b/dom/system/gonk/tests/test_ril_worker_cf.js @@ -47,37 +47,18 @@ add_test(function test_toaFromString_unk add_test(function test_toaFromString_international() { let retval = toaFromString("+34666222333"); do_check_eq(retval, TOA_INTERNATIONAL); run_next_test(); }); -function _getWorker() { - let _postedMessage; - let _worker = newWorker({ - postRILMessage: function(data) { - }, - postMessage: function(message) { - _postedMessage = message; - } - }); - return { - get postedMessage() { - return _postedMessage; - }, - get worker() { - return _worker; - } - }; -} - add_test(function test_setCallForward_unconditional() { - let workerHelper = _getWorker(); + let workerHelper = newInterceptWorker(); let worker = workerHelper.worker; let context = worker.ContextPool._contexts[0]; context.RIL.setCallForward = function fakeSetCallForward(options) { context.RIL[REQUEST_SET_CALL_FORWARD](0, { rilRequestError: ERROR_SUCCESS }); }; @@ -94,17 +75,17 @@ add_test(function test_setCallForward_un do_check_eq(postedMessage.errorMsg, GECKO_ERROR_SUCCESS); do_check_true(postedMessage.success); run_next_test(); }); add_test(function test_queryCallForwardStatus_unconditional() { - let workerHelper = _getWorker(); + let workerHelper = newInterceptWorker(); let worker = workerHelper.worker; let context = worker.ContextPool._contexts[0]; context.RIL.setCallForward = function fakeSetCallForward(options) { context.RIL[REQUEST_SET_CALL_FORWARD](0, { rilRequestError: ERROR_SUCCESS }); };
--- a/dom/system/gonk/tests/test_ril_worker_clip.js +++ b/dom/system/gonk/tests/test_ril_worker_clip.js @@ -2,37 +2,18 @@ http://creativecommons.org/publicdomain/zero/1.0/ */ subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); function run_test() { run_next_test(); } -function _getWorker() { - let _postedMessage; - let _worker = newWorker({ - postRILMessage: function(data) { - }, - postMessage: function(message) { - _postedMessage = message; - } - }); - return { - get postedMessage() { - return _postedMessage; - }, - get worker() { - return _worker; - } - }; -} - add_test(function test_queryCLIP_provisioned() { - let workerHelper = _getWorker(); + let workerHelper = newInterceptWorker(); let worker = workerHelper.worker; let context = worker.ContextPool._contexts[0]; context.Buf.readInt32 = function fakeReadUint32() { return context.Buf.int32Array.pop(); }; context.RIL.queryCLIP = function fakeQueryCLIP(options) { @@ -51,17 +32,17 @@ add_test(function test_queryCLIP_provisi do_check_eq(postedMessage.errorMsg, undefined); do_check_true(postedMessage.success); do_check_eq(postedMessage.provisioned, 1); run_next_test(); }); add_test(function test_getCLIP_error_generic_failure_invalid_length() { - let workerHelper = _getWorker(); + let workerHelper = newInterceptWorker(); let worker = workerHelper.worker; let context = worker.ContextPool._contexts[0]; context.Buf.readInt32 = function fakeReadUint32() { return context.Buf.int32Array.pop(); }; context.RIL.queryCLIP = function fakeQueryCLIP(options) {
--- a/dom/system/gonk/tests/test_ril_worker_clir.js +++ b/dom/system/gonk/tests/test_ril_worker_clir.js @@ -11,37 +11,18 @@ const CLIR_DEFAULT = 0; const CLIR_INVOCATION = 1; // Allows CLI presentation. const CLIR_SUPPRESSION = 2; function run_test() { run_next_test(); } -function _getWorker() { - let _postedMessage; - let _worker = newWorker({ - postRILMessage: function(data) { - }, - postMessage: function(message) { - _postedMessage = message; - } - }); - return { - get postedMessage() { - return _postedMessage; - }, - get worker() { - return _worker; - } - }; -} - add_test(function test_setCLIR_success() { - let workerHelper = _getWorker(); + let workerHelper = newInterceptWorker(); let worker = workerHelper.worker; let context = worker.ContextPool._contexts[0]; context.RIL.setCLIR = function fakeSetCLIR(options) { context.RIL[REQUEST_SET_CLIR](0, { rilMessageType: "setCLIR", rilRequestError: ERROR_SUCCESS }); @@ -55,17 +36,17 @@ add_test(function test_setCLIR_success() do_check_eq(postedMessage.errorMsg, undefined); do_check_true(postedMessage.success); run_next_test(); }); add_test(function test_setCLIR_generic_failure() { - let workerHelper = _getWorker(); + let workerHelper = newInterceptWorker(); let worker = workerHelper.worker; let context = worker.ContextPool._contexts[0]; context.RIL.setCLIR = function fakeSetCLIR(options) { context.RIL[REQUEST_SET_CLIR](0, { rilMessageType: "setCLIR", rilRequestError: ERROR_GENERIC_FAILURE }); @@ -79,17 +60,17 @@ add_test(function test_setCLIR_generic_f do_check_eq(postedMessage.errorMsg, "GenericFailure"); do_check_false(postedMessage.success); run_next_test(); }); add_test(function test_getCLIR_n0_m1() { - let workerHelper = _getWorker(); + let workerHelper = newInterceptWorker(); let worker = workerHelper.worker; let context = worker.ContextPool._contexts[0]; context.Buf.readInt32 = function fakeReadUint32() { return context.Buf.int32Array.pop(); }; context.RIL.getCLIR = function fakeGetCLIR(options) { @@ -112,17 +93,17 @@ add_test(function test_getCLIR_n0_m1() { do_check_eq(postedMessage.errorMsg, undefined); do_check_true(postedMessage.success); do_check_eq(postedMessage.n, 0); do_check_eq(postedMessage.m, 1); run_next_test(); }); add_test(function test_getCLIR_error_generic_failure_invalid_length() { - let workerHelper = _getWorker(); + let workerHelper = newInterceptWorker(); let worker = workerHelper.worker; let context = worker.ContextPool._contexts[0]; context.Buf.readInt32 = function fakeReadUint32() { return context.Buf.int32Array.pop(); }; context.RIL.getCLIR = function fakeGetCLIR(options) {
--- a/dom/system/gonk/tests/test_ril_worker_cw.js +++ b/dom/system/gonk/tests/test_ril_worker_cw.js @@ -2,37 +2,18 @@ http://creativecommons.org/publicdomain/zero/1.0/ */ subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); function run_test() { run_next_test(); } -function _getWorker() { - let _postedMessage; - let _worker = newWorker({ - postRILMessage: function(data) { - }, - postMessage: function(message) { - _postedMessage = message; - } - }); - return { - get postedMessage() { - return _postedMessage; - }, - get worker() { - return _worker; - } - }; -} - add_test(function test_setCallWaiting_success() { - let workerHelper = _getWorker(); + let workerHelper = newInterceptWorker(); let worker = workerHelper.worker; let context = worker.ContextPool._contexts[0]; context.RIL.setCallWaiting = function fakeSetCallWaiting(options) { context.RIL[REQUEST_SET_CALL_WAITING](0, { rilRequestError: ERROR_SUCCESS }); }; @@ -45,17 +26,17 @@ add_test(function test_setCallWaiting_su do_check_eq(postedMessage.errorMsg, undefined); do_check_true(postedMessage.success); run_next_test(); }); add_test(function test_setCallWaiting_generic_failure() { - let workerHelper = _getWorker(); + let workerHelper = newInterceptWorker(); let worker = workerHelper.worker; let context = worker.ContextPool._contexts[0]; context.RIL.setCallWaiting = function fakeSetCallWaiting(options) { context.RIL[REQUEST_SET_CALL_WAITING](0, { rilRequestError: ERROR_GENERIC_FAILURE }); }; @@ -68,17 +49,17 @@ add_test(function test_setCallWaiting_ge do_check_eq(postedMessage.errorMsg, "GenericFailure"); do_check_false(postedMessage.success); run_next_test(); }); add_test(function test_queryCallWaiting_success_enabled_true() { - let workerHelper = _getWorker(); + let workerHelper = newInterceptWorker(); let worker = workerHelper.worker; let context = worker.ContextPool._contexts[0]; context.Buf.readInt32 = function fakeReadUint32() { return context.Buf.int32Array.pop(); }; context.RIL.queryCallWaiting = function fakeQueryCallWaiting(options) { @@ -99,17 +80,17 @@ add_test(function test_queryCallWaiting_ do_check_eq(postedMessage.errorMsg, undefined); do_check_true(postedMessage.success); do_check_eq(postedMessage.length, 1); do_check_true(postedMessage.enabled); run_next_test(); }); add_test(function test_queryCallWaiting_success_enabled_false() { - let workerHelper = _getWorker(); + let workerHelper = newInterceptWorker(); let worker = workerHelper.worker; let context = worker.ContextPool._contexts[0]; context.Buf.readInt32 = function fakeReadUint32() { return context.Buf.int32Array.pop(); }; context.RIL.queryCallWaiting = function fakeQueryCallWaiting(options) {
--- a/dom/system/gonk/tests/test_ril_worker_ecm.js +++ b/dom/system/gonk/tests/test_ril_worker_ecm.js @@ -2,35 +2,16 @@ http://creativecommons.org/publicdomain/zero/1.0/ */ subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); function run_test() { run_next_test(); } -function _getWorker() { - let _postedMessage; - let _worker = newWorker({ - postRILMessage: function(data) { - }, - postMessage: function(message) { - _postedMessage = message; - } - }); - return { - get postedMessage() { - return _postedMessage; - }, - get worker() { - return _worker; - } - }; -} - var timeoutCallback = null; var timeoutDelayMs = 0; const TIMER_ID = 1234; const TIMEOUT_VALUE = 300000; // 5 mins. // No window in xpcshell-test. Create our own timer mechanism. function setTimeout(callback, timeoutMs) { @@ -49,17 +30,17 @@ function fireTimeout() { do_check_neq(timeoutCallback, null); if (timeoutCallback) { timeoutCallback(); timeoutCallback = null; } } add_test(function test_enter_emergencyCbMode() { - let workerHelper = _getWorker(); + let workerHelper = newInterceptWorker(); let worker = workerHelper.worker; let context = worker.ContextPool._contexts[0]; // Do it twice. Should always send the event. for (let i = 0; i < 2; ++i) { context.RIL[UNSOLICITED_ENTER_EMERGENCY_CALLBACK_MODE](); let postedMessage = workerHelper.postedMessage; @@ -74,17 +55,17 @@ add_test(function test_enter_emergencyCb // Should start timer. do_check_eq(context.RIL._exitEmergencyCbModeTimeoutID, TIMER_ID); } run_next_test(); }); add_test(function test_exit_emergencyCbMode() { - let workerHelper = _getWorker(); + let workerHelper = newInterceptWorker(); let worker = workerHelper.worker; let context = worker.ContextPool._contexts[0]; context.RIL[UNSOLICITED_ENTER_EMERGENCY_CALLBACK_MODE](); context.RIL[UNSOLICITED_EXIT_EMERGENCY_CALLBACK_MODE](); let postedMessage = workerHelper.postedMessage; // Should store the mode. @@ -96,17 +77,17 @@ add_test(function test_exit_emergencyCbM // Should clear timer. do_check_eq(context.RIL._exitEmergencyCbModeTimeoutID, null); run_next_test(); }); add_test(function test_request_exit_emergencyCbMode_when_timeout() { - let workerHelper = _getWorker(); + let workerHelper = newInterceptWorker(); let worker = workerHelper.worker; let context = worker.ContextPool._contexts[0]; context.RIL[UNSOLICITED_ENTER_EMERGENCY_CALLBACK_MODE](); do_check_eq(context.RIL._isInEmergencyCbMode, true); do_check_eq(context.RIL._exitEmergencyCbModeTimeoutID, TIMER_ID); let parcelTypes = []; @@ -122,17 +103,17 @@ add_test(function test_request_exit_emer // Check indeed sent out REQUEST_EXIT_EMERGENCY_CALLBACK_MODE. do_check_neq(parcelTypes.indexOf(REQUEST_EXIT_EMERGENCY_CALLBACK_MODE), -1); run_next_test(); }); add_test(function test_request_exit_emergencyCbMode_when_dial() { - let workerHelper = _getWorker(); + let workerHelper = newInterceptWorker(); let worker = workerHelper.worker; let context = worker.ContextPool._contexts[0]; context.RIL[UNSOLICITED_ENTER_EMERGENCY_CALLBACK_MODE](); do_check_eq(context.RIL._isInEmergencyCbMode, true); do_check_eq(context.RIL._exitEmergencyCbModeTimeoutID, TIMER_ID); let parcelTypes = []; @@ -149,17 +130,17 @@ add_test(function test_request_exit_emer // Check indeed sent out REQUEST_EXIT_EMERGENCY_CALLBACK_MODE. do_check_neq(parcelTypes.indexOf(REQUEST_EXIT_EMERGENCY_CALLBACK_MODE), -1); run_next_test(); }); add_test(function test_request_exit_emergencyCbMode_explicitly() { - let workerHelper = _getWorker(); + let workerHelper = newInterceptWorker(); let worker = workerHelper.worker; let context = worker.ContextPool._contexts[0]; context.RIL[UNSOLICITED_ENTER_EMERGENCY_CALLBACK_MODE](); do_check_eq(context.RIL._isInEmergencyCbMode, true); do_check_eq(context.RIL._exitEmergencyCbModeTimeoutID, TIMER_ID); let parcelTypes = [];
deleted file mode 100644 --- a/dom/system/gonk/tests/test_ril_worker_icc.js +++ /dev/null @@ -1,3198 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -/** - * Helper function. - */ -function newUint8Worker() { - let worker = newWorker(); - let index = 0; // index for read - let buf = []; - - let context = worker.ContextPool._contexts[0]; - context.Buf.writeUint8 = function(value) { - buf.push(value); - }; - - context.Buf.readUint8 = function() { - return buf[index++]; - }; - - context.Buf.seekIncoming = function(offset) { - index += offset; - }; - - context.Buf.getReadAvailable = function() { - return buf.length - index; - }; - - worker.debug = do_print; - - return worker; -} - -/** - * Verify ICCPDUHelper#readICCUCS2String() - */ -add_test(function test_read_icc_ucs2_string() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - - // 0x80 - let text = "TEST"; - helper.writeUCS2String(text); - // Also write two unused octets. - let ffLen = 2; - for (let i = 0; i < ffLen; i++) { - helper.writeHexOctet(0xff); - } - do_check_eq(iccHelper.readICCUCS2String(0x80, (2 * text.length) + ffLen), text); - - // 0x81 - let array = [0x08, 0xd2, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca, - 0xff, 0xff]; - let len = array.length; - for (let i = 0; i < len; i++) { - helper.writeHexOctet(array[i]); - } - do_check_eq(iccHelper.readICCUCS2String(0x81, len), "Mozilla\u694a"); - - // 0x82 - let array2 = [0x08, 0x69, 0x00, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, - 0xca, 0xff, 0xff]; - let len2 = array2.length; - for (let i = 0; i < len2; i++) { - helper.writeHexOctet(array2[i]); - } - do_check_eq(iccHelper.readICCUCS2String(0x82, len2), "Mozilla\u694a"); - - run_next_test(); -}); - -/** - * Verify ICCPDUHelper#readDiallingNumber - */ -add_test(function test_read_dialling_number() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - let str = "123456789"; - - helper.readHexOctet = function() { - return 0x81; - }; - - helper.readSwappedNibbleBcdString = function(len) { - return str.substring(0, len); - }; - - for (let i = 0; i < str.length; i++) { - do_check_eq(str.substring(0, i - 1), // -1 for the TON - iccHelper.readDiallingNumber(i)); - } - - run_next_test(); -}); - -/** - * Verify ICCPDUHelper#read8BitUnpackedToString - */ -add_test(function test_read_8bit_unpacked_to_string() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; - const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; - - // Test 1: Read GSM alphabets. - // Write alphabets before ESCAPE. - for (let i = 0; i < PDU_NL_EXTENDED_ESCAPE; i++) { - helper.writeHexOctet(i); - } - - // Write two ESCAPEs to make it become ' '. - helper.writeHexOctet(PDU_NL_EXTENDED_ESCAPE); - helper.writeHexOctet(PDU_NL_EXTENDED_ESCAPE); - - for (let i = PDU_NL_EXTENDED_ESCAPE + 1; i < langTable.length; i++) { - helper.writeHexOctet(i); - } - - // Also write two unused fields. - let ffLen = 2; - for (let i = 0; i < ffLen; i++) { - helper.writeHexOctet(0xff); - } - - do_check_eq(iccHelper.read8BitUnpackedToString(PDU_NL_EXTENDED_ESCAPE), - langTable.substring(0, PDU_NL_EXTENDED_ESCAPE)); - do_check_eq(iccHelper.read8BitUnpackedToString(2), " "); - do_check_eq(iccHelper.read8BitUnpackedToString(langTable.length - - PDU_NL_EXTENDED_ESCAPE - 1 + ffLen), - langTable.substring(PDU_NL_EXTENDED_ESCAPE + 1)); - - // Test 2: Read GSM extended alphabets. - for (let i = 0; i < langShiftTable.length; i++) { - helper.writeHexOctet(PDU_NL_EXTENDED_ESCAPE); - helper.writeHexOctet(i); - } - - // Read string before RESERVED_CONTROL. - do_check_eq(iccHelper.read8BitUnpackedToString(PDU_NL_RESERVED_CONTROL * 2), - langShiftTable.substring(0, PDU_NL_RESERVED_CONTROL)); - // ESCAPE + RESERVED_CONTROL will become ' '. - do_check_eq(iccHelper.read8BitUnpackedToString(2), " "); - // Read string between RESERVED_CONTROL and EXTENDED_ESCAPE. - do_check_eq(iccHelper.read8BitUnpackedToString( - (PDU_NL_EXTENDED_ESCAPE - PDU_NL_RESERVED_CONTROL - 1) * 2), - langShiftTable.substring(PDU_NL_RESERVED_CONTROL + 1, - PDU_NL_EXTENDED_ESCAPE)); - // ESCAPE + ESCAPE will become ' '. - do_check_eq(iccHelper.read8BitUnpackedToString(2), " "); - // Read remaining string. - do_check_eq(iccHelper.read8BitUnpackedToString( - (langShiftTable.length - PDU_NL_EXTENDED_ESCAPE - 1) * 2), - langShiftTable.substring(PDU_NL_EXTENDED_ESCAPE + 1)); - - run_next_test(); -}); - -/** - * Verify ICCPDUHelper#writeStringTo8BitUnpacked. - * - * Test writing GSM 8 bit alphabets. - */ -add_test(function test_write_string_to_8bit_unpacked() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; - const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; - // Length of trailing 0xff. - let ffLen = 2; - let str; - - // Test 1, write GSM alphabets. - iccHelper.writeStringTo8BitUnpacked(langTable.length + ffLen, langTable); - - for (let i = 0; i < langTable.length; i++) { - do_check_eq(helper.readHexOctet(), i); - } - - for (let i = 0; i < ffLen; i++) { - do_check_eq(helper.readHexOctet(), 0xff); - } - - // Test 2, write GSM extended alphabets. - str = "\u000c\u20ac"; - iccHelper.writeStringTo8BitUnpacked(4, str); - - do_check_eq(iccHelper.read8BitUnpackedToString(4), str); - - // Test 3, write GSM and GSM extended alphabets. - // \u000c, \u20ac are from gsm extended alphabets. - // \u00a3 is from gsm alphabet. - str = "\u000c\u20ac\u00a3"; - - // 2 octets * 2 = 4 octets for 2 gsm extended alphabets, - // 1 octet for 1 gsm alphabet, - // 2 octes for trailing 0xff. - // "Totally 7 octets are to be written." - iccHelper.writeStringTo8BitUnpacked(7, str); - - do_check_eq(iccHelper.read8BitUnpackedToString(7), str); - - run_next_test(); -}); - -/** - * Verify ICCPDUHelper#writeStringTo8BitUnpacked with maximum octets written. - */ -add_test(function test_write_string_to_8bit_unpacked_with_max_octets_written() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; - const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; - - // The maximum of the number of octets that can be written is 3. - // Only 3 characters shall be written even the length of the string is 4. - iccHelper.writeStringTo8BitUnpacked(3, langTable.substring(0, 4)); - helper.writeHexOctet(0xff); // dummy octet. - for (let i = 0; i < 3; i++) { - do_check_eq(helper.readHexOctet(), i); - } - do_check_false(helper.readHexOctet() == 4); - - // \u000c is GSM extended alphabet, 2 octets. - // \u00a3 is GSM alphabet, 1 octet. - let str = "\u000c\u00a3"; - iccHelper.writeStringTo8BitUnpacked(3, str); - do_check_eq(iccHelper.read8BitUnpackedToString(3), str); - - str = "\u00a3\u000c"; - iccHelper.writeStringTo8BitUnpacked(3, str); - do_check_eq(iccHelper.read8BitUnpackedToString(3), str); - - // 2 GSM extended alphabets cost 4 octets, but maximum is 3, so only the 1st - // alphabet can be written. - str = "\u000c\u000c"; - iccHelper.writeStringTo8BitUnpacked(3, str); - helper.writeHexOctet(0xff); // dummy octet. - do_check_eq(iccHelper.read8BitUnpackedToString(4), str.substring(0, 1)); - - run_next_test(); -}); - -/** - * Verify ICCPDUHelper.readAlphaIdentifier - */ -add_test(function test_read_alpha_identifier() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - - // UCS2: 0x80 - let text = "TEST"; - helper.writeHexOctet(0x80); - helper.writeUCS2String(text); - // Also write two unused octets. - let ffLen = 2; - for (let i = 0; i < ffLen; i++) { - helper.writeHexOctet(0xff); - } - do_check_eq(iccHelper.readAlphaIdentifier(1 + (2 * text.length) + ffLen), text); - - // UCS2: 0x81 - let array = [0x81, 0x08, 0xd2, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca, 0xff, 0xff]; - for (let i = 0; i < array.length; i++) { - helper.writeHexOctet(array[i]); - } - do_check_eq(iccHelper.readAlphaIdentifier(array.length), "Mozilla\u694a"); - - // UCS2: 0x82 - let array2 = [0x82, 0x08, 0x69, 0x00, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca, 0xff, 0xff]; - for (let i = 0; i < array2.length; i++) { - helper.writeHexOctet(array2[i]); - } - do_check_eq(iccHelper.readAlphaIdentifier(array2.length), "Mozilla\u694a"); - - // GSM 8 Bit Unpacked - const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; - for (let i = 0; i < PDU_NL_EXTENDED_ESCAPE; i++) { - helper.writeHexOctet(i); - } - do_check_eq(iccHelper.readAlphaIdentifier(PDU_NL_EXTENDED_ESCAPE), - langTable.substring(0, PDU_NL_EXTENDED_ESCAPE)); - - run_next_test(); -}); - -/** - * Verify ICCPDUHelper.writeAlphaIdentifier - */ -add_test(function test_write_alpha_identifier() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - // Length of trailing 0xff. - let ffLen = 2; - - // Removal - iccHelper.writeAlphaIdentifier(10, null); - do_check_eq(iccHelper.readAlphaIdentifier(10), ""); - - // GSM 8 bit - let str = "Mozilla"; - iccHelper.writeAlphaIdentifier(str.length + ffLen, str); - do_check_eq(iccHelper.readAlphaIdentifier(str.length + ffLen), str); - - // UCS2 - str = "Mozilla\u694a"; - iccHelper.writeAlphaIdentifier(str.length * 2 + ffLen, str); - // * 2 for each character will be encoded to UCS2 alphabets. - do_check_eq(iccHelper.readAlphaIdentifier(str.length * 2 + ffLen), str); - - // Test with maximum octets written. - // 1 coding scheme (0x80) and 1 UCS2 character, total 3 octets. - str = "\u694a"; - iccHelper.writeAlphaIdentifier(3, str); - do_check_eq(iccHelper.readAlphaIdentifier(3), str); - - // 1 coding scheme (0x80) and 2 UCS2 characters, total 5 octets. - // numOctets is limited to 4, so only 1 UCS2 character can be written. - str = "\u694a\u694a"; - iccHelper.writeAlphaIdentifier(4, str); - helper.writeHexOctet(0xff); // dummy octet. - do_check_eq(iccHelper.readAlphaIdentifier(5), str.substring(0, 1)); - - // Write 0 octet. - iccHelper.writeAlphaIdentifier(0, "1"); - helper.writeHexOctet(0xff); // dummy octet. - do_check_eq(iccHelper.readAlphaIdentifier(1), ""); - - run_next_test(); -}); - -/** - * Verify ICCPDUHelper.readAlphaIdDiallingNumber - */ -add_test(function test_read_alpha_id_dialling_number() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - let buf = context.Buf; - const recordSize = 32; - - function testReadAlphaIdDiallingNumber(contact) { - iccHelper.readAlphaIdentifier = function() { - return contact.alphaId; - }; - - iccHelper.readNumberWithLength = function() { - return contact.number; - }; - - let strLen = recordSize * 2; - buf.writeInt32(strLen); // fake length - helper.writeHexOctet(0xff); // fake CCP - helper.writeHexOctet(0xff); // fake EXT1 - buf.writeStringDelimiter(strLen); - - let contactR = iccHelper.readAlphaIdDiallingNumber(recordSize); - if (contact.alphaId == "" && contact.number == "") { - do_check_eq(contactR, null); - } else { - do_check_eq(contactR.alphaId, contact.alphaId); - do_check_eq(contactR.number, contact.number); - } - } - - testReadAlphaIdDiallingNumber({alphaId: "AlphaId", number: "0987654321"}); - testReadAlphaIdDiallingNumber({alphaId: "", number: ""}); - - run_next_test(); -}); - -/** - * Verify ICCPDUHelper.writeAlphaIdDiallingNumber - */ -add_test(function test_write_alpha_id_dialling_number() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.ICCPDUHelper; - const recordSize = 32; - - // Write a normal contact. - let contactW = { - alphaId: "Mozilla", - number: "1234567890" - }; - helper.writeAlphaIdDiallingNumber(recordSize, contactW.alphaId, - contactW.number); - - let contactR = helper.readAlphaIdDiallingNumber(recordSize); - do_check_eq(contactW.alphaId, contactR.alphaId); - do_check_eq(contactW.number, contactR.number); - - // Write a contact with alphaId encoded in UCS2 and number has '+'. - let contactUCS2 = { - alphaId: "火狐", - number: "+1234567890" - }; - helper.writeAlphaIdDiallingNumber(recordSize, contactUCS2.alphaId, - contactUCS2.number); - contactR = helper.readAlphaIdDiallingNumber(recordSize); - do_check_eq(contactUCS2.alphaId, contactR.alphaId); - do_check_eq(contactUCS2.number, contactR.number); - - // Write a null contact (Removal). - helper.writeAlphaIdDiallingNumber(recordSize); - contactR = helper.readAlphaIdDiallingNumber(recordSize); - do_check_eq(contactR, null); - - // Write a longer alphaId/dialling number - // Dialling Number : Maximum 20 digits(10 octets). - // Alpha Identifier: 32(recordSize) - 14 (10 octets for Dialling Number, 1 - // octet for TON/NPI, 1 for number length octet, and 2 for - // Ext) = Maximum 18 octets. - let longContact = { - alphaId: "AAAAAAAAABBBBBBBBBCCCCCCCCC", - number: "123456789012345678901234567890", - }; - helper.writeAlphaIdDiallingNumber(recordSize, longContact.alphaId, - longContact.number); - contactR = helper.readAlphaIdDiallingNumber(recordSize); - do_check_eq(contactR.alphaId, "AAAAAAAAABBBBBBBBB"); - do_check_eq(contactR.number, "12345678901234567890"); - - // Add '+' to number and test again. - longContact.number = "+123456789012345678901234567890"; - helper.writeAlphaIdDiallingNumber(recordSize, longContact.alphaId, - longContact.number); - contactR = helper.readAlphaIdDiallingNumber(recordSize); - do_check_eq(contactR.alphaId, "AAAAAAAAABBBBBBBBB"); - do_check_eq(contactR.number, "+12345678901234567890"); - - run_next_test(); -}); - -/** - * Verify ICCPDUHelper.writeDiallingNumber - */ -add_test(function test_write_dialling_number() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.ICCPDUHelper; - - // with + - let number = "+123456"; - let len = 4; - helper.writeDiallingNumber(number); - do_check_eq(helper.readDiallingNumber(len), number); - - // without + - number = "987654"; - len = 4; - helper.writeDiallingNumber(number); - do_check_eq(helper.readDiallingNumber(len), number); - - number = "9876543"; - len = 5; - helper.writeDiallingNumber(number); - do_check_eq(helper.readDiallingNumber(len), number); - - run_next_test(); -}); - -/** - * Verify ICCPDUHelper.readNumberWithLength - */ -add_test(function test_read_number_with_length() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - let number = "123456789"; - - iccHelper.readDiallingNumber = function(numLen) { - return number.substring(0, numLen); - }; - - helper.writeHexOctet(number.length + 1); - helper.writeHexOctet(PDU_TOA_ISDN); - do_check_eq(iccHelper.readNumberWithLength(), number); - - helper.writeHexOctet(0xff); - do_check_eq(iccHelper.readNumberWithLength(), null); - - run_next_test(); -}); - -/** - * Verify ICCPDUHelper.writeNumberWithLength - */ -add_test(function test_write_number_with_length() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - - function test(number, expectedNumber) { - expectedNumber = expectedNumber || number; - iccHelper.writeNumberWithLength(number); - let numLen = helper.readHexOctet(); - do_check_eq(expectedNumber, iccHelper.readDiallingNumber(numLen)); - for (let i = 0; i < (ADN_MAX_BCD_NUMBER_BYTES - numLen); i++) { - do_check_eq(0xff, helper.readHexOctet()); - } - } - - // without + - test("123456789"); - - // with + - test("+987654321"); - - // extended BCD coding - test("1*2#3,4*5#6,"); - - // with + and extended BCD coding - test("+1*2#3,4*5#6,"); - - // non-supported characters should not be written. - test("(1)23-456+789", "123456789"); - - test("++(01)2*3-4#5,6+7(8)9*0#1,", "+012*34#5,6789*0#1,"); - - // null - iccHelper.writeNumberWithLength(null); - for (let i = 0; i < (ADN_MAX_BCD_NUMBER_BYTES + 1); i++) { - do_check_eq(0xff, helper.readHexOctet()); - } - - run_next_test(); -}); - -/** - * Verify GsmPDUHelper.writeTimestamp - */ -add_test(function test_write_timestamp() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - - // current date - let dateInput = new Date(); - let dateOutput = new Date(); - helper.writeTimestamp(dateInput); - dateOutput.setTime(helper.readTimestamp()); - - do_check_eq(dateInput.getFullYear(), dateOutput.getFullYear()); - do_check_eq(dateInput.getMonth(), dateOutput.getMonth()); - do_check_eq(dateInput.getDate(), dateOutput.getDate()); - do_check_eq(dateInput.getHours(), dateOutput.getHours()); - do_check_eq(dateInput.getMinutes(), dateOutput.getMinutes()); - do_check_eq(dateInput.getSeconds(), dateOutput.getSeconds()); - do_check_eq(dateInput.getTimezoneOffset(), dateOutput.getTimezoneOffset()); - - // 2034-01-23 12:34:56 -0800 GMT - let time = Date.UTC(2034, 1, 23, 12, 34, 56); - time = time - (8 * 60 * 60 * 1000); - dateInput.setTime(time); - helper.writeTimestamp(dateInput); - dateOutput.setTime(helper.readTimestamp()); - - do_check_eq(dateInput.getFullYear(), dateOutput.getFullYear()); - do_check_eq(dateInput.getMonth(), dateOutput.getMonth()); - do_check_eq(dateInput.getDate(), dateOutput.getDate()); - do_check_eq(dateInput.getHours(), dateOutput.getHours()); - do_check_eq(dateInput.getMinutes(), dateOutput.getMinutes()); - do_check_eq(dateInput.getSeconds(), dateOutput.getSeconds()); - do_check_eq(dateInput.getTimezoneOffset(), dateOutput.getTimezoneOffset()); - - run_next_test(); -}); - -/** - * Verify GsmPDUHelper.octectToBCD and GsmPDUHelper.BCDToOctet - */ -add_test(function test_octect_BCD() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - - // 23 - let number = 23; - let octet = helper.BCDToOctet(number); - do_check_eq(helper.octetToBCD(octet), number); - - // 56 - number = 56; - octet = helper.BCDToOctet(number); - do_check_eq(helper.octetToBCD(octet), number); - - // 0x23 - octet = 0x23; - number = helper.octetToBCD(octet); - do_check_eq(helper.BCDToOctet(number), octet); - - // 0x56 - octet = 0x56; - number = helper.octetToBCD(octet); - do_check_eq(helper.BCDToOctet(number), octet); - - run_next_test(); -}); - -/** - * Verify ICCUtilsHelper.isICCServiceAvailable. - */ -add_test(function test_is_icc_service_available() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ICCUtilsHelper = context.ICCUtilsHelper; - let RIL = context.RIL; - - function test_table(sst, geckoService, simEnabled, usimEnabled) { - RIL.iccInfoPrivate.sst = sst; - RIL.appType = CARD_APPTYPE_SIM; - do_check_eq(ICCUtilsHelper.isICCServiceAvailable(geckoService), simEnabled); - RIL.appType = CARD_APPTYPE_USIM; - do_check_eq(ICCUtilsHelper.isICCServiceAvailable(geckoService), usimEnabled); - } - - test_table([0x08], "ADN", true, false); - test_table([0x08], "FDN", false, false); - test_table([0x08], "SDN", false, true); - - run_next_test(); -}); - -/** - * Verify ICCUtilsHelper.isGsm8BitAlphabet - */ -add_test(function test_is_gsm_8bit_alphabet() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ICCUtilsHelper = context.ICCUtilsHelper; - const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; - const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; - - do_check_eq(ICCUtilsHelper.isGsm8BitAlphabet(langTable), true); - do_check_eq(ICCUtilsHelper.isGsm8BitAlphabet(langShiftTable), true); - do_check_eq(ICCUtilsHelper.isGsm8BitAlphabet("\uaaaa"), false); - - run_next_test(); -}); - -/** - * Verify RIL.iccGetCardLockState("fdn") - */ -add_test(function test_icc_get_card_lock_state_fdn() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - let buf = context.Buf; - - buf.sendParcel = function() { - // Request Type. - do_check_eq(this.readInt32(), REQUEST_QUERY_FACILITY_LOCK) - - // Token : we don't care. - this.readInt32(); - - // String Array Length. - do_check_eq(this.readInt32(), ril.v5Legacy ? 3 : 4); - - // Facility. - do_check_eq(this.readString(), ICC_CB_FACILITY_FDN); - - // 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()); - - if (!ril.v5Legacy) { - // AID. Ignore because it's from modem. - this.readInt32(); - } - - run_next_test(); - }; - - ril.iccGetCardLockState({lockType: "fdn"}); -}); - -add_test(function test_get_network_name_from_icc() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let RIL = context.RIL; - let ICCUtilsHelper = context.ICCUtilsHelper; - - function testGetNetworkNameFromICC(operatorData, expectedResult) { - let result = ICCUtilsHelper.getNetworkNameFromICC(operatorData.mcc, - operatorData.mnc, - operatorData.lac); - - if (expectedResult == null) { - do_check_eq(result, expectedResult); - } else { - do_check_eq(result.fullName, expectedResult.longName); - do_check_eq(result.shortName, expectedResult.shortName); - } - } - - // Before EF_OPL and EF_PNN have been loaded. - testGetNetworkNameFromICC({mcc: 123, mnc: 456, lac: 0x1000}, null); - testGetNetworkNameFromICC({mcc: 321, mnc: 654, lac: 0x2000}, null); - - // Set HPLMN - RIL.iccInfo.mcc = 123; - RIL.iccInfo.mnc = 456; - - RIL.voiceRegistrationState = { - cell: { - gsmLocationAreaCode: 0x1000 - } - }; - RIL.operator = {}; - - // Set EF_PNN - RIL.iccInfoPrivate = { - PNN: [ - {"fullName": "PNN1Long", "shortName": "PNN1Short"}, - {"fullName": "PNN2Long", "shortName": "PNN2Short"}, - {"fullName": "PNN3Long", "shortName": "PNN3Short"}, - {"fullName": "PNN4Long", "shortName": "PNN4Short"} - ] - }; - - // EF_OPL isn't available and current isn't in HPLMN, - testGetNetworkNameFromICC({mcc: 321, mnc: 654, lac: 0x1000}, null); - - // EF_OPL isn't available and current is in HPLMN, - // the first record of PNN should be returned. - testGetNetworkNameFromICC({mcc: 123, mnc: 456, lac: 0x1000}, - {longName: "PNN1Long", shortName: "PNN1Short"}); - - // Set EF_OPL - RIL.iccInfoPrivate.OPL = [ - { - "mcc": 123, - "mnc": 456, - "lacTacStart": 0, - "lacTacEnd": 0xFFFE, - "pnnRecordId": 4 - }, - { - "mcc": 321, - "mnc": 654, - "lacTacStart": 0, - "lacTacEnd": 0x0010, - "pnnRecordId": 3 - }, - { - "mcc": 321, - "mnc": 654, - "lacTacStart": 0x0100, - "lacTacEnd": 0x1010, - "pnnRecordId": 2 - } - ]; - - // Both EF_PNN and EF_OPL are presented, and current PLMN is HPLMN, - testGetNetworkNameFromICC({mcc: 123, mnc: 456, lac: 0x1000}, - {longName: "PNN4Long", shortName: "PNN4Short"}); - - // Current PLMN is not HPLMN, and according to LAC, we should get - // the second PNN record. - testGetNetworkNameFromICC({mcc: 321, mnc: 654, lac: 0x1000}, - {longName: "PNN2Long", shortName: "PNN2Short"}); - - // Current PLMN is not HPLMN, and according to LAC, we should get - // the thrid PNN record. - testGetNetworkNameFromICC({mcc: 321, mnc: 654, lac: 0x0001}, - {longName: "PNN3Long", shortName: "PNN3Short"}); - - run_next_test(); -}); - -add_test(function test_path_id_for_spid_and_spn() { - let worker = newWorker({ - postRILMessage: function(data) { - // Do nothing - }, - postMessage: function(message) { - // Do nothing - }}); - let context = worker.ContextPool._contexts[0]; - let RIL = context.RIL; - let ICCFileHelper = context.ICCFileHelper; - - // Test SIM - RIL.appType = CARD_APPTYPE_SIM; - do_check_eq(ICCFileHelper.getEFPath(ICC_EF_SPDI), - EF_PATH_MF_SIM + EF_PATH_DF_GSM); - do_check_eq(ICCFileHelper.getEFPath(ICC_EF_SPN), - EF_PATH_MF_SIM + EF_PATH_DF_GSM); - - // Test USIM - RIL.appType = CARD_APPTYPE_USIM; - 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 ICCUtilsHelper.parsePbrTlvs - */ -add_test(function test_parse_pbr_tlvs() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let buf = context.Buf; - - let pbrTlvs = [ - {tag: ICC_USIM_TYPE1_TAG, - length: 0x0F, - value: [{tag: ICC_USIM_EFADN_TAG, - length: 0x03, - value: [0x4F, 0x3A, 0x02]}, - {tag: ICC_USIM_EFIAP_TAG, - length: 0x03, - value: [0x4F, 0x25, 0x01]}, - {tag: ICC_USIM_EFPBC_TAG, - length: 0x03, - value: [0x4F, 0x09, 0x04]}] - }, - {tag: ICC_USIM_TYPE2_TAG, - length: 0x05, - value: [{tag: ICC_USIM_EFEMAIL_TAG, - length: 0x03, - value: [0x4F, 0x50, 0x0B]}, - {tag: ICC_USIM_EFANR_TAG, - length: 0x03, - value: [0x4F, 0x11, 0x02]}, - {tag: ICC_USIM_EFANR_TAG, - length: 0x03, - value: [0x4F, 0x12, 0x03]}] - }, - {tag: ICC_USIM_TYPE3_TAG, - length: 0x0A, - value: [{tag: ICC_USIM_EFCCP1_TAG, - length: 0x03, - value: [0x4F, 0x3D, 0x0A]}, - {tag: ICC_USIM_EFEXT1_TAG, - length: 0x03, - value: [0x4F, 0x4A, 0x03]}] - }, - ]; - - let pbr = context.ICCUtilsHelper.parsePbrTlvs(pbrTlvs); - do_check_eq(pbr.adn.fileId, 0x4F3a); - do_check_eq(pbr.iap.fileId, 0x4F25); - do_check_eq(pbr.pbc.fileId, 0x4F09); - do_check_eq(pbr.email.fileId, 0x4F50); - do_check_eq(pbr.anr0.fileId, 0x4f11); - do_check_eq(pbr.anr1.fileId, 0x4f12); - do_check_eq(pbr.ccp1.fileId, 0x4F3D); - do_check_eq(pbr.ext1.fileId, 0x4F4A); - - run_next_test(); -}); - -/** - * Verify ICCIOHelper.loadLinearFixedEF with recordSize. - */ -add_test(function test_load_linear_fixed_ef() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - let io = context.ICCIOHelper; - - io.getResponse = function fakeGetResponse(options) { - // When recordSize is provided, loadLinearFixedEF should call iccIO directly. - do_check_true(false); - run_next_test(); - }; - - ril.iccIO = function fakeIccIO(options) { - do_check_true(true); - run_next_test(); - }; - - io.loadLinearFixedEF({recordSize: 0x20}); -}); - -/** - * Verify ICCIOHelper.loadLinearFixedEF without recordSize. - */ -add_test(function test_load_linear_fixed_ef() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - let io = context.ICCIOHelper; - - io.getResponse = function fakeGetResponse(options) { - do_check_true(true); - run_next_test(); - }; - - ril.iccIO = function fakeIccIO(options) { - // When recordSize is not provided, loadLinearFixedEF should call getResponse. - do_check_true(false); - run_next_test(); - }; - - io.loadLinearFixedEF({}); -}); - -/** - * Verify ICCRecordHelper.readPBR - */ -add_test(function test_read_pbr() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let record = context.ICCRecordHelper; - let buf = context.Buf; - let io = context.ICCIOHelper; - - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - let pbr_1 = [ - 0xa8, 0x05, 0xc0, 0x03, 0x4f, 0x3a, 0x01 - ]; - - // Write data size - buf.writeInt32(pbr_1.length * 2); - - // Write pbr - for (let i = 0; i < pbr_1.length; i++) { - helper.writeHexOctet(pbr_1[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(pbr_1.length * 2); - - options.totalRecords = 2; - if (options.callback) { - options.callback(options); - } - }; - - io.loadNextRecord = function fakeLoadNextRecord(options) { - let pbr_2 = [ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff - ]; - - options.p1++; - if (options.callback) { - options.callback(options); - } - }; - - let successCb = function successCb(pbrs) { - do_check_eq(pbrs[0].adn.fileId, 0x4f3a); - do_check_eq(pbrs.length, 1); - }; - - let errorCb = function errorCb(errorMsg) { - do_print("Reading EF_PBR failed, msg = " + errorMsg); - do_check_true(false); - }; - - record.readPBR(successCb, errorCb); - - // Check cache pbrs when 2nd call - let ifLoadEF = false; - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - ifLoadEF = true; - } - record.readPBR(successCb, errorCb); - do_check_false(ifLoadEF); - - run_next_test(); -}); - -/** - * Verify ICCRecordHelper.readEmail - */ -add_test(function test_read_email() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let record = context.ICCRecordHelper; - let buf = context.Buf; - let io = context.ICCIOHelper; - let recordSize; - - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - let email_1 = [ - 0x65, 0x6D, 0x61, 0x69, 0x6C, - 0x00, 0x6D, 0x6F, 0x7A, 0x69, - 0x6C, 0x6C, 0x61, 0x2E, 0x63, - 0x6F, 0x6D, 0x02, 0x23]; - - // Write data size - buf.writeInt32(email_1.length * 2); - - // Write email - for (let i = 0; i < email_1.length; i++) { - helper.writeHexOctet(email_1[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(email_1.length * 2); - - recordSize = email_1.length; - options.recordSize = recordSize; - if (options.callback) { - options.callback(options); - } - }; - - function doTestReadEmail(type, expectedResult) { - let fileId = 0x6a75; - let recordNumber = 1; - - // fileId and recordNumber are dummy arguments. - record.readEmail(fileId, type, recordNumber, function(email) { - do_check_eq(email, expectedResult); - }); - }; - - doTestReadEmail(ICC_USIM_TYPE1_TAG, "email@mozilla.com$#"); - doTestReadEmail(ICC_USIM_TYPE2_TAG, "email@mozilla.com"); - do_check_eq(record._emailRecordSize, recordSize); - - run_next_test(); -}); - -/** - * Verify ICCRecordHelper.updateEmail - */ -add_test(function test_update_email() { - const recordSize = 0x20; - const recordNumber = 1; - const fileId = 0x4f50; - const NUM_TESTS = 2; - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let pduHelper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - let ril = context.RIL; - ril.appType = CARD_APPTYPE_USIM; - let recordHelper = context.ICCRecordHelper; - let buf = context.Buf; - let ioHelper = context.ICCIOHelper; - let pbr = {email: {fileId: fileId, fileType: ICC_USIM_TYPE1_TAG}, - adn: {sfi: 1}}; - let count = 0; - - // Override. - ioHelper.updateLinearFixedEF = function(options) { - options.pathId = context.ICCFileHelper.getEFPath(options.fileId); - options.command = ICC_COMMAND_UPDATE_RECORD; - options.p1 = options.recordNumber; - options.p2 = READ_RECORD_ABSOLUTE_MODE; - options.p3 = recordSize; - ril.iccIO(options); - }; - - function do_test(pbr, expectedEmail, expectedAdnRecordId) { - buf.sendParcel = function() { - count++; - - // Request Type. - do_check_eq(this.readInt32(), REQUEST_SIM_IO); - - // Token : we don't care - this.readInt32(); - - // command. - do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD); - - // fileId. - do_check_eq(this.readInt32(), fileId); - - // pathId. - do_check_eq(this.readString(), - EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK); - - // p1. - do_check_eq(this.readInt32(), recordNumber); - - // p2. - do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE); - - // p3. - do_check_eq(this.readInt32(), recordSize); - - // data. - let strLen = this.readInt32(); - let email; - if (pbr.email.fileType === ICC_USIM_TYPE1_TAG) { - email = iccHelper.read8BitUnpackedToString(recordSize); - } else { - email = iccHelper.read8BitUnpackedToString(recordSize - 2); - do_check_eq(pduHelper.readHexOctet(), pbr.adn.sfi); - do_check_eq(pduHelper.readHexOctet(), expectedAdnRecordId); - } - this.readStringDelimiter(strLen); - do_check_eq(email, expectedEmail); - - // pin2. - do_check_eq(this.readString(), null); - - if (!ril.v5Legacy) { - // AID. Ignore because it's from modem. - this.readInt32(); - } - - if (count == NUM_TESTS) { - run_next_test(); - } - }; - recordHelper.updateEmail(pbr, recordNumber, expectedEmail, expectedAdnRecordId); - } - - do_test(pbr, "test@mail.com"); - pbr.email.fileType = ICC_USIM_TYPE2_TAG; - do_test(pbr, "test@mail.com", 1); -}); - -/** - * Verify ICCRecordHelper.readANR - */ -add_test(function test_read_anr() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let record = context.ICCRecordHelper; - let buf = context.Buf; - let io = context.ICCIOHelper; - let recordSize; - - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - let anr_1 = [ - 0x01, 0x05, 0x81, 0x10, 0x32, - 0x54, 0xF6, 0xFF, 0xFF]; - - // Write data size - buf.writeInt32(anr_1.length * 2); - - // Write anr - for (let i = 0; i < anr_1.length; i++) { - helper.writeHexOctet(anr_1[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(anr_1.length * 2); - - recordSize = anr_1.length; - options.recordSize = recordSize; - if (options.callback) { - options.callback(options); - } - }; - - function doTestReadAnr(fileType, expectedResult) { - let fileId = 0x4f11; - let recordNumber = 1; - - // fileId and recordNumber are dummy arguments. - record.readANR(fileId, fileType, recordNumber, function(anr) { - do_check_eq(anr, expectedResult); - }); - }; - - doTestReadAnr(ICC_USIM_TYPE1_TAG, "0123456"); - do_check_eq(record._anrRecordSize, recordSize); - - run_next_test(); -}); - -/** - * Verify ICCRecordHelper.updateANR - */ -add_test(function test_update_anr() { - const recordSize = 0x20; - const recordNumber = 1; - const fileId = 0x4f11; - const NUM_TESTS = 2; - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let pduHelper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - let ril = context.RIL; - ril.appType = CARD_APPTYPE_USIM; - let recordHelper = context.ICCRecordHelper; - let buf = context.Buf; - let ioHelper = context.ICCIOHelper; - let pbr = {anr0: {fileId: fileId, fileType: ICC_USIM_TYPE1_TAG}, - adn: {sfi: 1}}; - let count = 0; - - // Override. - ioHelper.updateLinearFixedEF = function(options) { - options.pathId = context.ICCFileHelper.getEFPath(options.fileId); - options.command = ICC_COMMAND_UPDATE_RECORD; - options.p1 = options.recordNumber; - options.p2 = READ_RECORD_ABSOLUTE_MODE; - options.p3 = recordSize; - ril.iccIO(options); - }; - - function do_test(pbr, expectedANR, expectedAdnRecordId) { - buf.sendParcel = function() { - count++; - - // Request Type. - do_check_eq(this.readInt32(), REQUEST_SIM_IO); - - // Token : we don't care - this.readInt32(); - - // command. - do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD); - - // fileId. - do_check_eq(this.readInt32(), fileId); - - // pathId. - do_check_eq(this.readString(), - EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK); - - // p1. - do_check_eq(this.readInt32(), recordNumber); - - // p2. - do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE); - - // p3. - do_check_eq(this.readInt32(), recordSize); - - // data. - let strLen = this.readInt32(); - // EF_AAS, ignore. - pduHelper.readHexOctet(); - do_check_eq(iccHelper.readNumberWithLength(), expectedANR); - // EF_CCP, ignore. - pduHelper.readHexOctet(); - // EF_EXT1, ignore. - pduHelper.readHexOctet(); - if (pbr.anr0.fileType === ICC_USIM_TYPE2_TAG) { - do_check_eq(pduHelper.readHexOctet(), pbr.adn.sfi); - do_check_eq(pduHelper.readHexOctet(), expectedAdnRecordId); - } - this.readStringDelimiter(strLen); - - // pin2. - do_check_eq(this.readString(), null); - - if (!ril.v5Legacy) { - // AID. Ignore because it's from modem. - this.readInt32(); - } - - if (count == NUM_TESTS) { - run_next_test(); - } - }; - recordHelper.updateANR(pbr, recordNumber, expectedANR, expectedAdnRecordId); - } - - do_test(pbr, "+123456789"); - pbr.anr0.fileType = ICC_USIM_TYPE2_TAG; - do_test(pbr, "123456789", 1); -}); - -/** - * Verify ICCRecordHelper.readIAP - */ -add_test(function test_read_iap() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let record = context.ICCRecordHelper; - let buf = context.Buf; - let io = context.ICCIOHelper; - let recordSize; - - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - let iap_1 = [0x01, 0x02]; - - // Write data size/ - buf.writeInt32(iap_1.length * 2); - - // Write iap. - for (let i = 0; i < iap_1.length; i++) { - helper.writeHexOctet(iap_1[i]); - } - - // Write string delimiter. - buf.writeStringDelimiter(iap_1.length * 2); - - recordSize = iap_1.length; - options.recordSize = recordSize; - if (options.callback) { - options.callback(options); - } - }; - - function doTestReadIAP(expectedIAP) { - const fileId = 0x4f17; - const recordNumber = 1; - - let successCb = function successCb(iap) { - for (let i = 0; i < iap.length; i++) { - do_check_eq(expectedIAP[i], iap[i]); - } - run_next_test(); - }.bind(this); - - let errorCb = function errorCb(errorMsg) { - do_print(errorMsg); - do_check_true(false); - run_next_test(); - }.bind(this); - - record.readIAP(fileId, recordNumber, successCb, errorCb); - }; - - doTestReadIAP([1, 2]); -}); - -/** - * Verify ICCRecordHelper.updateIAP - */ -add_test(function test_update_iap() { - const recordSize = 2; - const recordNumber = 1; - const fileId = 0x4f17; - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let pduHelper = context.GsmPDUHelper; - let ril = context.RIL; - ril.appType = CARD_APPTYPE_USIM; - let recordHelper = context.ICCRecordHelper; - let buf = context.Buf; - let ioHelper = context.ICCIOHelper; - let count = 0; - - // Override. - ioHelper.updateLinearFixedEF = function(options) { - options.pathId = context.ICCFileHelper.getEFPath(options.fileId); - options.command = ICC_COMMAND_UPDATE_RECORD; - options.p1 = options.recordNumber; - options.p2 = READ_RECORD_ABSOLUTE_MODE; - options.p3 = recordSize; - ril.iccIO(options); - }; - - function do_test(expectedIAP) { - buf.sendParcel = function() { - // Request Type. - do_check_eq(this.readInt32(), REQUEST_SIM_IO); - - // Token : we don't care - this.readInt32(); - - // command. - do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD); - - // fileId. - do_check_eq(this.readInt32(), fileId); - - // pathId. - do_check_eq(this.readString(), - EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK); - - // p1. - do_check_eq(this.readInt32(), recordNumber); - - // p2. - do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE); - - // p3. - do_check_eq(this.readInt32(), recordSize); - - // data. - let strLen = this.readInt32(); - for (let i = 0; i < recordSize; i++) { - do_check_eq(expectedIAP[i], pduHelper.readHexOctet()); - } - this.readStringDelimiter(strLen); - - // pin2. - do_check_eq(this.readString(), null); - - if (!ril.v5Legacy) { - // AID. Ignore because it's from modem. - this.readInt32(); - } - - run_next_test(); - }; - recordHelper.updateIAP(fileId, recordNumber, expectedIAP); - } - - do_test([1, 2]); -}); - -/** - * Verify ICCRecordHelper.updateADNLike. - */ -add_test(function test_update_adn_like() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - let record = context.ICCRecordHelper; - let io = context.ICCIOHelper; - let pdu = context.ICCPDUHelper; - let buf = context.Buf; - - ril.appType = CARD_APPTYPE_SIM; - const recordSize = 0x20; - let fileId; - - // Override. - io.updateLinearFixedEF = function(options) { - options.pathId = context.ICCFileHelper.getEFPath(options.fileId); - options.command = ICC_COMMAND_UPDATE_RECORD; - options.p1 = options.recordNumber; - options.p2 = READ_RECORD_ABSOLUTE_MODE; - options.p3 = recordSize; - ril.iccIO(options); - }; - - buf.sendParcel = function() { - // Request Type. - do_check_eq(this.readInt32(), REQUEST_SIM_IO); - - // Token : we don't care - this.readInt32(); - - // command. - do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD); - - // fileId. - do_check_eq(this.readInt32(), fileId); - - // pathId. - do_check_eq(this.readString(), EF_PATH_MF_SIM + EF_PATH_DF_TELECOM); - - // p1. - do_check_eq(this.readInt32(), 1); - - // p2. - do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE); - - // p3. - do_check_eq(this.readInt32(), 0x20); - - // data. - let contact = pdu.readAlphaIdDiallingNumber(0x20); - do_check_eq(contact.alphaId, "test"); - do_check_eq(contact.number, "123456"); - - // pin2. - if (fileId == ICC_EF_ADN) { - do_check_eq(this.readString(), null); - } else { - do_check_eq(this.readString(), "1111"); - } - - if (!ril.v5Legacy) { - // AID. Ignore because it's from modem. - this.readInt32(); - } - - if (fileId == ICC_EF_FDN) { - run_next_test(); - } - }; - - fileId = ICC_EF_ADN; - record.updateADNLike(fileId, - {recordId: 1, alphaId: "test", number: "123456"}); - - fileId = ICC_EF_FDN; - record.updateADNLike(fileId, - {recordId: 1, alphaId: "test", number: "123456"}, - "1111"); -}); - -/** - * Verify ICCRecordHelper.findFreeRecordId. - */ -add_test(function test_find_free_record_id() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let pduHelper = context.GsmPDUHelper; - let recordHelper = context.ICCRecordHelper; - let buf = context.Buf; - let io = context.ICCIOHelper; - - function writeRecord (record) { - // Write data size - buf.writeInt32(record.length * 2); - - for (let i = 0; i < record.length; i++) { - pduHelper.writeHexOctet(record[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(record.length * 2); - } - - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - // Some random data. - let record = [0x12, 0x34, 0x56, 0x78, 0x90]; - options.p1 = 1; - options.totalRecords = 2; - writeRecord(record); - if (options.callback) { - options.callback(options); - } - }; - - io.loadNextRecord = function fakeLoadNextRecord(options) { - // Unused bytes. - let record = [0xff, 0xff, 0xff, 0xff, 0xff]; - options.p1++; - writeRecord(record); - if (options.callback) { - options.callback(options); - } - }; - - let fileId = 0x0000; // Dummy. - recordHelper.findFreeRecordId( - fileId, - function(recordId) { - do_check_eq(recordId, 2); - run_next_test(); - }.bind(this), - function(errorMsg) { - do_print(errorMsg); - do_check_true(false); - run_next_test(); - }.bind(this)); -}); - -/** - * Verify ICCContactHelper.readICCContacts - */ -add_test(function test_read_icc_contacts() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let record = context.ICCRecordHelper; - let contactHelper = context.ICCContactHelper; - let ril = context.RIL; - - function do_test(aSimType, aContactType, aExpectedContact, aEnhancedPhoneBook) { - ril.appType = aSimType; - ril._isCdma = (aSimType === CARD_APPTYPE_RUIM); - ril.iccInfoPrivate.cst = (aEnhancedPhoneBook) ? - [0x0, 0x0C, 0x0, 0x0, 0x0]: - [0x0, 0x00, 0x0, 0x0, 0x0]; - - // Override some functions to test. - contactHelper.getContactFieldRecordId = function(pbr, contact, field, onsuccess, onerror) { - onsuccess(1); - }; - - record.readPBR = function readPBR(onsuccess, onerror) { - onsuccess([{adn:{fileId: 0x6f3a}, email: {}, anr0: {}}]); - }; - - record.readADNLike = function readADNLike(fileId, onsuccess, onerror) { - onsuccess([{recordId: 1, alphaId: "name", number: "111111"}]) - }; - - record.readEmail = function readEmail(fileId, fileType, recordNumber, onsuccess, onerror) { - onsuccess("hello@mail.com"); - }; - - record.readANR = function readANR(fileId, fileType, recordNumber, onsuccess, onerror) { - onsuccess("123456"); - }; - - let onsuccess = function onsuccess(contacts) { - let contact = contacts[0]; - for (let key in contact) { - do_print("check " + key); - if (Array.isArray(contact[key])) { - do_check_eq(contact[key][0], aExpectedContact[key]); - } else { - do_check_eq(contact[key], aExpectedContact[key]); - } - } - }; - - let onerror = function onerror(errorMsg) { - do_print("readICCContacts failed: " + errorMsg); - do_check_true(false); - }; - - contactHelper.readICCContacts(aSimType, aContactType, onsuccess, onerror); - } - - let expectedContact1 = { - pbrIndex: 0, - recordId: 1, - alphaId: "name", - number: "111111" - }; - - let expectedContact2 = { - pbrIndex: 0, - recordId: 1, - alphaId: "name", - number: "111111", - email: "hello@mail.com", - anr: "123456" - }; - - // SIM - do_print("Test read SIM adn contacts"); - do_test(CARD_APPTYPE_SIM, "adn", expectedContact1); - - do_print("Test read SIM fdn contacts"); - do_test(CARD_APPTYPE_SIM, "fdn", expectedContact1); - - // USIM - do_print("Test read USIM adn contacts"); - do_test(CARD_APPTYPE_USIM, "adn", expectedContact2); - - do_print("Test read USIM fdn contacts"); - do_test(CARD_APPTYPE_USIM, "fdn", expectedContact1); - - // RUIM - do_print("Test read RUIM adn contacts"); - do_test(CARD_APPTYPE_RUIM, "adn", expectedContact1); - - do_print("Test read RUIM fdn contacts"); - do_test(CARD_APPTYPE_RUIM, "fdn", expectedContact1); - - // RUIM with enhanced phone book - do_print("Test read RUIM adn contacts with enhanced phone book"); - do_test(CARD_APPTYPE_RUIM, "adn", expectedContact2, true); - - do_print("Test read RUIM fdn contacts with enhanced phone book"); - do_test(CARD_APPTYPE_RUIM, "fdn", expectedContact1, true); - - run_next_test(); -}); - -/** - * Verify ICCContactHelper.updateICCContact with appType is CARD_APPTYPE_USIM. - */ -add_test(function test_update_icc_contact() { - const ADN_RECORD_ID = 100; - const ADN_SFI = 1; - const IAP_FILE_ID = 0x4f17; - const EMAIL_FILE_ID = 0x4f50; - const EMAIL_RECORD_ID = 20; - const ANR0_FILE_ID = 0x4f11; - const ANR0_RECORD_ID = 30; - - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let recordHelper = context.ICCRecordHelper; - let contactHelper = context.ICCContactHelper; - let ril = context.RIL; - - function do_test(aSimType, aContactType, aContact, aPin2, aFileType, aHaveIapIndex, aEnhancedPhoneBook) { - ril.appType = aSimType; - ril._isCdma = (aSimType === CARD_APPTYPE_RUIM); - ril.iccInfoPrivate.cst = (aEnhancedPhoneBook) ? [0x0, 0x0C, 0x0, 0x0, 0x0] - : [0x0, 0x00, 0x0, 0x0, 0x0]; - - recordHelper.readPBR = function(onsuccess, onerror) { - if (aFileType === ICC_USIM_TYPE1_TAG) { - onsuccess([{ - adn: {fileId: ICC_EF_ADN}, - email: {fileId: EMAIL_FILE_ID, - fileType: ICC_USIM_TYPE1_TAG}, - anr0: {fileId: ANR0_FILE_ID, - fileType: ICC_USIM_TYPE1_TAG} - }]); - } else if (aFileType === ICC_USIM_TYPE2_TAG) { - onsuccess([{ - adn: {fileId: ICC_EF_ADN, - sfi: ADN_SFI}, - iap: {fileId: IAP_FILE_ID}, - email: {fileId: EMAIL_FILE_ID, - fileType: ICC_USIM_TYPE2_TAG, - indexInIAP: 0}, - anr0: {fileId: ANR0_FILE_ID, - fileType: ICC_USIM_TYPE2_TAG, - indexInIAP: 1} - }]); - } - }; - - recordHelper.updateADNLike = function(fileId, contact, pin2, onsuccess, onerror) { - if (aContactType === "fdn") { - do_check_eq(fileId, ICC_EF_FDN); - } else if (aContactType === "adn") { - do_check_eq(fileId, ICC_EF_ADN); - } - do_check_eq(pin2, aPin2); - do_check_eq(contact.alphaId, aContact.alphaId); - do_check_eq(contact.number, aContact.number); - onsuccess(); - }; - - recordHelper.readIAP = function(fileId, recordNumber, onsuccess, onerror) { - do_check_eq(fileId, IAP_FILE_ID); - do_check_eq(recordNumber, ADN_RECORD_ID); - onsuccess((aHaveIapIndex) ? [EMAIL_RECORD_ID, ANR0_RECORD_ID] - : [0xff, 0xff]); - }; - - recordHelper.updateIAP = function(fileId, recordNumber, iap, onsuccess, onerror) { - do_check_eq(fileId, IAP_FILE_ID); - do_check_eq(recordNumber, ADN_RECORD_ID); - onsuccess(); - }; - - recordHelper.updateEmail = function(pbr, recordNumber, email, adnRecordId, onsuccess, onerror) { - do_check_eq(pbr.email.fileId, EMAIL_FILE_ID); - if (pbr.email.fileType === ICC_USIM_TYPE1_TAG) { - do_check_eq(recordNumber, ADN_RECORD_ID); - } else if (pbr.email.fileType === ICC_USIM_TYPE2_TAG) { - do_check_eq(recordNumber, EMAIL_RECORD_ID); - } - do_check_eq(email, aContact.email); - onsuccess(); - }; - - recordHelper.updateANR = function(pbr, recordNumber, number, adnRecordId, onsuccess, onerror) { - do_check_eq(pbr.anr0.fileId, ANR0_FILE_ID); - if (pbr.anr0.fileType === ICC_USIM_TYPE1_TAG) { - do_check_eq(recordNumber, ADN_RECORD_ID); - } else if (pbr.anr0.fileType === ICC_USIM_TYPE2_TAG) { - do_check_eq(recordNumber, ANR0_RECORD_ID); - } - if (Array.isArray(aContact.anr)) { - do_check_eq(number, aContact.anr[0]); - } - onsuccess(); - }; - - recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) { - let recordId = 0; - if (fileId === EMAIL_FILE_ID) { - recordId = EMAIL_RECORD_ID; - } else if (fileId === ANR0_FILE_ID) { - recordId = ANR0_RECORD_ID; - } - onsuccess(recordId); - }; - - let isSuccess = false; - let onsuccess = function onsuccess() { - do_print("updateICCContact success"); - isSuccess = true; - }; - - let onerror = function onerror(errorMsg) { - do_print("updateICCContact failed: " + errorMsg); - }; - - contactHelper.updateICCContact(aSimType, aContactType, aContact, aPin2, onsuccess, onerror); - do_check_true(isSuccess); - } - - let contacts = [ - { - pbrIndex: 0, - recordId: ADN_RECORD_ID, - alphaId: "test", - number: "123456", - email: "test@mail.com", - anr: ["+654321"] - }, - // a contact without email and anr. - { - pbrIndex: 0, - recordId: ADN_RECORD_ID, - alphaId: "test2", - number: "123456", - }, - // a contact with email but no anr. - { - pbrIndex: 0, - recordId: ADN_RECORD_ID, - alphaId: "test3", - number: "123456", - email: "test@mail.com" - }, - // a contact with anr but no email. - { - pbrIndex: 0, - recordId: ADN_RECORD_ID, - alphaId: "test4", - number: "123456", - anr: ["+654321"] - }]; - - for (let i = 0; i < contacts.length; i++) { - let contact = contacts[i]; - // SIM - do_print("Test update SIM adn contacts"); - do_test(CARD_APPTYPE_SIM, "adn", contact); - - do_print("Test update SIM fdn contacts"); - do_test(CARD_APPTYPE_SIM, "fdn", contact, "1234"); - - // USIM - do_print("Test update USIM adn contacts"); - do_test(CARD_APPTYPE_USIM, "adn", contact, null, ICC_USIM_TYPE1_TAG); - do_test(CARD_APPTYPE_USIM, "adn", contact, null, ICC_USIM_TYPE2_TAG, true); - do_test(CARD_APPTYPE_USIM, "adn", contact, null, ICC_USIM_TYPE2_TAG, false); - - do_print("Test update USIM fdn contacts"); - do_test(CARD_APPTYPE_USIM, "fdn", contact, "1234"); - - // RUIM - do_print("Test update RUIM adn contacts"); - do_test(CARD_APPTYPE_RUIM, "adn", contact); - - do_print("Test update RUIM fdn contacts"); - do_test(CARD_APPTYPE_RUIM, "fdn", contact, "1234"); - - // RUIM with enhanced phone book - do_print("Test update RUIM adn contacts with enhanced phone book"); - do_test(CARD_APPTYPE_RUIM, "adn", contact, null, ICC_USIM_TYPE1_TAG, null, true); - do_test(CARD_APPTYPE_RUIM, "adn", contact, null, ICC_USIM_TYPE2_TAG, true, true); - do_test(CARD_APPTYPE_RUIM, "adn", contact, null, ICC_USIM_TYPE2_TAG, false, true); - - do_print("Test update RUIM fdn contacts with enhanced phone book"); - do_test(CARD_APPTYPE_RUIM, "fdn", contact, "1234", null, true); - } - - run_next_test(); -}); - -/** - * Verify updateICCContact with removal of anr and email with File Type 1. - */ -add_test(function test_update_icc_contact_with_remove_type1_attr() { - const ADN_RECORD_ID = 100; - const IAP_FILE_ID = 0x4f17; - const EMAIL_FILE_ID = 0x4f50; - const EMAIL_RECORD_ID = 20; - const ANR0_FILE_ID = 0x4f11; - const ANR0_RECORD_ID = 30; - - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let recordHelper = context.ICCRecordHelper; - let contactHelper = context.ICCContactHelper; - - recordHelper.updateADNLike = function(fileId, contact, pin2, onsuccess, onerror) { - onsuccess(); - }; - - let contact = { - pbrIndex: 0, - recordId: ADN_RECORD_ID, - alphaId: "test2", - number: "123456", - }; - - recordHelper.readIAP = function(fileId, recordNumber, onsuccess, onerror) { - onsuccess([EMAIL_RECORD_ID, ANR0_RECORD_ID]); - }; - - recordHelper.updateEmail = function(pbr, recordNumber, email, adnRecordId, onsuccess, onerror) { - do_check_true(email == null); - onsuccess(); - }; - - recordHelper.updateANR = function(pbr, recordNumber, number, adnRecordId, onsuccess, onerror) { - do_check_true(number == null); - onsuccess(); - }; - - function do_test(type) { - recordHelper.readPBR = function(onsuccess, onerror) { - if (type == ICC_USIM_TYPE1_TAG) { - onsuccess([{ - adn: {fileId: ICC_EF_ADN}, - email: {fileId: EMAIL_FILE_ID, - fileType: ICC_USIM_TYPE1_TAG}, - anr0: {fileId: ANR0_FILE_ID, - fileType: ICC_USIM_TYPE1_TAG}}]); - } else { - onsuccess([{ - adn: {fileId: ICC_EF_ADN}, - iap: {fileId: IAP_FILE_ID}, - email: {fileId: EMAIL_FILE_ID, - fileType: ICC_USIM_TYPE2_TAG, - indexInIAP: 0}, - anr0: {fileId: ANR0_FILE_ID, - fileType: ICC_USIM_TYPE2_TAG, - indexInIAP: 1}}]); - } - }; - - let successCb = function() { - do_check_true(true); - }; - - let errorCb = function(errorMsg) { - do_print(errorMsg); - do_check_true(false); - }; - - contactHelper.updateICCContact(CARD_APPTYPE_USIM, "adn", contact, null, successCb, errorCb); - } - - do_test(ICC_USIM_TYPE1_TAG); - do_test(ICC_USIM_TYPE2_TAG); - - run_next_test(); -}); - -/** - * Verify ICCContactHelper.findFreeICCContact in SIM - */ -add_test(function test_find_free_icc_contact_sim() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let recordHelper = context.ICCRecordHelper; - let contactHelper = context.ICCContactHelper; - // Correct record Id starts with 1, so put a null element at index 0. - let records = [null]; - const MAX_RECORDS = 3; - const PBR_INDEX = 0; - - recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) { - if (records.length > MAX_RECORDS) { - onerror("No free record found."); - return; - } - - onsuccess(records.length); - }; - - let successCb = function(pbrIndex, recordId) { - do_check_eq(pbrIndex, PBR_INDEX); - records[recordId] = {}; - }; - - let errorCb = function(errorMsg) { - do_print(errorMsg); - do_check_true(false); - }; - - for (let i = 0; i < MAX_RECORDS; i++) { - contactHelper.findFreeICCContact(CARD_APPTYPE_SIM, "adn", successCb, errorCb); - } - // The 1st element, records[0], is null. - do_check_eq(records.length - 1, MAX_RECORDS); - - // Now the EF is full, so finding a free one should result failure. - successCb = function(pbrIndex, recordId) { - do_check_true(false); - }; - - errorCb = function(errorMsg) { - do_check_true(errorMsg === "No free record found."); - }; - contactHelper.findFreeICCContact(CARD_APPTYPE_SIM, "adn", successCb, errorCb); - - run_next_test(); -}); - -/** - * Verify ICCContactHelper.findFreeICCContact in USIM - */ -add_test(function test_find_free_icc_contact_usim() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let recordHelper = context.ICCRecordHelper; - let contactHelper = context.ICCContactHelper; - const ADN1_FILE_ID = 0x6f3a; - const ADN2_FILE_ID = 0x6f3b; - const MAX_RECORDS = 3; - - // The adn in the first phonebook set has already two records, which means - // only 1 free record remained. - let pbrs = [{adn: {fileId: ADN1_FILE_ID, records: [null, {}, {}]}}, - {adn: {fileId: ADN2_FILE_ID, records: [null]}}]; - - recordHelper.readPBR = function readPBR(onsuccess, onerror) { - onsuccess(pbrs); - }; - - recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) { - let pbr = (fileId == ADN1_FILE_ID ? pbrs[0]: pbrs[1]); - if (pbr.adn.records.length > MAX_RECORDS) { - onerror("No free record found."); - return; - } - - onsuccess(pbr.adn.records.length); - }; - - let successCb = function(pbrIndex, recordId) { - do_check_eq(pbrIndex, 0); - pbrs[pbrIndex].adn.records[recordId] = {}; - }; - - let errorCb = function(errorMsg) { - do_check_true(false); - }; - - contactHelper.findFreeICCContact(CARD_APPTYPE_USIM, "adn", successCb, errorCb); - - // Now the EF_ADN in the 1st phonebook set is full, so the next free contact - // will come from the 2nd phonebook set. - successCb = function(pbrIndex, recordId) { - do_check_eq(pbrIndex, 1); - do_check_eq(recordId, 1); - } - contactHelper.findFreeICCContact(CARD_APPTYPE_USIM, "adn", successCb, errorCb); - - run_next_test(); -}); - -/** - * Test error message returned in onerror for readICCContacts. - */ -add_test(function test_error_message_read_icc_contact () { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - - function do_test(options, expectedErrorMsg) { - ril.sendChromeMessage = function(message) { - do_check_eq(message.errorMsg, expectedErrorMsg); - } - ril.readICCContacts(options); - } - - // Error 1, didn't specify correct contactType. - do_test({}, CONTACT_ERR_REQUEST_NOT_SUPPORTED); - - // Error 2, specifying a non-supported contactType. - ril.appType = CARD_APPTYPE_USIM; - do_test({contactType: "sdn"}, CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED); - - // Error 3, suppose we update the supported PBR fields in USIM_PBR_FIELDS, - // but forget to add implemenetations for it. - USIM_PBR_FIELDS.push("pbc"); - do_test({contactType: "adn"}, CONTACT_ERR_FIELD_NOT_SUPPORTED); - - run_next_test(); -}); - -/** - * Test error message returned in onerror for updateICCContact. - */ -add_test(function test_error_message_update_icc_contact() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - - const ICCID = "123456789"; - ril.iccInfo.iccid = ICCID; - - function do_test(options, expectedErrorMsg) { - ril.sendChromeMessage = function(message) { - do_check_eq(message.errorMsg, expectedErrorMsg); - } - ril.updateICCContact(options); - } - - // Error 1, didn't specify correct contactType. - do_test({}, CONTACT_ERR_REQUEST_NOT_SUPPORTED); - - // Error 2, specifying a correct contactType, but without providing 'contact'. - do_test({contactType: "adn"}, CONTACT_ERR_REQUEST_NOT_SUPPORTED); - - // Error 3, specifying a non-supported contactType. - ril.appType = CARD_APPTYPE_USIM; - do_test({contactType: "sdn", contact: {}}, CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED); - - // Error 4, without supplying pin2. - do_test({contactType: "fdn", contact: {contactId: ICCID + "1"}}, GECKO_ERROR_SIM_PIN2); - - // Error 5, No free record found in EF_ADN. - let record = context.ICCRecordHelper; - record.readPBR = function(onsuccess, onerror) { - onsuccess([{adn: {fileId: 0x4f3a}}]); - }; - - let io = context.ICCIOHelper; - io.loadLinearFixedEF = function(options) { - options.totalRecords = 1; - options.p1 = 1; - options.callback(options); - }; - - do_test({contactType: "adn", contact: {}}, CONTACT_ERR_NO_FREE_RECORD_FOUND); - - // Error 6, ICC IO Error. - io.loadLinearFixedEF = function(options) { - ril[REQUEST_SIM_IO](0, {rilRequestError: ERROR_GENERIC_FAILURE}); - }; - do_test({contactType: "adn", contact: {contactId: ICCID + "1"}}, - GECKO_ERROR_GENERIC_FAILURE); - - // Error 7, suppose we update the supported PBR fields in USIM_PBR_FIELDS, - // but forget to add implemenetations for it. - USIM_PBR_FIELDS.push("pbc"); - do_test({contactType: "adn", contact: {contactId: ICCID + "1"}}, - CONTACT_ERR_FIELD_NOT_SUPPORTED); - - // Error 8, EF_PBR doesn't exist. - record.readPBR = function(onsuccess, onerror) { - onsuccess([]); - }; - - do_test({contactType: "adn", contact: {contactId: ICCID + "1"}}, - CONTACT_ERR_CANNOT_ACCESS_PHONEBOOK); - - run_next_test(); -}); - -add_test(function test_process_icc_io_error() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ioHelper = context.ICCIOHelper; - - function do_test(errorCode, expectedErrorMsg) { - let called = false; - function errorCb(errorMsg) { - called = true; - do_check_eq(errorMsg, expectedErrorMsg); - } - - ioHelper.processICCIOError({rilRequestError: errorCode, - fileId: 0xffff, - command: 0xff, - sw1: 0xff, - sw2: 0xff, - onerror: errorCb}); - do_check_true(called); - } - - for (let i = 0; i < ERROR_REJECTED_BY_REMOTE + 1; i++) { - do_test(i, RIL_ERROR_TO_GECKO_ERROR[i]); - } - - run_next_test(); -}); - -add_test(function test_personalization_state() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - - context.ICCRecordHelper.readICCID = function fakeReadICCID() {}; - - function testPersonalization(isCdma, cardPersoState, geckoCardState) { - let iccStatus = { - cardState: CARD_STATE_PRESENT, - gsmUmtsSubscriptionAppIndex: (!isCdma) ? 0 : -1, - cdmaSubscriptionAppIndex: (isCdma) ? 0 : -1, - apps: [ - { - app_state: CARD_APPSTATE_SUBSCRIPTION_PERSO, - perso_substate: cardPersoState - }], - }; - - ril._isCdma = isCdma; - ril._processICCStatus(iccStatus); - do_check_eq(ril.cardState, geckoCardState); - } - - // Test GSM personalization state. - testPersonalization(false, CARD_PERSOSUBSTATE_SIM_NETWORK, - GECKO_CARDSTATE_NETWORK_LOCKED); - testPersonalization(false, CARD_PERSOSUBSTATE_SIM_CORPORATE, - GECKO_CARDSTATE_CORPORATE_LOCKED); - testPersonalization(false, CARD_PERSOSUBSTATE_SIM_SERVICE_PROVIDER, - GECKO_CARDSTATE_SERVICE_PROVIDER_LOCKED); - testPersonalization(false, CARD_PERSOSUBSTATE_SIM_NETWORK_PUK, - GECKO_CARDSTATE_NETWORK_PUK_REQUIRED); - testPersonalization(false, CARD_PERSOSUBSTATE_SIM_CORPORATE_PUK, - GECKO_CARDSTATE_CORPORATE_PUK_REQUIRED); - testPersonalization(false, CARD_PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK, - GECKO_CARDSTATE_SERVICE_PROVIDER_PUK_REQUIRED); - testPersonalization(false, CARD_PERSOSUBSTATE_READY, - GECKO_CARDSTATE_PERSONALIZATION_READY); - - // Test CDMA personalization state. - testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_NETWORK1, - GECKO_CARDSTATE_NETWORK1_LOCKED); - testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_NETWORK2, - GECKO_CARDSTATE_NETWORK2_LOCKED); - testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_HRPD, - GECKO_CARDSTATE_HRPD_NETWORK_LOCKED); - testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_CORPORATE, - GECKO_CARDSTATE_RUIM_CORPORATE_LOCKED); - testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER, - GECKO_CARDSTATE_RUIM_SERVICE_PROVIDER_LOCKED); - testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_RUIM, - GECKO_CARDSTATE_RUIM_LOCKED); - testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_NETWORK1_PUK, - GECKO_CARDSTATE_NETWORK1_PUK_REQUIRED); - testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_NETWORK2_PUK, - GECKO_CARDSTATE_NETWORK2_PUK_REQUIRED); - testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_HRPD_PUK, - GECKO_CARDSTATE_HRPD_NETWORK_PUK_REQUIRED); - testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_CORPORATE_PUK, - GECKO_CARDSTATE_RUIM_CORPORATE_PUK_REQUIRED); - testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK, - GECKO_CARDSTATE_RUIM_SERVICE_PROVIDER_PUK_REQUIRED); - testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_RUIM_PUK, - GECKO_CARDSTATE_RUIM_PUK_REQUIRED); - - run_next_test(); -}); - -/** - * Verify SIM app_state in _processICCStatus - */ -add_test(function test_card_app_state() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - - context.ICCRecordHelper.readICCID = function fakeReadICCID() {}; - - function testCardAppState(cardAppState, geckoCardState) { - let iccStatus = { - cardState: CARD_STATE_PRESENT, - gsmUmtsSubscriptionAppIndex: 0, - apps: [ - { - app_state: cardAppState - }], - }; - - ril._processICCStatus(iccStatus); - do_check_eq(ril.cardState, geckoCardState); - } - - testCardAppState(CARD_APPSTATE_ILLEGAL, - GECKO_CARDSTATE_ILLEGAL); - testCardAppState(CARD_APPSTATE_PIN, - GECKO_CARDSTATE_PIN_REQUIRED); - testCardAppState(CARD_APPSTATE_PUK, - GECKO_CARDSTATE_PUK_REQUIRED); - testCardAppState(CARD_APPSTATE_READY, - GECKO_CARDSTATE_READY); - testCardAppState(CARD_APPSTATE_UNKNOWN, - GECKO_CARDSTATE_UNKNOWN); - testCardAppState(CARD_APPSTATE_DETECTED, - GECKO_CARDSTATE_UNKNOWN); - - run_next_test(); -}); - -/** - * Verify permanent blocked for ICC. - */ -add_test(function test_icc_permanent_blocked() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - - context.ICCRecordHelper.readICCID = function fakeReadICCID() {}; - - function testPermanentBlocked(pin1_replaced, universalPINState, pin1) { - let iccStatus = { - cardState: CARD_STATE_PRESENT, - gsmUmtsSubscriptionAppIndex: 0, - universalPINState: universalPINState, - apps: [ - { - pin1_replaced: pin1_replaced, - pin1: pin1 - }] - }; - - ril._processICCStatus(iccStatus); - do_check_eq(ril.cardState, GECKO_CARDSTATE_PERMANENT_BLOCKED); - } - - testPermanentBlocked(1, - CARD_PINSTATE_ENABLED_PERM_BLOCKED, - CARD_PINSTATE_UNKNOWN); - testPermanentBlocked(1, - CARD_PINSTATE_ENABLED_PERM_BLOCKED, - CARD_PINSTATE_ENABLED_PERM_BLOCKED); - testPermanentBlocked(0, - CARD_PINSTATE_UNKNOWN, - CARD_PINSTATE_ENABLED_PERM_BLOCKED); - - run_next_test(); -}); - -/** - * Verify iccSetCardLock - Facility Lock. - */ -add_test(function test_set_icc_card_lock_facility_lock() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let aid = "123456789"; - let ril = context.RIL; - ril.aid = aid; - 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 () { - // Request Type. - do_check_eq(this.readInt32(), REQUEST_SET_FACILITY_LOCK); - - // Token : we don't care - this.readInt32(); - - 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[1], aEnabled ? "1" : "0"); - do_check_eq(parcel[2], GECKO_CARDLOCK_TO_PASSWORD[aLock]); - do_check_eq(parcel[3], serviceClass.toString()); - do_check_eq(parcel[4], aid); - }; - - let lock = {lockType: aLock, - enabled: aEnabled}; - lock[GECKO_CARDLOCK_TO_PASSWORD_TYPE[aLock]] = aPassword; - - ril.iccSetCardLock(lock); - } - - 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); - - run_next_test(); -}); - -/** - * Verify iccUnlockCardLock. - */ -add_test(function test_unlock_card_lock_corporateLocked() { - 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"; - - 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. - do_check_eq(this.readString(), aPassword); - }; - - let lock = {lockType: aLock}; - lock[GECKO_CARDLOCK_TO_PASSWORD_TYPE[aLock]] = aPassword; - ril.iccUnlockCardLock(lock); - } - - 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); - - run_next_test(); -}); - -/** - * Verify MCC and MNC parsing - */ -add_test(function test_mcc_mnc_parsing() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.ICCUtilsHelper; - - function do_test(imsi, mncLength, expectedMcc, expectedMnc) { - let result = helper.parseMccMncFromImsi(imsi, mncLength); - - if (!imsi) { - do_check_eq(result, null); - return; - } - - do_check_eq(result.mcc, expectedMcc); - do_check_eq(result.mnc, expectedMnc); - } - - // Test the imsi is null. - do_test(null, null, null, null); - - // Test MCC is Taiwan - do_test("466923202422409", 0x02, "466", "92"); - do_test("466923202422409", 0x03, "466", "923"); - do_test("466923202422409", null, "466", "92"); - - // Test MCC is US - do_test("310260542718417", 0x02, "310", "26"); - do_test("310260542718417", 0x03, "310", "260"); - do_test("310260542718417", null, "310", "260"); - - run_next_test(); - }); - - /** - * Verify reading EF_AD and parsing MCC/MNC - */ -add_test(function test_reading_ad_and_parsing_mcc_mnc() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let record = context.SimRecordHelper; - let helper = context.GsmPDUHelper; - let ril = context.RIL; - let buf = context.Buf; - let io = context.ICCIOHelper; - - function do_test(mncLengthInEf, imsi, expectedMcc, expectedMnc) { - ril.iccInfoPrivate.imsi = imsi; - - io.loadTransparentEF = function fakeLoadTransparentEF(options) { - let ad = [0x00, 0x00, 0x00]; - if (typeof mncLengthInEf === 'number') { - ad.push(mncLengthInEf); - } - - // Write data size - buf.writeInt32(ad.length * 2); - - // Write data - for (let i = 0; i < ad.length; i++) { - helper.writeHexOctet(ad[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(ad.length * 2); - - if (options.callback) { - options.callback(options); - } - }; - - record.readAD(); - - do_check_eq(ril.iccInfo.mcc, expectedMcc); - do_check_eq(ril.iccInfo.mnc, expectedMnc); - } - - do_test(undefined, "466923202422409", "466", "92" ); - do_test(0x00, "466923202422409", "466", "92" ); - do_test(0x01, "466923202422409", "466", "92" ); - do_test(0x02, "466923202422409", "466", "92" ); - do_test(0x03, "466923202422409", "466", "923"); - do_test(0x04, "466923202422409", "466", "92" ); - do_test(0xff, "466923202422409", "466", "92" ); - - do_test(undefined, "310260542718417", "310", "260"); - do_test(0x00, "310260542718417", "310", "260"); - do_test(0x01, "310260542718417", "310", "260"); - do_test(0x02, "310260542718417", "310", "26" ); - do_test(0x03, "310260542718417", "310", "260"); - do_test(0x04, "310260542718417", "310", "260"); - do_test(0xff, "310260542718417", "310", "260"); - - run_next_test(); -}); - -add_test(function test_reading_optional_efs() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let record = context.SimRecordHelper; - let gsmPdu = context.GsmPDUHelper; - let ril = context.RIL; - let buf = context.Buf; - let io = context.ICCIOHelper; - - function buildSST(supportedEf) { - let sst = []; - let len = supportedEf.length; - for (let i = 0; i < len; i++) { - let index, bitmask, iccService; - if (ril.appType === CARD_APPTYPE_SIM) { - iccService = GECKO_ICC_SERVICES.sim[supportedEf[i]]; - iccService -= 1; - index = Math.floor(iccService / 4); - bitmask = 2 << ((iccService % 4) << 1); - } else if (ril.appType === CARD_APPTYPE_USIM){ - iccService = GECKO_ICC_SERVICES.usim[supportedEf[i]]; - iccService -= 1; - index = Math.floor(iccService / 8); - bitmask = 1 << ((iccService % 8) << 0); - } - - if (sst) { - sst[index] |= bitmask; - } - } - return sst; - } - - ril.updateCellBroadcastConfig = function fakeUpdateCellBroadcastConfig() { - // Ignore updateCellBroadcastConfig after reading SST - }; - - function do_test(sst, supportedEf) { - // Clone supportedEf to local array for testing - let testEf = supportedEf.slice(0); - - record.readMSISDN = function fakeReadMSISDN() { - testEf.splice(testEf.indexOf("MSISDN"), 1); - }; - - record.readMBDN = function fakeReadMBDN() { - testEf.splice(testEf.indexOf("MDN"), 1); - }; - - record.readMWIS = function fakeReadMWIS() { - testEf.splice(testEf.indexOf("MWIS"), 1); - }; - - io.loadTransparentEF = function fakeLoadTransparentEF(options) { - // Write data size - buf.writeInt32(sst.length * 2); - - // Write data - for (let i = 0; i < sst.length; i++) { - gsmPdu.writeHexOctet(sst[i] || 0); - } - - // Write string delimiter - buf.writeStringDelimiter(sst.length * 2); - - if (options.callback) { - options.callback(options); - } - - if (testEf.length !== 0) { - do_print("Un-handled EF: " + JSON.stringify(testEf)); - do_check_true(false); - } - }; - - record.readSST(); - } - - // TODO: Add all necessary optional EFs eventually - let supportedEf = ["MSISDN", "MDN", "MWIS"]; - ril.appType = CARD_APPTYPE_SIM; - do_test(buildSST(supportedEf), supportedEf); - ril.appType = CARD_APPTYPE_USIM; - do_test(buildSST(supportedEf), supportedEf); - - run_next_test(); -}); - -/** - * Verify fetchSimRecords. - */ -add_test(function test_fetch_sim_recodes() { - let worker = newWorker(); - let context = worker.ContextPool._contexts[0]; - let RIL = context.RIL; - let iccRecord = context.ICCRecordHelper; - let simRecord = context.SimRecordHelper; - - function testFetchSimRecordes(expectCalled) { - let ifCalled = []; - - RIL.getIMSI = function() { - ifCalled.push("getIMSI"); - }; - - simRecord.readAD = function() { - ifCalled.push("readAD"); - }; - - simRecord.readSST = function() { - ifCalled.push("readSST"); - }; - - simRecord.fetchSimRecords(); - - for (let i = 0; i < expectCalled.length; i++ ) { - if (ifCalled[i] != expectCalled[i]) { - do_print(expectCalled[i] + " is not called."); - do_check_true(false); - } - } - } - - let expectCalled = ["getIMSI", "readAD", "readSST"]; - testFetchSimRecordes(expectCalled); - - run_next_test(); -}); - -add_test(function test_fetch_icc_recodes() { - let worker = newWorker(); - let context = worker.ContextPool._contexts[0]; - let RIL = context.RIL; - let iccRecord = context.ICCRecordHelper; - let simRecord = context.SimRecordHelper; - let ruimRecord = context.RuimRecordHelper; - let fetchTag = 0x00; - - simRecord.fetchSimRecords = function() { - fetchTag = 0x01; - }; - - ruimRecord.fetchRuimRecords = function() { - fetchTag = 0x02; - }; - - RIL.appType = CARD_APPTYPE_SIM; - iccRecord.fetchICCRecords(); - do_check_eq(fetchTag, 0x01); - - RIL.appType = CARD_APPTYPE_RUIM; - iccRecord.fetchICCRecords(); - do_check_eq(fetchTag, 0x02); - - RIL.appType = CARD_APPTYPE_USIM; - iccRecord.fetchICCRecords(); - do_check_eq(fetchTag, 0x01); - - run_next_test(); -}); - -/** - * Verify SimRecordHelper.readMWIS - */ -add_test(function test_read_mwis() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let recordHelper = context.SimRecordHelper; - let buf = context.Buf; - let io = context.ICCIOHelper; - let mwisData; - let postedMessage; - - worker.postMessage = function fakePostMessage(message) { - postedMessage = message; - }; - - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - if (mwisData) { - // Write data size - buf.writeInt32(mwisData.length * 2); - - // Write MWIS - for (let i = 0; i < mwisData.length; i++) { - helper.writeHexOctet(mwisData[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(mwisData.length * 2); - - options.recordSize = mwisData.length; - if (options.callback) { - options.callback(options); - } - } else { - do_print("mwisData[] is not set."); - } - }; - - function buildMwisData(isActive, msgCount) { - if (msgCount < 0 || msgCount === GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN) { - msgCount = 0; - } else if (msgCount > 255) { - msgCount = 255; - } - - mwisData = [ (isActive) ? 0x01 : 0x00, - msgCount, - 0xFF, 0xFF, 0xFF ]; - } - - function do_test(isActive, msgCount) { - buildMwisData(isActive, msgCount); - recordHelper.readMWIS(); - - do_check_eq("iccmwis", postedMessage.rilMessageType); - do_check_eq(isActive, postedMessage.mwi.active); - do_check_eq((isActive) ? msgCount : 0, postedMessage.mwi.msgCount); - } - - do_test(true, GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN); - do_test(true, 1); - do_test(true, 255); - - do_test(false, 0); - do_test(false, 255); // Test the corner case when mwi is disable with incorrect msgCount. - - run_next_test(); -}); - -/** - * Verify SimRecordHelper.updateMWIS - */ -add_test(function test_update_mwis() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let pduHelper = context.GsmPDUHelper; - let ril = context.RIL; - ril.appType = CARD_APPTYPE_USIM; - ril.iccInfoPrivate.mwis = [0x00, 0x00, 0x00, 0x00, 0x00]; - let recordHelper = context.SimRecordHelper; - let buf = context.Buf; - let ioHelper = context.ICCIOHelper; - let recordSize = ril.iccInfoPrivate.mwis.length; - let recordNum = 1; - - ioHelper.updateLinearFixedEF = function(options) { - options.pathId = context.ICCFileHelper.getEFPath(options.fileId); - options.command = ICC_COMMAND_UPDATE_RECORD; - options.p1 = options.recordNumber; - options.p2 = READ_RECORD_ABSOLUTE_MODE; - options.p3 = recordSize; - ril.iccIO(options); - }; - - function do_test(isActive, count) { - let mwis = ril.iccInfoPrivate.mwis; - let isUpdated = false; - - function buildMwisData() { - let result = mwis.slice(0); - result[0] = isActive? (mwis[0] | 0x01) : (mwis[0] & 0xFE); - result[1] = (count === GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN) ? 0 : count; - - return result; - } - - buf.sendParcel = function() { - isUpdated = true; - - // Request Type. - do_check_eq(this.readInt32(), REQUEST_SIM_IO); - - // Token : we don't care - this.readInt32(); - - // command. - do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD); - - // fileId. - do_check_eq(this.readInt32(), ICC_EF_MWIS); - - // pathId. - do_check_eq(this.readString(), - EF_PATH_MF_SIM + ((ril.appType === CARD_APPTYPE_USIM) ? EF_PATH_ADF_USIM : EF_PATH_DF_GSM)); - - // p1. - do_check_eq(this.readInt32(), recordNum); - - // p2. - do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE); - - // p3. - do_check_eq(this.readInt32(), recordSize); - - // data. - let strLen = this.readInt32(); - do_check_eq(recordSize * 2, strLen); - let expectedMwis = buildMwisData(); - for (let i = 0; i < recordSize; i++) { - do_check_eq(expectedMwis[i], pduHelper.readHexOctet()); - } - this.readStringDelimiter(strLen); - - // pin2. - do_check_eq(this.readString(), null); - - if (!ril.v5Legacy) { - // AID. Ignore because it's from modem. - this.readInt32(); - } - }; - - do_check_false(isUpdated); - - recordHelper.updateMWIS({ active: isActive, - msgCount: count }); - - do_check_true((ril.iccInfoPrivate.mwis) ? isUpdated : !isUpdated); - } - - do_test(true, GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN); - do_test(true, 1); - do_test(true, 255); - - do_test(false, 0); - - // Test if Path ID is correct for SIM. - ril.appType = CARD_APPTYPE_SIM; - do_test(false, 0); - - // Test if loadLinearFixedEF() is not invoked in updateMWIS() when - // EF_MWIS is not loaded/available. - delete ril.iccInfoPrivate.mwis; - do_test(false, 0); - - run_next_test(); -}); - -/** - * Verify the call flow of receiving Class 2 SMS stored in SIM: - * 1. UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM. - * 2. SimRecordHelper.readSMS(). - * 3. sendChromeMessage() with rilMessageType == "sms-received". - */ -add_test(function test_read_new_sms_on_sim() { - // Instead of reusing newUint8Worker defined in this file, - // we define our own worker to fake the methods in WorkerBuffer dynamically. - function newSmsOnSimWorkerHelper() { - let _postedMessage; - let _worker = newWorker({ - postRILMessage: function(data) { - }, - postMessage: function(message) { - _postedMessage = message; - } - }); - - _worker.debug = do_print; - - return { - get postedMessage() { - return _postedMessage; - }, - get worker() { - return _worker; - }, - fakeWokerBuffer: function() { - let context = _worker.ContextPool._contexts[0]; - let index = 0; // index for read - let buf = []; - context.Buf.writeUint8 = function(value) { - buf.push(value); - }; - context.Buf.readUint8 = function() { - return buf[index++]; - }; - context.Buf.seekIncoming = function(offset) { - index += offset; - }; - context.Buf.getReadAvailable = function() { - return buf.length - index; - }; - } - }; - } - - let workerHelper = newSmsOnSimWorkerHelper(); - let worker = workerHelper.worker; - let context = worker.ContextPool._contexts[0]; - - context.ICCIOHelper.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - // SimStatus: Unread, SMSC:+0123456789, Sender: +9876543210, Text: How are you? - let SimSmsPduHex = "0306911032547698040A9189674523010000208062917314080CC8F71D14969741F977FD07" - // In 4.2.25 EF_SMS Short Messages of 3GPP TS 31.102: - // 1. Record length == 176 bytes. - // 2. Any bytes in the record following the TPDU shall be filled with 'FF'. - + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"; - - workerHelper.fakeWokerBuffer(); - - context.Buf.writeString(SimSmsPduHex); - - options.recordSize = 176; // Record length is fixed to 176 bytes. - if (options.callback) { - options.callback(options); - } - }; - - function newSmsOnSimParcel() { - let data = new Uint8Array(4 + 4); // Int32List with 1 element. - let offset = 0; - - function writeInt(value) { - data[offset++] = value & 0xFF; - data[offset++] = (value >> 8) & 0xFF; - data[offset++] = (value >> 16) & 0xFF; - data[offset++] = (value >> 24) & 0xFF; - } - - writeInt(1); // Length of Int32List - writeInt(1); // RecordNum = 1. - - return newIncomingParcel(-1, - RESPONSE_TYPE_UNSOLICITED, - UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM, - data); - } - - function do_test() { - worker.onRILMessage(0, newSmsOnSimParcel()); - - let postedMessage = workerHelper.postedMessage; - - do_check_eq("sms-received", postedMessage.rilMessageType); - do_check_eq("+0123456789", postedMessage.SMSC); - do_check_eq("+9876543210", postedMessage.sender); - do_check_eq("How are you?", postedMessage.body); - } - - do_test(); - - run_next_test(); -}); - -// Test ICC_COMMAND_GET_RESPONSE with FCP template format. -/** - * Verify transparent structure with FCP template format. - */ -add_test(function test_fcp_template_for_transparent_structure() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let pduHelper = context.GsmPDUHelper; - let berHelper = context.BerTlvHelper; - - let tag_test = [ - 0x62, - 0x22, - 0x82, 0x02, 0x41, 0x21, - 0x83, 0x02, 0x2F, 0xE2, - 0xA5, 0x09, 0xC1, 0x04, 0x40, 0x0F, 0xF5, 0x55, 0x92, 0x01, 0x00, - 0x8A, 0x01, 0x05, - 0x8B, 0x03, 0x2F, 0x06, 0x0B, - 0x80, 0x02, 0x00, 0x0A, - 0x88, 0x01, 0x10]; - - for (let i = 0; i < tag_test.length; i++) { - pduHelper.writeHexOctet(tag_test[i]); - } - - let berTlv = berHelper.decode(tag_test.length); - let iter = Iterator(berTlv.value); - let tlv = berHelper.searchForNextTag(BER_FCP_FILE_DESCRIPTOR_TAG, iter); - do_check_eq(tlv.value.fileStructure, UICC_EF_STRUCTURE[EF_TYPE_TRANSPARENT]); - - tlv = berHelper.searchForNextTag(BER_FCP_FILE_IDENTIFIER_TAG, iter); - do_check_eq(tlv.value.fileId, 0x2FE2); - - tlv = berHelper.searchForNextTag(BER_FCP_FILE_SIZE_DATA_TAG, iter); - do_check_eq(tlv.value.fileSizeData, 0x0A); - - run_next_test(); -}); - -/** - * Verify linear fixed structure with FCP template format. - */ -add_test(function test_fcp_template_for_linear_fixed_structure() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let pduHelper = context.GsmPDUHelper; - let berHelper = context.BerTlvHelper; - - let tag_test = [ - 0x62, - 0x1E, - 0x82, 0x05, 0x42, 0x21, 0x00, 0x1A, 0x01, - 0x83, 0x02, 0x6F, 0x40, - 0xA5, 0x03, 0x92, 0x01, 0x00, - 0x8A, 0x01, 0x07, - 0x8B, 0x03, 0x6F, 0x06, 0x02, - 0x80, 0x02, 0x00, 0x1A, - 0x88, 0x00]; - - for (let i = 0; i < tag_test.length; i++) { - pduHelper.writeHexOctet(tag_test[i]); - } - - let berTlv = berHelper.decode(tag_test.length); - let iter = Iterator(berTlv.value); - let tlv = berHelper.searchForNextTag(BER_FCP_FILE_DESCRIPTOR_TAG, iter); - do_check_eq(tlv.value.fileStructure, UICC_EF_STRUCTURE[EF_TYPE_LINEAR_FIXED]); - do_check_eq(tlv.value.recordLength, 0x1A); - do_check_eq(tlv.value.numOfRecords, 0x01); - - tlv = berHelper.searchForNextTag(BER_FCP_FILE_IDENTIFIER_TAG, iter); - do_check_eq(tlv.value.fileId, 0x6F40); - - tlv = berHelper.searchForNextTag(BER_FCP_FILE_SIZE_DATA_TAG, iter); - do_check_eq(tlv.value.fileSizeData, 0x1A); - - run_next_test(); -}); - -add_test(function test_icc_io_get_response_for_transparent_structure() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let buf = context.Buf; - let iccioHelper = context.ICCIOHelper; - let pduHelper = context.GsmPDUHelper; - - let responseArray = [ - // SIM response. - [0x00, 0x00, 0x00, 0x0A, 0x2F, 0xE2, 0x04, 0x00, 0x0A, 0xA0, 0xAA, 0x00, - 0x02, 0x00, 0x00], - // USIM response. - [0x62, 0x22, 0x82, 0x02, 0x41, 0x21, 0x83, 0x02, 0x2F, 0xE2, 0xA5, 0x09, - 0xC1, 0x04, 0x40, 0x0F, 0xF5, 0x55, 0x92, 0x01, 0x00, 0x8A, 0x01, 0x05, - 0x8B, 0x03, 0x2F, 0x06, 0x0B, 0x80, 0x02, 0x00, 0x0A, 0x88, 0x01, 0x10] - ]; - - for (let i = 0; i < responseArray.length; i++) { - let strLen = responseArray[i].length * 2; - buf.writeInt32(strLen); - for (let j = 0; j < responseArray[i].length; j++) { - pduHelper.writeHexOctet(responseArray[i][j]); - } - buf.writeStringDelimiter(strLen); - - let options = {fileId: ICC_EF_ICCID, - type: EF_TYPE_TRANSPARENT}; - iccioHelper.processICCIOGetResponse(options); - - do_check_eq(options.fileSize, 0x0A); - } - - run_next_test(); -}); - -add_test(function test_icc_io_get_response_for_linear_fixed_structure() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let buf = context.Buf; - let iccioHelper = context.ICCIOHelper; - let pduHelper = context.GsmPDUHelper; - - let responseArray = [ - // SIM response. - [0x00, 0x00, 0x00, 0x1A, 0x6F, 0x40, 0x04, 0x00, 0x11, 0xA0, 0xAA, 0x00, - 0x02, 0x01, 0x1A], - // USIM response. - [0x62, 0x1E, 0x82, 0x05, 0x42, 0x21, 0x00, 0x1A, 0x01, 0x83, 0x02, 0x6F, - 0x40, 0xA5, 0x03, 0x92, 0x01, 0x00, 0x8A, 0x01, 0x07, 0x8B, 0x03, 0x6F, - 0x06, 0x02, 0x80, 0x02, 0x00, 0x1A, 0x88, 0x00] - ]; - - for (let i = 0; i < responseArray.length; i++) { - let strLen = responseArray[i].length * 2; - buf.writeInt32(strLen); - for (let j = 0; j < responseArray[i].length; j++) { - pduHelper.writeHexOctet(responseArray[i][j]); - } - buf.writeStringDelimiter(strLen); - - let options = {fileId: ICC_EF_MSISDN, - type: EF_TYPE_LINEAR_FIXED}; - iccioHelper.processICCIOGetResponse(options); - - do_check_eq(options.fileSize, 0x1A); - do_check_eq(options.recordSize, 0x1A); - do_check_eq(options.totalRecords, 0x01); - } - - run_next_test(); -}); - -/** - * Verify reading EF_ICCID. - */ -add_test(function test_handling_iccid() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let record = context.ICCRecordHelper; - let helper = context.GsmPDUHelper; - let ril = context.RIL; - let buf = context.Buf; - let io = context.ICCIOHelper; - - ril.reportStkServiceIsRunning = function fakeReportStkServiceIsRunning() { - }; - - function do_test(rawICCID, expectedICCID) { - io.loadTransparentEF = function fakeLoadTransparentEF(options) { - // Write data size - buf.writeInt32(rawICCID.length); - - // Write data - for (let i = 0; i < rawICCID.length; i += 2) { - helper.writeHexOctet(parseInt(rawICCID.substr(i, 2), 16)); - } - - // Write string delimiter - buf.writeStringDelimiter(rawICCID.length); - - if (options.callback) { - options.callback(options); - } - }; - - record.readICCID(); - - do_check_eq(ril.iccInfo.iccid, expectedICCID); - } - - // Invalid char at high nibbile + low nibbile contains 0xF. - do_test("9868002E90909F001519", "89860020909"); - // Invalid char at low nibbile. - do_test("986800E2909090001519", "8986002090909005191"); - // Valid ICCID. - do_test("98101430121181157002", "89014103211118510720"); - - run_next_test(); -});
new file mode 100644 --- /dev/null +++ b/dom/system/gonk/tests/test_ril_worker_icc_BerTlvHelper.js @@ -0,0 +1,87 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); + +function run_test() { + run_next_test(); +} + +// Test ICC_COMMAND_GET_RESPONSE with FCP template format. +/** + * Verify transparent structure with FCP template format. + */ +add_test(function test_fcp_template_for_transparent_structure() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let pduHelper = context.GsmPDUHelper; + let berHelper = context.BerTlvHelper; + + let tag_test = [ + 0x62, + 0x22, + 0x82, 0x02, 0x41, 0x21, + 0x83, 0x02, 0x2F, 0xE2, + 0xA5, 0x09, 0xC1, 0x04, 0x40, 0x0F, 0xF5, 0x55, 0x92, 0x01, 0x00, + 0x8A, 0x01, 0x05, + 0x8B, 0x03, 0x2F, 0x06, 0x0B, + 0x80, 0x02, 0x00, 0x0A, + 0x88, 0x01, 0x10]; + + for (let i = 0; i < tag_test.length; i++) { + pduHelper.writeHexOctet(tag_test[i]); + } + + let berTlv = berHelper.decode(tag_test.length); + let iter = Iterator(berTlv.value); + let tlv = berHelper.searchForNextTag(BER_FCP_FILE_DESCRIPTOR_TAG, iter); + do_check_eq(tlv.value.fileStructure, UICC_EF_STRUCTURE[EF_TYPE_TRANSPARENT]); + + tlv = berHelper.searchForNextTag(BER_FCP_FILE_IDENTIFIER_TAG, iter); + do_check_eq(tlv.value.fileId, 0x2FE2); + + tlv = berHelper.searchForNextTag(BER_FCP_FILE_SIZE_DATA_TAG, iter); + do_check_eq(tlv.value.fileSizeData, 0x0A); + + run_next_test(); +}); + +/** + * Verify linear fixed structure with FCP template format. + */ +add_test(function test_fcp_template_for_linear_fixed_structure() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let pduHelper = context.GsmPDUHelper; + let berHelper = context.BerTlvHelper; + + let tag_test = [ + 0x62, + 0x1E, + 0x82, 0x05, 0x42, 0x21, 0x00, 0x1A, 0x01, + 0x83, 0x02, 0x6F, 0x40, + 0xA5, 0x03, 0x92, 0x01, 0x00, + 0x8A, 0x01, 0x07, + 0x8B, 0x03, 0x6F, 0x06, 0x02, + 0x80, 0x02, 0x00, 0x1A, + 0x88, 0x00]; + + for (let i = 0; i < tag_test.length; i++) { + pduHelper.writeHexOctet(tag_test[i]); + } + + let berTlv = berHelper.decode(tag_test.length); + let iter = Iterator(berTlv.value); + let tlv = berHelper.searchForNextTag(BER_FCP_FILE_DESCRIPTOR_TAG, iter); + do_check_eq(tlv.value.fileStructure, UICC_EF_STRUCTURE[EF_TYPE_LINEAR_FIXED]); + do_check_eq(tlv.value.recordLength, 0x1A); + do_check_eq(tlv.value.numOfRecords, 0x01); + + tlv = berHelper.searchForNextTag(BER_FCP_FILE_IDENTIFIER_TAG, iter); + do_check_eq(tlv.value.fileId, 0x6F40); + + tlv = berHelper.searchForNextTag(BER_FCP_FILE_SIZE_DATA_TAG, iter); + do_check_eq(tlv.value.fileSizeData, 0x1A); + + run_next_test(); +});
new file mode 100644 --- /dev/null +++ b/dom/system/gonk/tests/test_ril_worker_icc_CardLock.js @@ -0,0 +1,357 @@ +/* Any copyright is dedicated to the Public Domain. + 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") + */ +add_test(function test_icc_get_card_lock_state_fdn() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let ril = context.RIL; + let buf = context.Buf; + + buf.sendParcel = function() { + // Request Type. + do_check_eq(this.readInt32(), REQUEST_QUERY_FACILITY_LOCK) + + // Token : we don't care. + this.readInt32(); + + // String Array Length. + do_check_eq(this.readInt32(), ril.v5Legacy ? 3 : 4); + + // Facility. + do_check_eq(this.readString(), ICC_CB_FACILITY_FDN); + + // 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()); + + if (!ril.v5Legacy) { + // AID. Ignore because it's from modem. + this.readInt32(); + } + + run_next_test(); + }; + + ril.iccGetCardLockState({lockType: "fdn"}); +}); + +add_test(function test_path_id_for_spid_and_spn() { + let worker = newWorker({ + postRILMessage: function(data) { + // Do nothing + }, + postMessage: function(message) { + // Do nothing + }}); + let context = worker.ContextPool._contexts[0]; + let RIL = context.RIL; + let ICCFileHelper = context.ICCFileHelper; + + // Test SIM + RIL.appType = CARD_APPTYPE_SIM; + do_check_eq(ICCFileHelper.getEFPath(ICC_EF_SPDI), + EF_PATH_MF_SIM + EF_PATH_DF_GSM); + do_check_eq(ICCFileHelper.getEFPath(ICC_EF_SPN), + EF_PATH_MF_SIM + EF_PATH_DF_GSM); + + // Test USIM + RIL.appType = CARD_APPTYPE_USIM; + 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(); +}); + +add_test(function test_personalization_state() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let ril = context.RIL; + + context.ICCRecordHelper.readICCID = function fakeReadICCID() {}; + + function testPersonalization(isCdma, cardPersoState, geckoCardState) { + let iccStatus = { + cardState: CARD_STATE_PRESENT, + gsmUmtsSubscriptionAppIndex: (!isCdma) ? 0 : -1, + cdmaSubscriptionAppIndex: (isCdma) ? 0 : -1, + apps: [ + { + app_state: CARD_APPSTATE_SUBSCRIPTION_PERSO, + perso_substate: cardPersoState + }], + }; + + ril._isCdma = isCdma; + ril._processICCStatus(iccStatus); + do_check_eq(ril.cardState, geckoCardState); + } + + // Test GSM personalization state. + testPersonalization(false, CARD_PERSOSUBSTATE_SIM_NETWORK, + GECKO_CARDSTATE_NETWORK_LOCKED); + testPersonalization(false, CARD_PERSOSUBSTATE_SIM_CORPORATE, + GECKO_CARDSTATE_CORPORATE_LOCKED); + testPersonalization(false, CARD_PERSOSUBSTATE_SIM_SERVICE_PROVIDER, + GECKO_CARDSTATE_SERVICE_PROVIDER_LOCKED); + testPersonalization(false, CARD_PERSOSUBSTATE_SIM_NETWORK_PUK, + GECKO_CARDSTATE_NETWORK_PUK_REQUIRED); + testPersonalization(false, CARD_PERSOSUBSTATE_SIM_CORPORATE_PUK, + GECKO_CARDSTATE_CORPORATE_PUK_REQUIRED); + testPersonalization(false, CARD_PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK, + GECKO_CARDSTATE_SERVICE_PROVIDER_PUK_REQUIRED); + testPersonalization(false, CARD_PERSOSUBSTATE_READY, + GECKO_CARDSTATE_PERSONALIZATION_READY); + + // Test CDMA personalization state. + testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_NETWORK1, + GECKO_CARDSTATE_NETWORK1_LOCKED); + testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_NETWORK2, + GECKO_CARDSTATE_NETWORK2_LOCKED); + testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_HRPD, + GECKO_CARDSTATE_HRPD_NETWORK_LOCKED); + testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_CORPORATE, + GECKO_CARDSTATE_RUIM_CORPORATE_LOCKED); + testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER, + GECKO_CARDSTATE_RUIM_SERVICE_PROVIDER_LOCKED); + testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_RUIM, + GECKO_CARDSTATE_RUIM_LOCKED); + testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_NETWORK1_PUK, + GECKO_CARDSTATE_NETWORK1_PUK_REQUIRED); + testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_NETWORK2_PUK, + GECKO_CARDSTATE_NETWORK2_PUK_REQUIRED); + testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_HRPD_PUK, + GECKO_CARDSTATE_HRPD_NETWORK_PUK_REQUIRED); + testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_CORPORATE_PUK, + GECKO_CARDSTATE_RUIM_CORPORATE_PUK_REQUIRED); + testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK, + GECKO_CARDSTATE_RUIM_SERVICE_PROVIDER_PUK_REQUIRED); + testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_RUIM_PUK, + GECKO_CARDSTATE_RUIM_PUK_REQUIRED); + + run_next_test(); +}); + +/** + * Verify SIM app_state in _processICCStatus + */ +add_test(function test_card_app_state() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let ril = context.RIL; + + context.ICCRecordHelper.readICCID = function fakeReadICCID() {}; + + function testCardAppState(cardAppState, geckoCardState) { + let iccStatus = { + cardState: CARD_STATE_PRESENT, + gsmUmtsSubscriptionAppIndex: 0, + apps: [ + { + app_state: cardAppState + }], + }; + + ril._processICCStatus(iccStatus); + do_check_eq(ril.cardState, geckoCardState); + } + + testCardAppState(CARD_APPSTATE_ILLEGAL, + GECKO_CARDSTATE_ILLEGAL); + testCardAppState(CARD_APPSTATE_PIN, + GECKO_CARDSTATE_PIN_REQUIRED); + testCardAppState(CARD_APPSTATE_PUK, + GECKO_CARDSTATE_PUK_REQUIRED); + testCardAppState(CARD_APPSTATE_READY, + GECKO_CARDSTATE_READY); + testCardAppState(CARD_APPSTATE_UNKNOWN, + GECKO_CARDSTATE_UNKNOWN); + testCardAppState(CARD_APPSTATE_DETECTED, + GECKO_CARDSTATE_UNKNOWN); + + run_next_test(); +}); + +/** + * Verify permanent blocked for ICC. + */ +add_test(function test_icc_permanent_blocked() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let ril = context.RIL; + + context.ICCRecordHelper.readICCID = function fakeReadICCID() {}; + + function testPermanentBlocked(pin1_replaced, universalPINState, pin1) { + let iccStatus = { + cardState: CARD_STATE_PRESENT, + gsmUmtsSubscriptionAppIndex: 0, + universalPINState: universalPINState, + apps: [ + { + pin1_replaced: pin1_replaced, + pin1: pin1 + }] + }; + + ril._processICCStatus(iccStatus); + do_check_eq(ril.cardState, GECKO_CARDSTATE_PERMANENT_BLOCKED); + } + + testPermanentBlocked(1, + CARD_PINSTATE_ENABLED_PERM_BLOCKED, + CARD_PINSTATE_UNKNOWN); + testPermanentBlocked(1, + CARD_PINSTATE_ENABLED_PERM_BLOCKED, + CARD_PINSTATE_ENABLED_PERM_BLOCKED); + testPermanentBlocked(0, + CARD_PINSTATE_UNKNOWN, + CARD_PINSTATE_ENABLED_PERM_BLOCKED); + + run_next_test(); +}); + +/** + * Verify iccSetCardLock - Facility Lock. + */ +add_test(function test_set_icc_card_lock_facility_lock() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let aid = "123456789"; + let ril = context.RIL; + ril.aid = aid; + 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 () { + // Request Type. + do_check_eq(this.readInt32(), REQUEST_SET_FACILITY_LOCK); + + // Token : we don't care + this.readInt32(); + + 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[1], aEnabled ? "1" : "0"); + do_check_eq(parcel[2], GECKO_CARDLOCK_TO_PASSWORD[aLock]); + do_check_eq(parcel[3], serviceClass.toString()); + do_check_eq(parcel[4], aid); + }; + + let lock = {lockType: aLock, + enabled: aEnabled}; + lock[GECKO_CARDLOCK_TO_PASSWORD_TYPE[aLock]] = aPassword; + + ril.iccSetCardLock(lock); + } + + 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); + + run_next_test(); +}); + +/** + * Verify iccUnlockCardLock. + */ +add_test(function test_unlock_card_lock_corporateLocked() { + 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"; + + 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. + do_check_eq(this.readString(), aPassword); + }; + + let lock = {lockType: aLock}; + lock[GECKO_CARDLOCK_TO_PASSWORD_TYPE[aLock]] = aPassword; + ril.iccUnlockCardLock(lock); + } + + 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); + + run_next_test(); +});
new file mode 100644 --- /dev/null +++ b/dom/system/gonk/tests/test_ril_worker_icc_GsmPDUHelper.js @@ -0,0 +1,79 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); + +function run_test() { + run_next_test(); +} + +/** + * Verify GsmPDUHelper.writeTimestamp + */ +add_test(function test_write_timestamp() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let helper = context.GsmPDUHelper; + + // current date + let dateInput = new Date(); + let dateOutput = new Date(); + helper.writeTimestamp(dateInput); + dateOutput.setTime(helper.readTimestamp()); + + do_check_eq(dateInput.getFullYear(), dateOutput.getFullYear()); + do_check_eq(dateInput.getMonth(), dateOutput.getMonth()); + do_check_eq(dateInput.getDate(), dateOutput.getDate()); + do_check_eq(dateInput.getHours(), dateOutput.getHours()); + do_check_eq(dateInput.getMinutes(), dateOutput.getMinutes()); + do_check_eq(dateInput.getSeconds(), dateOutput.getSeconds()); + do_check_eq(dateInput.getTimezoneOffset(), dateOutput.getTimezoneOffset()); + + // 2034-01-23 12:34:56 -0800 GMT + let time = Date.UTC(2034, 1, 23, 12, 34, 56); + time = time - (8 * 60 * 60 * 1000); + dateInput.setTime(time); + helper.writeTimestamp(dateInput); + dateOutput.setTime(helper.readTimestamp()); + + do_check_eq(dateInput.getFullYear(), dateOutput.getFullYear()); + do_check_eq(dateInput.getMonth(), dateOutput.getMonth()); + do_check_eq(dateInput.getDate(), dateOutput.getDate()); + do_check_eq(dateInput.getHours(), dateOutput.getHours()); + do_check_eq(dateInput.getMinutes(), dateOutput.getMinutes()); + do_check_eq(dateInput.getSeconds(), dateOutput.getSeconds()); + do_check_eq(dateInput.getTimezoneOffset(), dateOutput.getTimezoneOffset()); + + run_next_test(); +}); + +/** + * Verify GsmPDUHelper.octectToBCD and GsmPDUHelper.BCDToOctet + */ +add_test(function test_octect_BCD() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let helper = context.GsmPDUHelper; + + // 23 + let number = 23; + let octet = helper.BCDToOctet(number); + do_check_eq(helper.octetToBCD(octet), number); + + // 56 + number = 56; + octet = helper.BCDToOctet(number); + do_check_eq(helper.octetToBCD(octet), number); + + // 0x23 + octet = 0x23; + number = helper.octetToBCD(octet); + do_check_eq(helper.BCDToOctet(number), octet); + + // 0x56 + octet = 0x56; + number = helper.octetToBCD(octet); + do_check_eq(helper.BCDToOctet(number), octet); + + run_next_test(); +});
new file mode 100644 --- /dev/null +++ b/dom/system/gonk/tests/test_ril_worker_icc_ICCContactHelper.js @@ -0,0 +1,590 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); + +function run_test() { + run_next_test(); +} + +/** + * Test error message returned in onerror for readICCContacts. + */ +add_test(function test_error_message_read_icc_contact () { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let ril = context.RIL; + + function do_test(options, expectedErrorMsg) { + ril.sendChromeMessage = function(message) { + do_check_eq(message.errorMsg, expectedErrorMsg); + } + ril.readICCContacts(options); + } + + // Error 1, didn't specify correct contactType. + do_test({}, CONTACT_ERR_REQUEST_NOT_SUPPORTED); + + // Error 2, specifying a non-supported contactType. + ril.appType = CARD_APPTYPE_USIM; + do_test({contactType: "sdn"}, CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED); + + // Error 3, suppose we update the supported PBR fields in USIM_PBR_FIELDS, + // but forget to add implemenetations for it. + USIM_PBR_FIELDS.push("pbc"); + do_test({contactType: "adn"}, CONTACT_ERR_FIELD_NOT_SUPPORTED); + + run_next_test(); +}); + +/** + * Test error message returned in onerror for updateICCContact. + */ +add_test(function test_error_message_update_icc_contact() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let ril = context.RIL; + + const ICCID = "123456789"; + ril.iccInfo.iccid = ICCID; + + function do_test(options, expectedErrorMsg) { + ril.sendChromeMessage = function(message) { + do_check_eq(message.errorMsg, expectedErrorMsg); + } + ril.updateICCContact(options); + } + + // Error 1, didn't specify correct contactType. + do_test({}, CONTACT_ERR_REQUEST_NOT_SUPPORTED); + + // Error 2, specifying a correct contactType, but without providing 'contact'. + do_test({contactType: "adn"}, CONTACT_ERR_REQUEST_NOT_SUPPORTED); + + // Error 3, specifying a non-supported contactType. + ril.appType = CARD_APPTYPE_USIM; + do_test({contactType: "sdn", contact: {}}, CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED); + + // Error 4, without supplying pin2. + do_test({contactType: "fdn", contact: {contactId: ICCID + "1"}}, GECKO_ERROR_SIM_PIN2); + + // Error 5, No free record found in EF_ADN. + let record = context.ICCRecordHelper; + record.readPBR = function(onsuccess, onerror) { + onsuccess([{adn: {fileId: 0x4f3a}}]); + }; + + let io = context.ICCIOHelper; + io.loadLinearFixedEF = function(options) { + options.totalRecords = 1; + options.p1 = 1; + options.callback(options); + }; + + do_test({contactType: "adn", contact: {}}, CONTACT_ERR_NO_FREE_RECORD_FOUND); + + // Error 6, ICC IO Error. + io.loadLinearFixedEF = function(options) { + ril[REQUEST_SIM_IO](0, {rilRequestError: ERROR_GENERIC_FAILURE}); + }; + do_test({contactType: "adn", contact: {contactId: ICCID + "1"}}, + GECKO_ERROR_GENERIC_FAILURE); + + // Error 7, suppose we update the supported PBR fields in USIM_PBR_FIELDS, + // but forget to add implemenetations for it. + USIM_PBR_FIELDS.push("pbc"); + do_test({contactType: "adn", contact: {contactId: ICCID + "1"}}, + CONTACT_ERR_FIELD_NOT_SUPPORTED); + + // Error 8, EF_PBR doesn't exist. + record.readPBR = function(onsuccess, onerror) { + onsuccess([]); + }; + + do_test({contactType: "adn", contact: {contactId: ICCID + "1"}}, + CONTACT_ERR_CANNOT_ACCESS_PHONEBOOK); + + run_next_test(); +}); + +/** + * Verify ICCContactHelper.readICCContacts + */ +add_test(function test_read_icc_contacts() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let record = context.ICCRecordHelper; + let contactHelper = context.ICCContactHelper; + let ril = context.RIL; + + function do_test(aSimType, aContactType, aExpectedContact, aEnhancedPhoneBook) { + ril.appType = aSimType; + ril._isCdma = (aSimType === CARD_APPTYPE_RUIM); + ril.iccInfoPrivate.cst = (aEnhancedPhoneBook) ? + [0x0, 0x0C, 0x0, 0x0, 0x0]: + [0x0, 0x00, 0x0, 0x0, 0x0]; + + // Override some functions to test. + contactHelper.getContactFieldRecordId = function(pbr, contact, field, onsuccess, onerror) { + onsuccess(1); + }; + + record.readPBR = function readPBR(onsuccess, onerror) { + onsuccess([{adn:{fileId: 0x6f3a}, email: {}, anr0: {}}]); + }; + + record.readADNLike = function readADNLike(fileId, onsuccess, onerror) { + onsuccess([{recordId: 1, alphaId: "name", number: "111111"}]) + }; + + record.readEmail = function readEmail(fileId, fileType, recordNumber, onsuccess, onerror) { + onsuccess("hello@mail.com"); + }; + + record.readANR = function readANR(fileId, fileType, recordNumber, onsuccess, onerror) { + onsuccess("123456"); + }; + + let onsuccess = function onsuccess(contacts) { + let contact = contacts[0]; + for (let key in contact) { + do_print("check " + key); + if (Array.isArray(contact[key])) { + do_check_eq(contact[key][0], aExpectedContact[key]); + } else { + do_check_eq(contact[key], aExpectedContact[key]); + } + } + }; + + let onerror = function onerror(errorMsg) { + do_print("readICCContacts failed: " + errorMsg); + do_check_true(false); + }; + + contactHelper.readICCContacts(aSimType, aContactType, onsuccess, onerror); + } + + let expectedContact1 = { + pbrIndex: 0, + recordId: 1, + alphaId: "name", + number: "111111" + }; + + let expectedContact2 = { + pbrIndex: 0, + recordId: 1, + alphaId: "name", + number: "111111", + email: "hello@mail.com", + anr: "123456" + }; + + // SIM + do_print("Test read SIM adn contacts"); + do_test(CARD_APPTYPE_SIM, "adn", expectedContact1); + + do_print("Test read SIM fdn contacts"); + do_test(CARD_APPTYPE_SIM, "fdn", expectedContact1); + + // USIM + do_print("Test read USIM adn contacts"); + do_test(CARD_APPTYPE_USIM, "adn", expectedContact2); + + do_print("Test read USIM fdn contacts"); + do_test(CARD_APPTYPE_USIM, "fdn", expectedContact1); + + // RUIM + do_print("Test read RUIM adn contacts"); + do_test(CARD_APPTYPE_RUIM, "adn", expectedContact1); + + do_print("Test read RUIM fdn contacts"); + do_test(CARD_APPTYPE_RUIM, "fdn", expectedContact1); + + // RUIM with enhanced phone book + do_print("Test read RUIM adn contacts with enhanced phone book"); + do_test(CARD_APPTYPE_RUIM, "adn", expectedContact2, true); + + do_print("Test read RUIM fdn contacts with enhanced phone book"); + do_test(CARD_APPTYPE_RUIM, "fdn", expectedContact1, true); + + run_next_test(); +}); + +/** + * Verify ICCContactHelper.updateICCContact with appType is CARD_APPTYPE_USIM. + */ +add_test(function test_update_icc_contact() { + const ADN_RECORD_ID = 100; + const ADN_SFI = 1; + const IAP_FILE_ID = 0x4f17; + const EMAIL_FILE_ID = 0x4f50; + const EMAIL_RECORD_ID = 20; + const ANR0_FILE_ID = 0x4f11; + const ANR0_RECORD_ID = 30; + + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let recordHelper = context.ICCRecordHelper; + let contactHelper = context.ICCContactHelper; + let ril = context.RIL; + + function do_test(aSimType, aContactType, aContact, aPin2, aFileType, aHaveIapIndex, aEnhancedPhoneBook) { + ril.appType = aSimType; + ril._isCdma = (aSimType === CARD_APPTYPE_RUIM); + ril.iccInfoPrivate.cst = (aEnhancedPhoneBook) ? [0x0, 0x0C, 0x0, 0x0, 0x0] + : [0x0, 0x00, 0x0, 0x0, 0x0]; + + recordHelper.readPBR = function(onsuccess, onerror) { + if (aFileType === ICC_USIM_TYPE1_TAG) { + onsuccess([{ + adn: {fileId: ICC_EF_ADN}, + email: {fileId: EMAIL_FILE_ID, + fileType: ICC_USIM_TYPE1_TAG}, + anr0: {fileId: ANR0_FILE_ID, + fileType: ICC_USIM_TYPE1_TAG} + }]); + } else if (aFileType === ICC_USIM_TYPE2_TAG) { + onsuccess([{ + adn: {fileId: ICC_EF_ADN, + sfi: ADN_SFI}, + iap: {fileId: IAP_FILE_ID}, + email: {fileId: EMAIL_FILE_ID, + fileType: ICC_USIM_TYPE2_TAG, + indexInIAP: 0}, + anr0: {fileId: ANR0_FILE_ID, + fileType: ICC_USIM_TYPE2_TAG, + indexInIAP: 1} + }]); + } + }; + + recordHelper.updateADNLike = function(fileId, contact, pin2, onsuccess, onerror) { + if (aContactType === "fdn") { + do_check_eq(fileId, ICC_EF_FDN); + } else if (aContactType === "adn") { + do_check_eq(fileId, ICC_EF_ADN); + } + do_check_eq(pin2, aPin2); + do_check_eq(contact.alphaId, aContact.alphaId); + do_check_eq(contact.number, aContact.number); + onsuccess(); + }; + + recordHelper.readIAP = function(fileId, recordNumber, onsuccess, onerror) { + do_check_eq(fileId, IAP_FILE_ID); + do_check_eq(recordNumber, ADN_RECORD_ID); + onsuccess((aHaveIapIndex) ? [EMAIL_RECORD_ID, ANR0_RECORD_ID] + : [0xff, 0xff]); + }; + + recordHelper.updateIAP = function(fileId, recordNumber, iap, onsuccess, onerror) { + do_check_eq(fileId, IAP_FILE_ID); + do_check_eq(recordNumber, ADN_RECORD_ID); + onsuccess(); + }; + + recordHelper.updateEmail = function(pbr, recordNumber, email, adnRecordId, onsuccess, onerror) { + do_check_eq(pbr.email.fileId, EMAIL_FILE_ID); + if (pbr.email.fileType === ICC_USIM_TYPE1_TAG) { + do_check_eq(recordNumber, ADN_RECORD_ID); + } else if (pbr.email.fileType === ICC_USIM_TYPE2_TAG) { + do_check_eq(recordNumber, EMAIL_RECORD_ID); + } + do_check_eq(email, aContact.email); + onsuccess(); + }; + + recordHelper.updateANR = function(pbr, recordNumber, number, adnRecordId, onsuccess, onerror) { + do_check_eq(pbr.anr0.fileId, ANR0_FILE_ID); + if (pbr.anr0.fileType === ICC_USIM_TYPE1_TAG) { + do_check_eq(recordNumber, ADN_RECORD_ID); + } else if (pbr.anr0.fileType === ICC_USIM_TYPE2_TAG) { + do_check_eq(recordNumber, ANR0_RECORD_ID); + } + if (Array.isArray(aContact.anr)) { + do_check_eq(number, aContact.anr[0]); + } + onsuccess(); + }; + + recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) { + let recordId = 0; + if (fileId === EMAIL_FILE_ID) { + recordId = EMAIL_RECORD_ID; + } else if (fileId === ANR0_FILE_ID) { + recordId = ANR0_RECORD_ID; + } + onsuccess(recordId); + }; + + let isSuccess = false; + let onsuccess = function onsuccess() { + do_print("updateICCContact success"); + isSuccess = true; + }; + + let onerror = function onerror(errorMsg) { + do_print("updateICCContact failed: " + errorMsg); + }; + + contactHelper.updateICCContact(aSimType, aContactType, aContact, aPin2, onsuccess, onerror); + do_check_true(isSuccess); + } + + let contacts = [ + { + pbrIndex: 0, + recordId: ADN_RECORD_ID, + alphaId: "test", + number: "123456", + email: "test@mail.com", + anr: ["+654321"] + }, + // a contact without email and anr. + { + pbrIndex: 0, + recordId: ADN_RECORD_ID, + alphaId: "test2", + number: "123456", + }, + // a contact with email but no anr. + { + pbrIndex: 0, + recordId: ADN_RECORD_ID, + alphaId: "test3", + number: "123456", + email: "test@mail.com" + }, + // a contact with anr but no email. + { + pbrIndex: 0, + recordId: ADN_RECORD_ID, + alphaId: "test4", + number: "123456", + anr: ["+654321"] + }]; + + for (let i = 0; i < contacts.length; i++) { + let contact = contacts[i]; + // SIM + do_print("Test update SIM adn contacts"); + do_test(CARD_APPTYPE_SIM, "adn", contact); + + do_print("Test update SIM fdn contacts"); + do_test(CARD_APPTYPE_SIM, "fdn", contact, "1234"); + + // USIM + do_print("Test update USIM adn contacts"); + do_test(CARD_APPTYPE_USIM, "adn", contact, null, ICC_USIM_TYPE1_TAG); + do_test(CARD_APPTYPE_USIM, "adn", contact, null, ICC_USIM_TYPE2_TAG, true); + do_test(CARD_APPTYPE_USIM, "adn", contact, null, ICC_USIM_TYPE2_TAG, false); + + do_print("Test update USIM fdn contacts"); + do_test(CARD_APPTYPE_USIM, "fdn", contact, "1234"); + + // RUIM + do_print("Test update RUIM adn contacts"); + do_test(CARD_APPTYPE_RUIM, "adn", contact); + + do_print("Test update RUIM fdn contacts"); + do_test(CARD_APPTYPE_RUIM, "fdn", contact, "1234"); + + // RUIM with enhanced phone book + do_print("Test update RUIM adn contacts with enhanced phone book"); + do_test(CARD_APPTYPE_RUIM, "adn", contact, null, ICC_USIM_TYPE1_TAG, null, true); + do_test(CARD_APPTYPE_RUIM, "adn", contact, null, ICC_USIM_TYPE2_TAG, true, true); + do_test(CARD_APPTYPE_RUIM, "adn", contact, null, ICC_USIM_TYPE2_TAG, false, true); + + do_print("Test update RUIM fdn contacts with enhanced phone book"); + do_test(CARD_APPTYPE_RUIM, "fdn", contact, "1234", null, true); + } + + run_next_test(); +}); + +/** + * Verify updateICCContact with removal of anr and email with File Type 1. + */ +add_test(function test_update_icc_contact_with_remove_type1_attr() { + const ADN_RECORD_ID = 100; + const IAP_FILE_ID = 0x4f17; + const EMAIL_FILE_ID = 0x4f50; + const EMAIL_RECORD_ID = 20; + const ANR0_FILE_ID = 0x4f11; + const ANR0_RECORD_ID = 30; + + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let recordHelper = context.ICCRecordHelper; + let contactHelper = context.ICCContactHelper; + + recordHelper.updateADNLike = function(fileId, contact, pin2, onsuccess, onerror) { + onsuccess(); + }; + + let contact = { + pbrIndex: 0, + recordId: ADN_RECORD_ID, + alphaId: "test2", + number: "123456", + }; + + recordHelper.readIAP = function(fileId, recordNumber, onsuccess, onerror) { + onsuccess([EMAIL_RECORD_ID, ANR0_RECORD_ID]); + }; + + recordHelper.updateEmail = function(pbr, recordNumber, email, adnRecordId, onsuccess, onerror) { + do_check_true(email == null); + onsuccess(); + }; + + recordHelper.updateANR = function(pbr, recordNumber, number, adnRecordId, onsuccess, onerror) { + do_check_true(number == null); + onsuccess(); + }; + + function do_test(type) { + recordHelper.readPBR = function(onsuccess, onerror) { + if (type == ICC_USIM_TYPE1_TAG) { + onsuccess([{ + adn: {fileId: ICC_EF_ADN}, + email: {fileId: EMAIL_FILE_ID, + fileType: ICC_USIM_TYPE1_TAG}, + anr0: {fileId: ANR0_FILE_ID, + fileType: ICC_USIM_TYPE1_TAG}}]); + } else { + onsuccess([{ + adn: {fileId: ICC_EF_ADN}, + iap: {fileId: IAP_FILE_ID}, + email: {fileId: EMAIL_FILE_ID, + fileType: ICC_USIM_TYPE2_TAG, + indexInIAP: 0}, + anr0: {fileId: ANR0_FILE_ID, + fileType: ICC_USIM_TYPE2_TAG, + indexInIAP: 1}}]); + } + }; + + let successCb = function() { + do_check_true(true); + }; + + let errorCb = function(errorMsg) { + do_print(errorMsg); + do_check_true(false); + }; + + contactHelper.updateICCContact(CARD_APPTYPE_USIM, "adn", contact, null, successCb, errorCb); + } + + do_test(ICC_USIM_TYPE1_TAG); + do_test(ICC_USIM_TYPE2_TAG); + + run_next_test(); +}); + +/** + * Verify ICCContactHelper.findFreeICCContact in SIM + */ +add_test(function test_find_free_icc_contact_sim() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let recordHelper = context.ICCRecordHelper; + let contactHelper = context.ICCContactHelper; + // Correct record Id starts with 1, so put a null element at index 0. + let records = [null]; + const MAX_RECORDS = 3; + const PBR_INDEX = 0; + + recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) { + if (records.length > MAX_RECORDS) { + onerror("No free record found."); + return; + } + + onsuccess(records.length); + }; + + let successCb = function(pbrIndex, recordId) { + do_check_eq(pbrIndex, PBR_INDEX); + records[recordId] = {}; + }; + + let errorCb = function(errorMsg) { + do_print(errorMsg); + do_check_true(false); + }; + + for (let i = 0; i < MAX_RECORDS; i++) { + contactHelper.findFreeICCContact(CARD_APPTYPE_SIM, "adn", successCb, errorCb); + } + // The 1st element, records[0], is null. + do_check_eq(records.length - 1, MAX_RECORDS); + + // Now the EF is full, so finding a free one should result failure. + successCb = function(pbrIndex, recordId) { + do_check_true(false); + }; + + errorCb = function(errorMsg) { + do_check_true(errorMsg === "No free record found."); + }; + contactHelper.findFreeICCContact(CARD_APPTYPE_SIM, "adn", successCb, errorCb); + + run_next_test(); +}); + +/** + * Verify ICCContactHelper.findFreeICCContact in USIM + */ +add_test(function test_find_free_icc_contact_usim() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let recordHelper = context.ICCRecordHelper; + let contactHelper = context.ICCContactHelper; + const ADN1_FILE_ID = 0x6f3a; + const ADN2_FILE_ID = 0x6f3b; + const MAX_RECORDS = 3; + + // The adn in the first phonebook set has already two records, which means + // only 1 free record remained. + let pbrs = [{adn: {fileId: ADN1_FILE_ID, records: [null, {}, {}]}}, + {adn: {fileId: ADN2_FILE_ID, records: [null]}}]; + + recordHelper.readPBR = function readPBR(onsuccess, onerror) { + onsuccess(pbrs); + }; + + recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) { + let pbr = (fileId == ADN1_FILE_ID ? pbrs[0]: pbrs[1]); + if (pbr.adn.records.length > MAX_RECORDS) { + onerror("No free record found."); + return; + } + + onsuccess(pbr.adn.records.length); + }; + + let successCb = function(pbrIndex, recordId) { + do_check_eq(pbrIndex, 0); + pbrs[pbrIndex].adn.records[recordId] = {}; + }; + + let errorCb = function(errorMsg) { + do_check_true(false); + }; + + contactHelper.findFreeICCContact(CARD_APPTYPE_USIM, "adn", successCb, errorCb); + + // Now the EF_ADN in the 1st phonebook set is full, so the next free contact + // will come from the 2nd phonebook set. + successCb = function(pbrIndex, recordId) { + do_check_eq(pbrIndex, 1); + do_check_eq(recordId, 1); + } + contactHelper.findFreeICCContact(CARD_APPTYPE_USIM, "adn", successCb, errorCb); + + run_next_test(); +});
new file mode 100644 --- /dev/null +++ b/dom/system/gonk/tests/test_ril_worker_icc_ICCIOHelper.js @@ -0,0 +1,164 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); + +function run_test() { + run_next_test(); +} + +/** + * Verify ICCIOHelper.loadLinearFixedEF with recordSize. + */ +add_test(function test_load_linear_fixed_ef() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let ril = context.RIL; + let io = context.ICCIOHelper; + + io.getResponse = function fakeGetResponse(options) { + // When recordSize is provided, loadLinearFixedEF should call iccIO directly. + do_check_true(false); + run_next_test(); + }; + + ril.iccIO = function fakeIccIO(options) { + do_check_true(true); + run_next_test(); + }; + + io.loadLinearFixedEF({recordSize: 0x20}); +}); + +/** + * Verify ICCIOHelper.loadLinearFixedEF without recordSize. + */ +add_test(function test_load_linear_fixed_ef() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let ril = context.RIL; + let io = context.ICCIOHelper; + + io.getResponse = function fakeGetResponse(options) { + do_check_true(true); + run_next_test(); + }; + + ril.iccIO = function fakeIccIO(options) { + // When recordSize is not provided, loadLinearFixedEF should call getResponse. + do_check_true(false); + run_next_test(); + }; + + io.loadLinearFixedEF({}); +}); + +/** + * Verify ICCIOHelper.processICCIOError. + */ +add_test(function test_process_icc_io_error() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let ioHelper = context.ICCIOHelper; + + function do_test(errorCode, expectedErrorMsg) { + let called = false; + function errorCb(errorMsg) { + called = true; + do_check_eq(errorMsg, expectedErrorMsg); + } + + ioHelper.processICCIOError({rilRequestError: errorCode, + fileId: 0xffff, + command: 0xff, + sw1: 0xff, + sw2: 0xff, + onerror: errorCb}); + do_check_true(called); + } + + for (let i = 0; i < ERROR_REJECTED_BY_REMOTE + 1; i++) { + do_test(i, RIL_ERROR_TO_GECKO_ERROR[i]); + } + + run_next_test(); +}); + +/** + * Verify ICCIOHelper.processICCIOGetResponse for EF_TYPE_TRANSPARENT. + */ +add_test(function test_icc_io_get_response_for_transparent_structure() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let buf = context.Buf; + let iccioHelper = context.ICCIOHelper; + let pduHelper = context.GsmPDUHelper; + + let responseArray = [ + // SIM response. + [0x00, 0x00, 0x00, 0x0A, 0x2F, 0xE2, 0x04, 0x00, 0x0A, 0xA0, 0xAA, 0x00, + 0x02, 0x00, 0x00], + // USIM response. + [0x62, 0x22, 0x82, 0x02, 0x41, 0x21, 0x83, 0x02, 0x2F, 0xE2, 0xA5, 0x09, + 0xC1, 0x04, 0x40, 0x0F, 0xF5, 0x55, 0x92, 0x01, 0x00, 0x8A, 0x01, 0x05, + 0x8B, 0x03, 0x2F, 0x06, 0x0B, 0x80, 0x02, 0x00, 0x0A, 0x88, 0x01, 0x10] + ]; + + for (let i = 0; i < responseArray.length; i++) { + let strLen = responseArray[i].length * 2; + buf.writeInt32(strLen); + for (let j = 0; j < responseArray[i].length; j++) { + pduHelper.writeHexOctet(responseArray[i][j]); + } + buf.writeStringDelimiter(strLen); + + let options = {fileId: ICC_EF_ICCID, + type: EF_TYPE_TRANSPARENT}; + iccioHelper.processICCIOGetResponse(options); + + do_check_eq(options.fileSize, 0x0A); + } + + run_next_test(); +}); + +/** + * Verify ICCIOHelper.processICCIOGetResponse for EF_TYPE_LINEAR_FIXED. + */ +add_test(function test_icc_io_get_response_for_linear_fixed_structure() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let buf = context.Buf; + let iccioHelper = context.ICCIOHelper; + let pduHelper = context.GsmPDUHelper; + + let responseArray = [ + // SIM response. + [0x00, 0x00, 0x00, 0x1A, 0x6F, 0x40, 0x04, 0x00, 0x11, 0xA0, 0xAA, 0x00, + 0x02, 0x01, 0x1A], + // USIM response. + [0x62, 0x1E, 0x82, 0x05, 0x42, 0x21, 0x00, 0x1A, 0x01, 0x83, 0x02, 0x6F, + 0x40, 0xA5, 0x03, 0x92, 0x01, 0x00, 0x8A, 0x01, 0x07, 0x8B, 0x03, 0x6F, + 0x06, 0x02, 0x80, 0x02, 0x00, 0x1A, 0x88, 0x00] + ]; + + for (let i = 0; i < responseArray.length; i++) { + let strLen = responseArray[i].length * 2; + buf.writeInt32(strLen); + for (let j = 0; j < responseArray[i].length; j++) { + pduHelper.writeHexOctet(responseArray[i][j]); + } + buf.writeStringDelimiter(strLen); + + let options = {fileId: ICC_EF_MSISDN, + type: EF_TYPE_LINEAR_FIXED}; + iccioHelper.processICCIOGetResponse(options); + + do_check_eq(options.fileSize, 0x1A); + do_check_eq(options.recordSize, 0x1A); + do_check_eq(options.totalRecords, 0x01); + } + + run_next_test(); +}); +
new file mode 100644 --- /dev/null +++ b/dom/system/gonk/tests/test_ril_worker_icc_ICCPDUHelper.js @@ -0,0 +1,520 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); + +function run_test() { + run_next_test(); +} + +/** + * Verify ICCPDUHelper#readICCUCS2String() + */ +add_test(function test_read_icc_ucs2_string() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let helper = context.GsmPDUHelper; + let iccHelper = context.ICCPDUHelper; + + // 0x80 + let text = "TEST"; + helper.writeUCS2String(text); + // Also write two unused octets. + let ffLen = 2; + for (let i = 0; i < ffLen; i++) { + helper.writeHexOctet(0xff); + } + do_check_eq(iccHelper.readICCUCS2String(0x80, (2 * text.length) + ffLen), text); + + // 0x81 + let array = [0x08, 0xd2, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca, + 0xff, 0xff]; + let len = array.length; + for (let i = 0; i < len; i++) { + helper.writeHexOctet(array[i]); + } + do_check_eq(iccHelper.readICCUCS2String(0x81, len), "Mozilla\u694a"); + + // 0x82 + let array2 = [0x08, 0x69, 0x00, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, + 0xca, 0xff, 0xff]; + let len2 = array2.length; + for (let i = 0; i < len2; i++) { + helper.writeHexOctet(array2[i]); + } + do_check_eq(iccHelper.readICCUCS2String(0x82, len2), "Mozilla\u694a"); + + run_next_test(); +}); + +/** + * Verify ICCPDUHelper#readDiallingNumber + */ +add_test(function test_read_dialling_number() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let helper = context.GsmPDUHelper; + let iccHelper = context.ICCPDUHelper; + let str = "123456789"; + + helper.readHexOctet = function() { + return 0x81; + }; + + helper.readSwappedNibbleBcdString = function(len) { + return str.substring(0, len); + }; + + for (let i = 0; i < str.length; i++) { + do_check_eq(str.substring(0, i - 1), // -1 for the TON + iccHelper.readDiallingNumber(i)); + } + + run_next_test(); +}); + +/** + * Verify ICCPDUHelper#read8BitUnpackedToString + */ +add_test(function test_read_8bit_unpacked_to_string() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let helper = context.GsmPDUHelper; + let iccHelper = context.ICCPDUHelper; + const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; + const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; + + // Test 1: Read GSM alphabets. + // Write alphabets before ESCAPE. + for (let i = 0; i < PDU_NL_EXTENDED_ESCAPE; i++) { + helper.writeHexOctet(i); + } + + // Write two ESCAPEs to make it become ' '. + helper.writeHexOctet(PDU_NL_EXTENDED_ESCAPE); + helper.writeHexOctet(PDU_NL_EXTENDED_ESCAPE); + + for (let i = PDU_NL_EXTENDED_ESCAPE + 1; i < langTable.length; i++) { + helper.writeHexOctet(i); + } + + // Also write two unused fields. + let ffLen = 2; + for (let i = 0; i < ffLen; i++) { + helper.writeHexOctet(0xff); + } + + do_check_eq(iccHelper.read8BitUnpackedToString(PDU_NL_EXTENDED_ESCAPE), + langTable.substring(0, PDU_NL_EXTENDED_ESCAPE)); + do_check_eq(iccHelper.read8BitUnpackedToString(2), " "); + do_check_eq(iccHelper.read8BitUnpackedToString(langTable.length - + PDU_NL_EXTENDED_ESCAPE - 1 + ffLen), + langTable.substring(PDU_NL_EXTENDED_ESCAPE + 1)); + + // Test 2: Read GSM extended alphabets. + for (let i = 0; i < langShiftTable.length; i++) { + helper.writeHexOctet(PDU_NL_EXTENDED_ESCAPE); + helper.writeHexOctet(i); + } + + // Read string before RESERVED_CONTROL. + do_check_eq(iccHelper.read8BitUnpackedToString(PDU_NL_RESERVED_CONTROL * 2), + langShiftTable.substring(0, PDU_NL_RESERVED_CONTROL)); + // ESCAPE + RESERVED_CONTROL will become ' '. + do_check_eq(iccHelper.read8BitUnpackedToString(2), " "); + // Read string between RESERVED_CONTROL and EXTENDED_ESCAPE. + do_check_eq(iccHelper.read8BitUnpackedToString( + (PDU_NL_EXTENDED_ESCAPE - PDU_NL_RESERVED_CONTROL - 1) * 2), + langShiftTable.substring(PDU_NL_RESERVED_CONTROL + 1, + PDU_NL_EXTENDED_ESCAPE)); + // ESCAPE + ESCAPE will become ' '. + do_check_eq(iccHelper.read8BitUnpackedToString(2), " "); + // Read remaining string. + do_check_eq(iccHelper.read8BitUnpackedToString( + (langShiftTable.length - PDU_NL_EXTENDED_ESCAPE - 1) * 2), + langShiftTable.substring(PDU_NL_EXTENDED_ESCAPE + 1)); + + run_next_test(); +}); + +/** + * Verify ICCPDUHelper#writeStringTo8BitUnpacked. + * + * Test writing GSM 8 bit alphabets. + */ +add_test(function test_write_string_to_8bit_unpacked() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let helper = context.GsmPDUHelper; + let iccHelper = context.ICCPDUHelper; + const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; + const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; + // Length of trailing 0xff. + let ffLen = 2; + let str; + + // Test 1, write GSM alphabets. + iccHelper.writeStringTo8BitUnpacked(langTable.length + ffLen, langTable); + + for (let i = 0; i < langTable.length; i++) { + do_check_eq(helper.readHexOctet(), i); + } + + for (let i = 0; i < ffLen; i++) { + do_check_eq(helper.readHexOctet(), 0xff); + } + + // Test 2, write GSM extended alphabets. + str = "\u000c\u20ac"; + iccHelper.writeStringTo8BitUnpacked(4, str); + + do_check_eq(iccHelper.read8BitUnpackedToString(4), str); + + // Test 3, write GSM and GSM extended alphabets. + // \u000c, \u20ac are from gsm extended alphabets. + // \u00a3 is from gsm alphabet. + str = "\u000c\u20ac\u00a3"; + + // 2 octets * 2 = 4 octets for 2 gsm extended alphabets, + // 1 octet for 1 gsm alphabet, + // 2 octes for trailing 0xff. + // "Totally 7 octets are to be written." + iccHelper.writeStringTo8BitUnpacked(7, str); + + do_check_eq(iccHelper.read8BitUnpackedToString(7), str); + + run_next_test(); +}); + +/** + * Verify ICCPDUHelper#writeStringTo8BitUnpacked with maximum octets written. + */ +add_test(function test_write_string_to_8bit_unpacked_with_max_octets_written() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let helper = context.GsmPDUHelper; + let iccHelper = context.ICCPDUHelper; + const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; + const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; + + // The maximum of the number of octets that can be written is 3. + // Only 3 characters shall be written even the length of the string is 4. + iccHelper.writeStringTo8BitUnpacked(3, langTable.substring(0, 4)); + helper.writeHexOctet(0xff); // dummy octet. + for (let i = 0; i < 3; i++) { + do_check_eq(helper.readHexOctet(), i); + } + do_check_false(helper.readHexOctet() == 4); + + // \u000c is GSM extended alphabet, 2 octets. + // \u00a3 is GSM alphabet, 1 octet. + let str = "\u000c\u00a3"; + iccHelper.writeStringTo8BitUnpacked(3, str); + do_check_eq(iccHelper.read8BitUnpackedToString(3), str); + + str = "\u00a3\u000c"; + iccHelper.writeStringTo8BitUnpacked(3, str); + do_check_eq(iccHelper.read8BitUnpackedToString(3), str); + + // 2 GSM extended alphabets cost 4 octets, but maximum is 3, so only the 1st + // alphabet can be written. + str = "\u000c\u000c"; + iccHelper.writeStringTo8BitUnpacked(3, str); + helper.writeHexOctet(0xff); // dummy octet. + do_check_eq(iccHelper.read8BitUnpackedToString(4), str.substring(0, 1)); + + run_next_test(); +}); + +/** + * Verify ICCPDUHelper.readAlphaIdentifier + */ +add_test(function test_read_alpha_identifier() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let helper = context.GsmPDUHelper; + let iccHelper = context.ICCPDUHelper; + + // UCS2: 0x80 + let text = "TEST"; + helper.writeHexOctet(0x80); + helper.writeUCS2String(text); + // Also write two unused octets. + let ffLen = 2; + for (let i = 0; i < ffLen; i++) { + helper.writeHexOctet(0xff); + } + do_check_eq(iccHelper.readAlphaIdentifier(1 + (2 * text.length) + ffLen), text); + + // UCS2: 0x81 + let array = [0x81, 0x08, 0xd2, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca, 0xff, 0xff]; + for (let i = 0; i < array.length; i++) { + helper.writeHexOctet(array[i]); + } + do_check_eq(iccHelper.readAlphaIdentifier(array.length), "Mozilla\u694a"); + + // UCS2: 0x82 + let array2 = [0x82, 0x08, 0x69, 0x00, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca, 0xff, 0xff]; + for (let i = 0; i < array2.length; i++) { + helper.writeHexOctet(array2[i]); + } + do_check_eq(iccHelper.readAlphaIdentifier(array2.length), "Mozilla\u694a"); + + // GSM 8 Bit Unpacked + const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; + for (let i = 0; i < PDU_NL_EXTENDED_ESCAPE; i++) { + helper.writeHexOctet(i); + } + do_check_eq(iccHelper.readAlphaIdentifier(PDU_NL_EXTENDED_ESCAPE), + langTable.substring(0, PDU_NL_EXTENDED_ESCAPE)); + + run_next_test(); +}); + +/** + * Verify ICCPDUHelper.writeAlphaIdentifier + */ +add_test(function test_write_alpha_identifier() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let helper = context.GsmPDUHelper; + let iccHelper = context.ICCPDUHelper; + // Length of trailing 0xff. + let ffLen = 2; + + // Removal + iccHelper.writeAlphaIdentifier(10, null); + do_check_eq(iccHelper.readAlphaIdentifier(10), ""); + + // GSM 8 bit + let str = "Mozilla"; + iccHelper.writeAlphaIdentifier(str.length + ffLen, str); + do_check_eq(iccHelper.readAlphaIdentifier(str.length + ffLen), str); + + // UCS2 + str = "Mozilla\u694a"; + iccHelper.writeAlphaIdentifier(str.length * 2 + ffLen, str); + // * 2 for each character will be encoded to UCS2 alphabets. + do_check_eq(iccHelper.readAlphaIdentifier(str.length * 2 + ffLen), str); + + // Test with maximum octets written. + // 1 coding scheme (0x80) and 1 UCS2 character, total 3 octets. + str = "\u694a"; + iccHelper.writeAlphaIdentifier(3, str); + do_check_eq(iccHelper.readAlphaIdentifier(3), str); + + // 1 coding scheme (0x80) and 2 UCS2 characters, total 5 octets. + // numOctets is limited to 4, so only 1 UCS2 character can be written. + str = "\u694a\u694a"; + iccHelper.writeAlphaIdentifier(4, str); + helper.writeHexOctet(0xff); // dummy octet. + do_check_eq(iccHelper.readAlphaIdentifier(5), str.substring(0, 1)); + + // Write 0 octet. + iccHelper.writeAlphaIdentifier(0, "1"); + helper.writeHexOctet(0xff); // dummy octet. + do_check_eq(iccHelper.readAlphaIdentifier(1), ""); + + run_next_test(); +}); + +/** + * Verify ICCPDUHelper.readAlphaIdDiallingNumber + */ +add_test(function test_read_alpha_id_dialling_number() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let helper = context.GsmPDUHelper; + let iccHelper = context.ICCPDUHelper; + let buf = context.Buf; + const recordSize = 32; + + function testReadAlphaIdDiallingNumber(contact) { + iccHelper.readAlphaIdentifier = function() { + return contact.alphaId; + }; + + iccHelper.readNumberWithLength = function() { + return contact.number; + }; + + let strLen = recordSize * 2; + buf.writeInt32(strLen); // fake length + helper.writeHexOctet(0xff); // fake CCP + helper.writeHexOctet(0xff); // fake EXT1 + buf.writeStringDelimiter(strLen); + + let contactR = iccHelper.readAlphaIdDiallingNumber(recordSize); + if (contact.alphaId == "" && contact.number == "") { + do_check_eq(contactR, null); + } else { + do_check_eq(contactR.alphaId, contact.alphaId); + do_check_eq(contactR.number, contact.number); + } + } + + testReadAlphaIdDiallingNumber({alphaId: "AlphaId", number: "0987654321"}); + testReadAlphaIdDiallingNumber({alphaId: "", number: ""}); + + run_next_test(); +}); + +/** + * Verify ICCPDUHelper.writeAlphaIdDiallingNumber + */ +add_test(function test_write_alpha_id_dialling_number() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let helper = context.ICCPDUHelper; + const recordSize = 32; + + // Write a normal contact. + let contactW = { + alphaId: "Mozilla", + number: "1234567890" + }; + helper.writeAlphaIdDiallingNumber(recordSize, contactW.alphaId, + contactW.number); + + let contactR = helper.readAlphaIdDiallingNumber(recordSize); + do_check_eq(contactW.alphaId, contactR.alphaId); + do_check_eq(contactW.number, contactR.number); + + // Write a contact with alphaId encoded in UCS2 and number has '+'. + let contactUCS2 = { + alphaId: "火狐", + number: "+1234567890" + }; + helper.writeAlphaIdDiallingNumber(recordSize, contactUCS2.alphaId, + contactUCS2.number); + contactR = helper.readAlphaIdDiallingNumber(recordSize); + do_check_eq(contactUCS2.alphaId, contactR.alphaId); + do_check_eq(contactUCS2.number, contactR.number); + + // Write a null contact (Removal). + helper.writeAlphaIdDiallingNumber(recordSize); + contactR = helper.readAlphaIdDiallingNumber(recordSize); + do_check_eq(contactR, null); + + // Write a longer alphaId/dialling number + // Dialling Number : Maximum 20 digits(10 octets). + // Alpha Identifier: 32(recordSize) - 14 (10 octets for Dialling Number, 1 + // octet for TON/NPI, 1 for number length octet, and 2 for + // Ext) = Maximum 18 octets. + let longContact = { + alphaId: "AAAAAAAAABBBBBBBBBCCCCCCCCC", + number: "123456789012345678901234567890", + }; + helper.writeAlphaIdDiallingNumber(recordSize, longContact.alphaId, + longContact.number); + contactR = helper.readAlphaIdDiallingNumber(recordSize); + do_check_eq(contactR.alphaId, "AAAAAAAAABBBBBBBBB"); + do_check_eq(contactR.number, "12345678901234567890"); + + // Add '+' to number and test again. + longContact.number = "+123456789012345678901234567890"; + helper.writeAlphaIdDiallingNumber(recordSize, longContact.alphaId, + longContact.number); + contactR = helper.readAlphaIdDiallingNumber(recordSize); + do_check_eq(contactR.alphaId, "AAAAAAAAABBBBBBBBB"); + do_check_eq(contactR.number, "+12345678901234567890"); + + run_next_test(); +}); + +/** + * Verify ICCPDUHelper.writeDiallingNumber + */ +add_test(function test_write_dialling_number() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let helper = context.ICCPDUHelper; + + // with + + let number = "+123456"; + let len = 4; + helper.writeDiallingNumber(number); + do_check_eq(helper.readDiallingNumber(len), number); + + // without + + number = "987654"; + len = 4; + helper.writeDiallingNumber(number); + do_check_eq(helper.readDiallingNumber(len), number); + + number = "9876543"; + len = 5; + helper.writeDiallingNumber(number); + do_check_eq(helper.readDiallingNumber(len), number); + + run_next_test(); +}); + +/** + * Verify ICCPDUHelper.readNumberWithLength + */ +add_test(function test_read_number_with_length() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let helper = context.GsmPDUHelper; + let iccHelper = context.ICCPDUHelper; + let number = "123456789"; + + iccHelper.readDiallingNumber = function(numLen) { + return number.substring(0, numLen); + }; + + helper.writeHexOctet(number.length + 1); + helper.writeHexOctet(PDU_TOA_ISDN); + do_check_eq(iccHelper.readNumberWithLength(), number); + + helper.writeHexOctet(0xff); + do_check_eq(iccHelper.readNumberWithLength(), null); + + run_next_test(); +}); + +/** + * Verify ICCPDUHelper.writeNumberWithLength + */ +add_test(function test_write_number_with_length() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let helper = context.GsmPDUHelper; + let iccHelper = context.ICCPDUHelper; + + function test(number, expectedNumber) { + expectedNumber = expectedNumber || number; + iccHelper.writeNumberWithLength(number); + let numLen = helper.readHexOctet(); + do_check_eq(expectedNumber, iccHelper.readDiallingNumber(numLen)); + for (let i = 0; i < (ADN_MAX_BCD_NUMBER_BYTES - numLen); i++) { + do_check_eq(0xff, helper.readHexOctet()); + } + } + + // without + + test("123456789"); + + // with + + test("+987654321"); + + // extended BCD coding + test("1*2#3,4*5#6,"); + + // with + and extended BCD coding + test("+1*2#3,4*5#6,"); + + // non-supported characters should not be written. + test("(1)23-456+789", "123456789"); + + test("++(01)2*3-4#5,6+7(8)9*0#1,", "+012*34#5,6789*0#1,"); + + // null + iccHelper.writeNumberWithLength(null); + for (let i = 0; i < (ADN_MAX_BCD_NUMBER_BYTES + 1); i++) { + do_check_eq(0xff, helper.readHexOctet()); + } + + run_next_test(); +});
new file mode 100644 --- /dev/null +++ b/dom/system/gonk/tests/test_ril_worker_icc_ICCRecordHelper.js @@ -0,0 +1,725 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); + +function run_test() { + run_next_test(); +} + +/** + * Verify ICCRecordHelper.readPBR + */ +add_test(function test_read_pbr() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let helper = context.GsmPDUHelper; + let record = context.ICCRecordHelper; + let buf = context.Buf; + let io = context.ICCIOHelper; + + io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { + let pbr_1 = [ + 0xa8, 0x05, 0xc0, 0x03, 0x4f, 0x3a, 0x01 + ]; + + // Write data size + buf.writeInt32(pbr_1.length * 2); + + // Write pbr + for (let i = 0; i < pbr_1.length; i++) { + helper.writeHexOctet(pbr_1[i]); + } + + // Write string delimiter + buf.writeStringDelimiter(pbr_1.length * 2); + + options.totalRecords = 2; + if (options.callback) { + options.callback(options); + } + }; + + io.loadNextRecord = function fakeLoadNextRecord(options) { + let pbr_2 = [ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + ]; + + options.p1++; + if (options.callback) { + options.callback(options); + } + }; + + let successCb = function successCb(pbrs) { + do_check_eq(pbrs[0].adn.fileId, 0x4f3a); + do_check_eq(pbrs.length, 1); + }; + + let errorCb = function errorCb(errorMsg) { + do_print("Reading EF_PBR failed, msg = " + errorMsg); + do_check_true(false); + }; + + record.readPBR(successCb, errorCb); + + // Check cache pbrs when 2nd call + let ifLoadEF = false; + io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { + ifLoadEF = true; + } + record.readPBR(successCb, errorCb); + do_check_false(ifLoadEF); + + run_next_test(); +}); + +/** + * Verify ICCRecordHelper.readEmail + */ +add_test(function test_read_email() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let helper = context.GsmPDUHelper; + let record = context.ICCRecordHelper; + let buf = context.Buf; + let io = context.ICCIOHelper; + let recordSize; + + io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { + let email_1 = [ + 0x65, 0x6D, 0x61, 0x69, 0x6C, + 0x00, 0x6D, 0x6F, 0x7A, 0x69, + 0x6C, 0x6C, 0x61, 0x2E, 0x63, + 0x6F, 0x6D, 0x02, 0x23]; + + // Write data size + buf.writeInt32(email_1.length * 2); + + // Write email + for (let i = 0; i < email_1.length; i++) { + helper.writeHexOctet(email_1[i]); + } + + // Write string delimiter + buf.writeStringDelimiter(email_1.length * 2); + + recordSize = email_1.length; + options.recordSize = recordSize; + if (options.callback) { + options.callback(options); + } + }; + + function doTestReadEmail(type, expectedResult) { + let fileId = 0x6a75; + let recordNumber = 1; + + // fileId and recordNumber are dummy arguments. + record.readEmail(fileId, type, recordNumber, function(email) { + do_check_eq(email, expectedResult); + }); + }; + + doTestReadEmail(ICC_USIM_TYPE1_TAG, "email@mozilla.com$#"); + doTestReadEmail(ICC_USIM_TYPE2_TAG, "email@mozilla.com"); + do_check_eq(record._emailRecordSize, recordSize); + + run_next_test(); +}); + +/** + * Verify ICCRecordHelper.updateEmail + */ +add_test(function test_update_email() { + const recordSize = 0x20; + const recordNumber = 1; + const fileId = 0x4f50; + const NUM_TESTS = 2; + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let pduHelper = context.GsmPDUHelper; + let iccHelper = context.ICCPDUHelper; + let ril = context.RIL; + ril.appType = CARD_APPTYPE_USIM; + let recordHelper = context.ICCRecordHelper; + let buf = context.Buf; + let ioHelper = context.ICCIOHelper; + let pbr = {email: {fileId: fileId, fileType: ICC_USIM_TYPE1_TAG}, + adn: {sfi: 1}}; + let count = 0; + + // Override. + ioHelper.updateLinearFixedEF = function(options) { + options.pathId = context.ICCFileHelper.getEFPath(options.fileId); + options.command = ICC_COMMAND_UPDATE_RECORD; + options.p1 = options.recordNumber; + options.p2 = READ_RECORD_ABSOLUTE_MODE; + options.p3 = recordSize; + ril.iccIO(options); + }; + + function do_test(pbr, expectedEmail, expectedAdnRecordId) { + buf.sendParcel = function() { + count++; + + // Request Type. + do_check_eq(this.readInt32(), REQUEST_SIM_IO); + + // Token : we don't care + this.readInt32(); + + // command. + do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD); + + // fileId. + do_check_eq(this.readInt32(), fileId); + + // pathId. + do_check_eq(this.readString(), + EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK); + + // p1. + do_check_eq(this.readInt32(), recordNumber); + + // p2. + do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE); + + // p3. + do_check_eq(this.readInt32(), recordSize); + + // data. + let strLen = this.readInt32(); + let email; + if (pbr.email.fileType === ICC_USIM_TYPE1_TAG) { + email = iccHelper.read8BitUnpackedToString(recordSize); + } else { + email = iccHelper.read8BitUnpackedToString(recordSize - 2); + do_check_eq(pduHelper.readHexOctet(), pbr.adn.sfi); + do_check_eq(pduHelper.readHexOctet(), expectedAdnRecordId); + } + this.readStringDelimiter(strLen); + do_check_eq(email, expectedEmail); + + // pin2. + do_check_eq(this.readString(), null); + + if (!ril.v5Legacy) { + // AID. Ignore because it's from modem. + this.readInt32(); + } + + if (count == NUM_TESTS) { + run_next_test(); + } + }; + recordHelper.updateEmail(pbr, recordNumber, expectedEmail, expectedAdnRecordId); + } + + do_test(pbr, "test@mail.com"); + pbr.email.fileType = ICC_USIM_TYPE2_TAG; + do_test(pbr, "test@mail.com", 1); +}); + +/** + * Verify ICCRecordHelper.readANR + */ +add_test(function test_read_anr() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let helper = context.GsmPDUHelper; + let record = context.ICCRecordHelper; + let buf = context.Buf; + let io = context.ICCIOHelper; + let recordSize; + + io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { + let anr_1 = [ + 0x01, 0x05, 0x81, 0x10, 0x32, + 0x54, 0xF6, 0xFF, 0xFF]; + + // Write data size + buf.writeInt32(anr_1.length * 2); + + // Write anr + for (let i = 0; i < anr_1.length; i++) { + helper.writeHexOctet(anr_1[i]); + } + + // Write string delimiter + buf.writeStringDelimiter(anr_1.length * 2); + + recordSize = anr_1.length; + options.recordSize = recordSize; + if (options.callback) { + options.callback(options); + } + }; + + function doTestReadAnr(fileType, expectedResult) { + let fileId = 0x4f11; + let recordNumber = 1; + + // fileId and recordNumber are dummy arguments. + record.readANR(fileId, fileType, recordNumber, function(anr) { + do_check_eq(anr, expectedResult); + }); + }; + + doTestReadAnr(ICC_USIM_TYPE1_TAG, "0123456"); + do_check_eq(record._anrRecordSize, recordSize); + + run_next_test(); +}); + +/** + * Verify ICCRecordHelper.updateANR + */ +add_test(function test_update_anr() { + const recordSize = 0x20; + const recordNumber = 1; + const fileId = 0x4f11; + const NUM_TESTS = 2; + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let pduHelper = context.GsmPDUHelper; + let iccHelper = context.ICCPDUHelper; + let ril = context.RIL; + ril.appType = CARD_APPTYPE_USIM; + let recordHelper = context.ICCRecordHelper; + let buf = context.Buf; + let ioHelper = context.ICCIOHelper; + let pbr = {anr0: {fileId: fileId, fileType: ICC_USIM_TYPE1_TAG}, + adn: {sfi: 1}}; + let count = 0; + + // Override. + ioHelper.updateLinearFixedEF = function(options) { + options.pathId = context.ICCFileHelper.getEFPath(options.fileId); + options.command = ICC_COMMAND_UPDATE_RECORD; + options.p1 = options.recordNumber; + options.p2 = READ_RECORD_ABSOLUTE_MODE; + options.p3 = recordSize; + ril.iccIO(options); + }; + + function do_test(pbr, expectedANR, expectedAdnRecordId) { + buf.sendParcel = function() { + count++; + + // Request Type. + do_check_eq(this.readInt32(), REQUEST_SIM_IO); + + // Token : we don't care + this.readInt32(); + + // command. + do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD); + + // fileId. + do_check_eq(this.readInt32(), fileId); + + // pathId. + do_check_eq(this.readString(), + EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK); + + // p1. + do_check_eq(this.readInt32(), recordNumber); + + // p2. + do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE); + + // p3. + do_check_eq(this.readInt32(), recordSize); + + // data. + let strLen = this.readInt32(); + // EF_AAS, ignore. + pduHelper.readHexOctet(); + do_check_eq(iccHelper.readNumberWithLength(), expectedANR); + // EF_CCP, ignore. + pduHelper.readHexOctet(); + // EF_EXT1, ignore. + pduHelper.readHexOctet(); + if (pbr.anr0.fileType === ICC_USIM_TYPE2_TAG) { + do_check_eq(pduHelper.readHexOctet(), pbr.adn.sfi); + do_check_eq(pduHelper.readHexOctet(), expectedAdnRecordId); + } + this.readStringDelimiter(strLen); + + // pin2. + do_check_eq(this.readString(), null); + + if (!ril.v5Legacy) { + // AID. Ignore because it's from modem. + this.readInt32(); + } + + if (count == NUM_TESTS) { + run_next_test(); + } + }; + recordHelper.updateANR(pbr, recordNumber, expectedANR, expectedAdnRecordId); + } + + do_test(pbr, "+123456789"); + pbr.anr0.fileType = ICC_USIM_TYPE2_TAG; + do_test(pbr, "123456789", 1); +}); + +/** + * Verify ICCRecordHelper.readIAP + */ +add_test(function test_read_iap() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let helper = context.GsmPDUHelper; + let record = context.ICCRecordHelper; + let buf = context.Buf; + let io = context.ICCIOHelper; + let recordSize; + + io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { + let iap_1 = [0x01, 0x02]; + + // Write data size/ + buf.writeInt32(iap_1.length * 2); + + // Write iap. + for (let i = 0; i < iap_1.length; i++) { + helper.writeHexOctet(iap_1[i]); + } + + // Write string delimiter. + buf.writeStringDelimiter(iap_1.length * 2); + + recordSize = iap_1.length; + options.recordSize = recordSize; + if (options.callback) { + options.callback(options); + } + }; + + function doTestReadIAP(expectedIAP) { + const fileId = 0x4f17; + const recordNumber = 1; + + let successCb = function successCb(iap) { + for (let i = 0; i < iap.length; i++) { + do_check_eq(expectedIAP[i], iap[i]); + } + run_next_test(); + }.bind(this); + + let errorCb = function errorCb(errorMsg) { + do_print(errorMsg); + do_check_true(false); + run_next_test(); + }.bind(this); + + record.readIAP(fileId, recordNumber, successCb, errorCb); + }; + + doTestReadIAP([1, 2]); +}); + +/** + * Verify ICCRecordHelper.updateIAP + */ +add_test(function test_update_iap() { + const recordSize = 2; + const recordNumber = 1; + const fileId = 0x4f17; + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let pduHelper = context.GsmPDUHelper; + let ril = context.RIL; + ril.appType = CARD_APPTYPE_USIM; + let recordHelper = context.ICCRecordHelper; + let buf = context.Buf; + let ioHelper = context.ICCIOHelper; + let count = 0; + + // Override. + ioHelper.updateLinearFixedEF = function(options) { + options.pathId = context.ICCFileHelper.getEFPath(options.fileId); + options.command = ICC_COMMAND_UPDATE_RECORD; + options.p1 = options.recordNumber; + options.p2 = READ_RECORD_ABSOLUTE_MODE; + options.p3 = recordSize; + ril.iccIO(options); + }; + + function do_test(expectedIAP) { + buf.sendParcel = function() { + // Request Type. + do_check_eq(this.readInt32(), REQUEST_SIM_IO); + + // Token : we don't care + this.readInt32(); + + // command. + do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD); + + // fileId. + do_check_eq(this.readInt32(), fileId); + + // pathId. + do_check_eq(this.readString(), + EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK); + + // p1. + do_check_eq(this.readInt32(), recordNumber); + + // p2. + do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE); + + // p3. + do_check_eq(this.readInt32(), recordSize); + + // data. + let strLen = this.readInt32(); + for (let i = 0; i < recordSize; i++) { + do_check_eq(expectedIAP[i], pduHelper.readHexOctet()); + } + this.readStringDelimiter(strLen); + + // pin2. + do_check_eq(this.readString(), null); + + if (!ril.v5Legacy) { + // AID. Ignore because it's from modem. + this.readInt32(); + } + + run_next_test(); + }; + recordHelper.updateIAP(fileId, recordNumber, expectedIAP); + } + + do_test([1, 2]); +}); + +/** + * Verify ICCRecordHelper.updateADNLike. + */ +add_test(function test_update_adn_like() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let ril = context.RIL; + let record = context.ICCRecordHelper; + let io = context.ICCIOHelper; + let pdu = context.ICCPDUHelper; + let buf = context.Buf; + + ril.appType = CARD_APPTYPE_SIM; + const recordSize = 0x20; + let fileId; + + // Override. + io.updateLinearFixedEF = function(options) { + options.pathId = context.ICCFileHelper.getEFPath(options.fileId); + options.command = ICC_COMMAND_UPDATE_RECORD; + options.p1 = options.recordNumber; + options.p2 = READ_RECORD_ABSOLUTE_MODE; + options.p3 = recordSize; + ril.iccIO(options); + }; + + buf.sendParcel = function() { + // Request Type. + do_check_eq(this.readInt32(), REQUEST_SIM_IO); + + // Token : we don't care + this.readInt32(); + + // command. + do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD); + + // fileId. + do_check_eq(this.readInt32(), fileId); + + // pathId. + do_check_eq(this.readString(), EF_PATH_MF_SIM + EF_PATH_DF_TELECOM); + + // p1. + do_check_eq(this.readInt32(), 1); + + // p2. + do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE); + + // p3. + do_check_eq(this.readInt32(), 0x20); + + // data. + let contact = pdu.readAlphaIdDiallingNumber(0x20); + do_check_eq(contact.alphaId, "test"); + do_check_eq(contact.number, "123456"); + + // pin2. + if (fileId == ICC_EF_ADN) { + do_check_eq(this.readString(), null); + } else { + do_check_eq(this.readString(), "1111"); + } + + if (!ril.v5Legacy) { + // AID. Ignore because it's from modem. + this.readInt32(); + } + + if (fileId == ICC_EF_FDN) { + run_next_test(); + } + }; + + fileId = ICC_EF_ADN; + record.updateADNLike(fileId, + {recordId: 1, alphaId: "test", number: "123456"}); + + fileId = ICC_EF_FDN; + record.updateADNLike(fileId, + {recordId: 1, alphaId: "test", number: "123456"}, + "1111"); +}); + +/** + * Verify ICCRecordHelper.findFreeRecordId. + */ +add_test(function test_find_free_record_id() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let pduHelper = context.GsmPDUHelper; + let recordHelper = context.ICCRecordHelper; + let buf = context.Buf; + let io = context.ICCIOHelper; + + function writeRecord (record) { + // Write data size + buf.writeInt32(record.length * 2); + + for (let i = 0; i < record.length; i++) { + pduHelper.writeHexOctet(record[i]); + } + + // Write string delimiter + buf.writeStringDelimiter(record.length * 2); + } + + io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { + // Some random data. + let record = [0x12, 0x34, 0x56, 0x78, 0x90]; + options.p1 = 1; + options.totalRecords = 2; + writeRecord(record); + if (options.callback) { + options.callback(options); + } + }; + + io.loadNextRecord = function fakeLoadNextRecord(options) { + // Unused bytes. + let record = [0xff, 0xff, 0xff, 0xff, 0xff]; + options.p1++; + writeRecord(record); + if (options.callback) { + options.callback(options); + } + }; + + let fileId = 0x0000; // Dummy. + recordHelper.findFreeRecordId( + fileId, + function(recordId) { + do_check_eq(recordId, 2); + run_next_test(); + }.bind(this), + function(errorMsg) { + do_print(errorMsg); + do_check_true(false); + run_next_test(); + }.bind(this)); +}); + +/** + * Verify ICCRecordHelper.fetchICCRecords. + */ +add_test(function test_fetch_icc_recodes() { + let worker = newWorker(); + let context = worker.ContextPool._contexts[0]; + let RIL = context.RIL; + let iccRecord = context.ICCRecordHelper; + let simRecord = context.SimRecordHelper; + let ruimRecord = context.RuimRecordHelper; + let fetchTag = 0x00; + + simRecord.fetchSimRecords = function() { + fetchTag = 0x01; + }; + + ruimRecord.fetchRuimRecords = function() { + fetchTag = 0x02; + }; + + RIL.appType = CARD_APPTYPE_SIM; + iccRecord.fetchICCRecords(); + do_check_eq(fetchTag, 0x01); + + RIL.appType = CARD_APPTYPE_RUIM; + iccRecord.fetchICCRecords(); + do_check_eq(fetchTag, 0x02); + + RIL.appType = CARD_APPTYPE_USIM; + iccRecord.fetchICCRecords(); + do_check_eq(fetchTag, 0x01); + + run_next_test(); +}); + +/** + * Verify reading EF_ICCID. + */ +add_test(function test_handling_iccid() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let record = context.ICCRecordHelper; + let helper = context.GsmPDUHelper; + let ril = context.RIL; + let buf = context.Buf; + let io = context.ICCIOHelper; + + ril.reportStkServiceIsRunning = function fakeReportStkServiceIsRunning() { + }; + + function do_test(rawICCID, expectedICCID) { + io.loadTransparentEF = function fakeLoadTransparentEF(options) { + // Write data size + buf.writeInt32(rawICCID.length); + + // Write data + for (let i = 0; i < rawICCID.length; i += 2) { + helper.writeHexOctet(parseInt(rawICCID.substr(i, 2), 16)); + } + + // Write string delimiter + buf.writeStringDelimiter(rawICCID.length); + + if (options.callback) { + options.callback(options); + } + }; + + record.readICCID(); + + do_check_eq(ril.iccInfo.iccid, expectedICCID); + } + + // Invalid char at high nibbile + low nibbile contains 0xF. + do_test("9868002E90909F001519", "89860020909"); + // Invalid char at low nibbile. + do_test("986800E2909090001519", "8986002090909005191"); + // Valid ICCID. + do_test("98101430121181157002", "89014103211118510720"); + + run_next_test(); +});
new file mode 100644 --- /dev/null +++ b/dom/system/gonk/tests/test_ril_worker_icc_ICCUtilsHelper.js @@ -0,0 +1,236 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); + +function run_test() { + run_next_test(); +} + +/** + * Verify ICCUtilsHelper.isICCServiceAvailable. + */ +add_test(function test_is_icc_service_available() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let ICCUtilsHelper = context.ICCUtilsHelper; + let RIL = context.RIL; + + function test_table(sst, geckoService, simEnabled, usimEnabled) { + RIL.iccInfoPrivate.sst = sst; + RIL.appType = CARD_APPTYPE_SIM; + do_check_eq(ICCUtilsHelper.isICCServiceAvailable(geckoService), simEnabled); + RIL.appType = CARD_APPTYPE_USIM; + do_check_eq(ICCUtilsHelper.isICCServiceAvailable(geckoService), usimEnabled); + } + + test_table([0x08], "ADN", true, false); + test_table([0x08], "FDN", false, false); + test_table([0x08], "SDN", false, true); + + run_next_test(); +}); + +/** + * Verify ICCUtilsHelper.isGsm8BitAlphabet + */ +add_test(function test_is_gsm_8bit_alphabet() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let ICCUtilsHelper = context.ICCUtilsHelper; + const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; + const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; + + do_check_eq(ICCUtilsHelper.isGsm8BitAlphabet(langTable), true); + do_check_eq(ICCUtilsHelper.isGsm8BitAlphabet(langShiftTable), true); + do_check_eq(ICCUtilsHelper.isGsm8BitAlphabet("\uaaaa"), false); + + run_next_test(); +}); + +/** + * Verify ICCUtilsHelper.parsePbrTlvs + */ +add_test(function test_parse_pbr_tlvs() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let buf = context.Buf; + + let pbrTlvs = [ + {tag: ICC_USIM_TYPE1_TAG, + length: 0x0F, + value: [{tag: ICC_USIM_EFADN_TAG, + length: 0x03, + value: [0x4F, 0x3A, 0x02]}, + {tag: ICC_USIM_EFIAP_TAG, + length: 0x03, + value: [0x4F, 0x25, 0x01]}, + {tag: ICC_USIM_EFPBC_TAG, + length: 0x03, + value: [0x4F, 0x09, 0x04]}] + }, + {tag: ICC_USIM_TYPE2_TAG, + length: 0x05, + value: [{tag: ICC_USIM_EFEMAIL_TAG, + length: 0x03, + value: [0x4F, 0x50, 0x0B]}, + {tag: ICC_USIM_EFANR_TAG, + length: 0x03, + value: [0x4F, 0x11, 0x02]}, + {tag: ICC_USIM_EFANR_TAG, + length: 0x03, + value: [0x4F, 0x12, 0x03]}] + }, + {tag: ICC_USIM_TYPE3_TAG, + length: 0x0A, + value: [{tag: ICC_USIM_EFCCP1_TAG, + length: 0x03, + value: [0x4F, 0x3D, 0x0A]}, + {tag: ICC_USIM_EFEXT1_TAG, + length: 0x03, + value: [0x4F, 0x4A, 0x03]}] + }, + ]; + + let pbr = context.ICCUtilsHelper.parsePbrTlvs(pbrTlvs); + do_check_eq(pbr.adn.fileId, 0x4F3a); + do_check_eq(pbr.iap.fileId, 0x4F25); + do_check_eq(pbr.pbc.fileId, 0x4F09); + do_check_eq(pbr.email.fileId, 0x4F50); + do_check_eq(pbr.anr0.fileId, 0x4f11); + do_check_eq(pbr.anr1.fileId, 0x4f12); + do_check_eq(pbr.ccp1.fileId, 0x4F3D); + do_check_eq(pbr.ext1.fileId, 0x4F4A); + + run_next_test(); +}); + +/** + * Verify MCC and MNC parsing + */ +add_test(function test_mcc_mnc_parsing() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let helper = context.ICCUtilsHelper; + + function do_test(imsi, mncLength, expectedMcc, expectedMnc) { + let result = helper.parseMccMncFromImsi(imsi, mncLength); + + if (!imsi) { + do_check_eq(result, null); + return; + } + + do_check_eq(result.mcc, expectedMcc); + do_check_eq(result.mnc, expectedMnc); + } + + // Test the imsi is null. + do_test(null, null, null, null); + + // Test MCC is Taiwan + do_test("466923202422409", 0x02, "466", "92"); + do_test("466923202422409", 0x03, "466", "923"); + do_test("466923202422409", null, "466", "92"); + + // Test MCC is US + do_test("310260542718417", 0x02, "310", "26"); + do_test("310260542718417", 0x03, "310", "260"); + do_test("310260542718417", null, "310", "260"); + + run_next_test(); +}); + +add_test(function test_get_network_name_from_icc() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let RIL = context.RIL; + let ICCUtilsHelper = context.ICCUtilsHelper; + + function testGetNetworkNameFromICC(operatorData, expectedResult) { + let result = ICCUtilsHelper.getNetworkNameFromICC(operatorData.mcc, + operatorData.mnc, + operatorData.lac); + + if (expectedResult == null) { + do_check_eq(result, expectedResult); + } else { + do_check_eq(result.fullName, expectedResult.longName); + do_check_eq(result.shortName, expectedResult.shortName); + } + } + + // Before EF_OPL and EF_PNN have been loaded. + testGetNetworkNameFromICC({mcc: 123, mnc: 456, lac: 0x1000}, null); + testGetNetworkNameFromICC({mcc: 321, mnc: 654, lac: 0x2000}, null); + + // Set HPLMN + RIL.iccInfo.mcc = 123; + RIL.iccInfo.mnc = 456; + + RIL.voiceRegistrationState = { + cell: { + gsmLocationAreaCode: 0x1000 + } + }; + RIL.operator = {}; + + // Set EF_PNN + RIL.iccInfoPrivate = { + PNN: [ + {"fullName": "PNN1Long", "shortName": "PNN1Short"}, + {"fullName": "PNN2Long", "shortName": "PNN2Short"}, + {"fullName": "PNN3Long", "shortName": "PNN3Short"}, + {"fullName": "PNN4Long", "shortName": "PNN4Short"} + ] + }; + + // EF_OPL isn't available and current isn't in HPLMN, + testGetNetworkNameFromICC({mcc: 321, mnc: 654, lac: 0x1000}, null); + + // EF_OPL isn't available and current is in HPLMN, + // the first record of PNN should be returned. + testGetNetworkNameFromICC({mcc: 123, mnc: 456, lac: 0x1000}, + {longName: "PNN1Long", shortName: "PNN1Short"}); + + // Set EF_OPL + RIL.iccInfoPrivate.OPL = [ + { + "mcc": 123, + "mnc": 456, + "lacTacStart": 0, + "lacTacEnd": 0xFFFE, + "pnnRecordId": 4 + }, + { + "mcc": 321, + "mnc": 654, + "lacTacStart": 0, + "lacTacEnd": 0x0010, + "pnnRecordId": 3 + }, + { + "mcc": 321, + "mnc": 654, + "lacTacStart": 0x0100, + "lacTacEnd": 0x1010, + "pnnRecordId": 2 + } + ]; + + // Both EF_PNN and EF_OPL are presented, and current PLMN is HPLMN, + testGetNetworkNameFromICC({mcc: 123, mnc: 456, lac: 0x1000}, + {longName: "PNN4Long", shortName: "PNN4Short"}); + + // Current PLMN is not HPLMN, and according to LAC, we should get + // the second PNN record. + testGetNetworkNameFromICC({mcc: 321, mnc: 654, lac: 0x1000}, + {longName: "PNN2Long", shortName: "PNN2Short"}); + + // Current PLMN is not HPLMN, and according to LAC, we should get + // the thrid PNN record. + testGetNetworkNameFromICC({mcc: 321, mnc: 654, lac: 0x0001}, + {longName: "PNN3Long", shortName: "PNN3Short"}); + + run_next_test(); +});
new file mode 100644 --- /dev/null +++ b/dom/system/gonk/tests/test_ril_worker_icc_SimRecordHelper.js @@ -0,0 +1,489 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); + +function run_test() { + run_next_test(); +} + +/** + * Verify reading EF_AD and parsing MCC/MNC + */ +add_test(function test_reading_ad_and_parsing_mcc_mnc() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let record = context.SimRecordHelper; + let helper = context.GsmPDUHelper; + let ril = context.RIL; + let buf = context.Buf; + let io = context.ICCIOHelper; + + function do_test(mncLengthInEf, imsi, expectedMcc, expectedMnc) { + ril.iccInfoPrivate.imsi = imsi; + + io.loadTransparentEF = function fakeLoadTransparentEF(options) { + let ad = [0x00, 0x00, 0x00]; + if (typeof mncLengthInEf === 'number') { + ad.push(mncLengthInEf); + } + + // Write data size + buf.writeInt32(ad.length * 2); + + // Write data + for (let i = 0; i < ad.length; i++) { + helper.writeHexOctet(ad[i]); + } + + // Write string delimiter + buf.writeStringDelimiter(ad.length * 2); + + if (options.callback) { + options.callback(options); + } + }; + + record.readAD(); + + do_check_eq(ril.iccInfo.mcc, expectedMcc); + do_check_eq(ril.iccInfo.mnc, expectedMnc); + } + + do_test(undefined, "466923202422409", "466", "92" ); + do_test(0x00, "466923202422409", "466", "92" ); + do_test(0x01, "466923202422409", "466", "92" ); + do_test(0x02, "466923202422409", "466", "92" ); + do_test(0x03, "466923202422409", "466", "923"); + do_test(0x04, "466923202422409", "466", "92" ); + do_test(0xff, "466923202422409", "466", "92" ); + + do_test(undefined, "310260542718417", "310", "260"); + do_test(0x00, "310260542718417", "310", "260"); + do_test(0x01, "310260542718417", "310", "260"); + do_test(0x02, "310260542718417", "310", "26" ); + do_test(0x03, "310260542718417", "310", "260"); + do_test(0x04, "310260542718417", "310", "260"); + do_test(0xff, "310260542718417", "310", "260"); + + run_next_test(); +}); + +add_test(function test_reading_optional_efs() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let record = context.SimRecordHelper; + let gsmPdu = context.GsmPDUHelper; + let ril = context.RIL; + let buf = context.Buf; + let io = context.ICCIOHelper; + + function buildSST(supportedEf) { + let sst = []; + let len = supportedEf.length; + for (let i = 0; i < len; i++) { + let index, bitmask, iccService; + if (ril.appType === CARD_APPTYPE_SIM) { + iccService = GECKO_ICC_SERVICES.sim[supportedEf[i]]; + iccService -= 1; + index = Math.floor(iccService / 4); + bitmask = 2 << ((iccService % 4) << 1); + } else if (ril.appType === CARD_APPTYPE_USIM){ + iccService = GECKO_ICC_SERVICES.usim[supportedEf[i]]; + iccService -= 1; + index = Math.floor(iccService / 8); + bitmask = 1 << ((iccService % 8) << 0); + } + + if (sst) { + sst[index] |= bitmask; + } + } + return sst; + } + + ril.updateCellBroadcastConfig = function fakeUpdateCellBroadcastConfig() { + // Ignore updateCellBroadcastConfig after reading SST + }; + + function do_test(sst, supportedEf) { + // Clone supportedEf to local array for testing + let testEf = supportedEf.slice(0); + + record.readMSISDN = function fakeReadMSISDN() { + testEf.splice(testEf.indexOf("MSISDN"), 1); + }; + + record.readMBDN = function fakeReadMBDN() { + testEf.splice(testEf.indexOf("MDN"), 1); + }; + + record.readMWIS = function fakeReadMWIS() { + testEf.splice(testEf.indexOf("MWIS"), 1); + }; + + io.loadTransparentEF = function fakeLoadTransparentEF(options) { + // Write data size + buf.writeInt32(sst.length * 2); + + // Write data + for (let i = 0; i < sst.length; i++) { + gsmPdu.writeHexOctet(sst[i] || 0); + } + + // Write string delimiter + buf.writeStringDelimiter(sst.length * 2); + + if (options.callback) { + options.callback(options); + } + + if (testEf.length !== 0) { + do_print("Un-handled EF: " + JSON.stringify(testEf)); + do_check_true(false); + } + }; + + record.readSST(); + } + + // TODO: Add all necessary optional EFs eventually + let supportedEf = ["MSISDN", "MDN", "MWIS"]; + ril.appType = CARD_APPTYPE_SIM; + do_test(buildSST(supportedEf), supportedEf); + ril.appType = CARD_APPTYPE_USIM; + do_test(buildSST(supportedEf), supportedEf); + + run_next_test(); +}); + +/** + * Verify fetchSimRecords. + */ +add_test(function test_fetch_sim_recodes() { + let worker = newWorker(); + let context = worker.ContextPool._contexts[0]; + let RIL = context.RIL; + let iccRecord = context.ICCRecordHelper; + let simRecord = context.SimRecordHelper; + + function testFetchSimRecordes(expectCalled) { + let ifCalled = []; + + RIL.getIMSI = function() { + ifCalled.push("getIMSI"); + }; + + simRecord.readAD = function() { + ifCalled.push("readAD"); + }; + + simRecord.readSST = function() { + ifCalled.push("readSST"); + }; + + simRecord.fetchSimRecords(); + + for (let i = 0; i < expectCalled.length; i++ ) { + if (ifCalled[i] != expectCalled[i]) { + do_print(expectCalled[i] + " is not called."); + do_check_true(false); + } + } + } + + let expectCalled = ["getIMSI", "readAD", "readSST"]; + testFetchSimRecordes(expectCalled); + + run_next_test(); +}); + +/** + * Verify SimRecordHelper.readMWIS + */ +add_test(function test_read_mwis() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let helper = context.GsmPDUHelper; + let recordHelper = context.SimRecordHelper; + let buf = context.Buf; + let io = context.ICCIOHelper; + let mwisData; + let postedMessage; + + worker.postMessage = function fakePostMessage(message) { + postedMessage = message; + }; + + io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { + if (mwisData) { + // Write data size + buf.writeInt32(mwisData.length * 2); + + // Write MWIS + for (let i = 0; i < mwisData.length; i++) { + helper.writeHexOctet(mwisData[i]); + } + + // Write string delimiter + buf.writeStringDelimiter(mwisData.length * 2); + + options.recordSize = mwisData.length; + if (options.callback) { + options.callback(options); + } + } else { + do_print("mwisData[] is not set."); + } + }; + + function buildMwisData(isActive, msgCount) { + if (msgCount < 0 || msgCount === GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN) { + msgCount = 0; + } else if (msgCount > 255) { + msgCount = 255; + } + + mwisData = [ (isActive) ? 0x01 : 0x00, + msgCount, + 0xFF, 0xFF, 0xFF ]; + } + + function do_test(isActive, msgCount) { + buildMwisData(isActive, msgCount); + recordHelper.readMWIS(); + + do_check_eq("iccmwis", postedMessage.rilMessageType); + do_check_eq(isActive, postedMessage.mwi.active); + do_check_eq((isActive) ? msgCount : 0, postedMessage.mwi.msgCount); + } + + do_test(true, GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN); + do_test(true, 1); + do_test(true, 255); + + do_test(false, 0); + do_test(false, 255); // Test the corner case when mwi is disable with incorrect msgCount. + + run_next_test(); +}); + +/** + * Verify SimRecordHelper.updateMWIS + */ +add_test(function test_update_mwis() { + let worker = newUint8Worker(); + let context = worker.ContextPool._contexts[0]; + let pduHelper = context.GsmPDUHelper; + let ril = context.RIL; + ril.appType = CARD_APPTYPE_USIM; + ril.iccInfoPrivate.mwis = [0x00, 0x00, 0x00, 0x00, 0x00]; + let recordHelper = context.SimRecordHelper; + let buf = context.Buf; + let ioHelper = context.ICCIOHelper; + let recordSize = ril.iccInfoPrivate.mwis.length; + let recordNum = 1; + + ioHelper.updateLinearFixedEF = function(options) { + options.pathId = context.ICCFileHelper.getEFPath(options.fileId); + options.command = ICC_COMMAND_UPDATE_RECORD; + options.p1 = options.recordNumber; + options.p2 = READ_RECORD_ABSOLUTE_MODE; + options.p3 = recordSize; + ril.iccIO(options); + }; + + function do_test(isActive, count) { + let mwis = ril.iccInfoPrivate.mwis; + let isUpdated = false; + + function buildMwisData() { + let result = mwis.slice(0); + result[0] = isActive? (mwis[0] | 0x01) : (mwis[0] & 0xFE); + result[1] = (count === GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN) ? 0 : count; + + return result; + } + + buf.sendParcel = function() { + isUpdated = true; + + // Request Type. + do_check_eq(this.readInt32(), REQUEST_SIM_IO); + + // Token : we don't care + this.readInt32(); + + // command. + do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD); + + // fileId. + do_check_eq(this.readInt32(), ICC_EF_MWIS); + + // pathId. + do_check_eq(this.readString(), + EF_PATH_MF_SIM + ((ril.appType === CARD_APPTYPE_USIM) ? EF_PATH_ADF_USIM : EF_PATH_DF_GSM)); + + // p1. + do_check_eq(this.readInt32(), recordNum); + + // p2. + do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE); + + // p3. + do_check_eq(this.readInt32(), recordSize); + + // data. + let strLen = this.readInt32(); + do_check_eq(recordSize * 2, strLen); + let expectedMwis = buildMwisData(); + for (let i = 0; i < recordSize; i++) { + do_check_eq(expectedMwis[i], pduHelper.readHexOctet()); + } + this.readStringDelimiter(strLen); + + // pin2. + do_check_eq(this.readString(), null); + + if (!ril.v5Legacy) { + // AID. Ignore because it's from modem. + this.readInt32(); + } + }; + + do_check_false(isUpdated); + + recordHelper.updateMWIS({ active: isActive, + msgCount: count }); + + do_check_true((ril.iccInfoPrivate.mwis) ? isUpdated : !isUpdated); + } + + do_test(true, GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN); + do_test(true, 1); + do_test(true, 255); + + do_test(false, 0); + + // Test if Path ID is correct for SIM. + ril.appType = CARD_APPTYPE_SIM; + do_test(false, 0); + + // Test if loadLinearFixedEF() is not invoked in updateMWIS() when + // EF_MWIS is not loaded/available. + delete ril.iccInfoPrivate.mwis; + do_test(false, 0); + + run_next_test(); +}); + +/** + * Verify the call flow of receiving Class 2 SMS stored in SIM: + * 1. UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM. + * 2. SimRecordHelper.readSMS(). + * 3. sendChromeMessage() with rilMessageType == "sms-received". + */ +add_test(function test_read_new_sms_on_sim() { + // Instead of reusing newUint8Worker defined in this file, + // we define our own worker to fake the methods in WorkerBuffer dynamically. + function newSmsOnSimWorkerHelper() { + let _postedMessage; + let _worker = newWorker({ + postRILMessage: function(data) { + }, + postMessage: function(message) { + _postedMessage = message; + } + }); + + _worker.debug = do_print; + + return { + get postedMessage() { + return _postedMessage; + }, + get worker() { + return _worker; + }, + fakeWokerBuffer: function() { + let context = _worker.ContextPool._contexts[0]; + let index = 0; // index for read + let buf = []; + context.Buf.writeUint8 = function(value) { + buf.push(value); + }; + context.Buf.readUint8 = function() { + return buf[index++]; + }; + context.Buf.seekIncoming = function(offset) { + index += offset; + }; + context.Buf.getReadAvailable = function() { + return buf.length - index; + }; + } + }; + } + + let workerHelper = newSmsOnSimWorkerHelper(); + let worker = workerHelper.worker; + let context = worker.ContextPool._contexts[0]; + + context.ICCIOHelper.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { + // SimStatus: Unread, SMSC:+0123456789, Sender: +9876543210, Text: How are you? + let SimSmsPduHex = "0306911032547698040A9189674523010000208062917314080CC8F71D14969741F977FD07" + // In 4.2.25 EF_SMS Short Messages of 3GPP TS 31.102: + // 1. Record length == 176 bytes. + // 2. Any bytes in the record following the TPDU shall be filled with 'FF'. + + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"; + + workerHelper.fakeWokerBuffer(); + + context.Buf.writeString(SimSmsPduHex); + + options.recordSize = 176; // Record length is fixed to 176 bytes. + if (options.callback) { + options.callback(options); + } + }; + + function newSmsOnSimParcel() { + let data = new Uint8Array(4 + 4); // Int32List with 1 element. + let offset = 0; + + function writeInt(value) { + data[offset++] = value & 0xFF; + data[offset++] = (value >> 8) & 0xFF; + data[offset++] = (value >> 16) & 0xFF; + data[offset++] = (value >> 24) & 0xFF; + } + + writeInt(1); // Length of Int32List + writeInt(1); // RecordNum = 1. + + return newIncomingParcel(-1, + RESPONSE_TYPE_UNSOLICITED, + UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM, + data); + } + + function do_test() { + worker.onRILMessage(0, newSmsOnSimParcel()); + + let postedMessage = workerHelper.postedMessage; + + do_check_eq("sms-received", postedMessage.rilMessageType); + do_check_eq("+0123456789", postedMessage.SMSC); + do_check_eq("+9876543210", postedMessage.sender); + do_check_eq("How are you?", postedMessage.body); + } + + do_test(); + + run_next_test(); +}); + +
--- a/dom/system/gonk/tests/test_ril_worker_mmi.js +++ b/dom/system/gonk/tests/test_ril_worker_mmi.js @@ -2,357 +2,32 @@ http://creativecommons.org/publicdomain/zero/1.0/ */ subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); function run_test() { run_next_test(); } -function parseMMI(mmi) { - let worker = newWorker({ - postRILMessage: function(data) { - // Do nothing - }, - postMessage: function(message) { - // Do nothing - } - }); - let context = worker.ContextPool._contexts[0]; - return context.RIL._parseMMI(mmi); -} - -function getWorker() { - let _postedMessage; - let _worker = newWorker({ - postRILMessage: function(data) { - }, - postMessage: function(message) { - _postedMessage = message; - }, - }); - - return { - get postedMessage() { - return _postedMessage; - }, - get worker() { - return _worker; - } - }; -} - function testSendMMI(mmi, error) { - let workerhelper = getWorker(); + let workerhelper = newInterceptWorker(); let worker = workerhelper.worker; let context = worker.ContextPool._contexts[0]; do_print("worker.postMessage " + worker.postMessage); context.RIL.radioState = GECKO_RADIOSTATE_READY; context.RIL.sendMMI({rilMessageType: "sendMMI", mmi: mmi}); let postedMessage = workerhelper.postedMessage; do_check_eq(postedMessage.rilMessageType, "sendMMI"); do_check_eq(postedMessage.errorMsg, error); } -add_test(function test_parseMMI_empty() { - let mmi = parseMMI(""); - - do_check_null(mmi); - - run_next_test(); -}); - -add_test(function test_parseMMI_undefined() { - let mmi = parseMMI(); - - do_check_null(mmi); - - run_next_test(); -}); - -add_test(function test_parseMMI_one_digit_short_code() { - let mmi = parseMMI("1"); - - do_check_eq(mmi.fullMMI, "1"); - do_check_eq(mmi.procedure, undefined); - do_check_eq(mmi.serviceCode, undefined); - do_check_eq(mmi.sia, undefined); - do_check_eq(mmi.sib, undefined); - do_check_eq(mmi.sic, undefined); - do_check_eq(mmi.pwd, undefined); - do_check_eq(mmi.dialNumber, undefined); - - run_next_test(); -}); - -add_test(function test_parseMMI_invalid_short_code() { - let mmi = parseMMI("11"); - - do_check_null(mmi); - - run_next_test(); -}); - -add_test(function test_parseMMI_short_code() { - let mmi = parseMMI("21"); - - do_check_eq(mmi.fullMMI, "21"); - do_check_eq(mmi.procedure, undefined); - do_check_eq(mmi.serviceCode, undefined); - do_check_eq(mmi.sia, undefined); - do_check_eq(mmi.sib, undefined); - do_check_eq(mmi.sic, undefined); - do_check_eq(mmi.pwd, undefined); - do_check_eq(mmi.dialNumber, undefined); - - run_next_test(); -}); - -add_test(function test_parseMMI_dial_string() { - let mmi = parseMMI("12345"); - - do_check_null(mmi); - - run_next_test(); -}); - -add_test(function test_parseMMI_USSD_without_asterisk_prefix() { - let mmi = parseMMI("123#"); - - do_check_eq(mmi.fullMMI, "123#"); - do_check_eq(mmi.procedure, undefined); - do_check_eq(mmi.serviceCode, undefined); - do_check_eq(mmi.sia, undefined); - do_check_eq(mmi.sib, undefined); - do_check_eq(mmi.sic, undefined); - do_check_eq(mmi.pwd, undefined); - do_check_eq(mmi.dialNumber, undefined); - - run_next_test(); -}); - -add_test(function test_parseMMI_USSD() { - let mmi = parseMMI("*123#"); - - do_check_eq(mmi.fullMMI, "*123#"); - do_check_eq(mmi.procedure, MMI_PROCEDURE_ACTIVATION); - do_check_eq(mmi.serviceCode, "123"); - do_check_eq(mmi.sia, undefined); - do_check_eq(mmi.sib, undefined); - do_check_eq(mmi.sic, undefined); - do_check_eq(mmi.pwd, undefined); - do_check_eq(mmi.dialNumber, ""); - - run_next_test(); -}); - -add_test(function test_parseMMI_sia() { - let mmi = parseMMI("*123*1#"); - - do_check_eq(mmi.fullMMI, "*123*1#"); - do_check_eq(mmi.procedure, MMI_PROCEDURE_ACTIVATION); - do_check_eq(mmi.serviceCode, "123"); - do_check_eq(mmi.sia, "1"); - do_check_eq(mmi.sib, undefined); - do_check_eq(mmi.sic, undefined); - do_check_eq(mmi.pwd, undefined); - do_check_eq(mmi.dialNumber, ""); - - run_next_test(); -}); - -add_test(function test_parseMMI_sib() { - let mmi = parseMMI("*123**1#"); - - do_check_eq(mmi.fullMMI, "*123**1#"); - do_check_eq(mmi.procedure, MMI_PROCEDURE_ACTIVATION); - do_check_eq(mmi.serviceCode, "123"); - do_check_eq(mmi.sia, ""); - do_check_eq(mmi.sib, "1"); - do_check_eq(mmi.sic, undefined); - do_check_eq(mmi.pwd, undefined); - do_check_eq(mmi.dialNumber, ""); - - run_next_test(); -}); - -add_test(function test_parseMMI_sic() { - let mmi = parseMMI("*123***1#"); - - do_check_eq(mmi.fullMMI, "*123***1#"); - do_check_eq(mmi.procedure, MMI_PROCEDURE_ACTIVATION); - do_check_eq(mmi.serviceCode, "123"); - do_check_eq(mmi.sia, ""); - do_check_eq(mmi.sib, ""); - do_check_eq(mmi.sic, "1"); - do_check_eq(mmi.pwd, undefined); - do_check_eq(mmi.dialNumber, ""); - - run_next_test(); -}); - -add_test(function test_parseMMI_sia_sib() { - let mmi = parseMMI("*123*1*1#"); - - do_check_eq(mmi.fullMMI, "*123*1*1#"); - do_check_eq(mmi.procedure, MMI_PROCEDURE_ACTIVATION); - do_check_eq(mmi.serviceCode, "123"); - do_check_eq(mmi.sia, "1"); - do_check_eq(mmi.sib, "1"); - do_check_eq(mmi.sic, undefined); - do_check_eq(mmi.pwd, undefined); - do_check_eq(mmi.dialNumber, ""); - - run_next_test(); -}); - -add_test(function test_parseMMI_sia_sic() { - let mmi = parseMMI("*123*1**1#"); - - do_check_eq(mmi.fullMMI, "*123*1**1#"); - do_check_eq(mmi.procedure, MMI_PROCEDURE_ACTIVATION); - do_check_eq(mmi.serviceCode, "123"); - do_check_eq(mmi.sia, "1"); - do_check_eq(mmi.sib, ""); - do_check_eq(mmi.sic, "1"); - do_check_eq(mmi.pwd, undefined); - do_check_eq(mmi.dialNumber, ""); - - run_next_test(); -}); - -add_test(function test_parseMMI_sib_sic() { - let mmi = parseMMI("*123**1*1#"); - - do_check_eq(mmi.fullMMI, "*123**1*1#"); - do_check_eq(mmi.procedure, MMI_PROCEDURE_ACTIVATION); - do_check_eq(mmi.serviceCode, "123"); - do_check_eq(mmi.sia, ""); - do_check_eq(mmi.sib, "1"); - do_check_eq(mmi.sic, "1"); - do_check_eq(mmi.pwd, undefined); - do_check_eq(mmi.dialNumber, ""); - - run_next_test(); -}); - -add_test(function test_parseMMI_pwd() { - let mmi = parseMMI("*123****1#"); - - do_check_eq(mmi.fullMMI, "*123****1#"); - do_check_eq(mmi.procedure, MMI_PROCEDURE_ACTIVATION); - do_check_eq(mmi.serviceCode, "123"); - do_check_eq(mmi.sia, ""); - do_check_eq(mmi.sib, ""); - do_check_eq(mmi.sic, ""); - do_check_eq(mmi.pwd, "1"); - do_check_eq(mmi.dialNumber, ""); - - run_next_test(); -}); - -add_test(function test_parseMMI_dial_number() { - let mmi = parseMMI("*123#345"); - - do_check_eq(mmi.fullMMI, "*123#"); - do_check_eq(mmi.procedure, MMI_PROCEDURE_ACTIVATION); - do_check_eq(mmi.serviceCode, "123"); - do_check_eq(mmi.sia, undefined); - do_check_eq(mmi.sib, undefined); - do_check_eq(mmi.sic, undefined); - do_check_eq(mmi.pwd, undefined); - do_check_eq(mmi.dialNumber, "345"); - - run_next_test(); -}); - - -/** - * MMI procedures tests - */ - -add_test(function test_parseMMI_activation() { - let mmi = parseMMI("*00*12*34*56#"); - - do_check_eq(mmi.fullMMI, "*00*12*34*56#"); - do_check_eq(mmi.procedure, MMI_PROCEDURE_ACTIVATION); - do_check_eq(mmi.serviceCode, "00"); - do_check_eq(mmi.sia, "12"); - do_check_eq(mmi.sib, "34"); - do_check_eq(mmi.sic, "56"); - do_check_eq(mmi.pwd, undefined); - do_check_eq(mmi.dialNumber, ""); - - run_next_test(); -}); - -add_test(function test_parseMMI_deactivation() { - let mmi = parseMMI("#00*12*34*56#"); - - do_check_eq(mmi.fullMMI, "#00*12*34*56#"); - do_check_eq(mmi.procedure, MMI_PROCEDURE_DEACTIVATION); - do_check_eq(mmi.serviceCode, "00"); - do_check_eq(mmi.sia, "12"); - do_check_eq(mmi.sib, "34"); - do_check_eq(mmi.sic, "56"); - do_check_eq(mmi.pwd, undefined); - do_check_eq(mmi.dialNumber, ""); - - run_next_test(); -}); - -add_test(function test_parseMMI_interrogation() { - let mmi = parseMMI("*#00*12*34*56#"); - - do_check_eq(mmi.fullMMI, "*#00*12*34*56#"); - do_check_eq(mmi.procedure, MMI_PROCEDURE_INTERROGATION); - do_check_eq(mmi.serviceCode, "00"); - do_check_eq(mmi.sia, "12"); - do_check_eq(mmi.sib, "34"); - do_check_eq(mmi.sic, "56"); - do_check_eq(mmi.pwd, undefined); - do_check_eq(mmi.dialNumber, ""); - - run_next_test(); -}); - -add_test(function test_parseMMI_registration() { - let mmi = parseMMI("**00*12*34*56#"); - - do_check_eq(mmi.fullMMI, "**00*12*34*56#"); - do_check_eq(mmi.procedure, MMI_PROCEDURE_REGISTRATION); - do_check_eq(mmi.serviceCode, "00"); - do_check_eq(mmi.sia, "12"); - do_check_eq(mmi.sib, "34"); - do_check_eq(mmi.sic, "56"); - do_check_eq(mmi.pwd, undefined); - do_check_eq(mmi.dialNumber, ""); - - run_next_test(); -}); - -add_test(function test_parseMMI_erasure() { - let mmi = parseMMI("##00*12*34*56#"); - - do_check_eq(mmi.fullMMI, "##00*12*34*56#"); - do_check_eq(mmi.procedure, MMI_PROCEDURE_ERASURE); - do_check_eq(mmi.serviceCode, "00"); - do_check_eq(mmi.sia, "12"); - do_check_eq(mmi.sib, "34"); - do_check_eq(mmi.sic, "56"); - do_check_eq(mmi.pwd, undefined); - do_check_eq(mmi.dialNumber, ""); - - run_next_test(); -}); - /** * sendMMI tests. */ add_test(function test_sendMMI_empty() { testSendMMI("", MMI_ERROR_KS_ERROR); run_next_test(); @@ -366,17 +41,17 @@ add_test(function test_sendMMI_undefined add_test(function test_sendMMI_invalid() { testSendMMI("11", MMI_ERROR_KS_ERROR); run_next_test(); }); add_test(function test_sendMMI_short_code() { - let workerhelper = getWorker(); + let workerhelper = newInterceptWorker(); let worker = workerhelper.worker; let context = worker.ContextPool._contexts[0]; let ussdOptions; context.RIL.sendUSSD = function fakeSendUSSD(options){ ussdOptions = options; context.RIL[REQUEST_SEND_USSD](0, { @@ -398,161 +73,18 @@ add_test(function test_sendMMI_short_cod }); add_test(function test_sendMMI_dial_string() { testSendMMI("123", MMI_ERROR_KS_ERROR); run_next_test(); }); -function setCallForwardSuccess(mmi) { - let workerhelper = getWorker(); - let worker = workerhelper.worker; - let context = worker.ContextPool._contexts[0]; - - context.RIL.setCallForward = function fakeSetCallForward(options) { - context.RIL[REQUEST_SET_CALL_FORWARD](0, { - rilRequestError: ERROR_SUCCESS - }); - }; - - context.RIL.radioState = GECKO_RADIOSTATE_READY; - context.RIL.sendMMI({mmi: mmi}); - - let postedMessage = workerhelper.postedMessage; - - do_check_eq(postedMessage.errorMsg, GECKO_ERROR_SUCCESS); - do_check_true(postedMessage.success); -} - -add_test(function test_sendMMI_call_forwarding_activation() { - setCallForwardSuccess("*21*12345*99*10#"); - - run_next_test(); -}); - -add_test(function test_sendMMI_call_forwarding_deactivation() { - setCallForwardSuccess("#21*12345*99*10#"); - - run_next_test(); -}); - -add_test(function test_sendMMI_call_forwarding_interrogation() { - let workerhelper = getWorker(); - let worker = workerhelper.worker; - let context = worker.ContextPool._contexts[0]; - - context.Buf.readInt32 = function fakeReadUint32() { - return context.Buf.int32Array.pop(); - }; - - context.Buf.readString = function fakeReadString() { - return "+34666222333"; - }; - - context.RIL.queryCallForwardStatus = function fakeQueryCallForward(options) { - context.Buf.int32Array = [ - 0, // rules.timeSeconds - 145, // rules.toa - 49, // rules.serviceClass - CALL_FORWARD_REASON_UNCONDITIONAL, // rules.reason - 1, // rules.active - 1 // rulesLength - ]; - context.RIL[REQUEST_QUERY_CALL_FORWARD_STATUS](1, { - rilRequestError: ERROR_SUCCESS - }); - }; - - context.RIL.radioState = GECKO_RADIOSTATE_READY; - context.RIL.sendMMI({mmi: "*#21#"}); - - let postedMessage = workerhelper.postedMessage; - - do_check_eq(postedMessage.errorMsg, GECKO_ERROR_SUCCESS); - do_check_true(postedMessage.success); - do_check_true(Array.isArray(postedMessage.rules)); - do_check_eq(postedMessage.rules.length, 1); - do_check_true(postedMessage.rules[0].active); - do_check_eq(postedMessage.rules[0].reason, CALL_FORWARD_REASON_UNCONDITIONAL); - do_check_eq(postedMessage.rules[0].number, "+34666222333"); - run_next_test(); -}); - -add_test(function test_sendMMI_call_forwarding_interrogation_no_rules() { - let workerhelper = getWorker(); - let worker = workerhelper.worker; - let context = worker.ContextPool._contexts[0]; - - context.Buf.readInt32 = function fakeReadUint32() { - return 0; - }; - - context.RIL.queryCallForwardStatus = function fakeQueryCallForward(options) { - context.RIL[REQUEST_QUERY_CALL_FORWARD_STATUS](1, { - rilRequestError: ERROR_SUCCESS - }); - }; - - context.RIL.radioState = GECKO_RADIOSTATE_READY; - context.RIL.sendMMI({mmi: "*#21#"}); - - let postedMessage = workerhelper.postedMessage; - - do_check_eq(postedMessage.errorMsg, GECKO_ERROR_GENERIC_FAILURE); - do_check_false(postedMessage.success); - - run_next_test(); -}); - - -add_test(function test_sendMMI_call_forwarding_registration() { - setCallForwardSuccess("**21*12345*99*10#"); - - run_next_test(); -}); - -add_test(function test_sendMMI_call_forwarding_erasure() { - setCallForwardSuccess("##21*12345*99#"); - - run_next_test(); -}); - -add_test(function test_sendMMI_call_forwarding_CFB() { - setCallForwardSuccess("*67*12345*99*10#"); - - run_next_test(); -}); - -add_test(function test_sendMMI_call_forwarding_CFNRy() { - setCallForwardSuccess("*61*12345*99*10#"); - - run_next_test(); -}); - -add_test(function test_sendMMI_call_forwarding_CFNRc() { - setCallForwardSuccess("*62*12345*99*10#"); - - run_next_test(); -}); - -add_test(function test_sendMMI_call_forwarding_CFAll() { - setCallForwardSuccess("*004*12345*99*10#"); - - run_next_test(); -}); - -add_test(function test_sendMMI_call_forwarding_CFAllConditional() { - setCallForwardSuccess("*002*12345*99*10#"); - - run_next_test(); -}); - add_test(function test_sendMMI_change_PIN() { - let workerhelper = getWorker(); + let workerhelper = newInterceptWorker(); let worker = workerhelper.worker; let context = worker.ContextPool._contexts[0]; context.RIL.changeICCPIN = function fakeChangeICCPIN(options) { context.RIL[REQUEST_ENTER_SIM_PIN](0, { rilRequestError: ERROR_SUCCESS }); }; @@ -588,17 +120,17 @@ add_test(function test_sendMMI_change_PI add_test(function test_sendMMI_change_PIN_new_PIN_mismatch() { testSendMMI("**04*4567*1234*4567#", MMI_ERROR_KS_MISMATCH_PIN); run_next_test(); }); add_test(function test_sendMMI_change_PIN2() { - let workerhelper = getWorker(); + let workerhelper = newInterceptWorker(); let worker = workerhelper.worker; let context = worker.ContextPool._contexts[0]; context.RIL.changeICCPIN2 = function fakeChangeICCPIN2(options){ context.RIL[REQUEST_ENTER_SIM_PIN2](0, { rilRequestError: ERROR_SUCCESS }); }; @@ -634,17 +166,17 @@ add_test(function test_sendMMI_change_PI add_test(function test_sendMMI_change_PIN2_new_PIN2_mismatch() { testSendMMI("**042*4567*1234*4567#", MMI_ERROR_KS_MISMATCH_PIN); run_next_test(); }); add_test(function test_sendMMI_unblock_PIN() { - let workerhelper = getWorker(); + let workerhelper = newInterceptWorker(); let worker = workerhelper.worker; let context = worker.ContextPool._contexts[0]; context.RIL.enterICCPUK = function fakeEnterICCPUK(options){ context.RIL[REQUEST_ENTER_SIM_PUK](0, { rilRequestError: ERROR_SUCCESS }); }; @@ -680,17 +212,17 @@ add_test(function test_sendMMI_unblock_P add_test(function test_sendMMI_unblock_PIN_new_PIN_mismatch() { testSendMMI("**05*4567*1234*4567#", MMI_ERROR_KS_MISMATCH_PIN); run_next_test(); }); add_test(function test_sendMMI_unblock_PIN2() { - let workerhelper = getWorker(); + let workerhelper = newInterceptWorker(); let worker = workerhelper.worker; let context = worker.ContextPool._contexts[0]; context.RIL.enterICCPUK2 = function fakeEnterICCPUK2(options){ context.RIL[REQUEST_ENTER_SIM_PUK2](0, { rilRequestError: ERROR_SUCCESS }); }; @@ -726,17 +258,17 @@ add_test(function test_sendMMI_unblock_P add_test(function test_sendMMI_unblock_PIN2_new_PIN_mismatch() { testSendMMI("**052*4567*1234*4567#", MMI_ERROR_KS_MISMATCH_PIN); run_next_test(); }); add_test(function test_sendMMI_get_IMEI() { - let workerhelper = getWorker(); + let workerhelper = newInterceptWorker(); let worker = workerhelper.worker; let context = worker.ContextPool._contexts[0]; let mmiOptions; context.RIL.getIMEI = function getIMEI(options){ mmiOptions = options; context.RIL[REQUEST_SEND_USSD](0, { rilRequestError: ERROR_SUCCESS, @@ -750,17 +282,17 @@ add_test(function test_sendMMI_get_IMEI( do_check_neq(mmiOptions.mmi, null); do_check_eq (postedMessage.errorMsg, GECKO_ERROR_SUCCESS); do_check_true(postedMessage.success); run_next_test(); }); add_test(function test_sendMMI_get_IMEI_error() { - let workerhelper = getWorker(); + let workerhelper = newInterceptWorker(); let worker = workerhelper.worker; let context = worker.ContextPool._contexts[0]; let mmiOptions; context.RIL.getIMEI = function getIMEI(options){ mmiOptions = options; context.RIL[REQUEST_SEND_USSD](0, { rilRequestError: ERROR_RADIO_NOT_AVAILABLE, @@ -774,17 +306,17 @@ add_test(function test_sendMMI_get_IMEI_ do_check_neq(mmiOptions.mmi, null); do_check_eq (postedMessage.errorMsg, GECKO_ERROR_RADIO_NOT_AVAILABLE); do_check_false(postedMessage.success); run_next_test(); }); add_test(function test_sendMMI_call_barring_BAIC_interrogation_voice() { - let workerhelper = getWorker(); + let workerhelper = newInterceptWorker(); let worker = workerhelper.worker; let context = worker.ContextPool._contexts[0]; context.Buf.readInt32List = function fakeReadUint32List() { return [1]; }; context.RIL.queryICCFacilityLock = @@ -805,17 +337,17 @@ add_test(function test_sendMMI_call_barr do_check_eq(postedMessage.statusMessage, MMI_SM_KS_SERVICE_ENABLED_FOR); do_check_true(Array.isArray(postedMessage.additionalInformation)); do_check_eq(postedMessage.additionalInformation[0], "serviceClassVoice"); run_next_test(); }); add_test(function test_sendMMI_call_barring_BAIC_activation() { - let workerhelper = getWorker(); + let workerhelper = newInterceptWorker(); let worker = workerhelper.worker; let context = worker.ContextPool._contexts[0]; let mmiOptions; context.RIL.setICCFacilityLock = function fakeSetICCFacilityLock(options){ mmiOptions = options; context.RIL[REQUEST_SET_FACILITY_LOCK](0, { @@ -833,17 +365,17 @@ add_test(function test_sendMMI_call_barr do_check_eq(mmiOptions.procedure, MMI_PROCEDURE_ACTIVATION); do_check_true(postedMessage.success); do_check_eq(postedMessage.statusMessage, MMI_SM_KS_SERVICE_ENABLED); run_next_test(); }); add_test(function test_sendMMI_call_barring_BAIC_deactivation() { - let workerhelper = getWorker(); + let workerhelper = newInterceptWorker(); let worker = workerhelper.worker; let context = worker.ContextPool._contexts[0]; let mmiOptions; context.RIL.setICCFacilityLock = function fakeSetICCFacilityLock(options){ mmiOptions = options; context.RIL[REQUEST_SET_FACILITY_LOCK](0, { @@ -867,17 +399,17 @@ add_test(function test_sendMMI_call_barr add_test(function test_sendMMI_call_barring_BAIC_procedure_not_supported() { testSendMMI("**33*0000#", MMI_ERROR_KS_NOT_SUPPORTED); run_next_test(); }); add_test(function test_sendMMI_USSD() { - let workerhelper = getWorker(); + let workerhelper = newInterceptWorker(); let worker = workerhelper.worker; let context = worker.ContextPool._contexts[0]; let ussdOptions; context.RIL.sendUSSD = function fakeSendUSSD(options){ ussdOptions = options; context.RIL[REQUEST_SEND_USSD](0, { rilRequestError: ERROR_SUCCESS @@ -893,17 +425,17 @@ add_test(function test_sendMMI_USSD() { do_check_eq (postedMessage.errorMsg, GECKO_ERROR_SUCCESS); do_check_true(postedMessage.success); do_check_true(context.RIL._ussdSession); run_next_test(); }); add_test(function test_sendMMI_USSD_error() { - let workerhelper = getWorker(); + let workerhelper = newInterceptWorker(); let worker = workerhelper.worker; let context = worker.ContextPool._contexts[0]; let ussdOptions; context.RIL.sendUSSD = function fakeSendUSSD(options){ ussdOptions = options; context.RIL[REQUEST_SEND_USSD](0, { rilRequestError: ERROR_GENERIC_FAILURE @@ -919,17 +451,17 @@ add_test(function test_sendMMI_USSD_erro do_check_eq (postedMessage.errorMsg, GECKO_ERROR_GENERIC_FAILURE); do_check_false(postedMessage.success); do_check_false(context.RIL._ussdSession); run_next_test(); }); function setCallWaitingSuccess(mmi) { - let workerhelper = getWorker(); + let workerhelper = newInterceptWorker(); let worker = workerhelper.worker; let context = worker.ContextPool._contexts[0]; context.RIL.setCallWaiting = function fakeSetCallWaiting(options) { context.RIL[REQUEST_SET_CALL_WAITING](0, { rilRequestError: ERROR_SUCCESS }); }; @@ -963,17 +495,17 @@ add_test(function test_sendMMI_call_wait add_test(function test_sendMMI_call_waiting_erasure() { testSendMMI("##43#", MMI_ERROR_KS_NOT_SUPPORTED); run_next_test(); }); add_test(function test_sendMMI_call_waiting_interrogation() { - let workerhelper = getWorker(); + let workerhelper = newInterceptWorker(); let worker = workerhelper.worker; let context = worker.ContextPool._contexts[0]; context.Buf.readInt32 = function fakeReadUint32() { return context.Buf.int32Array.pop(); }; context.RIL.queryCallWaiting = function fakeQueryCallWaiting(options) {
new file mode 100644 --- /dev/null +++ b/dom/system/gonk/tests/test_ril_worker_mmi_cf.js @@ -0,0 +1,151 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); + +function run_test() { + run_next_test(); +} + +function setCallForwardSuccess(mmi) { + let workerhelper = newInterceptWorker(); + let worker = workerhelper.worker; + let context = worker.ContextPool._contexts[0]; + + context.RIL.setCallForward = function fakeSetCallForward(options) { + context.RIL[REQUEST_SET_CALL_FORWARD](0, { + rilRequestError: ERROR_SUCCESS + }); + }; + + context.RIL.radioState = GECKO_RADIOSTATE_READY; + context.RIL.sendMMI({mmi: mmi}); + + let postedMessage = workerhelper.postedMessage; + + do_check_eq(postedMessage.errorMsg, GECKO_ERROR_SUCCESS); + do_check_true(postedMessage.success); +} + +add_test(function test_sendMMI_call_forwarding_activation() { + setCallForwardSuccess("*21*12345*99*10#"); + + run_next_test(); +}); + +add_test(function test_sendMMI_call_forwarding_deactivation() { + setCallForwardSuccess("#21*12345*99*10#"); + + run_next_test(); +}); + +add_test(function test_sendMMI_call_forwarding_interrogation() { + let workerhelper = newInterceptWorker(); + let worker = workerhelper.worker; + let context = worker.ContextPool._contexts[0]; + + context.Buf.readInt32 = function fakeReadUint32() { + return context.Buf.int32Array.pop(); + }; + + context.Buf.readString = function fakeReadString() { + return "+34666222333"; + }; + + context.RIL.queryCallForwardStatus = function fakeQueryCallForward(options) { + context.Buf.int32Array = [ + 0, // rules.timeSeconds + 145, // rules.toa + 49, // rules.serviceClass + CALL_FORWARD_REASON_UNCONDITIONAL, // rules.reason + 1, // rules.active + 1 // rulesLength + ]; + context.RIL[REQUEST_QUERY_CALL_FORWARD_STATUS](1, { + rilRequestError: ERROR_SUCCESS + }); + }; + + context.RIL.radioState = GECKO_RADIOSTATE_READY; + context.RIL.sendMMI({mmi: "*#21#"}); + + let postedMessage = workerhelper.postedMessage; + + do_check_eq(postedMessage.errorMsg, GECKO_ERROR_SUCCESS); + do_check_true(postedMessage.success); + do_check_true(Array.isArray(postedMessage.rules)); + do_check_eq(postedMessage.rules.length, 1); + do_check_true(postedMessage.rules[0].active); + do_check_eq(postedMessage.rules[0].reason, CALL_FORWARD_REASON_UNCONDITIONAL); + do_check_eq(postedMessage.rules[0].number, "+34666222333"); + run_next_test(); +}); + +add_test(function test_sendMMI_call_forwarding_interrogation_no_rules() { + let workerhelper = newInterceptWorker(); + let worker = workerhelper.worker; + let context = worker.ContextPool._contexts[0]; + + context.Buf.readInt32 = function fakeReadUint32() { + return 0; + }; + + context.RIL.queryCallForwardStatus = function fakeQueryCallForward(options) { + context.RIL[REQUEST_QUERY_CALL_FORWARD_STATUS](1, { + rilRequestError: ERROR_SUCCESS + }); + }; + + context.RIL.radioState = GECKO_RADIOSTATE_READY; + context.RIL.sendMMI({mmi: "*#21#"}); + + let postedMessage = workerhelper.postedMessage; + + do_check_eq(postedMessage.errorMsg, GECKO_ERROR_GENERIC_FAILURE); + do_check_false(postedMessage.success); + + run_next_test(); +}); + + +add_test(function test_sendMMI_call_forwarding_registration() { + setCallForwardSuccess("**21*12345*99*10#"); + + run_next_test(); +}); + +add_test(function test_sendMMI_call_forwarding_erasure() { + setCallForwardSuccess("##21*12345*99#"); + + run_next_test(); +}); + +add_test(function test_sendMMI_call_forwarding_CFB() { + setCallForwardSuccess("*67*12345*99*10#"); + + run_next_test(); +}); + +add_test(function test_sendMMI_call_forwarding_CFNRy() { + setCallForwardSuccess("*61*12345*99*10#"); + + run_next_test(); +}); + +add_test(function test_sendMMI_call_forwarding_CFNRc() { + setCallForwardSuccess("*62*12345*99*10#"); + + run_next_test(); +}); + +add_test(function test_sendMMI_call_forwarding_CFAll() { + setCallForwardSuccess("*004*12345*99*10#"); + + run_next_test(); +}); + +add_test(function test_sendMMI_call_forwarding_CFAllConditional() { + setCallForwardSuccess("*002*12345*99*10#"); + + run_next_test(); +});
new file mode 100644 --- /dev/null +++ b/dom/system/gonk/tests/test_ril_worker_mmi_parseMMI.js @@ -0,0 +1,317 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); + +function run_test() { + run_next_test(); +} + +let worker; +function parseMMI(mmi) { + if (!worker) { + worker = newWorker({ + postRILMessage: function(data) { + // Do nothing + }, + postMessage: function(message) { + // Do nothing + } + }); + } + + let context = worker.ContextPool._contexts[0]; + return context.RIL._parseMMI(mmi); +} + +add_test(function test_parseMMI_empty() { + let mmi = parseMMI(""); + + do_check_null(mmi); + + run_next_test(); +}); + +add_test(function test_parseMMI_undefined() { + let mmi = parseMMI(); + + do_check_null(mmi); + + run_next_test(); +}); + +add_test(function test_parseMMI_one_digit_short_code() { + let mmi = parseMMI("1"); + + do_check_eq(mmi.fullMMI, "1"); + do_check_eq(mmi.procedure, undefined); + do_check_eq(mmi.serviceCode, undefined); + do_check_eq(mmi.sia, undefined); + do_check_eq(mmi.sib, undefined); + do_check_eq(mmi.sic, undefined); + do_check_eq(mmi.pwd, undefined); + do_check_eq(mmi.dialNumber, undefined); + + run_next_test(); +}); + +add_test(function test_parseMMI_invalid_short_code() { + let mmi = parseMMI("11"); + + do_check_null(mmi); + + run_next_test(); +}); + +add_test(function test_parseMMI_short_code() { + let mmi = parseMMI("21"); + + do_check_eq(mmi.fullMMI, "21"); + do_check_eq(mmi.procedure, undefined); + do_check_eq(mmi.serviceCode, undefined); + do_check_eq(mmi.sia, undefined); + do_check_eq(mmi.sib, undefined); + do_check_eq(mmi.sic, undefined); + do_check_eq(mmi.pwd, undefined); + do_check_eq(mmi.dialNumber, undefined); + + run_next_test(); +}); + +add_test(function test_parseMMI_dial_string() { + let mmi = parseMMI("12345"); + + do_check_null(mmi); + + run_next_test(); +}); + +add_test(function test_parseMMI_USSD_without_asterisk_prefix() { + let mmi = parseMMI("123#"); + + do_check_eq(mmi.fullMMI, "123#"); + do_check_eq(mmi.procedure, undefined); + do_check_eq(mmi.serviceCode, undefined); + do_check_eq(mmi.sia, undefined); + do_check_eq(mmi.sib, undefined); + do_check_eq(mmi.sic, undefined); + do_check_eq(mmi.pwd, undefined); + do_check_eq(mmi.dialNumber, undefined); + + run_next_test(); +}); + +add_test(function test_parseMMI_USSD() { + let mmi = parseMMI("*123#"); + + do_check_eq(mmi.fullMMI, "*123#"); + do_check_eq(mmi.procedure, MMI_PROCEDURE_ACTIVATION); + do_check_eq(mmi.serviceCode, "123"); + do_check_eq(mmi.sia, undefined); + do_check_eq(mmi.sib, undefined); + do_check_eq(mmi.sic, undefined); + do_check_eq(mmi.pwd, undefined); + do_check_eq(mmi.dialNumber, ""); + + run_next_test(); +}); + +add_test(function test_parseMMI_sia() { + let mmi = parseMMI("*123*1#"); + + do_check_eq(mmi.fullMMI, "*123*1#"); + do_check_eq(mmi.procedure, MMI_PROCEDURE_ACTIVATION); + do_check_eq(mmi.serviceCode, "123"); + do_check_eq(mmi.sia, "1"); + do_check_eq(mmi.sib, undefined); + do_check_eq(mmi.sic, undefined); + do_check_eq(mmi.pwd, undefined); + do_check_eq(mmi.dialNumber, ""); + + run_next_test(); +}); + +add_test(function test_parseMMI_sib() { + let mmi = parseMMI("*123**1#"); + + do_check_eq(mmi.fullMMI, "*123**1#"); + do_check_eq(mmi.procedure, MMI_PROCEDURE_ACTIVATION); + do_check_eq(mmi.serviceCode, "123"); + do_check_eq(mmi.sia, ""); + do_check_eq(mmi.sib, "1"); + do_check_eq(mmi.sic, undefined); + do_check_eq(mmi.pwd, undefined); + do_check_eq(mmi.dialNumber, ""); + + run_next_test(); +}); + +add_test(function test_parseMMI_sic() { + let mmi = parseMMI("*123***1#"); + + do_check_eq(mmi.fullMMI, "*123***1#"); + do_check_eq(mmi.procedure, MMI_PROCEDURE_ACTIVATION); + do_check_eq(mmi.serviceCode, "123"); + do_check_eq(mmi.sia, ""); + do_check_eq(mmi.sib, ""); + do_check_eq(mmi.sic, "1"); + do_check_eq(mmi.pwd, undefined); + do_check_eq(mmi.dialNumber, ""); + + run_next_test(); +}); + +add_test(function test_parseMMI_sia_sib() { + let mmi = parseMMI("*123*1*1#"); + + do_check_eq(mmi.fullMMI, "*123*1*1#"); + do_check_eq(mmi.procedure, MMI_PROCEDURE_ACTIVATION); + do_check_eq(mmi.serviceCode, "123"); + do_check_eq(mmi.sia, "1"); + do_check_eq(mmi.sib, "1"); + do_check_eq(mmi.sic, undefined); + do_check_eq(mmi.pwd, undefined); + do_check_eq(mmi.dialNumber, ""); + + run_next_test(); +}); + +add_test(function test_parseMMI_sia_sic() { + let mmi = parseMMI("*123*1**1#"); + + do_check_eq(mmi.fullMMI, "*123*1**1#"); + do_check_eq(mmi.procedure, MMI_PROCEDURE_ACTIVATION); + do_check_eq(mmi.serviceCode, "123"); + do_check_eq(mmi.sia, "1"); + do_check_eq(mmi.sib, ""); + do_check_eq(mmi.sic, "1"); + do_check_eq(mmi.pwd, undefined); + do_check_eq(mmi.dialNumber, ""); + + run_next_test(); +}); + +add_test(function test_parseMMI_sib_sic() { + let mmi = parseMMI("*123**1*1#"); + + do_check_eq(mmi.fullMMI, "*123**1*1#"); + do_check_eq(mmi.procedure, MMI_PROCEDURE_ACTIVATION); + do_check_eq(mmi.serviceCode, "123"); + do_check_eq(mmi.sia, ""); + do_check_eq(mmi.sib, "1"); + do_check_eq(mmi.sic, "1"); + do_check_eq(mmi.pwd, undefined); + do_check_eq(mmi.dialNumber, ""); + + run_next_test(); +}); + +add_test(function test_parseMMI_pwd() { + let mmi = parseMMI("*123****1#"); + + do_check_eq(mmi.fullMMI, "*123****1#"); + do_check_eq(mmi.procedure, MMI_PROCEDURE_ACTIVATION); + do_check_eq(mmi.serviceCode, "123"); + do_check_eq(mmi.sia, ""); + do_check_eq(mmi.sib, ""); + do_check_eq(mmi.sic, ""); + do_check_eq(mmi.pwd, "1"); + do_check_eq(mmi.dialNumber, ""); + + run_next_test(); +}); + +add_test(function test_parseMMI_dial_number() { + let mmi = parseMMI("*123#345"); + + do_check_eq(mmi.fullMMI, "*123#"); + do_check_eq(mmi.procedure, MMI_PROCEDURE_ACTIVATION); + do_check_eq(mmi.serviceCode, "123"); + do_check_eq(mmi.sia, undefined); + do_check_eq(mmi.sib, undefined); + do_check_eq(mmi.sic, undefined); + do_check_eq(mmi.pwd, undefined); + do_check_eq(mmi.dialNumber, "345"); + + run_next_test(); +}); + + +/** + * MMI procedures tests + */ + +add_test(function test_parseMMI_activation() { + let mmi = parseMMI("*00*12*34*56#"); + + do_check_eq(mmi.fullMMI, "*00*12*34*56#"); + do_check_eq(mmi.procedure, MMI_PROCEDURE_ACTIVATION); + do_check_eq(mmi.serviceCode, "00"); + do_check_eq(mmi.sia, "12"); + do_check_eq(mmi.sib, "34"); + do_check_eq(mmi.sic, "56"); + do_check_eq(mmi.pwd, undefined); + do_check_eq(mmi.dialNumber, ""); + + run_next_test(); +}); + +add_test(function test_parseMMI_deactivation() { + let mmi = parseMMI("#00*12*34*56#"); + + do_check_eq(mmi.fullMMI, "#00*12*34*56#"); + do_check_eq(mmi.procedure, MMI_PROCEDURE_DEACTIVATION); + do_check_eq(mmi.serviceCode, "00"); + do_check_eq(mmi.sia, "12"); + do_check_eq(mmi.sib, "34"); + do_check_eq(mmi.sic, "56"); + do_check_eq(mmi.pwd, undefined); + do_check_eq(mmi.dialNumber, ""); + + run_next_test(); +}); + +add_test(function test_parseMMI_interrogation() { + let mmi = parseMMI("*#00*12*34*56#"); + + do_check_eq(mmi.fullMMI, "*#00*12*34*56#"); + do_check_eq(mmi.procedure, MMI_PROCEDURE_INTERROGATION); + do_check_eq(mmi.serviceCode, "00"); + do_check_eq(mmi.sia, "12"); + do_check_eq(mmi.sib, "34"); + do_check_eq(mmi.sic, "56"); + do_check_eq(mmi.pwd, undefined); + do_check_eq(mmi.dialNumber, ""); + + run_next_test(); +}); + +add_test(function test_parseMMI_registration() { + let mmi = parseMMI("**00*12*34*56#"); + + do_check_eq(m