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

CLOSED TREE
This commit is contained in:
Ryan VanderMeulen 2014-10-28 16:22:39 -04:00
commit c52190b294
31 changed files with 943 additions and 798 deletions

View File

@ -22,4 +22,7 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please # changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more. # don't change CLOBBER for WebIDL changes any more.
Backout of bug 1087560 needed a CLOBBER Updating CLOBBER for Bug 1084342
There are some refactored files in in dom/bluetooth. Updating CLOBBER to not
leave artifacts from older builds.

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0"> <project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="75e10bb632b1e4a47493d0a66bc32fb74249c57f"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="b48f66220dff75f767eddf28a1d58192fc811410"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/> <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/> <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f718a14ed4963ac99d613b7ba7a997dae7b13d70"/>
<!-- Stock Android things --> <!-- 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/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/> <project groups="linux" 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"/>
@ -113,7 +113,7 @@
<project name="platform/ndk" path="ndk" revision="e58ef003be4306bb53a8c11331146f39e4eab31f"/> <project name="platform/ndk" path="ndk" revision="e58ef003be4306bb53a8c11331146f39e4eab31f"/>
<project name="platform/prebuilts/misc" path="prebuilts/misc" revision="ee724654c72825f8d732ba45caf75ca59e06975d"/> <project name="platform/prebuilts/misc" path="prebuilts/misc" revision="ee724654c72825f8d732ba45caf75ca59e06975d"/>
<project name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="c792f0bd9fff7aea2887c60bbb3a9bbdb534ffa3"/> <project name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="c792f0bd9fff7aea2887c60bbb3a9bbdb534ffa3"/>
<project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="1a982dd6b02b939c75cd116d2d9de97e6ff3de24"/> <project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="c24c8871173bf6aedcf236cab075edf092a7015c"/>
<project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="cfcef469537869947abb9aa1d656774cc2678d4c"/> <project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="cfcef469537869947abb9aa1d656774cc2678d4c"/>
<project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5a48c04c4bb5f079bc757e29864a42427378e051"/> <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5a48c04c4bb5f079bc757e29864a42427378e051"/>
<project name="platform/system/extras" path="system/extras" revision="10e78a05252b3de785f88c2d0b9ea8a428009c50"/> <project name="platform/system/extras" path="system/extras" revision="10e78a05252b3de785f88c2d0b9ea8a428009c50"/>

View File

@ -19,13 +19,13 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="75e10bb632b1e4a47493d0a66bc32fb74249c57f"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="b48f66220dff75f767eddf28a1d58192fc811410"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c058843242068d0df7c107e09da31b53d2e08fa6"/> <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c058843242068d0df7c107e09da31b53d2e08fa6"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f718a14ed4963ac99d613b7ba7a997dae7b13d70"/>
<!-- Stock Android things --> <!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/> <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/> <project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>

View File

@ -17,10 +17,10 @@
</project> </project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="75e10bb632b1e4a47493d0a66bc32fb74249c57f"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="b48f66220dff75f767eddf28a1d58192fc811410"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f718a14ed4963ac99d613b7ba7a997dae7b13d70"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/> <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/> <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things --> <!-- Stock Android things -->

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0"> <project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="75e10bb632b1e4a47493d0a66bc32fb74249c57f"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="b48f66220dff75f767eddf28a1d58192fc811410"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/> <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/> <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f718a14ed4963ac99d613b7ba7a997dae7b13d70"/>
<!-- Stock Android things --> <!-- 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/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/> <project groups="linux" 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"/>
@ -113,7 +113,7 @@
<project name="platform/ndk" path="ndk" revision="cb5519af32ae7b4a9c334913a612462ecd04c5d0"/> <project name="platform/ndk" path="ndk" revision="cb5519af32ae7b4a9c334913a612462ecd04c5d0"/>
<project name="platform/prebuilts/misc" path="prebuilts/misc" revision="99c9a644e84a1b0e0a5d240406753b6bc4caca54"/> <project name="platform/prebuilts/misc" path="prebuilts/misc" revision="99c9a644e84a1b0e0a5d240406753b6bc4caca54"/>
<project name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="6aa61f8557a22039a30b42b7f283996381fd625d"/> <project name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="6aa61f8557a22039a30b42b7f283996381fd625d"/>
<project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="1a982dd6b02b939c75cd116d2d9de97e6ff3de24"/> <project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="c24c8871173bf6aedcf236cab075edf092a7015c"/>
<project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="b562b01c93de9578d5db537b6a602a38e1aaa0ce"/> <project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="b562b01c93de9578d5db537b6a602a38e1aaa0ce"/>
<project name="platform/prebuilts/tools" path="prebuilts/tools" revision="387f03e815f57d536dd922706db1622bddba8d81"/> <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="387f03e815f57d536dd922706db1622bddba8d81"/>
<project name="platform/system/extras" path="system/extras" revision="5356165f67f4a81c2ef28671c13697f1657590df"/> <project name="platform/system/extras" path="system/extras" revision="5356165f67f4a81c2ef28671c13697f1657590df"/>

View File

@ -19,13 +19,13 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="75e10bb632b1e4a47493d0a66bc32fb74249c57f"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="b48f66220dff75f767eddf28a1d58192fc811410"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c058843242068d0df7c107e09da31b53d2e08fa6"/> <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c058843242068d0df7c107e09da31b53d2e08fa6"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f718a14ed4963ac99d613b7ba7a997dae7b13d70"/>
<!-- Stock Android things --> <!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/> <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/> <project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0"> <project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="75e10bb632b1e4a47493d0a66bc32fb74249c57f"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="b48f66220dff75f767eddf28a1d58192fc811410"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/> <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/> <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f718a14ed4963ac99d613b7ba7a997dae7b13d70"/>
<!-- Stock Android things --> <!-- 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/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/> <project groups="linux" 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"/>
@ -113,7 +113,7 @@
<project name="platform/ndk" path="ndk" revision="e58ef003be4306bb53a8c11331146f39e4eab31f"/> <project name="platform/ndk" path="ndk" revision="e58ef003be4306bb53a8c11331146f39e4eab31f"/>
<project name="platform/prebuilts/misc" path="prebuilts/misc" revision="a094aa8f160e211fb4994fdfaaac8a78aa6cc897"/> <project name="platform/prebuilts/misc" path="prebuilts/misc" revision="a094aa8f160e211fb4994fdfaaac8a78aa6cc897"/>
<project name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="c792f0bd9fff7aea2887c60bbb3a9bbdb534ffa3"/> <project name="platform/prebuilts/ndk" path="prebuilts/ndk" revision="c792f0bd9fff7aea2887c60bbb3a9bbdb534ffa3"/>
<project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="1a982dd6b02b939c75cd116d2d9de97e6ff3de24"/> <project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="c24c8871173bf6aedcf236cab075edf092a7015c"/>
<project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="69d524e80cdf3981006627c65ac85f3a871238a3"/> <project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="69d524e80cdf3981006627c65ac85f3a871238a3"/>
<project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5a48c04c4bb5f079bc757e29864a42427378e051"/> <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5a48c04c4bb5f079bc757e29864a42427378e051"/>
<project name="platform/system/extras" path="system/extras" revision="576f57b6510de59c08568b53c0fb60588be8689e"/> <project name="platform/system/extras" path="system/extras" revision="576f57b6510de59c08568b53c0fb60588be8689e"/>

View File

@ -17,10 +17,10 @@
</project> </project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="75e10bb632b1e4a47493d0a66bc32fb74249c57f"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="b48f66220dff75f767eddf28a1d58192fc811410"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f718a14ed4963ac99d613b7ba7a997dae7b13d70"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/> <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/> <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things --> <!-- Stock Android things -->

View File

@ -4,6 +4,6 @@
"remote": "", "remote": "",
"branch": "" "branch": ""
}, },
"revision": "6b4f6119f0e3816af1db5b27a3fa76f8278f77f4", "revision": "f797c345e7f872424ce9fd24f1bd3b769cd6dc9d",
"repo_path": "/integration/gaia-central" "repo_path": "/integration/gaia-central"
} }

View File

@ -17,12 +17,12 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="75e10bb632b1e4a47493d0a66bc32fb74249c57f"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="b48f66220dff75f767eddf28a1d58192fc811410"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f718a14ed4963ac99d613b7ba7a997dae7b13d70"/>
<!-- Stock Android things --> <!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/> <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
<project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/> <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>

