Merge m-c to inbound a=merge CLOSED TREE

This commit is contained in:
Wes Kocher 2015-03-05 15:39:58 -08:00
commit 54e2f5bc11
63 changed files with 1365 additions and 964 deletions

View File

@ -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="0017f2bbc63781a5409644b664d80ebaa1543653"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="7a91c16bfa348be8b25e09719178efa051512988"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2e85143db5d5f6edc4c2b97263c02b558fee757e"/>
<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="dc71d1dd75366780c713010a6be48bf8fead2379"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="5c53c636b768f7d3ed3747aecc2b7fecf3a36894"/>
<!-- 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"/>
@ -121,7 +121,7 @@
<project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="8f7d94ac711af4678169805137c6c42def39b3ed"/>
<project name="platform/system/netd" path="system/netd" revision="3ae56364946d4a5bf5a5f83f12f9a45a30398e33"/>
<project name="platform/system/security" path="system/security" revision="ee8068b9e7bfb2770635062fc9c2035be2142bd8"/>
<project name="platform/system/vold" path="system/vold" revision="2e43efe1b30d0b98574d293059556aebd2f46454"/>
<project name="platform/system/vold" path="system/vold" revision="1a4ed05ce98de851c867ace572f2a97c0b50bb2e"/>
<!--original fetch url was http://sprdsource.spreadtrum.com:8085/b2g/android-->
<remote fetch="https://git.mozilla.org/external/sprd-aosp" name="sprd-aosp"/>
<default remote="sprd-aosp" revision="sprdb2g_gonk4.4" sync-j="4"/>

View File

@ -19,13 +19,13 @@
<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="0017f2bbc63781a5409644b664d80ebaa1543653"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="7a91c16bfa348be8b25e09719178efa051512988"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2e85143db5d5f6edc4c2b97263c02b558fee757e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="93f9ba577f68d772093987c2f1c0a4ae293e1802"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="97c3d9b8b87774ca7a08c89145e95b55652459ef"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="dc71d1dd75366780c713010a6be48bf8fead2379"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="5c53c636b768f7d3ed3747aecc2b7fecf3a36894"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
<project name="platform_bionic" path="bionic" remote="b2g" revision="e2b3733ba3fa5e3f404e983d2e4142b1f6b1b846"/>

View File

@ -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="0017f2bbc63781a5409644b664d80ebaa1543653"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="7a91c16bfa348be8b25e09719178efa051512988"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2e85143db5d5f6edc4c2b97263c02b558fee757e"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="dc71d1dd75366780c713010a6be48bf8fead2379"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="5c53c636b768f7d3ed3747aecc2b7fecf3a36894"/>
<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="2eac5a8f931ab1c4aa41be7ac02db8a821df6efc"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="95faf8d85851de4a87d351b424c8c2f3cde3aa5b"/>
<project name="android-sdk" path="sdk" remote="b2g" revision="8b1365af38c9a653df97349ee53a3f5d64fd590a"/>
<project name="darwinstreamingserver" path="system/darwinstreamingserver" remote="b2g" revision="cf85968c7f85e0ec36e72c87ceb4837a943b8af6"/>
</manifest>

View File

@ -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="0017f2bbc63781a5409644b664d80ebaa1543653"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="7a91c16bfa348be8b25e09719178efa051512988"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2e85143db5d5f6edc4c2b97263c02b558fee757e"/>
<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="dc71d1dd75366780c713010a6be48bf8fead2379"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="5c53c636b768f7d3ed3747aecc2b7fecf3a36894"/>
<!-- 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"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="52775e03a2d8532429dff579cb2cd56718e488c3">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0017f2bbc63781a5409644b664d80ebaa1543653"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="7a91c16bfa348be8b25e09719178efa051512988"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2e85143db5d5f6edc4c2b97263c02b558fee757e"/>
<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="dc71d1dd75366780c713010a6be48bf8fead2379"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="5c53c636b768f7d3ed3747aecc2b7fecf3a36894"/>
<!-- 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="50d1ca4ab8add54523b7bc692860d57e8ee4c0d1"/>
<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="fb3845864573857677f9b500040a8f011eaf5078"/>

View File

@ -19,13 +19,13 @@
<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="0017f2bbc63781a5409644b664d80ebaa1543653"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="7a91c16bfa348be8b25e09719178efa051512988"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2e85143db5d5f6edc4c2b97263c02b558fee757e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="93f9ba577f68d772093987c2f1c0a4ae293e1802"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="97c3d9b8b87774ca7a08c89145e95b55652459ef"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="dc71d1dd75366780c713010a6be48bf8fead2379"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="5c53c636b768f7d3ed3747aecc2b7fecf3a36894"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
<project name="platform_bionic" path="bionic" remote="b2g" revision="e2b3733ba3fa5e3f404e983d2e4142b1f6b1b846"/>

View File

@ -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="0017f2bbc63781a5409644b664d80ebaa1543653"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="7a91c16bfa348be8b25e09719178efa051512988"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2e85143db5d5f6edc4c2b97263c02b558fee757e"/>
<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="dc71d1dd75366780c713010a6be48bf8fead2379"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="5c53c636b768f7d3ed3747aecc2b7fecf3a36894"/>
<!-- 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="2eac5a8f931ab1c4aa41be7ac02db8a821df6efc"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="95faf8d85851de4a87d351b424c8c2f3cde3aa5b"/>
<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"/>

View File

@ -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="0017f2bbc63781a5409644b664d80ebaa1543653"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="7a91c16bfa348be8b25e09719178efa051512988"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2e85143db5d5f6edc4c2b97263c02b558fee757e"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="dc71d1dd75366780c713010a6be48bf8fead2379"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="5c53c636b768f7d3ed3747aecc2b7fecf3a36894"/>
<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="2eac5a8f931ab1c4aa41be7ac02db8a821df6efc"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="95faf8d85851de4a87d351b424c8c2f3cde3aa5b"/>
<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"/>

View File

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "0017f2bbc63781a5409644b664d80ebaa1543653",
"git_revision": "7a91c16bfa348be8b25e09719178efa051512988",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "2f6fbd430b0ee8042f103c52e4ead2d87f37e22e",
"revision": "61047a7d0f14b8c435f7a5f8f3283f024b5518be",
"repo_path": "integration/gaia-central"
}

View File

@ -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="0017f2bbc63781a5409644b664d80ebaa1543653"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="7a91c16bfa348be8b25e09719178efa051512988"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2e85143db5d5f6edc4c2b97263c02b558fee757e"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="c42985975f2bbc42859b9136ed348186d989b93d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="dc71d1dd75366780c713010a6be48bf8fead2379"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="5c53c636b768f7d3ed3747aecc2b7fecf3a36894"/>
<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="2eac5a8f931ab1c4aa41be7ac02db8a821df6efc"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="95faf8d85851de4a87d351b424c8c2f3cde3aa5b"/>
<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"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="52775e03a2d8532429dff579cb2cd56718e488c3">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0017f2bbc63781a5409644b664d80ebaa1543653"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="7a91c16bfa348be8b25e09719178efa051512988"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2e85143db5d5f6edc4c2b97263c02b558fee757e"/>
<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="dc71d1dd75366780c713010a6be48bf8fead2379"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="5c53c636b768f7d3ed3747aecc2b7fecf3a36894"/>
<!-- 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="50d1ca4ab8add54523b7bc692860d57e8ee4c0d1"/>
<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="fb3845864573857677f9b500040a8f011eaf5078"/>
@ -157,5 +157,5 @@
<project name="platform/hardware/qcom/sensors" path="hardware/qcom/sensors" revision="3724fd91ef5183684d97e2bf1d7ff948faabe090"/>
<project name="platform/hardware/qcom/wlan" path="hardware/qcom/wlan" revision="2e54754cc0529d26ccac37ed291600048adbf6c0"/>
<project name="platform/hardware/ril" path="hardware/ril" revision="71dfa8228ad0d6cdf6bac0426ac59404ab74b7f3"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="2eac5a8f931ab1c4aa41be7ac02db8a821df6efc"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="95faf8d85851de4a87d351b424c8c2f3cde3aa5b"/>
</manifest>

View File

@ -451,6 +451,8 @@
@RESPATH@/components/NetworkStatsManager.manifest
@RESPATH@/components/NetworkStatsServiceProxy.js
@RESPATH@/components/NetworkStatsServiceProxy.manifest
@RESPATH@/components/TetheringService.js
@RESPATH@/components/TetheringService.manifest
@RESPATH@/components/WifiWorker.js
@RESPATH@/components/WifiWorker.manifest
#endif // MOZ_WIDGET_GONK

View File

@ -1887,10 +1887,8 @@ pref("dom.ipc.reportProcessHangs", false);
pref("dom.ipc.reportProcessHangs", true);
#endif
#ifndef NIGHTLY_BUILD
// Disable reader mode by default.
pref("reader.parse-on-load.enabled", false);
#endif
// Disable ReadingList by default.
pref("browser.readinglist.enabled", false);

View File

