Merge b2g-inbound to m-c. a=merge

This commit is contained in:
Ryan VanderMeulen 2015-07-17 10:14:32 -04:00
Родитель 4c5dfa9330 9dd7a87303
Коммит 715c04c018
35 изменённых файлов: 2324 добавлений и 1880 удалений

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="77bc0d940bde2a5d2d4dfadfcccc6d8d77456d36"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8c009877aff6b8b2f4a60756e2d09c0182393721"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f2a1305448efefacb2ec7e654d797bb9fbe7202e"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="503fde923fd32bf81b59ca29eee69d67ade37d37"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="77bc0d940bde2a5d2d4dfadfcccc6d8d77456d36"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8c009877aff6b8b2f4a60756e2d09c0182393721"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f2a1305448efefacb2ec7e654d797bb9fbe7202e"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="503fde923fd32bf81b59ca29eee69d67ade37d37"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>

Просмотреть файл

@ -19,7 +19,7 @@
<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="77bc0d940bde2a5d2d4dfadfcccc6d8d77456d36"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8c009877aff6b8b2f4a60756e2d09c0182393721"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="8bc59310552179f9a8bc6cdd0188e2475df52fb7"/>

Просмотреть файл

@ -17,10 +17,10 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="77bc0d940bde2a5d2d4dfadfcccc6d8d77456d36"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8c009877aff6b8b2f4a60756e2d09c0182393721"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f2a1305448efefacb2ec7e654d797bb9fbe7202e"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="503fde923fd32bf81b59ca29eee69d67ade37d37"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="77bc0d940bde2a5d2d4dfadfcccc6d8d77456d36"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8c009877aff6b8b2f4a60756e2d09c0182393721"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f2a1305448efefacb2ec7e654d797bb9fbe7202e"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="503fde923fd32bf81b59ca29eee69d67ade37d37"/>
<!-- 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"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="77bc0d940bde2a5d2d4dfadfcccc6d8d77456d36"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8c009877aff6b8b2f4a60756e2d09c0182393721"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f2a1305448efefacb2ec7e654d797bb9fbe7202e"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="503fde923fd32bf81b59ca29eee69d67ade37d37"/>
<!-- Stock Android things -->
<project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
<project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>

Просмотреть файл

@ -19,7 +19,7 @@
<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="77bc0d940bde2a5d2d4dfadfcccc6d8d77456d36"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8c009877aff6b8b2f4a60756e2d09c0182393721"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="8bc59310552179f9a8bc6cdd0188e2475df52fb7"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="77bc0d940bde2a5d2d4dfadfcccc6d8d77456d36"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8c009877aff6b8b2f4a60756e2d09c0182393721"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f2a1305448efefacb2ec7e654d797bb9fbe7202e"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="503fde923fd32bf81b59ca29eee69d67ade37d37"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>

Просмотреть файл

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "77bc0d940bde2a5d2d4dfadfcccc6d8d77456d36",
"git_revision": "8c009877aff6b8b2f4a60756e2d09c0182393721",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "dfd4a9e8f31e64d427030d3612a48f7dbcada5d3",
"revision": "494ef969c9ddbf15fc8a094c2da7bc46d08b1fc3",
"repo_path": "integration/gaia-central"
}

Просмотреть файл

@ -17,10 +17,10 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="77bc0d940bde2a5d2d4dfadfcccc6d8d77456d36"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8c009877aff6b8b2f4a60756e2d09c0182393721"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f2a1305448efefacb2ec7e654d797bb9fbe7202e"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="503fde923fd32bf81b59ca29eee69d67ade37d37"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="77bc0d940bde2a5d2d4dfadfcccc6d8d77456d36"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8c009877aff6b8b2f4a60756e2d09c0182393721"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f2a1305448efefacb2ec7e654d797bb9fbe7202e"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="503fde923fd32bf81b59ca29eee69d67ade37d37"/>
<!-- Stock Android things -->
<project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
<project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>

Просмотреть файл

@ -119,7 +119,7 @@ SystemWorkerManager::Shutdown()
ShutdownAutoMounter();
#ifdef MOZ_B2G_RIL
RilConsumer::Shutdown();
RilWorker::Shutdown();
#endif
nsCOMPtr<nsIWifi> wifi(do_QueryInterface(mWifiWorker));
@ -201,7 +201,7 @@ SystemWorkerManager::RegisterRilWorker(unsigned int aClientId,
return NS_ERROR_FAILURE;
}
return RilConsumer::Register(aClientId, wctd);
return RilWorker::Register(aClientId, wctd);
#endif // MOZ_B2G_RIL
}

Просмотреть файл

@ -2976,151 +2976,6 @@ CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_ALL_SERVICE] = ICC_CB_FACI
CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_OUTGOING_SERVICE] = ICC_CB_FACILITY_BA_MO;
CALL_BARRING_PROGRAM_TO_FACILITY[CALL_BARRING_PROGRAM_INCOMING_SERVICE] = ICC_CB_FACILITY_BA_MT;
// CLIR constants. Must be in sync with nsIMobileConnectionService interface
this.CLIR_DEFAULT = 0;
this.CLIR_INVOCATION = 1;
this.CLIR_SUPPRESSION = 2;
// MMI procedure as defined in TS.22.030 6.5.2
this.MMI_PROCEDURE_ACTIVATION = "*";
this.MMI_PROCEDURE_DEACTIVATION = "#";
this.MMI_PROCEDURE_INTERROGATION = "*#";
this.MMI_PROCEDURE_REGISTRATION = "**";
this.MMI_PROCEDURE_ERASURE = "##";
this.MMI_PROC_TO_CF_ACTION = {};
MMI_PROC_TO_CF_ACTION[MMI_PROCEDURE_ACTIVATION] = CALL_FORWARD_ACTION_ENABLE;
MMI_PROC_TO_CF_ACTION[MMI_PROCEDURE_DEACTIVATION] = CALL_FORWARD_ACTION_DISABLE;
MMI_PROC_TO_CF_ACTION[MMI_PROCEDURE_INTERROGATION] = CALL_FORWARD_ACTION_QUERY_STATUS;
MMI_PROC_TO_CF_ACTION[MMI_PROCEDURE_REGISTRATION] = CALL_FORWARD_ACTION_REGISTRATION;
MMI_PROC_TO_CF_ACTION[MMI_PROCEDURE_ERASURE] = CALL_FORWARD_ACTION_ERASURE;
// MMI call forwarding service codes as defined in TS.22.030 Annex B
this.MMI_SC_CFU = "21";
this.MMI_SC_CF_BUSY = "67";
this.MMI_SC_CF_NO_REPLY = "61";
this.MMI_SC_CF_NOT_REACHABLE = "62";
this.MMI_SC_CF_ALL = "002";
this.MMI_SC_CF_ALL_CONDITIONAL = "004";
this.MMI_SC_TO_CF_REASON = {};
MMI_SC_TO_CF_REASON[MMI_SC_CFU] = CALL_FORWARD_REASON_UNCONDITIONAL;
MMI_SC_TO_CF_REASON[MMI_SC_CF_BUSY] = CALL_FORWARD_REASON_MOBILE_BUSY;
MMI_SC_TO_CF_REASON[MMI_SC_CF_NO_REPLY] = CALL_FORWARD_REASON_NO_REPLY;
MMI_SC_TO_CF_REASON[MMI_SC_CF_NOT_REACHABLE] = CALL_FORWARD_REASON_NOT_REACHABLE;
MMI_SC_TO_CF_REASON[MMI_SC_CF_ALL] = CALL_FORWARD_REASON_ALL_CALL_FORWARDING;
MMI_SC_TO_CF_REASON[MMI_SC_CF_ALL_CONDITIONAL] = CALL_FORWARD_REASON_ALL_CONDITIONAL_CALL_FORWARDING;
// MMI service codes for PIN/PIN2/PUK/PUK2 management as defined in TS.22.030
// sec 6.6
this.MMI_SC_PIN = "04";
this.MMI_SC_PIN2 = "042";
this.MMI_SC_PUK = "05";
this.MMI_SC_PUK2 = "052";
// MMI service code for IMEI presentation as defined in TS.22.030 sec 6.7
this.MMI_SC_IMEI = "06";
// MMI called line presentation service codes
this.MMI_SC_CLIP = "30";
this.MMI_SC_CLIR = "31";
// MMI call waiting service code
this.MMI_SC_CALL_WAITING = "43";
// MMI service code for registration new password as defined in TS 22.030 6.5.4
this.MMI_SC_CHANGE_PASSWORD = "03";
this.MMI_ZZ_BARRING_SERVICE = "330";
// MMI call barring service codes
this.MMI_SC_BAOC = "33";
this.MMI_SC_BAOIC = "331";
this.MMI_SC_BAOICxH = "332";
this.MMI_SC_BAIC = "35";
this.MMI_SC_BAICr = "351";
this.MMI_SC_BA_ALL = "330";
this.MMI_SC_BA_MO = "333";
this.MMI_SC_BA_MT = "353";
this.MMI_SC_TO_CB_FACILITY = {};
MMI_SC_TO_CB_FACILITY[MMI_SC_BAOC] = ICC_CB_FACILITY_BAOC;
MMI_SC_TO_CB_FACILITY[MMI_SC_BAOIC] = ICC_CB_FACILITY_BAOIC;
MMI_SC_TO_CB_FACILITY[MMI_SC_BAOICxH] = ICC_CB_FACILITY_BAOICxH;
MMI_SC_TO_CB_FACILITY[MMI_SC_BAIC] = ICC_CB_FACILITY_BAIC;
MMI_SC_TO_CB_FACILITY[MMI_SC_BAICr] = ICC_CB_FACILITY_BAICr;
MMI_SC_TO_CB_FACILITY[MMI_SC_BA_ALL] = ICC_CB_FACILITY_BA_ALL;
MMI_SC_TO_CB_FACILITY[MMI_SC_BA_MO] = ICC_CB_FACILITY_BA_MO;
MMI_SC_TO_CB_FACILITY[MMI_SC_BA_MT] = ICC_CB_FACILITY_BA_MT;
// MMI service code key strings.
this.MMI_KS_SC_CALL_BARRING = "scCallBarring";
this.MMI_KS_SC_CALL_FORWARDING = "scCallForwarding";
this.MMI_KS_SC_CLIP = "scClip";
this.MMI_KS_SC_CLIR = "scClir";
this.MMI_KS_SC_PWD = "scPwd";
this.MMI_KS_SC_CALL_WAITING = "scCallWaiting";
this.MMI_KS_SC_PIN = "scPin";
this.MMI_KS_SC_PIN2 = "scPin2";
this.MMI_KS_SC_PUK = "scPuk";
this.MMI_KS_SC_PUK2 = "scPuk2";
this.MMI_KS_SC_CHANGE_PASSWORD = "scChangePassword";
this.MMI_KS_SC_IMEI = "scImei";
this.MMI_KS_SC_USSD = "scUssd";
this.MMI_KS_SC_CALL = "scCall";
// MMI error messages key strings.
this.MMI_ERROR_KS_ERROR = "emMmiError";
this.MMI_ERROR_KS_NOT_SUPPORTED = "emMmiErrorNotSupported";
this.MMI_ERROR_KS_INVALID_ACTION = "emMmiErrorInvalidAction";
this.MMI_ERROR_KS_MISMATCH_PIN = "emMmiErrorMismatchPin";
this.MMI_ERROR_KS_MISMATCH_PASSWORD = "emMmiErrorMismatchPassword";
this.MMI_ERROR_KS_BAD_PIN = "emMmiErrorBadPin";
this.MMI_ERROR_KS_BAD_PUK = "emMmiErrorBadPuk";
this.MMI_ERROR_KS_INVALID_PIN = "emMmiErrorInvalidPin";
this.MMI_ERROR_KS_INVALID_PASSWORD = "emMmiErrorInvalidPassword";
this.MMI_ERROR_KS_NEEDS_PUK = "emMmiErrorNeedsPuk";
this.MMI_ERROR_KS_SIM_BLOCKED = "emMmiErrorSimBlocked";
// MMI status message.
this.MMI_SM_KS_PASSWORD_CHANGED = "smPasswordChanged";
this.MMI_SM_KS_PIN_CHANGED = "smPinChanged";
this.MMI_SM_KS_PIN2_CHANGED = "smPin2Changed";
this.MMI_SM_KS_PIN_UNBLOCKED = "smPinUnblocked";
this.MMI_SM_KS_PIN2_UNBLOCKED = "smPin2Unblocked";
this.MMI_SM_KS_SERVICE_ENABLED = "smServiceEnabled";
this.MMI_SM_KS_SERVICE_ENABLED_FOR = "smServiceEnabledFor";
this.MMI_SM_KS_SERVICE_DISABLED = "smServiceDisabled";
this.MMI_SM_KS_SERVICE_REGISTERED = "smServiceRegistered";
this.MMI_SM_KS_SERVICE_ERASED = "smServiceErased";
this.MMI_SM_KS_SERVICE_INTERROGATED = "smServiceInterrogated";
this.MMI_SM_KS_SERVICE_NOT_PROVISIONED = "smServiceNotProvisioned";
this.MMI_SM_KS_CLIR_PERMANENT = "smClirPermanent";
this.MMI_SM_KS_CLIR_DEFAULT_ON_NEXT_CALL_ON = "smClirDefaultOnNextCallOn";
this.MMI_SM_KS_CLIR_DEFAULT_ON_NEXT_CALL_OFF = "smClirDefaultOnNextCallOff";
this.MMI_SM_KS_CLIR_DEFAULT_OFF_NEXT_CALL_ON = "smClirDefaultOffNextCallOn";
this.MMI_SM_KS_CLIR_DEFAULT_OFF_NEXT_CALL_OFF = "smClirDefaultOffNextCallOff";
this.MMI_SM_KS_CALL_CONTROL = "smCallControl";
// MMI Service class
this.MMI_KS_SERVICE_CLASS_VOICE = "serviceClassVoice";
this.MMI_KS_SERVICE_CLASS_DATA = "serviceClassData";
this.MMI_KS_SERVICE_CLASS_FAX = "serviceClassFax";
this.MMI_KS_SERVICE_CLASS_SMS = "serviceClassSms";
this.MMI_KS_SERVICE_CLASS_DATA_SYNC = "serviceClassDataSync";
this.MMI_KS_SERVICE_CLASS_DATA_ASYNC = "serviceClassDataAsync";
this.MMI_KS_SERVICE_CLASS_PACKET = "serviceClassPacket";
this.MMI_KS_SERVICE_CLASS_PAD = "serviceClassPad";
this.MMI_KS_SERVICE_CLASS_MAPPING = {};
MMI_KS_SERVICE_CLASS_MAPPING[ICC_SERVICE_CLASS_VOICE] = MMI_KS_SERVICE_CLASS_VOICE;
MMI_KS_SERVICE_CLASS_MAPPING[ICC_SERVICE_CLASS_DATA] = MMI_KS_SERVICE_CLASS_DATA;
MMI_KS_SERVICE_CLASS_MAPPING[ICC_SERVICE_CLASS_FAX] = MMI_KS_SERVICE_CLASS_FAX;
MMI_KS_SERVICE_CLASS_MAPPING[ICC_SERVICE_CLASS_SMS] = MMI_KS_SERVICE_CLASS_SMS;
MMI_KS_SERVICE_CLASS_MAPPING[ICC_SERVICE_CLASS_DATA_SYNC] = MMI_KS_SERVICE_CLASS_DATA_SYNC;
MMI_KS_SERVICE_CLASS_MAPPING[ICC_SERVICE_CLASS_DATA_ASYNC] = MMI_KS_SERVICE_CLASS_DATA_ASYNC;
MMI_KS_SERVICE_CLASS_MAPPING[ICC_SERVICE_CLASS_PACKET] = MMI_KS_SERVICE_CLASS_PACKET;
MMI_KS_SERVICE_CLASS_MAPPING[ICC_SERVICE_CLASS_PAD] = MMI_KS_SERVICE_CLASS_PAD;
/**
* CDMA PDU constants
*/