View File

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="75e10bb632b1e4a47493d0a66bc32fb74249c57f"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="b48f66220dff75f767eddf28a1d58192fc811410"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -17,10 +17,10 @@
</project> </project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="75e10bb632b1e4a47493d0a66bc32fb74249c57f"/> <project name="gaia" path="gaia" remote="mozillaorg" revision="b48f66220dff75f767eddf28a1d58192fc811410"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f718a14ed4963ac99d613b7ba7a997dae7b13d70"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/> <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/> <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things --> <!-- Stock Android things -->

View File

@ -17,12 +17,12 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="75e10bb632b1e4a47493d0a66bc32fb74249c57f"/> <project name="gaia.git" path="gaia" remote="mozillaorg" revision="b48f66220dff75f767eddf28a1d58192fc811410"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/> <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/> <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="be8b952fde51d8c83748b41ce232f02b2218451d"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f718a14ed4963ac99d613b7ba7a997dae7b13d70"/>
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/> <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
<!-- Stock Android things --> <!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/> <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>

View File

@ -5,10 +5,8 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */ * You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BluetoothSocketHALInterface.h" #include "BluetoothSocketHALInterface.h"
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include "BluetoothHALHelpers.h" #include "BluetoothHALHelpers.h"
#include "BluetoothSocketMessageWatcher.h"
#include "mozilla/FileUtils.h" #include "mozilla/FileUtils.h"
#include "nsClassHashtable.h" #include "nsClassHashtable.h"
#include "nsXULAppAPI.h" #include "nsXULAppAPI.h"
@ -107,294 +105,6 @@ BluetoothSocketHALInterface::Listen(BluetoothSocketType aType,
} }
} }
#define CMSGHDR_CONTAINS_FD(_cmsghdr) \
( ((_cmsghdr)->cmsg_level == SOL_SOCKET) && \
((_cmsghdr)->cmsg_type == SCM_RIGHTS) )
class SocketMessageWatcher;
/* |SocketMessageWatcherWrapper| wraps SocketMessageWatcher to keep it from
* being released by hash table's Remove() method.
*/
class SocketMessageWatcherWrapper
{
public:
SocketMessageWatcherWrapper(SocketMessageWatcher* aSocketMessageWatcher)
: mSocketMessageWatcher(aSocketMessageWatcher)
{
MOZ_ASSERT(mSocketMessageWatcher);
}
SocketMessageWatcher* GetSocketMessageWatcher()
{
return mSocketMessageWatcher;
}
private:
SocketMessageWatcher* mSocketMessageWatcher;
};
/* |sWatcherHashTable| maps result handlers to corresponding watchers */
static nsClassHashtable<nsRefPtrHashKey<BluetoothSocketResultHandler>,
SocketMessageWatcherWrapper>
sWatcherHashtable;
/* |SocketMessageWatcher| receives Bluedroid's socket setup
* messages on the I/O thread. You need to inherit from this
* class to make use of it.
*
* Bluedroid sends two socket info messages (20 bytes) at
* the beginning of a connection to both peers.
*
* - 1st message: [channel:4]
* - 2nd message: [size:2][bd address:6][channel:4][connection status:4]
*
* On the server side, the second message will contain a
* socket file descriptor for the connection. The client
* uses the original file descriptor.
*/
class SocketMessageWatcher : public MessageLoopForIO::Watcher
{
public:
static const unsigned char MSG1_SIZE = 4;
static const unsigned char MSG2_SIZE = 16;
static const unsigned char OFF_CHANNEL1 = 0;
static const unsigned char OFF_SIZE = 4;
static const unsigned char OFF_BDADDRESS = 6;
static const unsigned char OFF_CHANNEL2 = 12;
static const unsigned char OFF_STATUS = 16;
SocketMessageWatcher(int aFd, BluetoothSocketResultHandler* aRes)
: mFd(aFd)
, mClientFd(-1)
, mLen(0)
, mRes(aRes)
{
MOZ_ASSERT(mRes);
}
virtual ~SocketMessageWatcher()
{ }
virtual void Proceed(BluetoothStatus aStatus) = 0;
void OnFileCanReadWithoutBlocking(int aFd) MOZ_OVERRIDE
{
BluetoothStatus status;
switch (mLen) {
case 0:
status = RecvMsg1();
break;
case MSG1_SIZE:
status = RecvMsg2();
break;
default:
/* message-size error */
status = STATUS_FAIL;
break;
}
if (IsComplete() || status != STATUS_SUCCESS) {
StopWatching();
Proceed(status);
}
}
void OnFileCanWriteWithoutBlocking(int aFd) MOZ_OVERRIDE
{ }
void Watch()
{
// add this watcher and its result handler to hash table
sWatcherHashtable.Put(mRes, new SocketMessageWatcherWrapper(this));
MessageLoopForIO::current()->WatchFileDescriptor(
mFd,
true,
MessageLoopForIO::WATCH_READ,
&mWatcher,
this);
}
void StopWatching()
{
mWatcher.StopWatchingFileDescriptor();
// remove this watcher and its result handler from hash table
sWatcherHashtable.Remove(mRes);
}
bool IsComplete() const
{
return mLen == (MSG1_SIZE + MSG2_SIZE);
}
int GetFd() const
{
return mFd;
}
int32_t GetChannel1() const
{
return ReadInt32(OFF_CHANNEL1);
}
int32_t GetSize() const
{
return ReadInt16(OFF_SIZE);
}
nsString GetBdAddress() const
{
nsString bdAddress;
ReadBdAddress(OFF_BDADDRESS, bdAddress);
return bdAddress;
}
int32_t GetChannel2() const
{
return ReadInt32(OFF_CHANNEL2);
}
int32_t GetConnectionStatus() const
{
return ReadInt32(OFF_STATUS);
}
int GetClientFd() const
{
return mClientFd;
}
BluetoothSocketResultHandler* GetResultHandler() const
{
return mRes;
}
private:
BluetoothStatus RecvMsg1()
{
struct iovec iv;
memset(&iv, 0, sizeof(iv));
iv.iov_base = mBuf;
iv.iov_len = MSG1_SIZE;
struct msghdr msg;
memset(&msg, 0, sizeof(msg));
msg.msg_iov = &iv;
msg.msg_iovlen = 1;
ssize_t res = TEMP_FAILURE_RETRY(recvmsg(mFd, &msg, MSG_NOSIGNAL));
if (res <= 0) {
return STATUS_FAIL;
}
mLen += res;
return STATUS_SUCCESS;
}
BluetoothStatus RecvMsg2()
{
struct iovec iv;
memset(&iv, 0, sizeof(iv));
iv.iov_base = mBuf + MSG1_SIZE;
iv.iov_len = MSG2_SIZE;
struct msghdr msg;
struct cmsghdr cmsgbuf[2 * sizeof(cmsghdr) + 0x100];
memset(&msg, 0, sizeof(msg));
msg.msg_iov = &iv;
msg.msg_iovlen = 1;
msg.msg_control = cmsgbuf;
msg.msg_controllen = sizeof(cmsgbuf);
ssize_t res = TEMP_FAILURE_RETRY(recvmsg(mFd, &msg, MSG_NOSIGNAL));
if (res <= 0) {
return STATUS_FAIL;
}
mLen += res;
if (msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) {
return STATUS_FAIL;
}
struct cmsghdr *cmsgptr = CMSG_FIRSTHDR(&msg);
// Extract client fd from message header
for (; cmsgptr; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
if (CMSGHDR_CONTAINS_FD(cmsgptr)) {
// if multiple file descriptors have been sent, we close
// all but the final one.
if (mClientFd != -1) {
TEMP_FAILURE_RETRY(close(mClientFd));
}
// retrieve sent client fd
mClientFd = *(static_cast<int*>(CMSG_DATA(cmsgptr)));
}
}
return STATUS_SUCCESS;
}
int16_t ReadInt16(unsigned long aOffset) const
{
/* little-endian buffer */
return (static_cast<int16_t>(mBuf[aOffset + 1]) << 8) |
static_cast<int16_t>(mBuf[aOffset]);
}
int32_t ReadInt32(unsigned long aOffset) const
{
/* little-endian buffer */
return (static_cast<int32_t>(mBuf[aOffset + 3]) << 24) |
(static_cast<int32_t>(mBuf[aOffset + 2]) << 16) |
(static_cast<int32_t>(mBuf[aOffset + 1]) << 8) |
static_cast<int32_t>(mBuf[aOffset]);
}
void ReadBdAddress(unsigned long aOffset, nsAString& aBdAddress) const
{
const bt_bdaddr_t* bdAddress =
reinterpret_cast<const bt_bdaddr_t*>(mBuf+aOffset);
if (NS_FAILED(Convert(*bdAddress, aBdAddress))) {
aBdAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE);
}
}
MessageLoopForIO::FileDescriptorWatcher mWatcher;
int mFd;
int mClientFd;
unsigned char mLen;
uint8_t mBuf[MSG1_SIZE + MSG2_SIZE];
nsRefPtr<BluetoothSocketResultHandler> mRes;
};
/* |SocketMessageWatcherTask| starts a SocketMessageWatcher
* on the I/O task
*/
class SocketMessageWatcherTask MOZ_FINAL : public Task
{
public:
SocketMessageWatcherTask(SocketMessageWatcher* aWatcher)
: mWatcher(aWatcher)
{
MOZ_ASSERT(mWatcher);
}
void Run() MOZ_OVERRIDE
{
mWatcher->Watch();
}
private:
SocketMessageWatcher* mWatcher;
};
/* |DeleteTask| deletes a class instance on the I/O thread /* |DeleteTask| deletes a class instance on the I/O thread
*/ */
template <typename T> template <typename T>
@ -419,11 +129,12 @@ private:
* Bluedroid and forwarding the connected socket to the * Bluedroid and forwarding the connected socket to the
* resource handler. * resource handler.
*/ */
class ConnectWatcher MOZ_FINAL : public SocketMessageWatcher class BluetoothSocketHALInterface::ConnectWatcher MOZ_FINAL
: public SocketMessageWatcher
{ {
public: public:
ConnectWatcher(int aFd, BluetoothSocketResultHandler* aRes) ConnectWatcher(int aFd, BluetoothSocketResultHandler* aRes)
: SocketMessageWatcher(aFd, aRes) : SocketMessageWatcher(aFd, aRes)
{ } { }
void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE
@ -477,11 +188,12 @@ BluetoothSocketHALInterface::Connect(const nsAString& aBdAddr,
* connection, Bluedroid sends the 2nd message with the socket * connection, Bluedroid sends the 2nd message with the socket
* info and socket file descriptor. * info and socket file descriptor.
*/ */
class AcceptWatcher MOZ_FINAL : public SocketMessageWatcher class BluetoothSocketHALInterface::AcceptWatcher MOZ_FINAL
: public SocketMessageWatcher
{ {
public: public:
AcceptWatcher(int aFd, BluetoothSocketResultHandler* aRes) AcceptWatcher(int aFd, BluetoothSocketResultHandler* aRes)
: SocketMessageWatcher(aFd, aRes) : SocketMessageWatcher(aFd, aRes)
{ } { }
void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE
@ -508,36 +220,6 @@ BluetoothSocketHALInterface::Accept(int aFd,
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t); XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
} }
/* |DeleteSocketMessageWatcherTask| deletes a watching SocketMessageWatcher
* on the I/O task
*/
class DeleteSocketMessageWatcherTask MOZ_FINAL : public Task
{
public:
DeleteSocketMessageWatcherTask(BluetoothSocketResultHandler* aRes)
: mRes(aRes)
{
MOZ_ASSERT(mRes);
}
void Run() MOZ_OVERRIDE
{
// look up hash table for the watcher corresponding to |mRes|
SocketMessageWatcherWrapper* wrapper = sWatcherHashtable.Get(mRes);
if (!wrapper) {
return;
}
// stop the watcher if it exists
SocketMessageWatcher* watcher = wrapper->GetSocketMessageWatcher();
watcher->StopWatching();
watcher->Proceed(STATUS_DONE);
}
private:
BluetoothSocketResultHandler* mRes;
};
void void
BluetoothSocketHALInterface::Close(BluetoothSocketResultHandler* aRes) BluetoothSocketHALInterface::Close(BluetoothSocketResultHandler* aRes)
{ {

View File

@ -20,6 +20,9 @@ class BluetoothSocketHALInterface MOZ_FINAL
: public BluetoothSocketInterface : public BluetoothSocketInterface
{ {
public: public:
class ConnectWatcher;
class AcceptWatcher;
friend class BluetoothHALInterface; friend class BluetoothHALInterface;
void Listen(BluetoothSocketType aType, void Listen(BluetoothSocketType aType,

View File

@ -0,0 +1,325 @@
/* -*- 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 "BluetoothSocketMessageWatcher.h"
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include "BluetoothInterface.h"
#include "nsClassHashtable.h"
BEGIN_BLUETOOTH_NAMESPACE
//
// SocketMessageWatcherWrapper
//
/* |SocketMessageWatcherWrapper| wraps SocketMessageWatcher to keep it from
* being released by hash table's Remove() method.
*/
class SocketMessageWatcherWrapper
{
public:
SocketMessageWatcherWrapper(SocketMessageWatcher* aSocketMessageWatcher)
: mSocketMessageWatcher(aSocketMessageWatcher)
{
MOZ_ASSERT(mSocketMessageWatcher);
}
SocketMessageWatcher* GetSocketMessageWatcher()
{
return mSocketMessageWatcher;
}
private:
SocketMessageWatcher* mSocketMessageWatcher;
};
/* |sWatcherHashTable| maps result handlers to corresponding watchers */
static nsClassHashtable<nsRefPtrHashKey<BluetoothSocketResultHandler>,
SocketMessageWatcherWrapper>
sWatcherHashtable;
//
// SocketMessageWatcher
//
SocketMessageWatcher::SocketMessageWatcher(
int aFd, BluetoothSocketResultHandler* aRes)
: mFd(aFd)
, mClientFd(-1)
, mLen(0)
, mRes(aRes)
{
MOZ_ASSERT(mRes);
}
SocketMessageWatcher::~SocketMessageWatcher()
{ }
void
SocketMessageWatcher::OnFileCanReadWithoutBlocking(int aFd)
{
BluetoothStatus status;
switch (mLen) {
case 0:
status = RecvMsg1();
break;
case MSG1_SIZE:
status = RecvMsg2();
break;
default:
/* message-size error */
status = STATUS_FAIL;
break;
}
if (IsComplete() || status != STATUS_SUCCESS) {
StopWatching();
Proceed(status);
}
}
void
SocketMessageWatcher::OnFileCanWriteWithoutBlocking(int aFd)
{ }
void
SocketMessageWatcher::Watch()
{
// add this watcher and its result handler to hash table
sWatcherHashtable.Put(mRes, new SocketMessageWatcherWrapper(this));
MessageLoopForIO::current()->WatchFileDescriptor(
mFd,
true,
MessageLoopForIO::WATCH_READ,
&mWatcher,
this);
}
void
SocketMessageWatcher::StopWatching()
{
mWatcher.StopWatchingFileDescriptor();
// remove this watcher and its result handler from hash table
sWatcherHashtable.Remove(mRes);
}
bool
SocketMessageWatcher::IsComplete() const
{
return mLen == (MSG1_SIZE + MSG2_SIZE);
}
int
SocketMessageWatcher::GetFd() const
{
return mFd;
}
int32_t
SocketMessageWatcher::GetChannel1() const
{
return ReadInt32(OFF_CHANNEL1);
}
int32_t
SocketMessageWatcher::GetSize() const
{
return ReadInt16(OFF_SIZE);
}
nsString
SocketMessageWatcher::GetBdAddress() const
{
nsString bdAddress;
ReadBdAddress(OFF_BDADDRESS, bdAddress);
return bdAddress;
}
int32_t
SocketMessageWatcher::GetChannel2() const
{
return ReadInt32(OFF_CHANNEL2);
}
int32_t
SocketMessageWatcher::GetConnectionStatus() const
{
return ReadInt32(OFF_STATUS);
}
int
SocketMessageWatcher::GetClientFd() const
{
return mClientFd;
}
BluetoothSocketResultHandler*
SocketMessageWatcher::GetResultHandler() const
{
return mRes;
}
BluetoothStatus
SocketMessageWatcher::RecvMsg1()
{
struct iovec iv;
memset(&iv, 0, sizeof(iv));
iv.iov_base = mBuf;
iv.iov_len = MSG1_SIZE;
struct msghdr msg;
memset(&msg, 0, sizeof(msg));
msg.msg_iov = &iv;
msg.msg_iovlen = 1;
ssize_t res = TEMP_FAILURE_RETRY(recvmsg(mFd, &msg, MSG_NOSIGNAL));
if (res <= 0) {
return STATUS_FAIL;
}
mLen += res;
return STATUS_SUCCESS;
}
#define CMSGHDR_CONTAINS_FD(_cmsghdr) \
( ((_cmsghdr)->cmsg_level == SOL_SOCKET) && \
((_cmsghdr)->cmsg_type == SCM_RIGHTS) )
BluetoothStatus
SocketMessageWatcher::RecvMsg2()
{
struct iovec iv;
memset(&iv, 0, sizeof(iv));
iv.iov_base = mBuf + MSG1_SIZE;
iv.iov_len = MSG2_SIZE;
struct msghdr msg;
struct cmsghdr cmsgbuf[CMSG_SPACE(sizeof(int))];
memset(&msg, 0, sizeof(msg));
msg.msg_iov = &iv;
msg.msg_iovlen = 1;
msg.msg_control = cmsgbuf;
msg.msg_controllen = sizeof(cmsgbuf);
ssize_t res = TEMP_FAILURE_RETRY(recvmsg(mFd, &msg, MSG_NOSIGNAL));
if (res <= 0) {
return STATUS_FAIL;
}
mLen += res;
if (msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) {
return STATUS_FAIL;
}
struct cmsghdr *cmsgptr = CMSG_FIRSTHDR(&msg);
// Extract client fd from message header
for (; cmsgptr; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
if (CMSGHDR_CONTAINS_FD(cmsgptr)) {
// if multiple file descriptors have been sent, we close
// all but the final one.
if (mClientFd != -1) {
TEMP_FAILURE_RETRY(close(mClientFd));
}
// retrieve sent client fd
memcpy(&mClientFd, CMSG_DATA(cmsgptr), sizeof(mClientFd));
}
}
return STATUS_SUCCESS;
}
int16_t
SocketMessageWatcher::ReadInt16(unsigned long aOffset) const
{
/* little-endian buffer */
return (static_cast<int16_t>(mBuf[aOffset + 1]) << 8) |
static_cast<int16_t>(mBuf[aOffset]);
}
int32_t
SocketMessageWatcher::ReadInt32(unsigned long aOffset) const
{
/* little-endian buffer */
return (static_cast<int32_t>(mBuf[aOffset + 3]) << 24) |
(static_cast<int32_t>(mBuf[aOffset + 2]) << 16) |
(static_cast<int32_t>(mBuf[aOffset + 1]) << 8) |
static_cast<int32_t>(mBuf[aOffset]);
}
void
SocketMessageWatcher::ReadBdAddress(unsigned long aOffset,
nsAString& aBdAddress) const
{
char str[BLUETOOTH_ADDRESS_LENGTH + 1];
int res = snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
static_cast<int>(mBuf[aOffset + 0]),
static_cast<int>(mBuf[aOffset + 1]),
static_cast<int>(mBuf[aOffset + 2]),
static_cast<int>(mBuf[aOffset + 3]),
static_cast<int>(mBuf[aOffset + 4]),
static_cast<int>(mBuf[aOffset + 5]));
if (res < 0) {
aBdAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE);
} else if ((size_t)res >= sizeof(str)) { /* string buffer too small */
aBdAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE);
} else {
aBdAddress = NS_ConvertUTF8toUTF16(str);
}
}
//
// SocketMessageWatcherTask
//
SocketMessageWatcherTask::SocketMessageWatcherTask(
SocketMessageWatcher* aWatcher)
: mWatcher(aWatcher)
{
MOZ_ASSERT(mWatcher);
}
void
SocketMessageWatcherTask::Run()
{
mWatcher->Watch();
}
//
// DeleteSocketMessageWatcherTask
//
DeleteSocketMessageWatcherTask::DeleteSocketMessageWatcherTask(
BluetoothSocketResultHandler* aRes)
: mRes(aRes)
{
MOZ_ASSERT(mRes);
}
void
DeleteSocketMessageWatcherTask::Run()
{
// look up hash table for the watcher corresponding to |mRes|
SocketMessageWatcherWrapper* wrapper = sWatcherHashtable.Get(mRes);
if (!wrapper) {
return;
}
// stop the watcher if it exists
SocketMessageWatcher* watcher = wrapper->GetSocketMessageWatcher();
watcher->StopWatching();
watcher->Proceed(STATUS_DONE);
}
END_BLUETOOTH_NAMESPACE

View File

@ -0,0 +1,109 @@
/* -*- 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 "base/message_loop.h"
#include "BluetoothCommon.h"
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothSocketResultHandler;
/* |SocketMessageWatcher| receives Bluedroid's socket setup
* messages on the I/O thread. You need to inherit from this
* class to make use of it.
*
* Bluedroid sends two socket info messages (20 bytes) at
* the beginning of a connection to both peers.
*
* - 1st message: [channel:4]
* - 2nd message: [size:2][bd address:6][channel:4][connection status:4]
*
* On the server side, the second message will contain a
* socket file descriptor for the connection. The client
* uses the original file descriptor.
*/
class SocketMessageWatcher : public MessageLoopForIO::Watcher
{
public:
static const unsigned char MSG1_SIZE = 4;
static const unsigned char MSG2_SIZE = 16;
static const unsigned char OFF_CHANNEL1 = 0;
static const unsigned char OFF_SIZE = 4;
static const unsigned char OFF_BDADDRESS = 6;
static const unsigned char OFF_CHANNEL2 = 12;
static const unsigned char OFF_STATUS = 16;
virtual ~SocketMessageWatcher();
virtual void Proceed(BluetoothStatus aStatus) = 0;
void OnFileCanReadWithoutBlocking(int aFd) MOZ_OVERRIDE;
void OnFileCanWriteWithoutBlocking(int aFd) MOZ_OVERRIDE;
void Watch();
void StopWatching();
bool IsComplete() const;
int GetFd() const;
int32_t GetChannel1() const;
int32_t GetSize() const;
nsString GetBdAddress() const;
int32_t GetChannel2() const;
int32_t GetConnectionStatus() const;
int GetClientFd() const;
BluetoothSocketResultHandler* GetResultHandler() const;
protected:
SocketMessageWatcher(int aFd, BluetoothSocketResultHandler* aRes);
private:
BluetoothStatus RecvMsg1();
BluetoothStatus RecvMsg2();
int16_t ReadInt16(unsigned long aOffset) const;
int32_t ReadInt32(unsigned long aOffset) const;
void ReadBdAddress(unsigned long aOffset, nsAString& aBdAddress) const;
MessageLoopForIO::FileDescriptorWatcher mWatcher;
int mFd;
int mClientFd;
unsigned char mLen;
uint8_t mBuf[MSG1_SIZE + MSG2_SIZE];
nsRefPtr<BluetoothSocketResultHandler> mRes;
};
/* |SocketMessageWatcherTask| starts a SocketMessageWatcher
* on the I/O task
*/
class SocketMessageWatcherTask MOZ_FINAL : public Task
{
public:
SocketMessageWatcherTask(SocketMessageWatcher* aWatcher);
void Run() MOZ_OVERRIDE;
private:
SocketMessageWatcher* mWatcher;
};
/* |DeleteSocketMessageWatcherTask| deletes a watching SocketMessageWatcher
* on the I/O task
*/
class DeleteSocketMessageWatcherTask MOZ_FINAL : public Task
{
public:
DeleteSocketMessageWatcherTask(BluetoothSocketResultHandler* aRes);
void Run() MOZ_OVERRIDE;
private:
BluetoothSocketResultHandler* mRes;
};
END_BLUETOOTH_NAMESPACE

View File

@ -55,6 +55,7 @@ if CONFIG['MOZ_B2G_BT']:
'bluedroid/BluetoothServiceBluedroid.cpp', 'bluedroid/BluetoothServiceBluedroid.cpp',
'bluedroid/BluetoothSocket.cpp', 'bluedroid/BluetoothSocket.cpp',
'bluedroid/BluetoothSocketHALInterface.cpp', 'bluedroid/BluetoothSocketHALInterface.cpp',
'bluedroid/BluetoothSocketMessageWatcher.cpp',
'bluedroid/BluetoothUtils.cpp', 'bluedroid/BluetoothUtils.cpp',
] ]
LOCAL_INCLUDES += [ LOCAL_INCLUDES += [

View File

@ -5,10 +5,8 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */ * You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BluetoothSocketHALInterface.h" #include "BluetoothSocketHALInterface.h"
#include <errno.h>
#include <sys/socket.h>
#include <unistd.h>
#include "BluetoothHALHelpers.h" #include "BluetoothHALHelpers.h"
#include "BluetoothSocketMessageWatcher.h"
#include "mozilla/FileUtils.h" #include "mozilla/FileUtils.h"
#include "nsClassHashtable.h" #include "nsClassHashtable.h"
#include "nsXULAppAPI.h" #include "nsXULAppAPI.h"
@ -107,294 +105,6 @@ BluetoothSocketHALInterface::Listen(BluetoothSocketType aType,
} }
} }
#define CMSGHDR_CONTAINS_FD(_cmsghdr) \
( ((_cmsghdr)->cmsg_level == SOL_SOCKET) && \
((_cmsghdr)->cmsg_type == SCM_RIGHTS) )
class SocketMessageWatcher;
/* |SocketMessageWatcherWrapper| wraps SocketMessageWatcher to keep it from
* being released by hash table's Remove() method.
*/
class SocketMessageWatcherWrapper
{
public:
SocketMessageWatcherWrapper(SocketMessageWatcher* aSocketMessageWatcher)
: mSocketMessageWatcher(aSocketMessageWatcher)
{
MOZ_ASSERT(mSocketMessageWatcher);
}
SocketMessageWatcher* GetSocketMessageWatcher()
{
return mSocketMessageWatcher;
}
private:
SocketMessageWatcher* mSocketMessageWatcher;
};
/* |sWatcherHashTable| maps result handlers to corresponding watchers */
static nsClassHashtable<nsRefPtrHashKey<BluetoothSocketResultHandler>,
SocketMessageWatcherWrapper>
sWatcherHashtable;
/* |SocketMessageWatcher| receives Bluedroid's socket setup
* messages on the I/O thread. You need to inherit from this
* class to make use of it.
*
* Bluedroid sends two socket info messages (20 bytes) at
* the beginning of a connection to both peers.
*
* - 1st message: [channel:4]
* - 2nd message: [size:2][bd address:6][channel:4][connection status:4]
*
* On the server side, the second message will contain a
* socket file descriptor for the connection. The client
* uses the original file descriptor.
*/
class SocketMessageWatcher : public MessageLoopForIO::Watcher
{
public:
static const unsigned char MSG1_SIZE = 4;
static const unsigned char MSG2_SIZE = 16;
static const unsigned char OFF_CHANNEL1 = 0;
static const unsigned char OFF_SIZE = 4;
static const unsigned char OFF_BDADDRESS = 6;
static const unsigned char OFF_CHANNEL2 = 12;
static const unsigned char OFF_STATUS = 16;
SocketMessageWatcher(int aFd, BluetoothSocketResultHandler* aRes)
: mFd(aFd)
, mClientFd(-1)
, mLen(0)
, mRes(aRes)
{
MOZ_ASSERT(mRes);
}
virtual ~SocketMessageWatcher()
{ }
virtual void Proceed(BluetoothStatus aStatus) = 0;
void OnFileCanReadWithoutBlocking(int aFd) MOZ_OVERRIDE
{
BluetoothStatus status;
switch (mLen) {
case 0:
status = RecvMsg1();
break;
case MSG1_SIZE:
status = RecvMsg2();
break;
default:
/* message-size error */
status = STATUS_FAIL;
break;
}
if (IsComplete() || status != STATUS_SUCCESS) {
StopWatching();
Proceed(status);
}
}
void OnFileCanWriteWithoutBlocking(int aFd) MOZ_OVERRIDE
{ }
void Watch()
{
// add this watcher and its result handler to hash table
sWatcherHashtable.Put(mRes, new SocketMessageWatcherWrapper(this));
MessageLoopForIO::current()->WatchFileDescriptor(
mFd,
true,
MessageLoopForIO::WATCH_READ,
&mWatcher,
this);
}
void StopWatching()
{
mWatcher.StopWatchingFileDescriptor();
// remove this watcher and its result handler from hash table
sWatcherHashtable.Remove(mRes);
}
bool IsComplete() const
{
return mLen == (MSG1_SIZE + MSG2_SIZE);
}
int GetFd() const
{
return mFd;
}
int32_t GetChannel1() const
{
return ReadInt32(OFF_CHANNEL1);
}
int32_t GetSize() const
{
return ReadInt16(OFF_SIZE);
}
nsString GetBdAddress() const
{
nsString bdAddress;
ReadBdAddress(OFF_BDADDRESS, bdAddress);
return bdAddress;
}
int32_t GetChannel2() const
{
return ReadInt32(OFF_CHANNEL2);
}
int32_t GetConnectionStatus() const
{
return ReadInt32(OFF_STATUS);
}
int GetClientFd() const
{
return mClientFd;
}
BluetoothSocketResultHandler* GetResultHandler() const
{
return mRes;
}
private:
BluetoothStatus RecvMsg1()
{
struct iovec iv;
memset(&iv, 0, sizeof(iv));
iv.iov_base = mBuf;
iv.iov_len = MSG1_SIZE;
struct msghdr msg;
memset(&msg, 0, sizeof(msg));
msg.msg_iov = &iv;
msg.msg_iovlen = 1;
ssize_t res = TEMP_FAILURE_RETRY(recvmsg(mFd, &msg, MSG_NOSIGNAL));
if (res <= 0) {
return STATUS_FAIL;
}
mLen += res;
return STATUS_SUCCESS;
}
BluetoothStatus RecvMsg2()
{
struct iovec iv;
memset(&iv, 0, sizeof(iv));
iv.iov_base = mBuf + MSG1_SIZE;
iv.iov_len = MSG2_SIZE;
struct msghdr msg;
struct cmsghdr cmsgbuf[2 * sizeof(cmsghdr) + 0x100];
memset(&msg, 0, sizeof(msg));
msg.msg_iov = &iv;
msg.msg_iovlen = 1;
msg.msg_control = cmsgbuf;
msg.msg_controllen = sizeof(cmsgbuf);
ssize_t res = TEMP_FAILURE_RETRY(recvmsg(mFd, &msg, MSG_NOSIGNAL));
if (res <= 0) {
return STATUS_FAIL;
}
mLen += res;
if (msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) {
return STATUS_FAIL;
}
struct cmsghdr *cmsgptr = CMSG_FIRSTHDR(&msg);
// Extract client fd from message header
for (; cmsgptr; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
if (CMSGHDR_CONTAINS_FD(cmsgptr)) {
// if multiple file descriptors have been sent, we close
// all but the final one.
if (mClientFd != -1) {
TEMP_FAILURE_RETRY(close(mClientFd));
}
// retrieve sent client fd
mClientFd = *(static_cast<int*>(CMSG_DATA(cmsgptr)));
}
}
return STATUS_SUCCESS;
}
int16_t ReadInt16(unsigned long aOffset) const
{
/* little-endian buffer */
return (static_cast<int16_t>(mBuf[aOffset + 1]) << 8) |
static_cast<int16_t>(mBuf[aOffset]);
}
int32_t ReadInt32(unsigned long aOffset) const
{
/* little-endian buffer */
return (static_cast<int32_t>(mBuf[aOffset + 3]) << 24) |
(static_cast<int32_t>(mBuf[aOffset + 2]) << 16) |
(static_cast<int32_t>(mBuf[aOffset + 1]) << 8) |
static_cast<int32_t>(mBuf[aOffset]);
}
void ReadBdAddress(unsigned long aOffset, nsAString& aBdAddress) const
{
const bt_bdaddr_t* bdAddress =
reinterpret_cast<const bt_bdaddr_t*>(mBuf+aOffset);
if (NS_FAILED(Convert(*bdAddress, aBdAddress))) {
aBdAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE);
}
}
MessageLoopForIO::FileDescriptorWatcher mWatcher;
int mFd;
int mClientFd;
unsigned char mLen;
uint8_t mBuf[MSG1_SIZE + MSG2_SIZE];
nsRefPtr<BluetoothSocketResultHandler> mRes;
};
/* |SocketMessageWatcherTask| starts a SocketMessageWatcher
* on the I/O task
*/
class SocketMessageWatcherTask MOZ_FINAL : public Task
{
public:
SocketMessageWatcherTask(SocketMessageWatcher* aWatcher)
: mWatcher(aWatcher)
{
MOZ_ASSERT(mWatcher);
}
void Run() MOZ_OVERRIDE
{
mWatcher->Watch();
}
private:
SocketMessageWatcher* mWatcher;
};
/* |DeleteTask| deletes a class instance on the I/O thread /* |DeleteTask| deletes a class instance on the I/O thread
*/ */
template <typename T> template <typename T>
@ -419,11 +129,12 @@ private:
* Bluedroid and forwarding the connected socket to the * Bluedroid and forwarding the connected socket to the
* resource handler. * resource handler.
*/ */
class ConnectWatcher MOZ_FINAL : public SocketMessageWatcher class BluetoothSocketHALInterface::ConnectWatcher MOZ_FINAL
: public SocketMessageWatcher
{ {
public: public:
ConnectWatcher(int aFd, BluetoothSocketResultHandler* aRes) ConnectWatcher(int aFd, BluetoothSocketResultHandler* aRes)
: SocketMessageWatcher(aFd, aRes) : SocketMessageWatcher(aFd, aRes)
{ } { }
void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE
@ -477,11 +188,12 @@ BluetoothSocketHALInterface::Connect(const nsAString& aBdAddr,
* connection, Bluedroid sends the 2nd message with the socket * connection, Bluedroid sends the 2nd message with the socket
* info and socket file descriptor. * info and socket file descriptor.
*/ */
class AcceptWatcher MOZ_FINAL : public SocketMessageWatcher class BluetoothSocketHALInterface::AcceptWatcher MOZ_FINAL
: public SocketMessageWatcher
{ {
public: public:
AcceptWatcher(int aFd, BluetoothSocketResultHandler* aRes) AcceptWatcher(int aFd, BluetoothSocketResultHandler* aRes)
: SocketMessageWatcher(aFd, aRes) : SocketMessageWatcher(aFd, aRes)
{ } { }
void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE
@ -508,36 +220,6 @@ BluetoothSocketHALInterface::Accept(int aFd,
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t); XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
} }
/* |DeleteSocketMessageWatcherTask| deletes a watching SocketMessageWatcher
* on the I/O task
*/
class DeleteSocketMessageWatcherTask MOZ_FINAL : public Task
{
public:
DeleteSocketMessageWatcherTask(BluetoothSocketResultHandler* aRes)
: mRes(aRes)
{
MOZ_ASSERT(mRes);
}
void Run() MOZ_OVERRIDE
{
// look up hash table for the watcher corresponding to |mRes|
SocketMessageWatcherWrapper* wrapper = sWatcherHashtable.Get(mRes);
if (!wrapper) {
return;
}
// stop the watcher if it exists
SocketMessageWatcher* watcher = wrapper->GetSocketMessageWatcher();
watcher->StopWatching();
watcher->Proceed(STATUS_DONE);
}
private:
BluetoothSocketResultHandler* mRes;
};
void void
BluetoothSocketHALInterface::Close(BluetoothSocketResultHandler* aRes) BluetoothSocketHALInterface::Close(BluetoothSocketResultHandler* aRes)
{ {

View File

@ -20,6 +20,9 @@ class BluetoothSocketHALInterface MOZ_FINAL
: public BluetoothSocketInterface : public BluetoothSocketInterface
{ {
public: public:
class ConnectWatcher;
class AcceptWatcher;
friend class BluetoothHALInterface; friend class BluetoothHALInterface;
void Listen(BluetoothSocketType aType, void Listen(BluetoothSocketType aType,

View File

@ -0,0 +1,325 @@
/* -*- 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 "BluetoothSocketMessageWatcher.h"
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include "BluetoothInterface.h"
#include "nsClassHashtable.h"
BEGIN_BLUETOOTH_NAMESPACE
//
// SocketMessageWatcherWrapper
//
/* |SocketMessageWatcherWrapper| wraps SocketMessageWatcher to keep it from
* being released by hash table's Remove() method.
*/
class SocketMessageWatcherWrapper
{
public:
SocketMessageWatcherWrapper(SocketMessageWatcher* aSocketMessageWatcher)
: mSocketMessageWatcher(aSocketMessageWatcher)
{
MOZ_ASSERT(mSocketMessageWatcher);
}
SocketMessageWatcher* GetSocketMessageWatcher()
{
return mSocketMessageWatcher;
}
private:
SocketMessageWatcher* mSocketMessageWatcher;
};
/* |sWatcherHashTable| maps result handlers to corresponding watchers */
static nsClassHashtable<nsRefPtrHashKey<BluetoothSocketResultHandler>,
SocketMessageWatcherWrapper>
sWatcherHashtable;
//
// SocketMessageWatcher
//
SocketMessageWatcher::SocketMessageWatcher(
int aFd, BluetoothSocketResultHandler* aRes)
: mFd(aFd)
, mClientFd(-1)
, mLen(0)
, mRes(aRes)
{
MOZ_ASSERT(mRes);
}
SocketMessageWatcher::~SocketMessageWatcher()
{ }
void
SocketMessageWatcher::OnFileCanReadWithoutBlocking(int aFd)
{
BluetoothStatus status;
switch (mLen) {
case 0:
status = RecvMsg1();
break;
case MSG1_SIZE:
status = RecvMsg2();
break;
default:
/* message-size error */
status = STATUS_FAIL;
break;
}
if (IsComplete() || status != STATUS_SUCCESS) {
StopWatching();
Proceed(status);
}
}
void
SocketMessageWatcher::OnFileCanWriteWithoutBlocking(int aFd)
{ }
void
SocketMessageWatcher::Watch()
{
// add this watcher and its result handler to hash table
sWatcherHashtable.Put(mRes, new SocketMessageWatcherWrapper(this));
MessageLoopForIO::current()->WatchFileDescriptor(
mFd,
true,
MessageLoopForIO::WATCH_READ,
&mWatcher,
this);
}
void
SocketMessageWatcher::StopWatching()
{
mWatcher.StopWatchingFileDescriptor();
// remove this watcher and its result handler from hash table
sWatcherHashtable.Remove(mRes);
}
bool
SocketMessageWatcher::IsComplete() const
{
return mLen == (MSG1_SIZE + MSG2_SIZE);
}
int
SocketMessageWatcher::GetFd() const
{
return mFd;
}
int32_t
SocketMessageWatcher::GetChannel1() const
{
return ReadInt32(OFF_CHANNEL1);
}
int32_t
SocketMessageWatcher::GetSize() const
{
return ReadInt16(OFF_SIZE);
}
nsString
SocketMessageWatcher::GetBdAddress() const
{
nsString bdAddress;
ReadBdAddress(OFF_BDADDRESS, bdAddress);
return bdAddress;
}
int32_t
SocketMessageWatcher::GetChannel2() const
{
return ReadInt32(OFF_CHANNEL2);
}
int32_t
SocketMessageWatcher::GetConnectionStatus() const
{
return ReadInt32(OFF_STATUS);
}
int
SocketMessageWatcher::GetClientFd() const
{
return mClientFd;
}
BluetoothSocketResultHandler*
SocketMessageWatcher::GetResultHandler() const
{
return mRes;
}
BluetoothStatus
SocketMessageWatcher::RecvMsg1()
{
struct iovec iv;
memset(&iv, 0, sizeof(iv));
iv.iov_base = mBuf;
iv.iov_len = MSG1_SIZE;
struct msghdr msg;
memset(&msg, 0, sizeof(msg));
msg.msg_iov = &iv;
msg.msg_iovlen = 1;
ssize_t res = TEMP_FAILURE_RETRY(recvmsg(mFd, &msg, MSG_NOSIGNAL));
if (res <= 0) {
return STATUS_FAIL;
}
mLen += res;
return STATUS_SUCCESS;
}
#define CMSGHDR_CONTAINS_FD(_cmsghdr) \
( ((_cmsghdr)->cmsg_level == SOL_SOCKET) && \
((_cmsghdr)->cmsg_type == SCM_RIGHTS) )
BluetoothStatus
SocketMessageWatcher::RecvMsg2()
{
struct iovec iv;
memset(&iv, 0, sizeof(iv));
iv.iov_base = mBuf + MSG1_SIZE;
iv.iov_len = MSG2_SIZE;
struct msghdr msg;
struct cmsghdr cmsgbuf[CMSG_SPACE(sizeof(int))];
memset(&msg, 0, sizeof(msg));
msg.msg_iov = &iv;
msg.msg_iovlen = 1;
msg.msg_control = cmsgbuf;
msg.msg_controllen = sizeof(cmsgbuf);
ssize_t res = TEMP_FAILURE_RETRY(recvmsg(mFd, &msg, MSG_NOSIGNAL));
if (res <= 0) {
return STATUS_FAIL;
}
mLen += res;
if (msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) {
return STATUS_FAIL;
}
struct cmsghdr *cmsgptr = CMSG_FIRSTHDR(&msg);
// Extract client fd from message header
for (; cmsgptr; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
if (CMSGHDR_CONTAINS_FD(cmsgptr)) {
// if multiple file descriptors have been sent, we close
// all but the final one.
if (mClientFd != -1) {
TEMP_FAILURE_RETRY(close(mClientFd));
}
// retrieve sent client fd
memcpy(&mClientFd, CMSG_DATA(cmsgptr), sizeof(mClientFd));
}
}
return STATUS_SUCCESS;
}
int16_t
SocketMessageWatcher::ReadInt16(unsigned long aOffset) const
{
/* little-endian buffer */
return (static_cast<int16_t>(mBuf[aOffset + 1]) << 8) |
static_cast<int16_t>(mBuf[aOffset]);
}
int32_t
SocketMessageWatcher::ReadInt32(unsigned long aOffset) const
{
/* little-endian buffer */
return (static_cast<int32_t>(mBuf[aOffset + 3]) << 24) |
(static_cast<int32_t>(mBuf[aOffset + 2]) << 16) |
(static_cast<int32_t>(mBuf[aOffset + 1]) << 8) |
static_cast<int32_t>(mBuf[aOffset]);
}
void
SocketMessageWatcher::ReadBdAddress(unsigned long aOffset,
nsAString& aBdAddress) const
{
char str[BLUETOOTH_ADDRESS_LENGTH + 1];
int res = snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
static_cast<int>(mBuf[aOffset + 0]),
static_cast<int>(mBuf[aOffset + 1]),
static_cast<int>(mBuf[aOffset + 2]),
static_cast<int>(mBuf[aOffset + 3]),
static_cast<int>(mBuf[aOffset + 4]),
static_cast<int>(mBuf[aOffset + 5]));
if (res < 0) {
aBdAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE);
} else if ((size_t)res >= sizeof(str)) { /* string buffer too small */
aBdAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE);
} else {
aBdAddress = NS_ConvertUTF8toUTF16(str);
}
}
//
// SocketMessageWatcherTask
//
SocketMessageWatcherTask::SocketMessageWatcherTask(
SocketMessageWatcher* aWatcher)
: mWatcher(aWatcher)
{
MOZ_ASSERT(mWatcher);
}
void
SocketMessageWatcherTask::Run()
{
mWatcher->Watch();
}
//
// DeleteSocketMessageWatcherTask
//
DeleteSocketMessageWatcherTask::DeleteSocketMessageWatcherTask(
BluetoothSocketResultHandler* aRes)
: mRes(aRes)
{
MOZ_ASSERT(mRes);
}
void
DeleteSocketMessageWatcherTask::Run()
{
// look up hash table for the watcher corresponding to |mRes|
SocketMessageWatcherWrapper* wrapper = sWatcherHashtable.Get(mRes);
if (!wrapper) {
return;
}
// stop the watcher if it exists
SocketMessageWatcher* watcher = wrapper->GetSocketMessageWatcher();
watcher->StopWatching();
watcher->Proceed(STATUS_DONE);
}
END_BLUETOOTH_NAMESPACE

View File

@ -0,0 +1,109 @@
/* -*- 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 "base/message_loop.h"
#include "BluetoothCommon.h"
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothSocketResultHandler;
/* |SocketMessageWatcher| receives Bluedroid's socket setup
* messages on the I/O thread. You need to inherit from this
* class to make use of it.
*
* Bluedroid sends two socket info messages (20 bytes) at
* the beginning of a connection to both peers.
*
* - 1st message: [channel:4]
* - 2nd message: [size:2][bd address:6][channel:4][connection status:4]
*
* On the server side, the second message will contain a
* socket file descriptor for the connection. The client
* uses the original file descriptor.
*/
class SocketMessageWatcher : public MessageLoopForIO::Watcher
{
public:
static const unsigned char MSG1_SIZE = 4;
static const unsigned char MSG2_SIZE = 16;
static const unsigned char OFF_CHANNEL1 = 0;
static const unsigned char OFF_SIZE = 4;
static const unsigned char OFF_BDADDRESS = 6;
static const unsigned char OFF_CHANNEL2 = 12;
static const unsigned char OFF_STATUS = 16;
virtual ~SocketMessageWatcher();
virtual void Proceed(BluetoothStatus aStatus) = 0;
void OnFileCanReadWithoutBlocking(int aFd) MOZ_OVERRIDE;
void OnFileCanWriteWithoutBlocking(int aFd) MOZ_OVERRIDE;
void Watch();
void StopWatching();
bool IsComplete() const;
int GetFd() const;
int32_t GetChannel1() const;
int32_t GetSize() const;
nsString GetBdAddress() const;
int32_t GetChannel2() const;
int32_t GetConnectionStatus() const;
int GetClientFd() const;
BluetoothSocketResultHandler* GetResultHandler() const;
protected:
SocketMessageWatcher(int aFd, BluetoothSocketResultHandler* aRes);
private:
BluetoothStatus RecvMsg1();
BluetoothStatus RecvMsg2();
int16_t ReadInt16(unsigned long aOffset) const;
int32_t ReadInt32(unsigned long aOffset) const;
void ReadBdAddress(unsigned long aOffset, nsAString& aBdAddress) const;
MessageLoopForIO::FileDescriptorWatcher mWatcher;
int mFd;
int mClientFd;
unsigned char mLen;
uint8_t mBuf[MSG1_SIZE + MSG2_SIZE];
nsRefPtr<BluetoothSocketResultHandler> mRes;
};
/* |SocketMessageWatcherTask| starts a SocketMessageWatcher
* on the I/O task
*/
class SocketMessageWatcherTask MOZ_FINAL : public Task
{
public:
SocketMessageWatcherTask(SocketMessageWatcher* aWatcher);
void Run() MOZ_OVERRIDE;
private:
SocketMessageWatcher* mWatcher;
};
/* |DeleteSocketMessageWatcherTask| deletes a watching SocketMessageWatcher
* on the I/O task
*/
class DeleteSocketMessageWatcherTask MOZ_FINAL : public Task
{
public:
DeleteSocketMessageWatcherTask(BluetoothSocketResultHandler* aRes);
void Run() MOZ_OVERRIDE;
private:
BluetoothSocketResultHandler* mRes;
};
END_BLUETOOTH_NAMESPACE

View File

@ -60,6 +60,7 @@ if CONFIG['MOZ_B2G_BT']:
'bluedroid/BluetoothServiceBluedroid.cpp', 'bluedroid/BluetoothServiceBluedroid.cpp',
'bluedroid/BluetoothSocket.cpp', 'bluedroid/BluetoothSocket.cpp',
'bluedroid/BluetoothSocketHALInterface.cpp', 'bluedroid/BluetoothSocketHALInterface.cpp',
'bluedroid/BluetoothSocketMessageWatcher.cpp',
'bluedroid/BluetoothUtils.cpp', 'bluedroid/BluetoothUtils.cpp',
] ]
LOCAL_INCLUDES += [ LOCAL_INCLUDES += [

View File

@ -311,6 +311,14 @@ nsDOMCameraManager::GetCamera(const nsAString& aCamera,
} }
nsCOMPtr<nsIPrincipal> principal = sop->GetPrincipal(); nsCOMPtr<nsIPrincipal> principal = sop->GetPrincipal();
// If we are a CERTIFIED app, we can short-circuit the permission check,
// which gets us a performance win.
uint16_t status = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
principal->GetAppStatus(&status);
if (status == nsIPrincipal::APP_STATUS_CERTIFIED && CheckPermission(mWindow)) {
PermissionAllowed(cameraId, aInitialConfig, successCallback, errorCallback, promise);
return promise.forget();
}
nsCOMPtr<nsIRunnable> permissionRequest = nsCOMPtr<nsIRunnable> permissionRequest =
new CameraPermissionRequest(principal, mWindow, this, cameraId, aInitialConfig, new CameraPermissionRequest(principal, mWindow, this, cameraId, aInitialConfig,

View File

@ -337,64 +337,6 @@ Icc::UpdateContact(const JSContext* aCx, const nsAString& aContactType,
return request.forget().downcast<DOMRequest>(); return request.forget().downcast<DOMRequest>();
} }
already_AddRefed<DOMRequest>
Icc::IccOpenChannel(const nsAString& aAid, ErrorResult& aRv)
{
if (!mProvider) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<nsIDOMDOMRequest> request;
nsresult rv = mProvider->IccOpenChannel(mClientId, GetOwner(), aAid,
getter_AddRefs(request));
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return nullptr;
}
return request.forget().downcast<DOMRequest>();
}
already_AddRefed<DOMRequest>
Icc::IccExchangeAPDU(const JSContext* aCx, int32_t aChannel,
JS::Handle<JS::Value> aApdu, ErrorResult& aRv)
{
if (!mProvider) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<nsIDOMDOMRequest> request;
nsresult rv = mProvider->IccExchangeAPDU(mClientId, GetOwner(), aChannel,
aApdu, getter_AddRefs(request));
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return nullptr;
}
return request.forget().downcast<DOMRequest>();
}
already_AddRefed<DOMRequest>
Icc::IccCloseChannel(int32_t aChannel, ErrorResult& aRv)
{
if (!mProvider) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<nsIDOMDOMRequest> request;
nsresult rv = mProvider->IccCloseChannel(mClientId, GetOwner(), aChannel,
getter_AddRefs(request));
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return nullptr;
}
return request.forget().downcast<DOMRequest>();
}
already_AddRefed<DOMRequest> already_AddRefed<DOMRequest>
Icc::MatchMvno(const nsAString& aMvnoType, Icc::MatchMvno(const nsAString& aMvnoType,
const nsAString& aMvnoData, const nsAString& aMvnoData,

View File

@ -99,16 +99,6 @@ public:
JS::Handle<JS::Value> aContact, const nsAString& aPin2, JS::Handle<JS::Value> aContact, const nsAString& aPin2,
ErrorResult& aRv); ErrorResult& aRv);
already_AddRefed<DOMRequest>
IccOpenChannel(const nsAString& aAid, ErrorResult& aRv);
already_AddRefed<DOMRequest>
IccExchangeAPDU(const JSContext* aCx, int32_t aChannel,
JS::Handle<JS::Value> aApdu, ErrorResult& aRv);
already_AddRefed<DOMRequest>
IccCloseChannel(int32_t aChannel, ErrorResult& aRv);
already_AddRefed<DOMRequest> already_AddRefed<DOMRequest>
MatchMvno(const nsAString& aMvnoType, const nsAString& aMatchData, MatchMvno(const nsAString& aMvnoType, const nsAString& aMatchData,
ErrorResult& aRv); ErrorResult& aRv);

View File

@ -172,7 +172,7 @@ cubeb_stream_type ConvertChannelToCubebType(dom::AudioChannel aChannel)
{ {
switch(aChannel) { switch(aChannel) {
case dom::AudioChannel::Normal: case dom::AudioChannel::Normal:
return CUBEB_STREAM_TYPE_SYSTEM; /* FALLTHROUGH */
case dom::AudioChannel::Content: case dom::AudioChannel::Content:
return CUBEB_STREAM_TYPE_MUSIC; return CUBEB_STREAM_TYPE_MUSIC;
case dom::AudioChannel::Notification: case dom::AudioChannel::Notification:

View File

@ -69,12 +69,14 @@ NetUtils::NetUtils()
int32_t NetUtils::do_ifc_enable(const char *ifname) int32_t NetUtils::do_ifc_enable(const char *ifname)
{ {
USE_DLFUNC(ifc_enable) USE_DLFUNC(ifc_enable)
mozilla::MutexAutoLock lock(mIfcMutex);
return ifc_enable(ifname); return ifc_enable(ifname);
} }
int32_t NetUtils::do_ifc_disable(const char *ifname) int32_t NetUtils::do_ifc_disable(const char *ifname)
{ {
USE_DLFUNC(ifc_disable) USE_DLFUNC(ifc_disable)
mozilla::MutexAutoLock lock(mIfcMutex);
return ifc_disable(ifname); return ifc_disable(ifname);
} }

View File

@ -414,58 +414,6 @@ interface MozIcc : EventTarget
any contact, any contact,
optional DOMString? pin2 = null); optional DOMString? pin2 = null);
// Integrated Circuit Card Secure Element Interfaces.
/**
* A secure element is a smart card chip that can hold
* several different applications with the necessary security.
* The most known secure element is the Universal Integrated Circuit Card
* (UICC).
*/
/**
* Send request to open a logical channel defined by its
* application identifier (AID).
*
* @param aid
* The application identifier of the applet to be selected on this
* channel.
*
* @return a DOMRequest.
* The request's result will be an instance of channel (channelID)
* if available or null.
*/
[Throws]
DOMRequest iccOpenChannel(DOMString aid);
/**
* Interface, used to communicate with an applet through the
* application data protocol units (APDUs) and is
* used for all data that is exchanged between the UICC and the terminal (ME).
*
* @param channel
* The application identifier of the applet to which APDU is directed.
* @param apdu
* Application protocol data unit.
*
* @return a DOMRequest.
* The request's result will be response APDU.
*/
[Throws]
DOMRequest iccExchangeAPDU(long channel, any apdu);
/**
* Send request to close the selected logical channel identified by its
* application identifier (AID).
*
* @param aid
* The application identifier of the applet, to be closed.
*
* @return a DOMRequest.
*/
[Throws]
DOMRequest iccCloseChannel(long channel);
// Integrated Circuit Card Helpers. // Integrated Circuit Card Helpers.
/** /**

View File

@ -1330,7 +1330,7 @@ function P2pStateMachine(aP2pCommand, aNetUtil) {
debug('Stop DHCP server result: ' + success); debug('Stop DHCP server result: ' + success);
aP2pCommand.p2pDisable(function(success) { aP2pCommand.p2pDisable(function(success) {
debug('P2P function disabled'); debug('P2P function disabled');
aP2pCommand.closeSupplicantConnection(function (status) { closeSupplicantConnectionIfNeeded(function() {
debug('Supplicant connection closed'); debug('Supplicant connection closed');
gNetworkService.disableInterface(P2P_INTERFACE_NAME, function (success){ gNetworkService.disableInterface(P2P_INTERFACE_NAME, function (success){
debug('Disabled interface: ' + P2P_INTERFACE_NAME); debug('Disabled interface: ' + P2P_INTERFACE_NAME);
@ -1340,6 +1340,15 @@ function P2pStateMachine(aP2pCommand, aNetUtil) {
}); });
}); });
}); });
function closeSupplicantConnectionIfNeeded(callback) {
// No need to connect to supplicant on KK. Call back directly.
if (aP2pCommand.getSdkVersion() >= 19) {
callback();
return;
}
aP2pCommand.closeSupplicantConnection(callback);
}
}, },
handleEvent: function(aEvent) { handleEvent: function(aEvent) {

View File

@ -169,6 +169,9 @@ GonkDiskSpaceWatcher::DoStart()
NS_WARNING("Error calling inotify_init()"); NS_WARNING("Error calling inotify_init()");
if (errno == ENOSYS) { if (errno == ENOSYS) {
NS_WARNING("Warning: No fanotify support in this device's kernel.\n"); NS_WARNING("Warning: No fanotify support in this device's kernel.\n");
#if ANDROID_VERSION >= 19
MOZ_CRASH("Fanotify support must be enabled in the kernel.");
#endif
} }
return; return;
} }