@ -28,6 +28,12 @@ richlistitem.download[active] {
.download-state:not(:-moz-any([state="2"], /* Failed */
[state="4"]) /* Paused */)
.downloadCancelMenuItem,
/* Blocked (dirty) downloads that have not been confirmed and
have temporary data. */
.download-state:not( [state="8"] /* Blocked (dirty) */)
.downloadUnblockMenuItem,
.download-state[state="8"]:not(.temporary-block)
.downloadUnblockMenuItem,
.download-state[state]:not(:-moz-any([state="1"], /* Finished */
[state="2"], /* Failed */
[state="3"], /* Canceled */

View File

@ -36,9 +36,9 @@ const DOWNLOAD_META_DATA_ANNO = "downloads/metaData";
const DOWNLOAD_VIEW_SUPPORTED_COMMANDS =
["cmd_delete", "cmd_copy", "cmd_paste", "cmd_selectAll",
"downloadsCmd_pauseResume", "downloadsCmd_cancel",
"downloadsCmd_open", "downloadsCmd_show", "downloadsCmd_retry",
"downloadsCmd_openReferrer", "downloadsCmd_clearDownloads"];
"downloadsCmd_pauseResume", "downloadsCmd_cancel", "downloadsCmd_unblock",
"downloadsCmd_confirmBlock", "downloadsCmd_open", "downloadsCmd_show",
"downloadsCmd_retry", "downloadsCmd_openReferrer", "downloadsCmd_clearDownloads"];
/**
* Represents a download from the browser history. It implements part of the
@ -301,6 +301,11 @@ HistoryDownloadElementShell.prototype = {
},
onChanged() {
// This cannot be placed within onStateChanged because
// when a download goes from hasBlockedData to !hasBlockedData
// it will still remain in the same state.
this.element.classList.toggle("temporary-block",
!!this.download.hasBlockedData);
this._updateProgress();
},
@ -336,6 +341,9 @@ HistoryDownloadElementShell.prototype = {
return this.download.stopped;
case "downloadsCmd_cancel":
return !!this._sessionDownload;
case "downloadsCmd_confirmBlock":
case "downloadsCmd_unblock":
return this.download.hasBlockedData;
}
return false;
},
@ -386,6 +394,19 @@ HistoryDownloadElementShell.prototype = {
}
break;
}
case "downloadsCmd_unblock": {
DownloadsCommon.confirmUnblockDownload(DownloadsCommon.BLOCK_VERDICT_MALWARE,
window).then((confirmed) => {
if (confirmed) {
return this.download.unblock();
}
}).catch(Cu.reportError);
break;
}
case "downloadsCmd_confirmBlock": {
this.download.confirmBlock().catch(Cu.reportError);
break;
}
}
},
@ -1274,6 +1295,8 @@ DownloadsPlacesView.prototype = {
let download = element._shell.download;
contextMenu.setAttribute("state",
DownloadsCommon.stateOfDownload(download));
contextMenu.classList.toggle("temporary-block",
!!download.hasBlockedData);
if (!download.stopped) {
// The hasPartialData property of a download may change at any time after

View File

@ -61,6 +61,10 @@
oncommand="goDoCommand('downloadsCmd_pauseResume')"/>
<command id="downloadsCmd_cancel"
oncommand="goDoCommand('downloadsCmd_cancel')"/>
<command id="downloadsCmd_unblock"
oncommand="goDoCommand('downloadsCmd_unblock')"/>
<command id="downloadsCmd_confirmBlock"
oncommand="goDoCommand('downloadsCmd_confirmBlock')"/>
<command id="downloadsCmd_open"
oncommand="goDoCommand('downloadsCmd_open')"/>
<command id="downloadsCmd_show"
@ -86,6 +90,10 @@
class="downloadCancelMenuItem"
label="&cmd.cancel.label;"
accesskey="&cmd.cancel.accesskey;"/>
<menuitem command="downloadsCmd_unblock"
class="downloadUnblockMenuItem"
label="&cmd.unblock.label;"
accesskey="&cmd.unblock.accesskey;"/>
<menuitem command="cmd_delete"
class="downloadRemoveFromHistoryMenuItem"
label="&cmd.removeFromHistory.label;"

View File

@ -34,6 +34,13 @@ richlistitem.download button {
[state="4"]) /* Paused */)
> .downloadCancel,
/* Blocked (dirty) downloads that have not been confirmed and
have temporary data. */
.download-state:not( [state="8"])
> .downloadConfirmBlock,
.download-state[state="8"]:not(.temporary-block)
> .downloadConfirmBlock,
.download-state[state]:not(:-moz-any([state="2"], /* Failed */
[state="3"]) /* Canceled */)
> .downloadRetry,

View File

@ -60,6 +60,9 @@
tooltiptext="&cmd.show.label;"
#endif
oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_show');"/>
<xul:button class="downloadButton downloadConfirmBlock"
tooltiptext="&cmd.removeFile.label;"
oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_confirmBlock');"/>
</xul:stack>
</content>
</binding>
@ -103,7 +106,9 @@
tooltiptext="&cmd.show.label;"
#endif
oncommand="goDoCommand('downloadsCmd_show')"/>
<xul:button class="downloadButton downloadConfirmBlock"
tooltiptext="&cmd.removeFile.label;"
oncommand="goDoCommand('downloadsCmd_confirmBlock');"/>
</content>
</binding>

View File

@ -38,6 +38,13 @@ richlistitem[type="download"]:not([selected]) button {
.download-state:not( [state="4"] /* Paused */)
.downloadResumeMenuItem,
/* Blocked (dirty) downloads that have not been confirmed and
have temporary data. */
.download-state:not( [state="8"] /* Blocked (dirty) */)
.downloadUnblockMenuItem,
.download-state[state="8"]:not(.temporary-block)
.downloadUnblockMenuItem,
.download-state:not(:-moz-any([state="2"], /* Failed */
[state="4"]) /* Paused */)
.downloadCancelMenuItem,
@ -71,6 +78,13 @@ richlistitem[type="download"]:not([selected]) button {
[state="4"]) /* Paused */)
.downloadCancel,
/* Blocked (dirty) downloads that have not been confirmed and
have temporary data. */
.download-state:not( [state="8"] /* Blocked (dirty) */)
.downloadConfirmBlock,
.download-state[state="8"]:not(.temporary-block)
.downloadConfirmBlock,
.download-state:not(:-moz-any([state="2"], /* Failed */
[state="3"]) /* Canceled */)
.downloadRetry,

View File

@ -960,6 +960,8 @@ const DownloadsView = {
// Set the state attribute so that only the appropriate items are displayed.
let contextMenu = document.getElementById("downloadsContextMenu");
contextMenu.setAttribute("state", element.getAttribute("state"));
contextMenu.classList.toggle("temporary-block",
element.classList.contains("temporary-block"));
},
onDownloadDragStart(aEvent) {
@ -1025,6 +1027,11 @@ DownloadsViewItem.prototype = {
},
onChanged() {
// This cannot be placed within onStateChanged because
// when a download goes from hasBlockedData to !hasBlockedData
// it will still remain in the same state.
this.element.classList.toggle("temporary-block",
!!this.download.hasBlockedData);
this._updateProgress();
},
};
@ -1166,6 +1173,9 @@ DownloadsViewItemController.prototype = {
case "downloadsCmd_copyLocation":
case "downloadsCmd_doDefault":
return true;
case "downloadsCmd_unblock":
case "downloadsCmd_confirmBlock":
return this.download.hasBlockedData;
}
return false;
},
@ -1196,6 +1206,20 @@ DownloadsViewItemController.prototype = {
this.download.removePartialData().catch(Cu.reportError);
},
downloadsCmd_unblock() {
DownloadsPanel.hidePanel();
DownloadsCommon.confirmUnblockDownload(DownloadsCommon.BLOCK_VERDICT_MALWARE,
window).then((confirmed) => {
if (confirmed) {
return this.download.unblock();
}
}).catch(Cu.reportError);
},
downloadsCmd_confirmBlock() {
this.download.confirmBlock().catch(Cu.reportError);
},
downloadsCmd_open() {
this.download.launch().catch(Cu.reportError);

View File

@ -21,6 +21,10 @@
oncommand="goDoCommand('downloadsCmd_pauseResume')"/>
<command id="downloadsCmd_cancel"
oncommand="goDoCommand('downloadsCmd_cancel')"/>
<command id="downloadsCmd_unblock"
oncommand="goDoCommand('downloadsCmd_unblock')"/>
<command id="downloadsCmd_confirmBlock"
oncommand="goDoCommand('downloadsCmd_confirmBlock')"/>
<command id="downloadsCmd_open"
oncommand="goDoCommand('downloadsCmd_open')"/>
<command id="downloadsCmd_show"
@ -65,6 +69,10 @@
class="downloadCancelMenuItem"
label="&cmd.cancel.label;"
accesskey="&cmd.cancel.accesskey;"/>
<menuitem command="downloadsCmd_unblock"
class="downloadUnblockMenuItem"
label="&cmd.unblock.label;"
accesskey="&cmd.unblock.accesskey;"/>
<menuitem command="cmd_delete"
class="downloadRemoveFromHistoryMenuItem"
label="&cmd.removeFromHistory.label;"

View File

@ -33,14 +33,14 @@ function addDialogOpenObserver(buttonAction) {
add_task(function* test_confirm_unblock_dialog_unblock() {
addDialogOpenObserver("cancel");
let result = yield DownloadsCommon.confirmUnblockDownload(DownloadsCommon.UNBLOCK_MALWARE,
let result = yield DownloadsCommon.confirmUnblockDownload(DownloadsCommon.BLOCK_VERDICT_MALWARE,
window);
ok(result, "Should return true when the user clicks on `Unblock` button.");
});
add_task(function* test_confirm_unblock_dialog_keep_safe() {
addDialogOpenObserver("accept");
let result = yield DownloadsCommon.confirmUnblockDownload(DownloadsCommon.UNBLOCK_MALWARE,
let result = yield DownloadsCommon.confirmUnblockDownload(DownloadsCommon.BLOCK_VERDICT_MALWARE,
window);
ok(!result, "Should return false when the user clicks on `Keep me safe` button.");
});

View File

@ -25,10 +25,7 @@ gFrameTree.addObserver({
}
});
docShell.QueryInterface(Ci.nsIWebNavigation).
sessionHistory.addSHistoryListener({
let historyListener = {
OnHistoryNewEntry: function () {
sendAsyncMessage("ss-test:OnHistoryNewEntry");
},
@ -66,7 +63,10 @@ docShell.QueryInterface(Ci.nsIWebNavigation).
Ci.nsISHistoryListener,
Ci.nsISupportsWeakReference
])
});
};
docShell.QueryInterface(Ci.nsIWebNavigation).
sessionHistory.addSHistoryListener(historyListener);
/**
* This frame script is only loaded for sessionstore mochitests. It enables us

View File

@ -27,10 +27,11 @@ function MockFront (blueprint) {
function MockMemoryFront () {
MockFront.call(this, [
["attach"],
["detach"],
["initialize"],
["destroy"],
["attach"],
["detach"],
["getState", "detached"],
["startRecordingAllocations", 0],
["stopRecordingAllocations", 0],
["getAllocations", createMockAllocations],
@ -40,10 +41,10 @@ exports.MockMemoryFront = MockMemoryFront;
function MockTimelineFront () {
MockFront.call(this, [
["start", 0],
["stop", 0],
["initialize"],
["destroy"],
["start", 0],
["stop", 0],
]);
}
exports.MockTimelineFront = MockTimelineFront;

View File

@ -358,6 +358,7 @@ PerformanceFront.prototype = {
*/
_pullAllocationSites: Task.async(function *() {
let memoryData = yield this._request("memory", "getAllocations");
let isStillAttached = yield this._request("memory", "getState") == "attached";
this.emit("allocations", {
sites: memoryData.allocations,
@ -366,8 +367,10 @@ PerformanceFront.prototype = {
counts: memoryData.counts
});
let delay = DEFAULT_ALLOCATION_SITES_PULL_TIMEOUT;
this._sitesPullTimeout = setTimeout(this._pullAllocationSites, delay);
if (isStillAttached) {
let delay = DEFAULT_ALLOCATION_SITES_PULL_TIMEOUT;
this._sitesPullTimeout = setTimeout(this._pullAllocationSites, delay);
}
}),
/**

View File

@ -69,14 +69,12 @@
<!-- LOCALIZATION NOTE (cmd.unblock.label):
This command may be shown in the context menu, as a menu button item, or as
a text link when malware or potentially unwanted downloads are blocked.
Note: This string doesn't exist in the UI yet. See bug 1053890.
-->
<!ENTITY cmd.unblock.label "Unblock">
<!ENTITY cmd.unblock.accesskey "U">
<!-- LOCALIZATION NOTE (cmd.removeFile.label):
This command may be shown in the context menu or as a menu button label
when malware or potentially unwanted downloads are blocked.
Note: This string doesn't exist in the UI yet. See bug 1053890.
-->
<!ENTITY cmd.removeFile.label "Remove File">
<!ENTITY cmd.removeFile.accesskey "m">

View File

@ -48,27 +48,35 @@
/*** Button icons ***/
.downloadButton.downloadConfirmBlock,
.downloadButton.downloadCancel {
-moz-image-region: rect(0px, 16px, 16px, 0px);
}
richlistitem.download:hover > .downloadButton.downloadConfirmBlock,
richlistitem.download:hover > .downloadButton.downloadCancel {
-moz-image-region: rect(0px, 32px, 16px, 16px);
}
richlistitem.download:hover > .downloadButton.downloadConfirmBlock:hover,
richlistitem.download:hover > .downloadButton.downloadCancel:hover {
-moz-image-region: rect(0px, 48px, 16px, 32px);
}
richlistitem.download:hover > .downloadButton.downloadConfirmBlock:active,
richlistitem.download:hover > .downloadButton.downloadCancel:active {
-moz-image-region: rect(0px, 64px, 16px, 48px);
}
richlistitem.download[selected] > .downloadButton.downloadConfirmBlock,
richlistitem.download[selected] > .downloadButton.downloadCancel {
-moz-image-region: rect(0px, 80px, 16px, 64px);
}
richlistitem.download:hover[selected] > .downloadButton.downloadConfirmBlock,
richlistitem.download:hover[selected] > .downloadButton.downloadCancel {
-moz-image-region: rect(0px, 96px, 16px, 80px);
}
richlistitem.download:hover[selected] > .downloadButton.downloadConfirmBlock:hover,
richlistitem.download:hover[selected] > .downloadButton.downloadCancel:hover {
-moz-image-region: rect(0px, 112px, 16px, 96px);
}
richlistitem.download:hover[selected] > .downloadButton.downloadConfirmBlock:active,
richlistitem.download:hover[selected] > .downloadButton.downloadCancel:active {
-moz-image-region: rect(0px, 128px, 16px, 112px);
}

View File

@ -176,15 +176,19 @@ richlistitem[type="download"]:last-child {
/*** Button icons ***/
.downloadButton.downloadConfirmBlock,
.downloadButton.downloadCancel {
-moz-image-region: rect(0px, 16px, 16px, 0px);
}
richlistitem[type="download"]:hover > stack > .downloadButton.downloadConfirmBlock,
richlistitem[type="download"]:hover > stack > .downloadButton.downloadCancel {
-moz-image-region: rect(0px, 32px, 16px, 16px);
}
richlistitem[type="download"]:hover > stack > .downloadButton.downloadConfirmBlock:hover,
richlistitem[type="download"]:hover > stack > .downloadButton.downloadCancel:hover {
-moz-image-region: rect(0px, 48px, 16px, 32px);
}
richlistitem[type="download"]:hover > stack > .downloadButton.downloadConfirmBlock:active,
richlistitem[type="download"]:hover > stack > .downloadButton.downloadCancel:active {
-moz-image-region: rect(0px, 64px, 16px, 48px);
}

View File

@ -48,27 +48,35 @@
/*** Button icons ***/
.downloadButton.downloadConfirmBlock,
.downloadButton.downloadCancel {
-moz-image-region: rect(0px, 16px, 16px, 0px);
}
richlistitem.download:hover > .downloadButton.downloadConfirmBlock,
richlistitem.download:hover > .downloadButton.downloadCancel {
-moz-image-region: rect(0px, 32px, 16px, 16px);
}
richlistitem.download:hover > .downloadButton.downloadConfirmBlock:hover,
richlistitem.download:hover > .downloadButton.downloadCancel:hover {
-moz-image-region: rect(0px, 48px, 16px, 32px);
}
richlistitem.download:hover > .downloadButton.downloadConfirmBlock:active,
richlistitem.download:hover > .downloadButton.downloadCancel:active {
-moz-image-region: rect(0px, 64px, 16px, 48px);
}
richlistitem.download[selected] > .downloadButton.downloadConfirmBlock,
richlistitem.download[selected] > .downloadButton.downloadCancel {
-moz-image-region: rect(0px, 80px, 16px, 64px);
}
richlistitem.download:hover[selected] > .downloadButton.downloadConfirmBlock,
richlistitem.download:hover[selected] > .downloadButton.downloadCancel {
-moz-image-region: rect(0px, 96px, 16px, 80px);
}
richlistitem.download:hover[selected] > .downloadButton.downloadConfirmBlock:hover,
richlistitem.download:hover[selected] > .downloadButton.downloadCancel:hover {
-moz-image-region: rect(0px, 112px, 16px, 96px);
}
richlistitem.download:hover[selected] > .downloadButton.downloadConfirmBlock:active,
richlistitem.download:hover[selected] > .downloadButton.downloadCancel:active {
-moz-image-region: rect(0px, 128px, 16px, 112px);
}
@ -132,27 +140,35 @@ richlistitem.download:hover[selected] > .downloadButton.downloadRetry:active {
height: 16px;
}
.downloadButton.downloadConfirmBlock,
.downloadButton.downloadCancel {
-moz-image-region: rect(0px, 32px, 32px, 0px);
}
richlistitem.download:hover > .downloadButton.downloadConfirmBlock,
richlistitem.download:hover > .downloadButton.downloadCancel {
-moz-image-region: rect(0px, 64px, 32px, 32px);
}
richlistitem.download:hover > .downloadButton.downloadConfirmBlock:hover,
richlistitem.download:hover > .downloadButton.downloadCancel:hover {
-moz-image-region: rect(0px, 96px, 32px, 64px);
}
richlistitem.download:hover > .downloadButton.downloadConfirmBlock:active,
richlistitem.download:hover > .downloadButton.downloadCancel:active {
-moz-image-region: rect(0px, 128px, 32px, 96px);
}
richlistitem.download[selected] > .downloadButton.downloadConfirmBlock,
richlistitem.download[selected] > .downloadButton.downloadCancel {
-moz-image-region: rect(0px, 160px, 32px, 128px);
}
richlistitem.download:hover[selected] > .downloadButton.downloadConfirmBlock,
richlistitem.download:hover[selected] > .downloadButton.downloadCancel {
-moz-image-region: rect(0px, 192px, 32px, 160px);
}
richlistitem.download:hover[selected] > .downloadButton.downloadConfirmBlock:hover,
richlistitem.download:hover[selected] > .downloadButton.downloadCancel:hover {
-moz-image-region: rect(0px, 224px, 32px, 192px);
}
richlistitem.download:hover[selected] > .downloadButton.downloadConfirmBlock:active,
richlistitem.download:hover[selected] > .downloadButton.downloadCancel:active {
-moz-image-region: rect(0px, 256px, 32px, 224px);
}

View File

@ -189,27 +189,35 @@ richlistitem[type="download"]:last-child {
/*** Button icons ***/
.downloadButton.downloadConfirmBlock,
.downloadButton.downloadCancel {
-moz-image-region: rect(0px, 16px, 16px, 0px);
}
richlistitem[type="download"]:hover > stack > .downloadButton.downloadConfirmBlock,
richlistitem[type="download"]:hover > stack > .downloadButton.downloadCancel {
-moz-image-region: rect(0px, 32px, 16px, 16px);
}
richlistitem[type="download"]:hover > stack > .downloadButton.downloadConfirmBlock:hover,
richlistitem[type="download"]:hover > stack > .downloadButton.downloadCancel:hover {
-moz-image-region: rect(0px, 48px, 16px, 32px);
}
richlistitem[type="download"]:hover > stack > .downloadButton.downloadConfirmBlock:active,
richlistitem[type="download"]:hover > stack > .downloadButton.downloadCancel:active {
-moz-image-region: rect(0px, 64px, 16px, 48px);
}
#downloadsPanel[keyfocus] > #downloadsListBox:focus > richlistitem[type="download"][selected] > stack > .downloadButton.downloadConfirmBlock,
#downloadsPanel[keyfocus] > #downloadsListBox:focus > richlistitem[type="download"][selected] > stack > .downloadButton.downloadCancel {
-moz-image-region: rect(0px, 80px, 16px, 64px);
}
#downloadsPanel[keyfocus] > #downloadsListBox:focus > richlistitem[type="download"]:hover[selected] > stack > .downloadButton.downloadConfirmBlock,
#downloadsPanel[keyfocus] > #downloadsListBox:focus > richlistitem[type="download"]:hover[selected] > stack > .downloadButton.downloadCancel {
-moz-image-region: rect(0px, 96px, 16px, 80px);
}
#downloadsPanel[keyfocus] > #downloadsListBox:focus > richlistitem[type="download"]:hover[selected] > stack > .downloadButton.downloadConfirmBlock:hover,
#downloadsPanel[keyfocus] > #downloadsListBox:focus > richlistitem[type="download"]:hover[selected] > stack > .downloadButton.downloadCancel:hover {
-moz-image-region: rect(0px, 112px, 16px, 96px);
}
#downloadsPanel[keyfocus] > #downloadsListBox:focus > richlistitem[type="download"]:hover[selected] > stack > .downloadButton.downloadConfirmBlock:active,
#downloadsPanel[keyfocus] > #downloadsListBox:focus > richlistitem[type="download"]:hover[selected] > stack > .downloadButton.downloadCancel:active {
-moz-image-region: rect(0px, 128px, 16px, 112px);
}
@ -276,27 +284,35 @@ richlistitem[type="download"]:hover > stack > .downloadButton.downloadRetry:acti
height: 16px;
}
.downloadButton.downloadConfirmBlock,
.downloadButton.downloadCancel {
-moz-image-region: rect(0px, 32px, 32px, 0px);
}
richlistitem[type="download"]:hover > stack > .downloadButton.downloadConfirmBlock,
richlistitem[type="download"]:hover > stack > .downloadButton.downloadCancel {
-moz-image-region: rect(0px, 64px, 32px, 32px);
}
richlistitem[type="download"]:hover > stack > .downloadButton.downloadConfirmBlock:hover,
richlistitem[type="download"]:hover > stack > .downloadButton.downloadCancel:hover {
-moz-image-region: rect(0px, 96px, 32px, 64px);
}
richlistitem[type="download"]:hover > stack > .downloadButton.downloadConfirmBlock:active,
richlistitem[type="download"]:hover > stack > .downloadButton.downloadCancel:active {
-moz-image-region: rect(0px, 128px, 32px, 96px);
}
#downloadsPanel[keyfocus] > #downloadsListBox:focus > richlistitem[type="download"][selected] > stack > .downloadButton.downloadConfirmBlock,
#downloadsPanel[keyfocus] > #downloadsListBox:focus > richlistitem[type="download"][selected] > stack > .downloadButton.downloadCancel {
-moz-image-region: rect(0px, 160px, 32px, 128px);
}
#downloadsPanel[keyfocus] > #downloadsListBox:focus > richlistitem[type="download"]:hover[selected] > stack > .downloadButton.downloadConfirmBlock,
#downloadsPanel[keyfocus] > #downloadsListBox:focus > richlistitem[type="download"]:hover[selected] > stack > .downloadButton.downloadCancel {
-moz-image-region: rect(0px, 192px, 32px, 160px);
}
#downloadsPanel[keyfocus] > #downloadsListBox:focus > richlistitem[type="download"]:hover[selected] > stack > .downloadButton.downloadConfirmBlock:hover,
#downloadsPanel[keyfocus] > #downloadsListBox:focus > richlistitem[type="download"]:hover[selected] > stack > .downloadButton.downloadCancel:hover {
-moz-image-region: rect(0px, 224px, 32px, 192px);
}
#downloadsPanel[keyfocus] > #downloadsListBox:focus > richlistitem[type="download"]:hover[selected] > stack > .downloadButton.downloadConfirmBlock:active,
#downloadsPanel[keyfocus] > #downloadsListBox:focus > richlistitem[type="download"]:hover[selected] > stack > .downloadButton.downloadCancel:active {
-moz-image-region: rect(0px, 256px, 32px, 224px);
}

View File

@ -53,18 +53,22 @@
/*** Button icons ***/
.downloadButton.downloadConfirmBlock,
.downloadButton.downloadCancel {
-moz-image-region: rect(0px, 16px, 16px, 0px);
}
richlistitem.download:hover > .downloadButton.downloadConfirmBlock,
richlistitem.download:hover > .downloadButton.downloadCancel {
-moz-image-region: rect(0px, 32px, 16px, 16px);
}
richlistitem.download:hover > .downloadButton.downloadConfirmBlock:hover,
richlistitem.download:hover > .downloadButton.downloadCancel:hover {
-moz-image-region: rect(0px, 48px, 16px, 32px);
}
richlistitem.download:hover > .downloadButton.downloadConfirmBlock:active,
richlistitem.download:hover > .downloadButton.downloadCancel:active {
-moz-image-region: rect(0px, 64px, 16px, 48px);
}
@ -102,18 +106,22 @@ richlistitem.download:hover > .downloadButton.downloadRetry:active {
}
%ifndef WINDOWS_AERO
richlistitem.download[selected] > .downloadButton.downloadConfirmBlock,
richlistitem.download[selected] > .downloadButton.downloadCancel {
-moz-image-region: rect(0px, 80px, 16px, 64px);
}
richlistitem.download[selected]:hover > .downloadButton.downloadConfirmBlock,
richlistitem.download[selected]:hover > .downloadButton.downloadCancel {
-moz-image-region: rect(0px, 96px, 16px, 80px);
}
richlistitem.download[selected]:hover > .downloadButton.downloadConfirmBlock:hover,
richlistitem.download[selected]:hover > .downloadButton.downloadCancel:hover {
-moz-image-region: rect(0px, 112px, 16px, 96px);
}
richlistitem.download[selected]:hover > .downloadButton.downloadConfirmBlock:active,
richlistitem.download[selected]:hover > .downloadButton.downloadCancel:active {
-moz-image-region: rect(0px, 128px, 16px, 112px);
}