Просмотреть файл

@ -244,16 +244,6 @@ RilObject.prototype = {
*/
this._pendingNetworkInfo = {rilMessageType: "networkinfochanged"};
/**
* USSD session flag.
* Only one USSD session may exist at a time, and the session is assumed
* to exist until:
* a) There's a call to cancelUSSD()
* b) The implementation sends a UNSOLICITED_ON_USSD with a type code
* of "0" (USSD-Notify/no further action) or "2" (session terminated)
*/
this._ussdSession = null;
/**
* Cell Broadcast Search Lists.
*/
@ -870,60 +860,6 @@ RilObject.prototype = {
Buf.sendParcel();
},
/**
* Query call waiting status via MMI.
*/
_handleQueryMMICallWaiting: function(options) {
let Buf = this.context.Buf;
function callback(options) {
options.length = Buf.readInt32();
options.enabled = (Buf.readInt32() === 1);
let services = Buf.readInt32();
if (options.enabled) {
options.statusMessage = MMI_SM_KS_SERVICE_ENABLED_FOR;
let serviceClass = [];
for (let serviceClassMask = 1;
serviceClassMask <= ICC_SERVICE_CLASS_MAX;
serviceClassMask <<= 1) {
if ((serviceClassMask & services) !== 0) {
serviceClass.push(MMI_KS_SERVICE_CLASS_MAPPING[serviceClassMask]);
}
}
options.additionalInformation = serviceClass;
} else {
options.statusMessage = MMI_SM_KS_SERVICE_DISABLED;
}
// Prevent DataCloneError when sending chrome messages.
delete options.callback;
this.sendChromeMessage(options);
}
options.callback = callback;
this.queryCallWaiting(options);
},
/**
* Set call waiting status via MMI.
*/
_handleSetMMICallWaiting: function(options) {
function callback(options) {
if (options.enabled) {
options.statusMessage = MMI_SM_KS_SERVICE_ENABLED;
} else {
options.statusMessage = MMI_SM_KS_SERVICE_DISABLED;
}
// Prevent DataCloneError when sending chrome messages.
delete options.callback;
this.sendChromeMessage(options);
}
options.callback = callback;
this.setCallWaiting(options);
},
/**
* Query call waiting status.
*
@ -957,9 +893,6 @@ RilObject.prototype = {
/**
* Queries current CLIP status.
*
* (MMI request for code "*#30#")
*
*/
queryCLIP: function(options) {
this.context.Buf.simpleRequest(REQUEST_QUERY_CLIP, options);
@ -1239,6 +1172,15 @@ RilObject.prototype = {
},
getIMEI: function(options) {
// A device's IMEI can't change, so we only need to request it once.
if (this.IMEI) {
if (options && options.rilMessageType) {
options.imei = this.IMEI;
this.sendChromeMessage(options);
}
return;
}
this.context.Buf.simpleRequest(REQUEST_GET_IMEI, options);
},
@ -1893,325 +1835,13 @@ RilObject.prototype = {
this.context.Buf.simpleRequest(REQUEST_LAST_CALL_FAIL_CAUSE, options);
},
sendMMI: function(options) {
if (DEBUG) {
this.context.debug("SendMMI " + JSON.stringify(options));
}
let _sendMMIError = (function(errorMsg) {
options.errorMsg = errorMsg;
this.sendChromeMessage(options);
}).bind(this);
// It's neither a valid mmi code nor an ongoing ussd.
let mmi = options.mmi;
if (!mmi && !this._ussdSession) {
_sendMMIError(MMI_ERROR_KS_ERROR);
return;
}
function _isValidPINPUKRequest() {
// The only allowed MMI procedure for ICC PIN, PIN2, PUK and PUK2 handling
// is "Registration" (**).
if (mmi.procedure != MMI_PROCEDURE_REGISTRATION ) {
_sendMMIError(MMI_ERROR_KS_INVALID_ACTION);
return false;
}
if (!mmi.sia || !mmi.sib || !mmi.sic) {
_sendMMIError(MMI_ERROR_KS_ERROR);
return false;
}
if (mmi.sia.length < 4 || mmi.sia.length > 8 ||
mmi.sib.length < 4 || mmi.sib.length > 8 ||
mmi.sic.length < 4 || mmi.sic.length > 8) {
_sendMMIError(MMI_ERROR_KS_INVALID_PIN);
return false;
}
if (mmi.sib != mmi.sic) {
_sendMMIError(MMI_ERROR_KS_MISMATCH_PIN);
return false;
}
return true;
}
function _isValidChangePasswordRequest() {
if (mmi.procedure !== MMI_PROCEDURE_REGISTRATION &&
mmi.procedure !== MMI_PROCEDURE_ACTIVATION) {
_sendMMIError(MMI_ERROR_KS_INVALID_ACTION);
return false;
}
if (mmi.sia !== "" && mmi.sia !== MMI_ZZ_BARRING_SERVICE) {
_sendMMIError(MMI_ERROR_KS_NOT_SUPPORTED);
return false;
}
let validPassword = si => /^[0-9]{4}$/.test(si);
if (!validPassword(mmi.sib) || !validPassword(mmi.sic) ||
!validPassword(mmi.pwd)) {
_sendMMIError(MMI_ERROR_KS_INVALID_PASSWORD);
return false;
}
if (mmi.sic != mmi.pwd) {
_sendMMIError(MMI_ERROR_KS_MISMATCH_PASSWORD);
return false;
}
return true;
}
let _isRadioAvailable = (function() {
if (this.radioState !== GECKO_RADIOSTATE_ENABLED) {
_sendMMIError(GECKO_ERROR_RADIO_NOT_AVAILABLE);
return false;
}
return true;
}).bind(this);
// We check if the MMI service code is supported and in that case we
// trigger the appropriate RIL request if possible.
let sc = mmi.serviceCode;
switch (sc) {
// Call forwarding
case MMI_SC_CFU:
case MMI_SC_CF_BUSY:
case MMI_SC_CF_NO_REPLY:
case MMI_SC_CF_NOT_REACHABLE:
case MMI_SC_CF_ALL:
case MMI_SC_CF_ALL_CONDITIONAL:
if (!_isRadioAvailable()) {
return;
}
// Call forwarding requires at least an action, given by the MMI
// procedure, and a reason, given by the MMI service code, but there
// is no way that we get this far without a valid procedure or service
// code.
options.action = MMI_PROC_TO_CF_ACTION[mmi.procedure];
options.reason = MMI_SC_TO_CF_REASON[sc];
options.number = mmi.sia;
options.serviceClass = this._siToServiceClass(mmi.sib);
if (options.action == CALL_FORWARD_ACTION_QUERY_STATUS) {
this.queryCallForwardStatus(options);
return;
}
options.isSetCallForward = true;
options.timeSeconds = mmi.sic;
this.setCallForward(options);
return;
// Change the current ICC PIN number.
case MMI_SC_PIN:
// As defined in TS.122.030 6.6.2 to change the ICC PIN we should expect
// an MMI code of the form **04*OLD_PIN*NEW_PIN*NEW_PIN#, where old PIN
// should be entered as the SIA parameter and the new PIN as SIB and
// SIC.
if (!_isRadioAvailable() || !_isValidPINPUKRequest()) {
return;
}
options.password = mmi.sia;
options.newPassword = mmi.sib;
this.changeICCPIN(options);
return;
// Change the current ICC PIN2 number.
case MMI_SC_PIN2:
// As defined in TS.122.030 6.6.2 to change the ICC PIN2 we should
// enter and MMI code of the form **042*OLD_PIN2*NEW_PIN2*NEW_PIN2#,
// where the old PIN2 should be entered as the SIA parameter and the
// new PIN2 as SIB and SIC.
if (!_isRadioAvailable() || !_isValidPINPUKRequest()) {
return;
}
options.password = mmi.sia;
options.newPassword = mmi.sib;
this.changeICCPIN2(options);
return;
// Unblock ICC PIN.
case MMI_SC_PUK:
// As defined in TS.122.030 6.6.3 to unblock the ICC PIN we should
// enter an MMI code of the form **05*PUK*NEW_PIN*NEW_PIN#, where PUK
// should be entered as the SIA parameter and the new PIN as SIB and
// SIC.
if (!_isRadioAvailable() || !_isValidPINPUKRequest()) {
return;
}
options.password = mmi.sia;
options.newPin = mmi.sib;
this.enterICCPUK(options);
return;
// Unblock ICC PIN2.
case MMI_SC_PUK2:
// As defined in TS.122.030 6.6.3 to unblock the ICC PIN2 we should
// enter an MMI code of the form **052*PUK2*NEW_PIN2*NEW_PIN2#, where
// PUK2 should be entered as the SIA parameter and the new PIN2 as SIB
// and SIC.
if (!_isRadioAvailable() || !_isValidPINPUKRequest()) {
return;
}
options.password = mmi.sia;
options.newPin = mmi.sib;
this.enterICCPUK2(options);
return;
// IMEI
case MMI_SC_IMEI:
// A device's IMEI can't change, so we only need to request it once.
if (this.IMEI == null) {
this.getIMEI(options);
return;
}
// If we already had the device's IMEI, we just send it to chrome.
options.statusMessage = this.IMEI;
this.sendChromeMessage(options);
return;
// CLIP
case MMI_SC_CLIP:
options.procedure = mmi.procedure;
if (options.procedure === MMI_PROCEDURE_INTERROGATION) {
this.queryCLIP(options);
} else {
_sendMMIError(MMI_ERROR_KS_NOT_SUPPORTED);
}
return;
// CLIR (non-temporary ones)
// TODO: Both dial() and sendMMI() functions should be unified at some
// point in the future. In the mean time we handle temporary CLIR MMI
// commands through the dial() function. Please see bug 889737.
case MMI_SC_CLIR:
options.procedure = mmi.procedure;
switch (options.procedure) {
case MMI_PROCEDURE_INTERROGATION:
this.getCLIR(options);
return;
case MMI_PROCEDURE_ACTIVATION:
options.clirMode = CLIR_INVOCATION;
break;
case MMI_PROCEDURE_DEACTIVATION:
options.clirMode = CLIR_SUPPRESSION;
break;
default:
_sendMMIError(MMI_ERROR_KS_NOT_SUPPORTED);
return;
}
options.isSetCLIR = true;
this.setCLIR(options);
return;
// Change call barring password
case MMI_SC_CHANGE_PASSWORD:
if (!_isRadioAvailable() || !_isValidChangePasswordRequest()) {
return;
}
options.pin = mmi.sib;
options.newPin = mmi.sic;
this.changeCallBarringPassword(options);
return;
// Call barring
case MMI_SC_BAOC:
case MMI_SC_BAOIC:
case MMI_SC_BAOICxH:
case MMI_SC_BAIC:
case MMI_SC_BAICr:
case MMI_SC_BA_ALL:
case MMI_SC_BA_MO:
case MMI_SC_BA_MT:
options.password = mmi.sia || "";
options.serviceClass = this._siToServiceClass(mmi.sib);
options.facility = MMI_SC_TO_CB_FACILITY[sc];
options.procedure = mmi.procedure;
if (mmi.procedure === MMI_PROCEDURE_INTERROGATION) {
this.queryICCFacilityLock(options);
return;
}
if (mmi.procedure === MMI_PROCEDURE_ACTIVATION) {
options.enabled = 1;
} else if (mmi.procedure === MMI_PROCEDURE_DEACTIVATION) {
options.enabled = 0;
} else {
_sendMMIError(MMI_ERROR_KS_NOT_SUPPORTED);
return;
}
this.setICCFacilityLock(options);
return;
// Call waiting
case MMI_SC_CALL_WAITING:
if (!_isRadioAvailable()) {
return;
}
if (mmi.procedure === MMI_PROCEDURE_INTERROGATION) {
this._handleQueryMMICallWaiting(options);
return;
}
if (mmi.procedure === MMI_PROCEDURE_ACTIVATION) {
options.enabled = true;
} else if (mmi.procedure === MMI_PROCEDURE_DEACTIVATION) {
options.enabled = false;
} else {
_sendMMIError(MMI_ERROR_KS_NOT_SUPPORTED);
return;
}
options.serviceClass = this._siToServiceClass(mmi.sia);
this._handleSetMMICallWaiting(options);
return;
}
// If the MMI code is not a known code, it is treated as an ussd.
if (!_isRadioAvailable()) {
return;
}
options.ussd = mmi.fullMMI;
if (this._ussdSession) {
if (DEBUG) this.context.debug("Cancel existing ussd session.");
this.cachedUSSDRequest = options;
this.cancelUSSD({});
return;
}
this.sendUSSD(options, false);
},
/**
* Cache the request for send out a new ussd when there is an existing
* session. We should do cancelUSSD first.
*/
cachedUSSDRequest : null,
/**
* Send USSD.
*
* @param ussd
* String containing the USSD code.
*/
sendUSSD: function(options, checkSession = true) {
if (checkSession && !this._ussdSession) {
options.errorMsg = GECKO_ERROR_GENERIC_FAILURE;
this.sendChromeMessage(options);
return;
}
sendUSSD: function(options) {
let Buf = this.context.Buf;
Buf.newParcel(REQUEST_SEND_USSD, options);
Buf.writeString(options.ussd);
@ -2935,47 +2565,6 @@ RilObject.prototype = {
*/
_processEnterAndChangeICCResponses: function(length, options) {
options.retryCount = length ? this.context.Buf.readInt32List()[0] : -1;
if (options.rilMessageType != "sendMMI") {
this.sendChromeMessage(options);
return;
}
let serviceCode = options.mmi.serviceCode;
if (!options.errorMsg) {
switch (serviceCode) {
case MMI_SC_PIN:
options.statusMessage = MMI_SM_KS_PIN_CHANGED;
break;
case MMI_SC_PIN2:
options.statusMessage = MMI_SM_KS_PIN2_CHANGED;
break;
case MMI_SC_PUK:
options.statusMessage = MMI_SM_KS_PIN_UNBLOCKED;
break;
case MMI_SC_PUK2:
options.statusMessage = MMI_SM_KS_PIN2_UNBLOCKED;
break;
}
} else {
if (options.retryCount <= 0) {
if (serviceCode === MMI_SC_PUK) {
options.errorMsg = MMI_ERROR_KS_SIM_BLOCKED;
} else if (serviceCode === MMI_SC_PIN) {
options.errorMsg = MMI_ERROR_KS_NEEDS_PUK;
}
} else {
if (serviceCode === MMI_SC_PIN || serviceCode === MMI_SC_PIN2) {
options.errorMsg = MMI_ERROR_KS_BAD_PIN;
} else if (serviceCode === MMI_SC_PUK || serviceCode === MMI_SC_PUK2) {
options.errorMsg = MMI_ERROR_KS_BAD_PUK;
}
if (options.retryCount !== undefined) {
options.additionalInformation = options.retryCount;
}
}
}
this.sendChromeMessage(options);
},
@ -3584,44 +3173,6 @@ RilObject.prototype = {
return toa;
},
/**
* Helper for translating basic service group to call forwarding service class
* parameter.
*/
_siToServiceClass: function(si) {
if (!si) {
return ICC_SERVICE_CLASS_NONE;
}
let serviceCode = parseInt(si, 10);
switch (serviceCode) {
case 10:
return ICC_SERVICE_CLASS_SMS + ICC_SERVICE_CLASS_FAX + ICC_SERVICE_CLASS_VOICE;
case 11:
return ICC_SERVICE_CLASS_VOICE;
case 12:
return ICC_SERVICE_CLASS_SMS + ICC_SERVICE_CLASS_FAX;
case 13:
return ICC_SERVICE_CLASS_FAX;
case 16:
return ICC_SERVICE_CLASS_SMS;
case 19:
return ICC_SERVICE_CLASS_FAX + ICC_SERVICE_CLASS_VOICE;
case 21:
return ICC_SERVICE_CLASS_PAD + ICC_SERVICE_CLASS_DATA_ASYNC;
case 22:
return ICC_SERVICE_CLASS_PACKET + ICC_SERVICE_CLASS_DATA_SYNC;
case 25:
return ICC_SERVICE_CLASS_DATA_ASYNC;
case 26:
return ICC_SERVICE_CLASS_DATA_SYNC + SERVICE_CLASS_VOICE;
case 99:
return ICC_SERVICE_CLASS_PACKET;
default:
return ICC_SERVICE_CLASS_NONE;
}
},
/**
* @param message A decoded SMS-DELIVER message.
*
@ -4745,24 +4296,12 @@ RilObject.prototype[REQUEST_SEND_USSD] = function REQUEST_SEND_USSD(length, opti
if (DEBUG) {
this.context.debug("REQUEST_SEND_USSD " + JSON.stringify(options));
}
this._ussdSession = !options.errorMsg;
this.sendChromeMessage(options);
};
RilObject.prototype[REQUEST_CANCEL_USSD] = function REQUEST_CANCEL_USSD(length, options) {
if (DEBUG) {
this.context.debug("REQUEST_CANCEL_USSD" + JSON.stringify(options));
}
this._ussdSession = !!options.errorMsg;
// The cancelUSSD is triggered by ril_worker itself.
if (this.cachedUSSDRequest) {
if (DEBUG) this.context.debug("Send out the cached ussd request");
this.sendUSSD(this.cachedUSSDRequest);
this.cachedUSSDRequest = null;
return;
}
this.sendChromeMessage(options);
};
RilObject.prototype[REQUEST_GET_CLIR] = function REQUEST_GET_CLIR(length, options) {
@ -4781,66 +4320,6 @@ RilObject.prototype[REQUEST_GET_CLIR] = function REQUEST_GET_CLIR(length, option
options.n = Buf.readInt32(); // Will be TS 27.007 +CLIR parameter 'n'.
options.m = Buf.readInt32(); // Will be TS 27.007 +CLIR parameter 'm'.
if (options.rilMessageType === "sendMMI") {
// TS 27.007 +CLIR parameter 'm'.
switch (options.m) {
// CLIR not provisioned.
case 0:
options.statusMessage = MMI_SM_KS_SERVICE_NOT_PROVISIONED;
break;
// CLIR provisioned in permanent mode.
case 1:
options.statusMessage = MMI_SM_KS_CLIR_PERMANENT;
break;
// Unknown (e.g. no network, etc.).
case 2:
options.errorMsg = MMI_ERROR_KS_ERROR;
break;
// CLIR temporary mode presentation restricted.
case 3:
// TS 27.007 +CLIR parameter 'n'.
switch (options.n) {
// Default.
case 0:
// CLIR invocation.
case 1:
options.statusMessage = MMI_SM_KS_CLIR_DEFAULT_ON_NEXT_CALL_ON;
break;
// CLIR suppression.
case 2:
options.statusMessage = MMI_SM_KS_CLIR_DEFAULT_ON_NEXT_CALL_OFF;
break;
default:
options.errorMsg = GECKO_ERROR_GENERIC_FAILURE;
break;
}
break;
// CLIR temporary mode presentation allowed.
case 4:
// TS 27.007 +CLIR parameter 'n'.
switch (options.n) {
// Default.
case 0:
// CLIR suppression.
case 2:
options.statusMessage = MMI_SM_KS_CLIR_DEFAULT_OFF_NEXT_CALL_OFF;
break;
// CLIR invocation.
case 1:
options.statusMessage = MMI_SM_KS_CLIR_DEFAULT_OFF_NEXT_CALL_ON;
break;
default:
options.errorMsg = GECKO_ERROR_GENERIC_FAILURE;
break;
}
break;
default:
options.errorMsg = GECKO_ERROR_GENERIC_FAILURE;
break;
}
}
this.sendChromeMessage(options);
};
RilObject.prototype[REQUEST_SET_CLIR] = function REQUEST_SET_CLIR(length, options) {
@ -4849,16 +4328,6 @@ RilObject.prototype[REQUEST_SET_CLIR] = function REQUEST_SET_CLIR(length, option
return;
}
if (!options.errorMsg && options.rilMessageType === "sendMMI") {
switch (options.procedure) {
case MMI_PROCEDURE_ACTIVATION:
options.statusMessage = MMI_SM_KS_SERVICE_ENABLED;
break;
case MMI_PROCEDURE_DEACTIVATION:
options.statusMessage = MMI_SM_KS_SERVICE_DISABLED;
break;
}
}
this.sendChromeMessage(options);
};
@ -4891,52 +4360,19 @@ RilObject.prototype[REQUEST_QUERY_CALL_FORWARD_STATUS] =
rules[i] = rule;
}
options.rules = rules;
if (options.rilMessageType === "sendMMI") {
options.statusMessage = MMI_SM_KS_SERVICE_INTERROGATED;
// MMI query call forwarding options request returns a set of rules that
// will be exposed in the form of an array of MozCallForwardingOptions
// instances.
options.additionalInformation = rules;
}
this.sendChromeMessage(options);
};
RilObject.prototype[REQUEST_SET_CALL_FORWARD] =
function REQUEST_SET_CALL_FORWARD(length, options) {
if (!options.errorMsg && options.rilMessageType === "sendMMI") {
switch (options.action) {
case CALL_FORWARD_ACTION_ENABLE:
options.statusMessage = MMI_SM_KS_SERVICE_ENABLED;
break;
case CALL_FORWARD_ACTION_DISABLE:
options.statusMessage = MMI_SM_KS_SERVICE_DISABLED;
break;
case CALL_FORWARD_ACTION_REGISTRATION:
options.statusMessage = MMI_SM_KS_SERVICE_REGISTERED;
break;
case CALL_FORWARD_ACTION_ERASURE:
options.statusMessage = MMI_SM_KS_SERVICE_ERASED;
break;
}
}
this.sendChromeMessage(options);
};
RilObject.prototype[REQUEST_QUERY_CALL_WAITING] =
function REQUEST_QUERY_CALL_WAITING(length, options) {
if (options.errorMsg) {
if (options.callback) {
// Prevent DataCloneError when sending chrome messages.
delete options.callback;
}
this.sendChromeMessage(options);
return;
}
if (options.callback) {
options.callback.call(this, options);
return;
}
let Buf = this.context.Buf;
let results = Buf.readInt32List();
let enabled = (results[0] === 1);
@ -4945,37 +4381,23 @@ RilObject.prototype[REQUEST_QUERY_CALL_WAITING] =
};
RilObject.prototype[REQUEST_SET_CALL_WAITING] = function REQUEST_SET_CALL_WAITING(length, options) {
if (options.errorMsg) {
if (options.callback) {
// Prevent DataCloneError when sending chrome messages.
delete options.callback;
}
this.sendChromeMessage(options);
return;
}
if (options.callback) {
options.callback.call(this, options);
return;
}
this.sendChromeMessage(options);
};
RilObject.prototype[REQUEST_SMS_ACKNOWLEDGE] = null;
RilObject.prototype[REQUEST_GET_IMEI] = function REQUEST_GET_IMEI(length, options) {
this.IMEI = this.context.Buf.readString();
let rilMessageType = options.rilMessageType;
// So far we only send the IMEI back to chrome if it was requested via MMI.
if (rilMessageType !== "sendMMI") {
return;
}
if (!options.errorMsg && this.IMEI == null) {
options.errorMsg = GECKO_ERROR_GENERIC_FAILURE;
// If the request wasn't made by ril_worker itself, we send the IMEI back to
// chrome.
if (options.rilMessageType) {
if (options.errorMsg) {
this.sendChromeMessage(options);
return;
}
options.imei = this.IMEI;
this.sendChromeMessage(options);
}
options.statusMessage = this.IMEI;
this.sendChromeMessage(options);
};
RilObject.prototype[REQUEST_GET_IMEISV] = function REQUEST_GET_IMEISV(length, options) {
if (options.errorMsg) {
@ -5003,57 +4425,22 @@ RilObject.prototype[REQUEST_QUERY_FACILITY_LOCK] = function REQUEST_QUERY_FACILI
}
// Buf.readInt32List()[0] for Call Barring is a bit vector of services.
let services = this.context.Buf.readInt32List()[0];
options.serviceClass = this.context.Buf.readInt32List()[0];
if (options.queryServiceClass) {
options.enabled = (services & options.queryServiceClass) ? true : false;
options.enabled = (options.serviceClass & options.queryServiceClass) ? true : false;
options.serviceClass = options.queryServiceClass;
} else {
options.enabled = services ? true : false;
options.enabled = options.serviceClass ? true : false;
}
if (options.rilMessageType === "sendMMI") {
if (!options.enabled) {
options.statusMessage = MMI_SM_KS_SERVICE_DISABLED;
} else {
options.statusMessage = MMI_SM_KS_SERVICE_ENABLED_FOR;
let serviceClass = [];
for (let serviceClassMask = 1;
serviceClassMask <= ICC_SERVICE_CLASS_MAX;
serviceClassMask <<= 1) {
if ((serviceClassMask & services) !== 0) {
serviceClass.push(MMI_KS_SERVICE_CLASS_MAPPING[serviceClassMask]);
}
}
options.additionalInformation = serviceClass;
}
}
this.sendChromeMessage(options);
};
RilObject.prototype[REQUEST_SET_FACILITY_LOCK] = function REQUEST_SET_FACILITY_LOCK(length, options) {
options.retryCount = length ? this.context.Buf.readInt32List()[0] : -1;
if (!options.errorMsg && (options.rilMessageType === "sendMMI")) {
switch (options.procedure) {
case MMI_PROCEDURE_ACTIVATION:
options.statusMessage = MMI_SM_KS_SERVICE_ENABLED;
break;
case MMI_PROCEDURE_DEACTIVATION:
options.statusMessage = MMI_SM_KS_SERVICE_DISABLED;
break;
}
}
this.sendChromeMessage(options);
};
RilObject.prototype[REQUEST_CHANGE_BARRING_PASSWORD] =
function REQUEST_CHANGE_BARRING_PASSWORD(length, options) {
if (options.rilMessageType != "sendMMI") {
this.sendChromeMessage(options);
return;
}
options.statusMessage = MMI_SM_KS_PASSWORD_CHANGED;
this.sendChromeMessage(options);
};
RilObject.prototype[REQUEST_QUERY_NETWORK_SELECTION_MODE] = function REQUEST_QUERY_NETWORK_SELECTION_MODE(length, options) {
@ -5129,25 +4516,7 @@ RilObject.prototype[REQUEST_QUERY_CLIP] = function REQUEST_QUERY_CLIP(length, op
return;
}
// options.provisioned informs about the called party receives the calling
// party's address information:
// 0 for CLIP not provisioned
// 1 for CLIP provisioned
// 2 for unknown
options.provisioned = Buf.readInt32();
if (options.rilMessageType === "sendMMI") {
switch (options.provisioned) {
case 0:
options.statusMessage = MMI_SM_KS_SERVICE_DISABLED;
break;
case 1:
options.statusMessage = MMI_SM_KS_SERVICE_ENABLED;
break;
default:
options.errorMsg = MMI_ERROR_KS_ERROR;
break;
}
}
this.sendChromeMessage(options);
};
RilObject.prototype[REQUEST_LAST_DATA_CALL_FAIL_CAUSE] = null;
@ -5721,18 +5090,12 @@ RilObject.prototype[UNSOLICITED_ON_USSD] = function UNSOLICITED_ON_USSD() {
this.context.debug("On USSD. Type Code: " + typeCode + " Message: " + message);
}
let oldSession = this._ussdSession;
// Per ril.h the USSD session is assumed to persist if the type code is "1".
this._ussdSession = typeCode == "1";
if (!oldSession && !this._ussdSession && !message) {
return;
}
this.sendChromeMessage({rilMessageType: "ussdreceived",
message: message,
sessionEnded: !this._ussdSession});
// Per ril.h the USSD session is assumed to persist if
// the type code is "1", otherwise the current session
// (if any) is assumed to have terminated.
sessionEnded: typeCode !== "1"});
};
RilObject.prototype[UNSOLICITED_ON_USSD_REQUEST] = null;
RilObject.prototype[UNSOLICITED_NITZ_TIME_RECEIVED] = function UNSOLICITED_NITZ_TIME_RECEIVED() {

Просмотреть файл

@ -1,513 +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();
}
function createMMIOptions(procedure, serviceCode, sia, sib, sic) {
let mmi = {
fullMMI: Array.slice(arguments).join("*") + "#",
procedure: procedure,
serviceCode: serviceCode,
sia: sia,
sib: sib,
sic: sic
};
return mmi;
}
function testSendMMI(mmi, error) {
let workerhelper = newInterceptWorker();
let worker = workerhelper.worker;
let context = worker.ContextPool._contexts[0];
do_print("worker.postMessage " + worker.postMessage);
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
context.RIL.sendMMI({rilMessageType: "sendMMI", mmi: mmi});
let postedMessage = workerhelper.postedMessage;
equal(postedMessage.rilMessageType, "sendMMI");
equal(postedMessage.errorMsg, error);
}
/**
* sendMMI tests.
*/
add_test(function test_sendMMI_null() {
testSendMMI(null, MMI_ERROR_KS_ERROR);
run_next_test();
});
add_test(function test_sendMMI_short_code() {
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, {});
};
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
context.RIL.sendMMI({mmi: {fullMMI: "**"}});
let postedMessage = workerhelper.postedMessage;
equal(ussdOptions.ussd, "**");
equal(postedMessage.errorMsg, undefined);
ok(context.RIL._ussdSession);
run_next_test();
});
add_test(function test_sendMMI_change_PIN() {
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, {});
};
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
context.RIL.sendMMI({mmi: createMMIOptions("**", "04", "1234", "4567",
"4567")});
let postedMessage = workerhelper.postedMessage;
equal(postedMessage.errorMsg, undefined);
run_next_test();
});
add_test(function test_sendMMI_change_PIN_no_new_PIN() {
testSendMMI(createMMIOptions("**", "04", "1234", "", "4567"),
MMI_ERROR_KS_ERROR);
run_next_test();
});
add_test(function test_sendMMI_change_PIN_no_old_PIN() {
testSendMMI(createMMIOptions("**", "04", "", "1234", "4567"),
MMI_ERROR_KS_ERROR);
run_next_test();
});
add_test(function test_sendMMI_change_PIN_wrong_procedure() {
testSendMMI(createMMIOptions("*", "04", "1234", "4567", "4567"),
MMI_ERROR_KS_INVALID_ACTION);
run_next_test();
});
add_test(function test_sendMMI_change_PIN_new_PIN_mismatch() {
testSendMMI(createMMIOptions("**", "04", "4567", "1234", "4567"),
MMI_ERROR_KS_MISMATCH_PIN);
run_next_test();
});
add_test(function test_sendMMI_change_PIN2() {
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, {});
};
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
context.RIL.sendMMI({mmi: createMMIOptions("**", "042", "1234", "4567",
"4567")});
let postedMessage = workerhelper.postedMessage;
equal(postedMessage.errorMsg, undefined);
run_next_test();
});
add_test(function test_sendMMI_change_PIN2_no_new_PIN2() {
testSendMMI(createMMIOptions("**", "042", "1234", "", "4567"),
MMI_ERROR_KS_ERROR);
run_next_test();
});
add_test(function test_sendMMI_change_PIN2_no_old_PIN2() {
testSendMMI(createMMIOptions("**", "042", "", "1234", "4567"),
MMI_ERROR_KS_ERROR);
run_next_test();
});
add_test(function test_sendMMI_change_PIN2_wrong_procedure() {
testSendMMI(createMMIOptions("*", "042", "1234", "4567", "4567"),
MMI_ERROR_KS_INVALID_ACTION);
run_next_test();
});
add_test(function test_sendMMI_change_PIN2_new_PIN2_mismatch() {
testSendMMI(createMMIOptions("**", "042", "4567", "1234", "4567"),
MMI_ERROR_KS_MISMATCH_PIN);
run_next_test();
});
add_test(function test_sendMMI_unblock_PIN() {
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, {});
};
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
context.RIL.sendMMI({mmi: createMMIOptions("**", "05", "1234", "4567",
"4567")});
let postedMessage = workerhelper.postedMessage;
equal(postedMessage.errorMsg, undefined);
run_next_test();
});
add_test(function test_sendMMI_unblock_PIN_no_new_PIN() {
testSendMMI(createMMIOptions("**", "05", "1234", "", "4567"),
MMI_ERROR_KS_ERROR);
run_next_test();
});
add_test(function test_sendMMI_unblock_PIN_no_PUK() {
testSendMMI(createMMIOptions("**", "05", "", "1234", "4567"),
MMI_ERROR_KS_ERROR);
run_next_test();
});
add_test(function test_sendMMI_unblock_PIN_wrong_procedure() {
testSendMMI(createMMIOptions("*", "05", "1234", "4567", "4567"),
MMI_ERROR_KS_INVALID_ACTION);
run_next_test();
});
add_test(function test_sendMMI_unblock_PIN_new_PIN_mismatch() {
testSendMMI(createMMIOptions("**", "05", "4567", "1234", "4567"),
MMI_ERROR_KS_MISMATCH_PIN);
run_next_test();
});
add_test(function test_sendMMI_unblock_PIN2() {
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, {});
};
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
context.RIL.sendMMI({mmi: createMMIOptions("**", "052", "1234", "4567",
"4567")});
let postedMessage = workerhelper.postedMessage;
equal(postedMessage.errorMsg, undefined);
run_next_test();
});
add_test(function test_sendMMI_unblock_PIN2_no_new_PIN2() {
testSendMMI(createMMIOptions("**", "052", "1234", "", "4567"),
MMI_ERROR_KS_ERROR);
run_next_test();
});
add_test(function test_sendMMI_unblock_PIN2_no_PUK2() {
testSendMMI(createMMIOptions("**", "052", "", "1234", "4567"),
MMI_ERROR_KS_ERROR);
run_next_test();
});
add_test(function test_sendMMI_unblock_PIN2_wrong_procedure() {
testSendMMI(createMMIOptions("*", "052", "1234", "4567", "4567"),
MMI_ERROR_KS_INVALID_ACTION);
run_next_test();
});
add_test(function test_sendMMI_unblock_PIN2_new_PIN_mismatch() {
testSendMMI(createMMIOptions("**", "052", "4567", "1234", "4567"),
MMI_ERROR_KS_MISMATCH_PIN);
run_next_test();
});
add_test(function test_sendMMI_get_IMEI() {
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, {});
};
context.RIL.sendMMI({mmi: createMMIOptions("*#", "06")});
let postedMessage = workerhelper.postedMessage;
notEqual(mmiOptions.mmi, null);
equal(postedMessage.errorMsg, undefined);
run_next_test();
});
add_test(function test_sendMMI_get_IMEI_error() {
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, {
errorMsg: GECKO_ERROR_RADIO_NOT_AVAILABLE
});
};
context.RIL.sendMMI({mmi: createMMIOptions("*#", "06")});
let postedMessage = workerhelper.postedMessage;
notEqual(mmiOptions.mmi, null);
equal (postedMessage.errorMsg, GECKO_ERROR_RADIO_NOT_AVAILABLE);
run_next_test();
});
add_test(function test_sendMMI_call_barring_BAIC_interrogation_voice() {
let workerhelper = newInterceptWorker();
let worker = workerhelper.worker;
let context = worker.ContextPool._contexts[0];
context.Buf.readInt32List = function fakeReadUint32List() {
return [1];
};
context.RIL.queryICCFacilityLock =
function fakeQueryICCFacilityLock(options) {
context.RIL[REQUEST_QUERY_FACILITY_LOCK](1, {
rilMessageType: "sendMMI"
});
};
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
context.RIL.sendMMI({mmi: createMMIOptions("*#", "33")});
let postedMessage = workerhelper.postedMessage;
equal(postedMessage.errorMsg, undefined);
ok(postedMessage.enabled);
equal(postedMessage.statusMessage, MMI_SM_KS_SERVICE_ENABLED_FOR);
ok(Array.isArray(postedMessage.additionalInformation));
equal(postedMessage.additionalInformation[0], "serviceClassVoice");
run_next_test();
});
add_test(function test_sendMMI_call_barring_BAIC_activation() {
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, {
rilMessageType: "sendMMI",
procedure: MMI_PROCEDURE_ACTIVATION
});
};
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
context.RIL.sendMMI({mmi: createMMIOptions("*", "33")});
let postedMessage = workerhelper.postedMessage;
equal(mmiOptions.procedure, MMI_PROCEDURE_ACTIVATION);
equal(postedMessage.errorMsg, undefined);
equal(postedMessage.statusMessage, MMI_SM_KS_SERVICE_ENABLED);
run_next_test();
});
add_test(function test_sendMMI_call_barring_BAIC_deactivation() {
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, {
rilMessageType: "sendMMI",
procedure: MMI_PROCEDURE_DEACTIVATION
});
};
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
context.RIL.sendMMI({mmi: createMMIOptions("#", "33")});
let postedMessage = workerhelper.postedMessage;
equal(mmiOptions.procedure, MMI_PROCEDURE_DEACTIVATION);
equal(postedMessage.errorMsg, undefined);
equal(postedMessage.statusMessage, MMI_SM_KS_SERVICE_DISABLED);
run_next_test();
});
add_test(function test_sendMMI_call_barring_BAIC_procedure_not_supported() {
testSendMMI(createMMIOptions("**", "33", "0000"), MMI_ERROR_KS_NOT_SUPPORTED);
run_next_test();
});
add_test(function test_sendMMI_USSD() {
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, {});
};
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
context.RIL.sendMMI({mmi: createMMIOptions("*", "123")});
let postedMessage = workerhelper.postedMessage;
equal(ussdOptions.ussd, "**123#");
equal(postedMessage.errorMsg, undefined);
ok(context.RIL._ussdSession);
run_next_test();
});
add_test(function test_sendMMI_USSD_error() {
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, {
errorMsg: GECKO_ERROR_GENERIC_FAILURE
});
};
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
context.RIL.sendMMI({mmi: createMMIOptions("*", "123")});
let postedMessage = workerhelper.postedMessage;
equal(ussdOptions.ussd, "**123#");
equal(postedMessage.errorMsg, GECKO_ERROR_GENERIC_FAILURE);
ok(!context.RIL._ussdSession);
run_next_test();
});
function setCallWaitingSuccess(mmi) {
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, {});
};
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
context.RIL.sendMMI({mmi: mmi});
let postedMessage = workerhelper.postedMessage;
equal(postedMessage.errorMsg, undefined);
}
add_test(function test_sendMMI_call_waiting_activation() {
setCallWaitingSuccess(createMMIOptions("*", "43", "10"));
run_next_test();
});
add_test(function test_sendMMI_call_waiting_deactivation() {
setCallWaitingSuccess(createMMIOptions("#", "43"));
run_next_test();
});
add_test(function test_sendMMI_call_waiting_registration() {
testSendMMI(createMMIOptions("**", "43"), MMI_ERROR_KS_NOT_SUPPORTED);
run_next_test();
});
add_test(function test_sendMMI_call_waiting_erasure() {
testSendMMI(createMMIOptions("##", "43"), MMI_ERROR_KS_NOT_SUPPORTED);
run_next_test();
});
add_test(function test_sendMMI_call_waiting_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.RIL.queryCallWaiting = function fakeQueryCallWaiting(options) {
context.Buf.int32Array = [
7, // serviceClass
1, // enabled
2 // length
];
context.RIL[REQUEST_QUERY_CALL_WAITING](1, {});
};
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
context.RIL.sendMMI({mmi: createMMIOptions("*#", "43")});
let postedMessage = workerhelper.postedMessage;
equal(postedMessage.errorMsg, undefined);
equal(postedMessage.serviceClass, 7);
run_next_test();
});

