зеркало из https://github.com/mozilla/gecko-dev.git
Merge b2ginbound to m-c a=merge
This commit is contained in:
Коммит
b6e78e87bc
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0645bbed4d6cbd8064652eebafe011edc3e417fd"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="15134b080b5f406e5aa36f5136c17dafb4e31f64"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f2f0cbee2f2517070dd194051d509c07cdacff"/>
|
||||
<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="c7d4045742862a7cf3f0074902ebc7d1b339b0ee"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f4c86a6371082db0be8087b17a31bb79d35fb1d1"/>
|
||||
<!-- 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"/>
|
||||
|
@ -134,8 +134,8 @@
|
|||
<project name="platform/hardware/akm" path="hardware/akm" revision="6d3be412647b0eab0adff8a2768736cf4eb68039"/>
|
||||
<project groups="invensense" name="platform/hardware/invensense" path="hardware/invensense" revision="e6d9ab28b4f4e7684f6c07874ee819c9ea0002a2"/>
|
||||
<project name="platform/hardware/ril" path="hardware/ril" revision="865ce3b4a2ba0b3a31421ca671f4d6c5595f8690"/>
|
||||
<project name="kernel/common" path="kernel" revision="df636d2c31ad4434a7de2565359ad982b3767118"/>
|
||||
<project name="platform/system/core" path="system/core" revision="3747764c63d23de586c56e1cef6dca2cdd90b2ea"/>
|
||||
<project name="kernel/common" path="kernel" revision="65d2a18bd4ab0f1ed36a76c1e3c4f9ae98f345b9"/>
|
||||
<project name="platform/system/core" path="system/core" revision="7992618bd4ee33ce96897675a5c0a9b619122f13"/>
|
||||
<project name="u-boot" path="u-boot" revision="f1502910977ac88f43da7bf9277c3523ad4b0b2f"/>
|
||||
<project name="vendor/sprd/gps" path="vendor/sprd/gps" revision="4c59900937dc2e978b7b14b7f1ea617e3d5d550e"/>
|
||||
<project name="vendor/sprd/open-source" path="vendor/sprd/open-source" revision="e503b1d14d7fdee532b8f391407299da193c1b2d"/>
|
||||
|
|
|
@ -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="0645bbed4d6cbd8064652eebafe011edc3e417fd"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="15134b080b5f406e5aa36f5136c17dafb4e31f64"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f2f0cbee2f2517070dd194051d509c07cdacff"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9a9797062c6001d6346504161c51187a2968466b"/>
|
||||
|
|
|
@ -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="0645bbed4d6cbd8064652eebafe011edc3e417fd"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="15134b080b5f406e5aa36f5136c17dafb4e31f64"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f2f0cbee2f2517070dd194051d509c07cdacff"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="c7d4045742862a7cf3f0074902ebc7d1b339b0ee"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f4c86a6371082db0be8087b17a31bb79d35fb1d1"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -135,7 +135,7 @@
|
|||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c5f8d282efe4a4e8b1e31a37300944e338e60e4f"/>
|
||||
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9f28c4faea3b2f01db227b2467b08aeba96d9bec"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="eb8b8828c412bf8d164ad42a39766becd39f9fb5"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="d82e00fb6380b4f6cea7a96213913ee9eb441239"/>
|
||||
<project name="android-sdk" path="sdk" remote="b2g" revision="8b1365af38c9a653df97349ee53a3f5d64fd590a"/>
|
||||
<project name="darwinstreamingserver" path="system/darwinstreamingserver" remote="b2g" revision="cf85968c7f85e0ec36e72c87ceb4837a943b8af6"/>
|
||||
</manifest>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0645bbed4d6cbd8064652eebafe011edc3e417fd"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="15134b080b5f406e5aa36f5136c17dafb4e31f64"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f2f0cbee2f2517070dd194051d509c07cdacff"/>
|
||||
<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="c7d4045742862a7cf3f0074902ebc7d1b339b0ee"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f4c86a6371082db0be8087b17a31bb79d35fb1d1"/>
|
||||
<!-- 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="6b0721ca0e92788df30daf8f7a5fb2863544f9c8">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0645bbed4d6cbd8064652eebafe011edc3e417fd"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="15134b080b5f406e5aa36f5136c17dafb4e31f64"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f2f0cbee2f2517070dd194051d509c07cdacff"/>
|
||||
<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="c7d4045742862a7cf3f0074902ebc7d1b339b0ee"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f4c86a6371082db0be8087b17a31bb79d35fb1d1"/>
|
||||
<!-- 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="0645bbed4d6cbd8064652eebafe011edc3e417fd"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="15134b080b5f406e5aa36f5136c17dafb4e31f64"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f2f0cbee2f2517070dd194051d509c07cdacff"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9a9797062c6001d6346504161c51187a2968466b"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0645bbed4d6cbd8064652eebafe011edc3e417fd"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="15134b080b5f406e5aa36f5136c17dafb4e31f64"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f2f0cbee2f2517070dd194051d509c07cdacff"/>
|
||||
<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="c7d4045742862a7cf3f0074902ebc7d1b339b0ee"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f4c86a6371082db0be8087b17a31bb79d35fb1d1"/>
|
||||
<!-- 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"/>
|
||||
|
@ -146,7 +146,7 @@
|
|||
<project name="platform/hardware/ril" path="hardware/ril" revision="12b1977cc704b35f2e9db2bb423fa405348bc2f3"/>
|
||||
<project name="platform/system/bluetooth" path="system/bluetooth" revision="985bf15264d865fe7b9c5b45f61c451cbaafa43d"/>
|
||||
<project name="platform/system/core" path="system/core" revision="42839aedcf70bf6bc92a3b7ea4a5cc9bf9aef3f9"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="eb8b8828c412bf8d164ad42a39766becd39f9fb5"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="d82e00fb6380b4f6cea7a96213913ee9eb441239"/>
|
||||
<project name="platform/system/qcom" path="system/qcom" revision="63e3f6f176caad587d42bba4c16b66d953fb23c2"/>
|
||||
<project name="platform/vendor/qcom-opensource/wlan/prima" path="vendor/qcom/opensource/wlan/prima" revision="d8952a42771045fca73ec600e2b42a4c7129d723"/>
|
||||
<project name="platform/vendor/qcom/msm8610" path="device/qcom/msm8610" revision="4c187c1f3a0dffd8e51a961735474ea703535b99"/>
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
</project>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0645bbed4d6cbd8064652eebafe011edc3e417fd"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="15134b080b5f406e5aa36f5136c17dafb4e31f64"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f2f0cbee2f2517070dd194051d509c07cdacff"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="c7d4045742862a7cf3f0074902ebc7d1b339b0ee"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f4c86a6371082db0be8087b17a31bb79d35fb1d1"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -145,7 +145,7 @@
|
|||
<project name="platform/hardware/ril" path="hardware/ril" revision="c4e2ac95907a5519a0e09f01a0d8e27fec101af0"/>
|
||||
<project name="platform/system/bluetooth" path="system/bluetooth" revision="e1eb226fa3ad3874ea7b63c56a9dc7012d7ff3c2"/>
|
||||
<project name="platform/system/core" path="system/core" revision="adc485d8755af6a61641d197de7cfef667722580"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="eb8b8828c412bf8d164ad42a39766becd39f9fb5"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="d82e00fb6380b4f6cea7a96213913ee9eb441239"/>
|
||||
<project name="platform/system/qcom" path="system/qcom" revision="1cdab258b15258b7f9657da70e6f06ebd5a2fc25"/>
|
||||
<project name="platform/vendor/qcom/msm8610" path="device/qcom/msm8610" revision="4ae5df252123591d5b941191790e7abed1bce5a4"/>
|
||||
<project name="platform/vendor/qcom-opensource/wlan/prima" path="vendor/qcom/opensource/wlan/prima" revision="ce18b47b4a4f93a581d672bbd5cb6d12fe796ca9"/>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"git": {
|
||||
"git_revision": "0645bbed4d6cbd8064652eebafe011edc3e417fd",
|
||||
"git_revision": "15134b080b5f406e5aa36f5136c17dafb4e31f64",
|
||||
"remote": "https://git.mozilla.org/releases/gaia.git",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "b8a031b1d0d2dfe6dc33194ec18b25c6f0cd625a",
|
||||
"revision": "457b84a122653f399cb817513b5149c4c087afe9",
|
||||
"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="0645bbed4d6cbd8064652eebafe011edc3e417fd"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="15134b080b5f406e5aa36f5136c17dafb4e31f64"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f2f0cbee2f2517070dd194051d509c07cdacff"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="c7d4045742862a7cf3f0074902ebc7d1b339b0ee"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f4c86a6371082db0be8087b17a31bb79d35fb1d1"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -130,7 +130,7 @@
|
|||
<project name="device-mako" path="device/lge/mako" remote="b2g" revision="78d17f0c117f0c66dd55ee8d5c5dde8ccc93ecba"/>
|
||||
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="3a9a17613cc685aa232432566ad6cc607eab4ec1"/>
|
||||
<project name="device/lge/mako-kernel" path="device/lge/mako-kernel" revision="d1729e53d71d711c8fde25eab8728ff2b9b4df0e"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="eb8b8828c412bf8d164ad42a39766becd39f9fb5"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="d82e00fb6380b4f6cea7a96213913ee9eb441239"/>
|
||||
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/>
|
||||
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
|
||||
<project name="platform/hardware/broadcom/wlan" path="hardware/broadcom/wlan" revision="0e1929fa3aa38bf9d40e9e953d619fab8164c82e"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="6b0721ca0e92788df30daf8f7a5fb2863544f9c8">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0645bbed4d6cbd8064652eebafe011edc3e417fd"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="15134b080b5f406e5aa36f5136c17dafb4e31f64"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f2f0cbee2f2517070dd194051d509c07cdacff"/>
|
||||
<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="c7d4045742862a7cf3f0074902ebc7d1b339b0ee"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="f4c86a6371082db0be8087b17a31bb79d35fb1d1"/>
|
||||
<!-- 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"/>
|
||||
|
@ -156,5 +156,5 @@
|
|||
<project name="platform/hardware/qcom/sensors" path="hardware/qcom/sensors" revision="fde83fdf67e9b919f8a49008725bd595221bf33f"/>
|
||||
<project name="platform/hardware/qcom/wlan" path="hardware/qcom/wlan" revision="6417804bea95f6e46094a01a06025a86e28c5b0d"/>
|
||||
<project name="platform/hardware/ril" path="hardware/ril" revision="e00d716e7e3d31729f75399855b6921e90cb0b66"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="eb8b8828c412bf8d164ad42a39766becd39f9fb5"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="d82e00fb6380b4f6cea7a96213913ee9eb441239"/>
|
||||
</manifest>
|
||||
|
|
|
@ -235,10 +235,16 @@ extern bool gBluetoothDebugFlag;
|
|||
|
||||
/**
|
||||
* When a remote BLE device gets connected / disconnected, we'll dispatch an
|
||||
* event
|
||||
* event.
|
||||
*/
|
||||
#define GATT_CONNECTION_STATE_CHANGED_ID "connectionstatechanged"
|
||||
|
||||
/**
|
||||
* When attributes of BluetoothManager, BluetoothAdapter, or BluetoothDevice
|
||||
* are changed, we'll dispatch an event.
|
||||
*/
|
||||
#define ATTRIBUTE_CHANGED_ID "attributechanged"
|
||||
|
||||
// Bluetooth address format: xx:xx:xx:xx:xx:xx (or xx_xx_xx_xx_xx_xx)
|
||||
#define BLUETOOTH_ADDRESS_LENGTH 17
|
||||
#define BLUETOOTH_ADDRESS_NONE "00:00:00:00:00:00"
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#define mozilla_dom_bluetooth_BluetoothSocketObserver_h
|
||||
|
||||
#include "BluetoothCommon.h"
|
||||
#include "mozilla/ipc/UnixSocket.h"
|
||||
#include "mozilla/ipc/SocketBase.h"
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "BluetoothProfileManagerBase.h"
|
||||
#include "BluetoothSocketObserver.h"
|
||||
#include "DeviceStorage.h"
|
||||
#include "mozilla/ipc/UnixSocket.h"
|
||||
#include "mozilla/ipc/SocketBase.h"
|
||||
#include "nsCOMArray.h"
|
||||
|
||||
class nsIDOMBlob;
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include "BluetoothUtils.h"
|
||||
#include "BluetoothUuid.h"
|
||||
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
||||
#include "mozilla/ipc/UnixSocket.h"
|
||||
#include "mozilla/ipc/SocketBase.h"
|
||||
#include "mozilla/StaticMutex.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/unused.h"
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "BluetoothSocketObserver.h"
|
||||
#include "BluetoothInterface.h"
|
||||
#include "BluetoothUtils.h"
|
||||
#include "mozilla/ipc/UnixSocketWatcher.h"
|
||||
#include "mozilla/FileUtils.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "BluetoothHfpManagerBase.h"
|
||||
#include "BluetoothRilListener.h"
|
||||
#include "BluetoothSocketObserver.h"
|
||||
#include "mozilla/ipc/UnixSocket.h"
|
||||
#include "mozilla/ipc/SocketBase.h"
|
||||
#include "mozilla/Hal.h"
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
||||
#include "mozilla/dom/ipc/BlobChild.h"
|
||||
#include "mozilla/dom/ipc/BlobParent.h"
|
||||
#include "mozilla/ipc/UnixSocket.h"
|
||||
#include "mozilla/ipc/SocketBase.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsISettingsService.h"
|
||||
|
|
|
@ -23,9 +23,6 @@ namespace dom {
|
|||
class BlobChild;
|
||||
class BlobParent;
|
||||
}
|
||||
namespace ipc {
|
||||
class UnixSocketConsumer;
|
||||
}
|
||||
}
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
|
|
@ -9,22 +9,10 @@
|
|||
|
||||
#include "BluetoothService.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
class UnixSocketConsumer;
|
||||
}
|
||||
namespace dom {
|
||||
namespace bluetooth {
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
class BluetoothChild;
|
||||
|
||||
} // namespace bluetooth
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
class BluetoothServiceChildProcess : public BluetoothService
|
||||
{
|
||||
friend class mozilla::dom::bluetooth::BluetoothChild;
|
||||
|
|
|
@ -791,7 +791,7 @@ BluetoothAdapter::SetAdapterState(BluetoothAdapterState aState)
|
|||
mState = aState;
|
||||
|
||||
// Fire BluetoothAttributeEvent for changed adapter state
|
||||
nsTArray<nsString> types;
|
||||
Sequence<nsString> types;
|
||||
BT_APPEND_ENUM_STRING(types,
|
||||
BluetoothAdapterAttribute,
|
||||
BluetoothAdapterAttribute::State);
|
||||
|
@ -806,7 +806,7 @@ BluetoothAdapter::HandlePropertyChanged(const BluetoothValue& aValue)
|
|||
const InfallibleTArray<BluetoothNamedValue>& arr =
|
||||
aValue.get_ArrayOfBluetoothNamedValue();
|
||||
|
||||
nsTArray<nsString> types;
|
||||
Sequence<nsString> types;
|
||||
for (uint32_t i = 0, propCount = arr.Length(); i < propCount; ++i) {
|
||||
BluetoothAdapterAttribute type =
|
||||
ConvertStringToAdapterAttribute(arr[i].name());
|
||||
|
@ -912,26 +912,17 @@ BluetoothAdapter::HandleDeviceUnpaired(const BluetoothValue& aValue)
|
|||
}
|
||||
|
||||
void
|
||||
BluetoothAdapter::DispatchAttributeEvent(const nsTArray<nsString>& aTypes)
|
||||
BluetoothAdapter::DispatchAttributeEvent(const Sequence<nsString>& aTypes)
|
||||
{
|
||||
NS_ENSURE_TRUE_VOID(aTypes.Length());
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
NS_ENSURE_TRUE_VOID(jsapi.Init(GetOwner()));
|
||||
JSContext* cx = jsapi.cx();
|
||||
JS::Rooted<JS::Value> value(cx);
|
||||
BluetoothAttributeEventInit init;
|
||||
init.mAttrs = aTypes;
|
||||
|
||||
if (!ToJSValue(cx, aTypes, &value)) {
|
||||
JS_ClearPendingException(cx);
|
||||
return;
|
||||
}
|
||||
|
||||
RootedDictionary<BluetoothAttributeEventInit> init(cx);
|
||||
init.mAttrs = value;
|
||||
nsRefPtr<BluetoothAttributeEvent> event =
|
||||
BluetoothAttributeEvent::Constructor(this,
|
||||
NS_LITERAL_STRING("attributechanged"),
|
||||
init);
|
||||
BluetoothAttributeEvent::Constructor(
|
||||
this, NS_LITERAL_STRING(ATTRIBUTE_CHANGED_ID), init);
|
||||
|
||||
DispatchTrustedEvent(event);
|
||||
}
|
||||
|
||||
|
|
|
@ -253,7 +253,7 @@ private:
|
|||
/**
|
||||
* Fire BluetoothAttributeEvent to trigger onattributechanged event handler.
|
||||
*/
|
||||
void DispatchAttributeEvent(const nsTArray<nsString>& aTypes);
|
||||
void DispatchAttributeEvent(const Sequence<nsString>& aTypes);
|
||||
|
||||
/**
|
||||
* Fire BluetoothDeviceEvent to trigger
|
||||
|
|
|
@ -261,7 +261,7 @@ BluetoothDevice::HandlePropertyChanged(const BluetoothValue& aValue)
|
|||
const InfallibleTArray<BluetoothNamedValue>& arr =
|
||||
aValue.get_ArrayOfBluetoothNamedValue();
|
||||
|
||||
nsTArray<nsString> types;
|
||||
Sequence<nsString> types;
|
||||
for (uint32_t i = 0, propCount = arr.Length(); i < propCount; ++i) {
|
||||
BluetoothDeviceAttribute type =
|
||||
ConvertStringToDeviceAttribute(arr[i].name());
|
||||
|
@ -283,26 +283,16 @@ BluetoothDevice::HandlePropertyChanged(const BluetoothValue& aValue)
|
|||
}
|
||||
|
||||
void
|
||||
BluetoothDevice::DispatchAttributeEvent(const nsTArray<nsString>& aTypes)
|
||||
BluetoothDevice::DispatchAttributeEvent(const Sequence<nsString>& aTypes)
|
||||
{
|
||||
NS_ENSURE_TRUE_VOID(aTypes.Length());
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
NS_ENSURE_TRUE_VOID(jsapi.Init(GetOwner()));
|
||||
JSContext* cx = jsapi.cx();
|
||||
JS::Rooted<JS::Value> value(cx);
|
||||
|
||||
if (!ToJSValue(cx, aTypes, &value)) {
|
||||
JS_ClearPendingException(cx);
|
||||
return;
|
||||
}
|
||||
|
||||
RootedDictionary<BluetoothAttributeEventInit> init(cx);
|
||||
init.mAttrs = value;
|
||||
BluetoothAttributeEventInit init;
|
||||
init.mAttrs = aTypes;
|
||||
nsRefPtr<BluetoothAttributeEvent> event =
|
||||
BluetoothAttributeEvent::Constructor(this,
|
||||
NS_LITERAL_STRING("attributechanged"),
|
||||
init);
|
||||
BluetoothAttributeEvent::Constructor(
|
||||
this, NS_LITERAL_STRING(ATTRIBUTE_CHANGED_ID), init);
|
||||
|
||||
DispatchTrustedEvent(event);
|
||||
}
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ private:
|
|||
/**
|
||||
* Fire BluetoothAttributeEvent to trigger onattributechanged event handler.
|
||||
*/
|
||||
void DispatchAttributeEvent(const nsTArray<nsString>& aTypes);
|
||||
void DispatchAttributeEvent(const Sequence<nsString>& aTypes);
|
||||
|
||||
/**
|
||||
* Convert uint32_t to BluetoothDeviceType.
|
||||
|
|
|
@ -246,28 +246,18 @@ BluetoothManager::DispatchAttributeEvent()
|
|||
MOZ_ASSERT(NS_IsMainThread());
|
||||
BT_API2_LOGR();
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
NS_ENSURE_TRUE_VOID(jsapi.Init(GetOwner()));
|
||||
JSContext* cx = jsapi.cx();
|
||||
JS::Rooted<JS::Value> value(cx);
|
||||
|
||||
nsTArray<nsString> types;
|
||||
Sequence<nsString> types;
|
||||
BT_APPEND_ENUM_STRING(types,
|
||||
BluetoothManagerAttribute,
|
||||
BluetoothManagerAttribute::DefaultAdapter);
|
||||
|
||||
if (!ToJSValue(cx, types, &value)) {
|
||||
JS_ClearPendingException(cx);
|
||||
return;
|
||||
}
|
||||
|
||||
// Notify application of default adapter change
|
||||
RootedDictionary<BluetoothAttributeEventInit> init(cx);
|
||||
init.mAttrs = value;
|
||||
BluetoothAttributeEventInit init;
|
||||
init.mAttrs = types;
|
||||
nsRefPtr<BluetoothAttributeEvent> event =
|
||||
BluetoothAttributeEvent::Constructor(this,
|
||||
NS_LITERAL_STRING("attributechanged"),
|
||||
init);
|
||||
BluetoothAttributeEvent::Constructor(
|
||||
this, NS_LITERAL_STRING(ATTRIBUTE_CHANGED_ID), init);
|
||||
|
||||
DispatchTrustedEvent(event);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,9 +24,6 @@ namespace dom {
|
|||
class BlobChild;
|
||||
class BlobParent;
|
||||
}
|
||||
namespace ipc {
|
||||
class UnixSocketConsumer;
|
||||
}
|
||||
}
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
|
|
@ -9,22 +9,10 @@
|
|||
|
||||
#include "BluetoothService.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
class UnixSocketConsumer;
|
||||
}
|
||||
namespace dom {
|
||||
namespace bluetooth {
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
class BluetoothChild;
|
||||
|
||||
} // namespace bluetooth
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
class BluetoothServiceChildProcess : public BluetoothService
|
||||
{
|
||||
friend class mozilla::dom::bluetooth::BluetoothChild;
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
||||
#include "mozilla/Hal.h"
|
||||
#include "mozilla/ipc/UnixSocket.h"
|
||||
#include "mozilla/ipc/SocketBase.h"
|
||||
#include "mozilla/ipc/DBusUtils.h"
|
||||
#include "mozilla/ipc/RawDBusConnection.h"
|
||||
#include "mozilla/LazyIdleThread.h"
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include "BluetoothRilListener.h"
|
||||
#endif
|
||||
#include "BluetoothSocketObserver.h"
|
||||
#include "mozilla/ipc/UnixSocket.h"
|
||||
#include "mozilla/ipc/SocketBase.h"
|
||||
#include "mozilla/Hal.h"
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "BluetoothProfileManagerBase.h"
|
||||
#include "BluetoothSocketObserver.h"
|
||||
#include "DeviceStorage.h"
|
||||
#include "mozilla/ipc/UnixSocket.h"
|
||||
#include "mozilla/ipc/SocketBase.h"
|
||||
#include "nsCOMArray.h"
|
||||
|
||||
class nsIDOMBlob;
|
||||
|
|
|
@ -5,13 +5,544 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "BluetoothSocket.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include "BluetoothSocketObserver.h"
|
||||
#include "BluetoothUnixSocketConnector.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
USING_BLUETOOTH_NAMESPACE
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
static const size_t MAX_READ_SIZE = 1 << 16;
|
||||
|
||||
//
|
||||
// BluetoothSocketIO
|
||||
//
|
||||
|
||||
class BluetoothSocket::BluetoothSocketIO final
|
||||
: public UnixSocketWatcher
|
||||
, protected SocketIOBase
|
||||
{
|
||||
public:
|
||||
BluetoothSocketIO(MessageLoop* mIOLoop,
|
||||
BluetoothSocket* aConsumer,
|
||||
UnixSocketConnector* aConnector,
|
||||
const nsACString& aAddress);
|
||||
~BluetoothSocketIO();
|
||||
|
||||
void GetSocketAddr(nsAString& aAddrStr) const;
|
||||
SocketConsumerBase* GetConsumer();
|
||||
SocketBase* GetSocketBase();
|
||||
|
||||
// Shutdown state
|
||||
//
|
||||
|
||||
bool IsShutdownOnMainThread() const;
|
||||
void ShutdownOnMainThread();
|
||||
|
||||
bool IsShutdownOnIOThread() const;
|
||||
void ShutdownOnIOThread();
|
||||
|
||||
// Delayed-task handling
|
||||
//
|
||||
|
||||
void SetDelayedConnectTask(CancelableTask* aTask);
|
||||
void ClearDelayedConnectTask();
|
||||
void CancelDelayedConnectTask();
|
||||
|
||||
// Task callback methods
|
||||
//
|
||||
|
||||
/**
|
||||
* Run bind/listen to prepare for further runs of accept()
|
||||
*/
|
||||
void Listen();
|
||||
|
||||
/**
|
||||
* Connect to a socket
|
||||
*/
|
||||
void Connect();
|
||||
|
||||
void Send(UnixSocketRawData* aData);
|
||||
|
||||
// I/O callback methods
|
||||
//
|
||||
|
||||
void OnAccepted(int aFd, const sockaddr_any* aAddr,
|
||||
socklen_t aAddrLen) override;
|
||||
void OnConnected() override;
|
||||
void OnError(const char* aFunction, int aErrno) override;
|
||||
void OnListening() override;
|
||||
void OnSocketCanReceiveWithoutBlocking() override;
|
||||
void OnSocketCanSendWithoutBlocking() override;
|
||||
|
||||
private:
|
||||
void FireSocketError();
|
||||
|
||||
// Set up flags on file descriptor.
|
||||
static bool SetSocketFlags(int aFd);
|
||||
|
||||
/**
|
||||
* Consumer pointer. Non-thread safe RefPtr, so should only be manipulated
|
||||
* directly from main thread. All non-main-thread accesses should happen with
|
||||
* mIO as container.
|
||||
*/
|
||||
RefPtr<BluetoothSocket> mConsumer;
|
||||
|
||||
/**
|
||||
* Connector object used to create the connection we are currently using.
|
||||
*/
|
||||
nsAutoPtr<UnixSocketConnector> mConnector;
|
||||
|
||||
/**
|
||||
* If true, do not requeue whatever task we're running
|
||||
*/
|
||||
bool mShuttingDownOnIOThread;
|
||||
|
||||
/**
|
||||
* Address we are connecting to, assuming we are creating a client connection.
|
||||
*/
|
||||
nsCString mAddress;
|
||||
|
||||
/**
|
||||
* Size of the socket address struct
|
||||
*/
|
||||
socklen_t mAddrSize;
|
||||
|
||||
/**
|
||||
* Address struct of the socket currently in use
|
||||
*/
|
||||
sockaddr_any mAddr;
|
||||
|
||||
/**
|
||||
* Task member for delayed connect task. Should only be access on main thread.
|
||||
*/
|
||||
CancelableTask* mDelayedConnectTask;
|
||||
};
|
||||
|
||||
BluetoothSocket::BluetoothSocketIO::BluetoothSocketIO(
|
||||
MessageLoop* mIOLoop,
|
||||
BluetoothSocket* aConsumer,
|
||||
UnixSocketConnector* aConnector,
|
||||
const nsACString& aAddress)
|
||||
: UnixSocketWatcher(mIOLoop)
|
||||
, SocketIOBase(MAX_READ_SIZE)
|
||||
, mConsumer(aConsumer)
|
||||
, mConnector(aConnector)
|
||||
, mShuttingDownOnIOThread(false)
|
||||
, mAddress(aAddress)
|
||||
, mDelayedConnectTask(nullptr)
|
||||
{
|
||||
MOZ_ASSERT(mConsumer);
|
||||
MOZ_ASSERT(mConnector);
|
||||
}
|
||||
|
||||
BluetoothSocket::BluetoothSocketIO::~BluetoothSocketIO()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(IsShutdownOnMainThread());
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothSocket::BluetoothSocketIO::GetSocketAddr(nsAString& aAddrStr) const
|
||||
{
|
||||
if (!mConnector) {
|
||||
NS_WARNING("No connector to get socket address from!");
|
||||
aAddrStr.Truncate();
|
||||
return;
|
||||
}
|
||||
mConnector->GetSocketAddr(mAddr, aAddrStr);
|
||||
}
|
||||
|
||||
SocketConsumerBase*
|
||||
BluetoothSocket::BluetoothSocketIO::GetConsumer()
|
||||
{
|
||||
return mConsumer.get();
|
||||
}
|
||||
|
||||
SocketBase*
|
||||
BluetoothSocket::BluetoothSocketIO::GetSocketBase()
|
||||
{
|
||||
return GetConsumer();
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothSocket::BluetoothSocketIO::IsShutdownOnMainThread() const
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
return mConsumer == nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothSocket::BluetoothSocketIO::ShutdownOnMainThread()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!IsShutdownOnMainThread());
|
||||
|
||||
mConsumer = nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothSocket::BluetoothSocketIO::IsShutdownOnIOThread() const
|
||||
{
|
||||
return mShuttingDownOnIOThread;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothSocket::BluetoothSocketIO::ShutdownOnIOThread()
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(!mShuttingDownOnIOThread);
|
||||
|
||||
Close(); // will also remove fd from I/O loop
|
||||
mShuttingDownOnIOThread = true;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothSocket::BluetoothSocketIO::SetDelayedConnectTask(CancelableTask* aTask)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mDelayedConnectTask = aTask;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothSocket::BluetoothSocketIO::ClearDelayedConnectTask()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mDelayedConnectTask = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothSocket::BluetoothSocketIO::CancelDelayedConnectTask()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!mDelayedConnectTask) {
|
||||
return;
|
||||
}
|
||||
|
||||
mDelayedConnectTask->Cancel();
|
||||
ClearDelayedConnectTask();
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothSocket::BluetoothSocketIO::Listen()
|
||||
{
|
||||
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
|
||||
MOZ_ASSERT(mConnector);
|
||||
|
||||
// This will set things we don't particularly care about, but it will hand
|
||||
// back the correct structure size which is what we do care about.
|
||||
if (!mConnector->CreateAddr(true, mAddrSize, mAddr, nullptr)) {
|
||||
NS_WARNING("Cannot create socket address!");
|
||||
FireSocketError();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsOpen()) {
|
||||
int fd = mConnector->Create();
|
||||
if (fd < 0) {
|
||||
NS_WARNING("Cannot create socket fd!");
|
||||
FireSocketError();
|
||||
return;
|
||||
}
|
||||
if (!SetSocketFlags(fd)) {
|
||||
NS_WARNING("Cannot set socket flags!");
|
||||
FireSocketError();
|
||||
return;
|
||||
}
|
||||
SetFd(fd);
|
||||
|
||||
// calls OnListening on success, or OnError otherwise
|
||||
nsresult rv = UnixSocketWatcher::Listen(
|
||||
reinterpret_cast<struct sockaddr*>(&mAddr), mAddrSize);
|
||||
NS_WARN_IF(NS_FAILED(rv));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothSocket::BluetoothSocketIO::Connect()
|
||||
{
|
||||
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
|
||||
MOZ_ASSERT(mConnector);
|
||||
|
||||
if (!IsOpen()) {
|
||||
int fd = mConnector->Create();
|
||||
if (fd < 0) {
|
||||
NS_WARNING("Cannot create socket fd!");
|
||||
FireSocketError();
|
||||
return;
|
||||
}
|
||||
if (!SetSocketFlags(fd)) {
|
||||
NS_WARNING("Cannot set socket flags!");
|
||||
FireSocketError();
|
||||
return;
|
||||
}
|
||||
SetFd(fd);
|
||||
}
|
||||
|
||||
if (!mConnector->CreateAddr(false, mAddrSize, mAddr, mAddress.get())) {
|
||||
NS_WARNING("Cannot create socket address!");
|
||||
FireSocketError();
|
||||
return;
|
||||
}
|
||||
|
||||
// calls OnConnected() on success, or OnError() otherwise
|
||||
nsresult rv = UnixSocketWatcher::Connect(
|
||||
reinterpret_cast<struct sockaddr*>(&mAddr), mAddrSize);
|
||||
NS_WARN_IF(NS_FAILED(rv));
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothSocket::BluetoothSocketIO::Send(UnixSocketRawData* aData)
|
||||
{
|
||||
EnqueueData(aData);
|
||||
AddWatchers(WRITE_WATCHER, false);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothSocket::BluetoothSocketIO::OnAccepted(
|
||||
int aFd, const sockaddr_any* aAddr, socklen_t aAddrLen)
|
||||
{
|
||||
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
|
||||
MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_LISTENING);
|
||||
MOZ_ASSERT(aAddr);
|
||||
MOZ_ASSERT(aAddrLen > 0 && (size_t)aAddrLen <= sizeof(mAddr));
|
||||
|
||||
memcpy (&mAddr, aAddr, aAddrLen);
|
||||
mAddrSize = aAddrLen;
|
||||
|
||||
if (!mConnector->SetUp(aFd)) {
|
||||
NS_WARNING("Could not set up socket!");
|
||||
return;
|
||||
}
|
||||
|
||||
RemoveWatchers(READ_WATCHER|WRITE_WATCHER);
|
||||
Close();
|
||||
if (!SetSocketFlags(aFd)) {
|
||||
return;
|
||||
}
|
||||
SetSocket(aFd, SOCKET_IS_CONNECTED);
|
||||
|
||||
nsRefPtr<nsRunnable> r =
|
||||
new SocketIOEventRunnable<BluetoothSocketIO>(
|
||||
this, SocketIOEventRunnable<BluetoothSocketIO>::CONNECT_SUCCESS);
|
||||
NS_DispatchToMainThread(r);
|
||||
|
||||
AddWatchers(READ_WATCHER, true);
|
||||
if (HasPendingData()) {
|
||||
AddWatchers(WRITE_WATCHER, false);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothSocket::BluetoothSocketIO::OnConnected()
|
||||
{
|
||||
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
|
||||
MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED);
|
||||
|
||||
if (!SetSocketFlags(GetFd())) {
|
||||
NS_WARNING("Cannot set socket flags!");
|
||||
FireSocketError();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mConnector->SetUp(GetFd())) {
|
||||
NS_WARNING("Could not set up socket!");
|
||||
FireSocketError();
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<nsRunnable> r =
|
||||
new SocketIOEventRunnable<BluetoothSocketIO>(
|
||||
this, SocketIOEventRunnable<BluetoothSocketIO>::CONNECT_SUCCESS);
|
||||
NS_DispatchToMainThread(r);
|
||||
|
||||
AddWatchers(READ_WATCHER, true);
|
||||
if (HasPendingData()) {
|
||||
AddWatchers(WRITE_WATCHER, false);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothSocket::BluetoothSocketIO::OnListening()
|
||||
{
|
||||
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
|
||||
MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_LISTENING);
|
||||
|
||||
if (!mConnector->SetUpListenSocket(GetFd())) {
|
||||
NS_WARNING("Could not set up listen socket!");
|
||||
FireSocketError();
|
||||
return;
|
||||
}
|
||||
|
||||
AddWatchers(READ_WATCHER, true);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothSocket::BluetoothSocketIO::OnError(const char* aFunction, int aErrno)
|
||||
{
|
||||
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
|
||||
|
||||
UnixFdWatcher::OnError(aFunction, aErrno);
|
||||
FireSocketError();
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothSocket::BluetoothSocketIO::OnSocketCanReceiveWithoutBlocking()
|
||||
{
|
||||
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
|
||||
MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED); // see bug 990984
|
||||
|
||||
ssize_t res = ReceiveData(GetFd(), this);
|
||||
if (res < 0) {
|
||||
/* I/O error */
|
||||
RemoveWatchers(READ_WATCHER|WRITE_WATCHER);
|
||||
} else if (!res) {
|
||||
/* EOF or peer shutdown */
|
||||
RemoveWatchers(READ_WATCHER);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothSocket::BluetoothSocketIO::OnSocketCanSendWithoutBlocking()
|
||||
{
|
||||
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
|
||||
MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED); // see bug 990984
|
||||
|
||||
nsresult rv = SendPendingData(GetFd(), this);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasPendingData()) {
|
||||
AddWatchers(WRITE_WATCHER, false);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothSocket::BluetoothSocketIO::FireSocketError()
|
||||
{
|
||||
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
|
||||
|
||||
// Clean up watchers, statuses, fds
|
||||
Close();
|
||||
|
||||
// Tell the main thread we've errored
|
||||
nsRefPtr<nsRunnable> r =
|
||||
new SocketIOEventRunnable<BluetoothSocketIO>(
|
||||
this, SocketIOEventRunnable<BluetoothSocketIO>::CONNECT_ERROR);
|
||||
|
||||
NS_DispatchToMainThread(r);
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothSocket::BluetoothSocketIO::SetSocketFlags(int aFd)
|
||||
{
|
||||
// Set socket addr to be reused even if kernel is still waiting to close
|
||||
int n = 1;
|
||||
if (setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set close-on-exec bit.
|
||||
int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFD));
|
||||
if (-1 == flags) {
|
||||
return false;
|
||||
}
|
||||
flags |= FD_CLOEXEC;
|
||||
if (-1 == TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFD, flags))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set non-blocking status flag.
|
||||
flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL));
|
||||
if (-1 == flags) {
|
||||
return false;
|
||||
}
|
||||
flags |= O_NONBLOCK;
|
||||
if (-1 == TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// Socket tasks
|
||||
//
|
||||
|
||||
class BluetoothSocket::ListenTask final
|
||||
: public SocketIOTask<BluetoothSocketIO>
|
||||
{
|
||||
public:
|
||||
ListenTask(BluetoothSocketIO* aIO)
|
||||
: SocketIOTask<BluetoothSocketIO>(aIO)
|
||||
{ }
|
||||
|
||||
void Run() override
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
if (!IsCanceled()) {
|
||||
GetIO()->Listen();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class BluetoothSocket::ConnectTask final
|
||||
: public SocketIOTask<BluetoothSocketIO>
|
||||
{
|
||||
public:
|
||||
ConnectTask(BluetoothSocketIO* aIO)
|
||||
: SocketIOTask<BluetoothSocketIO>(aIO)
|
||||
{ }
|
||||
|
||||
void Run() override
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(!IsCanceled());
|
||||
|
||||
GetIO()->Connect();
|
||||
}
|
||||
};
|
||||
|
||||
class BluetoothSocket::DelayedConnectTask final
|
||||
: public SocketIOTask<BluetoothSocketIO>
|
||||
{
|
||||
public:
|
||||
DelayedConnectTask(BluetoothSocketIO* aIO)
|
||||
: SocketIOTask<BluetoothSocketIO>(aIO)
|
||||
{ }
|
||||
|
||||
void Run() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (IsCanceled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
BluetoothSocketIO* io = GetIO();
|
||||
if (io->IsShutdownOnMainThread()) {
|
||||
return;
|
||||
}
|
||||
|
||||
io->ClearDelayedConnectTask();
|
||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new ConnectTask(io));
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// BluetoothSocket
|
||||
//
|
||||
|
||||
BluetoothSocket::BluetoothSocket(BluetoothSocketObserver* aObserver,
|
||||
BluetoothSocketType aType,
|
||||
|
@ -21,10 +552,16 @@ BluetoothSocket::BluetoothSocket(BluetoothSocketObserver* aObserver,
|
|||
, mType(aType)
|
||||
, mAuth(aAuth)
|
||||
, mEncrypt(aEncrypt)
|
||||
, mIO(nullptr)
|
||||
{
|
||||
MOZ_ASSERT(aObserver);
|
||||
}
|
||||
|
||||
BluetoothSocket::~BluetoothSocket()
|
||||
{
|
||||
MOZ_ASSERT(!mIO);
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothSocket::Connect(const nsAString& aDeviceAddress,
|
||||
const BluetoothUuid& aServiceUuid,
|
||||
|
@ -101,3 +638,122 @@ BluetoothSocket::OnDisconnect()
|
|||
mObserver->OnSocketDisconnect(this);
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothSocket::SendSocketData(UnixSocketRawData* aData)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (!mIO) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!mIO->IsShutdownOnMainThread());
|
||||
XRE_GetIOMessageLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
new SocketIOSendTask<BluetoothSocketIO, UnixSocketRawData>(mIO, aData));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothSocket::SendSocketData(const nsACString& aStr)
|
||||
{
|
||||
if (aStr.Length() > MAX_READ_SIZE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsAutoPtr<UnixSocketRawData> data(
|
||||
new UnixSocketRawData(aStr.BeginReading(), aStr.Length()));
|
||||
|
||||
if (!SendSocketData(data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unused << data.forget();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothSocket::CloseSocket()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (!mIO) {
|
||||
return;
|
||||
}
|
||||
|
||||
mIO->CancelDelayedConnectTask();
|
||||
|
||||
// From this point on, we consider mIO as being deleted.
|
||||
// We sever the relationship here so any future calls to listen or connect
|
||||
// will create a new implementation.
|
||||
mIO->ShutdownOnMainThread();
|
||||
|
||||
XRE_GetIOMessageLoop()->PostTask(
|
||||
FROM_HERE, new SocketIOShutdownTask<BluetoothSocketIO>(mIO));
|
||||
|
||||
mIO = nullptr;
|
||||
|
||||
NotifyDisconnect();
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothSocket::GetSocketAddr(nsAString& aAddrStr)
|
||||
{
|
||||
aAddrStr.Truncate();
|
||||
if (!mIO || GetConnectionStatus() != SOCKET_CONNECTED) {
|
||||
NS_WARNING("No socket currently open!");
|
||||
return;
|
||||
}
|
||||
mIO->GetSocketAddr(aAddrStr);
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothSocket::ConnectSocket(BluetoothUnixSocketConnector* aConnector,
|
||||
const char* aAddress,
|
||||
int aDelayMs)
|
||||
{
|
||||
MOZ_ASSERT(aConnector);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<UnixSocketConnector> connector(aConnector);
|
||||
|
||||
if (mIO) {
|
||||
NS_WARNING("Socket already connecting/connected!");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCString addr(aAddress);
|
||||
MessageLoop* ioLoop = XRE_GetIOMessageLoop();
|
||||
mIO = new BluetoothSocketIO(ioLoop, this, connector.forget(), addr);
|
||||
SetConnectionStatus(SOCKET_CONNECTING);
|
||||
if (aDelayMs > 0) {
|
||||
DelayedConnectTask* connectTask = new DelayedConnectTask(mIO);
|
||||
mIO->SetDelayedConnectTask(connectTask);
|
||||
MessageLoop::current()->PostDelayedTask(FROM_HERE, connectTask, aDelayMs);
|
||||
} else {
|
||||
ioLoop->PostTask(FROM_HERE, new ConnectTask(mIO));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothSocket::ListenSocket(BluetoothUnixSocketConnector* aConnector)
|
||||
{
|
||||
MOZ_ASSERT(aConnector);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<UnixSocketConnector> connector(aConnector);
|
||||
|
||||
if (mIO) {
|
||||
NS_WARNING("Socket already connecting/connected!");
|
||||
return false;
|
||||
}
|
||||
|
||||
mIO = new BluetoothSocketIO(
|
||||
XRE_GetIOMessageLoop(), this, connector.forget(), EmptyCString());
|
||||
SetConnectionStatus(SOCKET_LISTENING);
|
||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new ListenTask(mIO));
|
||||
return true;
|
||||
}
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
|
|
@ -8,19 +8,27 @@
|
|||
#define mozilla_dom_bluetooth_BluetoothSocket_h
|
||||
|
||||
#include "BluetoothCommon.h"
|
||||
#include "mozilla/ipc/UnixSocket.h"
|
||||
#include <stdlib.h>
|
||||
#include "mozilla/ipc/SocketBase.h"
|
||||
#include "mozilla/ipc/UnixSocketWatcher.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
class BluetoothSocketObserver;
|
||||
class BluetoothUnixSocketConnector;
|
||||
|
||||
class BluetoothSocket : public mozilla::ipc::UnixSocketConsumer
|
||||
class BluetoothSocket final : public mozilla::ipc::SocketConsumerBase
|
||||
{
|
||||
public:
|
||||
BluetoothSocket(BluetoothSocketObserver* aObserver,
|
||||
BluetoothSocketType aType,
|
||||
bool aAuth,
|
||||
bool aEncrypt);
|
||||
~BluetoothSocket();
|
||||
|
||||
bool Connect(const nsAString& aDeviceAddress,
|
||||
const BluetoothUuid& aServiceUuid,
|
||||
|
@ -44,11 +52,73 @@ public:
|
|||
GetSocketAddr(aDeviceAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue data to be sent to the socket on the IO thread. Can only be called on
|
||||
* originating thread.
|
||||
*
|
||||
* @param aMessage Data to be sent to socket
|
||||
*
|
||||
* @return true if data is queued, false otherwise (i.e. not connected)
|
||||
*/
|
||||
bool SendSocketData(mozilla::ipc::UnixSocketRawData* aMessage);
|
||||
|
||||
/**
|
||||
* Convenience function for sending strings to the socket (common in bluetooth
|
||||
* profile usage). Converts to a UnixSocketRawData struct. Can only be called
|
||||
* on originating thread.
|
||||
*
|
||||
* @param aMessage String to be sent to socket
|
||||
*
|
||||
* @return true if data is queued, false otherwise (i.e. not connected)
|
||||
*/
|
||||
bool SendSocketData(const nsACString& aMessage);
|
||||
|
||||
/**
|
||||
* 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 aAddress Address to connect to.
|
||||
* @param aDelayMs Time delay in milli-seconds.
|
||||
*
|
||||
* @return true on connect task started, false otherwise.
|
||||
*/
|
||||
bool ConnectSocket(BluetoothUnixSocketConnector* aConnector,
|
||||
const char* aAddress,
|
||||
int aDelayMs = 0);
|
||||
|
||||
/**
|
||||
* Starts a task on the socket that will try to accept a new connection in a
|
||||
* non-blocking manner.
|
||||
*
|
||||
* @param aConnector Connector object for socket type specific functions
|
||||
*
|
||||
* @return true on listen started, false otherwise
|
||||
*/
|
||||
bool ListenSocket(BluetoothUnixSocketConnector* aConnector);
|
||||
|
||||
/**
|
||||
* Queues the internal representation of socket for deletion. Can be called
|
||||
* from main thread.
|
||||
*/
|
||||
void CloseSocket();
|
||||
|
||||
/**
|
||||
* Get the current sockaddr for the socket
|
||||
*/
|
||||
void GetSocketAddr(nsAString& aAddrStr);
|
||||
|
||||
private:
|
||||
class BluetoothSocketIO;
|
||||
class ConnectTask;
|
||||
class DelayedConnectTask;
|
||||
class ListenTask;
|
||||
|
||||
BluetoothSocketObserver* mObserver;
|
||||
BluetoothSocketType mType;
|
||||
bool mAuth;
|
||||
bool mEncrypt;
|
||||
BluetoothSocketIO* mIO;
|
||||
};
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include "BluetoothCommon.h"
|
||||
#include <sys/socket.h>
|
||||
#include <mozilla/ipc/UnixSocket.h>
|
||||
#include <mozilla/ipc/UnixSocketConnector.h>
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
|
|
|
@ -49,13 +49,26 @@ function isEnabledMiddleClickPaste()
|
|||
}
|
||||
}
|
||||
|
||||
function isEnabledTouchCaret()
|
||||
{
|
||||
try {
|
||||
return SpecialPowers.getBoolPref("touchcaret.enabled");
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function doTest(aButton)
|
||||
{
|
||||
// NOTE #1: Right click causes a context menu to popup, then, the click event
|
||||
// isn't generated.
|
||||
// NOTE #2: If middle click causes text to be pasted, then, the click event
|
||||
// isn't generated.
|
||||
if (aButton != 2 && (aButton != 1 || !isEnabledMiddleClickPaste())) {
|
||||
// NOTE #3: If touch caret is enabled, touch caret would ovelap input element,
|
||||
// then, the click event isn't generated.
|
||||
if (aButton != 2 &&
|
||||
(aButton != 1 || !isEnabledMiddleClickPaste()) &&
|
||||
(aButton != 0 || !isEnabledTouchCaret())) {
|
||||
gClickCount = 0;
|
||||
// click on border of input
|
||||
synthesizeMouse(input, 5, 5, { button: aButton });
|
||||
|
|
|
@ -92,6 +92,47 @@ private:
|
|||
bool mEnabled;
|
||||
bool mShutdown;
|
||||
nsRefPtr<ContentParent> mPreallocatedAppProcess;
|
||||
|
||||
#if defined(MOZ_NUWA_PROCESS) && defined(ENABLE_TESTS)
|
||||
// For testing NS_NewUnmonitoredThread().
|
||||
|
||||
void CreateUnmonitoredThread();
|
||||
void DestroyUnmonitoredThread();
|
||||
|
||||
class UnmonitoredThreadRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
UnmonitoredThreadRunnable()
|
||||
: mMonitor("UnmonitoredThreadRunnable")
|
||||
, mEnabled(true)
|
||||
{ }
|
||||
|
||||
NS_IMETHODIMP Run() override
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
while (mEnabled) {
|
||||
mMonitor.Wait();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void Disable()
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
mEnabled = false;
|
||||
mMonitor.NotifyAll();
|
||||
}
|
||||
|
||||
private:
|
||||
~UnmonitoredThreadRunnable() { }
|
||||
|
||||
Monitor mMonitor;
|
||||
bool mEnabled;
|
||||
};
|
||||
|
||||
nsCOMPtr<nsIThread> mUnmonitoredThread;
|
||||
nsRefPtr<UnmonitoredThreadRunnable> mUnmonitoredThreadRunnable;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* static */ StaticRefPtr<PreallocatedProcessManagerImpl>
|
||||
|
@ -155,6 +196,40 @@ PreallocatedProcessManagerImpl::Observe(nsISupports* aSubject,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
#if defined(MOZ_NUWA_PROCESS) && defined(ENABLE_TESTS)
|
||||
void
|
||||
PreallocatedProcessManagerImpl::CreateUnmonitoredThread()
|
||||
{
|
||||
if (Preferences::GetBool("dom.ipc.newUnmonitoredThread.testMode")) {
|
||||
// Create an unmonitored thread and dispatch a blocking runnable in test
|
||||
// case startup.
|
||||
nsresult rv = NS_NewUnmonitoredThread(getter_AddRefs(mUnmonitoredThread),
|
||||
nullptr);
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
|
||||
mUnmonitoredThreadRunnable = new UnmonitoredThreadRunnable();
|
||||
mUnmonitoredThread->Dispatch(mUnmonitoredThreadRunnable,
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PreallocatedProcessManagerImpl::DestroyUnmonitoredThread()
|
||||
{
|
||||
// Cleanup after the test case finishes.
|
||||
if (mUnmonitoredThreadRunnable) {
|
||||
mUnmonitoredThreadRunnable->Disable();
|
||||
}
|
||||
|
||||
if (mUnmonitoredThread) {
|
||||
mUnmonitoredThread->Shutdown();
|
||||
}
|
||||
|
||||
mUnmonitoredThreadRunnable = nullptr;
|
||||
mUnmonitoredThread = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
PreallocatedProcessManagerImpl::RereadPrefs()
|
||||
{
|
||||
|
@ -180,6 +255,11 @@ PreallocatedProcessManagerImpl::Enable()
|
|||
|
||||
mEnabled = true;
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#ifdef ENABLE_TESTS
|
||||
// For testing New_UnmonitoredThread().
|
||||
CreateUnmonitoredThread();
|
||||
#endif
|
||||
|
||||
ScheduleDelayedNuwaFork();
|
||||
#else
|
||||
AllocateAfterDelay();
|
||||
|
@ -372,6 +452,11 @@ PreallocatedProcessManagerImpl::Disable()
|
|||
mEnabled = false;
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#ifdef ENABLE_TESTS
|
||||
// Shut down the test-only unmonitored thread.
|
||||
DestroyUnmonitoredThread();
|
||||
#endif
|
||||
|
||||
// Cancel pending fork.
|
||||
if (mPreallocateAppProcessTask) {
|
||||
mPreallocateAppProcessTask->Cancel();
|
||||
|
|
|
@ -17,6 +17,8 @@ skip-if = buildapp == 'b2g' || buildapp == 'mulet'
|
|||
skip-if = toolkit != 'gonk'
|
||||
[test_NuwaProcessDeadlock.html]
|
||||
skip-if = toolkit != 'gonk'
|
||||
[test_NewUnmonitoredThread.html]
|
||||
skip-if = toolkit != 'gonk'
|
||||
[test_child_docshell.html]
|
||||
skip-if = toolkit == 'cocoa' # disabled due to hangs, see changeset 6852e7c47edf
|
||||
[test_CrashService_crash.html]
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Test if Nuwa process created successfully.
|
||||
-->
|
||||
<head>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body onload="setup()">
|
||||
|
||||
<script type="application/javascript;version=1.7">
|
||||
"use strict";
|
||||
|
||||
function runTest()
|
||||
{
|
||||
info("Launch the Nuwa process");
|
||||
let cpmm = SpecialPowers.Cc["@mozilla.org/childprocessmessagemanager;1"]
|
||||
.getService(SpecialPowers.Ci.nsISyncMessageSender);
|
||||
let seenNuwaReady = false;
|
||||
let msgHandler = {
|
||||
receiveMessage: function receiveMessage(msg) {
|
||||
msg = SpecialPowers.wrap(msg);
|
||||
if (msg.name == 'TEST-ONLY:nuwa-ready') {
|
||||
ok(true, "Got nuwa-ready");
|
||||
is(seenNuwaReady, false, "Already received nuwa ready");
|
||||
seenNuwaReady = true;
|
||||
} else if (msg.name == 'TEST-ONLY:nuwa-add-new-process') {
|
||||
ok(true, "Got nuwa-add-new-process");
|
||||
is(seenNuwaReady, true, "Receive nuwa-add-new-process before nuwa-ready");
|
||||
shutdown();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function shutdown() {
|
||||
info("Shut down the test case");
|
||||
cpmm.removeMessageListener("TEST-ONLY:nuwa-ready", msgHandler);
|
||||
cpmm.removeMessageListener("TEST-ONLY:nuwa-add-new-process", msgHandler);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
cpmm.addMessageListener("TEST-ONLY:nuwa-ready", msgHandler);
|
||||
cpmm.addMessageListener("TEST-ONLY:nuwa-add-new-process", msgHandler);
|
||||
|
||||
|
||||
// Setting this pref to true should cause us to prelaunch a process.
|
||||
SpecialPowers.setBoolPref('dom.ipc.processPrelaunch.enabled', true);
|
||||
}
|
||||
|
||||
function setup2()
|
||||
{
|
||||
info("Enable the Nuwa process to test the unmonitored thread");
|
||||
|
||||
SpecialPowers.pushPrefEnv({
|
||||
'set': [
|
||||
['dom.ipc.processPrelaunch.enabled', false],
|
||||
['dom.ipc.preallocatedProcessManager.testMode', true]
|
||||
]
|
||||
}, runTest);
|
||||
}
|
||||
|
||||
function setup()
|
||||
{
|
||||
info("Create an unmonitored thread.");
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv({
|
||||
'set': [
|
||||
// For testing NS_NewUnmonitoredThread()
|
||||
['dom.ipc.newUnmonitoredThread.testMode', true],
|
||||
]
|
||||
}, setup2);
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -167,6 +167,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "gMobileConnectionService",
|
|||
"@mozilla.org/mobileconnection/mobileconnectionservice;1",
|
||||
"nsIMobileConnectionService");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "gNetworkService",
|
||||
"@mozilla.org/network/service;1",
|
||||
"nsINetworkService");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "MMS", function() {
|
||||
let MMS = {};
|
||||
Cu.import("resource://gre/modules/MmsPduHelper.jsm", MMS);
|
||||
|
@ -706,33 +710,38 @@ XPCOMUtils.defineLazyGetter(this, "gMmsTransactionHelper", function() {
|
|||
url = mmsConnection.mmsc;
|
||||
}
|
||||
|
||||
let startTransaction = () => {
|
||||
let startTransaction = netId => {
|
||||
if (DEBUG) debug("sendRequest: register proxy filter to " + url);
|
||||
let proxyFilter = new MmsProxyFilter(mmsConnection, url);
|
||||
gpps.registerFilter(proxyFilter, 0);
|
||||
|
||||
cancellable.xhr =
|
||||
this.sendHttpRequest(mmsConnection, method,
|
||||
url, istream, proxyFilter,
|
||||
url, istream, proxyFilter, netId,
|
||||
(aHttpStatus, aData) =>
|
||||
cancellable.done(aHttpStatus, aData));
|
||||
};
|
||||
|
||||
mmsConnection.ensureRouting(url)
|
||||
.then(() => startTransaction(),
|
||||
(aError) => {
|
||||
debug("Failed to ensureRouting: " + aError);
|
||||
let onRejected = aReason => {
|
||||
debug(aReason);
|
||||
mmsConnection.release();
|
||||
cancellable.done(_HTTP_STATUS_FAILED_TO_ROUTE, null);
|
||||
};
|
||||
|
||||
mmsConnection.release();
|
||||
cancellable.done(_HTTP_STATUS_FAILED_TO_ROUTE, null);
|
||||
});
|
||||
// TODO: |getNetId| will be implemented as a sync call in nsINetworkManager
|
||||
// once Bug 1141903 is landed.
|
||||
mmsConnection.ensureRouting(url)
|
||||
.then(() => gNetworkService.getNetId(mmsConnection.networkInterface.name),
|
||||
(aReason) => onRejected('Failed to ensureRouting: ' + aReason))
|
||||
.then((netId) => startTransaction(netId),
|
||||
(aReason) => onRejected('Failed to getNetId: ' + aReason));
|
||||
});
|
||||
|
||||
return cancellable;
|
||||
},
|
||||
|
||||
sendHttpRequest: function(mmsConnection, method, url, istream, proxyFilter,
|
||||
callback) {
|
||||
netId, callback) {
|
||||
let releaseMmsConnectionAndCallback = (httpStatus, data) => {
|
||||
gpps.unregisterFilter(proxyFilter);
|
||||
// Always release the MMS network connection before callback.
|
||||
|
@ -745,6 +754,7 @@ XPCOMUtils.defineLazyGetter(this, "gMmsTransactionHelper", function() {
|
|||
.createInstance(Ci.nsIXMLHttpRequest);
|
||||
|
||||
// Basic setups
|
||||
xhr.networkInterfaceId = netId;
|
||||
xhr.open(method, url, true);
|
||||
xhr.responseType = "arraybuffer";
|
||||
if (istream) {
|
||||
|
|
|
@ -613,6 +613,10 @@ Nfc.prototype = {
|
|||
message.target.sendAsyncMessage(nfcMsgType, message.data);
|
||||
},
|
||||
|
||||
getErrorMessage: function getErrorMessage(errorCode) {
|
||||
return NFC.NFC_ERROR_MSG[errorCode];
|
||||
},
|
||||
|
||||
/**
|
||||
* Process the incoming message from the NFC Service.
|
||||
*/
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#define NfcService_h
|
||||
|
||||
#include "mozilla/ipc/Nfc.h"
|
||||
#include "mozilla/ipc/UnixSocket.h"
|
||||
#include "mozilla/ipc/SocketBase.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsINfcService.h"
|
||||
#include "NfcMessageHandler.h"
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "OpenFileFinder.h"
|
||||
#include "Volume.h"
|
||||
#include "VolumeManager.h"
|
||||
#include "nsIStatusReporter.h"
|
||||
|
||||
using namespace mozilla::hal;
|
||||
USING_MTP_NAMESPACE
|
||||
|
@ -259,6 +260,10 @@ public:
|
|||
}
|
||||
|
||||
void UpdateState();
|
||||
void GetStatus(bool& umsAvail, bool& umsConfigured, bool& umsEnabled, bool& mtpAvail,
|
||||
bool& mtpConfigured, bool& mtpEnabled, bool& rndisConfigured);
|
||||
|
||||
nsresult Dump(nsACString& desc);
|
||||
|
||||
void ConfigureUsbFunction(const char* aUsbFunc);
|
||||
|
||||
|
@ -459,6 +464,21 @@ private:
|
|||
static StaticRefPtr<AutoMounter> sAutoMounter;
|
||||
static StaticRefPtr<MozMtpServer> sMozMtpServer;
|
||||
|
||||
// The following is for status reporter
|
||||
enum STATE_REPORTER_STATE
|
||||
{
|
||||
REPORTER_UNREGISTERED,
|
||||
REPORTER_REGISTERED
|
||||
};
|
||||
|
||||
static int status_reporter_progress = REPORTER_UNREGISTERED;
|
||||
nsresult getState(nsACString &desc)
|
||||
{
|
||||
sAutoMounter->Dump(desc);
|
||||
return NS_OK;
|
||||
}
|
||||
NS_STATUS_REPORTER_IMPLEMENT(AutoMounter, "AutoMounter", getState);
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
void
|
||||
|
@ -703,56 +723,12 @@ AutoMounter::UpdateState()
|
|||
//
|
||||
// Since IsUsbCablePluggedIn returns state == CONFIGURED, it will look
|
||||
// like a cable pull and replugin.
|
||||
|
||||
bool umsAvail = false;
|
||||
bool umsConfigured = false;
|
||||
bool umsEnabled = false;
|
||||
bool mtpAvail = false;
|
||||
bool mtpConfigured = false;
|
||||
bool mtpEnabled = false;
|
||||
bool rndisConfigured = false;
|
||||
bool umsAvail, umsConfigured, umsEnabled;
|
||||
bool mtpAvail, mtpConfigured, mtpEnabled;
|
||||
bool rndisConfigured;
|
||||
bool usbCablePluggedIn = IsUsbCablePluggedIn();
|
||||
|
||||
if (access(ICS_SYS_USB_FUNCTIONS, F_OK) == 0) {
|
||||
char functionsStr[60];
|
||||
if (!ReadSysFile(ICS_SYS_USB_FUNCTIONS, functionsStr, sizeof(functionsStr))) {
|
||||
ERR("Error reading file '%s': %s", ICS_SYS_USB_FUNCTIONS, strerror(errno));
|
||||
functionsStr[0] = '\0';
|
||||
}
|
||||
DBG("UpdateState: USB functions: '%s'", functionsStr);
|
||||
|
||||
bool usbConfigured = IsUsbConfigured();
|
||||
|
||||
// On the Nexus 4/5, it advertises that the UMS usb function is available,
|
||||
// but we have a further requirement that mass_storage be in the
|
||||
// persist.sys.usb.config property.
|
||||
char persistSysUsbConfig[PROPERTY_VALUE_MAX];
|
||||
property_get(PERSIST_SYS_USB_CONFIG, persistSysUsbConfig, "");
|
||||
if (IsUsbFunctionEnabled(persistSysUsbConfig, USB_FUNC_UMS)) {
|
||||
umsAvail = (access(ICS_SYS_UMS_DIRECTORY, F_OK) == 0);
|
||||
}
|
||||
if (umsAvail) {
|
||||
umsConfigured = usbConfigured && strstr(functionsStr, USB_FUNC_UMS) != nullptr;
|
||||
umsEnabled = (mMode == AUTOMOUNTER_ENABLE_UMS) ||
|
||||
((mMode == AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED) && umsConfigured);
|
||||
} else {
|
||||
umsConfigured = false;
|
||||
umsEnabled = false;
|
||||
}
|
||||
|
||||
mtpAvail = (access(ICS_SYS_MTP_DIRECTORY, F_OK) == 0);
|
||||
if (mtpAvail) {
|
||||
mtpConfigured = usbConfigured && strstr(functionsStr, USB_FUNC_MTP) != nullptr;
|
||||
mtpEnabled = (mMode == AUTOMOUNTER_ENABLE_MTP) ||
|
||||
((mMode == AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED) && mtpConfigured);
|
||||
} else {
|
||||
mtpConfigured = false;
|
||||
mtpEnabled = false;
|
||||
}
|
||||
|
||||
rndisConfigured = strstr(functionsStr, USB_FUNC_RNDIS) != nullptr;
|
||||
}
|
||||
|
||||
GetStatus(umsAvail, umsConfigured, umsEnabled, mtpAvail,
|
||||
mtpConfigured, mtpEnabled, rndisConfigured);
|
||||
bool enabled = mtpEnabled || umsEnabled;
|
||||
|
||||
if (mMode == AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED) {
|
||||
|
@ -1139,6 +1115,167 @@ AutoMounter::UpdateState()
|
|||
|
||||
/***************************************************************************/
|
||||
|
||||
void AutoMounter::GetStatus(bool& umsAvail, bool& umsConfigured, bool& umsEnabled,
|
||||
bool& mtpAvail, bool& mtpConfigured, bool& mtpEnabled,
|
||||
bool& rndisConfigured)
|
||||
{
|
||||
umsConfigured = false;
|
||||
umsEnabled = false;
|
||||
mtpAvail = false;
|
||||
mtpConfigured = false;
|
||||
mtpEnabled = false;
|
||||
rndisConfigured = false;
|
||||
|
||||
if (access(ICS_SYS_USB_FUNCTIONS, F_OK) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
char functionsStr[60];
|
||||
if (!ReadSysFile(ICS_SYS_USB_FUNCTIONS, functionsStr, sizeof(functionsStr))) {
|
||||
ERR("Error reading file '%s': %s", ICS_SYS_USB_FUNCTIONS, strerror(errno));
|
||||
functionsStr[0] = '\0';
|
||||
}
|
||||
DBG("GetStatus: USB functions: '%s'", functionsStr);
|
||||
|
||||
bool usbConfigured = IsUsbConfigured();
|
||||
|
||||
// On the Nexus 4/5, it advertises that the UMS usb function is available,
|
||||
// but we have a further requirement that mass_storage be in the
|
||||
// persist.sys.usb.config property.
|
||||
char persistSysUsbConfig[PROPERTY_VALUE_MAX];
|
||||
property_get(PERSIST_SYS_USB_CONFIG, persistSysUsbConfig, "");
|
||||
if (IsUsbFunctionEnabled(persistSysUsbConfig, USB_FUNC_UMS)) {
|
||||
umsAvail = (access(ICS_SYS_UMS_DIRECTORY, F_OK) == 0);
|
||||
}
|
||||
if (umsAvail) {
|
||||
umsConfigured = usbConfigured && strstr(functionsStr, USB_FUNC_UMS) != nullptr;
|
||||
umsEnabled = (mMode == AUTOMOUNTER_ENABLE_UMS) ||
|
||||
((mMode == AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED) && umsConfigured);
|
||||
} else {
|
||||
umsConfigured = false;
|
||||
umsEnabled = false;
|
||||
}
|
||||
|
||||
mtpAvail = (access(ICS_SYS_MTP_DIRECTORY, F_OK) == 0);
|
||||
if (mtpAvail) {
|
||||
mtpConfigured = usbConfigured && strstr(functionsStr, USB_FUNC_MTP) != nullptr;
|
||||
mtpEnabled = (mMode == AUTOMOUNTER_ENABLE_MTP) ||
|
||||
((mMode == AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED) && mtpConfigured);
|
||||
} else {
|
||||
mtpConfigured = false;
|
||||
mtpEnabled = false;
|
||||
}
|
||||
|
||||
rndisConfigured = strstr(functionsStr, USB_FUNC_RNDIS) != nullptr;
|
||||
}
|
||||
|
||||
|
||||
nsresult AutoMounter::Dump(nsACString& desc)
|
||||
{
|
||||
DBG("GetState!");
|
||||
bool umsAvail, umsConfigured, umsEnabled;
|
||||
bool mtpAvail, mtpConfigured, mtpEnabled;
|
||||
bool rndisConfigured;
|
||||
GetStatus(umsAvail, umsConfigured, umsEnabled, mtpAvail,
|
||||
mtpConfigured, mtpEnabled, rndisConfigured);
|
||||
if (mMode == AUTOMOUNTER_DISABLE_WHEN_UNPLUGGED) {
|
||||
// DISABLE_WHEN_UNPLUGGED implies already enabled.
|
||||
if (!IsUsbCablePluggedIn()) {
|
||||
mMode = AUTOMOUNTER_DISABLE;
|
||||
mtpEnabled = false;
|
||||
umsEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Automounter information
|
||||
desc += "Current Mode:";
|
||||
desc += ModeStr(mMode);
|
||||
desc += "|";
|
||||
|
||||
|
||||
desc += "Current State:";
|
||||
desc += StateStr(mState);
|
||||
desc += "|";
|
||||
|
||||
desc += "UMS Status:";
|
||||
if (umsAvail) {
|
||||
desc += "Available";
|
||||
} else {
|
||||
desc += "UnAvailable";
|
||||
}
|
||||
desc += ",";
|
||||
if (umsConfigured) {
|
||||
desc += "Configured";
|
||||
} else {
|
||||
desc += "Un-Configured";
|
||||
}
|
||||
desc += ",";
|
||||
if (umsEnabled) {
|
||||
desc += "Enabled";
|
||||
} else {
|
||||
desc += "Disabled";
|
||||
}
|
||||
desc += "|";
|
||||
|
||||
|
||||
desc += "MTP Status:";
|
||||
if (mtpAvail) {
|
||||
desc += "Available";
|
||||
} else {
|
||||
desc += "UnAvailable";
|
||||
}
|
||||
desc += ",";
|
||||
if (mtpConfigured) {
|
||||
desc += "Configured";
|
||||
} else {
|
||||
desc += "Un-Configured";
|
||||
}
|
||||
desc += ",";
|
||||
if (mtpEnabled) {
|
||||
desc += "Enabled";
|
||||
} else {
|
||||
desc += "Disabled";
|
||||
}
|
||||
|
||||
|
||||
// Volume information
|
||||
VolumeArray::index_type volIndex;
|
||||
VolumeArray::size_type numVolumes = VolumeManager::NumVolumes();
|
||||
for (volIndex = 0; volIndex < numVolumes; volIndex++) {
|
||||
RefPtr<Volume> vol = VolumeManager::GetVolume(volIndex);
|
||||
|
||||
desc += "|";
|
||||
desc += vol->NameStr();
|
||||
desc += ":";
|
||||
desc += vol->StateStr();
|
||||
desc += "@";
|
||||
desc += vol->MountPoint().get();
|
||||
|
||||
if (!vol->MediaPresent()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vol->CanBeShared()) {
|
||||
desc += ",CanBeShared";
|
||||
}
|
||||
if (vol->CanBeFormatted()) {
|
||||
desc += ",CanBeFormatted";
|
||||
}
|
||||
if (vol->CanBeMounted()) {
|
||||
desc += ",CanBeMounted";
|
||||
}
|
||||
if (vol->IsRemovable()) {
|
||||
desc += ",Removable";
|
||||
}
|
||||
if (vol->IsHotSwappable()) {
|
||||
desc += ",HotSwappable";
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
InitAutoMounterIOThread()
|
||||
{
|
||||
|
@ -1270,6 +1407,12 @@ InitAutoMounter()
|
|||
// start it here and have it send events to the AutoMounter running
|
||||
// on the IO Thread.
|
||||
sUsbCableObserver = new UsbCableObserver();
|
||||
|
||||
// Register status reporter into reporter manager
|
||||
if(status_reporter_progress == REPORTER_UNREGISTERED) {
|
||||
NS_RegisterStatusReporter(new NS_STATUS_REPORTER_NAME(AutoMounter));
|
||||
}
|
||||
status_reporter_progress = REPORTER_REGISTERED;
|
||||
}
|
||||
|
||||
int32_t
|
||||
|
@ -1340,6 +1483,11 @@ ShutdownAutoMounter()
|
|||
if (sAutoMounter) {
|
||||
DBG("ShutdownAutoMounter: About to StopMtpServer");
|
||||
sAutoMounter->StopMtpServer();
|
||||
// Unregister status reporter into reporter manager
|
||||
if(status_reporter_progress == REPORTER_REGISTERED) {
|
||||
NS_UnregisterStatusReporter(new NS_STATUS_REPORTER_NAME(AutoMounter));
|
||||
}
|
||||
status_reporter_progress = REPORTER_UNREGISTERED;
|
||||
}
|
||||
sAutoMounterSetting = nullptr;
|
||||
sUsbCableObserver = nullptr;
|
||||
|
|
|
@ -277,48 +277,53 @@ NetworkManager.prototype = {
|
|||
switch (network.state) {
|
||||
case Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED:
|
||||
gNetworkService.createNetwork(network.name, () => {
|
||||
// Add host route for data calls
|
||||
if (this.isNetworkTypeMobile(network.type)) {
|
||||
let currentInterfaceLinks = this.networkInterfaceLinks[networkId];
|
||||
let newLinkRoutes = network.getDnses().concat(network.httpProxyHost);
|
||||
// If gateways have changed, remove all old routes first.
|
||||
this._handleGateways(networkId, network.getGateways())
|
||||
.then(() => this._updateRoutes(currentInterfaceLinks.linkRoutes,
|
||||
newLinkRoutes,
|
||||
network.getGateways(), network.name))
|
||||
.then(() => currentInterfaceLinks.setLinks(newLinkRoutes,
|
||||
network.getGateways(),
|
||||
network.name));
|
||||
}
|
||||
|
||||
// Remove pre-created default route and let setAndConfigureActive()
|
||||
// to set default route only on preferred network
|
||||
gNetworkService.removeDefaultRoute(network);
|
||||
|
||||
// Dun type is a special case where we add the default route to a
|
||||
// secondary table.
|
||||
if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN) {
|
||||
this.setSecondaryDefaultRoute(network);
|
||||
}
|
||||
|
||||
this._addSubnetRoutes(network);
|
||||
this.setAndConfigureActive();
|
||||
|
||||
// Update data connection when Wifi connected/disconnected
|
||||
if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_WIFI && this.mRil) {
|
||||
for (let i = 0; i < this.mRil.numRadioInterfaces; i++) {
|
||||
this.mRil.getRadioInterface(i).updateRILNetworkInterface();
|
||||
// Set DNS server as early as possible to prevent from
|
||||
// premature domain name lookup.
|
||||
gNetworkService.setDNS(network, () => {
|
||||
// Add host route for data calls
|
||||
if (this.isNetworkTypeMobile(network.type)) {
|
||||
let currentInterfaceLinks = this.networkInterfaceLinks[networkId];
|
||||
let newLinkRoutes = network.getDnses().concat(network.httpProxyHost);
|
||||
// If gateways have changed, remove all old routes first.
|
||||
this._handleGateways(networkId, network.getGateways())
|
||||
.then(() => this._updateRoutes(currentInterfaceLinks.linkRoutes,
|
||||
newLinkRoutes,
|
||||
network.getGateways(), network.name))
|
||||
.then(() => currentInterfaceLinks.setLinks(newLinkRoutes,
|
||||
network.getGateways(),
|
||||
network.name));
|
||||
}
|
||||
}
|
||||
|
||||
// Probing the public network accessibility after routing table is ready
|
||||
CaptivePortalDetectionHelper
|
||||
.notify(CaptivePortalDetectionHelper.EVENT_CONNECT, this.active);
|
||||
// Dun type is a special case where we add the default route to a
|
||||
// secondary table.
|
||||
if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN) {
|
||||
this.setSecondaryDefaultRoute(network);
|
||||
}
|
||||
|
||||
// Notify outer modules like MmsService to start the transaction after
|
||||
// the configuration of the network interface is done.
|
||||
Services.obs.notifyObservers(network, TOPIC_CONNECTION_STATE_CHANGED,
|
||||
this.convertConnectionType(network));
|
||||
this._addSubnetRoutes(network);
|
||||
this.setAndConfigureActive();
|
||||
|
||||
// Update data connection when Wifi connected/disconnected
|
||||
if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_WIFI && this.mRil) {
|
||||
for (let i = 0; i < this.mRil.numRadioInterfaces; i++) {
|
||||
this.mRil.getRadioInterface(i).updateRILNetworkInterface();
|
||||
}
|
||||
}
|
||||
|
||||
// Probing the public network accessibility after routing table is ready
|
||||
CaptivePortalDetectionHelper
|
||||
.notify(CaptivePortalDetectionHelper.EVENT_CONNECT, this.active);
|
||||
|
||||
// Notify outer modules like MmsService to start the transaction after
|
||||
// the configuration of the network interface is done.
|
||||
Services.obs.notifyObservers(network, TOPIC_CONNECTION_STATE_CHANGED,
|
||||
this.convertConnectionType(network));
|
||||
});
|
||||
});
|
||||
|
||||
break;
|
||||
|
@ -641,7 +646,7 @@ NetworkManager.prototype = {
|
|||
// The override was just set, so reconfigure the network.
|
||||
if (this.active != this._overriddenActive) {
|
||||
this.active = this._overriddenActive;
|
||||
this._setDefaultRouteAndDNS(this.active, oldActive);
|
||||
this._setDefaultRouteAndProxy(this.active, oldActive);
|
||||
Services.obs.notifyObservers(this.active, TOPIC_ACTIVE_CHANGED, null);
|
||||
}
|
||||
return;
|
||||
|
@ -652,7 +657,7 @@ NetworkManager.prototype = {
|
|||
this.active.state == Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED &&
|
||||
this.active.type == this._preferredNetworkType) {
|
||||
debug("Active network is already our preferred type.");
|
||||
this._setDefaultRouteAndDNS(this.active, oldActive);
|
||||
this._setDefaultRouteAndProxy(this.active, oldActive);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -686,10 +691,8 @@ NetworkManager.prototype = {
|
|||
this.active = defaultDataNetwork;
|
||||
}
|
||||
// Don't set default route on secondary APN
|
||||
if (this.isNetworkTypeSecondaryMobile(this.active.type)) {
|
||||
gNetworkService.setDNS(this.active, function() {});
|
||||
} else {
|
||||
this._setDefaultRouteAndDNS(this.active, oldActive);
|
||||
if (!this.isNetworkTypeSecondaryMobile(this.active.type)) {
|
||||
this._setDefaultRouteAndProxy(this.active, oldActive);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -713,44 +716,48 @@ NetworkManager.prototype = {
|
|||
return Promise.resolve([hostname]);
|
||||
}
|
||||
|
||||
let deferred = Promise.defer();
|
||||
let onLookupComplete = (aRequest, aRecord, aStatus) => {
|
||||
if (!Components.isSuccessCode(aStatus)) {
|
||||
deferred.reject(new Error(
|
||||
"Failed to resolve '" + hostname + "', with status: " + aStatus));
|
||||
return;
|
||||
}
|
||||
// Wrap gDNSService.asyncResolveExtended to a promise, which
|
||||
// resolves with an array of ip addresses or rejects with
|
||||
// the reason otherwise.
|
||||
let hostResolveWrapper = aNetId => {
|
||||
return new Promise((aResolve, aReject) => {
|
||||
// Callback for gDNSService.asyncResolveExtended.
|
||||
let onLookupComplete = (aRequest, aRecord, aStatus) => {
|
||||
if (!Components.isSuccessCode(aStatus)) {
|
||||
aReject(new Error("Failed to resolve '" + hostname +
|
||||
"', with status: " + aStatus));
|
||||
return;
|
||||
}
|
||||
|
||||
let retval = [];
|
||||
while (aRecord.hasMore()) {
|
||||
retval.push(aRecord.getNextAddrAsString());
|
||||
}
|
||||
let retval = [];
|
||||
while (aRecord.hasMore()) {
|
||||
retval.push(aRecord.getNextAddrAsString());
|
||||
}
|
||||
|
||||
if (!retval.length) {
|
||||
deferred.reject(new Error("No valid address after DNS lookup!"));
|
||||
return;
|
||||
}
|
||||
if (!retval.length) {
|
||||
aReject(new Error("No valid address after DNS lookup!"));
|
||||
return;
|
||||
}
|
||||
|
||||
debug("hostname is resolved: " + hostname);
|
||||
debug("Addresses: " + JSON.stringify(retval));
|
||||
debug("hostname is resolved: " + hostname);
|
||||
debug("Addresses: " + JSON.stringify(retval));
|
||||
|
||||
deferred.resolve(retval);
|
||||
aResolve(retval);
|
||||
};
|
||||
|
||||
debug('Calling gDNSService.asyncResolveExtended: ' + aNetId + ', ' + hostname);
|
||||
gDNSService.asyncResolveExtended(hostname,
|
||||
0,
|
||||
aNetId,
|
||||
onLookupComplete,
|
||||
Services.tm.mainThread);
|
||||
});
|
||||
};
|
||||
|
||||
// Bug 1058282 - Explicitly request ipv4 to get around 8.8.8.8 probe at
|
||||
// http://androidxref.com/4.3_r2.1/xref/bionic/libc/netbsd/net/getaddrinfo.c#1923
|
||||
//
|
||||
// Whenever MMS connection is the only network interface, there is no
|
||||
// default route so that any ip probe will fail.
|
||||
let flags = 0;
|
||||
if (network.type === Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_MMS) {
|
||||
flags |= Ci.nsIDNSService.RESOLVE_DISABLE_IPV6;
|
||||
}
|
||||
|
||||
// TODO: Bug 992772 - Resolve the hostname with specified networkInterface.
|
||||
gDNSService.asyncResolve(hostname, flags, onLookupComplete, Services.tm.mainThread);
|
||||
|
||||
return deferred.promise;
|
||||
// TODO: |getNetId| will be implemented as a sync call in nsINetworkManager
|
||||
// once Bug 1141903 is landed.
|
||||
return gNetworkService.getNetId(network.name)
|
||||
.then(aNetId => hostResolveWrapper(aNetId));
|
||||
},
|
||||
|
||||
convertConnectionType: function(network) {
|
||||
|
@ -774,15 +781,13 @@ NetworkManager.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
_setDefaultRouteAndDNS: function(network, oldInterface) {
|
||||
_setDefaultRouteAndProxy: function(network, oldInterface) {
|
||||
gNetworkService.setDefaultRoute(network, oldInterface, function(success) {
|
||||
if (!success) {
|
||||
gNetworkService.destroyNetwork(network, function() {});
|
||||
return;
|
||||
}
|
||||
gNetworkService.setDNS(network, function(result) {
|
||||
gNetworkService.setNetworkProxy(network);
|
||||
});
|
||||
gNetworkService.setNetworkProxy(network);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
@ -391,7 +391,8 @@ NetworkService.prototype = {
|
|||
cmd: "setDNS",
|
||||
ifname: networkInterface.name,
|
||||
domain: "mozilla." + networkInterface.name + ".doman",
|
||||
dnses: dnses
|
||||
dnses: dnses,
|
||||
gateways: networkInterface.getGateways()
|
||||
};
|
||||
this.controlMessage(options, function(result) {
|
||||
callback.setDnsResult(result.success ? null : result.reason);
|
||||
|
@ -762,6 +763,23 @@ NetworkService.prototype = {
|
|||
callback.nativeCommandResult(!result.error);
|
||||
});
|
||||
},
|
||||
|
||||
getNetId: function(interfaceName) {
|
||||
let params = {
|
||||
cmd: "getNetId",
|
||||
ifname: interfaceName
|
||||
};
|
||||
|
||||
return new Promise((aResolve, aReject) => {
|
||||
this.controlMessage(params, result => {
|
||||
if (result.error) {
|
||||
aReject(result.reason);
|
||||
return;
|
||||
}
|
||||
aResolve(result.netId);
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([NetworkService]);
|
||||
|
|
|
@ -440,7 +440,6 @@ CommandResult::CommandResult(int32_t aResultCode)
|
|||
strerror_r(abs(aResultCode), strerrorBuf, STRERROR_R_BUF_SIZE);
|
||||
mResult.mReason = NS_ConvertUTF8toUTF16(strerrorBuf);
|
||||
}
|
||||
mResult.mRet = true;
|
||||
}
|
||||
|
||||
CommandResult::CommandResult(const mozilla::dom::NetworkResultOptions& aResult)
|
||||
|
@ -1535,6 +1534,7 @@ void NetworkUtils::ExecuteCommand(NetworkParams aOptions)
|
|||
BUILD_ENTRY(resetConnections),
|
||||
BUILD_ENTRY(createNetwork),
|
||||
BUILD_ENTRY(destroyNetwork),
|
||||
BUILD_ENTRY(getNetId),
|
||||
|
||||
#undef BUILD_ENTRY
|
||||
};
|
||||
|
@ -1704,6 +1704,7 @@ CommandResult NetworkUtils::setDNS(NetworkParams& aOptions)
|
|||
// Lollipop.
|
||||
static CommandFunc COMMAND_CHAIN[] = {
|
||||
setInterfaceDns,
|
||||
addDefaultRouteToNetwork,
|
||||
defaultAsyncSuccessHandler
|
||||
};
|
||||
NetIdManager::NetIdInfo netIdInfo;
|
||||
|
@ -1717,7 +1718,12 @@ CommandResult NetworkUtils::setDNS(NetworkParams& aOptions)
|
|||
if (SDK_VERSION >= 18) {
|
||||
// JB, KK.
|
||||
static CommandFunc COMMAND_CHAIN[] = {
|
||||
#if ANDROID_VERSION == 18
|
||||
// Since we don't use per-interface DNS lookup feature on JB,
|
||||
// we need to set the default DNS interface whenever setting the
|
||||
// DNS name server.
|
||||
setDefaultInterface,
|
||||
#endif
|
||||
setInterfaceDns,
|
||||
defaultAsyncSuccessHandler
|
||||
};
|
||||
|
@ -1898,6 +1904,17 @@ CommandResult NetworkUtils::setDefaultRouteLegacy(NetworkParams& aOptions)
|
|||
}
|
||||
}
|
||||
|
||||
// Set the default DNS interface.
|
||||
if (SDK_VERSION >= 18) {
|
||||
// For JB, KK only.
|
||||
static CommandFunc COMMAND_CHAIN[] = {
|
||||
setDefaultInterface,
|
||||
defaultAsyncSuccessHandler
|
||||
};
|
||||
runChain(aOptions, COMMAND_CHAIN, setDnsFail);
|
||||
return CommandResult::Pending();
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -2516,6 +2533,27 @@ CommandResult NetworkUtils::destroyNetwork(NetworkParams& aOptions)
|
|||
return CommandResult::Pending();
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the netId associated with the given network interface name.
|
||||
*/
|
||||
CommandResult NetworkUtils::getNetId(NetworkParams& aOptions)
|
||||
{
|
||||
NetworkResultOptions result;
|
||||
|
||||
if (SDK_VERSION < 20) {
|
||||
// For pre-Lollipop, use the interface name as the fallback.
|
||||
result.mNetId = GET_FIELD(mIfname);
|
||||
return result;
|
||||
}
|
||||
|
||||
NetIdManager::NetIdInfo netIdInfo;
|
||||
if (-1 == mNetIdManager.lookup(GET_FIELD(mIfname), &netIdInfo)) {
|
||||
return ESRCH;
|
||||
}
|
||||
result.mNetId.AppendInt(netIdInfo.mNetId, 10);
|
||||
return result;
|
||||
}
|
||||
|
||||
void NetworkUtils::sendBroadcastMessage(uint32_t code, char* reason)
|
||||
{
|
||||
NetworkResultOptions result;
|
||||
|
|
|
@ -309,6 +309,7 @@ private:
|
|||
CommandResult updateUpStream(NetworkParams& aOptions);
|
||||
CommandResult createNetwork(NetworkParams& aOptions);
|
||||
CommandResult destroyNetwork(NetworkParams& aOptions);
|
||||
CommandResult getNetId(NetworkParams& aOptions);
|
||||
|
||||
CommandResult addHostRouteLegacy(NetworkParams& aOptions);
|
||||
CommandResult removeHostRouteLegacy(NetworkParams& aOptions);
|
||||
|
|
|
@ -159,7 +159,7 @@ interface nsIDhcpRequestCallback : nsISupports
|
|||
/**
|
||||
* Provide network services.
|
||||
*/
|
||||
[scriptable, uuid(e40dd966-cb04-4dc7-ac4b-6382769c00b9)]
|
||||
[scriptable, uuid(a0f29630-c25c-11e4-8830-0800200c9a66)]
|
||||
interface nsINetworkService : nsISupports
|
||||
{
|
||||
const long MODIFY_ROUTE_ADD = 0;
|
||||
|
@ -486,4 +486,17 @@ interface nsINetworkService : nsISupports
|
|||
*/
|
||||
void destroyNetwork(in DOMString interfaceName,
|
||||
in nsINativeCommandCallback callback);
|
||||
|
||||
/**
|
||||
* Query the netId associated with given network interface name.
|
||||
*
|
||||
* @param interfaceName
|
||||
* The network interface name which we want to query.
|
||||
*
|
||||
* @return A deferred promise that resolves with a string to indicate.
|
||||
* the queried netId on success and rejects if the interface name
|
||||
* is invalid.
|
||||
*
|
||||
*/
|
||||
jsval getNetId(in DOMString interfaceName);
|
||||
};
|
||||
|
|
|
@ -9,13 +9,11 @@
|
|||
optional BluetoothAttributeEventInit eventInitDict)]
|
||||
interface BluetoothAttributeEvent : Event
|
||||
{
|
||||
readonly attribute any attrs;
|
||||
// We don't support sequence in event codegen yet (Bug 1023762)
|
||||
// Bug 1015796:
|
||||
// readonly attribute sequence<DOMString> attrs;
|
||||
[Cached, Constant]
|
||||
readonly attribute sequence<DOMString> attrs;
|
||||
};
|
||||
|
||||
dictionary BluetoothAttributeEventInit : EventInit
|
||||
{
|
||||
any attrs = null;
|
||||
required sequence<DOMString> attrs;
|
||||
};
|
||||
|
|
|
@ -96,4 +96,6 @@ dictionary NetworkResultOptions
|
|||
long dns1 = 0;
|
||||
long dns2 = 0;
|
||||
long server = 0;
|
||||
|
||||
DOMString netId = ""; // for "getNetId".
|
||||
};
|
||||
|
|
|
@ -1,667 +0,0 @@
|
|||
/* -*- 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 "UnixSocket.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include <fcntl.h>
|
||||
#include "mozilla/unused.h"
|
||||
|
||||
static const size_t MAX_READ_SIZE = 1 << 16;
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
//
|
||||
// UnixSocketConsumerIO
|
||||
//
|
||||
|
||||
class UnixSocketConsumerIO final : public UnixSocketWatcher
|
||||
, protected SocketIOBase
|
||||
{
|
||||
public:
|
||||
UnixSocketConsumerIO(MessageLoop* mIOLoop,
|
||||
UnixSocketConsumer* aConsumer,
|
||||
UnixSocketConnector* aConnector,
|
||||
const nsACString& aAddress);
|
||||
~UnixSocketConsumerIO();
|
||||
|
||||
void GetSocketAddr(nsAString& aAddrStr) const;
|
||||
SocketConsumerBase* GetConsumer();
|
||||
SocketBase* GetSocketBase();
|
||||
|
||||
// Shutdown state
|
||||
//
|
||||
|
||||
bool IsShutdownOnMainThread() const;
|
||||
void ShutdownOnMainThread();
|
||||
|
||||
bool IsShutdownOnIOThread() const;
|
||||
void ShutdownOnIOThread();
|
||||
|
||||
// Delayed-task handling
|
||||
//
|
||||
|
||||
void SetDelayedConnectTask(CancelableTask* aTask);
|
||||
void ClearDelayedConnectTask();
|
||||
void CancelDelayedConnectTask();
|
||||
|
||||
// Task callback methods
|
||||
//
|
||||
|
||||
/**
|
||||
* Run bind/listen to prepare for further runs of accept()
|
||||
*/
|
||||
void Listen();
|
||||
|
||||
/**
|
||||
* Connect to a socket
|
||||
*/
|
||||
void Connect();
|
||||
|
||||
void Send(UnixSocketRawData* aData);
|
||||
|
||||
// I/O callback methods
|
||||
//
|
||||
|
||||
void OnAccepted(int aFd, const sockaddr_any* aAddr,
|
||||
socklen_t aAddrLen) override;
|
||||
void OnConnected() override;
|
||||
void OnError(const char* aFunction, int aErrno) override;
|
||||
void OnListening() override;
|
||||
void OnSocketCanReceiveWithoutBlocking() override;
|
||||
void OnSocketCanSendWithoutBlocking() override;
|
||||
|
||||
private:
|
||||
void FireSocketError();
|
||||
|
||||
// Set up flags on file descriptor.
|
||||
static bool SetSocketFlags(int aFd);
|
||||
|
||||
/**
|
||||
* Consumer pointer. Non-thread safe RefPtr, so should only be manipulated
|
||||
* directly from main thread. All non-main-thread accesses should happen with
|
||||
* mIO as container.
|
||||
*/
|
||||
RefPtr<UnixSocketConsumer> mConsumer;
|
||||
|
||||
/**
|
||||
* Connector object used to create the connection we are currently using.
|
||||
*/
|
||||
nsAutoPtr<UnixSocketConnector> mConnector;
|
||||
|
||||
/**
|
||||
* If true, do not requeue whatever task we're running
|
||||
*/
|
||||
bool mShuttingDownOnIOThread;
|
||||
|
||||
/**
|
||||
* Address we are connecting to, assuming we are creating a client connection.
|
||||
*/
|
||||
nsCString mAddress;
|
||||
|
||||
/**
|
||||
* Size of the socket address struct
|
||||
*/
|
||||
socklen_t mAddrSize;
|
||||
|
||||
/**
|
||||
* Address struct of the socket currently in use
|
||||
*/
|
||||
sockaddr_any mAddr;
|
||||
|
||||
/**
|
||||
* Task member for delayed connect task. Should only be access on main thread.
|
||||
*/
|
||||
CancelableTask* mDelayedConnectTask;
|
||||
};
|
||||
|
||||
UnixSocketConsumerIO::UnixSocketConsumerIO(MessageLoop* mIOLoop,
|
||||
UnixSocketConsumer* aConsumer,
|
||||
UnixSocketConnector* aConnector,
|
||||
const nsACString& aAddress)
|
||||
: UnixSocketWatcher(mIOLoop)
|
||||
, SocketIOBase(MAX_READ_SIZE)
|
||||
, mConsumer(aConsumer)
|
||||
, mConnector(aConnector)
|
||||
, mShuttingDownOnIOThread(false)
|
||||
, mAddress(aAddress)
|
||||
, mDelayedConnectTask(nullptr)
|
||||
{
|
||||
MOZ_ASSERT(mConsumer);
|
||||
MOZ_ASSERT(mConnector);
|
||||
}
|
||||
|
||||
UnixSocketConsumerIO::~UnixSocketConsumerIO()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(IsShutdownOnMainThread());
|
||||
}
|
||||
|
||||
void
|
||||
UnixSocketConsumerIO::GetSocketAddr(nsAString& aAddrStr) const
|
||||
{
|
||||
if (!mConnector) {
|
||||
NS_WARNING("No connector to get socket address from!");
|
||||
aAddrStr.Truncate();
|
||||
return;
|
||||
}
|
||||
mConnector->GetSocketAddr(mAddr, aAddrStr);
|
||||
}
|
||||
|
||||
SocketConsumerBase*
|
||||
UnixSocketConsumerIO::GetConsumer()
|
||||
{
|
||||
return mConsumer.get();
|
||||
}
|
||||
|
||||
SocketBase*
|
||||
UnixSocketConsumerIO::GetSocketBase()
|
||||
{
|
||||
return GetConsumer();
|
||||
}
|
||||
|
||||
bool
|
||||
UnixSocketConsumerIO::IsShutdownOnMainThread() const
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
return mConsumer == nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
UnixSocketConsumerIO::ShutdownOnMainThread()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!IsShutdownOnMainThread());
|
||||
|
||||
mConsumer = nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
UnixSocketConsumerIO::IsShutdownOnIOThread() const
|
||||
{
|
||||
return mShuttingDownOnIOThread;
|
||||
}
|
||||
|
||||
void
|
||||
UnixSocketConsumerIO::ShutdownOnIOThread()
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(!mShuttingDownOnIOThread);
|
||||
|
||||
Close(); // will also remove fd from I/O loop
|
||||
mShuttingDownOnIOThread = true;
|
||||
}
|
||||
|
||||
void
|
||||
UnixSocketConsumerIO::SetDelayedConnectTask(CancelableTask* aTask)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mDelayedConnectTask = aTask;
|
||||
}
|
||||
|
||||
void
|
||||
UnixSocketConsumerIO::ClearDelayedConnectTask()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mDelayedConnectTask = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
UnixSocketConsumerIO::CancelDelayedConnectTask()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!mDelayedConnectTask) {
|
||||
return;
|
||||
}
|
||||
|
||||
mDelayedConnectTask->Cancel();
|
||||
ClearDelayedConnectTask();
|
||||
}
|
||||
|
||||
void
|
||||
UnixSocketConsumerIO::Listen()
|
||||
{
|
||||
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
|
||||
MOZ_ASSERT(mConnector);
|
||||
|
||||
// This will set things we don't particularly care about, but it will hand
|
||||
// back the correct structure size which is what we do care about.
|
||||
if (!mConnector->CreateAddr(true, mAddrSize, mAddr, nullptr)) {
|
||||
NS_WARNING("Cannot create socket address!");
|
||||
FireSocketError();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsOpen()) {
|
||||
int fd = mConnector->Create();
|
||||
if (fd < 0) {
|
||||
NS_WARNING("Cannot create socket fd!");
|
||||
FireSocketError();
|
||||
return;
|
||||
}
|
||||
if (!SetSocketFlags(fd)) {
|
||||
NS_WARNING("Cannot set socket flags!");
|
||||
FireSocketError();
|
||||
return;
|
||||
}
|
||||
SetFd(fd);
|
||||
|
||||
// calls OnListening on success, or OnError otherwise
|
||||
nsresult rv = UnixSocketWatcher::Listen(
|
||||
reinterpret_cast<struct sockaddr*>(&mAddr), mAddrSize);
|
||||
NS_WARN_IF(NS_FAILED(rv));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UnixSocketConsumerIO::Connect()
|
||||
{
|
||||
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
|
||||
MOZ_ASSERT(mConnector);
|
||||
|
||||
if (!IsOpen()) {
|
||||
int fd = mConnector->Create();
|
||||
if (fd < 0) {
|
||||
NS_WARNING("Cannot create socket fd!");
|
||||
FireSocketError();
|
||||
return;
|
||||
}
|
||||
if (!SetSocketFlags(fd)) {
|
||||
NS_WARNING("Cannot set socket flags!");
|
||||
FireSocketError();
|
||||
return;
|
||||
}
|
||||
SetFd(fd);
|
||||
}
|
||||
|
||||
if (!mConnector->CreateAddr(false, mAddrSize, mAddr, mAddress.get())) {
|
||||
NS_WARNING("Cannot create socket address!");
|
||||
FireSocketError();
|
||||
return;
|
||||
}
|
||||
|
||||
// calls OnConnected() on success, or OnError() otherwise
|
||||
nsresult rv = UnixSocketWatcher::Connect(
|
||||
reinterpret_cast<struct sockaddr*>(&mAddr), mAddrSize);
|
||||
NS_WARN_IF(NS_FAILED(rv));
|
||||
}
|
||||
|
||||
void
|
||||
UnixSocketConsumerIO::Send(UnixSocketRawData* aData)
|
||||
{
|
||||
EnqueueData(aData);
|
||||
AddWatchers(WRITE_WATCHER, false);
|
||||
}
|
||||
|
||||
void
|
||||
UnixSocketConsumerIO::OnAccepted(int aFd,
|
||||
const sockaddr_any* aAddr,
|
||||
socklen_t aAddrLen)
|
||||
{
|
||||
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
|
||||
MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_LISTENING);
|
||||
MOZ_ASSERT(aAddr);
|
||||
MOZ_ASSERT(aAddrLen > 0 && (size_t)aAddrLen <= sizeof(mAddr));
|
||||
|
||||
memcpy (&mAddr, aAddr, aAddrLen);
|
||||
mAddrSize = aAddrLen;
|
||||
|
||||
if (!mConnector->SetUp(aFd)) {
|
||||
NS_WARNING("Could not set up socket!");
|
||||
return;
|
||||
}
|
||||
|
||||
RemoveWatchers(READ_WATCHER|WRITE_WATCHER);
|
||||
Close();
|
||||
if (!SetSocketFlags(aFd)) {
|
||||
return;
|
||||
}
|
||||
SetSocket(aFd, SOCKET_IS_CONNECTED);
|
||||
|
||||
nsRefPtr<nsRunnable> r =
|
||||
new SocketIOEventRunnable<UnixSocketConsumerIO>(
|
||||
this, SocketIOEventRunnable<UnixSocketConsumerIO>::CONNECT_SUCCESS);
|
||||
NS_DispatchToMainThread(r);
|
||||
|
||||
AddWatchers(READ_WATCHER, true);
|
||||
if (HasPendingData()) {
|
||||
AddWatchers(WRITE_WATCHER, false);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UnixSocketConsumerIO::OnConnected()
|
||||
{
|
||||
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
|
||||
MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED);
|
||||
|
||||
if (!SetSocketFlags(GetFd())) {
|
||||
NS_WARNING("Cannot set socket flags!");
|
||||
FireSocketError();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mConnector->SetUp(GetFd())) {
|
||||
NS_WARNING("Could not set up socket!");
|
||||
FireSocketError();
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<nsRunnable> r =
|
||||
new SocketIOEventRunnable<UnixSocketConsumerIO>(
|
||||
this, SocketIOEventRunnable<UnixSocketConsumerIO>::CONNECT_SUCCESS);
|
||||
NS_DispatchToMainThread(r);
|
||||
|
||||
AddWatchers(READ_WATCHER, true);
|
||||
if (HasPendingData()) {
|
||||
AddWatchers(WRITE_WATCHER, false);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UnixSocketConsumerIO::OnListening()
|
||||
{
|
||||
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
|
||||
MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_LISTENING);
|
||||
|
||||
if (!mConnector->SetUpListenSocket(GetFd())) {
|
||||
NS_WARNING("Could not set up listen socket!");
|
||||
FireSocketError();
|
||||
return;
|
||||
}
|
||||
|
||||
AddWatchers(READ_WATCHER, true);
|
||||
}
|
||||
|
||||
void
|
||||
UnixSocketConsumerIO::OnError(const char* aFunction, int aErrno)
|
||||
{
|
||||
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
|
||||
|
||||
UnixFdWatcher::OnError(aFunction, aErrno);
|
||||
FireSocketError();
|
||||
}
|
||||
|
||||
void
|
||||
UnixSocketConsumerIO::OnSocketCanReceiveWithoutBlocking()
|
||||
{
|
||||
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
|
||||
MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED); // see bug 990984
|
||||
|
||||
ssize_t res = ReceiveData(GetFd(), this);
|
||||
if (res < 0) {
|
||||
/* I/O error */
|
||||
RemoveWatchers(READ_WATCHER|WRITE_WATCHER);
|
||||
} else if (!res) {
|
||||
/* EOF or peer shutdown */
|
||||
RemoveWatchers(READ_WATCHER);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UnixSocketConsumerIO::OnSocketCanSendWithoutBlocking()
|
||||
{
|
||||
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
|
||||
MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED); // see bug 990984
|
||||
|
||||
nsresult rv = SendPendingData(GetFd(), this);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasPendingData()) {
|
||||
AddWatchers(WRITE_WATCHER, false);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UnixSocketConsumerIO::FireSocketError()
|
||||
{
|
||||
MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
|
||||
|
||||
// Clean up watchers, statuses, fds
|
||||
Close();
|
||||
|
||||
// Tell the main thread we've errored
|
||||
nsRefPtr<nsRunnable> r =
|
||||
new SocketIOEventRunnable<UnixSocketConsumerIO>(
|
||||
this, SocketIOEventRunnable<UnixSocketConsumerIO>::CONNECT_ERROR);
|
||||
|
||||
NS_DispatchToMainThread(r);
|
||||
}
|
||||
|
||||
bool
|
||||
UnixSocketConsumerIO::SetSocketFlags(int aFd)
|
||||
{
|
||||
// Set socket addr to be reused even if kernel is still waiting to close
|
||||
int n = 1;
|
||||
if (setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set close-on-exec bit.
|
||||
int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFD));
|
||||
if (-1 == flags) {
|
||||
return false;
|
||||
}
|
||||
flags |= FD_CLOEXEC;
|
||||
if (-1 == TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFD, flags))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set non-blocking status flag.
|
||||
flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL));
|
||||
if (-1 == flags) {
|
||||
return false;
|
||||
}
|
||||
flags |= O_NONBLOCK;
|
||||
if (-1 == TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// Socket tasks
|
||||
//
|
||||
|
||||
class ListenTask final : public SocketIOTask<UnixSocketConsumerIO>
|
||||
{
|
||||
public:
|
||||
ListenTask(UnixSocketConsumerIO* aIO)
|
||||
: SocketIOTask<UnixSocketConsumerIO>(aIO)
|
||||
{ }
|
||||
|
||||
void Run() override
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
if (!IsCanceled()) {
|
||||
GetIO()->Listen();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class ConnectTask final : public SocketIOTask<UnixSocketConsumerIO>
|
||||
{
|
||||
public:
|
||||
ConnectTask(UnixSocketConsumerIO* aIO)
|
||||
: SocketIOTask<UnixSocketConsumerIO>(aIO)
|
||||
{ }
|
||||
|
||||
void Run() override
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(!IsCanceled());
|
||||
|
||||
GetIO()->Connect();
|
||||
}
|
||||
};
|
||||
|
||||
class DelayedConnectTask final : public SocketIOTask<UnixSocketConsumerIO>
|
||||
{
|
||||
public:
|
||||
DelayedConnectTask(UnixSocketConsumerIO* aIO)
|
||||
: SocketIOTask<UnixSocketConsumerIO>(aIO)
|
||||
{ }
|
||||
|
||||
void Run() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (IsCanceled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
UnixSocketConsumerIO* io = GetIO();
|
||||
if (io->IsShutdownOnMainThread()) {
|
||||
return;
|
||||
}
|
||||
|
||||
io->ClearDelayedConnectTask();
|
||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new ConnectTask(io));
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// UnixSocketConsumer
|
||||
//
|
||||
|
||||
UnixSocketConsumer::UnixSocketConsumer()
|
||||
: mIO(nullptr)
|
||||
{ }
|
||||
|
||||
UnixSocketConsumer::~UnixSocketConsumer()
|
||||
{
|
||||
MOZ_ASSERT(!mIO);
|
||||
}
|
||||
|
||||
bool
|
||||
UnixSocketConsumer::SendSocketData(UnixSocketRawData* aData)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (!mIO) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!mIO->IsShutdownOnMainThread());
|
||||
XRE_GetIOMessageLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
new SocketIOSendTask<UnixSocketConsumerIO, UnixSocketRawData>(mIO, aData));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
UnixSocketConsumer::SendSocketData(const nsACString& aStr)
|
||||
{
|
||||
if (aStr.Length() > MAX_READ_SIZE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsAutoPtr<UnixSocketRawData> data(
|
||||
new UnixSocketRawData(aStr.BeginReading(), aStr.Length()));
|
||||
|
||||
if (!SendSocketData(data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unused << data.forget();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
UnixSocketConsumer::CloseSocket()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (!mIO) {
|
||||
return;
|
||||
}
|
||||
|
||||
mIO->CancelDelayedConnectTask();
|
||||
|
||||
// From this point on, we consider mIO as being deleted.
|
||||
// We sever the relationship here so any future calls to listen or connect
|
||||
// will create a new implementation.
|
||||
mIO->ShutdownOnMainThread();
|
||||
|
||||
XRE_GetIOMessageLoop()->PostTask(
|
||||
FROM_HERE, new SocketIOShutdownTask<UnixSocketConsumerIO>(mIO));
|
||||
|
||||
mIO = nullptr;
|
||||
|
||||
NotifyDisconnect();
|
||||
}
|
||||
|
||||
void
|
||||
UnixSocketConsumer::GetSocketAddr(nsAString& aAddrStr)
|
||||
{
|
||||
aAddrStr.Truncate();
|
||||
if (!mIO || GetConnectionStatus() != SOCKET_CONNECTED) {
|
||||
NS_WARNING("No socket currently open!");
|
||||
return;
|
||||
}
|
||||
mIO->GetSocketAddr(aAddrStr);
|
||||
}
|
||||
|
||||
bool
|
||||
UnixSocketConsumer::ConnectSocket(UnixSocketConnector* aConnector,
|
||||
const char* aAddress,
|
||||
int aDelayMs)
|
||||
{
|
||||
MOZ_ASSERT(aConnector);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<UnixSocketConnector> connector(aConnector);
|
||||
|
||||
if (mIO) {
|
||||
NS_WARNING("Socket already connecting/connected!");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCString addr(aAddress);
|
||||
MessageLoop* ioLoop = XRE_GetIOMessageLoop();
|
||||
mIO = new UnixSocketConsumerIO(ioLoop, this, connector.forget(), addr);
|
||||
SetConnectionStatus(SOCKET_CONNECTING);
|
||||
if (aDelayMs > 0) {
|
||||
DelayedConnectTask* connectTask = new DelayedConnectTask(mIO);
|
||||
mIO->SetDelayedConnectTask(connectTask);
|
||||
MessageLoop::current()->PostDelayedTask(FROM_HERE, connectTask, aDelayMs);
|
||||
} else {
|
||||
ioLoop->PostTask(FROM_HERE, new ConnectTask(mIO));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
UnixSocketConsumer::ListenSocket(UnixSocketConnector* aConnector)
|
||||
{
|
||||
MOZ_ASSERT(aConnector);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoPtr<UnixSocketConnector> connector(aConnector);
|
||||
|
||||
if (mIO) {
|
||||
NS_WARNING("Socket already connecting/connected!");
|
||||
return false;
|
||||
}
|
||||
|
||||
mIO = new UnixSocketConsumerIO(
|
||||
XRE_GetIOMessageLoop(), this, connector.forget(), EmptyCString());
|
||||
SetConnectionStatus(SOCKET_LISTENING);
|
||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new ListenTask(mIO));
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
|
@ -1,95 +0,0 @@
|
|||
/* -*- 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_unixsocket_h
|
||||
#define mozilla_ipc_unixsocket_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/ipc/SocketBase.h"
|
||||
#include "mozilla/ipc/UnixSocketWatcher.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "UnixSocketConnector.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
class UnixSocketConsumerIO;
|
||||
|
||||
class UnixSocketConsumer : public SocketConsumerBase
|
||||
{
|
||||
protected:
|
||||
virtual ~UnixSocketConsumer();
|
||||
|
||||
public:
|
||||
UnixSocketConsumer();
|
||||
|
||||
/**
|
||||
* Queue data to be sent to the socket on the IO thread. Can only be called on
|
||||
* originating thread.
|
||||
*
|
||||
* @param aMessage Data to be sent to socket
|
||||
*
|
||||
* @return true if data is queued, false otherwise (i.e. not connected)
|
||||
*/
|
||||
bool SendSocketData(UnixSocketRawData* aMessage);
|
||||
|
||||
/**
|
||||
* Convenience function for sending strings to the socket (common in bluetooth
|
||||
* profile usage). Converts to a UnixSocketRawData struct. Can only be called
|
||||
* on originating thread.
|
||||
*
|
||||
* @param aMessage String to be sent to socket
|
||||
*
|
||||
* @return true if data is queued, false otherwise (i.e. not connected)
|
||||
*/
|
||||
bool SendSocketData(const nsACString& aMessage);
|
||||
|
||||
/**
|
||||
* 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 aAddress Address to connect to.
|
||||
* @param aDelayMs Time delay in milli-seconds.
|
||||
*
|
||||
* @return true on connect task started, false otherwise.
|
||||
*/
|
||||
bool ConnectSocket(UnixSocketConnector* aConnector,
|
||||
const char* aAddress,
|
||||
int aDelayMs = 0);
|
||||
|
||||
/**
|
||||
* Starts a task on the socket that will try to accept a new connection in a
|
||||
* non-blocking manner.
|
||||
*
|
||||
* @param aConnector Connector object for socket type specific functions
|
||||
*
|
||||
* @return true on listen started, false otherwise
|
||||
*/
|
||||
bool ListenSocket(UnixSocketConnector* aConnector);
|
||||
|
||||
/**
|
||||
* Queues the internal representation of socket for deletion. Can be called
|
||||
* from main thread.
|
||||
*/
|
||||
void CloseSocket();
|
||||
|
||||
/**
|
||||
* Get the current sockaddr for the socket
|
||||
*/
|
||||
void GetSocketAddr(nsAString& aAddrStr);
|
||||
|
||||
private:
|
||||
UnixSocketConsumerIO* mIO;
|
||||
};
|
||||
|
||||
} // namespace ipc
|
||||
} // namepsace mozilla
|
||||
|
||||
#endif // mozilla_ipc_unixsocket_h
|
|
@ -9,7 +9,6 @@ EXPORTS.mozilla.ipc += [
|
|||
'ListenSocket.h',
|
||||
'SocketBase.h',
|
||||
'StreamSocket.h',
|
||||
'UnixSocket.h',
|
||||
'UnixSocketConnector.h'
|
||||
]
|
||||
|
||||
|
@ -18,7 +17,6 @@ SOURCES += [
|
|||
'ListenSocket.cpp',
|
||||
'SocketBase.cpp',
|
||||
'StreamSocket.cpp',
|
||||
'UnixSocket.cpp',
|
||||
'UnixSocketConnector.cpp'
|
||||
]
|
||||
|
||||
|
|
|
@ -538,8 +538,8 @@ SelectionCarets::UpdateSelectionCarets()
|
|||
SetStartFrameVisibility(startFrameVisible);
|
||||
SetEndFrameVisibility(endFrameVisible);
|
||||
|
||||
SetStartFramePos(firstRectInRootFrame.BottomLeft());
|
||||
SetEndFramePos(lastRectInRootFrame.BottomRight());
|
||||
SetStartFramePos(firstRectInRootFrame);
|
||||
SetEndFramePos(lastRectInRootFrame);
|
||||
SetVisibility(true);
|
||||
|
||||
// Use half of the first(last) rect as the dragup(dragdown) boundary
|
||||
|
@ -892,7 +892,7 @@ SelectionCarets::SetSelectionDirection(nsDirection aDir)
|
|||
}
|
||||
|
||||
static void
|
||||
SetFramePos(dom::Element* aElement, const nsPoint& aPosition)
|
||||
SetFramePos(dom::Element* aElement, const nsRect& aCaretRect)
|
||||
{
|
||||
if (!aElement) {
|
||||
return;
|
||||
|
@ -900,9 +900,11 @@ SetFramePos(dom::Element* aElement, const nsPoint& aPosition)
|
|||
|
||||
nsAutoString styleStr;
|
||||
styleStr.AppendLiteral("left: ");
|
||||
styleStr.AppendFloat(nsPresContext::AppUnitsToFloatCSSPixels(aPosition.x));
|
||||
styleStr.AppendFloat(nsPresContext::AppUnitsToFloatCSSPixels(aCaretRect.Center().x));
|
||||
styleStr.AppendLiteral("px; top: ");
|
||||
styleStr.AppendFloat(nsPresContext::AppUnitsToFloatCSSPixels(aPosition.y));
|
||||
styleStr.AppendFloat(nsPresContext::AppUnitsToFloatCSSPixels(aCaretRect.y));
|
||||
styleStr.AppendLiteral("px; padding-top: ");
|
||||
styleStr.AppendFloat(nsPresContext::AppUnitsToFloatCSSPixels(aCaretRect.height));
|
||||
styleStr.AppendLiteral("px;");
|
||||
|
||||
SELECTIONCARETS_LOG_STATIC("Set style: %s",
|
||||
|
@ -912,17 +914,19 @@ SetFramePos(dom::Element* aElement, const nsPoint& aPosition)
|
|||
}
|
||||
|
||||
void
|
||||
SelectionCarets::SetStartFramePos(const nsPoint& aPosition)
|
||||
SelectionCarets::SetStartFramePos(const nsRect& aCaretRect)
|
||||
{
|
||||
SELECTIONCARETS_LOG("x=%d, y=%d", aPosition.x, aPosition.y);
|
||||
SetFramePos(mPresShell->GetSelectionCaretsStartElement(), aPosition);
|
||||
SELECTIONCARETS_LOG("x=%d, y=%d, w=%d, h=%d",
|
||||
aCaretRect.x, aCaretRect.y, aCaretRect.width, aCaretRect.height);
|
||||
SetFramePos(mPresShell->GetSelectionCaretsStartElement(), aCaretRect);
|
||||
}
|
||||
|
||||
void
|
||||
SelectionCarets::SetEndFramePos(const nsPoint& aPosition)
|
||||
SelectionCarets::SetEndFramePos(const nsRect& aCaretRect)
|
||||
{
|
||||
SELECTIONCARETS_LOG("x=%d, y=%d", aPosition.y, aPosition.y);
|
||||
SetFramePos(mPresShell->GetSelectionCaretsEndElement(), aPosition);
|
||||
SELECTIONCARETS_LOG("x=%d, y=%d, w=%d, h=%d",
|
||||
aCaretRect.x, aCaretRect.y, aCaretRect.width, aCaretRect.height);
|
||||
SetFramePos(mPresShell->GetSelectionCaretsEndElement(), aCaretRect);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -147,16 +147,16 @@ private:
|
|||
void SetSelectionDirection(nsDirection aDir);
|
||||
|
||||
/**
|
||||
* Move start frame of selection caret to given position.
|
||||
* Move start frame of selection caret based on current caret pos.
|
||||
* In app units.
|
||||
*/
|
||||
void SetStartFramePos(const nsPoint& aPosition);
|
||||
void SetStartFramePos(const nsRect& aCaretRect);
|
||||
|
||||
/**
|
||||
* Move end frame of selection caret to given position.
|
||||
* Move end frame of selection caret based on current caret pos.
|
||||
* In app units.
|
||||
*/
|
||||
void SetEndFramePos(const nsPoint& aPosition);
|
||||
void SetEndFramePos(const nsRect& aCaretRect);
|
||||
|
||||
/**
|
||||
* Check if aPosition is on the start or end frame of the
|
||||
|
|
|
@ -249,7 +249,7 @@ TouchCaret::GetCaretYCenterPosition()
|
|||
}
|
||||
|
||||
void
|
||||
TouchCaret::SetTouchFramePos(const nsPoint& aOrigin)
|
||||
TouchCaret::SetTouchFramePos(const nsRect& aCaretRect)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell);
|
||||
if (!presShell) {
|
||||
|
@ -263,14 +263,17 @@ TouchCaret::SetTouchFramePos(const nsPoint& aOrigin)
|
|||
|
||||
// Convert aOrigin to CSS pixels.
|
||||
nsRefPtr<nsPresContext> presContext = presShell->GetPresContext();
|
||||
int32_t x = presContext->AppUnitsToIntCSSPixels(aOrigin.x);
|
||||
int32_t y = presContext->AppUnitsToIntCSSPixels(aOrigin.y);
|
||||
int32_t x = presContext->AppUnitsToIntCSSPixels(aCaretRect.Center().x);
|
||||
int32_t y = presContext->AppUnitsToIntCSSPixels(aCaretRect.y);
|
||||
int32_t padding = presContext->AppUnitsToIntCSSPixels(aCaretRect.height);
|
||||
|
||||
nsAutoString styleStr;
|
||||
styleStr.AppendLiteral("left: ");
|
||||
styleStr.AppendInt(x);
|
||||
styleStr.AppendLiteral("px; top: ");
|
||||
styleStr.AppendInt(y);
|
||||
styleStr.AppendLiteral("px; padding-top: ");
|
||||
styleStr.AppendInt(padding);
|
||||
styleStr.AppendLiteral("px;");
|
||||
|
||||
TOUCHCARET_LOG("Set style: %s", NS_ConvertUTF16toUTF8(styleStr).get());
|
||||
|
@ -483,32 +486,27 @@ TouchCaret::UpdatePosition()
|
|||
{
|
||||
MOZ_ASSERT(mVisible);
|
||||
|
||||
nsPoint pos = GetTouchCaretPosition();
|
||||
pos = ClampPositionToScrollFrame(pos);
|
||||
SetTouchFramePos(pos);
|
||||
nsRect rect = GetTouchCaretRect();
|
||||
rect = ClampRectToScrollFrame(rect);
|
||||
SetTouchFramePos(rect);
|
||||
}
|
||||
|
||||
nsPoint
|
||||
TouchCaret::GetTouchCaretPosition()
|
||||
nsRect
|
||||
TouchCaret::GetTouchCaretRect()
|
||||
{
|
||||
nsRect focusRect;
|
||||
nsIFrame* focusFrame = GetCaretFocusFrame(&focusRect);
|
||||
nsIFrame* rootFrame = GetRootFrame();
|
||||
|
||||
// Position of the touch caret relative to focusFrame.
|
||||
nsPoint pos = nsPoint(focusRect.x + (focusRect.width / 2),
|
||||
focusRect.y + focusRect.height);
|
||||
|
||||
// Transform the position to make it relative to root frame.
|
||||
nsLayoutUtils::TransformPoint(focusFrame, rootFrame, pos);
|
||||
nsLayoutUtils::TransformRect(focusFrame, rootFrame, focusRect);
|
||||
|
||||
return pos;
|
||||
return focusRect;
|
||||
}
|
||||
|
||||
nsPoint
|
||||
TouchCaret::ClampPositionToScrollFrame(const nsPoint& aPosition)
|
||||
nsRect
|
||||
TouchCaret::ClampRectToScrollFrame(const nsRect& aRect)
|
||||
{
|
||||
nsPoint pos = aPosition;
|
||||
nsRect rect = aRect;
|
||||
nsIFrame* focusFrame = GetCaretFocusFrame();
|
||||
nsIFrame* rootFrame = GetRootFrame();
|
||||
|
||||
|
@ -522,7 +520,7 @@ TouchCaret::ClampPositionToScrollFrame(const nsPoint& aPosition)
|
|||
|
||||
// Clamp the touch caret in the scroll port.
|
||||
nsLayoutUtils::TransformRect(closestScrollFrame, rootFrame, visualRect);
|
||||
pos = visualRect.ClampPoint(pos);
|
||||
rect = rect.Intersect(visualRect);
|
||||
|
||||
// Get next ancestor scroll frame.
|
||||
closestScrollFrame =
|
||||
|
@ -530,7 +528,7 @@ TouchCaret::ClampPositionToScrollFrame(const nsPoint& aPosition)
|
|||
nsGkAtoms::scrollFrame);
|
||||
}
|
||||
|
||||
return pos;
|
||||
return rect;
|
||||
}
|
||||
|
||||
/* static */void
|
||||
|
|
|
@ -117,22 +117,22 @@ private:
|
|||
nscoord GetCaretYCenterPosition();
|
||||
|
||||
/**
|
||||
* Retrieve the position of the touch caret.
|
||||
* The returned point is relative to the canvas frame.
|
||||
* Retrieve the rect of the touch caret.
|
||||
* The returned rect is relative to the canvas frame.
|
||||
*/
|
||||
nsPoint GetTouchCaretPosition();
|
||||
nsRect GetTouchCaretRect();
|
||||
|
||||
/**
|
||||
* Clamp the position of the touch caret to the scroll frame boundary.
|
||||
* The returned point is relative to the canvas frame.
|
||||
* The returned rect is relative to the canvas frame.
|
||||
*/
|
||||
nsPoint ClampPositionToScrollFrame(const nsPoint& aPosition);
|
||||
nsRect ClampRectToScrollFrame(const nsRect& aRect);
|
||||
|
||||
/**
|
||||
* Set the position of the touch caret.
|
||||
* Touch caret is an absolute positioned div.
|
||||
*/
|
||||
void SetTouchFramePos(const nsPoint& aOrigin);
|
||||
void SetTouchFramePos(const nsRect& aRect);
|
||||
|
||||
void LaunchExpirationTimer();
|
||||
void CancelExpirationTimer();
|
||||
|
|
|
@ -510,9 +510,13 @@ nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
|
||||
nsIFrame* kid;
|
||||
for (kid = GetFirstPrincipalChild(); kid; kid = kid->GetNextSibling()) {
|
||||
// Skip touch caret frame if we do not build caret.
|
||||
if (!aBuilder->IsBuildingCaret() && kid->GetContent() == mTouchCaretElement) {
|
||||
continue;
|
||||
// Skip touch/selection caret frame if we do not build caret.
|
||||
if (!aBuilder->IsBuildingCaret()) {
|
||||
if(kid->GetContent() == mTouchCaretElement ||
|
||||
kid->GetContent() == mSelectionCaretsStartElement||
|
||||
kid->GetContent() == mSelectionCaretsEndElement) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Put our child into its own pseudo-stack.
|
||||
|
|
|
@ -318,11 +318,16 @@ div:-moz-native-anonymous.moz-touchcaret,
|
|||
div:-moz-native-anonymous.moz-selectioncaret-left,
|
||||
div:-moz-native-anonymous.moz-selectioncaret-right {
|
||||
position: fixed;
|
||||
width: 44px;
|
||||
height: 47px;
|
||||
}
|
||||
|
||||
div:-moz-native-anonymous.moz-selectioncaret-left > div,
|
||||
div:-moz-native-anonymous.moz-selectioncaret-right > div {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
div:-moz-native-anonymous.moz-touchcaret,
|
||||
|
@ -330,10 +335,9 @@ div:-moz-native-anonymous.moz-selectioncaret-left,
|
|||
div:-moz-native-anonymous.moz-selectioncaret-right,
|
||||
div:-moz-native-anonymous.moz-selectioncaret-left > div,
|
||||
div:-moz-native-anonymous.moz-selectioncaret-right > div {
|
||||
width: 44px;
|
||||
height: 47px;
|
||||
background-position: center center;
|
||||
background-size: 100% 100%;
|
||||
background-position: center bottom;
|
||||
background-size: 100%;
|
||||
background-repeat: no-repeat;
|
||||
z-index: 2147483647;
|
||||
}
|
||||
|
||||
|
|
|
@ -844,7 +844,7 @@ class MachCommands(MachCommandBase):
|
|||
elif conditions.is_emulator(self):
|
||||
return self.run_mochitest_remote(test_paths, **kwargs)
|
||||
elif conditions.is_b2g_desktop(self):
|
||||
return self.run_b2g_desktop(test_paths, **kwargs)
|
||||
return self.run_mochitest_b2g_desktop(test_paths, **kwargs)
|
||||
elif conditions.is_android(self):
|
||||
return self.run_mochitest_android(test_paths, **kwargs)
|
||||
|
||||
|
|
|
@ -93,6 +93,67 @@ NS_NewThread(nsIThread** aResult, nsIRunnable* aEvent, uint32_t aStackSize)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
#if defined(MOZ_NUWA_PROCESS) && !defined(XPCOM_GLUE_AVOID_NSPR)
|
||||
|
||||
namespace {
|
||||
class IgnoreThreadStatusRunnable : public nsIRunnable
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIRUNNABLE
|
||||
|
||||
private:
|
||||
virtual ~IgnoreThreadStatusRunnable() = default;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(IgnoreThreadStatusRunnable, nsIRunnable)
|
||||
|
||||
NS_IMETHODIMP IgnoreThreadStatusRunnable::Run(void)
|
||||
{
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
nsThreadManager::get()->SetIgnoreThreadStatus();
|
||||
return NS_OK;
|
||||
#endif
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
} // Anonymous namespace.
|
||||
#endif // defined(MOZ_NUWA_PROCESS) && !defined(XPCOM_GLUE_AVOID_NSPR)
|
||||
|
||||
NS_METHOD
|
||||
NS_NewUnmonitoredThread(nsIThread** aResult,
|
||||
nsIRunnable* aEvent,
|
||||
uint32_t aStackSize)
|
||||
{
|
||||
#if defined(MOZ_NUWA_PROCESS) && !defined(XPCOM_GLUE_AVOID_NSPR)
|
||||
// Hold a ref while dispatching the initial event to match NS_NewThread()
|
||||
nsCOMPtr<nsIThread> thread;
|
||||
nsresult rv = NS_NewThread(getter_AddRefs(thread), nullptr, aStackSize);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> ignoreme = new IgnoreThreadStatusRunnable();
|
||||
rv = thread->Dispatch(ignoreme, NS_DISPATCH_NORMAL);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (aEvent) {
|
||||
rv = thread->Dispatch(aEvent, NS_DISPATCH_NORMAL);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
*aResult = nullptr;
|
||||
thread.swap(*aResult);
|
||||
return rv;
|
||||
#else
|
||||
return NS_NewThread(aResult, aEvent, aStackSize);
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
NS_GetCurrentThread(nsIThread** aResult)
|
||||
{
|
||||
|
|
|
@ -61,6 +61,17 @@ NS_NewThread(nsIThread** aResult,
|
|||
nsIRunnable* aInitialEvent = nullptr,
|
||||
uint32_t aStackSize = nsIThreadManager::DEFAULT_STACK_SIZE);
|
||||
|
||||
/**
|
||||
* Create a new thread that is ignored in thread status monitoring by default on
|
||||
* platforms with Nuwa process enabled. On non-Nuwa platforms, this function is
|
||||
* identical to NS_NewThread().
|
||||
*/
|
||||
extern NS_METHOD
|
||||
NS_NewUnmonitoredThread(nsIThread** aResult,
|
||||
nsIRunnable* aInitialEvent = nullptr,
|
||||
uint32_t aStackSize =
|
||||
nsIThreadManager::DEFAULT_STACK_SIZE);
|
||||
|
||||
/**
|
||||
* Creates a named thread, otherwise the same as NS_NewThread
|
||||
*/
|
||||
|
|
Загрузка…
Ссылка в новой задаче