View File

@ -251,15 +251,19 @@ richlistitem[type="download"]:first-child {
/*** Button icons ***/
.downloadButton.downloadConfirmBlock,
.downloadButton.downloadCancel {
-moz-image-region: rect(0px, 16px, 16px, 0px);
}
richlistitem[type="download"]:hover > stack > .downloadButton.downloadConfirmBlock,
richlistitem[type="download"]:hover > stack > .downloadButton.downloadCancel {
-moz-image-region: rect(0px, 32px, 16px, 16px);
}
richlistitem[type="download"]:hover > stack > .downloadButton.downloadConfirmBlock:hover,
richlistitem[type="download"]:hover > stack > .downloadButton.downloadCancel:hover {
-moz-image-region: rect(0px, 48px, 16px, 32px);
}
richlistitem[type="download"]:hover > stack > .downloadButton.downloadConfirmBlock:active,
richlistitem[type="download"]:hover > stack > .downloadButton.downloadCancel:active {
-moz-image-region: rect(0px, 64px, 16px, 48px);
}

View File

@ -1550,4 +1550,8 @@ nsContentSink::NotifyDocElementCreated(nsIDocument* aDoc)
NotifyObservers(domDoc, "document-element-inserted",
EmptyString().get());
}
nsContentUtils::DispatchChromeEvent(aDoc, aDoc,
NS_LITERAL_STRING("DOMDocElementInserted"),
true, false);
}

View File

@ -40,8 +40,9 @@ Convert(ConvertNamedValue& aIn, bt_property_t& aOut)
if (aIn.mNamedValue.value().type() == BluetoothValue::Tuint32_t) {
// Set discoverable timeout
aOut.val =
reinterpret_cast<void*>(aIn.mNamedValue.value().get_uint32_t());
aOut.val = const_cast<void*>(static_cast<const void*>(
&(aIn.mNamedValue.value().get_uint32_t())));
aOut.len = sizeof(uint32_t);
} else if (aIn.mNamedValue.value().type() == BluetoothValue::TnsString) {
// Set name
aIn.mStringValue =

View File

@ -40,8 +40,9 @@ Convert(ConvertNamedValue& aIn, bt_property_t& aOut)
if (aIn.mNamedValue.value().type() == BluetoothValue::Tuint32_t) {
// Set discoverable timeout
aOut.val =
reinterpret_cast<void*>(aIn.mNamedValue.value().get_uint32_t());
aOut.val = const_cast<void*>(static_cast<const void*>(
&(aIn.mNamedValue.value().get_uint32_t())));
aOut.len = sizeof(uint32_t);
} else if (aIn.mNamedValue.value().type() == BluetoothValue::TnsString) {
// Set name
aIn.mStringValue =

View File

@ -13,3 +13,4 @@ support-files =
file_bug1108547-1.html
file_bug1108547-2.html
file_bug1108547-3.html
[browser_DOMDocElementInserted.js]

View File

@ -0,0 +1,24 @@
// Tests that the DOMDocElementInserted event is visible on the frame
add_task(function*() {
let tab = gBrowser.addTab();
let uri = "data:text/html;charset=utf-8,<html/>"
let eventPromise = ContentTask.spawn(tab.linkedBrowser, null, function() {
Cu.import("resource://gre/modules/PromiseUtils.jsm");
let deferred = PromiseUtils.defer();
let listener = (event) => {
removeEventListener("DOMDocElementInserted", listener, true);
deferred.resolve(event.target.documentURIObject.spec);
};
addEventListener("DOMDocElementInserted", listener, true);
return deferred.promise;
});
tab.linkedBrowser.loadURI(uri);
let loadedURI = yield eventPromise;
is(loadedURI, uri, "Should have seen the event for the right URI");
gBrowser.removeTab(tab);
});

View File

@ -36,6 +36,8 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MozIsoDepTech)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
const NFCTechType MozIsoDepTech::mTechnology = NFCTechType::ISO_DEP;
/* static */
already_AddRefed<MozIsoDepTech>
MozIsoDepTech::Constructor(const GlobalObject& aGlobal,

View File

@ -45,7 +45,7 @@ private:
nsRefPtr<nsPIDOMWindow> mWindow;
nsRefPtr<MozNFCTag> mTag;
static const NFCTechType mTechnology = NFCTechType::ISO_DEP;
static const NFCTechType mTechnology;
};
} // namespace dom

View File