Просмотреть файл

@ -1,156 +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();
}
function createMMIOptions(procedure, serviceCode, sia, sib, sic) {
let mmi = {
fullMMI: Array.slice(arguments).join("*") + "#",
procedure: procedure,
serviceCode: serviceCode,
sia: sia,
sib: sib,
sic: sic
};
return mmi;
}
function setCallForwardSuccess(procedure, serviceCode, sia, sib, sic) {
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, {});
};
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
context.RIL.sendMMI({mmi: createMMIOptions(procedure, serviceCode, sia, sib,
sic)});
let postedMessage = workerhelper.postedMessage;
equal(postedMessage.errorMsg, undefined);
}
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, {});
};
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
context.RIL.sendMMI({mmi: createMMIOptions("*#", "21")});
let postedMessage = workerhelper.postedMessage;
equal(postedMessage.errorMsg, undefined);
ok(Array.isArray(postedMessage.rules));
equal(postedMessage.rules.length, 1);
ok(postedMessage.rules[0].active);
equal(postedMessage.rules[0].reason, CALL_FORWARD_REASON_UNCONDITIONAL);
equal(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, {});
};
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
context.RIL.sendMMI({mmi: createMMIOptions("*#", "21")});
let postedMessage = workerhelper.postedMessage;
equal(postedMessage.errorMsg, GECKO_ERROR_GENERIC_FAILURE);
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();
});

Просмотреть файл

@ -23,8 +23,6 @@ skip-if = true
[test_ril_worker_sms_gsmpduhelper.js]
[test_ril_worker_sms_segment_info.js]
[test_ril_worker_smsc_address.js]
[test_ril_worker_mmi.js]
[test_ril_worker_mmi_cf.js]
[test_ril_worker_cf.js]
[test_ril_worker_cellbroadcast_config.js]
[test_ril_worker_cellbroadcast.js]

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -33,11 +33,18 @@ qemu = true
[test_incoming_answer_hangup_oncallschanged.js]
[test_incoming_basic_operations.js]
[test_incoming_onstatechange.js]
[test_mmi.js]
[test_mmi_call_barring.js]
[test_mmi_call_forwarding.js]
[test_mmi_call_waiting.js]
[test_mmi_change_barring_password.js]
[test_mmi_change_pin.js]
[test_mmi_change_pin2.js]
[test_mmi_clip.js]
[test_mmi_clir.js]
[test_mmi_imei.js]
[test_mmi_unlock_puk.js]
[test_mmi_unlock_puk2.js]
[test_mmi_ussd.js]
[test_multiple_hold.js]
[test_outgoing_already_held.js]
[test_outgoing_answer_hangup_oncallschanged.js]

Просмотреть файл