@ -81,6 +81,42 @@ const NFC_IPC_MSG_ENTRIES = [
"NFC:SetFocusApp"] }
];
// Should be consistent with NfcRequestType defined in NfcOptions.webidl.
const NfcRequestType = {
CHANGE_RF_STATE: "changeRFState",
READ_NDEF: "readNDEF",
WRITE_NDEF: "writeNDEF",
MAKE_READ_ONLY: "makeReadOnly",
FORMAT: "format",
TRANSCEIVE: "transceive"
};
// Should be consistent with NfcResponseType defined in NfcOptions.webidl.
const NfcResponseType = {
CHANGE_RF_STATE_RSP: "changeRFStateRsp",
READ_NDEF_RSP: "readNDEFRsp",
WRITE_NDEF_RSP: "writeNDEFRsp",
MAKE_READ_ONLY_RSP: "makeReadOnlyRsp",
FORMAT_RSP: "formatRsp",
TRANSCEIVE_RSP: "transceiveRsp",
};
const EventMsgTable = {};
EventMsgTable[NfcResponseType.CHANGE_RF_STATE_RSP] = "NFC:ChangeRFStateResponse";
EventMsgTable[NfcResponseType.READ_NDEF_RSP] = "NFC:ReadNDEFResponse";
EventMsgTable[NfcResponseType.WRITE_NDEF_RSP] = "NFC:WriteNDEFResponse";
EventMsgTable[NfcResponseType.MAKE_READ_ONLY_RSP] = "NFC:MakeReadOnlyResponse";
EventMsgTable[NfcResponseType.FORMAT_RSP] = "NFC:FormatResponse";
EventMsgTable[NfcResponseType.TRANSCEIVE_RSP] = "NFC:TransceiveResponse";
// Should be consistent with NfcNotificationType defined in NfcOptions.webidl.
const NfcNotificationType = {
INITIALIZED: "initialized",
TECH_DISCOVERED: "techDiscovered",
TECH_LOST: "techLost",
HCI_EVENT_TRANSACTION: "hciEventTransaction"
};
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
"@mozilla.org/parentprocessmessagemanager;1",
"nsIMessageBroadcaster");
@ -241,6 +277,14 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
sessionToken: sessionToken});
},
notifySendFileStatus: function notifySendFileStatus(message) {
if (message.data.status) {
message.data.errorMsg =
this.nfc.getErrorMessage(NFC.NFC_GECKO_ERROR_SEND_FILE_FAILED);
}
this.nfc.sendFileStatusResponse(message.data);
},
callDefaultFoundHandler: function callDefaultFoundHandler(message) {
let sysMsg = new NfcTechDiscoveredSysMsg(message.sessionToken,
message.isP2P,
@ -346,12 +390,7 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
case "NFC:NotifySendFileStatus":
// Upon receiving the status of sendFile operation, send the response
// to appropriate content process.
message.data.type = "NotifySendFileStatusResponse";
if (message.data.status) {
message.data.errorMsg =
this.nfc.getErrorMessage(NFC.NFC_GECKO_ERROR_SEND_FILE_FAILED);
}
this.nfc.sendNfcResponse(message.data);
this.notifySendFileStatus(message);
return null;
case "NFC:CallDefaultFoundHandler":
this.callDefaultFoundHandler(message.data);
@ -482,15 +521,33 @@ Nfc.prototype = {
this.nfcService.sendCommand(message);
},
sendNfcResponse: function sendNfcResponse(message) {
let target = this.targetsByRequestId[message.requestId];
sendFileStatusResponse: function sendFileStatusResponse(message) {
let target = this.getTargetByRequestId(message.requestId);
if (!target) {
debug("No target for requestId: " + message.requestId);
return;
}
delete this.targetsByRequestId[message.requestId];
target.sendAsyncMessage("NFC:" + message.type, message);
target.sendAsyncMessage("NFC:NotifySendFileStatusResponse", message);
},
sendNfcResponse: function sendNfcResponse(message) {
let target = this.getTargetByRequestId(message.requestId);
if (!target) {
return;
}
target.sendAsyncMessage(EventMsgTable[message.type], message);
},
getTargetByRequestId: function getTargetByRequestId(requestId) {
let target = this.targetsByRequestId[requestId];
if (!target) {
debug("No target for requestId: " + requestId);
return null;
}
delete this.targetsByRequestId[requestId];
return target;
},
/**
@ -522,12 +579,12 @@ Nfc.prototype = {
let message = Cu.cloneInto(event, this);
DEBUG && debug("Received message from NFC Service: " + JSON.stringify(message));
message.type = message.rspType || message.ntfType;
switch (message.type) {
case "InitializedNotification":
case NfcNotificationType.INITIALIZED:
// Do nothing.
break;
case "TechDiscoveredNotification":
message.type = "techDiscovered";
case NfcNotificationType.TECH_DISCOVERED:
// Update the upper layers with a session token (alias)
message.sessionToken =
SessionHelper.registerSession(message.sessionId, message.isP2P);
@ -548,9 +605,7 @@ Nfc.prototype = {
gMessageManager.onTagFound(message);
}
break;
case "TechLostNotification":
message.type = "techLost";
case NfcNotificationType.TECH_LOST:
// Update the upper layers with a session token (alias)
message.sessionToken = SessionHelper.getToken(message.sessionId);
if (SessionHelper.isP2PSession(message.sessionId)) {
@ -561,10 +616,10 @@ Nfc.prototype = {
SessionHelper.unregisterSession(message.sessionId);
break;
case "HCIEventTransactionNotification":
case NfcNotificationType.HCI_EVENT_TRANSACTION:
this.notifyHCIEventTransaction(message);
break;
case "ChangeRFStateResponse":
case NfcResponseType.CHANGE_RF_STATE_RSP:
this.sendNfcResponse(message);
if (!message.errorMsg) {
@ -572,11 +627,11 @@ Nfc.prototype = {
gMessageManager.onRFStateChanged(this.rfState);
}
break;
case "ReadNDEFResponse": // Fall through.
case "MakeReadOnlyResponse":
case "FormatResponse":
case "TransceiveResponse":
case "WriteNDEFResponse":
case NfcResponseType.READ_NDEF_RSP: // Fall through.
case NfcResponseType.WRITE_NDEF_RSP:
case NfcResponseType.MAKE_READ_ONLY_RSP:
case NfcResponseType.FORMAT_RSP:
case NfcResponseType.TRANSCEIVE_RSP:
this.sendNfcResponse(message);
break;
default:
@ -617,23 +672,23 @@ Nfc.prototype = {
switch (message.name) {
case "NFC:ChangeRFState":
this.sendToNfcService("changeRFState", message.data);
this.sendToNfcService(NfcRequestType.CHANGE_RF_STATE, message.data);
break;
case "NFC:ReadNDEF":
this.sendToNfcService("readNDEF", message.data);
this.sendToNfcService(NfcRequestType.READ_NDEF, message.data);
break;
case "NFC:WriteNDEF":
message.data.isP2P = SessionHelper.isP2PSession(message.data.sessionId);
this.sendToNfcService("writeNDEF", message.data);
this.sendToNfcService(NfcRequestType.WRITE_NDEF, message.data);
break;
case "NFC:MakeReadOnly":
this.sendToNfcService("makeReadOnly", message.data);
this.sendToNfcService(NfcRequestType.MAKE_READ_ONLY, message.data);
break;
case "NFC:Format":
this.sendToNfcService("format", message.data);
this.sendToNfcService(NfcRequestType.FORMAT, message.data);
break;
case "NFC:Transceive":
this.sendToNfcService("transceive", message.data);
this.sendToNfcService(NfcRequestType.TRANSCEIVE, message.data);
break;
case "NFC:SendFile":
// Chrome process is the arbitrator / mediator between

View File

@ -10,31 +10,6 @@ namespace mozilla {
#define NFCD_MAJOR_VERSION 1
#define NFCD_MINOR_VERSION 21
enum NfcRequest {
ChangeRFStateReq,
ReadNDEFReq,
WriteNDEFReq,
MakeReadOnlyReq,
FormatReq,
TransceiveReq,
};
enum NfcResponse {
ChangeRFStateRsp,
ReadNDEFRsp,
WriteNDEFRsp,
MakeReadOnlyRsp,
FormatRsp,
TransceiveRsp,
};
enum NfcNotification {
Initialized,
TechDiscovered,
TechLost,
HCIEventTransaction,
};
enum NfcTechlogy {
NDEF = 0,
NDEFWritable,

View File

@ -17,47 +17,33 @@ using namespace android;
using namespace mozilla;
using namespace mozilla::dom;
static const char* kChangeRFStateRequest = "changeRFState";
static const char* kReadNDEFRequest = "readNDEF";
static const char* kWriteNDEFRequest = "writeNDEF";
static const char* kMakeReadOnlyRequest = "makeReadOnly";
static const char* kFormatRequest = "format";
static const char* kTransceiveRequest = "transceive";
static const char* kChangeRFStateResponse = "ChangeRFStateResponse";
static const char* kReadNDEFResponse = "ReadNDEFResponse";
static const char* kWriteNDEFResponse = "WriteNDEFResponse";
static const char* kMakeReadOnlyResponse = "MakeReadOnlyResponse";
static const char* kFormatResponse = "FormatResponse";
static const char* kTransceiveResponse = "TransceiveResponse";
static const char* kInitializedNotification = "InitializedNotification";
static const char* kTechDiscoveredNotification = "TechDiscoveredNotification";
static const char* kTechLostNotification = "TechLostNotification";
static const char* kHCIEventTransactionNotification =
"HCIEventTransactionNotification";
bool
NfcMessageHandler::Marshall(Parcel& aParcel, const CommandOptions& aOptions)
{
bool result;
const char* type = NS_ConvertUTF16toUTF8(aOptions.mType).get();
if (!strcmp(type, kChangeRFStateRequest)) {
result = ChangeRFStateRequest(aParcel, aOptions);
} else if (!strcmp(type, kReadNDEFRequest)) {
result = ReadNDEFRequest(aParcel, aOptions);
} else if (!strcmp(type, kWriteNDEFRequest)) {
result = WriteNDEFRequest(aParcel, aOptions);
} else if (!strcmp(type, kMakeReadOnlyRequest)) {
result = MakeReadOnlyRequest(aParcel, aOptions);
} else if (!strcmp(type, kFormatRequest)) {
result = FormatRequest(aParcel, aOptions);
} else if (!strcmp(type, kTransceiveRequest)) {
result = TransceiveRequest(aParcel, aOptions);
} else {
result = false;
}
switch (aOptions.mType) {
case NfcRequestType::ChangeRFState:
result = ChangeRFStateRequest(aParcel, aOptions);
break;
case NfcRequestType::ReadNDEF:
result = ReadNDEFRequest(aParcel, aOptions);
break;
case NfcRequestType::WriteNDEF:
result = WriteNDEFRequest(aParcel, aOptions);
break;
case NfcRequestType::MakeReadOnly:
result = MakeReadOnlyRequest(aParcel, aOptions);
break;
case NfcRequestType::Format:
result = FormatRequest(aParcel, aOptions);
break;
case NfcRequestType::Transceive:
result = TransceiveRequest(aParcel, aOptions);
break;
default:
result = false;
break;
};
return result;
}
@ -67,30 +53,31 @@ NfcMessageHandler::Unmarshall(const Parcel& aParcel, EventOptions& aOptions)
{
mozilla::unused << htonl(aParcel.readInt32()); // parcel size
int32_t type = aParcel.readInt32();
bool isNotification = type >> 31;
bool isNtf = type >> 31;
int32_t msgType = type & ~(1 << 31);
return isNotification ? ProcessNotification(msgType, aParcel, aOptions) :
ProcessResponse(msgType, aParcel, aOptions);
return isNtf ? ProcessNotification(msgType, aParcel, aOptions) :
ProcessResponse(msgType, aParcel, aOptions);
}
bool
NfcMessageHandler::ProcessResponse(int32_t aType, const Parcel& aParcel, EventOptions& aOptions)
{
bool result;
switch (aType) {
case NfcResponse::ChangeRFStateRsp:
aOptions.mRspType = static_cast<NfcResponseType>(aType);
switch (aOptions.mRspType) {
case NfcResponseType::ChangeRFStateRsp:
result = ChangeRFStateResponse(aParcel, aOptions);
break;
case NfcResponse::ReadNDEFRsp:
case NfcResponseType::ReadNDEFRsp:
result = ReadNDEFResponse(aParcel, aOptions);
break;
case NfcResponse::WriteNDEFRsp: // Fall through.
case NfcResponse::MakeReadOnlyRsp:
case NfcResponse::FormatRsp:
result = GeneralResponse(aType, aParcel, aOptions);
case NfcResponseType::WriteNDEFRsp: // Fall through.
case NfcResponseType::MakeReadOnlyRsp:
case NfcResponseType::FormatRsp:
result = GeneralResponse(aParcel, aOptions);
break;
case NfcResponse::TransceiveRsp:
case NfcResponseType::TransceiveRsp:
result = TransceiveResponse(aParcel, aOptions);
break;
default:
@ -104,17 +91,18 @@ bool
NfcMessageHandler::ProcessNotification(int32_t aType, const Parcel& aParcel, EventOptions& aOptions)
{
bool result;
switch (aType) {
case NfcNotification::Initialized:
aOptions.mNtfType = static_cast<NfcNotificationType>(aType);
switch (aOptions.mNtfType) {
case NfcNotificationType::Initialized:
result = InitializeNotification(aParcel, aOptions);
break;
case NfcNotification::TechDiscovered:
case NfcNotificationType::TechDiscovered:
result = TechDiscoveredNotification(aParcel, aOptions);
break;
case NfcNotification::TechLost:
case NfcNotificationType::TechLost:
result = TechLostNotification(aParcel, aOptions);
break;
case NfcNotification::HCIEventTransaction:
case NfcNotificationType::HciEventTransaction:
result = HCIEventTransactionNotification(aParcel, aOptions);
break;
default:
@ -126,25 +114,8 @@ NfcMessageHandler::ProcessNotification(int32_t aType, const Parcel& aParcel, Eve
}
bool
NfcMessageHandler::GeneralResponse(const int32_t aResponse, const Parcel& aParcel, EventOptions& aOptions)
NfcMessageHandler::GeneralResponse(const Parcel& aParcel, EventOptions& aOptions)
{
const char* type;
switch (aResponse) {
case NfcResponse::WriteNDEFRsp:
type = kWriteNDEFResponse;
break;
case NfcResponse::MakeReadOnlyRsp:
type = kMakeReadOnlyResponse;
break;
case NfcResponse::FormatRsp:
type = kFormatResponse;
break;
default:
NMH_LOG("Nfcd, unknown general aResponse %d", aResponse);
return false;
}
aOptions.mType = NS_ConvertUTF8toUTF16(type);
aOptions.mErrorCode = aParcel.readInt32();
aOptions.mSessionId = aParcel.readInt32();
@ -157,7 +128,7 @@ NfcMessageHandler::GeneralResponse(const int32_t aResponse, const Parcel& aParce
bool
NfcMessageHandler::ChangeRFStateRequest(Parcel& aParcel, const CommandOptions& aOptions)
{
aParcel.writeInt32(NfcRequest::ChangeRFStateReq);
aParcel.writeInt32(static_cast<int32_t>(NfcRequestType::ChangeRFState));
aParcel.writeInt32(aOptions.mRfState);
mRequestIdQueue.AppendElement(aOptions.mRequestId);
return true;
@ -166,7 +137,6 @@ NfcMessageHandler::ChangeRFStateRequest(Parcel& aParcel, const CommandOptions& a
bool
NfcMessageHandler::ChangeRFStateResponse(const Parcel& aParcel, EventOptions& aOptions)
{
aOptions.mType = NS_ConvertUTF8toUTF16(kChangeRFStateResponse);
aOptions.mErrorCode = aParcel.readInt32();
NS_ENSURE_TRUE(!mRequestIdQueue.IsEmpty(), false);
aOptions.mRequestId = mRequestIdQueue[0];
@ -179,7 +149,7 @@ NfcMessageHandler::ChangeRFStateResponse(const Parcel& aParcel, EventOptions& aO
bool
NfcMessageHandler::ReadNDEFRequest(Parcel& aParcel, const CommandOptions& aOptions)
{
aParcel.writeInt32(NfcRequest::ReadNDEFReq);
aParcel.writeInt32(static_cast<int32_t>(NfcRequestType::ReadNDEF));
aParcel.writeInt32(aOptions.mSessionId);
mRequestIdQueue.AppendElement(aOptions.mRequestId);
return true;
@ -188,7 +158,6 @@ NfcMessageHandler::ReadNDEFRequest(Parcel& aParcel, const CommandOptions& aOptio
bool
NfcMessageHandler::ReadNDEFResponse(const Parcel& aParcel, EventOptions& aOptions)
{
aOptions.mType = NS_ConvertUTF8toUTF16(kReadNDEFResponse);
aOptions.mErrorCode = aParcel.readInt32();
aOptions.mSessionId = aParcel.readInt32();
@ -203,10 +172,26 @@ NfcMessageHandler::ReadNDEFResponse(const Parcel& aParcel, EventOptions& aOption
return true;
}
bool
NfcMessageHandler::TransceiveRequest(Parcel& aParcel, const CommandOptions& aOptions)
{
aParcel.writeInt32(static_cast<int32_t>(NfcRequestType::Transceive));
aParcel.writeInt32(aOptions.mSessionId);
aParcel.writeInt32(aOptions.mTechnology);
uint32_t length = aOptions.mCommand.Length();
aParcel.writeInt32(length);
void* data = aParcel.writeInplace(length);
memcpy(data, aOptions.mCommand.Elements(), length);
mRequestIdQueue.AppendElement(aOptions.mRequestId);
return true;
}
bool
NfcMessageHandler::TransceiveResponse(const Parcel& aParcel, EventOptions& aOptions)
{
aOptions.mType = NS_ConvertUTF8toUTF16(kTransceiveResponse);
aOptions.mErrorCode = aParcel.readInt32();
aOptions.mSessionId = aParcel.readInt32();
@ -224,7 +209,7 @@ NfcMessageHandler::TransceiveResponse(const Parcel& aParcel, EventOptions& aOpti
bool
NfcMessageHandler::WriteNDEFRequest(Parcel& aParcel, const CommandOptions& aOptions)
{
aParcel.writeInt32(NfcRequest::WriteNDEFReq);
aParcel.writeInt32(static_cast<int32_t>(NfcRequestType::WriteNDEF));
aParcel.writeInt32(aOptions.mSessionId);
aParcel.writeInt32(aOptions.mIsP2P);
WriteNDEFMessage(aParcel, aOptions);
@ -235,7 +220,7 @@ NfcMessageHandler::WriteNDEFRequest(Parcel& aParcel, const CommandOptions& aOpti
bool
NfcMessageHandler::MakeReadOnlyRequest(Parcel& aParcel, const CommandOptions& aOptions)
{
aParcel.writeInt32(NfcRequest::MakeReadOnlyReq);
aParcel.writeInt32(static_cast<int32_t>(NfcRequestType::MakeReadOnly));
aParcel.writeInt32(aOptions.mSessionId);
mRequestIdQueue.AppendElement(aOptions.mRequestId);
return true;
@ -244,33 +229,15 @@ NfcMessageHandler::MakeReadOnlyRequest(Parcel& aParcel, const CommandOptions& aO
bool
NfcMessageHandler::FormatRequest(Parcel& aParcel, const CommandOptions& aOptions)
{
aParcel.writeInt32(NfcRequest::FormatReq);
aParcel.writeInt32(static_cast<int32_t>(NfcRequestType::Format));
aParcel.writeInt32(aOptions.mSessionId);
mRequestIdQueue.AppendElement(aOptions.mRequestId);
return true;
}
bool
NfcMessageHandler::TransceiveRequest(Parcel& aParcel, const CommandOptions& aOptions)
{
aParcel.writeInt32(NfcRequest::TransceiveReq);
aParcel.writeInt32(aOptions.mSessionId);
aParcel.writeInt32(aOptions.mTechnology);
uint32_t length = aOptions.mCommand.Length();
aParcel.writeInt32(length);
void* data = aParcel.writeInplace(length);
memcpy(data, aOptions.mCommand.Elements(), length);
mRequestIdQueue.AppendElement(aOptions.mRequestId);
return true;
}
bool
NfcMessageHandler::InitializeNotification(const Parcel& aParcel, EventOptions& aOptions)
{
aOptions.mType = NS_ConvertUTF8toUTF16(kInitializedNotification);
aOptions.mStatus = aParcel.readInt32();
aOptions.mMajorVersion = aParcel.readInt32();
aOptions.mMinorVersion = aParcel.readInt32();
@ -287,7 +254,6 @@ NfcMessageHandler::InitializeNotification(const Parcel& aParcel, EventOptions& a
bool
NfcMessageHandler::TechDiscoveredNotification(const Parcel& aParcel, EventOptions& aOptions)
{
aOptions.mType = NS_ConvertUTF8toUTF16(kTechDiscoveredNotification);
aOptions.mSessionId = aParcel.readInt32();
aOptions.mIsP2P = aParcel.readInt32();
@ -318,7 +284,6 @@ NfcMessageHandler::TechDiscoveredNotification(const Parcel& aParcel, EventOption
bool
NfcMessageHandler::TechLostNotification(const Parcel& aParcel, EventOptions& aOptions)
{
aOptions.mType = NS_ConvertUTF8toUTF16(kTechLostNotification);
aOptions.mSessionId = aParcel.readInt32();
return true;
}
@ -326,8 +291,6 @@ NfcMessageHandler::TechLostNotification(const Parcel& aParcel, EventOptions& aOp
bool
NfcMessageHandler::HCIEventTransactionNotification(const Parcel& aParcel, EventOptions& aOptions)
{
aOptions.mType = NS_ConvertUTF8toUTF16(kHCIEventTransactionNotification);
aOptions.mOriginType = aParcel.readInt32();
aOptions.mOriginIndex = aParcel.readInt32();

View File

@ -25,7 +25,7 @@ public:
private:
bool ProcessResponse(int32_t aType, const android::Parcel& aParcel, EventOptions& aOptions);
bool GeneralResponse(int32_t aResponse, const android::Parcel& aParcel, EventOptions& aOptions);
bool GeneralResponse(const android::Parcel& aParcel, EventOptions& aOptions);
bool ChangeRFStateRequest(android::Parcel& aParcel, const CommandOptions& options);
bool ChangeRFStateResponse(const android::Parcel& aParcel, EventOptions& aOptions);
bool ReadNDEFRequest(android::Parcel& aParcel, const CommandOptions& options);

View File

@ -83,7 +83,7 @@ struct CommandOptions
#undef COPY_OPT_FIELD
}
nsString mType;
dom::NfcRequestType mType;
int32_t mSessionId;
nsString mRequestId;
int32_t mRfState;
@ -97,13 +97,16 @@ struct CommandOptions
struct EventOptions
{
EventOptions()
: mType(EmptyString()), mStatus(-1), mErrorCode(-1), mSessionId(-1), mRequestId(EmptyString()),
: mRspType(dom::NfcResponseType::EndGuard_),
mNtfType(dom::NfcNotificationType::EndGuard_),
mStatus(-1), mErrorCode(-1), mSessionId(-1), mRequestId(EmptyString()),
mMajorVersion(-1), mMinorVersion(-1), mIsP2P(-1),
mTagType(-1), mMaxNDEFSize(-1), mIsReadOnly(-1), mIsFormatable(-1), mRfState(-1),
mOriginType(-1), mOriginIndex(-1)
{}
nsString mType;
dom::NfcResponseType mRspType;
dom::NfcNotificationType mNtfType;
int32_t mStatus;
int32_t mErrorCode;
int32_t mSessionId;

View File

@ -98,7 +98,15 @@ public:
event.prop.Value() = mEvent.prop; \
}
COPY_FIELD(mType)
COPY_OPT_FIELD(mRspType, NfcResponseType::EndGuard_)
COPY_OPT_FIELD(mNtfType, NfcNotificationType::EndGuard_)
// Only one of rspType and ntfType should be used.
MOZ_ASSERT(((mEvent.mRspType != NfcResponseType::EndGuard_) ||
(mEvent.mNtfType != NfcNotificationType::EndGuard_)) &&
((mEvent.mRspType == NfcResponseType::EndGuard_) ||
(mEvent.mNtfType == NfcNotificationType::EndGuard_)));
COPY_OPT_FIELD(mRequestId, EmptyString())
COPY_OPT_FIELD(mStatus, -1)
COPY_OPT_FIELD(mSessionId, -1)

View File

@ -18,9 +18,6 @@ const NETWORKMANAGER_CID =
const DEFAULT_PREFERRED_NETWORK_TYPE = Ci.nsINetworkInterface.NETWORK_TYPE_WIFI;
XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService",
"@mozilla.org/settingsService;1",
"nsISettingsService");
XPCOMUtils.defineLazyGetter(this, "ppmm", function() {
return Cc["@mozilla.org/parentprocessmessagemanager;1"]
.getService(Ci.nsIMessageBroadcaster);
@ -34,83 +31,20 @@ XPCOMUtils.defineLazyServiceGetter(this, "gNetworkService",
"@mozilla.org/network/service;1",
"nsINetworkService");
XPCOMUtils.defineLazyServiceGetter(this, "gMobileConnectionService",
"@mozilla.org/mobileconnection/mobileconnectionservice;1",
"nsIMobileConnectionService");
const TOPIC_INTERFACE_REGISTERED = "network-interface-registered";
const TOPIC_INTERFACE_UNREGISTERED = "network-interface-unregistered";
const TOPIC_ACTIVE_CHANGED = "network-active-changed";
const TOPIC_MOZSETTINGS_CHANGED = "mozsettings-changed";
const TOPIC_PREF_CHANGED = "nsPref:changed";
const TOPIC_XPCOM_SHUTDOWN = "xpcom-shutdown";
const TOPIC_CONNECTION_STATE_CHANGED = "network-connection-state-changed";
const PREF_MANAGE_OFFLINE_STATUS = "network.gonk.manage-offline-status";
const POSSIBLE_USB_INTERFACE_NAME = "rndis0,usb0";
const DEFAULT_USB_INTERFACE_NAME = "rndis0";
const DEFAULT_3G_INTERFACE_NAME = "rmnet0";
const DEFAULT_WIFI_INTERFACE_NAME = "wlan0";
// The kernel's proc entry for network lists.
const KERNEL_NETWORK_ENTRY = "/sys/class/net";
const TETHERING_TYPE_WIFI = "WiFi";
const TETHERING_TYPE_USB = "USB";
const WIFI_FIRMWARE_AP = "AP";
const WIFI_FIRMWARE_STATION = "STA";
const WIFI_SECURITY_TYPE_NONE = "open";
const WIFI_SECURITY_TYPE_WPA_PSK = "wpa-psk";
const WIFI_SECURITY_TYPE_WPA2_PSK = "wpa2-psk";
const WIFI_CTRL_INTERFACE = "wl0.1";
const NETWORK_INTERFACE_UP = "up";
const NETWORK_INTERFACE_DOWN = "down";
const TETHERING_STATE_ONGOING = "ongoing";
const TETHERING_STATE_IDLE = "idle";
const TETHERING_STATE_ACTIVE = "active";
// Settings DB path for USB tethering.
const SETTINGS_USB_ENABLED = "tethering.usb.enabled";
const SETTINGS_USB_IP = "tethering.usb.ip";
const SETTINGS_USB_PREFIX = "tethering.usb.prefix";
const SETTINGS_USB_DHCPSERVER_STARTIP = "tethering.usb.dhcpserver.startip";
const SETTINGS_USB_DHCPSERVER_ENDIP = "tethering.usb.dhcpserver.endip";
const SETTINGS_USB_DNS1 = "tethering.usb.dns1";
const SETTINGS_USB_DNS2 = "tethering.usb.dns2";
// Settings DB path for WIFI tethering.
const SETTINGS_WIFI_DHCPSERVER_STARTIP = "tethering.wifi.dhcpserver.startip";
const SETTINGS_WIFI_DHCPSERVER_ENDIP = "tethering.wifi.dhcpserver.endip";
// Settings DB patch for dun required setting.
const SETTINGS_DUN_REQUIRED = "tethering.dun.required";
// Default value for USB tethering.
const DEFAULT_USB_IP = "192.168.0.1";
const DEFAULT_USB_PREFIX = "24";
const DEFAULT_USB_DHCPSERVER_STARTIP = "192.168.0.10";
const DEFAULT_USB_DHCPSERVER_ENDIP = "192.168.0.30";
const DEFAULT_DNS1 = "8.8.8.8";
const DEFAULT_DNS2 = "8.8.4.4";
const DEFAULT_WIFI_DHCPSERVER_STARTIP = "192.168.1.10";
const DEFAULT_WIFI_DHCPSERVER_ENDIP = "192.168.1.30";
const IPV4_ADDRESS_ANY = "0.0.0.0";
const IPV6_ADDRESS_ANY = "::0";
const IPV4_MAX_PREFIX_LENGTH = 32;
const IPV6_MAX_PREFIX_LENGTH = 128;
const SETTINGS_DATA_DEFAULT_SERVICE_ID = "ril.data.defaultServiceId";
const MOBILE_DUN_CONNECT_TIMEOUT = 30000;
const MOBILE_DUN_RETRY_INTERVAL = 5000;
const MOBILE_DUN_MAX_RETRIES = 5;
// Connection Type for Network Information API
const CONNECTION_TYPE_CELLULAR = 0;
const CONNECTION_TYPE_BLUETOOTH = 1;
@ -179,8 +113,6 @@ NetworkInterfaceLinks.prototype = {
function NetworkManager() {
this.networkInterfaces = {};
this.networkInterfaceLinks = {};
Services.obs.addObserver(this, TOPIC_XPCOM_SHUTDOWN, false);
Services.obs.addObserver(this, TOPIC_MOZSETTINGS_CHANGED, false);
try {
this._manageOfflineStatus =
@ -189,52 +121,8 @@ function NetworkManager() {
// Ignore.
}
Services.prefs.addObserver(PREF_MANAGE_OFFLINE_STATUS, this, false);
Services.obs.addObserver(this, TOPIC_XPCOM_SHUTDOWN, false);
// Possible usb tethering interfaces for different gonk platform.
this.possibleInterface = POSSIBLE_USB_INTERFACE_NAME.split(",");
this._dataDefaultServiceId = 0;
// Default values for internal and external interfaces.
this._tetheringInterface = Object.create(null);
this._tetheringInterface[TETHERING_TYPE_USB] = {
externalInterface: DEFAULT_3G_INTERFACE_NAME,
internalInterface: DEFAULT_USB_INTERFACE_NAME
};
this._tetheringInterface[TETHERING_TYPE_WIFI] = {
externalInterface: DEFAULT_3G_INTERFACE_NAME,
internalInterface: DEFAULT_WIFI_INTERFACE_NAME
};
this.initTetheringSettings();
let settingsLock = gSettingsService.createLock();
// Read the default service id for data call.
settingsLock.get(SETTINGS_DATA_DEFAULT_SERVICE_ID, this);
// Read usb tethering data from settings DB.
settingsLock.get(SETTINGS_USB_IP, this);
settingsLock.get(SETTINGS_USB_PREFIX, this);
settingsLock.get(SETTINGS_USB_DHCPSERVER_STARTIP, this);
settingsLock.get(SETTINGS_USB_DHCPSERVER_ENDIP, this);
settingsLock.get(SETTINGS_USB_DNS1, this);
settingsLock.get(SETTINGS_USB_DNS2, this);
settingsLock.get(SETTINGS_USB_ENABLED, this);
// Read wifi tethering data from settings DB.
settingsLock.get(SETTINGS_WIFI_DHCPSERVER_STARTIP, this);
settingsLock.get(SETTINGS_WIFI_DHCPSERVER_ENDIP, this);
this._usbTetheringSettingsToRead = [SETTINGS_USB_IP,
SETTINGS_USB_PREFIX,
SETTINGS_USB_DHCPSERVER_STARTIP,
SETTINGS_USB_DHCPSERVER_ENDIP,
SETTINGS_USB_DNS1,
SETTINGS_USB_DNS2,
SETTINGS_USB_ENABLED,
SETTINGS_WIFI_DHCPSERVER_STARTIP,
SETTINGS_WIFI_DHCPSERVER_ENDIP];
this.wantConnectionEvent = null;
this.setAndConfigureActive();
ppmm.addMessageListener('NetworkInterfaceList:ListInterface', this);
@ -258,12 +146,6 @@ NetworkManager.prototype = {
observe: function(subject, topic, data) {
switch (topic) {
case TOPIC_MOZSETTINGS_CHANGED:
if ("wrappedJSObject" in subject) {
subject = subject.wrappedJSObject;
}
this.handle(subject.key, subject.value);
break;
case TOPIC_PREF_CHANGED:
this._manageOfflineStatus =
Services.prefs.getBoolPref(PREF_MANAGE_OFFLINE_STATUS);
@ -271,10 +153,7 @@ NetworkManager.prototype = {
break;
case TOPIC_XPCOM_SHUTDOWN:
Services.obs.removeObserver(this, TOPIC_XPCOM_SHUTDOWN);
Services.obs.removeObserver(this, TOPIC_MOZSETTINGS_CHANGED);
this.dunConnectTimer.cancel();
this.dunRetryTimer.cancel();
Services.prefs.removeObserver(PREF_MANAGE_OFFLINE_STATUS, this);
break;
}
},
@ -344,11 +223,6 @@ NetworkManager.prototype = {
this.networkInterfaces[networkId] = network;
this.networkInterfaceLinks[networkId] = new NetworkInterfaceLinks();
if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN) {
debug("Force setting " + SETTINGS_DUN_REQUIRED + " to true.");
this.tetheringSettings[SETTINGS_DUN_REQUIRED] = true;
}
Services.obs.notifyObservers(network, TOPIC_INTERFACE_REGISTERED, null);
debug("Network '" + networkId + "' registered.");
},
@ -421,8 +295,6 @@ NetworkManager.prototype = {
}
}
this.onConnectionChanged(network);
// Probing the public network accessibility after routing table is ready
CaptivePortalDetectionHelper
.notify(CaptivePortalDetectionHelper.EVENT_CONNECT, this.active);
@ -495,11 +367,6 @@ NetworkManager.prototype = {
delete this.networkInterfaces[networkId];
if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN) {
this.tetheringSettings[SETTINGS_DUN_REQUIRED] =
libcutils.property_get("ro.tethering.dun_required") === "1";
}
Services.obs.notifyObservers(network, TOPIC_INTERFACE_UNREGISTERED, null);
debug("Network '" + networkId + "' unregistered.");
},
@ -510,8 +377,6 @@ NetworkManager.prototype = {
networkInterfaceLinks: null,
_dataDefaultServiceId: null,
_preferredNetworkType: DEFAULT_PREFERRED_NETWORK_TYPE,
get preferredNetworkType() {
return this._preferredNetworkType;
@ -893,569 +758,6 @@ NetworkManager.prototype = {
}
},
// nsISettingsServiceCallback
tetheringSettings: {},
initTetheringSettings: function() {
this.tetheringSettings[SETTINGS_USB_ENABLED] = false;
this.tetheringSettings[SETTINGS_USB_IP] = DEFAULT_USB_IP;
this.tetheringSettings[SETTINGS_USB_PREFIX] = DEFAULT_USB_PREFIX;
this.tetheringSettings[SETTINGS_USB_DHCPSERVER_STARTIP] = DEFAULT_USB_DHCPSERVER_STARTIP;
this.tetheringSettings[SETTINGS_USB_DHCPSERVER_ENDIP] = DEFAULT_USB_DHCPSERVER_ENDIP;
this.tetheringSettings[SETTINGS_USB_DNS1] = DEFAULT_DNS1;
this.tetheringSettings[SETTINGS_USB_DNS2] = DEFAULT_DNS2;
this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_STARTIP] = DEFAULT_WIFI_DHCPSERVER_STARTIP;
this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_ENDIP] = DEFAULT_WIFI_DHCPSERVER_ENDIP;
this.tetheringSettings[SETTINGS_DUN_REQUIRED] =
libcutils.property_get("ro.tethering.dun_required") === "1";
},
_usbTetheringRequestCount: 0,
handle: function(aName, aResult) {
switch(aName) {
case SETTINGS_DATA_DEFAULT_SERVICE_ID:
this._dataDefaultServiceId = aResult || 0;
debug("'_dataDefaultServiceId' is now " + this._dataDefaultServiceId);
break;
case SETTINGS_USB_ENABLED:
this._oldUsbTetheringEnabledState = this.tetheringSettings[SETTINGS_USB_ENABLED];
case SETTINGS_USB_IP:
case SETTINGS_USB_PREFIX:
case SETTINGS_USB_DHCPSERVER_STARTIP:
case SETTINGS_USB_DHCPSERVER_ENDIP:
case SETTINGS_USB_DNS1:
case SETTINGS_USB_DNS2:
case SETTINGS_WIFI_DHCPSERVER_STARTIP:
case SETTINGS_WIFI_DHCPSERVER_ENDIP:
if (aResult !== null) {
this.tetheringSettings[aName] = aResult;
}
debug("'" + aName + "'" + " is now " + this.tetheringSettings[aName]);
let index = this._usbTetheringSettingsToRead.indexOf(aName);
if (index != -1) {
this._usbTetheringSettingsToRead.splice(index, 1);
}
if (this._usbTetheringSettingsToRead.length) {
debug("We haven't read completely the usb Tethering data from settings db.");
break;
}
if (this._oldUsbTetheringEnabledState === this.tetheringSettings[SETTINGS_USB_ENABLED]) {
debug("No changes for SETTINGS_USB_ENABLED flag. Nothing to do.");
this.handlePendingWifiTetheringRequest();
break;
}
this._usbTetheringRequestCount++;
if (this._usbTetheringRequestCount === 1) {
if (this._wifiTetheringRequestOngoing) {
debug('USB tethering request is blocked by ongoing wifi tethering request.');
} else {
this.handleLastUsbTetheringRequest();
}
}
break;
};
},
handleError: function(aErrorMessage) {
debug("There was an error while reading Tethering settings.");
this.tetheringSettings = {};
this.tetheringSettings[SETTINGS_USB_ENABLED] = false;
},
getNetworkInterface: function(type, serviceId) {
for each (let network in this.networkInterfaces) {
if (network.type == type) {
try {
if (network instanceof Ci.nsIRilNetworkInterface) {
let rilNetwork = network.QueryInterface(Ci.nsIRilNetworkInterface);
if (rilNetwork.serviceId != serviceId) {
continue;
}
}
} catch (e) {}
return network;
}
}
return null;
},
_usbTetheringAction: TETHERING_STATE_IDLE,
_usbTetheringSettingsToRead: [],
_oldUsbTetheringEnabledState: null,
// External and internal interface name.
_tetheringInterface: null,
handleLastUsbTetheringRequest: function() {
debug('handleLastUsbTetheringRequest... ' + this._usbTetheringRequestCount);
if (this._usbTetheringRequestCount === 0) {
if (this.wantConnectionEvent) {
if (this.tetheringSettings[SETTINGS_USB_ENABLED]) {
this.wantConnectionEvent.call(this);
}
this.wantConnectionEvent = null;
}
this.handlePendingWifiTetheringRequest();
return;
}
// Cancel the accumlated count to 1 since we only care about the
// last state.
this._usbTetheringRequestCount = 1;
this.handleUSBTetheringToggle(this.tetheringSettings[SETTINGS_USB_ENABLED]);
this.wantConnectionEvent = null;
},
handlePendingWifiTetheringRequest: function() {
if (this._pendingWifiTetheringRequestArgs) {
this.setWifiTethering.apply(this, this._pendingWifiTetheringRequestArgs);
this._pendingWifiTetheringRequestArgs = null;
}
},
dunConnectTimer: Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer),
/**
* Callback when dun connection fails to connect within timeout.
*/
onDunConnectTimerTimeout: function() {
while (this._pendingTetheringRequests.length > 0) {
debug("onDunConnectTimerTimeout: callback without network info.");
let callback = this._pendingTetheringRequests.shift();
if (typeof callback === 'function') {
callback();
}
}
},
dunRetryTimes: 0,
dunRetryTimer: Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer),
setupDunConnection: function() {
this.dunRetryTimer.cancel();
let connection =
gMobileConnectionService.getItemByServiceId(this._dataDefaultServiceId);
let data = connection && connection.data;
if (data && data.state === "registered") {
let ril = this.mRil.getRadioInterface(this._dataDefaultServiceId);
this.dunRetryTimes = 0;
ril.setupDataCallByType(Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN);
this.dunConnectTimer.cancel();
this.dunConnectTimer.
initWithCallback(this.onDunConnectTimerTimeout.bind(this),
MOBILE_DUN_CONNECT_TIMEOUT, Ci.nsITimer.TYPE_ONE_SHOT);
return;
}
if (this.dunRetryTimes++ >= this.MOBILE_DUN_MAX_RETRIES) {
debug("setupDunConnection: max retries reached.");
this.dunRetryTimes = 0;
// same as dun connect timeout.
this.onDunConnectTimerTimeout();
return;
}
debug("Data not ready, retry dun after " + MOBILE_DUN_RETRY_INTERVAL + " ms.");
this.dunRetryTimer.
initWithCallback(this.setupDunConnection.bind(this),
MOBILE_DUN_RETRY_INTERVAL, Ci.nsITimer.TYPE_ONE_SHOT);
},
_pendingTetheringRequests: [],
_dunActiveUsers: 0,
handleDunConnection: function(enable, callback) {
debug("handleDunConnection: " + enable);
let dun = this.getNetworkInterface(
Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN, this._dataDefaultServiceId);
if (!enable) {
this._dunActiveUsers--;
if (this._dunActiveUsers > 0) {
debug("Dun still needed by others, do not disconnect.")
return;
}
this.dunRetryTimes = 0;
this.dunRetryTimer.cancel();
this.dunConnectTimer.cancel();
this._pendingTetheringRequests = [];
if (dun && (dun.state == Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED)) {
this.mRil.getRadioInterface(this._dataDefaultServiceId)
.deactivateDataCallByType(Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN);
}
return;
}
this._dunActiveUsers++;
if (!dun || (dun.state != Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED)) {
debug("DUN data call inactive, setup dun data call!")
this._pendingTetheringRequests.push(callback);
this.dunRetryTimes = 0;
this.setupDunConnection();
return;
}
this._tetheringInterface[TETHERING_TYPE_USB].externalInterface = dun.name;
callback(dun);
},
handleUSBTetheringToggle: function(enable) {
debug("handleUSBTetheringToggle: " + enable);
if (enable &&
(this._usbTetheringAction === TETHERING_STATE_ONGOING ||
this._usbTetheringAction === TETHERING_STATE_ACTIVE)) {
debug("Usb tethering already connecting/connected.");
this._usbTetheringRequestCount = 0;
this.handlePendingWifiTetheringRequest();
return;
}
if (!enable &&
this._usbTetheringAction === TETHERING_STATE_IDLE) {
debug("Usb tethering already disconnected.");
this._usbTetheringRequestCount = 0;
this.handlePendingWifiTetheringRequest();
return;
}
if (!enable) {
this.tetheringSettings[SETTINGS_USB_ENABLED] = false;
gNetworkService.enableUsbRndis(false, this.enableUsbRndisResult.bind(this));
return;
}
this.tetheringSettings[SETTINGS_USB_ENABLED] = true;
this._usbTetheringAction = TETHERING_STATE_ONGOING;
if (this.tetheringSettings[SETTINGS_DUN_REQUIRED]) {
this.handleDunConnection(true, function(network) {
if (!network){
this.usbTetheringResultReport("Dun connection failed");
return;
}
this._tetheringInterface[TETHERING_TYPE_USB].externalInterface = network.name;
gNetworkService.enableUsbRndis(true, this.enableUsbRndisResult.bind(this));
}.bind(this));
return;
}
if (this.active) {
this._tetheringInterface[TETHERING_TYPE_USB].externalInterface = this.active.name;
} else {
let mobile = this.getNetworkInterface(
Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE, this._dataDefaultServiceId);
if (mobile && mobile.name) {
this._tetheringInterface[TETHERING_TYPE_USB].externalInterface = mobile.name;
}
}
gNetworkService.enableUsbRndis(true, this.enableUsbRndisResult.bind(this));
},
getUSBTetheringParameters: function(enable, tetheringinterface) {
let interfaceIp;
let prefix;
let wifiDhcpStartIp;
let wifiDhcpEndIp;
let usbDhcpStartIp;
let usbDhcpEndIp;
let dns1;
let dns2;
let internalInterface = tetheringinterface.internalInterface;
let externalInterface = tetheringinterface.externalInterface;
interfaceIp = this.tetheringSettings[SETTINGS_USB_IP];
prefix = this.tetheringSettings[SETTINGS_USB_PREFIX];
wifiDhcpStartIp = this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_STARTIP];
wifiDhcpEndIp = this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_ENDIP];
usbDhcpStartIp = this.tetheringSettings[SETTINGS_USB_DHCPSERVER_STARTIP];
usbDhcpEndIp = this.tetheringSettings[SETTINGS_USB_DHCPSERVER_ENDIP];
dns1 = this.tetheringSettings[SETTINGS_USB_DNS1];
dns2 = this.tetheringSettings[SETTINGS_USB_DNS2];
// Using the default values here until application support these settings.
if (interfaceIp == "" || prefix == "" ||
wifiDhcpStartIp == "" || wifiDhcpEndIp == "" ||
usbDhcpStartIp == "" || usbDhcpEndIp == "") {
debug("Invalid subnet information.");
return null;
}
return {
ifname: internalInterface,
ip: interfaceIp,
prefix: prefix,
wifiStartIp: wifiDhcpStartIp,
wifiEndIp: wifiDhcpEndIp,
usbStartIp: usbDhcpStartIp,
usbEndIp: usbDhcpEndIp,
dns1: dns1,
dns2: dns2,
internalIfname: internalInterface,
externalIfname: externalInterface,
enable: enable,
link: enable ? NETWORK_INTERFACE_UP : NETWORK_INTERFACE_DOWN
};
},
notifyError: function(resetSettings, callback, msg) {
if (resetSettings) {
let settingsLock = gSettingsService.createLock();
// Disable wifi tethering with a useful error message for the user.
settingsLock.set("tethering.wifi.enabled", false, null, msg);
}
debug("setWifiTethering: " + (msg ? msg : "success"));
if (callback) {
// Callback asynchronously to avoid netsted toggling.
Services.tm.currentThread.dispatch(() => {
callback.wifiTetheringEnabledChange(msg);
}, Ci.nsIThread.DISPATCH_NORMAL);
}
},
_wifiTetheringRequestOngoing: false,
enableWifiTethering: function(enable, config, callback) {
// Fill in config's required fields.
config.ifname = this._tetheringInterface[TETHERING_TYPE_WIFI].internalInterface;
config.internalIfname = this._tetheringInterface[TETHERING_TYPE_WIFI].internalInterface;
config.externalIfname = this._tetheringInterface[TETHERING_TYPE_WIFI].externalInterface;
this._wifiTetheringRequestOngoing = true;
gNetworkService.setWifiTethering(enable, config, (function(error) {
// Disconnect dun on error or when wifi tethering is disabled.
if (this.tetheringSettings[SETTINGS_DUN_REQUIRED] &&
(!enable || error)) {
this.handleDunConnection(false);
}
let resetSettings = error;
debug('gNetworkService.setWifiTethering finished');
this.notifyError(resetSettings, callback, error);
this._wifiTetheringRequestOngoing = false;
if (this._usbTetheringRequestCount > 0) {
debug('Perform pending USB tethering requests.');
this.handleLastUsbTetheringRequest();
}
}).bind(this));
},
_pendingWifiTetheringRequestArgs: null,
// Enable/disable WiFi tethering by sending commands to netd.
setWifiTethering: function(enable, network, config, callback) {
debug("setWifiTethering: " + enable);
if (!network) {
this.notifyError(true, callback, "invalid network information");
return;
}
if (!config) {
this.notifyError(true, callback, "invalid configuration");
return;
}
if (this._usbTetheringRequestCount > 0) {
// If there's still pending usb tethering request, save
// the request params and redo |setWifiTethering| on
// usb tethering task complete.
debug('USB tethering request is being processed. Queue this wifi tethering request.');
this._pendingWifiTetheringRequestArgs = Array.prototype.slice.call(arguments);
debug('Pending args: ' + JSON.stringify(this._pendingWifiTetheringRequestArgs));
return;
}
if (!enable) {
this.enableWifiTethering(false, config, callback);
return;
}
this._tetheringInterface[TETHERING_TYPE_WIFI].internalInterface = network.name;
if (this.tetheringSettings[SETTINGS_DUN_REQUIRED]) {
this.handleDunConnection(true, function(config, callback, network) {
if (!network) {
this.notifyError(true, callback, "Dun connection failed");
return;
}
this._tetheringInterface[TETHERING_TYPE_WIFI].externalInterface = network.name;
this.enableWifiTethering(true, config, callback);
}.bind(this, config, callback));
return;
}
let mobile = this.getNetworkInterface(
Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE, this._dataDefaultServiceId);
// Update the real interface name
if (mobile && mobile.name) {
this._tetheringInterface[TETHERING_TYPE_WIFI].externalInterface = mobile.name;
}
this.enableWifiTethering(true, config, callback);
},
// Enable/disable USB tethering by sending commands to netd.
setUSBTethering: function(enable, tetheringInterface, callback) {
let params = this.getUSBTetheringParameters(enable, tetheringInterface);
if (params === null) {
gNetworkService.enableUsbRndis(false, function() {
this.usbTetheringResultReport("Invalid parameters");
});
return;
}
gNetworkService.setUSBTethering(enable, params, callback);
},
getUsbInterface: function() {
// Find the rndis interface.
for (let i = 0; i < this.possibleInterface.length; i++) {
try {
let file = new FileUtils.File(KERNEL_NETWORK_ENTRY + "/" +
this.possibleInterface[i]);
if (file.exists()) {
return this.possibleInterface[i];
}
} catch (e) {
debug("Not " + this.possibleInterface[i] + " interface.");
}
}
debug("Can't find rndis interface in possible lists.");
return DEFAULT_USB_INTERFACE_NAME;
},
enableUsbRndisResult: function(success, enable) {
if (success) {
// If enable is false, don't find usb interface cause it is already down,
// just use the internal interface in settings.
if (enable) {
this._tetheringInterface[TETHERING_TYPE_USB].internalInterface = this.getUsbInterface();
}
this.setUSBTethering(enable,
this._tetheringInterface[TETHERING_TYPE_USB],
this.usbTetheringResultReport.bind(this, enable));
} else {
this.usbTetheringResultReport(enable, "enableUsbRndisResult failure");
throw new Error("failed to set USB Function to adb");
}
},
usbTetheringResultReport: function(enable, error) {
this._usbTetheringRequestCount--;
let settingsLock = gSettingsService.createLock();
debug('usbTetheringResultReport callback. enable: ' + enable + ', error: ' + error);
// Disable tethering settings when fail to enable it.
if (error) {
this.tetheringSettings[SETTINGS_USB_ENABLED] = false;
settingsLock.set("tethering.usb.enabled", false, null);
// Skip others request when we found an error.
this._usbTetheringRequestCount = 0;
this._usbTetheringAction = TETHERING_STATE_IDLE;
if (this.tetheringSettings[SETTINGS_DUN_REQUIRED]) {
this.handleDunConnection(false);
}
} else {
if (enable) {
this._usbTetheringAction = TETHERING_STATE_ACTIVE;
} else {
this._usbTetheringAction = TETHERING_STATE_IDLE;
if (this.tetheringSettings[SETTINGS_DUN_REQUIRED]) {
this.handleDunConnection(false);
}
}
this.handleLastUsbTetheringRequest();
}
},
onConnectionChangedReport: function(success, externalIfname) {
debug("onConnectionChangedReport result: success " + success);
if (success) {
// Update the external interface.
this._tetheringInterface[TETHERING_TYPE_USB].externalInterface = externalIfname;
debug("Change the interface name to " + externalIfname);
}
},
onConnectionChanged: function(network) {
if (network.state != Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED) {
debug("We are only interested in CONNECTED event");
return;
}
if (this.tetheringSettings[SETTINGS_DUN_REQUIRED] &&
network.type === Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN) {
this.dunConnectTimer.cancel();
debug("DUN data call connected, process callbacks.");
while (this._pendingTetheringRequests.length > 0) {
let callback = this._pendingTetheringRequests.shift();
if (typeof callback === 'function') {
callback(network);
}
}
return;
}
if (!this.tetheringSettings[SETTINGS_USB_ENABLED]) {
debug("Usb tethering settings is not enabled");
return;
}
if (this.tetheringSettings[SETTINGS_DUN_REQUIRED] &&
network.type === Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN &&
this._tetheringInterface[TETHERING_TYPE_USB].externalInterface ===
network.name) {
debug("Dun required and dun interface is the same");
return;
}
if (this._tetheringInterface[TETHERING_TYPE_USB].externalInterface ===
this.active.name) {
debug("The active interface is the same");
return;
}
let previous = {
internalIfname: this._tetheringInterface[TETHERING_TYPE_USB].internalInterface,
externalIfname: this._tetheringInterface[TETHERING_TYPE_USB].externalInterface
};
let current = {
internalIfname: this._tetheringInterface[TETHERING_TYPE_USB].internalInterface,
externalIfname: network.name
};
let callback = (function() {
// Update external network interface.
debug("Update upstream interface to " + network.name);
gNetworkService.updateUpStream(previous, current, this.onConnectionChangedReport.bind(this));
}).bind(this);
if (this._usbTetheringAction === TETHERING_STATE_ONGOING) {
debug("Postpone the event and handle it when state is idle.");
this.wantConnectionEvent = callback;
return;
}
this.wantConnectionEvent = null;
callback.call(this);
},
_setDefaultRouteAndDNS: function(network, oldInterface) {
gNetworkService.setDefaultRoute(network, oldInterface, function(success) {
if (!success) {

View File

@ -0,0 +1,822 @@
/* 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/. */
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/FileUtils.jsm");
Cu.import("resource://gre/modules/systemlibs.js");
const TETHERINGSERVICE_CONTRACTID = "@mozilla.org/tethering/service;1";
const TETHERINGSERVICE_CID =
Components.ID("{527a4121-ee5a-4651-be9c-f46f59cf7c01}");
XPCOMUtils.defineLazyServiceGetter(this, "gNetworkManager",
"@mozilla.org/network/manager;1",
"nsINetworkManager");
XPCOMUtils.defineLazyServiceGetter(this, "gNetworkService",
"@mozilla.org/network/service;1",
"nsINetworkService");
XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService",
"@mozilla.org/settingsService;1",
"nsISettingsService");
XPCOMUtils.defineLazyServiceGetter(this, "gMobileConnectionService",
"@mozilla.org/mobileconnection/mobileconnectionservice;1",
"nsIMobileConnectionService");
XPCOMUtils.defineLazyGetter(this, "gRil", function() {
try {
return Cc["@mozilla.org/ril;1"].getService(Ci.nsIRadioInterfaceLayer);
} catch (e) {}
return null;
});
const TOPIC_INTERFACE_REGISTERED = "network-interface-registered";
const TOPIC_INTERFACE_UNREGISTERED = "network-interface-unregistered";
const TOPIC_MOZSETTINGS_CHANGED = "mozsettings-changed";
const TOPIC_CONNECTION_STATE_CHANGED = "network-connection-state-changed";
const TOPIC_XPCOM_SHUTDOWN = "xpcom-shutdown";
const POSSIBLE_USB_INTERFACE_NAME = "rndis0,usb0";
const DEFAULT_USB_INTERFACE_NAME = "rndis0";
const DEFAULT_3G_INTERFACE_NAME = "rmnet0";
const DEFAULT_WIFI_INTERFACE_NAME = "wlan0";
// The kernel's proc entry for network lists.
const KERNEL_NETWORK_ENTRY = "/sys/class/net";
const TETHERING_TYPE_WIFI = "WiFi";
const TETHERING_TYPE_USB = "USB";
const WIFI_FIRMWARE_AP = "AP";
const WIFI_FIRMWARE_STATION = "STA";
const WIFI_SECURITY_TYPE_NONE = "open";
const WIFI_SECURITY_TYPE_WPA_PSK = "wpa-psk";
const WIFI_SECURITY_TYPE_WPA2_PSK = "wpa2-psk";
const WIFI_CTRL_INTERFACE = "wl0.1";
const NETWORK_INTERFACE_UP = "up";
const NETWORK_INTERFACE_DOWN = "down";
const TETHERING_STATE_ONGOING = "ongoing";
const TETHERING_STATE_IDLE = "idle";
const TETHERING_STATE_ACTIVE = "active";
// Settings DB path for USB tethering.
const SETTINGS_USB_ENABLED = "tethering.usb.enabled";
const SETTINGS_USB_IP = "tethering.usb.ip";
const SETTINGS_USB_PREFIX = "tethering.usb.prefix";
const SETTINGS_USB_DHCPSERVER_STARTIP = "tethering.usb.dhcpserver.startip";
const SETTINGS_USB_DHCPSERVER_ENDIP = "tethering.usb.dhcpserver.endip";
const SETTINGS_USB_DNS1 = "tethering.usb.dns1";
const SETTINGS_USB_DNS2 = "tethering.usb.dns2";
// Settings DB path for WIFI tethering.
const SETTINGS_WIFI_DHCPSERVER_STARTIP = "tethering.wifi.dhcpserver.startip";
const SETTINGS_WIFI_DHCPSERVER_ENDIP = "tethering.wifi.dhcpserver.endip";
// Settings DB patch for dun required setting.
const SETTINGS_DUN_REQUIRED = "tethering.dun.required";
// Default value for USB tethering.
const DEFAULT_USB_IP = "192.168.0.1";
const DEFAULT_USB_PREFIX = "24";
const DEFAULT_USB_DHCPSERVER_STARTIP = "192.168.0.10";
const DEFAULT_USB_DHCPSERVER_ENDIP = "192.168.0.30";
const DEFAULT_DNS1 = "8.8.8.8";
const DEFAULT_DNS2 = "8.8.4.4";
const DEFAULT_WIFI_DHCPSERVER_STARTIP = "192.168.1.10";
const DEFAULT_WIFI_DHCPSERVER_ENDIP = "192.168.1.30";
const SETTINGS_DATA_DEFAULT_SERVICE_ID = "ril.data.defaultServiceId";
const MOBILE_DUN_CONNECT_TIMEOUT = 30000;
const MOBILE_DUN_RETRY_INTERVAL = 5000;
const MOBILE_DUN_MAX_RETRIES = 5;
let DEBUG = false;
// Read debug setting from pref.
try {
let debugPref = Services.prefs.getBoolPref("network.debugging.enabled");
DEBUG = DEBUG || debugPref;
} catch (e) {}
let debug;
if (DEBUG) {
debug = function(s) {
dump("-*- TetheringService: " + s + "\n");
};
} else {
debug = function(s) {};
}
function TetheringService() {
Services.obs.addObserver(this, TOPIC_XPCOM_SHUTDOWN, false);
Services.obs.addObserver(this, TOPIC_MOZSETTINGS_CHANGED, false);
Services.obs.addObserver(this, TOPIC_CONNECTION_STATE_CHANGED, false);
Services.obs.addObserver(this, TOPIC_INTERFACE_REGISTERED, false);
Services.obs.addObserver(this, TOPIC_INTERFACE_UNREGISTERED, false);
this._dataDefaultServiceId = 0;
// Possible usb tethering interfaces for different gonk platform.
this.possibleInterface = POSSIBLE_USB_INTERFACE_NAME.split(",");
// Default values for internal and external interfaces.
this._tetheringInterface = {};
this._tetheringInterface[TETHERING_TYPE_USB] = {
externalInterface: DEFAULT_3G_INTERFACE_NAME,
internalInterface: DEFAULT_USB_INTERFACE_NAME
};
this._tetheringInterface[TETHERING_TYPE_WIFI] = {
externalInterface: DEFAULT_3G_INTERFACE_NAME,
internalInterface: DEFAULT_WIFI_INTERFACE_NAME
};
this.tetheringSettings = {};
this.initTetheringSettings();
let settingsLock = gSettingsService.createLock();
// Read the default service id for data call.
settingsLock.get(SETTINGS_DATA_DEFAULT_SERVICE_ID, this);
// Read usb tethering data from settings DB.
settingsLock.get(SETTINGS_USB_IP, this);
settingsLock.get(SETTINGS_USB_PREFIX, this);
settingsLock.get(SETTINGS_USB_DHCPSERVER_STARTIP, this);
settingsLock.get(SETTINGS_USB_DHCPSERVER_ENDIP, this);
settingsLock.get(SETTINGS_USB_DNS1, this);
settingsLock.get(SETTINGS_USB_DNS2, this);
settingsLock.get(SETTINGS_USB_ENABLED, this);
// Read wifi tethering data from settings DB.
settingsLock.get(SETTINGS_WIFI_DHCPSERVER_STARTIP, this);
settingsLock.get(SETTINGS_WIFI_DHCPSERVER_ENDIP, this);
this._usbTetheringSettingsToRead = [SETTINGS_USB_IP,
SETTINGS_USB_PREFIX,
SETTINGS_USB_DHCPSERVER_STARTIP,
SETTINGS_USB_DHCPSERVER_ENDIP,
SETTINGS_USB_DNS1,
SETTINGS_USB_DNS2,
SETTINGS_USB_ENABLED,
SETTINGS_WIFI_DHCPSERVER_STARTIP,
SETTINGS_WIFI_DHCPSERVER_ENDIP];
this.wantConnectionEvent = null;
this.dunConnectTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
this.dunRetryTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
this._pendingTetheringRequests = [];
}
TetheringService.prototype = {
classID: TETHERINGSERVICE_CID,
classInfo: XPCOMUtils.generateCI({classID: TETHERINGSERVICE_CID,
contractID: TETHERINGSERVICE_CONTRACTID,
classDescription: "Tethering Service",
interfaces: [Ci.nsITetheringService]}),
QueryInterface: XPCOMUtils.generateQI([Ci.nsITetheringService,
Ci.nsISupportsWeakReference,
Ci.nsIObserver,
Ci.nsISettingsServiceCallback]),
// Flag to record the default client id for data call.
_dataDefaultServiceId: null,
// Number of usb tehering requests to be processed.
_usbTetheringRequestCount: 0,
// Usb tethering state.
_usbTetheringAction: TETHERING_STATE_IDLE,
// Tethering settings.
tetheringSettings: null,
// Tethering settings need to be read from settings DB.
_usbTetheringSettingsToRead: null,
// Previous usb tethering enabled state.
_oldUsbTetheringEnabledState: null,
// External and internal interface name.
_tetheringInterface: null,
// Dun connection timer.
dunConnectTimer: null,
// Dun connection retry times.
dunRetryTimes: 0,
// Dun retry timer.
dunRetryTimer: null,
// Pending tethering request to handle after dun is connected.
_pendingTetheringRequests: null,
// Flag to indicate wether wifi tethering is being processed.
_wifiTetheringRequestOngoing: false,
// Arguments for pending wifi tethering request.
_pendingWifiTetheringRequestArgs: null,
// nsIObserver
observe: function(aSubject, aTopic, aData) {
let network;
switch(aTopic) {
case TOPIC_MOZSETTINGS_CHANGED:
if ("wrappedJSObject" in aSubject) {
aSubject = aSubject.wrappedJSObject;
}
this.handle(aSubject.key, aSubject.value);
break;
case TOPIC_CONNECTION_STATE_CHANGED:
network = aSubject.QueryInterface(Ci.nsINetworkInterface);
debug("Network " + network.type + "/" + network.name +
" changed state to " + network.state);
this.onConnectionChanged(network);
break;
case TOPIC_INTERFACE_REGISTERED:
network = aSubject.QueryInterface(Ci.nsINetworkInterface);
if (network &&
network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN) {
debug("Force setting " + SETTINGS_DUN_REQUIRED + " to true.");
this.tetheringSettings[SETTINGS_DUN_REQUIRED] = true;
}
break;
case TOPIC_INTERFACE_UNREGISTERED:
network = aSubject.QueryInterface(Ci.nsINetworkInterface);
if (network &&
network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN) {
this.tetheringSettings[SETTINGS_DUN_REQUIRED] =
libcutils.property_get("ro.tethering.dun_required") === "1";
}
break;
case TOPIC_XPCOM_SHUTDOWN:
Services.obs.removeObserver(this, TOPIC_XPCOM_SHUTDOWN);
Services.obs.removeObserver(this, TOPIC_MOZSETTINGS_CHANGED);
Services.obs.removeObserver(this, TOPIC_CONNECTION_STATE_CHANGED);
Services.obs.removeObserver(this, TOPIC_INTERFACE_REGISTERED);
Services.obs.removeObserver(this, TOPIC_INTERFACE_UNREGISTERED);
this.dunConnectTimer.cancel();
this.dunRetryTimer.cancel();
break;
}
},
// nsISettingsServiceCallback
handle: function(aName, aResult) {
switch(aName) {
case SETTINGS_DATA_DEFAULT_SERVICE_ID:
this._dataDefaultServiceId = aResult || 0;
debug("'_dataDefaultServiceId' is now " + this._dataDefaultServiceId);
break;
case SETTINGS_USB_ENABLED:
this._oldUsbTetheringEnabledState = this.tetheringSettings[SETTINGS_USB_ENABLED];
case SETTINGS_USB_IP:
case SETTINGS_USB_PREFIX:
case SETTINGS_USB_DHCPSERVER_STARTIP:
case SETTINGS_USB_DHCPSERVER_ENDIP:
case SETTINGS_USB_DNS1:
case SETTINGS_USB_DNS2:
case SETTINGS_WIFI_DHCPSERVER_STARTIP:
case SETTINGS_WIFI_DHCPSERVER_ENDIP:
if (aResult !== null) {
this.tetheringSettings[aName] = aResult;
}
debug("'" + aName + "'" + " is now " + this.tetheringSettings[aName]);
let index = this._usbTetheringSettingsToRead.indexOf(aName);
if (index != -1) {
this._usbTetheringSettingsToRead.splice(index, 1);
}
if (this._usbTetheringSettingsToRead.length) {
debug("We haven't read completely the usb Tethering data from settings db.");
break;
}
if (this._oldUsbTetheringEnabledState === this.tetheringSettings[SETTINGS_USB_ENABLED]) {
debug("No changes for SETTINGS_USB_ENABLED flag. Nothing to do.");
this.handlePendingWifiTetheringRequest();
break;
}
this._usbTetheringRequestCount++;
if (this._usbTetheringRequestCount === 1) {
if (this._wifiTetheringRequestOngoing) {
debug('USB tethering request is blocked by ongoing wifi tethering request.');
} else {
this.handleLastUsbTetheringRequest();
}
}
break;
};
},
handleError: function(aErrorMessage) {
debug("There was an error while reading Tethering settings.");
this.tetheringSettings = {};
this.tetheringSettings[SETTINGS_USB_ENABLED] = false;
},
initTetheringSettings: function() {
this.tetheringSettings[SETTINGS_USB_ENABLED] = false;
this.tetheringSettings[SETTINGS_USB_IP] = DEFAULT_USB_IP;
this.tetheringSettings[SETTINGS_USB_PREFIX] = DEFAULT_USB_PREFIX;
this.tetheringSettings[SETTINGS_USB_DHCPSERVER_STARTIP] = DEFAULT_USB_DHCPSERVER_STARTIP;
this.tetheringSettings[SETTINGS_USB_DHCPSERVER_ENDIP] = DEFAULT_USB_DHCPSERVER_ENDIP;
this.tetheringSettings[SETTINGS_USB_DNS1] = DEFAULT_DNS1;
this.tetheringSettings[SETTINGS_USB_DNS2] = DEFAULT_DNS2;
this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_STARTIP] = DEFAULT_WIFI_DHCPSERVER_STARTIP;
this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_ENDIP] = DEFAULT_WIFI_DHCPSERVER_ENDIP;
this.tetheringSettings[SETTINGS_DUN_REQUIRED] =
libcutils.property_get("ro.tethering.dun_required") === "1";
},
getNetworkInterface: function(aType, aServiceId) {
for each (let network in gNetworkManager.networkInterfaces) {
if (network.type == aType) {
try {
if (network instanceof Ci.nsIRilNetworkInterface) {
let rilNetwork = network.QueryInterface(Ci.nsIRilNetworkInterface);
if (rilNetwork.serviceId != aServiceId) {
continue;
}
}
} catch (e) {}
return network;
}
}
return null;
},
handleLastUsbTetheringRequest: function() {
debug('handleLastUsbTetheringRequest... ' + this._usbTetheringRequestCount);
if (this._usbTetheringRequestCount === 0) {
if (this.wantConnectionEvent) {
if (this.tetheringSettings[SETTINGS_USB_ENABLED]) {
this.wantConnectionEvent.call(this);
}
this.wantConnectionEvent = null;
}
this.handlePendingWifiTetheringRequest();
return;
}
// Cancel the accumlated count to 1 since we only care about the
// last state.
this._usbTetheringRequestCount = 1;
this.handleUSBTetheringToggle(this.tetheringSettings[SETTINGS_USB_ENABLED]);
this.wantConnectionEvent = null;
},
handlePendingWifiTetheringRequest: function() {
if (this._pendingWifiTetheringRequestArgs) {
this.setWifiTethering.apply(this, this._pendingWifiTetheringRequestArgs);
this._pendingWifiTetheringRequestArgs = null;
}
},
/**
* Callback when dun connection fails to connect within timeout.
*/
onDunConnectTimerTimeout: function() {
while (this._pendingTetheringRequests.length > 0) {
debug("onDunConnectTimerTimeout: callback without network info.");
let callback = this._pendingTetheringRequests.shift();
if (typeof callback === 'function') {
callback();
}
}
},
setupDunConnection: function() {
this.dunRetryTimer.cancel();
let connection =
gMobileConnectionService.getItemByServiceId(this._dataDefaultServiceId);
let data = connection && connection.data;
if (data && data.state === "registered") {
let ril = gRil.getRadioInterface(this._dataDefaultServiceId);
this.dunRetryTimes = 0;
ril.setupDataCallByType(Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN);
this.dunConnectTimer.cancel();
this.dunConnectTimer.
initWithCallback(this.onDunConnectTimerTimeout.bind(this),
MOBILE_DUN_CONNECT_TIMEOUT, Ci.nsITimer.TYPE_ONE_SHOT);
return;
}
if (this.dunRetryTimes++ >= this.MOBILE_DUN_MAX_RETRIES) {
debug("setupDunConnection: max retries reached.");
this.dunRetryTimes = 0;
// same as dun connect timeout.
this.onDunConnectTimerTimeout();
return;
}
debug("Data not ready, retry dun after " + MOBILE_DUN_RETRY_INTERVAL + " ms.");
this.dunRetryTimer.
initWithCallback(this.setupDunConnection.bind(this),
MOBILE_DUN_RETRY_INTERVAL, Ci.nsITimer.TYPE_ONE_SHOT);
},
_dunActiveUsers: 0,
handleDunConnection: function(aEnable, aCallback) {
debug("handleDunConnection: " + aEnable);
let dun = this.getNetworkInterface(
Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN, this._dataDefaultServiceId);
if (!aEnable) {
this._dunActiveUsers--;
if (this._dunActiveUsers > 0) {
debug("Dun still needed by others, do not disconnect.")
return;
}
this.dunRetryTimes = 0;
this.dunRetryTimer.cancel();
this.dunConnectTimer.cancel();
this._pendingTetheringRequests = [];
if (dun && (dun.state == Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED)) {
gRil.getRadioInterface(this._dataDefaultServiceId)
.deactivateDataCallByType(Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN);
}
return;
}
this._dunActiveUsers++;
if (!dun || (dun.state != Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED)) {
debug("DUN data call inactive, setup dun data call!")
this._pendingTetheringRequests.push(aCallback);
this.dunRetryTimes = 0;
this.setupDunConnection();
return;
}
this._tetheringInterface[TETHERING_TYPE_USB].externalInterface = dun.name;
aCallback(dun);
},
handleUSBTetheringToggle: function(aEnable) {
debug("handleUSBTetheringToggle: " + aEnable);
if (aEnable &&
(this._usbTetheringAction === TETHERING_STATE_ONGOING ||
this._usbTetheringAction === TETHERING_STATE_ACTIVE)) {
debug("Usb tethering already connecting/connected.");
this._usbTetheringRequestCount = 0;
this.handlePendingWifiTetheringRequest();
return;
}
if (!aEnable &&
this._usbTetheringAction === TETHERING_STATE_IDLE) {
debug("Usb tethering already disconnected.");
this._usbTetheringRequestCount = 0;
this.handlePendingWifiTetheringRequest();
return;
}
if (!aEnable) {
this.tetheringSettings[SETTINGS_USB_ENABLED] = false;
gNetworkService.enableUsbRndis(false, this.enableUsbRndisResult.bind(this));
return;
}
this.tetheringSettings[SETTINGS_USB_ENABLED] = true;
this._usbTetheringAction = TETHERING_STATE_ONGOING;
if (this.tetheringSettings[SETTINGS_DUN_REQUIRED]) {
this.handleDunConnection(true, (aNetwork) => {
if (!aNetwork){
this.usbTetheringResultReport(aEnable, "Dun connection failed");
return;
}
this._tetheringInterface[TETHERING_TYPE_USB].externalInterface = aNetwork.name;
gNetworkService.enableUsbRndis(true, this.enableUsbRndisResult.bind(this));
});
return;
}
if (gNetworkManager.active) {
this._tetheringInterface[TETHERING_TYPE_USB].externalInterface =
gNetworkManager.active.name;
} else {
let mobile = this.getNetworkInterface(
Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE, this._dataDefaultServiceId);
if (mobile && mobile.name) {
this._tetheringInterface[TETHERING_TYPE_USB].externalInterface = mobile.name;
}
}
gNetworkService.enableUsbRndis(true, this.enableUsbRndisResult.bind(this));
},
getUSBTetheringParameters: function(aEnable, aTetheringInterface) {
let interfaceIp = this.tetheringSettings[SETTINGS_USB_IP];
let prefix = this.tetheringSettings[SETTINGS_USB_PREFIX];
let wifiDhcpStartIp = this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_STARTIP];
let wifiDhcpEndIp = this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_ENDIP];
let usbDhcpStartIp = this.tetheringSettings[SETTINGS_USB_DHCPSERVER_STARTIP];
let usbDhcpEndIp = this.tetheringSettings[SETTINGS_USB_DHCPSERVER_ENDIP];
let dns1 = this.tetheringSettings[SETTINGS_USB_DNS1];
let dns2 = this.tetheringSettings[SETTINGS_USB_DNS2];
let internalInterface = aTetheringInterface.internalInterface;
let externalInterface = aTetheringInterface.externalInterface;
// Using the default values here until application support these settings.
if (interfaceIp == "" || prefix == "" ||
wifiDhcpStartIp == "" || wifiDhcpEndIp == "" ||
usbDhcpStartIp == "" || usbDhcpEndIp == "") {
debug("Invalid subnet information.");
return null;
}
return {
ifname: internalInterface,
ip: interfaceIp,
prefix: prefix,
wifiStartIp: wifiDhcpStartIp,
wifiEndIp: wifiDhcpEndIp,
usbStartIp: usbDhcpStartIp,
usbEndIp: usbDhcpEndIp,
dns1: dns1,
dns2: dns2,
internalIfname: internalInterface,
externalIfname: externalInterface,
enable: aEnable,
link: aEnable ? NETWORK_INTERFACE_UP : NETWORK_INTERFACE_DOWN
};
},
notifyError: function(aResetSettings, aCallback, aMsg) {
if (aResetSettings) {
let settingsLock = gSettingsService.createLock();
// Disable wifi tethering with a useful error message for the user.
settingsLock.set("tethering.wifi.enabled", false, null, aMsg);
}
debug("setWifiTethering: " + (aMsg ? aMsg : "success"));
if (aCallback) {
// Callback asynchronously to avoid netsted toggling.
Services.tm.currentThread.dispatch(() => {
aCallback.wifiTetheringEnabledChange(aMsg);
}, Ci.nsIThread.DISPATCH_NORMAL);
}
},
enableWifiTethering: function(aEnable, aConfig, aCallback) {
// Fill in config's required fields.
aConfig.ifname = this._tetheringInterface[TETHERING_TYPE_WIFI].internalInterface;
aConfig.internalIfname = this._tetheringInterface[TETHERING_TYPE_WIFI].internalInterface;
aConfig.externalIfname = this._tetheringInterface[TETHERING_TYPE_WIFI].externalInterface;
this._wifiTetheringRequestOngoing = true;
gNetworkService.setWifiTethering(aEnable, aConfig, (aError) => {
// Disconnect dun on error or when wifi tethering is disabled.
if (this.tetheringSettings[SETTINGS_DUN_REQUIRED] &&
(!aEnable || aError)) {
this.handleDunConnection(false);
}
let resetSettings = aError;
debug('gNetworkService.setWifiTethering finished');
this.notifyError(resetSettings, aCallback, aError);
this._wifiTetheringRequestOngoing = false;
if (this._usbTetheringRequestCount > 0) {
debug('Perform pending USB tethering requests.');
this.handleLastUsbTetheringRequest();
}
});
},
// Enable/disable WiFi tethering by sending commands to netd.
setWifiTethering: function(aEnable, aNetwork, aConfig, aCallback) {
debug("setWifiTethering: " + aEnable);
if (!aNetwork) {
this.notifyError(true, aCallback, "invalid network information");
return;
}
if (!aConfig) {
this.notifyError(true, aCallback, "invalid configuration");
return;
}
if (this._usbTetheringRequestCount > 0) {
// If there's still pending usb tethering request, save
// the request params and redo |setWifiTethering| on
// usb tethering task complete.
debug('USB tethering request is being processed. Queue this wifi tethering request.');
this._pendingWifiTetheringRequestArgs = Array.prototype.slice.call(arguments);
debug('Pending args: ' + JSON.stringify(this._pendingWifiTetheringRequestArgs));
return;
}
if (!aEnable) {
this.enableWifiTethering(false, aConfig, aCallback);
return;
}
this._tetheringInterface[TETHERING_TYPE_WIFI].internalInterface = aNetwork.name;
if (this.tetheringSettings[SETTINGS_DUN_REQUIRED]) {
this.handleDunConnection(true, (aNetwork) => {
if (!aNetwork) {
this.notifyError(true, aCallback, "Dun connection failed");
return;
}
this._tetheringInterface[TETHERING_TYPE_WIFI].externalInterface = aNetwork.name;
this.enableWifiTethering(true, aConfig, aCallback);
});
return;
}
let mobile = this.getNetworkInterface(
Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE, this._dataDefaultServiceId);
// Update the real interface name
if (mobile && mobile.name) {
this._tetheringInterface[TETHERING_TYPE_WIFI].externalInterface = mobile.name;
}
this.enableWifiTethering(true, aConfig, aCallback);
},
// Enable/disable USB tethering by sending commands to netd.
setUSBTethering: function(aEnable, aTetheringInterface, aCallback) {
let params = this.getUSBTetheringParameters(aEnable, aTetheringInterface);
if (params === null) {
gNetworkService.enableUsbRndis(false, function() {
this.usbTetheringResultReport(aEnable, "Invalid parameters");
});
return;
}
gNetworkService.setUSBTethering(aEnable, params, aCallback);
},
getUsbInterface: function() {
// Find the rndis interface.
for (let i = 0; i < this.possibleInterface.length; i++) {
try {
let file = new FileUtils.File(KERNEL_NETWORK_ENTRY + "/" +
this.possibleInterface[i]);
if (file.exists()) {
return this.possibleInterface[i];
}
} catch (e) {
debug("Not " + this.possibleInterface[i] + " interface.");
}
}
debug("Can't find rndis interface in possible lists.");
return DEFAULT_USB_INTERFACE_NAME;
},
enableUsbRndisResult: function(aSuccess, aEnable) {
if (aSuccess) {
// If enable is false, don't find usb interface cause it is already down,
// just use the internal interface in settings.
if (aEnable) {
this._tetheringInterface[TETHERING_TYPE_USB].internalInterface =
this.getUsbInterface();
}
this.setUSBTethering(aEnable,
this._tetheringInterface[TETHERING_TYPE_USB],
this.usbTetheringResultReport.bind(this, aEnable));
} else {
this.usbTetheringResultReport(aEnable, "enableUsbRndisResult failure");
throw new Error("failed to set USB Function to adb");
}
},
usbTetheringResultReport: function(aEnable, aError) {
this._usbTetheringRequestCount--;
let settingsLock = gSettingsService.createLock();
debug('usbTetheringResultReport callback. enable: ' + aEnable +
', error: ' + aError);
// Disable tethering settings when fail to enable it.
if (aError) {
this.tetheringSettings[SETTINGS_USB_ENABLED] = false;
settingsLock.set("tethering.usb.enabled", false, null);
// Skip others request when we found an error.
this._usbTetheringRequestCount = 0;
this._usbTetheringAction = TETHERING_STATE_IDLE;
if (this.tetheringSettings[SETTINGS_DUN_REQUIRED]) {
this.handleDunConnection(false);
}
} else {
if (aEnable) {
this._usbTetheringAction = TETHERING_STATE_ACTIVE;
} else {
this._usbTetheringAction = TETHERING_STATE_IDLE;
if (this.tetheringSettings[SETTINGS_DUN_REQUIRED]) {
this.handleDunConnection(false);
}
}
this.handleLastUsbTetheringRequest();
}
},
onConnectionChangedReport: function(aSuccess, aExternalIfname) {
debug("onConnectionChangedReport result: success " + aSuccess);
if (aSuccess) {
// Update the external interface.
this._tetheringInterface[TETHERING_TYPE_USB].externalInterface =
aExternalIfname;
debug("Change the interface name to " + aExternalIfname);
}
},
onConnectionChanged: function(aNetwork) {
if (aNetwork.state != Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED) {
debug("We are only interested in CONNECTED event");
return;
}
if (this.tetheringSettings[SETTINGS_DUN_REQUIRED] &&
aNetwork.type === Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN) {
this.dunConnectTimer.cancel();
debug("DUN data call connected, process callbacks.");
while (this._pendingTetheringRequests.length > 0) {
let callback = this._pendingTetheringRequests.shift();
if (typeof callback === 'function') {
callback(aNetwork);
}
}
return;
}
if (!this.tetheringSettings[SETTINGS_USB_ENABLED]) {
debug("Usb tethering settings is not enabled");
return;
}
if (this.tetheringSettings[SETTINGS_DUN_REQUIRED] &&
aNetwork.type === Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN &&
this._tetheringInterface[TETHERING_TYPE_USB].externalInterface ===
aNetwork.name) {
debug("Dun required and dun interface is the same");
return;
}
if (this._tetheringInterface[TETHERING_TYPE_USB].externalInterface ===
gNetworkManager.active.name) {
debug("The active interface is the same");
return;
}
let previous = {
internalIfname: this._tetheringInterface[TETHERING_TYPE_USB].internalInterface,
externalIfname: this._tetheringInterface[TETHERING_TYPE_USB].externalInterface
};
let current = {
internalIfname: this._tetheringInterface[TETHERING_TYPE_USB].internalInterface,
externalIfname: aNetwork.name
};
let callback = (() => {
// Update external network interface.
debug("Update upstream interface to " + aNetwork.name);
gNetworkService.updateUpStream(previous, current,
this.onConnectionChangedReport.bind(this));
});
if (this._usbTetheringAction === TETHERING_STATE_ONGOING) {
debug("Postpone the event and handle it when state is idle.");
this.wantConnectionEvent = callback;
return;
}
this.wantConnectionEvent = null;
callback.call(this);
},
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([TetheringService]);