@ -0,0 +1,98 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = "head.js";
// Password is hardcoded as "0000" by default in emulator.
const PASSWORD = "0000";
// Emulator doesn't support BA_ALL(330), BA_MO(333), BA_MT(353).
const CB_TYPES = ["33", "331", "332", "35", "351"];
const CB_TYPES_UNSUPPORTED = ["330", "333", "353"];
// Basic Service - 10: Voice + Fax + SMS.
const BS = "10";
const MMI_SERVICE_CLASS = ["serviceClassVoice", "serviceClassFax",
"serviceClassSms"];
// Call barring doesn't support Registration (**) and Erasure (##) operation.
const OPERATION_UNSUPPORTED = ["**", "##"];
function sendCbMMI(aOperation, aType, aExpectedSuccess, aExpectedStatusMessage) {
let mmi = aOperation + aType + "*" + PASSWORD + "*" + BS + "#";
log("Test " + mmi + " ...");
return gSendMMI(mmi)
.then((aResult) => {
is(aResult.success, aExpectedSuccess, "Check success");
is(aResult.serviceCode, "scCallBarring", "Check serviceCode");
is(aResult.statusMessage, aExpectedStatusMessage, "Check statusMessage");
return aResult;
});
}
function testCallBarring(aEnabled) {
let promise = Promise.resolve();
CB_TYPES.forEach(function(aType) {
promise = promise
// Test setting call barring.
.then(() => sendCbMMI(aEnabled ? "*" : "#", aType, true,
aEnabled ? "smServiceEnabled" : "smServiceDisabled"))
// Test getting call barring.
.then(() => sendCbMMI("*#", aType, true,
aEnabled ? "smServiceEnabledFor": "smServiceDisabled"))
.then(aResult => {
if (aEnabled) {
is(aResult.additionalInformation.length, MMI_SERVICE_CLASS.length,
"Check additionalInformation.length");
for (let i = 0; i < MMI_SERVICE_CLASS.length; i++) {
is(aResult.additionalInformation[i], MMI_SERVICE_CLASS[i],
"Check additionalInformation[" + i + "]");
}
}
});
});
return promise;
}
function testUnsupportType() {
let promise = Promise.resolve();
CB_TYPES_UNSUPPORTED.forEach(function(aType) {
promise = promise
// Test setting call barring.
.then(() => sendCbMMI("*", aType, false, "RequestNotSupported"))
// Test getting call barring.
.then(() => sendCbMMI("*#", aType, false, "RequestNotSupported"));
});
return promise;
}
function testUnsupportedOperation() {
let promise = Promise.resolve();
let types = CB_TYPES.concat(CB_TYPES_UNSUPPORTED);
types.forEach(function(aType) {
OPERATION_UNSUPPORTED.forEach(function(aOperation) {
promise = promise
.then(() => sendCbMMI(aOperation, aType, false,
"emMmiErrorNotSupported"));
});
});
return promise;
}
// Start test.
startTest(function() {
// Activate call barring service.
return testCallBarring(true)
// Deactivate call barring service.
.then(() => testCallBarring(false))
.then(() => testUnsupportType())
.then(() => testUnsupportedOperation())
.catch(error => ok(false, "Promise reject: " + error))
.then(finish);;
});

Просмотреть файл

@ -0,0 +1,44 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = "head.js";
const TEST_DATA = [
// [mmi, expectedError]
// Currently emulator doesn't support REQUEST_QUERY_CALL_WAITING, so we expect
// to get a 'RequestNotSupported' error here.
["*#43*10#", "RequestNotSupported"],
// Currently emulator doesn't support REQUEST_SET_CALL_WAITING, so we expect
// to get a 'RequestNotSupported' error here.
["*43*10#", "RequestNotSupported"],
["#43*10#", "RequestNotSupported"],
// Unsupported Call Waiting MMI code.
["**43*10#", "emMmiErrorNotSupported"],
["##43*10#", "emMmiErrorNotSupported"],
];
function testCallWaiting(aMmi, aExpectedError) {
log("Test " + aMmi + " ...");
return gSendMMI(aMmi).then(aResult => {
// Since emulator doesn't support call waiting, so we expect the result is
// always failed.
ok(!aResult.success, "Check success");
is(aResult.serviceCode, "scCallWaiting", "Check serviceCode");
is(aResult.statusMessage, aExpectedError, "Check statusMessage");
});
}
// Start test
startTest(function() {
let promise = Promise.resolve();
TEST_DATA.forEach(function(aData) {
promise = promise.then(() => testCallWaiting(aData[0], aData[1]));
});
return promise
.catch(aError => ok(false, "Promise reject: " + aError))
.then(finish);
});

Просмотреть файл

@ -0,0 +1,105 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = "head.js";
const TEST_DATA = [
// Test passing no pin2.
{
pin2: "",
newPin2: "0000",
newPin2Again: "1111",
expectedError: {
name: "emMmiError",
additionalInformation: null
}
},
// Test passing no newPin2.
{
pin2: "0000",
newPin2: "",
newPin2Again: "",
expectedError: {
name: "emMmiError",
additionalInformation: null
}
},
// Test passing mismatched newPin2.
{
pin2: "0000",
newPin2: "0000",
newPin2Again: "1111",
expectedError: {
name: "emMmiErrorMismatchPin",
additionalInformation: null
}
},
// Test passing invalid pin2 (< 4 digit).
{
pin2: "123",
newPin2: "0000",
newPin2Again: "0000",
expectedError: {
name: "emMmiErrorInvalidPin",
additionalInformation: null
}
},
// Test passing invalid newPin2 (> 8 digit).
{
pin2: "0000",
newPin2: "123456789",
newPin2Again: "123456789",
expectedError: {
name: "emMmiErrorInvalidPin",
additionalInformation: null
}
},
// Test passing valid pin2 and newPin2. But currently emulator doesn't support
// REQUEST_CHANGE_SIM_PIN2, so we expect to get a 'RequestNotSupported' error
// here.
{
pin2: "0000",
newPin2: "0000",
newPin2Again: "0000",
expectedError: {
name: "RequestNotSupported",
additionalInformation: null
}
},
];
function testChangePin2(aPin2, aNewPin2, aNewPin2Again, aExpectedError) {
let MMI_CODE = "**042*" + aPin2 + "*" + aNewPin2 + "*" + aNewPin2Again + "#";
log("Test " + MMI_CODE);
return gSendMMI(MMI_CODE).then(aResult => {
is(aResult.success, !aExpectedError, "check success");
is(aResult.serviceCode, "scPin2", "Check service code");
if (aResult.success) {
is(aResult.statusMessage, "smPin2Changed", "Check status message");
is(aResult.additionalInformation, undefined, "Check additional information");
} else {
is(aResult.statusMessage, aExpectedError.name, "Check name");
is(aResult.additionalInformation, aExpectedError.additionalInformation,
"Check additional information");
}
});
}
// Start test
startTest(function() {
let promise = Promise.resolve();
for (let i = 0; i < TEST_DATA.length; i++) {
let data = TEST_DATA[i];
promise = promise.then(() => testChangePin2(data.pin2,
data.newPin2,
data.newPin2Again,
data.expectedError));
}
return promise
.catch(error => ok(false, "Promise reject: " + error))
.then(finish);
});

Просмотреть файл

@ -0,0 +1,42 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = "head.js";
const TEST_DATA = [
// [mmi, expectedError]
// Currently emulator doesn't support REQUEST_QUERY_CLIP, so we expect to
// get a 'RequestNotSupported' error here.
["*#30#", "RequestNotSupported"],
// Unsupported CLIP MMI code.
["*30#", "emMmiErrorNotSupported"],
["#30#", "emMmiErrorNotSupported"],
["**30#", "emMmiErrorNotSupported"],
["##30#", "emMmiErrorNotSupported"],
];
function testCLIP(aMmi, aExpectedError) {
log("Test " + aMmi + " ...");
return gSendMMI(aMmi).then(aResult => {
// Since emulator doesn't support clip, so we expect the result is always
// failed.
ok(!aResult.success, "Check success");
is(aResult.serviceCode, "scClip", "Check serviceCode");
is(aResult.statusMessage, aExpectedError, "Check statusMessage");
});
}
// Start test
startTest(function() {
let promise = Promise.resolve();
TEST_DATA.forEach(function(aData) {
promise = promise.then(() => testCLIP(aData[0], aData[1]));
});
return promise
.catch(aError => ok(false, "Promise reject: " + aError))
.then(finish);
});

Просмотреть файл

@ -0,0 +1,44 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = "head.js";
const TEST_DATA = [
// [mmi, expectedError]
// Currently emulator doesn't support REQUEST_GET_CLIR, so we expect to get a
// 'RequestNotSupported' error here.
["*#31#", "RequestNotSupported"],
// Currently emulator doesn't support REQUEST_SET_CLIR, so we expect to get a
// 'RequestNotSupported' error here.
["*31#", "RequestNotSupported"],
["#31#", "RequestNotSupported"],
// Unsupported CLIR MMI code.
["**31#", "emMmiErrorNotSupported"],
["##31#", "emMmiErrorNotSupported"],
];
function testCLIR(aMmi, aExpectedError) {
log("Test " + aMmi + " ...");
return gSendMMI(aMmi).then(aResult => {
// Since emulator doesn't support clip, so we expect the result is always
// failed.
ok(!aResult.success, "Check success");
is(aResult.serviceCode, "scClir", "Check serviceCode");
is(aResult.statusMessage, aExpectedError, "Check statusMessage");
});
}
// Start test
startTest(function() {
let promise = Promise.resolve();
TEST_DATA.forEach(function(aData) {
promise = promise.then(() => testCLIR(aData[0], aData[1]));
});
return promise
.catch(aError => ok(false, "Promise reject: " + aError))
.then(finish);
});

Просмотреть файл

@ -0,0 +1,44 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = "head.js";
function sendUnlockPuk2Mmi(aPuk2, aNewPin2, aNewPin2Again) {
let MMI_CODE = "**052*" + aPuk2 + "*" + aNewPin2 + "*" + aNewPin2Again + "#";
log("Test " + MMI_CODE);
return gSendMMI(MMI_CODE);
}
function testUnlockPuk2MmiError(aPuk2, aNewPin2, aNewPin2Again, aErrorName) {
return sendUnlockPuk2Mmi(aPuk2, aNewPin2, aNewPin2Again)
.then((aResult) => {
ok(!aResult.success, "Check success");
is(aResult.serviceCode, "scPuk2", "Check service code");
is(aResult.statusMessage, aErrorName, "Check statusMessage");
is(aResult.additionalInformation, null, "Check additional information");
});
}
// Start test
startTest(function() {
return Promise.resolve()
// Test passing no puk2.
.then(() => testUnlockPuk2MmiError("", "1111", "2222", "emMmiError"))
// Test passing no newPin2.
.then(() => testUnlockPuk2MmiError("11111111", "", "", "emMmiError"))
// Test passing mismatched newPin2.
.then(() => testUnlockPuk2MmiError("11111111", "1111", "2222",
"emMmiErrorMismatchPin"))
// Test passing invalid puk2 (> 8 digit).
.then(() => testUnlockPuk2MmiError("123456789", "0000", "0000",
"emMmiErrorInvalidPin"))
// Test passing valid puk2 and newPin2. But currently emulator doesn't
// support RIL_REQUEST_ENTER_SIM_PUK2, so we expect to get a
// 'RequestNotSupported' error here.
.then(() => testUnlockPuk2MmiError("11111111", "0000", "0000",
"RequestNotSupported"))
.catch(error => ok(false, "Promise reject: " + error))
.then(finish);
});

Просмотреть файл

@ -0,0 +1,25 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = "head.js";
function testUSSD() {
log("Test *#1234# ...");
return gSendMMI("*#1234#").then(aResult => {
// Since emulator doesn't support sending USSD, so we expect the result is
// always failed.
ok(!aResult.success, "Check success");
is(aResult.serviceCode, "scUssd", "Check serviceCode");
is(aResult.statusMessage, "RequestNotSupported", "Check statusMessage");
is(aResult.additionalInformation, undefined, "No additional information");
});
}
// Start test
startTest(function() {
return testUSSD()
.catch(error => ok(false, "Promise reject: " + error))
.then(finish);
});

Просмотреть файл

@ -1,7 +1,8 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
* http://creativecommons.org/publicdomain/zero/1.0/ */
subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
let TS = {};
subscriptLoader.loadSubScript("resource://gre/components/TelephonyService.js", TS);
let NS = {};
subscriptLoader.loadSubScript("resource://gre/modules/DialNumberUtils.jsm", NS);
@ -50,7 +51,7 @@ add_test(function test_parseMMI_USSD() {
let mmi = parseMMI("*123#");
equal(mmi.fullMMI, "*123#");
equal(mmi.procedure, MMI_PROCEDURE_ACTIVATION);
equal(mmi.procedure, TS.MMI_PROCEDURE_ACTIVATION);
equal(mmi.serviceCode, "123");
equal(mmi.sia, undefined);
equal(mmi.sib, undefined);
@ -73,7 +74,7 @@ add_test(function test_parseMMI_sia() {
let mmi = parseMMI("*123*1#");
equal(mmi.fullMMI, "*123*1#");
equal(mmi.procedure, MMI_PROCEDURE_ACTIVATION);
equal(mmi.procedure, TS.MMI_PROCEDURE_ACTIVATION);
equal(mmi.serviceCode, "123");
equal(mmi.sia, "1");
equal(mmi.sib, undefined);
@ -88,7 +89,7 @@ add_test(function test_parseMMI_sib() {
let mmi = parseMMI("*123**1#");
equal(mmi.fullMMI, "*123**1#");
equal(mmi.procedure, MMI_PROCEDURE_ACTIVATION);
equal(mmi.procedure, TS.MMI_PROCEDURE_ACTIVATION);
equal(mmi.serviceCode, "123");
equal(mmi.sia, "");
equal(mmi.sib, "1");
@ -103,7 +104,7 @@ add_test(function test_parseMMI_sic() {
let mmi = parseMMI("*123***1#");
equal(mmi.fullMMI, "*123***1#");
equal(mmi.procedure, MMI_PROCEDURE_ACTIVATION);
equal(mmi.procedure, TS.MMI_PROCEDURE_ACTIVATION);
equal(mmi.serviceCode, "123");
equal(mmi.sia, "");
equal(mmi.sib, "");
@ -118,7 +119,7 @@ add_test(function test_parseMMI_sia_sib() {
let mmi = parseMMI("*123*1*1#");
equal(mmi.fullMMI, "*123*1*1#");
equal(mmi.procedure, MMI_PROCEDURE_ACTIVATION);
equal(mmi.procedure, TS.MMI_PROCEDURE_ACTIVATION);
equal(mmi.serviceCode, "123");
equal(mmi.sia, "1");
equal(mmi.sib, "1");
@ -133,7 +134,7 @@ add_test(function test_parseMMI_sia_sic() {
let mmi = parseMMI("*123*1**1#");
equal(mmi.fullMMI, "*123*1**1#");
equal(mmi.procedure, MMI_PROCEDURE_ACTIVATION);
equal(mmi.procedure, TS.MMI_PROCEDURE_ACTIVATION);
equal(mmi.serviceCode, "123");
equal(mmi.sia, "1");
equal(mmi.sib, "");
@ -148,7 +149,7 @@ add_test(function test_parseMMI_sib_sic() {
let mmi = parseMMI("*123**1*1#");
equal(mmi.fullMMI, "*123**1*1#");
equal(mmi.procedure, MMI_PROCEDURE_ACTIVATION);
equal(mmi.procedure, TS.MMI_PROCEDURE_ACTIVATION);
equal(mmi.serviceCode, "123");
equal(mmi.sia, "");
equal(mmi.sib, "1");
@ -163,7 +164,7 @@ add_test(function test_parseMMI_pwd() {
let mmi = parseMMI("*123****1#");
equal(mmi.fullMMI, "*123****1#");
equal(mmi.procedure, MMI_PROCEDURE_ACTIVATION);
equal(mmi.procedure, TS.MMI_PROCEDURE_ACTIVATION);
equal(mmi.serviceCode, "123");
equal(mmi.sia, "");
equal(mmi.sib, "");
@ -178,7 +179,7 @@ add_test(function test_parseMMI_dial_number() {
let mmi = parseMMI("*123#345");
equal(mmi.fullMMI, "*123#");
equal(mmi.procedure, MMI_PROCEDURE_ACTIVATION);
equal(mmi.procedure, TS.MMI_PROCEDURE_ACTIVATION);
equal(mmi.serviceCode, "123");
equal(mmi.sia, undefined);
equal(mmi.sib, undefined);
@ -198,7 +199,7 @@ add_test(function test_parseMMI_activation() {
let mmi = parseMMI("*00*12*34*56#");
equal(mmi.fullMMI, "*00*12*34*56#");
equal(mmi.procedure, MMI_PROCEDURE_ACTIVATION);
equal(mmi.procedure, TS.MMI_PROCEDURE_ACTIVATION);
equal(mmi.serviceCode, "00");
equal(mmi.sia, "12");
equal(mmi.sib, "34");
@ -213,7 +214,7 @@ add_test(function test_parseMMI_deactivation() {
let mmi = parseMMI("#00*12*34*56#");
equal(mmi.fullMMI, "#00*12*34*56#");
equal(mmi.procedure, MMI_PROCEDURE_DEACTIVATION);
equal(mmi.procedure, TS.MMI_PROCEDURE_DEACTIVATION);
equal(mmi.serviceCode, "00");
equal(mmi.sia, "12");
equal(mmi.sib, "34");
@ -228,7 +229,7 @@ add_test(function test_parseMMI_interrogation() {
let mmi = parseMMI("*#00*12*34*56#");
equal(mmi.fullMMI, "*#00*12*34*56#");
equal(mmi.procedure, MMI_PROCEDURE_INTERROGATION);
equal(mmi.procedure, TS.MMI_PROCEDURE_INTERROGATION);
equal(mmi.serviceCode, "00");
equal(mmi.sia, "12");
equal(mmi.sib, "34");
@ -243,7 +244,7 @@ add_test(function test_parseMMI_registration() {
let mmi = parseMMI("**00*12*34*56#");
equal(mmi.fullMMI, "**00*12*34*56#");
equal(mmi.procedure, MMI_PROCEDURE_REGISTRATION);
equal(mmi.procedure, TS.MMI_PROCEDURE_REGISTRATION);
equal(mmi.serviceCode, "00");
equal(mmi.sia, "12");
equal(mmi.sib, "34");
@ -258,7 +259,7 @@ add_test(function test_parseMMI_erasure() {
let mmi = parseMMI("##00*12*34*56#");
equal(mmi.fullMMI, "##00*12*34*56#");
equal(mmi.procedure, MMI_PROCEDURE_ERASURE);
equal(mmi.procedure, TS.MMI_PROCEDURE_ERASURE);
equal(mmi.serviceCode, "00");
equal(mmi.sia, "12");
equal(mmi.sib, "34");

Просмотреть файл

@ -5,13 +5,22 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ipc/Ril.h"
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netdb.h> // For gethostbyname.
#include "jsfriendapi.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/workers/Workers.h"
#include "mozilla/ipc/RilSocket.h"
#include "mozilla/ipc/RilSocketConsumer.h"
#include "nsThreadUtils.h" // For NS_IsMainThread.
#include "RilConnector.h"
#ifdef CHROMIUM_LOG
#undef CHROMIUM_LOG
#endif
#if defined(MOZ_WIDGET_GONK)
#include <android/log.h>
#define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk", args)
@ -19,189 +28,95 @@
#define CHROMIUM_LOG(args...) printf(args);
#endif
#include "jsfriendapi.h"
#include "mozilla/ArrayUtils.h"
#include "nsTArray.h"
#include "nsThreadUtils.h" // For NS_IsMainThread.
#include "RilConnector.h"
namespace mozilla {
namespace ipc {
USING_WORKERS_NAMESPACE
using namespace mozilla::ipc;
USING_WORKERS_NAMESPACE;
using namespace JS;
namespace {
class RilConsumer;
static const char RIL_SOCKET_NAME[] = "/dev/socket/rilproxy";
static nsTArray<nsAutoPtr<mozilla::ipc::RilConsumer>> sRilConsumers;
static nsTArray<nsAutoPtr<RilConsumer>> sRilConsumers;
class ConnectWorkerToRIL final : public WorkerTask
//
// RilConsumer
//
class RilConsumer final : public RilSocketConsumer
{
public:
bool RunTask(JSContext* aCx) override;
};
RilConsumer();
class SendRilSocketDataTask final : public nsRunnable
{
public:
SendRilSocketDataTask(unsigned long aClientId,
UnixSocketRawData* aRawData)
: mRawData(aRawData)
, mClientId(aClientId)
{ }
nsresult ConnectWorkerToRIL(JSContext* aCx);
NS_IMETHOD Run() override
{
MOZ_ASSERT(NS_IsMainThread());
nsresult Register(unsigned long aClientId,
WorkerCrossThreadDispatcher* aDispatcher);
void Unregister();
if (sRilConsumers.Length() <= mClientId || !sRilConsumers[mClientId]) {
// Probably shutting down.
delete mRawData;
return NS_OK;
}
// Methods for |RilSocketConsumer|
//
sRilConsumers[mClientId]->Send(mRawData);
return NS_OK;
}
void ReceiveSocketData(JSContext* aCx,
int aIndex,
nsAutoPtr<UnixSocketBuffer>& aBuffer) override;
void OnConnectSuccess(int aIndex) override;
void OnConnectError(int aIndex) override;
void OnDisconnect(int aIndex) override;
protected:
static bool PostRILMessage(JSContext* aCx, unsigned aArgc, Value* aVp);
nsresult Send(JSContext* aCx, const CallArgs& aArgs);
nsresult Receive(JSContext* aCx,
uint32_t aClientId,
const UnixSocketBuffer* aBuffer);
void Close();
private:
UnixSocketRawData* mRawData;
unsigned long mClientId;
nsRefPtr<RilSocket> mSocket;
nsCString mAddress;
bool mShutdown;
};
static bool
PostToRIL(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
{
JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
NS_ASSERTION(!NS_IsMainThread(), "Expecting to be on the worker thread");
RilConsumer::RilConsumer()
: mShutdown(false)
{ }
if (args.length() != 2) {
JS_ReportError(aCx, "Expecting two arguments with the RIL message");
return false;
}
int clientId = args[0].toInt32();
JS::Value v = args[1];
UnixSocketRawData* raw = nullptr;
if (v.isString()) {
JSAutoByteString abs;
JS::Rooted<JSString*> str(aCx, v.toString());
if (!abs.encodeUtf8(aCx, str)) {
return false;
}
raw = new UnixSocketRawData(abs.ptr(), abs.length());
} else if (!v.isPrimitive()) {
JSObject* obj = v.toObjectOrNull();
if (!JS_IsTypedArrayObject(obj)) {
JS_ReportError(aCx, "Object passed in wasn't a typed array");
return false;
}
uint32_t type = JS_GetArrayBufferViewType(obj);
if (type != js::Scalar::Int8 &&
type != js::Scalar::Uint8 &&
type != js::Scalar::Uint8Clamped) {
JS_ReportError(aCx, "Typed array data is not octets");
return false;
}
JS::AutoCheckCannotGC nogc;
size_t size = JS_GetTypedArrayByteLength(obj);
void* data = JS_GetArrayBufferViewData(obj, nogc);
raw = new UnixSocketRawData(data, size);
} else {
JS_ReportError(
aCx, "Incorrect argument. Expecting a string or a typed array");
return false;
}
if (!raw) {
JS_ReportError(aCx, "Unable to post to RIL");
return false;
}
nsRefPtr<SendRilSocketDataTask> task = new SendRilSocketDataTask(clientId,
raw);
NS_DispatchToMainThread(task);
return true;
}
bool
ConnectWorkerToRIL::RunTask(JSContext* aCx)
nsresult
RilConsumer::ConnectWorkerToRIL(JSContext* aCx)
{
// Set up the postRILMessage on the function for worker -> RIL thread
// communication.
NS_ASSERTION(!NS_IsMainThread(), "Expecting to be on the worker thread");
NS_ASSERTION(!JS_IsRunning(aCx), "Are we being called somehow?");
JS::Rooted<JSObject*> workerGlobal(aCx, JS::CurrentGlobalOrNull(aCx));
Rooted<JSObject*> workerGlobal(aCx, CurrentGlobalOrNull(aCx));
// Check whether |postRILMessage| has been defined. No one but this class
// should ever define |postRILMessage| in a RIL worker.
JS::Rooted<JS::Value> val(aCx);
Rooted<Value> val(aCx);
if (!JS_GetProperty(aCx, workerGlobal, "postRILMessage", &val)) {
JS_ReportPendingException(aCx);
return false;
return NS_ERROR_FAILURE;
}
// Make sure that |postRILMessage| is a function.
if (JSTYPE_FUNCTION == JS_TypeOfValue(aCx, val)) {
return true;
return NS_OK;
}
return !!JS_DefineFunction(aCx, workerGlobal, "postRILMessage",
PostToRIL, 2, 0);
JSFunction* postRILMessage = JS_DefineFunction(aCx, workerGlobal,
"postRILMessage",
PostRILMessage, 2, 0);
if (NS_WARN_IF(!postRILMessage)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
class DispatchRILEvent final : public WorkerTask
{
public:
DispatchRILEvent(unsigned long aClient, UnixSocketBuffer* aBuffer)
: mClientId(aClient)
, mBuffer(aBuffer)
{ }
bool RunTask(JSContext* aCx) override;
private:
unsigned long mClientId;
nsAutoPtr<UnixSocketBuffer> mBuffer;
};
bool
DispatchRILEvent::RunTask(JSContext* aCx)
{
JS::Rooted<JSObject*> obj(aCx, JS::CurrentGlobalOrNull(aCx));
JS::Rooted<JSObject*> array(aCx,
JS_NewUint8Array(aCx, mBuffer->GetSize()));
if (!array) {
return false;
}
{
JS::AutoCheckCannotGC nogc;
memcpy(JS_GetArrayBufferViewData(array, nogc),
mBuffer->GetData(), mBuffer->GetSize());
}
JS::AutoValueArray<2> args(aCx);
args[0].setNumber((uint32_t)mClientId);
args[1].setObject(*array);
JS::Rooted<JS::Value> rval(aCx);
return JS_CallFunctionName(aCx, obj, "onRILMessage", args, &rval);
}
} // namespace
namespace mozilla {
namespace ipc {
RilConsumer::RilConsumer(unsigned long aClientId,
WorkerCrossThreadDispatcher* aDispatcher)
: mDispatcher(aDispatcher)
, mShutdown(false)
nsresult
RilConsumer::Register(unsigned long aClientId,
WorkerCrossThreadDispatcher* aDispatcher)
{
// Only append client id after RIL_SOCKET_NAME when it's not connected to
// the first(0) rilproxy for compatibility.
@ -214,60 +129,131 @@ RilConsumer::RilConsumer(unsigned long aClientId,
mAddress = addr_un.sun_path;
}
mSocket = new StreamSocket(this, aClientId);
mSocket->Connect(new RilConnector(mAddress, aClientId));
}
mSocket = new RilSocket(aDispatcher, this, aClientId);
nsresult
RilConsumer::Register(unsigned int aClientId,
WorkerCrossThreadDispatcher* aDispatcher)
{
MOZ_ASSERT(NS_IsMainThread());
sRilConsumers.EnsureLengthAtLeast(aClientId + 1);
if (sRilConsumers[aClientId]) {
NS_WARNING("RilConsumer already registered");
return NS_ERROR_FAILURE;
nsresult rv = mSocket->Connect(new RilConnector(mAddress, aClientId));
if (NS_FAILED(rv)) {
return rv;
}
nsRefPtr<ConnectWorkerToRIL> connection = new ConnectWorkerToRIL();
if (!aDispatcher->PostTask(connection)) {
NS_WARNING("Failed to connect worker to ril");
return NS_ERROR_UNEXPECTED;
}
// Now that we're set up, connect ourselves to the RIL thread.
sRilConsumers[aClientId] = new RilConsumer(aClientId, aDispatcher);
return NS_OK;
}
void
RilConsumer::Shutdown()
RilConsumer::Unregister()
{
MOZ_ASSERT(NS_IsMainThread());
for (unsigned long i = 0; i < sRilConsumers.Length(); i++) {
nsAutoPtr<RilConsumer> instance(sRilConsumers[i]);
if (!instance) {
continue;
}
instance->mShutdown = true;
instance->Close();
instance = nullptr;
}
mShutdown = true;
Close();
}
void
RilConsumer::Send(UnixSocketRawData* aRawData)
bool
RilConsumer::PostRILMessage(JSContext* aCx, unsigned aArgc, Value* aVp)
{
if (!mSocket || mSocket->GetConnectionStatus() != SOCKET_CONNECTED) {
// Probably shutting down.
delete aRawData;
return;
CallArgs args = CallArgsFromVp(aArgc, aVp);
if (args.length() != 2) {
JS_ReportError(aCx, "Expecting two arguments with the RIL message");
return false;
}
mSocket->SendSocketData(aRawData);
int clientId = args[0].toInt32();
if ((ssize_t)sRilConsumers.Length() <= clientId || !sRilConsumers[clientId]) {
// Probably shutting down.
return true;
}
nsresult rv = sRilConsumers[clientId]->Send(aCx, args);
if (NS_FAILED(rv)) {
return false;
}
return true;
}
nsresult
RilConsumer::Send(JSContext* aCx, const CallArgs& aArgs)
{
if (NS_WARN_IF(!mSocket) ||
NS_WARN_IF(mSocket->GetConnectionStatus() == SOCKET_DISCONNECTED)) {
// Probably shutting down.
return NS_OK;
}
nsAutoPtr<UnixSocketRawData> raw;
Value v = aArgs[1];
if (v.isString()) {
JSAutoByteString abs;
Rooted<JSString*> str(aCx, v.toString());
if (!abs.encodeUtf8(aCx, str)) {
return NS_ERROR_FAILURE;
}
raw = new UnixSocketRawData(abs.ptr(), abs.length());
} else if (!v.isPrimitive()) {
JSObject* obj = v.toObjectOrNull();
if (!JS_IsTypedArrayObject(obj)) {
JS_ReportError(aCx, "Object passed in wasn't a typed array");
return NS_ERROR_FAILURE;
}
uint32_t type = JS_GetArrayBufferViewType(obj);
if (type != js::Scalar::Int8 &&
type != js::Scalar::Uint8 &&
type != js::Scalar::Uint8Clamped) {
JS_ReportError(aCx, "Typed array data is not octets");
return NS_ERROR_FAILURE;
}
AutoCheckCannotGC nogc;
size_t size = JS_GetTypedArrayByteLength(obj);
void* data = JS_GetArrayBufferViewData(obj, nogc);
raw = new UnixSocketRawData(data, size);
} else {
JS_ReportError(
aCx, "Incorrect argument. Expecting a string or a typed array");
return NS_ERROR_FAILURE;
}
if (!raw) {
JS_ReportError(aCx, "Unable to post to RIL");
return NS_ERROR_FAILURE;
}
mSocket->SendSocketData(raw.forget());
return NS_OK;
}
nsresult
RilConsumer::Receive(JSContext* aCx,
uint32_t aClientId,
const UnixSocketBuffer* aBuffer)
{
MOZ_ASSERT(aBuffer);
Rooted<JSObject*> obj(aCx, CurrentGlobalOrNull(aCx));
Rooted<JSObject*> array(aCx, JS_NewUint8Array(aCx, aBuffer->GetSize()));
if (NS_WARN_IF(!array)) {
return NS_ERROR_FAILURE;
}
{
AutoCheckCannotGC nogc;
memcpy(JS_GetArrayBufferViewData(array, nogc),
aBuffer->GetData(), aBuffer->GetSize());
}
AutoValueArray<2> args(aCx);
args[0].setNumber(aClientId);
args[1].setObject(*array);
Rooted<Value> rval(aCx);
JS_CallFunctionName(aCx, obj, "onRILMessage", args, &rval);
return NS_OK;
}
void
@ -279,16 +265,14 @@ RilConsumer::Close()
}
}
// |StreamSocketConnector|
// |RilSocketConnector|
void
RilConsumer::ReceiveSocketData(int aIndex,
RilConsumer::ReceiveSocketData(JSContext* aCx,
int aIndex,
nsAutoPtr<UnixSocketBuffer>& aBuffer)
{
MOZ_ASSERT(NS_IsMainThread());
nsRefPtr<DispatchRILEvent> dre(new DispatchRILEvent(aIndex, aBuffer.forget()));
mDispatcher->PostTask(dre);
Receive(aCx, (uint32_t)aIndex, aBuffer);
}
void
@ -316,5 +300,140 @@ RilConsumer::OnDisconnect(int aIndex)
mSocket->GetSuggestedConnectDelayMs());
}
//
// RilWorker
//
nsTArray<nsAutoPtr<RilWorker>> RilWorker::sRilWorkers;
nsresult
RilWorker::Register(unsigned int aClientId,
WorkerCrossThreadDispatcher* aDispatcher)
{
MOZ_ASSERT(NS_IsMainThread());
sRilWorkers.EnsureLengthAtLeast(aClientId + 1);
if (sRilWorkers[aClientId]) {
NS_WARNING("RilWorkers already registered");
return NS_ERROR_FAILURE;
}
// Now that we're set up, connect ourselves to the RIL thread.
sRilWorkers[aClientId] = new RilWorker(aDispatcher);
nsresult rv = sRilWorkers[aClientId]->RegisterConsumer(aClientId);
if (NS_FAILED(rv)) {
return rv;
}
return NS_OK;
}
void
RilWorker::Shutdown()
{
MOZ_ASSERT(NS_IsMainThread());
for (size_t i = 0; i < sRilWorkers.Length(); ++i) {
if (!sRilWorkers[i]) {
continue;
}
sRilWorkers[i]->UnregisterConsumer(i);
sRilWorkers[i] = nullptr;
}
}
RilWorker::RilWorker(WorkerCrossThreadDispatcher* aDispatcher)
: mDispatcher(aDispatcher)
{
MOZ_ASSERT(mDispatcher);
}
class RilWorker::RegisterConsumerTask : public WorkerTask
{
public:
RegisterConsumerTask(unsigned int aClientId,
WorkerCrossThreadDispatcher* aDispatcher)
: mClientId(aClientId)
, mDispatcher(aDispatcher)
{
MOZ_ASSERT(mDispatcher);
}
bool RunTask(JSContext* aCx) override
{
sRilConsumers.EnsureLengthAtLeast(mClientId + 1);
MOZ_ASSERT(!sRilConsumers[mClientId]);
nsAutoPtr<RilConsumer> rilConsumer(new RilConsumer());
nsresult rv = rilConsumer->ConnectWorkerToRIL(aCx);
if (NS_FAILED(rv)) {
return false;
}
rv = rilConsumer->Register(mClientId, mDispatcher);
if (NS_FAILED(rv)) {
return false;
}
sRilConsumers[mClientId] = rilConsumer;
return true;
}
private:
unsigned int mClientId;
nsRefPtr<WorkerCrossThreadDispatcher> mDispatcher;
};
nsresult
RilWorker::RegisterConsumer(unsigned int aClientId)
{
nsRefPtr<RegisterConsumerTask> task = new RegisterConsumerTask(aClientId,
mDispatcher);
if (!mDispatcher->PostTask(task)) {
NS_WARNING("Failed to post register-consumer task.");
return NS_ERROR_UNEXPECTED;
}
return NS_OK;
}
class RilWorker::UnregisterConsumerTask : public WorkerTask
{
public:
UnregisterConsumerTask(unsigned int aClientId)
: mClientId(aClientId)
{ }
bool RunTask(JSContext* aCx) override
{
MOZ_ASSERT(mClientId < sRilConsumers.Length());
MOZ_ASSERT(sRilConsumers[mClientId]);
sRilConsumers[mClientId]->Unregister();
sRilConsumers[mClientId] = nullptr;
return true;
}
private:
unsigned int mClientId;
};
void
RilWorker::UnregisterConsumer(unsigned int aClientId)
{
nsRefPtr<UnregisterConsumerTask> task =
new UnregisterConsumerTask(aClientId);
if (!mDispatcher->PostTask(task)) {
NS_WARNING("Failed to post unregister-consumer task.");
return;
}
}
} // namespace ipc
} // namespace mozilla

Просмотреть файл

@ -7,42 +7,45 @@
#ifndef mozilla_ipc_Ril_h
#define mozilla_ipc_Ril_h 1
#include <mozilla/dom/workers/Workers.h>
#include <mozilla/ipc/StreamSocket.h>
#include <mozilla/ipc/StreamSocketConsumer.h>
#include "nsAutoPtr.h"
#include "nsError.h"
#include "nsTArray.h"
namespace mozilla {
namespace dom {
namespace workers {
class WorkerCrossThreadDispatcher;
} // namespace workers
} // namespace dom
namespace ipc {
class RilConsumer final : public StreamSocketConsumer
class RilConsumer;
class RilWorker final
{
public:
static nsresult Register(
unsigned int aClientId,
mozilla::dom::workers::WorkerCrossThreadDispatcher* aDispatcher);
static void Shutdown();
void Send(UnixSocketRawData* aRawData);
private:
RilConsumer(unsigned long aClientId,
mozilla::dom::workers::WorkerCrossThreadDispatcher* aDispatcher);
class RegisterConsumerTask;
class UnregisterConsumerTask;
void Close();
RilWorker(mozilla::dom::workers::WorkerCrossThreadDispatcher* aDispatcher);
// Methods for |StreamSocketConsumer|
//
nsresult RegisterConsumer(unsigned int aClientId);
void UnregisterConsumer(unsigned int aClientId);
void ReceiveSocketData(int aIndex,
nsAutoPtr<UnixSocketBuffer>& aBuffer) override;
void OnConnectSuccess(int aIndex) override;
void OnConnectError(int aIndex) override;
void OnDisconnect(int aIndex) override;
static nsTArray<nsAutoPtr<RilWorker>> sRilWorkers;
nsRefPtr<StreamSocket> mSocket;
nsRefPtr<mozilla::dom::workers::WorkerCrossThreadDispatcher> mDispatcher;
nsCString mAddress;
bool mShutdown;
};
} // namespace ipc

433
ipc/ril/RilSocket.cpp Normal file
Просмотреть файл

@ -0,0 +1,433 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RilSocket.h"
#include <fcntl.h>
#include "mozilla/dom/workers/Workers.h"
#include "mozilla/ipc/UnixSocketConnector.h"
#include "mozilla/RefPtr.h"
#include "nsXULAppAPI.h"
#include "RilSocketConsumer.h"
static const size_t MAX_READ_SIZE = 1 << 16;
namespace mozilla {
namespace ipc {
USING_WORKERS_NAMESPACE
//
// RilSocketIO
//
class RilSocketIO final : public ConnectionOrientedSocketIO
{
public:
class ConnectTask;
class DelayedConnectTask;
class ReceiveTask;
RilSocketIO(WorkerCrossThreadDispatcher* aDispatcher,
MessageLoop* aConsumerLoop,
MessageLoop* aIOLoop,
RilSocket* aRilSocket,
UnixSocketConnector* aConnector);
~RilSocketIO();
RilSocket* GetRilSocket();
DataSocket* GetDataSocket();
// Delayed-task handling
//
void SetDelayedConnectTask(CancelableTask* aTask);
void ClearDelayedConnectTask();
void CancelDelayedConnectTask();
// Methods for |DataSocket|
//
nsresult QueryReceiveBuffer(UnixSocketIOBuffer** aBuffer) override;
void ConsumeBuffer() override;
void DiscardBuffer() override;
// Methods for |SocketIOBase|
//
SocketBase* GetSocketBase() override;
bool IsShutdownOnConsumerThread() const override;
bool IsShutdownOnIOThread() const override;
void ShutdownOnConsumerThread() override;
void ShutdownOnIOThread() override;
private:
/**
* Cross-thread dispatcher for the RIL worker
*/
nsRefPtr<WorkerCrossThreadDispatcher> mDispatcher;
/**
* Consumer pointer. Non-thread safe RefPtr, so should only be manipulated
* directly from consumer thread. All non-consumer-thread accesses should
* happen with mIO as container.
*/
RefPtr<RilSocket> mRilSocket;
/**
* If true, do not requeue whatever task we're running
*/
bool mShuttingDownOnIOThread;
/**
* Task member for delayed connect task. Should only be access on consumer
* thread.
*/
CancelableTask* mDelayedConnectTask;
/**
* I/O buffer for received data
*/
nsAutoPtr<UnixSocketRawData> mBuffer;
};
RilSocketIO::RilSocketIO(WorkerCrossThreadDispatcher* aDispatcher,
MessageLoop* aConsumerLoop,
MessageLoop* aIOLoop,
RilSocket* aRilSocket,
UnixSocketConnector* aConnector)
: ConnectionOrientedSocketIO(aConsumerLoop, aIOLoop, aConnector)
, mDispatcher(aDispatcher)
, mRilSocket(aRilSocket)
, mShuttingDownOnIOThread(false)
, mDelayedConnectTask(nullptr)
{
MOZ_ASSERT(mDispatcher);
MOZ_ASSERT(mRilSocket);
}
RilSocketIO::~RilSocketIO()
{
MOZ_ASSERT(IsConsumerThread());
MOZ_ASSERT(IsShutdownOnConsumerThread());
}
RilSocket*
RilSocketIO::GetRilSocket()
{
return mRilSocket.get();
}
DataSocket*
RilSocketIO::GetDataSocket()
{
return mRilSocket.get();
}
void
RilSocketIO::SetDelayedConnectTask(CancelableTask* aTask)
{
MOZ_ASSERT(IsConsumerThread());
mDelayedConnectTask = aTask;
}
void
RilSocketIO::ClearDelayedConnectTask()
{
MOZ_ASSERT(IsConsumerThread());
mDelayedConnectTask = nullptr;
}
void
RilSocketIO::CancelDelayedConnectTask()
{
MOZ_ASSERT(IsConsumerThread());
if (!mDelayedConnectTask) {
return;
}
mDelayedConnectTask->Cancel();
ClearDelayedConnectTask();
}
// |DataSocketIO|
nsresult
RilSocketIO::QueryReceiveBuffer(UnixSocketIOBuffer** aBuffer)
{
MOZ_ASSERT(aBuffer);
if (!mBuffer) {
mBuffer = new UnixSocketRawData(MAX_READ_SIZE);
}
*aBuffer = mBuffer.get();
return NS_OK;
}
/**
* |ReceiveTask| transfers data received on the I/O thread
* to an instance of |RilSocket| on the consumer thread.
*/
class RilSocketIO::ReceiveTask final : public WorkerTask
{
public:
ReceiveTask(RilSocketIO* aIO, UnixSocketBuffer* aBuffer)
: mIO(aIO)
, mBuffer(aBuffer)
{
MOZ_ASSERT(mIO);
}
bool RunTask(JSContext* aCx) override
{
// Dispatched via WCTD, but still needs to run on the consumer thread
MOZ_ASSERT(mIO->IsConsumerThread());
if (NS_WARN_IF(mIO->IsShutdownOnConsumerThread())) {
// Since we've already explicitly closed and the close
// happened before this, this isn't really an error.
return true;
}
RilSocket* rilSocket = mIO->GetRilSocket();
MOZ_ASSERT(rilSocket);
rilSocket->ReceiveSocketData(aCx, mBuffer);
return true;
}
private:
RilSocketIO* mIO;
nsAutoPtr<UnixSocketBuffer> mBuffer;
};
void
RilSocketIO::ConsumeBuffer()
{
nsRefPtr<ReceiveTask> task = new ReceiveTask(this, mBuffer.forget());
NS_WARN_IF(!mDispatcher->PostTask(task));
}
void
RilSocketIO::DiscardBuffer()
{
// Nothing to do.
}
// |SocketIOBase|
SocketBase*
RilSocketIO::GetSocketBase()
{
return GetDataSocket();
}
bool
RilSocketIO::IsShutdownOnConsumerThread() const
{
MOZ_ASSERT(IsConsumerThread());
return mRilSocket == nullptr;
}
bool
RilSocketIO::IsShutdownOnIOThread() const
{
return mShuttingDownOnIOThread;
}
void
RilSocketIO::ShutdownOnConsumerThread()
{
MOZ_ASSERT(IsConsumerThread());
MOZ_ASSERT(!IsShutdownOnConsumerThread());
mRilSocket = nullptr;
}
void
RilSocketIO::ShutdownOnIOThread()
{
MOZ_ASSERT(!IsConsumerThread());
MOZ_ASSERT(!mShuttingDownOnIOThread);
Close(); // will also remove fd from I/O loop
mShuttingDownOnIOThread = true;
}
//
// Socket tasks
//
class RilSocketIO::ConnectTask final
: public SocketIOTask<RilSocketIO>
{
public:
ConnectTask(RilSocketIO* aIO)
: SocketIOTask<RilSocketIO>(aIO)
{ }
void Run() override
{
MOZ_ASSERT(!GetIO()->IsConsumerThread());
MOZ_ASSERT(!IsCanceled());
GetIO()->Connect();
}
};
class RilSocketIO::DelayedConnectTask final
: public SocketIOTask<RilSocketIO>
{
public:
DelayedConnectTask(RilSocketIO* aIO)
: SocketIOTask<RilSocketIO>(aIO)
{ }
void Run() override
{
MOZ_ASSERT(GetIO()->IsConsumerThread());
if (IsCanceled()) {
return;
}
RilSocketIO* io = GetIO();
if (io->IsShutdownOnConsumerThread()) {
return;
}
io->ClearDelayedConnectTask();
io->GetIOLoop()->PostTask(FROM_HERE, new ConnectTask(io));
}
};
//
// RilSocket
//
RilSocket::RilSocket(WorkerCrossThreadDispatcher* aDispatcher,
RilSocketConsumer* aConsumer, int aIndex)
: mIO(nullptr)
, mDispatcher(aDispatcher)
, mConsumer(aConsumer)
, mIndex(aIndex)
{
MOZ_ASSERT(mDispatcher);
MOZ_ASSERT(mConsumer);
}
RilSocket::~RilSocket()
{
MOZ_ASSERT(!mIO);
}
void
RilSocket::ReceiveSocketData(JSContext* aCx,
nsAutoPtr<UnixSocketBuffer>& aBuffer)
{
mConsumer->ReceiveSocketData(aCx, mIndex, aBuffer);
}
nsresult
RilSocket::Connect(UnixSocketConnector* aConnector, int aDelayMs,
MessageLoop* aConsumerLoop, MessageLoop* aIOLoop)
{
MOZ_ASSERT(!mIO);
mIO = new RilSocketIO(mDispatcher, aConsumerLoop, aIOLoop, this, aConnector);
SetConnectionStatus(SOCKET_CONNECTING);
if (aDelayMs > 0) {
RilSocketIO::DelayedConnectTask* connectTask =
new RilSocketIO::DelayedConnectTask(mIO);
mIO->SetDelayedConnectTask(connectTask);
MessageLoop::current()->PostDelayedTask(FROM_HERE, connectTask, aDelayMs);
} else {
aIOLoop->PostTask(FROM_HERE, new RilSocketIO::ConnectTask(mIO));
}
return NS_OK;
}
nsresult
RilSocket::Connect(UnixSocketConnector* aConnector, int aDelayMs)
{
return Connect(aConnector, aDelayMs,
MessageLoop::current(), XRE_GetIOMessageLoop());
}
// |ConnectionOrientedSocket|
nsresult
RilSocket::PrepareAccept(UnixSocketConnector* aConnector,
MessageLoop* aConsumerLoop,
MessageLoop* aIOLoop,
ConnectionOrientedSocketIO*& aIO)
{
MOZ_CRASH("|RilSocket| does not support accepting connections.");
}
// |DataSocket|
void
RilSocket::SendSocketData(UnixSocketIOBuffer* aBuffer)
{
MOZ_ASSERT(mIO);
MOZ_ASSERT(mIO->IsConsumerThread());
MOZ_ASSERT(!mIO->IsShutdownOnConsumerThread());
mIO->GetIOLoop()->PostTask(
FROM_HERE,
new SocketIOSendTask<RilSocketIO, UnixSocketIOBuffer>(mIO, aBuffer));
}
// |SocketBase|
void
RilSocket::Close()
{
MOZ_ASSERT(mIO);
MOZ_ASSERT(mIO->IsConsumerThread());
mIO->CancelDelayedConnectTask();
// From this point on, we consider |mIO| as being deleted. We sever
// the relationship here so any future calls to |Connect| will create
// a new I/O object.
mIO->ShutdownOnConsumerThread();
mIO->GetIOLoop()->PostTask(FROM_HERE, new SocketIOShutdownTask(mIO));
mIO = nullptr;
NotifyDisconnect();
}
void
RilSocket::OnConnectSuccess()
{
mConsumer->OnConnectSuccess(mIndex);
}
void
RilSocket::OnConnectError()
{
mConsumer->OnConnectError(mIndex);
}
void
RilSocket::OnDisconnect()
{
mConsumer->OnDisconnect(mIndex);
}
} // namespace ipc
} // namespace mozilla

110
ipc/ril/RilSocket.h Normal file
Просмотреть файл

@ -0,0 +1,110 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ipc_RilSocket_h
#define mozilla_ipc_RilSocket_h
#include "mozilla/ipc/ConnectionOrientedSocket.h"
class JSContext;
class MessageLoop;
namespace mozilla {
namespace dom {
namespace workers {
class WorkerCrossThreadDispatcher;
} // namespace workers
} // namespace dom
} // namespace mozilla
namespace mozilla {
namespace ipc {
class RilSocketConsumer;
class RilSocketIO;
class UnixSocketConnector;
class RilSocket final : public ConnectionOrientedSocket
{
public:
/**
* Constructs an instance of |RilSocket|.
*
* @param aDispatcher The dispatcher class for the received messages.
* @param aConsumer The consumer for the socket.
* @param aIndex An arbitrary index.
*/
RilSocket(mozilla::dom::workers::WorkerCrossThreadDispatcher* aDispatcher,
RilSocketConsumer* aConsumer, int aIndex);
/**
* Method to be called whenever data is received. RIL-worker only.
*
* @param aCx The RIL worker's JS context.
* @param aBuffer Data received from the socket.
*/
void ReceiveSocketData(JSContext* aCx, nsAutoPtr<UnixSocketBuffer>& aBuffer);
/**
* Starts a task on the socket that will try to connect to a socket in a
* non-blocking manner.
*
* @param aConnector Connector object for socket type specific functions
* @param aDelayMs Time delay in milliseconds.
* @param aConsumerLoop The socket's consumer thread.
* @param aIOLoop The socket's I/O thread.
* @return NS_OK on success, or an XPCOM error code otherwise.
*/
nsresult Connect(UnixSocketConnector* aConnector, int aDelayMs,
MessageLoop* aConsumerLoop, MessageLoop* aIOLoop);
/**
* Starts a task on the socket that will try to connect to a socket in a
* non-blocking manner.
*
* @param aConnector Connector object for socket type specific functions
* @param aDelayMs Time delay in milliseconds.
* @return NS_OK on success, or an XPCOM error code otherwise.
*/
nsresult Connect(UnixSocketConnector* aConnector, int aDelayMs = 0);
// Methods for |ConnectionOrientedSocket|
//
nsresult PrepareAccept(UnixSocketConnector* aConnector,
MessageLoop* aConsumerLoop,
MessageLoop* aIOLoop,
ConnectionOrientedSocketIO*& aIO) override;
// Methods for |DataSocket|
//
void SendSocketData(UnixSocketIOBuffer* aBuffer) override;
// Methods for |SocketBase|
//
void Close() override;
void OnConnectSuccess() override;
void OnConnectError() override;
void OnDisconnect() override;
protected:
virtual ~RilSocket();
private:
RilSocketIO* mIO;
nsRefPtr<mozilla::dom::workers::WorkerCrossThreadDispatcher> mDispatcher;
RilSocketConsumer* mConsumer;
int mIndex;
};
} // namespace ipc
} // namepsace mozilla
#endif // mozilla_ipc_RilSocket_h

Просмотреть файл

@ -0,0 +1,20 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RilSocketConsumer.h"
namespace mozilla {
namespace ipc {
//
// RilSocketConsumer
//
RilSocketConsumer::~RilSocketConsumer()
{ }
}
}

Просмотреть файл

@ -0,0 +1,64 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ipc_RilSocketConsumer_h
#define mozilla_ipc_RilSocketConsumer_h
#include "nsAutoPtr.h"
class JSContext;
namespace mozilla {
namespace ipc {
class UnixSocketBuffer;
/**
* |RilSocketConsumer| handles socket events and received data.
*/
class RilSocketConsumer
{
public:
/**
* Method to be called whenever data is received. RIL-worker only.
*
* @param aCx The RIL worker's JS context.
* @param aIndex The index that has been given to the stream socket.
* @param aBuffer Data received from the socket.
*/
virtual void ReceiveSocketData(JSContext* aCx,
int aIndex,
nsAutoPtr<UnixSocketBuffer>& aBuffer) = 0;
/**
* Callback for socket success. Consumer-thread only.
*
* @param aIndex The index that has been given to the stream socket.
*/
virtual void OnConnectSuccess(int aIndex) = 0;
/**
* Callback for socket errors. Consumer-thread only.
*
* @param aIndex The index that has been given to the stream socket.
*/
virtual void OnConnectError(int aIndex) = 0;
/**
* Callback for socket disconnect. Consumer-thread only.
*
* @param aIndex The index that has been given to the stream socket.
*/
virtual void OnDisconnect(int aIndex) = 0;
protected:
virtual ~RilSocketConsumer();
};
}
}
#endif

Просмотреть файл

@ -6,11 +6,15 @@
EXPORTS.mozilla.ipc += [
'Ril.h',
'RilSocket.h',
'RilSocketConsumer.h'
]
SOURCES += [
'Ril.cpp',
'RilConnector.cpp'
'RilConnector.cpp',
'RilSocket.cpp',
'RilSocketConsumer.cpp'
]
include('/ipc/chromium/chromium-config.mozbuild')