View File

@ -0,0 +1,4 @@
# TetheringService.js
component {527a4121-ee5a-4651-be9c-f46f59cf7c01} TetheringService.js
contract @mozilla.org/tethering/service;1 {527a4121-ee5a-4651-be9c-f46f59cf7c01}
category profile-after-change TetheringService @mozilla.org/tethering/service;1

View File

@ -21,6 +21,7 @@ XPIDL_SOURCES += [
'nsINetworkService.idl',
'nsINetworkWorker.idl',
'nsISystemWorkerManager.idl',
'nsITetheringService.idl',
'nsIVolume.idl',
'nsIVolumeMountLock.idl',
'nsIVolumeService.idl',
@ -75,6 +76,8 @@ EXTRA_COMPONENTS += [
'NetworkManager.manifest',
'NetworkService.js',
'NetworkService.manifest',
'TetheringService.js',
'TetheringService.manifest',
]
EXTRA_PP_COMPONENTS += [
'NetworkManager.js',

View File

@ -4,8 +4,6 @@
#include "nsISupports.idl"
interface nsIWifiTetheringCallback;
/**
* Information about networks that is exposed to network manager API consumers.
*/
@ -97,7 +95,7 @@ interface nsINetworkInterface : nsISupports
/**
* Manage network interfaces.
*/
[scriptable, uuid(19822018-2454-11e4-baa7-2b5894f0af6f)]
[scriptable, uuid(b0ab71bf-4b38-4796-8a3c-4141255f4259)]
interface nsINetworkManager : nsISupports
{
/**
@ -180,23 +178,6 @@ interface nsINetworkManager : nsISupports
*/
long overrideActive(in nsINetworkInterface network);
/**
* Enable or disable Wifi Tethering
*
* @param enabled
* Boolean that indicates whether tethering should be enabled (true) or disabled (false).
* @param network
* The Wifi network interface with at least name of network interface.
* @param config
* The Wifi Tethering configuration from settings db.
* @param callback
* Callback function used to report status to WifiManager.
*/
void setWifiTethering(in boolean enabled,
in nsINetworkInterface networkInterface,
in jsval config,
in nsIWifiTetheringCallback callback);
/**
* Add host route to the specified network into routing table.
*

View File

@ -0,0 +1,30 @@
/* 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 "nsISupports.idl"
interface nsINetworkInterface;
interface nsIWifiTetheringCallback;
[scriptable, uuid(80d65940-bd99-458f-8529-e438c7348087)]
interface nsITetheringService : nsISupports
{
/**
* Enable or disable Wifi Tethering
*
* @param enabled
* Boolean that indicates whether tethering should be enabled (true) or
* disabled (false).
* @param networkInterface
* The Wifi network interface with at least name of network interface.
* @param config
* The Wifi Tethering configuration from settings db.
* @param callback
* Callback function used to report status to WifiManager.
*/
void setWifiTethering(in boolean enabled,
in nsINetworkInterface networkInterface,
in jsval config,
in nsIWifiTetheringCallback callback);
};

View File

@ -9,5 +9,6 @@
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
window.addEventListener("DOMWindowCreated", function() { ok(false, "DOMWindowCreated should not have fired"); }, false);
window.addEventListener("DOMDocElementInserted", function() { ok(false, "DOMDocElementInserted should not have fired"); }, false);
<iframe src="data:text/plain,Hi"></iframe>

View File

@ -8,12 +8,46 @@ enum RFState {
"discovery"
};
/**
* Type of the Request used in NfcCommandOptions.
*/
enum NfcRequestType {
"changeRFState",
"readNDEF",
"writeNDEF",
"makeReadOnly",
"format",
"transceive"
};
/**
* Type of the Response used in NfcEventOptions.
*/
enum NfcResponseType {
"changeRFStateRsp",
"readNDEFRsp",
"writeNDEFRsp",
"makeReadOnlyRsp",
"formatRsp",
"transceiveRsp",
};
/**
* Type of the Notification used in NfcEventOptions.
*/
enum NfcNotificationType {
"initialized",
"techDiscovered",
"techLost",
"hciEventTransaction"
};
dictionary NfcCommandOptions
{
DOMString type = "";
required NfcRequestType type;
long sessionId;
DOMString requestId = "";
required DOMString requestId;
RFState rfState;
@ -28,7 +62,8 @@ dictionary NfcCommandOptions
dictionary NfcEventOptions
{
DOMString type = "";
NfcResponseType rspType;
NfcNotificationType ntfType;
long status;
NfcErrorMessage errorMsg;

View File

@ -97,6 +97,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService",
"@mozilla.org/settingsService;1",
"nsISettingsService");
XPCOMUtils.defineLazyServiceGetter(this, "gTetheringService",
"@mozilla.org/tethering/service;1",
"nsITetheringService");
// A note about errors and error handling in this file:
// The libraries that we use in this file are intended for C code. For
// C code, it is natural to return -1 for errors and 0 for success.
@ -1136,8 +1140,8 @@ var WifiManager = (function() {
function doStartWifiTethering() {
cancelWaitForDriverReadyTimer();
WifiNetworkInterface.name = libcutils.property_get("wifi.tethering.interface", manager.ifname);
gNetworkManager.setWifiTethering(enabled, WifiNetworkInterface,
configuration, function(result) {
gTetheringService.setWifiTethering(enabled, WifiNetworkInterface,
configuration, function(result) {
if (result) {
manager.tetheringState = "UNINITIALIZED";
} else {
@ -1164,8 +1168,8 @@ var WifiManager = (function() {
});
} else {
cancelWifiHotspotStatusTimer();
gNetworkManager.setWifiTethering(enabled, WifiNetworkInterface,
configuration, function(result) {
gTetheringService.setWifiTethering(enabled, WifiNetworkInterface,
configuration, function(result) {
// Should we fire a dom event if we fail to set wifi tethering ?
debug("Disable Wifi tethering result: " + (result ? result : "successfully"));
// Unload wifi driver even if we fail to control wifi tethering.

View File

@ -270,10 +270,6 @@ public class AndroidFxAccount {
return accountManager.getUserData(account, ACCOUNT_KEY_IDP_SERVER);
}
public String getAudience() {
return accountManager.getUserData(account, ACCOUNT_KEY_AUDIENCE);
}
public String getTokenServerURI() {
return accountManager.getUserData(account, ACCOUNT_KEY_TOKEN_SERVER);
}
@ -402,7 +398,6 @@ public class AndroidFxAccount {
userdata.putString(ACCOUNT_KEY_ACCOUNT_VERSION, "" + CURRENT_ACCOUNT_VERSION);
userdata.putString(ACCOUNT_KEY_IDP_SERVER, idpServerURI);
userdata.putString(ACCOUNT_KEY_TOKEN_SERVER, tokenServerURI);
userdata.putString(ACCOUNT_KEY_AUDIENCE, FxAccountUtils.getAudienceForURL(tokenServerURI));
userdata.putString(ACCOUNT_KEY_PROFILE, profile);
if (bundle == null) {

View File

@ -456,10 +456,10 @@ public class FxAccountSyncAdapter extends AbstractThreadedSyncAdapter {
// and extend the background delay even further into the future.
schedulePolicy.configureBackoffMillisBeforeSyncing(rateLimitBackoffHandler, backgroundBackoffHandler);
final String audience = fxAccount.getAudience();
final String authServerEndpoint = fxAccount.getAccountServerURI();
final String tokenServerEndpoint = fxAccount.getTokenServerURI();
final URI tokenServerEndpointURI = new URI(tokenServerEndpoint);
final String audience = FxAccountUtils.getAudienceForURL(tokenServerEndpoint);
// TODO: why doesn't the loginPolicy extract the audience from the account?
final FxAccountClient client = new FxAccountClient20(authServerEndpoint, executor);

View File

@ -24,6 +24,8 @@ ANDROID_PACKAGES = [
ANDROID_PLATFORM,
'extra-android-support',
'extra-google-google_play_services',
'extra-google-m2repository',
'extra-android-m2repository',
]
ANDROID_NDK_EXISTS = '''

View File

@ -404,6 +404,7 @@ class MachCommands(MachCommandBase):
@Command('xpcshell-test', category='testing',
description='Run XPCOM Shell tests (API direct unit testing)',
conditions=[lambda *args: True],
parser=_parser)
@CommandArgument('test_paths', default='all', nargs='*', metavar='TEST',
help='Test to run. Can be specified as a single JS file, a directory, '

View File

@ -196,7 +196,12 @@ this.DownloadIntegration = {
return this.shouldKeepBlockedDataInTest;
}
return false;
const FIREFOX_ID = "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}";
let os = Services.appinfo.OS;
return Services.appinfo.ID == FIREFOX_ID &&
(os == "Darwin" ||
os == "Linux" ||
os == "WINNT");
},
/**

View File

@ -19,7 +19,8 @@ loader.lazyRequireGetter(this, "StackFrameCache",
*
* @param String expectedState
* The expected state.
*
* @param String activity
* Additional info about what's going on.
* @param Function method
* The actor method to proceed with when the actor is in the expected
* state.
@ -27,11 +28,12 @@ loader.lazyRequireGetter(this, "StackFrameCache",
* @returns Function
* The decorated method.
*/
function expectState(expectedState, method) {
function expectState(expectedState, method, activity) {
return function(...args) {
if (this.state !== expectedState) {
const msg = "Wrong State: Expected '" + expectedState + "', but current "
+ "state is '" + this.state + "'";
const msg = `Wrong state while ${activity}:` +
`Expected '${expectedState}',` +
`but current state is '${this.state}'.`;
return Promise.reject(new Error(msg));
}
@ -96,7 +98,8 @@ let MemoryActor = protocol.ActorClass({
attach: method(expectState("detached", function() {
this.dbg.addDebuggees();
this.state = "attached";
}), {
},
`attaching to the debugger`), {
request: {},
response: {
type: "attached"
@ -111,13 +114,25 @@ let MemoryActor = protocol.ActorClass({
this.dbg.enabled = false;
this._dbg = null;
this.state = "detached";
}), {
},
`detaching from the debugger`), {
request: {},
response: {
type: "detached"
}
}),
/**
* Gets the current MemoryActor attach/detach state.
*/
getState: method(function() {
return this.state;
}, {
response: {
state: RetVal(0, "string")
}
}),
_clearDebuggees: function() {
if (this._dbg) {
if (this.dbg.memory.trackingAllocationSites) {
@ -153,7 +168,8 @@ let MemoryActor = protocol.ActorClass({
*/
takeCensus: method(expectState("attached", function() {
return this.dbg.memory.takeCensus();
}), {
},
`taking census`), {
request: {},
response: RetVal("json")
}),
@ -175,7 +191,8 @@ let MemoryActor = protocol.ActorClass({
this.dbg.memory.trackingAllocationSites = true;
return Date.now();
}), {
},
`starting recording allocations`), {
request: {
options: Arg(0, "nullable:AllocationsRecordingOptions")
},
@ -193,7 +210,8 @@ let MemoryActor = protocol.ActorClass({
this._clearFrames();
return Date.now();
}), {
},
`stopping recording allocations`), {
request: {},
response: {
// Accept `nullable` in the case of server Gecko <= 37, handled on the front
@ -295,7 +313,8 @@ let MemoryActor = protocol.ActorClass({
}
return this._frameCache.updateFramePacket(packet);
}), {
},
`getting allocations`), {
request: {},
response: RetVal("json")
}),

View File

@ -24,12 +24,14 @@ function run_test() {
];'
const testObject = 'var testObject = {"propA": [{"propB": "B"}]}';
const testHyphenated = 'var testHyphenated = {"prop-A": "res-A"}';
let sandbox = Components.utils.Sandbox("http://example.com");
let dbg = new Debugger;
let dbgObject = dbg.addDebuggee(sandbox);
Components.utils.evalInSandbox(testArray, sandbox);
Components.utils.evalInSandbox(testObject, sandbox);
Components.utils.evalInSandbox(testHyphenated, sandbox);
let results = JSPropertyProvider(dbgObject, null, "testArray[0].");
do_print("Test that suggestions are given for 'foo[n]' where n is an integer.");
@ -55,6 +57,10 @@ function run_test() {
results = JSPropertyProvider(dbgObject, null, "testArray[][1].");
do_check_null(results);
do_print("Test that suggestions are not given if there is an hyphen in the chain.");
results = JSPropertyProvider(dbgObject, null, "testHyphenated['prop-A'].");
do_check_null(results);
}
/**

View File

@ -1070,7 +1070,9 @@ function getMatchedProps_impl(aObj, aMatch, {chainIterator, getProperties})
if (prop.indexOf(aMatch) != 0) {
continue;
}
if (prop.indexOf('-') > -1) {
continue;
}
// If it is an array index, we can't take it.
// This uses a trick: converting a string to a number yields NaN if
// the operation failed, and NaN is not equal to itself.

View File

@ -552,10 +552,9 @@ endif
ifdef MOZ_SIGN_PREPARED_PACKAGE_CMD
ifeq (Darwin, $(OS_ARCH))
MAKE_PACKAGE = cd ./$(PKG_DMG_SOURCE) && $(MOZ_SIGN_PREPARED_PACKAGE_CMD) $(MOZ_MACBUNDLE_NAME) \
&& cd $(PACKAGE_BASE_DIR) \
&& (cd $(STAGEPATH)$(MOZ_PKG_DIR)$(_RESPATH) && $(CREATE_PRECOMPLETE_CMD)) \
&& $(INNER_MAKE_PACKAGE)
MAKE_PACKAGE = (cd $(STAGEPATH)$(MOZ_PKG_DIR)$(_RESPATH) && $(CREATE_PRECOMPLETE_CMD)) \
&& cd ./$(PKG_DMG_SOURCE) && $(MOZ_SIGN_PREPARED_PACKAGE_CMD) $(MOZ_MACBUNDLE_NAME) \
&& cd $(PACKAGE_BASE_DIR) && $(INNER_MAKE_PACKAGE)
else
MAKE_PACKAGE = $(MOZ_SIGN_PREPARED_PACKAGE_CMD) $(MOZ_PKG_DIR) \
&& $(or $(call MAKE_SIGN_EME_VOUCHER,$(STAGEPATH)$(MOZ_PKG_DIR)),true) \