mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 13:55:43 +00:00
Merge m-c to m-i
This commit is contained in:
commit
b1544015f4
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="ccda843399fe0d26fac7747fd787e5fe2e8dfdf7"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="1dd8ad8f96988afebc9691e1b818fa37aa32c790"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
@ -23,7 +23,7 @@
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ec7f77a328cb8bddd1907f90d16865a986bb4fef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="11ad0ea69796915552c9bae148d81fddf9856ddb"/>
|
||||
<!-- Stock Android things -->
|
||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
|
||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
|
||||
|
@ -19,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="ccda843399fe0d26fac7747fd787e5fe2e8dfdf7"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1dd8ad8f96988afebc9691e1b818fa37aa32c790"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="67f2907bc340bad250b4ea6ce2902b52896c9ef0"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ec7f77a328cb8bddd1907f90d16865a986bb4fef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="11ad0ea69796915552c9bae148d81fddf9856ddb"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
|
||||
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
|
||||
|
@ -17,10 +17,10 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="ccda843399fe0d26fac7747fd787e5fe2e8dfdf7"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="1dd8ad8f96988afebc9691e1b818fa37aa32c790"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ec7f77a328cb8bddd1907f90d16865a986bb4fef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="11ad0ea69796915552c9bae148d81fddf9856ddb"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="ccda843399fe0d26fac7747fd787e5fe2e8dfdf7"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="1dd8ad8f96988afebc9691e1b818fa37aa32c790"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
@ -23,7 +23,7 @@
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ec7f77a328cb8bddd1907f90d16865a986bb4fef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="11ad0ea69796915552c9bae148d81fddf9856ddb"/>
|
||||
<!-- 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"/>
|
||||
|
@ -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="ccda843399fe0d26fac7747fd787e5fe2e8dfdf7"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1dd8ad8f96988afebc9691e1b818fa37aa32c790"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="67f2907bc340bad250b4ea6ce2902b52896c9ef0"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ec7f77a328cb8bddd1907f90d16865a986bb4fef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="11ad0ea69796915552c9bae148d81fddf9856ddb"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
|
||||
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="ccda843399fe0d26fac7747fd787e5fe2e8dfdf7"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="1dd8ad8f96988afebc9691e1b818fa37aa32c790"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
@ -23,7 +23,7 @@
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ec7f77a328cb8bddd1907f90d16865a986bb4fef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="11ad0ea69796915552c9bae148d81fddf9856ddb"/>
|
||||
<!-- 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"/>
|
||||
|
@ -17,10 +17,10 @@
|
||||
</project>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="ccda843399fe0d26fac7747fd787e5fe2e8dfdf7"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="1dd8ad8f96988afebc9691e1b818fa37aa32c790"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ec7f77a328cb8bddd1907f90d16865a986bb4fef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="11ad0ea69796915552c9bae148d81fddf9856ddb"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -4,6 +4,6 @@
|
||||
"remote": "",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "1f41a654b3311705e7d71ff9b2137d3340c6c272",
|
||||
"revision": "eba399d3ba9724c77e073adccc0dfe9f8169dceb",
|
||||
"repo_path": "integration/gaia-central"
|
||||
}
|
||||
|
@ -17,11 +17,11 @@
|
||||
<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="ccda843399fe0d26fac7747fd787e5fe2e8dfdf7"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1dd8ad8f96988afebc9691e1b818fa37aa32c790"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ec7f77a328cb8bddd1907f90d16865a986bb4fef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="11ad0ea69796915552c9bae148d81fddf9856ddb"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
|
||||
<project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ccda843399fe0d26fac7747fd787e5fe2e8dfdf7"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1dd8ad8f96988afebc9691e1b818fa37aa32c790"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -17,10 +17,10 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="ccda843399fe0d26fac7747fd787e5fe2e8dfdf7"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="1dd8ad8f96988afebc9691e1b818fa37aa32c790"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ec7f77a328cb8bddd1907f90d16865a986bb4fef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="11ad0ea69796915552c9bae148d81fddf9856ddb"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -17,12 +17,12 @@
|
||||
<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="ccda843399fe0d26fac7747fd787e5fe2e8dfdf7"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1dd8ad8f96988afebc9691e1b818fa37aa32c790"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ec7f77a328cb8bddd1907f90d16865a986bb4fef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="11ad0ea69796915552c9bae148d81fddf9856ddb"/>
|
||||
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0"?>
|
||||
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1415397193000">
|
||||
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1416004676000">
|
||||
<emItems>
|
||||
<emItem blockID="i58" id="webmaster@buzzzzvideos.info">
|
||||
<versionRange minVersion="0" maxVersion="*">
|
||||
@ -533,6 +533,12 @@
|
||||
</versionRange>
|
||||
<prefs>
|
||||
</prefs>
|
||||
</emItem>
|
||||
<emItem blockID="i784" id="{41e5ef7a-171d-4ab5-8351-951c65a29908}">
|
||||
<versionRange minVersion="0" maxVersion="*" severity="3">
|
||||
</versionRange>
|
||||
<prefs>
|
||||
</prefs>
|
||||
</emItem>
|
||||
<emItem blockID="i374" id="update@firefox.com">
|
||||
<versionRange minVersion="0" maxVersion="*" severity="3">
|
||||
@ -886,6 +892,12 @@
|
||||
</versionRange>
|
||||
<prefs>
|
||||
</prefs>
|
||||
</emItem>
|
||||
<emItem blockID="i782" id="safebrowse@safebrowse.co">
|
||||
<versionRange minVersion="0" maxVersion="*" severity="3">
|
||||
</versionRange>
|
||||
<prefs>
|
||||
</prefs>
|
||||
</emItem>
|
||||
<emItem blockID="i654" id="{7b1bf0b6-a1b9-42b0-b75d-252036438bdc}">
|
||||
<versionRange minVersion="27.8" maxVersion="27.9" severity="3">
|
||||
@ -1542,6 +1554,12 @@
|
||||
</versionRange>
|
||||
<prefs>
|
||||
</prefs>
|
||||
</emItem>
|
||||
<emItem blockID="i780" id="{b6ef1336-69bb-45b6-8cba-e578fc0e4433}">
|
||||
<versionRange minVersion="0" maxVersion="*" severity="3">
|
||||
</versionRange>
|
||||
<prefs>
|
||||
</prefs>
|
||||
</emItem>
|
||||
<emItem blockID="i96" id="youtubeee@youtuber3.com">
|
||||
<versionRange minVersion="0" maxVersion="*">
|
||||
|
@ -399,8 +399,6 @@ const CustomizableWidgets = [
|
||||
}
|
||||
}, {
|
||||
id: "social-share-button",
|
||||
tooltiptext: "social-share-button.label",
|
||||
label: "social-share-button.tooltiptext",
|
||||
// custom build our button so we can attach to the share command
|
||||
type: "custom",
|
||||
onBuild: function(aDocument) {
|
||||
|
@ -183,7 +183,17 @@ let TimelineController = {
|
||||
* updating the UI as needed.
|
||||
*/
|
||||
_stopRecordingAndDiscardData: function*() {
|
||||
// Clear the markers before calling async method _stopRecording to properly
|
||||
// reset the selection if markers were already received. Bug 1092452.
|
||||
this._markers.length = 0;
|
||||
this._memory.length = 0;
|
||||
|
||||
yield this._stopRecording();
|
||||
|
||||
// Clear the markers after _stopRecording has finished. It's possible that
|
||||
// server sent new markers before it received the request to stop sending
|
||||
// them and client received them while we were waiting for _stopRecording
|
||||
// to finish. Bug 1067287.
|
||||
this._markers.length = 0;
|
||||
this._memory.length = 0;
|
||||
},
|
||||
|
@ -914,6 +914,9 @@ bin/libfreebl_32int64_3.so
|
||||
@BINPATH@/components/DataStoreImpl.js
|
||||
@BINPATH@/components/dom_datastore.xpt
|
||||
|
||||
; Shutdown Terminator
|
||||
@BINPATH@/components/nsTerminatorTelemetry.js
|
||||
@BINPATH@/components/terminator.manifest
|
||||
|
||||
#ifdef MOZ_ASAN
|
||||
#ifdef CLANG_CXX
|
||||
|
@ -1303,15 +1303,15 @@ this.UITour = {
|
||||
|
||||
addNavBarWidget: function (aTarget, aMessageManager, aCallbackID) {
|
||||
if (aTarget.node) {
|
||||
log.error("UITour: can't add a widget already present: " + data.target);
|
||||
log.error("addNavBarWidget: can't add a widget already present:", aTarget);
|
||||
return;
|
||||
}
|
||||
if (!aTarget.allowAdd) {
|
||||
log.error("UITour: not allowed to add this widget: " + data.target);
|
||||
log.error("addNavBarWidget: not allowed to add this widget:", aTarget);
|
||||
return;
|
||||
}
|
||||
if (!aTarget.widgetName) {
|
||||
log.error("UITour: can't add a widget without a widgetName property: " + data.target);
|
||||
log.error("addNavBarWidget: can't add a widget without a widgetName property:", aTarget);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,8 @@ leak:libfontconfig.so
|
||||
leak:GI___strdup
|
||||
# The symbol is really __GI___strdup, but if you have the leading _, it doesn't suppress it.
|
||||
|
||||
# Bug 1078015 - If the process terminates during a PR_Sleep, LSAN detects a leak
|
||||
leak:PR_Sleep
|
||||
|
||||
###
|
||||
### Bug 979928 - WebRTC leaks. m2, m3.
|
||||
@ -92,6 +94,7 @@ leak:processInternalEntity
|
||||
###
|
||||
|
||||
leak:libcairo.so
|
||||
leak:libdl.so
|
||||
leak:libdricore.so
|
||||
leak:libGL.so
|
||||
leak:libglib-2.0.so
|
||||
|
@ -84,7 +84,7 @@ CameraControlImpl::OnHardwareStateChange(CameraControlListener::HardwareState aN
|
||||
}
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
const char* state[] = { "open", "closed", "failed" };
|
||||
const char* state[] = { "closed", "open", "failed" };
|
||||
MOZ_ASSERT(aNewState >= 0);
|
||||
if (static_cast<unsigned int>(aNewState) < sizeof(state) / sizeof(state[0])) {
|
||||
DOM_CAMERA_LOGI("New hardware state is '%s'\n", state[aNewState]);
|
||||
|
@ -313,22 +313,114 @@ nsGonkCameraControl::SetConfigurationImpl(const Configuration& aConfig)
|
||||
return StartPreviewImpl();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGonkCameraControl::MaybeAdjustVideoSize()
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mCameraThread);
|
||||
MOZ_ASSERT(mSeparateVideoAndPreviewSizesSupported);
|
||||
|
||||
const Size& preview = mCurrentConfiguration.mPreviewSize;
|
||||
|
||||
// Some camera drivers will ignore our preview size if it's larger
|
||||
// than the currently set video recording size, so in picture mode, we
|
||||
// give preview size priority, and bump up the video size just in case.
|
||||
// This is done on a best-effort basis.
|
||||
|
||||
if (preview.width <= mLastRecorderSize.width &&
|
||||
preview.height <= mLastRecorderSize.height) {
|
||||
DOM_CAMERA_LOGI("Video size %ux%u is suitable for preview size %ux%u\n",
|
||||
mLastRecorderSize.width, mLastRecorderSize.height,
|
||||
preview.width, preview.height);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsTArray<Size> sizes;
|
||||
nsresult rv = Get(CAMERA_PARAM_SUPPORTED_VIDEOSIZES, sizes);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
const uint32_t previewArea = preview.width * preview.height;
|
||||
uint32_t bestDelta = UINT32_MAX;
|
||||
bool foundBest = false;
|
||||
SizeIndex best;
|
||||
|
||||
for (SizeIndex i = 0; i < sizes.Length(); ++i) {
|
||||
const Size& s = sizes[i];
|
||||
if (s.width < preview.width || s.height < preview.height) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const uint32_t area = s.width * s.height;
|
||||
const uint32_t delta = area - previewArea;
|
||||
if (delta < bestDelta) {
|
||||
bestDelta = delta;
|
||||
best = i;
|
||||
foundBest = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundBest) {
|
||||
// If no candidate was found, the driver will be fine with a video size
|
||||
// smaller than the chosen preview size.
|
||||
DOM_CAMERA_LOGI("No video size candidate for preview size %ux%u (0x%x)\n",
|
||||
preview.width, preview.height, rv);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
DOM_CAMERA_LOGI("Adjusting video size upwards to %ux%u\n",
|
||||
sizes[best].width, sizes[best].height);
|
||||
rv = Set(CAMERA_PARAM_VIDEOSIZE, sizes[best]);
|
||||
if (NS_FAILED(rv)) {
|
||||
DOM_CAMERA_LOGW("Failed to adjust video size for preview size %ux%u (0x%x)\n",
|
||||
preview.width, preview.height, rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
mLastRecorderSize = preview;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGonkCameraControl::SetPictureConfiguration(const Configuration& aConfig)
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d\n", __func__, __LINE__);
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mCameraThread);
|
||||
|
||||
nsresult rv = SetPreviewSize(aConfig.mPreviewSize);
|
||||
nsTArray<Size> sizes;
|
||||
nsresult rv = Get(CAMERA_PARAM_SUPPORTED_PREVIEWSIZES, sizes);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
Size preview;
|
||||
rv = GetSupportedSize(aConfig.mPreviewSize, sizes, preview);
|
||||
if (NS_FAILED(rv)) {
|
||||
DOM_CAMERA_LOGE(
|
||||
"Failed to find a supported preview size, requested size %ux%u (0x%x)",
|
||||
aConfig.mPreviewSize.width, aConfig.mPreviewSize.height, rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = Set(CAMERA_PARAM_PREVIEWSIZE, preview);
|
||||
if (NS_FAILED(rv)) {
|
||||
DOM_CAMERA_LOGE("Failed to set supported preview size %ux%u (0x%x)",
|
||||
preview.width, preview.height, rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
mCurrentConfiguration.mPreviewSize = preview;
|
||||
|
||||
if (mSeparateVideoAndPreviewSizesSupported) {
|
||||
MaybeAdjustVideoSize();
|
||||
}
|
||||
|
||||
mParams.Get(CAMERA_PARAM_PREVIEWFRAMERATE, mPreviewFps);
|
||||
|
||||
DOM_CAMERA_LOGI("picture mode preview: wanted %ux%u, got %ux%u (%u fps)\n",
|
||||
aConfig.mPreviewSize.width, aConfig.mPreviewSize.height,
|
||||
mCurrentConfiguration.mPreviewSize.width, mCurrentConfiguration.mPreviewSize.height,
|
||||
mPreviewFps);
|
||||
aConfig.mPreviewSize.width, aConfig.mPreviewSize.height,
|
||||
preview.width, preview.height,
|
||||
mPreviewFps);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -695,11 +787,10 @@ nsGonkCameraControl::SetThumbnailSizeImpl(const Size& aSize)
|
||||
int area = supportedSizes[i].width * supportedSizes[i].height;
|
||||
int delta = abs(area - targetArea);
|
||||
|
||||
if (area != 0
|
||||
&& delta < smallestDelta
|
||||
&& supportedSizes[i].width * mLastPictureSize.height /
|
||||
supportedSizes[i].height == mLastPictureSize.width
|
||||
) {
|
||||
if (area != 0 &&
|
||||
delta < smallestDelta &&
|
||||
supportedSizes[i].width * mLastPictureSize.height ==
|
||||
mLastPictureSize.width * supportedSizes[i].height) {
|
||||
smallestDelta = delta;
|
||||
smallestDeltaIndex = i;
|
||||
}
|
||||
@ -1249,71 +1340,9 @@ nsGonkCameraControl::OnTakePictureError()
|
||||
NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGonkCameraControl::SetPreviewSize(const Size& aSize)
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mCameraThread);
|
||||
|
||||
nsTArray<Size> previewSizes;
|
||||
nsresult rv = Get(CAMERA_PARAM_SUPPORTED_PREVIEWSIZES, previewSizes);
|
||||
if (NS_FAILED(rv)) {
|
||||
DOM_CAMERA_LOGE("Camera failed to return any preview sizes (0x%x)\n", rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
Size best;
|
||||
rv = GetSupportedSize(aSize, previewSizes, best);
|
||||
if (NS_FAILED(rv)) {
|
||||
DOM_CAMERA_LOGE("Failed to find a supported preview size, requested size %dx%d",
|
||||
aSize.width, aSize.height);
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (mSeparateVideoAndPreviewSizesSupported) {
|
||||
// Some camera drivers will ignore our preview size if it's larger
|
||||
// than the currently set video recording size, so we need to set
|
||||
// the video size here as well, just in case.
|
||||
if (best.width > mLastRecorderSize.width || best.height > mLastRecorderSize.height) {
|
||||
SetVideoSize(best);
|
||||
}
|
||||
} else {
|
||||
mLastRecorderSize = best;
|
||||
}
|
||||
mCurrentConfiguration.mPreviewSize = best;
|
||||
return Set(CAMERA_PARAM_PREVIEWSIZE, best);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGonkCameraControl::SetVideoSize(const Size& aSize)
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mCameraThread);
|
||||
|
||||
if (!mSeparateVideoAndPreviewSizesSupported) {
|
||||
DOM_CAMERA_LOGE("Camera does not support setting separate video size\n");
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsTArray<Size> videoSizes;
|
||||
nsresult rv = Get(CAMERA_PARAM_SUPPORTED_VIDEOSIZES, videoSizes);
|
||||
if (NS_FAILED(rv)) {
|
||||
DOM_CAMERA_LOGE("Camera failed to return any video sizes (0x%x)\n", rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
Size best;
|
||||
rv = GetSupportedSize(aSize, videoSizes, best);
|
||||
if (NS_FAILED(rv)) {
|
||||
DOM_CAMERA_LOGE("Failed to find a supported video size, requested size %dx%d",
|
||||
aSize.width, aSize.height);
|
||||
return rv;
|
||||
}
|
||||
mLastRecorderSize = best;
|
||||
return Set(CAMERA_PARAM_VIDEOSIZE, best);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGonkCameraControl::GetSupportedSize(const Size& aSize,
|
||||
const nsTArray<Size>& supportedSizes,
|
||||
const nsTArray<Size>& aSupportedSizes,
|
||||
Size& best)
|
||||
{
|
||||
nsresult rv = NS_ERROR_INVALID_ARG;
|
||||
@ -1323,24 +1352,25 @@ nsGonkCameraControl::GetSupportedSize(const Size& aSize,
|
||||
|
||||
if (!aSize.width && !aSize.height) {
|
||||
// no size specified, take the first supported size
|
||||
best = supportedSizes[0];
|
||||
best = aSupportedSizes[0];
|
||||
return NS_OK;
|
||||
} else if (aSize.width && aSize.height) {
|
||||
// both height and width specified, find the supported size closest to
|
||||
// the requested size, looking for an exact match first
|
||||
for (nsTArray<Size>::index_type i = 0; i < supportedSizes.Length(); i++) {
|
||||
Size size = supportedSizes[i];
|
||||
for (SizeIndex i = 0; i < aSupportedSizes.Length(); ++i) {
|
||||
Size size = aSupportedSizes[i];
|
||||
if (size.width == aSize.width && size.height == aSize.height) {
|
||||
best = size;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// no exact matches--look for a match closest in area
|
||||
uint32_t targetArea = aSize.width * aSize.height;
|
||||
for (nsTArray<Size>::index_type i = 0; i < supportedSizes.Length(); i++) {
|
||||
Size size = supportedSizes[i];
|
||||
uint32_t delta = abs((long int)(size.width * size.height - targetArea));
|
||||
// no exact match on dimensions--look for a match closest in area
|
||||
const uint32_t targetArea = aSize.width * aSize.height;
|
||||
for (SizeIndex i = 0; i < aSupportedSizes.Length(); i++) {
|
||||
Size size = aSupportedSizes[i];
|
||||
uint32_t delta =
|
||||
abs(static_cast<long int>(size.width * size.height - targetArea));
|
||||
if (delta < minSizeDelta) {
|
||||
minSizeDelta = delta;
|
||||
best = size;
|
||||
@ -1349,9 +1379,9 @@ nsGonkCameraControl::GetSupportedSize(const Size& aSize,
|
||||
}
|
||||
} else if (!aSize.width) {
|
||||
// width not specified, find closest height match
|
||||
for (nsTArray<Size>::index_type i = 0; i < supportedSizes.Length(); i++) {
|
||||
Size size = supportedSizes[i];
|
||||
delta = abs((long int)(size.height - aSize.height));
|
||||
for (SizeIndex i = 0; i < aSupportedSizes.Length(); i++) {
|
||||
Size size = aSupportedSizes[i];
|
||||
delta = abs(static_cast<long int>(size.height - aSize.height));
|
||||
if (delta < minSizeDelta) {
|
||||
minSizeDelta = delta;
|
||||
best = size;
|
||||
@ -1360,9 +1390,9 @@ nsGonkCameraControl::GetSupportedSize(const Size& aSize,
|
||||
}
|
||||
} else if (!aSize.height) {
|
||||
// height not specified, find closest width match
|
||||
for (nsTArray<Size>::index_type i = 0; i < supportedSizes.Length(); i++) {
|
||||
Size size = supportedSizes[i];
|
||||
delta = abs((long int)(size.width - aSize.width));
|
||||
for (SizeIndex i = 0; i < aSupportedSizes.Length(); i++) {
|
||||
Size size = aSupportedSizes[i];
|
||||
delta = abs(static_cast<long int>(size.width - aSize.width));
|
||||
if (delta < minSizeDelta) {
|
||||
minSizeDelta = delta;
|
||||
best = size;
|
||||
@ -1370,9 +1400,147 @@ nsGonkCameraControl::GetSupportedSize(const Size& aSize,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGonkCameraControl::SetVideoAndPreviewSize(const Size& aPreviewSize, const Size& aVideoSize)
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mCameraThread);
|
||||
MOZ_ASSERT(mSeparateVideoAndPreviewSizesSupported);
|
||||
|
||||
DOM_CAMERA_LOGI("Setting video size to %ux%u, preview size to %ux%u\n",
|
||||
aVideoSize.width, aVideoSize.height,
|
||||
aPreviewSize.width, aPreviewSize.height);
|
||||
|
||||
Size oldSize;
|
||||
nsresult rv = Get(CAMERA_PARAM_PREVIEWSIZE, oldSize);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = Set(CAMERA_PARAM_PREVIEWSIZE, aPreviewSize);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
rv = Set(CAMERA_PARAM_VIDEOSIZE, aVideoSize);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
Set(CAMERA_PARAM_VIDEOSIZE, oldSize); // error, try to restore the original preview size
|
||||
return rv;
|
||||
}
|
||||
|
||||
mCurrentConfiguration.mPreviewSize = aPreviewSize;
|
||||
mLastRecorderSize = aVideoSize;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGonkCameraControl::SelectVideoAndPreviewSize(const Configuration& aConfig, const Size& aVideoSize)
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mCameraThread);
|
||||
MOZ_ASSERT(mSeparateVideoAndPreviewSizesSupported);
|
||||
|
||||
nsTArray<Size> sizes;
|
||||
|
||||
nsresult rv = Get(CAMERA_PARAM_SUPPORTED_VIDEOSIZES, sizes);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
Size video;
|
||||
rv = GetSupportedSize(aVideoSize, sizes, video);
|
||||
if (NS_FAILED(rv)) {
|
||||
DOM_CAMERA_LOGE("Failed to find a supported video size, requested size %ux%u",
|
||||
aVideoSize.width, aVideoSize.height);
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = Get(CAMERA_PARAM_SUPPORTED_PREVIEWSIZES, sizes);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
Size preview;
|
||||
rv = GetSupportedSize(aConfig.mPreviewSize, sizes, preview);
|
||||
if (NS_FAILED(rv)) {
|
||||
DOM_CAMERA_LOGE("Failed to find a supported preview size, requested size %ux%u",
|
||||
aConfig.mPreviewSize.width, aConfig.mPreviewSize.height);
|
||||
return rv;
|
||||
}
|
||||
|
||||
Size preferred;
|
||||
rv = Get(CAMERA_PARAM_PREFERRED_PREVIEWSIZE_FOR_VIDEO, preferred);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// If the requested preview size has the same aspect ratio as the
|
||||
// requested video size, *and* is the same size or smaller than
|
||||
// the preferred video size, then we're done.
|
||||
const uint32_t preferredArea = preferred.width * preferred.height;
|
||||
if (video.width * aConfig.mPreviewSize.height == aConfig.mPreviewSize.width * video.height &&
|
||||
preview.width * preview.height <= preferredArea) {
|
||||
// We're done: set the video and preview sizes and return...
|
||||
return SetVideoAndPreviewSize(preview, video);
|
||||
}
|
||||
|
||||
// Otherwise, if the requested preview size is larger than the preferred
|
||||
// size, or there is an aspect ratio mismatch, then we need to set the
|
||||
// preview size to the closest size smaller than the preferred size,
|
||||
// preferably with the same aspect ratio as the requested video size.
|
||||
|
||||
SizeIndex bestSizeMatch;
|
||||
SizeIndex bestSizeMatchWithAspectRatio;
|
||||
bool foundSizeMatch = false;
|
||||
bool foundSizeMatchWithAspectRatio = false;
|
||||
|
||||
uint32_t bestAreaDelta = UINT32_MAX;
|
||||
uint32_t bestAreaDeltaWithAspect = UINT32_MAX;
|
||||
|
||||
for (SizeIndex i = 0; i < sizes.Length(); ++i) {
|
||||
const Size& s = sizes[i];
|
||||
const uint32_t area = s.width * s.height;
|
||||
if (area > preferredArea) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const uint32_t delta = preferredArea - area;
|
||||
if (s.width * video.height == video.width * s.height) {
|
||||
if (delta == 0) {
|
||||
// exact match, including aspect ratio--we can stop now
|
||||
bestSizeMatchWithAspectRatio = i;
|
||||
foundSizeMatchWithAspectRatio = true;
|
||||
break;
|
||||
} else if (delta < bestAreaDeltaWithAspect) {
|
||||
// aspect ratio match
|
||||
bestAreaDeltaWithAspect = delta;
|
||||
bestSizeMatchWithAspectRatio = i;
|
||||
foundSizeMatchWithAspectRatio = true;
|
||||
}
|
||||
} else if (delta < bestAreaDelta) {
|
||||
bestAreaDelta = delta;
|
||||
bestSizeMatch = i;
|
||||
foundSizeMatch = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundSizeMatchWithAspectRatio) {
|
||||
preview = sizes[bestSizeMatchWithAspectRatio];
|
||||
} else if (foundSizeMatch) {
|
||||
DOM_CAMERA_LOGW("Unable to match a preview size with aspect ratio of video size %ux%u\n",
|
||||
video.width, video.height);
|
||||
preview = sizes[bestSizeMatch];
|
||||
} else {
|
||||
DOM_CAMERA_LOGE("Unable to find a preview size for video size %ux%u\n",
|
||||
video.width, video.height);
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return SetVideoAndPreviewSize(preview, video);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGonkCameraControl::SetVideoConfiguration(const Configuration& aConfig)
|
||||
{
|
||||
@ -1392,12 +1560,11 @@ nsGonkCameraControl::SetVideoConfiguration(const Configuration& aConfig)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
mCurrentConfiguration.mRecorderProfile = aConfig.mRecorderProfile;
|
||||
const RecorderProfile::Video& video(profile->GetVideo());
|
||||
const Size& size = video.GetSize();
|
||||
int fps = video.GetFramesPerSecond();
|
||||
if (fps <= 0 || size.width <= 0 || size.height <= 0) {
|
||||
DOM_CAMERA_LOGE("Can't configure video with fps=%d, width=%d, height=%d\n",
|
||||
const uint32_t fps = video.GetFramesPerSecond();
|
||||
if (fps == 0 || fps > INT_MAX || size.width == 0 || size.height == 0) {
|
||||
DOM_CAMERA_LOGE("Can't configure video with fps=%u, width=%u, height=%u\n",
|
||||
fps, size.width, size.height);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@ -1410,32 +1577,26 @@ nsGonkCameraControl::SetVideoConfiguration(const Configuration& aConfig)
|
||||
|
||||
if (mSeparateVideoAndPreviewSizesSupported) {
|
||||
// The camera supports two video streams: a low(er) resolution preview
|
||||
// stream and and a potentially high(er) resolution stream for encoding.
|
||||
rv = SetVideoSize(size);
|
||||
// stream and and a potentially high(er) resolution stream for encoding.
|
||||
rv = SelectVideoAndPreviewSize(aConfig, size);
|
||||
if (NS_FAILED(rv)) {
|
||||
DOM_CAMERA_LOGE("Failed to set video mode video size (0x%x)\n", rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// The video size must be set first, before the preview size, because
|
||||
// some platforms have a dependency between the two.
|
||||
rv = SetPreviewSize(aConfig.mPreviewSize);
|
||||
if (NS_FAILED(rv)) {
|
||||
DOM_CAMERA_LOGE("Failed to set video mode preview size (0x%x)\n", rv);
|
||||
DOM_CAMERA_LOGE("Failed to set video and preview sizes (0x%x)\n", rv);
|
||||
return rv;
|
||||
}
|
||||
} else {
|
||||
// The camera only supports a single video stream: in this case, we set
|
||||
// the preview size to be the desired video recording size, and ignore
|
||||
// the specified preview size.
|
||||
rv = SetPreviewSize(size);
|
||||
rv = Set(CAMERA_PARAM_PREVIEWSIZE, size);
|
||||
if (NS_FAILED(rv)) {
|
||||
DOM_CAMERA_LOGE("Failed to set video mode preview size (0x%x)\n", rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
mCurrentConfiguration.mPreviewSize = size;
|
||||
}
|
||||
|
||||
rv = Set(CAMERA_PARAM_PREVIEWFRAMERATE, fps);
|
||||
rv = Set(CAMERA_PARAM_PREVIEWFRAMERATE, static_cast<int>(fps));
|
||||
if (NS_FAILED(rv)) {
|
||||
DOM_CAMERA_LOGE("Failed to set video mode frame rate (0x%x)\n", rv);
|
||||
return rv;
|
||||
|
@ -98,6 +98,8 @@ protected:
|
||||
using CameraControlImpl::OnConfigurationChange;
|
||||
using CameraControlImpl::OnUserError;
|
||||
|
||||
typedef nsTArray<Size>::index_type SizeIndex;
|
||||
|
||||
virtual void BeginBatchParameterSet() MOZ_OVERRIDE;
|
||||
virtual void EndBatchParameterSet() MOZ_OVERRIDE;
|
||||
|
||||
@ -130,8 +132,9 @@ protected:
|
||||
nsresult SetupRecording(int aFd, int aRotation, uint64_t aMaxFileSizeBytes,
|
||||
uint64_t aMaxVideoLengthMs);
|
||||
nsresult SetupRecordingFlash(bool aAutoEnableLowLightTorch);
|
||||
nsresult SetPreviewSize(const Size& aSize);
|
||||
nsresult SetVideoSize(const Size& aSize);
|
||||
nsresult SelectVideoAndPreviewSize(const Configuration& aConfig, const Size& aVideoSize);
|
||||
nsresult SetVideoAndPreviewSize(const Size& aPreviewSize, const Size& aVideoSize);
|
||||
nsresult MaybeAdjustVideoSize();
|
||||
nsresult PausePreview();
|
||||
nsresult GetSupportedSize(const Size& aSize, const nsTArray<Size>& supportedSizes, Size& best);
|
||||
|
||||
|
@ -117,6 +117,8 @@ GonkCameraParameters::Parameters::GetTextKey(uint32_t aKey)
|
||||
return KEY_RECORDING_HINT;
|
||||
case CAMERA_PARAM_PICTURE_QUALITY:
|
||||
return KEY_JPEG_QUALITY;
|
||||
case CAMERA_PARAM_PREFERRED_PREVIEWSIZE_FOR_VIDEO:
|
||||
return KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO;
|
||||
|
||||
case CAMERA_PARAM_SUPPORTED_PREVIEWSIZES:
|
||||
return KEY_SUPPORTED_PREVIEW_SIZES;
|
||||
|
@ -54,6 +54,7 @@ enum {
|
||||
CAMERA_PARAM_LUMINANCE,
|
||||
CAMERA_PARAM_SCENEMODE_HDR_RETURNNORMALPICTURE,
|
||||
CAMERA_PARAM_RECORDINGHINT,
|
||||
CAMERA_PARAM_PREFERRED_PREVIEWSIZE_FOR_VIDEO,
|
||||
|
||||
// supported features
|
||||
CAMERA_PARAM_SUPPORTED_PREVIEWSIZES,
|
||||
|
@ -1469,25 +1469,6 @@ CanvasRenderingContext2D::ClearTarget()
|
||||
state->colorStyles[Style::FILL] = NS_RGB(0,0,0);
|
||||
state->colorStyles[Style::STROKE] = NS_RGB(0,0,0);
|
||||
state->shadowColor = NS_RGBA(0,0,0,0);
|
||||
|
||||
// For vertical writing-mode, unless text-orientation is sideways,
|
||||
// we'll modify the initial value of textBaseline to 'middle'.
|
||||
nsRefPtr<nsStyleContext> canvasStyle;
|
||||
if (mCanvasElement && mCanvasElement->IsInDoc()) {
|
||||
nsCOMPtr<nsIPresShell> presShell = GetPresShell();
|
||||
if (presShell) {
|
||||
canvasStyle =
|
||||
nsComputedDOMStyle::GetStyleContextForElement(mCanvasElement,
|
||||
nullptr,
|
||||
presShell);
|
||||
if (canvasStyle) {
|
||||
WritingMode wm(canvasStyle);
|
||||
if (wm.IsVertical() && !wm.IsSideways()) {
|
||||
state->textBaseline = TextBaseline::MIDDLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -3284,7 +3265,6 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess
|
||||
gfxPoint point = mPt;
|
||||
bool rtl = mTextRun->IsRightToLeft();
|
||||
bool verticalRun = mTextRun->IsVertical();
|
||||
bool centerBaseline = mTextRun->UseCenterBaseline();
|
||||
|
||||
gfxFloat& inlineCoord = verticalRun ? point.y : point.x;
|
||||
inlineCoord += xOffset;
|
||||
@ -3353,27 +3333,20 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess
|
||||
if (runs[c].mOrientation ==
|
||||
gfxTextRunFactory::TEXT_ORIENT_VERTICAL_SIDEWAYS_RIGHT) {
|
||||
sidewaysRestore.Init(mCtx->mTarget);
|
||||
// TODO: The baseline adjustment here is kinda ad-hoc; eventually
|
||||
// perhaps we should check for horizontal and vertical baseline data
|
||||
// in the font, and adjust accordingly.
|
||||
// (The same will be true for HTML text layout.)
|
||||
const gfxFont::Metrics& metrics = mTextRun->GetFontGroup()->
|
||||
GetFirstValidFont()->GetMetrics(gfxFont::eHorizontal);
|
||||
|
||||
gfx::Matrix mat = mCtx->mTarget->GetTransform().Copy().
|
||||
mCtx->mTarget->SetTransform(mCtx->mTarget->GetTransform().Copy().
|
||||
PreTranslate(baselineOrigin). // translate origin for rotation
|
||||
PreRotate(gfx::Float(M_PI / 2.0)). // turn 90deg clockwise
|
||||
PreTranslate(-baselineOrigin); // undo the translation
|
||||
|
||||
if (centerBaseline) {
|
||||
// TODO: The baseline adjustment here is kinda ad hoc; eventually
|
||||
// perhaps we should check for horizontal and vertical baseline data
|
||||
// in the font, and adjust accordingly.
|
||||
// (The same will be true for HTML text layout.)
|
||||
float offset = (metrics.emAscent - metrics.emDescent) / 2;
|
||||
mat = mat.PreTranslate(Point(0, offset));
|
||||
// offset the (alphabetic) baseline of the
|
||||
PreTranslate(-baselineOrigin). // undo the translation
|
||||
PreTranslate(Point(0, (metrics.emAscent - metrics.emDescent) / 2)));
|
||||
// and offset the (alphabetic) baseline of the
|
||||
// horizontally-shaped text from the (centered)
|
||||
// default baseline used for vertical
|
||||
}
|
||||
|
||||
mCtx->mTarget->SetTransform(mat);
|
||||
}
|
||||
|
||||
RefPtr<GlyphRenderingOptions> renderingOptions = font->GetGlyphRenderingOptions();
|
||||
@ -3665,45 +3638,39 @@ CanvasRenderingContext2D::DrawOrMeasureText(const nsAString& aRawText,
|
||||
|
||||
processor.mPt.x -= anchorX * totalWidth;
|
||||
|
||||
// offset pt.y (or pt.x, for vertical text) based on text baseline
|
||||
// offset pt.y based on text baseline
|
||||
processor.mFontgrp->UpdateUserFonts(); // ensure user font generation is current
|
||||
const gfxFont::Metrics& fontMetrics =
|
||||
processor.mFontgrp->GetFirstValidFont()->GetMetrics(gfxFont::eHorizontal);
|
||||
processor.mFontgrp->GetFirstValidFont()->GetMetrics(
|
||||
((processor.mTextRunFlags & gfxTextRunFactory::TEXT_ORIENT_MASK) ==
|
||||
gfxTextRunFactory::TEXT_ORIENT_HORIZONTAL)
|
||||
? gfxFont::eHorizontal : gfxFont::eVertical);
|
||||
|
||||
gfxFloat baselineAnchor;
|
||||
gfxFloat anchorY;
|
||||
|
||||
switch (state.textBaseline)
|
||||
{
|
||||
case TextBaseline::HANGING:
|
||||
// fall through; best we can do with the information available
|
||||
case TextBaseline::TOP:
|
||||
baselineAnchor = fontMetrics.emAscent;
|
||||
anchorY = fontMetrics.emAscent;
|
||||
break;
|
||||
case TextBaseline::MIDDLE:
|
||||
baselineAnchor = (fontMetrics.emAscent - fontMetrics.emDescent) * .5f;
|
||||
anchorY = (fontMetrics.emAscent - fontMetrics.emDescent) * .5f;
|
||||
break;
|
||||
case TextBaseline::IDEOGRAPHIC:
|
||||
// fall through; best we can do with the information available
|
||||
case TextBaseline::ALPHABETIC:
|
||||
baselineAnchor = 0;
|
||||
anchorY = 0;
|
||||
break;
|
||||
case TextBaseline::BOTTOM:
|
||||
baselineAnchor = -fontMetrics.emDescent;
|
||||
anchorY = -fontMetrics.emDescent;
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("unexpected TextBaseline");
|
||||
}
|
||||
|
||||
if (processor.mTextRun->IsVertical()) {
|
||||
if (processor.mTextRun->UseCenterBaseline()) {
|
||||
// Adjust to account for mTextRun being shaped using center baseline
|
||||
// rather than alphabetic.
|
||||
baselineAnchor -= (fontMetrics.emAscent - fontMetrics.emDescent) * .5f;
|
||||
}
|
||||
processor.mPt.x -= baselineAnchor;
|
||||
} else {
|
||||
processor.mPt.y += baselineAnchor;
|
||||
}
|
||||
processor.mPt.y += anchorY;
|
||||
|
||||
// correct bounding box to get it to be the correct size/position
|
||||
processor.mBoundingBox.width = totalWidth;
|
||||
|
@ -134,11 +134,24 @@ else
|
||||
endif
|
||||
endif
|
||||
|
||||
# This stanza ensures that the set of GeckoView classes does not depend on too
|
||||
# much of Fennec, where "too much" is defined as the set of potentially
|
||||
# non-GeckoView classes that GeckoView already depended on at a certain point in
|
||||
# time. The idea is to set a high-water mark that is not to be crossed.
|
||||
classycle_jar := $(topsrcdir)/mobile/android/build/classycle/classycle-1.4.1.jar
|
||||
.geckoview.deps: geckoview.ddf $(classycle_jar) $(ALL_JARS)
|
||||
java -cp $(classycle_jar) \
|
||||
classycle.dependency.DependencyChecker \
|
||||
-mergeInnerClasses \
|
||||
-dependencies=@$< \
|
||||
$(ALL_JARS)
|
||||
@$(TOUCH) $@
|
||||
|
||||
# We touch the target file before invoking Proguard so that Proguard's
|
||||
# outputs are fresher than the target, preventing a subsequent
|
||||
# invocation from thinking Proguard's outputs are stale. This is safe
|
||||
# because Make removes the target file if any recipe command fails.
|
||||
.proguard.deps: $(ALL_JARS)
|
||||
.proguard.deps: .geckoview.deps $(ALL_JARS)
|
||||
$(REPORT_BUILD)
|
||||
@$(TOUCH) $@
|
||||
java \
|
||||
|
73
mobile/android/base/geckoview.ddf
Normal file
73
mobile/android/base/geckoview.ddf
Normal file
@ -0,0 +1,73 @@
|
||||
# This is a Classycle dependency definition file that asserts that the contents
|
||||
# of the GeckoView library (Classycle set [lib]) is a dependency (but does not
|
||||
# depend) on Fennec (Classycle set [main]). The additional Classycle set
|
||||
# [middle] consists of classes referenced by GeckoView that probably should not
|
||||
# be referenced. We want this middle set to shrink over time.
|
||||
|
||||
show allResults
|
||||
|
||||
[lib] = \
|
||||
org.mozilla.gecko.gfx.* \
|
||||
org.mozilla.gecko.mozglue.* \
|
||||
org.mozilla.gecko.sqlite.* \
|
||||
org.mozilla.gecko.util.* \
|
||||
org.mozilla.gecko.AndroidGamepadManager \
|
||||
org.mozilla.gecko.AppConstants \
|
||||
org.mozilla.gecko.BaseGeckoInterface \
|
||||
org.mozilla.gecko.ContextGetter \
|
||||
org.mozilla.gecko.CrashHandler \
|
||||
org.mozilla.gecko.EventDispatcher \
|
||||
org.mozilla.gecko.GeckoAccessibility \
|
||||
org.mozilla.gecko.GeckoAppShell \
|
||||
org.mozilla.gecko.GeckoBatteryManager \
|
||||
org.mozilla.gecko.GeckoEditable \
|
||||
org.mozilla.gecko.GeckoEditableClient \
|
||||
org.mozilla.gecko.GeckoEditableListener \
|
||||
org.mozilla.gecko.GeckoEvent \
|
||||
org.mozilla.gecko.GeckoInputConnection \
|
||||
org.mozilla.gecko.GeckoJavaSampler \
|
||||
org.mozilla.gecko.GeckoNetworkManager \
|
||||
org.mozilla.gecko.GeckoProfile \
|
||||
org.mozilla.gecko.GeckoScreenOrientation \
|
||||
org.mozilla.gecko.GeckoSharedPrefs \
|
||||
org.mozilla.gecko.GeckoThread \
|
||||
org.mozilla.gecko.GeckoView \
|
||||
org.mozilla.gecko.GlobalHistory \
|
||||
org.mozilla.gecko.InputMethods \
|
||||
org.mozilla.gecko.NSSBridge \
|
||||
org.mozilla.gecko.NotificationClient \
|
||||
org.mozilla.gecko.NotificationHandler \
|
||||
org.mozilla.gecko.PrefsHelper \
|
||||
org.mozilla.gecko.SmsManager \
|
||||
org.mozilla.gecko.SurfaceBits \
|
||||
org.mozilla.gecko.TouchEventInterceptor \
|
||||
org.mozilla.gecko.ZoomConstraints
|
||||
|
||||
[middle] = \
|
||||
org.mozilla.gecko.prompts.* \
|
||||
org.mozilla.gecko.AlertNotification \
|
||||
org.mozilla.gecko.FormAssistPopup \
|
||||
org.mozilla.gecko.GeckoActivity \
|
||||
org.mozilla.gecko.GeckoApp \
|
||||
org.mozilla.gecko.GeckoProfileDirectories \
|
||||
org.mozilla.gecko.GuestSession \
|
||||
org.mozilla.gecko.R \
|
||||
org.mozilla.gecko.Tab \
|
||||
org.mozilla.gecko.Tabs \
|
||||
org.mozilla.gecko.Telemetry \
|
||||
org.mozilla.gecko.TelemetryContract \
|
||||
org.mozilla.gecko.ThumbnailHelper \
|
||||
org.mozilla.gecko.db.BrowserDB \
|
||||
org.mozilla.gecko.db.LocalBrowserDB \
|
||||
org.mozilla.gecko.distribution.Distribution \
|
||||
org.mozilla.gecko.favicons.Favicons \
|
||||
org.mozilla.gecko.favicons.OnFaviconLoadedListener
|
||||
|
||||
[main] = org.mozilla.gecko.* excluding [lib] [middle]
|
||||
|
||||
check sets [lib] [middle] [main]
|
||||
|
||||
check [lib] directlyIndependentOf [main]
|
||||
|
||||
# This fails; if this passed, GeckoView would be ready to extract from Fennec.
|
||||
# check [lib] independentOf [middle]
|
22
mobile/android/build/classycle/LICENSE.txt
Normal file
22
mobile/android/build/classycle/LICENSE.txt
Normal file
@ -0,0 +1,22 @@
|
||||
Copyright (c) 2003-2008, Franz-Josef Elmer, All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
BIN
mobile/android/build/classycle/classycle-1.4.1.jar
Normal file
BIN
mobile/android/build/classycle/classycle-1.4.1.jar
Normal file
Binary file not shown.
@ -55,11 +55,6 @@ MOZ_PAY=1
|
||||
# Enable UI for healthreporter
|
||||
MOZ_SERVICES_HEALTHREPORT=1
|
||||
|
||||
# Wifi-AP/cell tower data reporting is enabled on non-release builds.
|
||||
if test ! "$RELEASE_BUILD"; then
|
||||
MOZ_DATA_REPORTING=1
|
||||
fi
|
||||
|
||||
# Enable runtime locale switching.
|
||||
MOZ_LOCALE_SWITCHER=1
|
||||
|
||||
|
@ -14,7 +14,7 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:0.14.1'
|
||||
classpath 'com.android.tools.build:gradle:0.12.2'
|
||||
}
|
||||
}
|
||||
|
||||
|
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
#Thu Nov 13 14:57:51 PST 2014
|
||||
#Wed Apr 10 15:27:10 PDT 2013
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.1-bin.zip
|
||||
distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip
|
||||
|
@ -32,6 +32,7 @@ import org.mozilla.mozstumbler.service.stumblerthread.scanners.WifiScanner;
|
||||
public final class Reporter extends BroadcastReceiver {
|
||||
private static final String LOG_TAG = AppGlobals.makeLogTag(Reporter.class.getSimpleName());
|
||||
public static final String ACTION_FLUSH_TO_BUNDLE = AppGlobals.ACTION_NAMESPACE + ".FLUSH";
|
||||
public static final String ACTION_NEW_BUNDLE = AppGlobals.ACTION_NAMESPACE + ".NEW_BUNDLE";
|
||||
private boolean mIsStarted;
|
||||
|
||||
/* The maximum number of Wi-Fi access points in a single observation. */
|
||||
@ -62,7 +63,12 @@ public final class Reporter extends BroadcastReceiver {
|
||||
|
||||
mContext = context.getApplicationContext();
|
||||
TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
mPhoneType = tm.getPhoneType();
|
||||
if (tm != null) {
|
||||
mPhoneType = tm.getPhoneType();
|
||||
} else {
|
||||
Log.d(LOG_TAG, "No telephony manager.");
|
||||
mPhoneType = TelephonyManager.PHONE_TYPE_NONE;
|
||||
}
|
||||
|
||||
mIsStarted = true;
|
||||
|
||||
|
@ -17,7 +17,6 @@ import org.mozilla.mozstumbler.service.stumblerthread.blocklist.WifiBlockListInt
|
||||
import org.mozilla.mozstumbler.service.stumblerthread.datahandling.DataStorageManager;
|
||||
import org.mozilla.mozstumbler.service.stumblerthread.scanners.ScanManager;
|
||||
import org.mozilla.mozstumbler.service.stumblerthread.scanners.cellscanner.CellScanner;
|
||||
import org.mozilla.mozstumbler.service.stumblerthread.scanners.cellscanner.CellScannerNoWCDMA;
|
||||
import org.mozilla.mozstumbler.service.uploadthread.UploadAlarmReceiver;
|
||||
import org.mozilla.mozstumbler.service.utils.NetworkUtils;
|
||||
import org.mozilla.mozstumbler.service.utils.PersistentIntentService;
|
||||
@ -109,10 +108,6 @@ public class StumblerService extends PersistentIntentService
|
||||
return mScanManager.getCellInfoCount();
|
||||
}
|
||||
|
||||
public int getCurrentCellInfoCount() {
|
||||
return mScanManager.getCurrentCellInfoCount();
|
||||
}
|
||||
|
||||
public boolean isGeofenced () {
|
||||
return mScanManager.isGeofenced();
|
||||
}
|
||||
@ -125,10 +120,6 @@ public class StumblerService extends PersistentIntentService
|
||||
NetworkUtils.createGlobalInstance(this);
|
||||
DataStorageManager.createGlobalInstance(this, this);
|
||||
|
||||
if (!CellScanner.isCellScannerImplSet()) {
|
||||
CellScanner.setCellScannerImpl(new CellScannerNoWCDMA(this));
|
||||
}
|
||||
|
||||
mReporter.startup(this);
|
||||
}
|
||||
|
||||
@ -144,8 +135,6 @@ public class StumblerService extends PersistentIntentService
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
UploadAlarmReceiver.cancelAlarm(this, !mScanManager.isPassiveMode());
|
||||
|
||||
if (!mScanManager.isScanning()) {
|
||||
return;
|
||||
}
|
||||
|
@ -424,8 +424,8 @@ public class DataStorageManager {
|
||||
}
|
||||
|
||||
mCurrentReports.reports.add(report);
|
||||
mCurrentReports.wifiCount = wifiCount;
|
||||
mCurrentReports.cellCount = cellCount;
|
||||
mCurrentReports.wifiCount += wifiCount;
|
||||
mCurrentReports.cellCount += cellCount;
|
||||
|
||||
if (mCurrentReports.reports.size() >= MAX_REPORTS_IN_MEMORY) {
|
||||
// save to disk
|
||||
|
@ -65,8 +65,23 @@ public class GPSScanner implements LocationListener {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isGpsAvailable(LocationManager locationManager) {
|
||||
if (locationManager == null ||
|
||||
locationManager.getProvider(LocationManager.GPS_PROVIDER) == null) {
|
||||
String msg = "No GPS available, scanning not started.";
|
||||
Log.d(LOG_TAG, msg);
|
||||
AppGlobals.guiLogError(msg);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void startPassiveMode() {
|
||||
LocationManager locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
|
||||
if (!isGpsAvailable(locationManager)) {
|
||||
return;
|
||||
}
|
||||
|
||||
locationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER,
|
||||
0,
|
||||
0, this);
|
||||
@ -74,6 +89,10 @@ public class GPSScanner implements LocationListener {
|
||||
|
||||
private void startActiveMode() {
|
||||
LocationManager lm = getLocationManager();
|
||||
if (!isGpsAvailable(lm)) {
|
||||
return;
|
||||
}
|
||||
|
||||
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,
|
||||
ACTIVE_MODE_GPS_MIN_UPDATE_TIME_MS,
|
||||
ACTIVE_MODE_GPS_MIN_UPDATE_DISTANCE_M,
|
||||
|
@ -98,6 +98,11 @@ public class ScanManager {
|
||||
}
|
||||
|
||||
mContext = context.getApplicationContext();
|
||||
if (mContext == null) {
|
||||
Log.w(LOG_TAG, "No app context available.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mGPSScanner == null) {
|
||||
mGPSScanner = new GPSScanner(context, this);
|
||||
mWifiScanner = new WifiScanner(context);
|
||||
@ -158,10 +163,6 @@ public class ScanManager {
|
||||
return (mCellScanner == null)? 0 :mCellScanner.getCellInfoCount();
|
||||
}
|
||||
|
||||
public int getCurrentCellInfoCount() {
|
||||
return (mCellScanner == null)? 0 :mCellScanner.getCurrentCellInfoCount();
|
||||
}
|
||||
|
||||
public int getLocationCount() {
|
||||
return (mGPSScanner == null)? 0 : mGPSScanner.getLocationCount();
|
||||
}
|
||||
|
@ -65,7 +65,11 @@ public class WifiScanner extends BroadcastReceiver {
|
||||
}
|
||||
|
||||
private List<ScanResult> getScanResults() {
|
||||
return (sIsTestMode)? mTestModeFakeScanResults : getWifiManager().getScanResults();
|
||||
WifiManager manager = getWifiManager();
|
||||
if (manager == null) {
|
||||
return null;
|
||||
}
|
||||
return getWifiManager().getScanResults();
|
||||
}
|
||||
|
||||
|
||||
@ -105,8 +109,12 @@ public class WifiScanner extends BroadcastReceiver {
|
||||
deactivatePeriodicScan();
|
||||
}
|
||||
} else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) {
|
||||
ArrayList<ScanResult> scanResults = new ArrayList<ScanResult>();
|
||||
for (ScanResult scanResult : getScanResults()) {
|
||||
final List<ScanResult> scanResultList = getScanResults();
|
||||
if (scanResultList == null) {
|
||||
return;
|
||||
}
|
||||
final ArrayList<ScanResult> scanResults = new ArrayList<ScanResult>();
|
||||
for (ScanResult scanResult : scanResultList) {
|
||||
scanResult.BSSID = BSSIDBlockList.canonicalizeBSSID(scanResult.BSSID);
|
||||
if (shouldLog(scanResult)) {
|
||||
scanResults.add(scanResult);
|
||||
|
@ -4,21 +4,28 @@
|
||||
|
||||
package org.mozilla.mozstumbler.service.stumblerthread.scanners.cellscanner;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
|
||||
import org.mozilla.mozstumbler.service.AppGlobals;
|
||||
import org.mozilla.mozstumbler.service.AppGlobals.ActiveOrPassiveStumbling;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import org.mozilla.mozstumbler.service.AppGlobals;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import org.mozilla.mozstumbler.service.AppGlobals.ActiveOrPassiveStumbling;
|
||||
|
||||
import org.mozilla.mozstumbler.service.stumblerthread.Reporter;
|
||||
|
||||
public class CellScanner {
|
||||
public static final String ACTION_BASE = AppGlobals.ACTION_NAMESPACE + ".CellScanner.";
|
||||
@ -30,47 +37,30 @@ public class CellScanner {
|
||||
private static final long CELL_MIN_UPDATE_TIME = 1000; // milliseconds
|
||||
|
||||
private final Context mContext;
|
||||
private static CellScannerImpl sImpl;
|
||||
private Timer mCellScanTimer;
|
||||
private final Set<String> mCells = new HashSet<String>();
|
||||
private int mCurrentCellInfoCount;
|
||||
private final ReportFlushedReceiver mReportFlushedReceiver = new ReportFlushedReceiver();
|
||||
private final AtomicBoolean mReportWasFlushed = new AtomicBoolean();
|
||||
private Handler mBroadcastScannedHandler;
|
||||
private final CellScannerImpl mCellScannerImplementation;
|
||||
|
||||
public ArrayList<CellInfo> sTestingModeCellInfoArray;
|
||||
|
||||
public interface CellScannerImpl {
|
||||
public void start();
|
||||
|
||||
public void stop();
|
||||
|
||||
public List<CellInfo> getCellInfo();
|
||||
void start();
|
||||
boolean isStarted();
|
||||
boolean isSupportedOnThisDevice();
|
||||
void stop();
|
||||
List<CellInfo> getCellInfo();
|
||||
}
|
||||
|
||||
public CellScanner(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
private static synchronized CellScannerImpl getImplementation() {
|
||||
return sImpl;
|
||||
}
|
||||
|
||||
public static synchronized boolean isCellScannerImplSet() {
|
||||
return sImpl != null;
|
||||
}
|
||||
|
||||
/* Fennec doesn't support the apis needed for full scanning, we have different implementations.*/
|
||||
public static synchronized void setCellScannerImpl(CellScannerImpl cellScanner) {
|
||||
sImpl = cellScanner;
|
||||
mCellScannerImplementation = new CellScannerImplementation(context);
|
||||
}
|
||||
|
||||
public void start(final ActiveOrPassiveStumbling stumblingMode) {
|
||||
if (getImplementation() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
getImplementation().start();
|
||||
} catch (UnsupportedOperationException uoe) {
|
||||
Log.e(LOG_TAG, "Cell scanner probe failed", uoe);
|
||||
if (!mCellScannerImplementation.isSupportedOnThisDevice()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -78,58 +68,95 @@ public class CellScanner {
|
||||
return;
|
||||
}
|
||||
|
||||
LocalBroadcastManager.getInstance(mContext).registerReceiver(mReportFlushedReceiver,
|
||||
new IntentFilter(Reporter.ACTION_NEW_BUNDLE));
|
||||
|
||||
// This is to ensure the broadcast happens from the same thread the CellScanner start() is on
|
||||
mBroadcastScannedHandler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
Intent intent = (Intent) msg.obj;
|
||||
LocalBroadcastManager.getInstance(mContext).sendBroadcastSync(intent);
|
||||
}
|
||||
};
|
||||
|
||||
mCellScannerImplementation.start();
|
||||
|
||||
mCellScanTimer = new Timer();
|
||||
|
||||
mCellScanTimer.schedule(new TimerTask() {
|
||||
int mPassiveScanCount;
|
||||
@Override
|
||||
public void run() {
|
||||
if (getImplementation() == null) {
|
||||
if (!mCellScannerImplementation.isStarted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (stumblingMode == ActiveOrPassiveStumbling.PASSIVE_STUMBLING &&
|
||||
mPassiveScanCount++ > AppGlobals.PASSIVE_MODE_MAX_SCANS_PER_GPS)
|
||||
mPassiveScanCount++ > AppGlobals.PASSIVE_MODE_MAX_SCANS_PER_GPS)
|
||||
{
|
||||
mPassiveScanCount = 0;
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
//if (SharedConstants.isDebug) Log.d(LOG_TAG, "Cell Scanning Timer fired");
|
||||
|
||||
final long curTime = System.currentTimeMillis();
|
||||
|
||||
ArrayList<CellInfo> cells = (sTestingModeCellInfoArray != null)? sTestingModeCellInfoArray :
|
||||
new ArrayList<CellInfo>(getImplementation().getCellInfo());
|
||||
new ArrayList<CellInfo>(mCellScannerImplementation.getCellInfo());
|
||||
|
||||
if (mReportWasFlushed.getAndSet(false)) {
|
||||
clearCells();
|
||||
}
|
||||
|
||||
mCurrentCellInfoCount = cells.size();
|
||||
if (cells.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (CellInfo cell: cells) mCells.add(cell.getCellIdentity());
|
||||
|
||||
for (CellInfo cell : cells) {
|
||||
addToCells(cell.getCellIdentity());
|
||||
}
|
||||
|
||||
Intent intent = new Intent(ACTION_CELLS_SCANNED);
|
||||
intent.putParcelableArrayListExtra(ACTION_CELLS_SCANNED_ARG_CELLS, cells);
|
||||
intent.putExtra(ACTION_CELLS_SCANNED_ARG_TIME, curTime);
|
||||
LocalBroadcastManager.getInstance(mContext).sendBroadcastSync(intent);
|
||||
// send to handler, so broadcast is not from timer thread
|
||||
Message message = new Message();
|
||||
message.obj = intent;
|
||||
mBroadcastScannedHandler.sendMessage(message);
|
||||
|
||||
}
|
||||
}, 0, CELL_MIN_UPDATE_TIME);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
private synchronized void clearCells() {
|
||||
mCells.clear();
|
||||
}
|
||||
|
||||
private synchronized void addToCells(String cell) {
|
||||
mCells.add(cell);
|
||||
}
|
||||
|
||||
public synchronized void stop() {
|
||||
mReportWasFlushed.set(false);
|
||||
clearCells();
|
||||
LocalBroadcastManager.getInstance(mContext).unregisterReceiver(mReportFlushedReceiver);
|
||||
|
||||
if (mCellScanTimer != null) {
|
||||
mCellScanTimer.cancel();
|
||||
mCellScanTimer = null;
|
||||
}
|
||||
if (getImplementation() != null) {
|
||||
getImplementation().stop();
|
||||
}
|
||||
mCellScannerImplementation.stop();
|
||||
}
|
||||
|
||||
public int getCellInfoCount() {
|
||||
public synchronized int getCellInfoCount() {
|
||||
return mCells.size();
|
||||
}
|
||||
|
||||
public int getCurrentCellInfoCount() {
|
||||
return mCurrentCellInfoCount;
|
||||
private class ReportFlushedReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context c, Intent i) {
|
||||
mReportWasFlushed.set(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,35 +10,40 @@ import android.os.Build;
|
||||
import android.telephony.CellIdentityCdma;
|
||||
import android.telephony.CellIdentityGsm;
|
||||
import android.telephony.CellIdentityLte;
|
||||
import android.telephony.CellIdentityWcdma;
|
||||
import android.telephony.CellInfoCdma;
|
||||
import android.telephony.CellInfoGsm;
|
||||
import android.telephony.CellInfoLte;
|
||||
import android.telephony.CellInfoWcdma;
|
||||
import android.telephony.CellLocation;
|
||||
import android.telephony.CellSignalStrengthCdma;
|
||||
import android.telephony.CellSignalStrengthGsm;
|
||||
import android.telephony.CellSignalStrengthLte;
|
||||
import android.telephony.CellSignalStrengthWcdma;
|
||||
import android.telephony.NeighboringCellInfo;
|
||||
import android.telephony.PhoneStateListener;
|
||||
import android.telephony.SignalStrength;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
|
||||
import org.mozilla.mozstumbler.service.AppGlobals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/* Fennec does not yet support the api level for WCDMA import */
|
||||
public class CellScannerNoWCDMA implements CellScanner.CellScannerImpl {
|
||||
public class CellScannerImplementation implements CellScanner.CellScannerImpl {
|
||||
|
||||
protected static String LOG_TAG = AppGlobals.makeLogTag(CellScannerNoWCDMA.class.getSimpleName());
|
||||
protected static String LOG_TAG = AppGlobals.makeLogTag(CellScannerImplementation.class.getSimpleName());
|
||||
protected GetAllCellInfoScannerImpl mGetAllInfoCellScanner;
|
||||
protected TelephonyManager mTelephonyManager;
|
||||
protected boolean mIsStarted;
|
||||
protected int mPhoneType;
|
||||
protected final Context mContext;
|
||||
protected volatile int mSignalStrength;
|
||||
protected volatile int mCdmaDbm;
|
||||
|
||||
protected volatile int mSignalStrength = CellInfo.UNKNOWN_SIGNAL;
|
||||
protected volatile int mCdmaDbm = CellInfo.UNKNOWN_SIGNAL;
|
||||
|
||||
private PhoneStateListener mPhoneStateListener;
|
||||
|
||||
@ -53,13 +58,28 @@ public class CellScannerNoWCDMA implements CellScanner.CellScannerImpl {
|
||||
List<CellInfo> getAllCellInfo(TelephonyManager tm);
|
||||
}
|
||||
|
||||
public CellScannerNoWCDMA(Context context) {
|
||||
public CellScannerImplementation(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
public boolean isSupportedOnThisDevice() {
|
||||
TelephonyManager telephonyManager = mTelephonyManager;
|
||||
if (telephonyManager == null) {
|
||||
telephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
}
|
||||
return telephonyManager != null &&
|
||||
(telephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA ||
|
||||
telephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
if (mIsStarted) {
|
||||
public synchronized boolean isStarted() {
|
||||
return mIsStarted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void start() {
|
||||
if (mIsStarted || !isSupportedOnThisDevice()) {
|
||||
return;
|
||||
}
|
||||
mIsStarted = true;
|
||||
@ -72,23 +92,8 @@ public class CellScannerNoWCDMA implements CellScanner.CellScannerImpl {
|
||||
}
|
||||
|
||||
mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
if (mTelephonyManager == null) {
|
||||
throw new UnsupportedOperationException("TelephonyManager service is not available");
|
||||
}
|
||||
|
||||
mPhoneType = mTelephonyManager.getPhoneType();
|
||||
|
||||
if (mPhoneType != TelephonyManager.PHONE_TYPE_GSM
|
||||
&& mPhoneType != TelephonyManager.PHONE_TYPE_CDMA) {
|
||||
throw new UnsupportedOperationException("Unexpected Phone Type: " + mPhoneType);
|
||||
}
|
||||
mSignalStrength = CellInfo.UNKNOWN_SIGNAL;
|
||||
mCdmaDbm = CellInfo.UNKNOWN_SIGNAL;
|
||||
}
|
||||
|
||||
mSignalStrength = CellInfo.UNKNOWN_SIGNAL;
|
||||
mCdmaDbm = CellInfo.UNKNOWN_SIGNAL;
|
||||
|
||||
mPhoneStateListener = new PhoneStateListener() {
|
||||
@Override
|
||||
public void onSignalStrengthsChanged(SignalStrength ss) {
|
||||
@ -103,9 +108,9 @@ public class CellScannerNoWCDMA implements CellScanner.CellScannerImpl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
public synchronized void stop() {
|
||||
mIsStarted = false;
|
||||
if (mTelephonyManager != null) {
|
||||
if (mTelephonyManager != null && mPhoneStateListener != null) {
|
||||
mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
|
||||
}
|
||||
mSignalStrength = CellInfo.UNKNOWN_SIGNAL;
|
||||
@ -113,7 +118,7 @@ public class CellScannerNoWCDMA implements CellScanner.CellScannerImpl {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CellInfo> getCellInfo() {
|
||||
public synchronized List<CellInfo> getCellInfo() {
|
||||
List<CellInfo> records = new ArrayList<CellInfo>();
|
||||
|
||||
List<CellInfo> allCells = mGetAllInfoCellScanner.getAllCellInfo(mTelephonyManager);
|
||||
@ -186,10 +191,39 @@ public class CellScannerNoWCDMA implements CellScanner.CellScannerImpl {
|
||||
return records;
|
||||
}
|
||||
|
||||
|
||||
@TargetApi(18)
|
||||
protected boolean addWCDMACellToList(List<CellInfo> cells,
|
||||
android.telephony.CellInfo observedCell,
|
||||
TelephonyManager tm) {
|
||||
boolean added = false;
|
||||
if (Build.VERSION.SDK_INT >= 18 &&
|
||||
observedCell instanceof CellInfoWcdma) {
|
||||
CellIdentityWcdma ident = ((CellInfoWcdma) observedCell).getCellIdentity();
|
||||
if (ident.getMnc() != Integer.MAX_VALUE && ident.getMcc() != Integer.MAX_VALUE) {
|
||||
CellInfo cell = new CellInfo(tm.getPhoneType());
|
||||
CellSignalStrengthWcdma strength = ((CellInfoWcdma) observedCell).getCellSignalStrength();
|
||||
cell.setWcmdaCellInfo(ident.getMcc(),
|
||||
ident.getMnc(),
|
||||
ident.getLac(),
|
||||
ident.getCid(),
|
||||
ident.getPsc(),
|
||||
strength.getAsuLevel());
|
||||
cells.add(cell);
|
||||
added = true;
|
||||
}
|
||||
}
|
||||
return added;
|
||||
}
|
||||
|
||||
@TargetApi(18)
|
||||
protected boolean addCellToList(List<CellInfo> cells,
|
||||
android.telephony.CellInfo observedCell,
|
||||
TelephonyManager tm) {
|
||||
android.telephony.CellInfo observedCell,
|
||||
TelephonyManager tm) {
|
||||
if (tm.getPhoneType() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean added = false;
|
||||
if (observedCell instanceof CellInfoGsm) {
|
||||
CellIdentityGsm ident = ((CellInfoGsm) observedCell).getCellIdentity();
|
||||
@ -226,10 +260,15 @@ public class CellScannerNoWCDMA implements CellScanner.CellScannerImpl {
|
||||
ident.getTac(),
|
||||
strength.getAsuLevel(),
|
||||
strength.getTimingAdvance());
|
||||
cells.add(cell);
|
||||
added = true;
|
||||
cells.add(cell);
|
||||
added = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!added && Build.VERSION.SDK_INT >= 18) {
|
||||
added = addWCDMACellToList(cells, observedCell, tm);
|
||||
}
|
||||
|
||||
return added;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ stumbler_sources = [
|
||||
'java/org/mozilla/mozstumbler/service/stumblerthread/Reporter.java',
|
||||
'java/org/mozilla/mozstumbler/service/stumblerthread/scanners/cellscanner/CellInfo.java',
|
||||
'java/org/mozilla/mozstumbler/service/stumblerthread/scanners/cellscanner/CellScanner.java',
|
||||
'java/org/mozilla/mozstumbler/service/stumblerthread/scanners/cellscanner/CellScannerNoWCDMA.java',
|
||||
'java/org/mozilla/mozstumbler/service/stumblerthread/scanners/cellscanner/CellScannerImplementation.java',
|
||||
'java/org/mozilla/mozstumbler/service/stumblerthread/scanners/GPSScanner.java',
|
||||
'java/org/mozilla/mozstumbler/service/stumblerthread/scanners/LocationBlockList.java',
|
||||
'java/org/mozilla/mozstumbler/service/stumblerthread/scanners/ScanManager.java',
|
||||
|
@ -1125,4 +1125,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
|
||||
|
||||
static const int32_t kUnknownId = -1;
|
||||
|
||||
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1423912295636000);
|
||||
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1424516980930000);
|
||||
|
@ -16,7 +16,6 @@ at.search.yahoo.com: did not receive HSTS header
|
||||
au.search.yahoo.com: did not receive HSTS header
|
||||
az.search.yahoo.com: did not receive HSTS header
|
||||
azprep.us: did not receive HSTS header
|
||||
bassh.net: did not receive HSTS header
|
||||
bccx.com: could not connect to host
|
||||
be.search.yahoo.com: did not receive HSTS header
|
||||
bedeta.de: could not connect to host
|
||||
@ -89,12 +88,13 @@ facebook.com: did not receive HSTS header
|
||||
fatzebra.com.au: did not receive HSTS header
|
||||
fi.search.yahoo.com: did not receive HSTS header
|
||||
filedir.com: did not receive HSTS header
|
||||
fixingdns.com: could not connect to host
|
||||
fixingdns.com: did not receive HSTS header
|
||||
fj.search.yahoo.com: did not receive HSTS header
|
||||
fr.search.yahoo.com: did not receive HSTS header
|
||||
gamesdepartment.co.uk: did not receive HSTS header
|
||||
get.zenpayroll.com: did not receive HSTS header
|
||||
getlantern.org: did not receive HSTS header
|
||||
gizzo.sk: could not connect to host
|
||||
gl.search.yahoo.com: did not receive HSTS header
|
||||
glass.google.com: did not receive HSTS header (error ignored - included regardless)
|
||||
gm.search.yahoo.com: did not receive HSTS header
|
||||
@ -108,6 +108,7 @@ gr.search.yahoo.com: did not receive HSTS header
|
||||
greplin.com: could not connect to host
|
||||
groups.google.com: did not receive HSTS header (error ignored - included regardless)
|
||||
hackerone-user-content.com: could not connect to host
|
||||
haste.ch: could not connect to host
|
||||
history.google.com: did not receive HSTS header (error ignored - included regardless)
|
||||
hk.search.yahoo.com: did not receive HSTS header
|
||||
hn.search.yahoo.com: did not receive HSTS header
|
||||
@ -121,6 +122,7 @@ id.search.yahoo.com: did not receive HSTS header
|
||||
ie.search.yahoo.com: did not receive HSTS header
|
||||
ilmconpm.de: did not receive HSTS header
|
||||
in.search.yahoo.com: did not receive HSTS header
|
||||
inertianetworks.com: did not receive HSTS header
|
||||
intercom.io: did not receive HSTS header
|
||||
iop.intuit.com: max-age too low: 86400
|
||||
irccloud.com: did not receive HSTS header
|
||||
@ -139,14 +141,13 @@ li.search.yahoo.com: did not receive HSTS header
|
||||
liberty.lavabit.com: could not connect to host
|
||||
lifeguard.aecom.com: max-age too low: 86400
|
||||
lists.mayfirst.org: did not receive HSTS header
|
||||
logentries.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 134" data: no]
|
||||
login.corp.google.com: max-age too low: 7776000 (error ignored - included regardless)
|
||||
logotype.se: did not receive HSTS header
|
||||
lovelycorral.com: did not receive HSTS header
|
||||
lt.search.yahoo.com: did not receive HSTS header
|
||||
lu.search.yahoo.com: did not receive HSTS header
|
||||
lumi.do: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 134" data: no]
|
||||
luxus-russen.de: did not receive HSTS header
|
||||
luxus-russen.de: could not connect to host
|
||||
lv.search.yahoo.com: did not receive HSTS header
|
||||
m.facebook.com: did not receive HSTS header
|
||||
m.gparent.org: could not connect to host
|
||||
@ -161,6 +162,7 @@ megaxchange.com: did not receive HSTS header
|
||||
minikneet.nl: did not receive HSTS header
|
||||
mobilethreat.net: could not connect to host
|
||||
mobilethreatnetwork.net: could not connect to host
|
||||
mocloud.eu: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 134" data: no]
|
||||
mt.search.yahoo.com: did not receive HSTS header
|
||||
mtouch.facebook.com: did not receive HSTS header
|
||||
mu.search.yahoo.com: did not receive HSTS header
|
||||
@ -216,6 +218,7 @@ ru.search.yahoo.com: did not receive HSTS header
|
||||
rw.search.yahoo.com: did not receive HSTS header
|
||||
sah3.net: could not connect to host
|
||||
saturngames.co.uk: did not receive HSTS header
|
||||
schreiber-netzwerk.eu: max-age too low: 0
|
||||
script.google.com: did not receive HSTS header (error ignored - included regardless)
|
||||
se.search.yahoo.com: did not receive HSTS header
|
||||
search.yahoo.com: did not receive HSTS header
|
||||
@ -235,10 +238,13 @@ sol.io: could not connect to host
|
||||
souyar.de: could not connect to host
|
||||
souyar.net: could not connect to host
|
||||
souyar.us: could not connect to host
|
||||
spdysync.com: did not receive HSTS header
|
||||
spongepowered.org: did not receive HSTS header
|
||||
spreadsheets.google.com: did not receive HSTS header (error ignored - included regardless)
|
||||
square.com: did not receive HSTS header
|
||||
ssl.google-analytics.com: did not receive HSTS header (error ignored - included regardless)
|
||||
ssl.panoramio.com: did not receive HSTS header
|
||||
staticanime.net: did not receive HSTS header
|
||||
stocktrade.de: could not connect to host
|
||||
sunshinepress.org: could not connect to host
|
||||
surfeasy.com: did not receive HSTS header
|
||||
@ -252,7 +258,6 @@ tektoria.de: did not receive HSTS header
|
||||
temehu.com: did not receive HSTS header
|
||||
terrax.berlin: could not connect to host
|
||||
th.search.yahoo.com: did not receive HSTS header
|
||||
tonerjet.co.uk: could not connect to host
|
||||
touch.facebook.com: did not receive HSTS header
|
||||
tr.search.yahoo.com: did not receive HSTS header
|
||||
translate.googleapis.com: did not receive HSTS header (error ignored - included regardless)
|
||||
|
@ -8,7 +8,7 @@
|
||||
/*****************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
const PRTime gPreloadListExpirationTime = INT64_C(1426331489992000);
|
||||
const PRTime gPreloadListExpirationTime = INT64_C(1426936177225000);
|
||||
|
||||
class nsSTSPreload
|
||||
{
|
||||
@ -36,6 +36,7 @@ static const nsSTSPreload kSTSPreloadList[] = {
|
||||
{ "aiticon.com", true },
|
||||
{ "aladdinschools.appspot.com", false },
|
||||
{ "alexsexton.com", true },
|
||||
{ "alexyang.me", true },
|
||||
{ "alpha.irccloud.com", false },
|
||||
{ "andreasbreitenlohner.de", true },
|
||||
{ "anetaben.nl", true },
|
||||
@ -73,10 +74,12 @@ static const nsSTSPreload kSTSPreloadList[] = {
|
||||
{ "barslecht.com", true },
|
||||
{ "barslecht.nl", true },
|
||||
{ "baruch.me", true },
|
||||
{ "bassh.net", true },
|
||||
{ "bautied.de", true },
|
||||
{ "bayrisch-fuer-anfaenger.de", true },
|
||||
{ "bccx.com", true },
|
||||
{ "bcrook.com", false },
|
||||
{ "beamitapp.com", true },
|
||||
{ "beastowner.com", true },
|
||||
{ "beastowner.li", true },
|
||||
{ "bedeta.de", true },
|
||||
@ -102,6 +105,7 @@ static const nsSTSPreload kSTSPreloadList[] = {
|
||||
{ "blog.torproject.org", false },
|
||||
{ "bodo-wolff.de", true },
|
||||
{ "bohramt.de", true },
|
||||
{ "bonigo.de", true },
|
||||
{ "boxcryptor.com", true },
|
||||
{ "brunosouza.org", true },
|
||||
{ "buddhistische-weisheiten.org", true },
|
||||
@ -119,15 +123,19 @@ static const nsSTSPreload kSTSPreloadList[] = {
|
||||
{ "cdnb.co", true },
|
||||
{ "celltek-server.de", false },
|
||||
{ "certible.com", true },
|
||||
{ "certly.io", true },
|
||||
{ "chainmonitor.com", true },
|
||||
{ "check.torproject.org", false },
|
||||
{ "checkout.google.com", true },
|
||||
{ "chontalpa.pw", true },
|
||||
{ "chrisjean.com", true },
|
||||
{ "chrome-devtools-frontend.appspot.com", true },
|
||||
{ "chrome.google.com", true },
|
||||
{ "chromiumcodereview.appspot.com", false },
|
||||
{ "chulado.com", true },
|
||||
{ "cktennis.com", true },
|
||||
{ "clapping-rhymes.com", true },
|
||||
{ "clintwilson.technology", true },
|
||||
{ "cloud.google.com", true },
|
||||
{ "cloudcert.org", true },
|
||||
{ "cloudns.com.au", true },
|
||||
@ -151,6 +159,7 @@ static const nsSTSPreload kSTSPreloadList[] = {
|
||||
{ "crowdjuris.com", true },
|
||||
{ "crypto.cat", false },
|
||||
{ "cryptopartyatx.org", true },
|
||||
{ "cspbuilder.info", true },
|
||||
{ "cube.de", true },
|
||||
{ "cujanovic.com", true },
|
||||
{ "cupcake.io", true },
|
||||
@ -171,14 +180,17 @@ static const nsSTSPreload kSTSPreloadList[] = {
|
||||
{ "debtkit.co.uk", true },
|
||||
{ "dedimax.de", true },
|
||||
{ "denh.am", true },
|
||||
{ "depechemode-live.com", true },
|
||||
{ "derevtsov.com", false },
|
||||
{ "derhil.de", true },
|
||||
{ "destinationbijoux.fr", true },
|
||||
{ "detectify.com", false },
|
||||
{ "developer.mydigipass.com", false },
|
||||
{ "devh.de", true },
|
||||
{ "diamante.ro", true },
|
||||
{ "die-besten-weisheiten.de", true },
|
||||
{ "dillonkorman.com", true },
|
||||
{ "dinamoelektrik.com", true },
|
||||
{ "dist.torproject.org", false },
|
||||
{ "dl.google.com", true },
|
||||
{ "dlc.viasinc.com", true },
|
||||
@ -211,22 +223,24 @@ static const nsSTSPreload kSTSPreloadList[] = {
|
||||
{ "errors.zenpayroll.com", false },
|
||||
{ "esec.rs", true },
|
||||
{ "espra.com", true },
|
||||
{ "ethack.org", true },
|
||||
{ "ethitter.com", true },
|
||||
{ "eurotramp.com", true },
|
||||
{ "everhome.de", true },
|
||||
{ "evstatus.com", true },
|
||||
{ "explodie.org", true },
|
||||
{ "f-droid.org", true },
|
||||
{ "fabianfischer.de", true },
|
||||
{ "factor.cc", false },
|
||||
{ "fairbill.com", true },
|
||||
{ "faq.lookout.com", false },
|
||||
{ "fastcomcorp.net", true },
|
||||
{ "fedorapeople.org", true },
|
||||
{ "feedbin.com", false },
|
||||
{ "ferienhaus-polchow-ruegen.de", false },
|
||||
{ "fiken.no", true },
|
||||
{ "firemail.io", true },
|
||||
{ "fischer-its.com", true },
|
||||
{ "fixingdns.com", true },
|
||||
{ "fj.simple.com", false },
|
||||
{ "flamer-scene.com", true },
|
||||
{ "fleximus.org", false },
|
||||
@ -313,13 +327,15 @@ static const nsSTSPreload kSTSPreloadList[] = {
|
||||
{ "imouto.my", false },
|
||||
{ "in.xero.com", false },
|
||||
{ "inbox.google.com", true },
|
||||
{ "inertianetworks.com", true },
|
||||
{ "inkbunny.net", true },
|
||||
{ "inleaked.com", true },
|
||||
{ "insouciant.org", true },
|
||||
{ "irische-segenswuensche.info", true },
|
||||
{ "ironfistdesign.com", true },
|
||||
{ "isitchristmas.com", true },
|
||||
{ "it-schwerin.de", true },
|
||||
{ "itsamurai.ru", true },
|
||||
{ "itshost.ru", true },
|
||||
{ "jackyyf.com", false },
|
||||
{ "janoberst.com", true },
|
||||
{ "janus-engineering.de", true },
|
||||
@ -327,16 +343,19 @@ static const nsSTSPreload kSTSPreloadList[] = {
|
||||
{ "jelmer.uk", true },
|
||||
{ "jfreitag.de", true },
|
||||
{ "jitsi.org", false },
|
||||
{ "jmedved.com", true },
|
||||
{ "jonas-keidel.de", true },
|
||||
{ "jonaswitmer.ch", true },
|
||||
{ "jonnybarnes.uk", true },
|
||||
{ "julian-kipka.de", true },
|
||||
{ "jwilsson.com", true },
|
||||
{ "jwilsson.me", true },
|
||||
{ "k-dev.de", true },
|
||||
{ "kaheim.de", true },
|
||||
{ "kardize24.pl", true },
|
||||
{ "kartonmodellbau.org", true },
|
||||
{ "kdex.de", true },
|
||||
{ "keepclean.me", true },
|
||||
{ "keeperapp.com", true },
|
||||
{ "keepersecurity.com", true },
|
||||
{ "kernel-error.de", true },
|
||||
@ -349,6 +368,7 @@ static const nsSTSPreload kSTSPreloadList[] = {
|
||||
{ "kinsights.com", false },
|
||||
{ "kitsta.com", true },
|
||||
{ "klatschreime.de", true },
|
||||
{ "klausbrinch.dk", true },
|
||||
{ "klaxn.com", true },
|
||||
{ "kleidertauschpartys.de", true },
|
||||
{ "knowledgehook.com", true },
|
||||
@ -364,6 +384,7 @@ static const nsSTSPreload kSTSPreloadList[] = {
|
||||
{ "launchkey.com", true },
|
||||
{ "lavalite.de", true },
|
||||
{ "lb-toner.de", true },
|
||||
{ "leonardcamacho.me", true },
|
||||
{ "library.linode.com", false },
|
||||
{ "liebel.org", true },
|
||||
{ "limpid.nl", true },
|
||||
@ -407,6 +428,7 @@ static const nsSTSPreload kSTSPreloadList[] = {
|
||||
{ "mattmccutchen.net", true },
|
||||
{ "mbp.banking.co.at", false },
|
||||
{ "md5file.com", true },
|
||||
{ "mdfnet.se", true },
|
||||
{ "mediacru.sh", true },
|
||||
{ "medium.com", true },
|
||||
{ "meetfinch.com", true },
|
||||
@ -415,7 +437,9 @@ static const nsSTSPreload kSTSPreloadList[] = {
|
||||
{ "members.mayfirst.org", false },
|
||||
{ "members.nearlyfreespeech.net", false },
|
||||
{ "miasarafina.de", true },
|
||||
{ "michalspacek.cz", true },
|
||||
{ "mig5.net", true },
|
||||
{ "mike-bland.com", true },
|
||||
{ "mikewest.org", true },
|
||||
{ "miku.hatsune.my", true },
|
||||
{ "minez-nightswatch.com", true },
|
||||
@ -458,11 +482,13 @@ static const nsSTSPreload kSTSPreloadList[] = {
|
||||
{ "nmctest.net", true },
|
||||
{ "nos-oignons.net", true },
|
||||
{ "npw.net", true },
|
||||
{ "oakslighting.co.uk", true },
|
||||
{ "okmx.de", true },
|
||||
{ "omitech.co.uk", true },
|
||||
{ "onedot.nl", true },
|
||||
{ "onedrive.com", true },
|
||||
{ "onedrive.live.com", false },
|
||||
{ "onsitemassageco.com", true },
|
||||
{ "oplop.appspot.com", true },
|
||||
{ "opsmate.com", false },
|
||||
{ "optimus.io", true },
|
||||
@ -513,6 +539,7 @@ static const nsSTSPreload kSTSPreloadList[] = {
|
||||
{ "prefontaine.name", true },
|
||||
{ "profiles.google.com", true },
|
||||
{ "projektzentrisch.de", true },
|
||||
{ "propagandism.org", true },
|
||||
{ "prowhisky.de", true },
|
||||
{ "pubkey.is", true },
|
||||
{ "publications.qld.gov.au", false },
|
||||
@ -550,7 +577,6 @@ static const nsSTSPreload kSTSPreloadList[] = {
|
||||
{ "sandbox.mydigipass.com", false },
|
||||
{ "schachburg.de", true },
|
||||
{ "schokokeks.org", false },
|
||||
{ "schreiber-netzwerk.eu", true },
|
||||
{ "schwarzer.it", true },
|
||||
{ "sciencex.com", true },
|
||||
{ "scotthelme.co.uk", true },
|
||||
@ -582,12 +608,13 @@ static const nsSTSPreload kSTSPreloadList[] = {
|
||||
{ "sites.google.com", true },
|
||||
{ "skydrive.live.com", false },
|
||||
{ "slattery.co", true },
|
||||
{ "slevomat.cz", true },
|
||||
{ "slidebatch.com", true },
|
||||
{ "smartcoin.com.br", true },
|
||||
{ "smartship.co.jp", true },
|
||||
{ "sour.is", true },
|
||||
{ "southside-crew.com", true },
|
||||
{ "spartantheatre.org", true },
|
||||
{ "spdysync.com", true },
|
||||
{ "spencerbaer.com", true },
|
||||
{ "spideroak.com", true },
|
||||
{ "spreadsheets.google.com", true },
|
||||
@ -611,10 +638,12 @@ static const nsSTSPreload kSTSPreloadList[] = {
|
||||
{ "studydrive.net", true },
|
||||
{ "subrosa.io", true },
|
||||
{ "suite73.org", true },
|
||||
{ "sunjaydhama.com", true },
|
||||
{ "supplies24.at", true },
|
||||
{ "supplies24.es", true },
|
||||
{ "support.mayfirst.org", false },
|
||||
{ "surkatty.org", true },
|
||||
{ "swehack.org", true },
|
||||
{ "sylaps.com", true },
|
||||
{ "sysctl.se", true },
|
||||
{ "syss.de", true },
|
||||
@ -634,6 +663,7 @@ static const nsSTSPreload kSTSPreloadList[] = {
|
||||
{ "therapynotes.com", false },
|
||||
{ "theshadestore.com", true },
|
||||
{ "thorncreek.net", false },
|
||||
{ "thusoy.com", true },
|
||||
{ "tickopa.co.uk", true },
|
||||
{ "timtaubert.de", true },
|
||||
{ "tinfoilsecurity.com", false },
|
||||
@ -641,6 +671,7 @@ static const nsSTSPreload kSTSPreloadList[] = {
|
||||
{ "tintenfix.net", true },
|
||||
{ "tipps-fuer-den-haushalt.de", true },
|
||||
{ "tittelbach.at", true },
|
||||
{ "tls.li", true },
|
||||
{ "tno.io", true },
|
||||
{ "tobias-kluge.de", true },
|
||||
{ "tollmanz.com", true },
|
||||
@ -681,6 +712,7 @@ static const nsSTSPreload kSTSPreloadList[] = {
|
||||
{ "usaa.com", false },
|
||||
{ "uzstyle.com", false },
|
||||
{ "vaddder.com", true },
|
||||
{ "vhost.co.id", true },
|
||||
{ "viasinc.com", false },
|
||||
{ "viennan.net", true },
|
||||
{ "vmoagents.com", false },
|
||||
@ -692,6 +724,7 @@ static const nsSTSPreload kSTSPreloadList[] = {
|
||||
{ "warrencreative.com", false },
|
||||
{ "watsonhall.uk", true },
|
||||
{ "webandmore.de", false },
|
||||
{ "webandwords.com.au", true },
|
||||
{ "webcollect.org.uk", true },
|
||||
{ "webfilings-eu-mirror.appspot.com", true },
|
||||
{ "webfilings-eu.appspot.com", true },
|
||||
@ -702,6 +735,7 @@ static const nsSTSPreload kSTSPreloadList[] = {
|
||||
{ "webmail.onlime.ch", false },
|
||||
{ "webmail.schokokeks.org", false },
|
||||
{ "websenat.de", true },
|
||||
{ "webtiles.co.uk", true },
|
||||
{ "weggeweest.nl", true },
|
||||
{ "welches-kinderfahrrad.de", true },
|
||||
{ "wepay.com", false },
|
||||
@ -773,11 +807,13 @@ static const nsSTSPreload kSTSPreloadList[] = {
|
||||
{ "xn--maraa-rta.org", true },
|
||||
{ "xps2pdf.co.uk", true },
|
||||
{ "y-o-w.com", true },
|
||||
{ "yoursecondphone.co", true },
|
||||
{ "ypart.eu", true },
|
||||
{ "z.ai", true },
|
||||
{ "zenpayroll.com", false },
|
||||
{ "zeplin.io", false },
|
||||
{ "zeropush.com", true },
|
||||
{ "zixiao.wang", true },
|
||||
{ "zlavomat.sk", true },
|
||||
{ "zotero.org", true },
|
||||
};
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
#include "mozilla/ModuleUtils.h"
|
||||
#include "nsAppStartup.h"
|
||||
#include "nsTerminator.h"
|
||||
#include "nsUserInfo.h"
|
||||
#include "nsToolkitCompsCID.h"
|
||||
#include "nsFindService.h"
|
||||
@ -44,12 +43,23 @@
|
||||
#include "NativeFileWatcherNotSupported.h"
|
||||
#endif // (XP_WIN)
|
||||
|
||||
#if !defined(MOZ_WIDGET_GONK) && !defined(MOZ_WIDGET_ANDROID)
|
||||
#define MOZ_HAS_TERMINATOR
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_HAS_TERMINATOR)
|
||||
#include "nsTerminator.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsAppStartup, Init)
|
||||
|
||||
#if defined(MOZ_HAS_TERMINATOR)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsTerminator)
|
||||
#endif
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsUserInfo)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFindService)
|
||||
@ -105,7 +115,9 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(NativeFileWatcherService, Init)
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(AddonPathService, AddonPathService::GetInstance)
|
||||
|
||||
NS_DEFINE_NAMED_CID(NS_TOOLKIT_APPSTARTUP_CID);
|
||||
#if defined(MOZ_HAS_TERMINATOR)
|
||||
NS_DEFINE_NAMED_CID(NS_TOOLKIT_TERMINATOR_CID);
|
||||
#endif
|
||||
NS_DEFINE_NAMED_CID(NS_USERINFO_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_ALERTSSERVICE_CID);
|
||||
#if !defined(MOZ_DISABLE_PARENTAL_CONTROLS)
|
||||
@ -134,7 +146,9 @@ NS_DEFINE_NAMED_CID(NATIVE_FILEWATCHER_SERVICE_CID);
|
||||
|
||||
static const Module::CIDEntry kToolkitCIDs[] = {
|
||||
{ &kNS_TOOLKIT_APPSTARTUP_CID, false, nullptr, nsAppStartupConstructor },
|
||||
#if defined(MOZ_HAS_TERMINATOR)
|
||||
{ &kNS_TOOLKIT_TERMINATOR_CID, false, nullptr, nsTerminatorConstructor },
|
||||
#endif
|
||||
{ &kNS_USERINFO_CID, false, nullptr, nsUserInfoConstructor },
|
||||
{ &kNS_ALERTSSERVICE_CID, false, nullptr, nsAlertsServiceConstructor },
|
||||
#if !defined(MOZ_DISABLE_PARENTAL_CONTROLS)
|
||||
@ -165,7 +179,9 @@ static const Module::CIDEntry kToolkitCIDs[] = {
|
||||
|
||||
static const Module::ContractIDEntry kToolkitContracts[] = {
|
||||
{ NS_APPSTARTUP_CONTRACTID, &kNS_TOOLKIT_APPSTARTUP_CID },
|
||||
#if defined(MOZ_HAS_TERMINATOR)
|
||||
{ NS_TOOLKIT_TERMINATOR_CONTRACTID, &kNS_TOOLKIT_TERMINATOR_CID },
|
||||
#endif
|
||||
{ NS_USERINFO_CONTRACTID, &kNS_USERINFO_CID },
|
||||
{ NS_ALERTSERVICE_CONTRACTID, &kNS_ALERTSSERVICE_CID },
|
||||
#if !defined(MOZ_DISABLE_PARENTAL_CONTROLS)
|
||||
|
@ -45,7 +45,6 @@ DIRS += [
|
||||
'startup',
|
||||
'statusfilter',
|
||||
'telemetry',
|
||||
'terminator',
|
||||
'thumbnails',
|
||||
'typeaheadfind',
|
||||
'urlformatter',
|
||||
@ -86,6 +85,9 @@ if CONFIG['MOZ_URL_CLASSIFIER']:
|
||||
if CONFIG['MOZ_CAPTIVEDETECT']:
|
||||
DIRS += ['captivedetect']
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] != "gonk" and CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android':
|
||||
DIRS += ['terminator']
|
||||
|
||||
DIRS += ['build']
|
||||
|
||||
EXTRA_COMPONENTS += [
|
||||
|
@ -86,13 +86,17 @@ SuggestAutoComplete.prototype = {
|
||||
*/
|
||||
onResultsReady: function(searchString, results, comments, formHistoryResult) {
|
||||
if (this._listener) {
|
||||
// Create a copy of the results array to use as labels, since
|
||||
// FormAutoCompleteResult doesn't like being passed the same array
|
||||
// for both.
|
||||
let labels = results.slice();
|
||||
let result = new FormAutoCompleteResult(
|
||||
searchString,
|
||||
Ci.nsIAutoCompleteResult.RESULT_SUCCESS,
|
||||
0,
|
||||
"",
|
||||
results,
|
||||
results,
|
||||
labels,
|
||||
comments,
|
||||
formHistoryResult);
|
||||
|
||||
|
@ -6775,6 +6775,34 @@
|
||||
"n_buckets": 10,
|
||||
"description": "Sidebar showing: seconds that the sidebar has been opened"
|
||||
},
|
||||
"SHUTDOWN_PHASE_DURATION_TICKS_QUIT_APPLICATION": {
|
||||
"expires_in_version": "never",
|
||||
"kind": "exponential",
|
||||
"high": 65,
|
||||
"n_buckets": 10,
|
||||
"description": "Duration of shutdown phase quit-application, as measured by the shutdown terminator, in seconds of activity"
|
||||
},
|
||||
"SHUTDOWN_PHASE_DURATION_TICKS_PROFILE_CHANGE_TEARDOWN": {
|
||||
"expires_in_version": "never",
|
||||
"kind": "exponential",
|
||||
"high": 65,
|
||||
"n_buckets": 10,
|
||||
"description": "Duration of shutdown phase profile-change-teardown, as measured by the shutdown terminator, in seconds of activity"
|
||||
},
|
||||
"SHUTDOWN_PHASE_DURATION_TICKS_XPCOM_WILL_SHUTDOWN": {
|
||||
"expires_in_version": "never",
|
||||
"kind": "exponential",
|
||||
"high": 65,
|
||||
"n_buckets": 10,
|
||||
"description": "Duration of shutdown phase xpcom-will-shutdown, as measured by the shutdown terminator, in seconds of activity"
|
||||
},
|
||||
"SHUTDOWN_PHASE_DURATION_TICKS_PROFILE_BEFORE_CHANGE": {
|
||||
"expires_in_version": "never",
|
||||
"kind": "exponential",
|
||||
"high": 65,
|
||||
"n_buckets": 10,
|
||||
"description": "Duration of shutdown phase profile-before-change, as measured by the shutdown terminator, in seconds of activity"
|
||||
},
|
||||
"BR_9_2_1_SUBJECT_ALT_NAMES": {
|
||||
"expires_in_version": "never",
|
||||
"kind": "enumerated",
|
||||
|
@ -4,6 +4,8 @@
|
||||
# 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/.
|
||||
|
||||
XPCSHELL_TESTS_MANIFESTS += ['tests/xpcshell/xpcshell.ini']
|
||||
|
||||
SOURCES += [
|
||||
'nsTerminator.cpp',
|
||||
]
|
||||
@ -13,6 +15,7 @@ EXPORTS += [
|
||||
]
|
||||
|
||||
EXTRA_COMPONENTS += [
|
||||
'nsTerminatorTelemetry.js',
|
||||
'terminator.manifest',
|
||||
]
|
||||
|
||||
|
@ -18,8 +18,14 @@
|
||||
#include "nsTerminator.h"
|
||||
|
||||
#include "prthread.h"
|
||||
#include "prmon.h"
|
||||
#include "plstr.h"
|
||||
#include "prio.h"
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsDirectoryServiceUtils.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIPrefService.h"
|
||||
@ -28,11 +34,14 @@
|
||||
#endif
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/MemoryChecking.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
// Normally, the number of milliseconds that AsyncShutdown waits until
|
||||
// it decides to crash is specified as a preference. We use the
|
||||
@ -51,29 +60,76 @@ namespace mozilla {
|
||||
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* Set to `true` by the main thread whenever we pass a shutdown phase,
|
||||
* which means that the shutdown is still ongoing. Reset to `false` by
|
||||
* the Terminator thread, once it has acknowledged the progress.
|
||||
*/
|
||||
Atomic<bool> gProgress(false);
|
||||
// Utility function: create a thread that is non-joinable,
|
||||
// does not prevent the process from terminating, is never
|
||||
// cooperatively scheduled, and uses a default stack size.
|
||||
PRThread* CreateSystemThread(void (*start)(void* arg),
|
||||
void* arg)
|
||||
{
|
||||
PRThread* thread = PR_CreateThread(
|
||||
PR_SYSTEM_THREAD, /* This thread will not prevent the process from terminating */
|
||||
start,
|
||||
arg,
|
||||
PR_PRIORITY_LOW,
|
||||
PR_GLOBAL_THREAD /* Make sure that the thread is never cooperatively scheduled */,
|
||||
PR_UNJOINABLE_THREAD,
|
||||
0 /* Use default stack size */
|
||||
);
|
||||
MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(thread); // This pointer will never be deallocated.
|
||||
return thread;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////
|
||||
//
|
||||
// The watchdog
|
||||
//
|
||||
// This nspr thread is in charge of crashing the process if any stage of shutdown
|
||||
// lasts more than some predefined duration. As a side-effect, it measures the
|
||||
// duration of each stage of shutdown.
|
||||
//
|
||||
|
||||
// The heartbeat of the operation.
|
||||
//
|
||||
// Main thread:
|
||||
//
|
||||
// * Whenever a shutdown step has been completed, the main thread
|
||||
// swaps gHeartbeat to 0 to mark that the shutdown process is still
|
||||
// progressing. The value swapped away indicates the number of ticks
|
||||
// it took for the shutdown step to advance.
|
||||
//
|
||||
// Watchdog thread:
|
||||
//
|
||||
// * Every tick, the watchdog thread increments gHearbeat atomically.
|
||||
//
|
||||
// A note about precision:
|
||||
// Since gHeartbeat is generally reset to 0 between two ticks, this means
|
||||
// that gHeartbeat stays at 0 less than one tick. Consequently, values
|
||||
// extracted from gHeartbeat must be considered rounded up.
|
||||
Atomic<uint32_t> gHeartbeat(0);
|
||||
|
||||
struct Options {
|
||||
int32_t crashAfterMS;
|
||||
/**
|
||||
* How many ticks before we should crash the process.
|
||||
*/
|
||||
uint32_t crashAfterTicks;
|
||||
};
|
||||
|
||||
/**
|
||||
* Entry point for the watchdog thread
|
||||
*/
|
||||
void
|
||||
Run(void* arg)
|
||||
RunWatchdog(void* arg)
|
||||
{
|
||||
PR_SetCurrentThreadName("Shutdown Hang Terminator");
|
||||
|
||||
// Let's copy and deallocate options, that's one less leak to worry
|
||||
// about.
|
||||
UniquePtr<Options> options((Options*)arg);
|
||||
int32_t crashAfterMS = options->crashAfterMS;
|
||||
uint32_t crashAfterTicks = options->crashAfterTicks;
|
||||
options = nullptr;
|
||||
|
||||
int32_t timeToLive = crashAfterMS;
|
||||
const uint32_t timeToLive = crashAfterTicks;
|
||||
while (true) {
|
||||
//
|
||||
// We do not want to sleep for the entire duration,
|
||||
@ -86,14 +142,8 @@ Run(void* arg)
|
||||
// more reasonable.
|
||||
//
|
||||
PR_Sleep(TICK_DURATION);
|
||||
if (gProgress.exchange(false)) {
|
||||
// We have passed at least one shutdown phase while waiting.
|
||||
// Shutdown is still alive, reset the countdown.
|
||||
timeToLive = crashAfterMS;
|
||||
continue;
|
||||
}
|
||||
timeToLive -= TICK_DURATION;
|
||||
if (timeToLive >= 0) {
|
||||
|
||||
if (gHeartbeat++ < timeToLive) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -102,20 +152,177 @@ Run(void* arg)
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
////////////////////////////////////////////
|
||||
//
|
||||
// Writer thread
|
||||
//
|
||||
// This nspr thread is in charge of writing to disk statistics produced by the
|
||||
// watchdog thread and collected by the main thread. Note that we use a nspr
|
||||
// thread rather than usual XPCOM I/O simply because we outlive XPCOM and its
|
||||
// threads.
|
||||
//
|
||||
|
||||
static char const *const sObserverTopics[] = {
|
||||
"quit-application",
|
||||
"profile-change-teardown",
|
||||
"profile-before-change",
|
||||
"xpcom-will-shutdown",
|
||||
"xpcom-shutdown",
|
||||
// Utility class, used by UniquePtr<> to close nspr files.
|
||||
class PR_CloseDelete
|
||||
{
|
||||
public:
|
||||
MOZ_CONSTEXPR PR_CloseDelete() {}
|
||||
|
||||
PR_CloseDelete(const PR_CloseDelete& aOther)
|
||||
{}
|
||||
|
||||
void operator()(PRFileDesc* aPtr) const
|
||||
{
|
||||
PR_Close(aPtr);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Communication between the main thread and the writer thread.
|
||||
//
|
||||
// Main thread:
|
||||
//
|
||||
// * Whenever a shutdown step has been completed, the main thread
|
||||
// obtains the number of ticks from the watchdog threads, builds
|
||||
// a string representing all the data gathered so far, places
|
||||
// this string in `gWriteData`, and wakes up the writer thread
|
||||
// using `gWriteReady`. If `gWriteData` already contained a non-null
|
||||
// pointer, this means that the writer thread is lagging behind the
|
||||
// main thread, and the main thread cleans up the memory.
|
||||
//
|
||||
// Writer thread:
|
||||
//
|
||||
// * When awake, the writer thread swaps `gWriteData` to nullptr. If
|
||||
// `gWriteData` contained data to write, the . If so, the writer
|
||||
// thread writes the data to a file named "ShutdownDuration.json.tmp",
|
||||
// then moves that file to "ShutdownDuration.json" and cleans up the
|
||||
// data. If `gWriteData` contains a nullptr, the writer goes to sleep
|
||||
// until it is awkened using `gWriteReady`.
|
||||
//
|
||||
//
|
||||
// The data written by the writer thread will be read by another
|
||||
// module upon the next restart and fed to Telemetry.
|
||||
//
|
||||
Atomic<nsCString*> gWriteData(nullptr);
|
||||
PRMonitor* gWriteReady = nullptr;
|
||||
|
||||
void RunWriter(void* arg)
|
||||
{
|
||||
PR_SetCurrentThreadName("Shutdown Statistics Writer");
|
||||
|
||||
MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(arg);
|
||||
// Shutdown will generally complete before we have a chance to
|
||||
// deallocate. This is not a leak.
|
||||
|
||||
// Setup destinationPath and tmpFilePath
|
||||
|
||||
nsCString destinationPath(static_cast<char*>(arg));
|
||||
nsAutoCString tmpFilePath;
|
||||
tmpFilePath.Append(destinationPath);
|
||||
tmpFilePath.AppendLiteral(".tmp");
|
||||
|
||||
// Cleanup any file leftover from a previous run
|
||||
unused << PR_Delete(tmpFilePath.get());
|
||||
unused << PR_Delete(destinationPath.get());
|
||||
|
||||
while (true) {
|
||||
//
|
||||
// Check whether we have received data from the main thread.
|
||||
//
|
||||
// We perform the check before waiting on `gWriteReady` as we may
|
||||
// have received data while we were busy writing.
|
||||
//
|
||||
// Also note that gWriteData may have been modified several times
|
||||
// since we last checked. That's ok, we are not losing any important
|
||||
// data (since we keep adding data), and we are not leaking memory
|
||||
// (since the main thread deallocates any data that hasn't been
|
||||
// consumed by the writer thread).
|
||||
//
|
||||
UniquePtr<nsCString> data(gWriteData.exchange(nullptr));
|
||||
if (!data) {
|
||||
// Data is not available yet.
|
||||
// Wait until the main thread provides it.
|
||||
PR_EnterMonitor(gWriteReady);
|
||||
PR_Wait(gWriteReady, PR_INTERVAL_NO_TIMEOUT);
|
||||
PR_ExitMonitor(gWriteReady);
|
||||
continue;
|
||||
}
|
||||
|
||||
MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(data.get());
|
||||
// Shutdown may complete before we have a chance to deallocate.
|
||||
// This is not a leak.
|
||||
|
||||
//
|
||||
// Write to a temporary file
|
||||
//
|
||||
// In case of any error, we simply give up. Since the data is
|
||||
// hardly critical, we don't want to spend too much effort
|
||||
// salvaging it.
|
||||
//
|
||||
UniquePtr<PRFileDesc, PR_CloseDelete>
|
||||
tmpFileDesc(PR_Open(tmpFilePath.get(),
|
||||
PR_WRONLY | PR_TRUNCATE | PR_CREATE_FILE,
|
||||
00600));
|
||||
|
||||
// Shutdown may complete before we have a chance to close the file.
|
||||
// This is not a leak.
|
||||
MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(tmpFileDesc.get());
|
||||
|
||||
if (tmpFileDesc == nullptr) {
|
||||
break;
|
||||
}
|
||||
if (PR_Write(tmpFileDesc.get(), data->get(), data->Length()) == -1) {
|
||||
break;
|
||||
}
|
||||
tmpFileDesc.reset();
|
||||
|
||||
//
|
||||
// Rename on top of destination file.
|
||||
//
|
||||
// This is not sufficient to guarantee that the destination file
|
||||
// will be written correctly, but, again, we don't care enough
|
||||
// about the data to make more efforts.
|
||||
//
|
||||
if (PR_Rename(tmpFilePath.get(), destinationPath.get()) != PR_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A step during shutdown.
|
||||
*
|
||||
* Shutdown is divided in steps, which all map to an observer
|
||||
* notification. The duration of a step is defined as the number of
|
||||
* ticks between the time we receive a notification and the next one.
|
||||
*/
|
||||
struct ShutdownStep
|
||||
{
|
||||
char const* const mTopic;
|
||||
int mTicks;
|
||||
|
||||
MOZ_CONSTEXPR ShutdownStep(const char *const topic)
|
||||
: mTopic(topic)
|
||||
, mTicks(-1)
|
||||
{}
|
||||
|
||||
};
|
||||
|
||||
static ShutdownStep sShutdownSteps[] = {
|
||||
ShutdownStep("quit-application"),
|
||||
ShutdownStep("profile-change-teardown"),
|
||||
ShutdownStep("profile-before-change"),
|
||||
ShutdownStep("xpcom-will-shutdown"),
|
||||
ShutdownStep("xpcom-shutdown"),
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsTerminator, nsIObserver)
|
||||
|
||||
nsTerminator::nsTerminator()
|
||||
: mInitialized(false)
|
||||
, mCurrentStep(-1)
|
||||
{
|
||||
}
|
||||
|
||||
@ -128,45 +335,92 @@ nsTerminator::SelfInit()
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ArrayLength(sObserverTopics); ++i) {
|
||||
DebugOnly<nsresult> rv = os->AddObserver(this, sObserverTopics[i], false);
|
||||
for (size_t i = 0; i < ArrayLength(sShutdownSteps); ++i) {
|
||||
DebugOnly<nsresult> rv = os->AddObserver(this, sShutdownSteps[i].mTopic, false);
|
||||
#if defined(DEBUG)
|
||||
NS_WARN_IF(NS_FAILED(rv));
|
||||
#endif // defined(DEBUG)
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Actually launch the thread. This takes place at the first sign of shutdown.
|
||||
// Actually launch these threads. This takes place at the first sign of shutdown.
|
||||
void
|
||||
nsTerminator::Start() {
|
||||
// Determine how long we need to wait
|
||||
nsTerminator::Start()
|
||||
{
|
||||
MOZ_ASSERT(!mInitialized);
|
||||
StartWatchdog();
|
||||
StartWriter();
|
||||
mInitialized = true;
|
||||
}
|
||||
|
||||
// Prepare, allocate and start the watchdog thread.
|
||||
// By design, it will never finish, nor be deallocated.
|
||||
void
|
||||
nsTerminator::StartWatchdog()
|
||||
{
|
||||
int32_t crashAfterMS =
|
||||
Preferences::GetInt("toolkit.asyncshutdown.crash_timeout",
|
||||
FALLBACK_ASYNCSHUTDOWN_CRASH_AFTER_MS);
|
||||
// Ignore negative values
|
||||
if (crashAfterMS <= 0) {
|
||||
crashAfterMS = FALLBACK_ASYNCSHUTDOWN_CRASH_AFTER_MS;
|
||||
}
|
||||
|
||||
// Add a little padding, to ensure that we do not crash before
|
||||
// AsyncShutdown.
|
||||
crashAfterMS += ADDITIONAL_WAIT_BEFORE_CRASH_MS;
|
||||
if (crashAfterMS > INT32_MAX - ADDITIONAL_WAIT_BEFORE_CRASH_MS) {
|
||||
// Defend against overflow
|
||||
crashAfterMS = INT32_MAX;
|
||||
} else {
|
||||
crashAfterMS += ADDITIONAL_WAIT_BEFORE_CRASH_MS;
|
||||
}
|
||||
|
||||
UniquePtr<Options> options(new Options());
|
||||
options->crashAfterMS = crashAfterMS;
|
||||
options->crashAfterTicks = crashAfterMS / TICK_DURATION;
|
||||
|
||||
// Allocate and start the thread.
|
||||
// By design, it will never finish, nor be deallocated.
|
||||
DebugOnly<PRThread*> thread = PR_CreateThread(
|
||||
PR_SYSTEM_THREAD, /* This thread will not prevent the process from terminating */
|
||||
Run,
|
||||
options.release(),
|
||||
PR_PRIORITY_LOW,
|
||||
PR_GLOBAL_THREAD /* Make sure that the thread is never cooperatively scheduled */,
|
||||
PR_UNJOINABLE_THREAD,
|
||||
0 /* Use default stack size */
|
||||
);
|
||||
DebugOnly<PRThread*> watchdogThread = CreateSystemThread(RunWatchdog,
|
||||
options.release());
|
||||
MOZ_ASSERT(watchdogThread);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(thread);
|
||||
mInitialized = true;
|
||||
// Prepare, allocate and start the writer thread. By design, it will never
|
||||
// finish, nor be deallocated. In case of error, we degrade
|
||||
// gracefully to not writing Telemetry data.
|
||||
void
|
||||
nsTerminator::StartWriter()
|
||||
{
|
||||
|
||||
if (!Telemetry::CanRecord()) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIFile> profLD;
|
||||
nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_LOCAL_50_DIR,
|
||||
getter_AddRefs(profLD));
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
rv = profLD->Append(NS_LITERAL_STRING("ShutdownDuration.json"));
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoString path;
|
||||
rv = profLD->GetPath(path);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
gWriteReady = PR_NewMonitor();
|
||||
MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(gWriteReady); // We will never deallocate this object
|
||||
PRThread* writerThread = CreateSystemThread(RunWriter,
|
||||
ToNewUTF8String(path));
|
||||
|
||||
if (!writerThread) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -185,19 +439,101 @@ nsTerminator::Observe(nsISupports *, const char *aTopic, const char16_t *)
|
||||
Start();
|
||||
}
|
||||
|
||||
// Inform the thread that we have advanced by one phase.
|
||||
gProgress.exchange(true);
|
||||
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
// In case of crash, we wish to know where in shutdown we are
|
||||
unused << CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ShutdownProgress"),
|
||||
nsAutoCString(aTopic));
|
||||
#endif // defined(MOZ_CRASH_REPORTER)
|
||||
UpdateHeartbeat(aTopic);
|
||||
UpdateTelemetry();
|
||||
UpdateCrashReport(aTopic);
|
||||
|
||||
// Perform a little cleanup
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
MOZ_RELEASE_ASSERT(os);
|
||||
(void)os->RemoveObserver(this, aTopic);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsTerminator::UpdateHeartbeat(const char* aTopic)
|
||||
{
|
||||
// Reset the clock, find out how long the current phase has lasted.
|
||||
uint32_t ticks = gHeartbeat.exchange(0);
|
||||
if (mCurrentStep > 0) {
|
||||
sShutdownSteps[mCurrentStep].mTicks = ticks;
|
||||
}
|
||||
|
||||
// Find out where we now are in the current shutdown.
|
||||
// Don't assume that shutdown takes place in the expected order.
|
||||
int nextStep = -1;
|
||||
for (size_t i = 0; i < ArrayLength(sShutdownSteps); ++i) {
|
||||
if (strcmp(sShutdownSteps[i].mTopic, aTopic) == 0) {
|
||||
nextStep = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(nextStep != -1);
|
||||
mCurrentStep = nextStep;
|
||||
}
|
||||
|
||||
void
|
||||
nsTerminator::UpdateTelemetry()
|
||||
{
|
||||
if (!Telemetry::CanRecord() || !gWriteReady) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// We need Telemetry data on the effective duration of each step,
|
||||
// to be able to tune the time-to-crash of each of both the
|
||||
// Terminator and AsyncShutdown. However, at this stage, it is too
|
||||
// late to record such data into Telemetry, so we write it to disk
|
||||
// and read it upon the next startup.
|
||||
//
|
||||
|
||||
// Build JSON.
|
||||
UniquePtr<nsCString> telemetryData(new nsCString());
|
||||
telemetryData->AppendLiteral("{");
|
||||
size_t fields = 0;
|
||||
for (size_t i = 0; i < ArrayLength(sShutdownSteps); ++i) {
|
||||
if (sShutdownSteps[i].mTicks < 0) {
|
||||
// Ignore this field.
|
||||
continue;
|
||||
}
|
||||
if (fields++ > 0) {
|
||||
telemetryData->Append(", ");
|
||||
}
|
||||
telemetryData->AppendLiteral("\"");
|
||||
telemetryData->Append(sShutdownSteps[i].mTopic);
|
||||
telemetryData->AppendLiteral("\": ");
|
||||
telemetryData->AppendInt(sShutdownSteps[i].mTicks);
|
||||
}
|
||||
telemetryData->AppendLiteral("}");
|
||||
|
||||
if (fields == 0) {
|
||||
// Nothing to write
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Send data to the worker thread.
|
||||
//
|
||||
delete gWriteData.exchange(telemetryData.release()); // Clear any data that hasn't been written yet
|
||||
|
||||
// In case the worker thread was sleeping, wake it up.
|
||||
PR_EnterMonitor(gWriteReady);
|
||||
PR_Notify(gWriteReady);
|
||||
PR_ExitMonitor(gWriteReady);
|
||||
}
|
||||
|
||||
void
|
||||
nsTerminator::UpdateCrashReport(const char* aTopic)
|
||||
{
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
// In case of crash, we wish to know where in shutdown we are
|
||||
nsAutoCString report(aTopic);
|
||||
|
||||
unused << CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ShutdownProgress"),
|
||||
report);
|
||||
#endif // defined(MOZ_CRASH_REPORTER)
|
||||
}
|
||||
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -22,10 +22,17 @@ public:
|
||||
private:
|
||||
nsresult SelfInit();
|
||||
void Start();
|
||||
void StartWatchdog();
|
||||
void StartWriter();
|
||||
|
||||
void UpdateHeartbeat(const char* aTopic);
|
||||
void UpdateTelemetry();
|
||||
void UpdateCrashReport(const char* aTopic);
|
||||
|
||||
~nsTerminator() {}
|
||||
|
||||
bool mInitialized;
|
||||
int32_t mCurrentStep;
|
||||
};
|
||||
|
||||
}
|
||||
|
105
toolkit/components/terminator/nsTerminatorTelemetry.js
Normal file
105
toolkit/components/terminator/nsTerminatorTelemetry.js
Normal file
@ -0,0 +1,105 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */
|
||||
/* 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";
|
||||
|
||||
/**
|
||||
* Read the data saved by nsTerminator during shutdown and feed it to the
|
||||
* relevant telemetry histograms.
|
||||
*/
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
const Cr = Components.results;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "OS",
|
||||
"resource://gre/modules/osfile.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
"resource://gre/modules/Promise.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||
"resource://gre/modules/Task.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "setTimeout",
|
||||
"resource://gre/modules/Timer.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
|
||||
function nsTerminatorTelemetry() {}
|
||||
|
||||
let HISTOGRAMS = {
|
||||
"quit-application": "SHUTDOWN_PHASE_DURATION_TICKS_QUIT_APPLICATION",
|
||||
"profile-change-teardown": "SHUTDOWN_PHASE_DURATION_TICKS_PROFILE_CHANGE_TEARDOWN",
|
||||
"profile-before-change": "SHUTDOWN_PHASE_DURATION_TICKS_PROFILE_BEFORE_CHANGE",
|
||||
"xpcom-will-shutdown": "SHUTDOWN_PHASE_DURATION_TICKS_XPCOM_WILL_SHUTDOWN",
|
||||
};
|
||||
|
||||
nsTerminatorTelemetry.prototype = {
|
||||
classID: Components.ID("{3f78ada1-cba2-442a-82dd-d5fb300ddea7}"),
|
||||
|
||||
_xpcom_factory: XPCOMUtils.generateSingletonFactory(nsTerminatorTelemetry),
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// nsISupports
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// nsIObserver
|
||||
|
||||
observe: function DS_observe(aSubject, aTopic, aData)
|
||||
{
|
||||
Task.spawn(function*() {
|
||||
//
|
||||
// This data is hardly critical, reading it can wait for a few seconds.
|
||||
//
|
||||
yield new Promise(resolve => setTimeout(resolve, 3000));
|
||||
|
||||
let PATH = OS.Path.join(OS.Constants.Path.localProfileDir,
|
||||
"ShutdownDuration.json");
|
||||
let raw;
|
||||
try {
|
||||
raw = yield OS.File.read(PATH, { encoding: "utf-8" });
|
||||
} catch (ex if ex.becauseNoSuchFile) {
|
||||
return;
|
||||
}
|
||||
// Let other errors be reported by Promise's error-reporting.
|
||||
|
||||
// Clean up
|
||||
OS.File.remove(PATH);
|
||||
OS.File.remove(PATH + ".tmp");
|
||||
|
||||
let data = JSON.parse(raw);
|
||||
for (let k of Object.keys(data)) {
|
||||
let id = HISTOGRAMS[k];
|
||||
try {
|
||||
let histogram = Services.telemetry.getHistogramById(id);
|
||||
if (!histogram) {
|
||||
throw new Error("Unknown histogram " + id);
|
||||
}
|
||||
|
||||
histogram.add(Number.parseInt(data[k]));
|
||||
} catch (ex) {
|
||||
// Make sure that the error is reported and causes test failures,
|
||||
// but otherwise, ignore it.
|
||||
Promise.reject(ex);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Inform observers that we are done.
|
||||
Services.obs.notifyObservers(null,
|
||||
"shutdown-terminator-telemetry-updated",
|
||||
"");
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Module
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([nsTerminatorTelemetry]);
|
@ -1,2 +1,5 @@
|
||||
category profile-after-change nsTerminator @mozilla.org/toolkit/shutdown-terminator;1
|
||||
|
||||
component {3f78ada1-cba2-442a-82dd-d5fb300ddea7} nsTerminatorTelemetry.js
|
||||
contract @mozilla.org/toolkit/shutdown-terminator-telemetry;1 {3f78ada1-cba2-442a-82dd-d5fb300ddea7}
|
||||
category profile-after-change nsTerminatorTelemetry @mozilla.org/toolkit/shutdown-terminator-telemetry;1
|
||||
|
@ -0,0 +1,108 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
// Test that the Shutdown Terminator records durations correctly
|
||||
|
||||
const Cu = Components.utils;
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm", this);
|
||||
Cu.import("resource://gre/modules/osfile.jsm", this);
|
||||
Cu.import("resource://gre/modules/Timer.jsm", this);
|
||||
Cu.import("resource://gre/modules/Task.jsm", this);
|
||||
|
||||
let {Path, File, Constants} = OS;
|
||||
|
||||
let PATH;
|
||||
let PATH_TMP;
|
||||
let terminator;
|
||||
|
||||
add_task(function* init() {
|
||||
do_get_profile();
|
||||
PATH = Path.join(Constants.Path.localProfileDir, "ShutdownDuration.json");
|
||||
PATH_TMP = PATH + ".tmp";
|
||||
|
||||
// Initialize the terminator
|
||||
// (normally, this is done through the manifest file, but xpcshell
|
||||
// doesn't take them into account).
|
||||
do_print("Initializing the Terminator");
|
||||
terminator = Cc["@mozilla.org/toolkit/shutdown-terminator;1"].
|
||||
createInstance(Ci.nsIObserver);
|
||||
terminator.observe(null, "profile-after-change", null);
|
||||
});
|
||||
|
||||
let promiseShutdownDurationData = Task.async(function*() {
|
||||
// Wait until PATH exists.
|
||||
// Timeout if it is never created.
|
||||
do_print("Waiting for file creation: " + PATH);
|
||||
while (true) {
|
||||
if ((yield OS.File.exists(PATH))) {
|
||||
break;
|
||||
}
|
||||
|
||||
do_print("The file does not exist yet. Waiting 1 second.");
|
||||
yield new Promise(resolve => setTimeout(resolve, 1000));
|
||||
}
|
||||
|
||||
do_print("The file has been created");
|
||||
let raw = yield OS.File.read(PATH, { encoding: "utf-8"} );
|
||||
do_print(raw);
|
||||
return JSON.parse(raw);
|
||||
});
|
||||
|
||||
add_task(function* test_record() {
|
||||
let PHASE0 = "profile-change-teardown";
|
||||
let PHASE1 = "profile-before-change";
|
||||
let PHASE2 = "xpcom-will-shutdown";
|
||||
let t0 = Date.now();
|
||||
|
||||
do_print("Starting shutdown");
|
||||
terminator.observe(null, "profile-change-teardown", null);
|
||||
|
||||
do_print("Moving to next phase");
|
||||
terminator.observe(null, PHASE1, null);
|
||||
|
||||
let data = yield promiseShutdownDurationData();
|
||||
|
||||
let t1 = Date.now();
|
||||
|
||||
Assert.ok(PHASE0 in data, "The file contains the expected key");
|
||||
let duration = data[PHASE0];
|
||||
Assert.equal(typeof duration, "number");
|
||||
Assert.ok(duration >= 0, "Duration is a non-negative number");
|
||||
Assert.ok(duration <= Math.ceil((t1 - t0) / 1000) + 1,
|
||||
"Duration is reasonable");
|
||||
|
||||
Assert.equal(Object.keys(data).length, 1, "Data does not contain other durations");
|
||||
|
||||
do_print("Cleaning up and moving to next phase");
|
||||
yield File.remove(PATH);
|
||||
yield File.remove(PATH_TMP);
|
||||
|
||||
do_print("Waiting at least one tick");
|
||||
let WAIT_MS = 2000;
|
||||
yield new Promise(resolve => setTimeout(resolve, WAIT_MS));
|
||||
|
||||
terminator.observe(null, PHASE2, null);
|
||||
data = yield promiseShutdownDurationData();
|
||||
|
||||
let t2 = Date.now();
|
||||
|
||||
Assert.equal(Object.keys(data).sort().join(", "),
|
||||
[PHASE0, PHASE1].sort().join(", "),
|
||||
"The file contains the expected keys");
|
||||
Assert.equal(data[PHASE0], duration, "Duration of phase 0 hasn't changed");
|
||||
let duration2 = data[PHASE1];
|
||||
Assert.equal(typeof duration2, "number");
|
||||
Assert.ok(duration2 >= WAIT_MS / 2000, "We have waited at least " + (WAIT_MS / 2000) + " ticks");
|
||||
Assert.ok(duration2 <= Math.ceil((t2 - t1) / 1000) + 1,
|
||||
"Duration is reasonable");
|
||||
});
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
// Test that the Shutdown Terminator reloads durations correctly
|
||||
|
||||
const Cu = Components.utils;
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm", this);
|
||||
Cu.import("resource://gre/modules/osfile.jsm", this);
|
||||
Cu.import("resource://gre/modules/Timer.jsm", this);
|
||||
Cu.import("resource://gre/modules/Task.jsm", this);
|
||||
|
||||
let {Path, File, Constants} = OS;
|
||||
|
||||
let PATH;
|
||||
|
||||
let HISTOGRAMS = {
|
||||
"quit-application": "SHUTDOWN_PHASE_DURATION_TICKS_QUIT_APPLICATION",
|
||||
"profile-change-teardown": "SHUTDOWN_PHASE_DURATION_TICKS_PROFILE_CHANGE_TEARDOWN",
|
||||
"profile-before-change": "SHUTDOWN_PHASE_DURATION_TICKS_PROFILE_BEFORE_CHANGE",
|
||||
"xpcom-will-shutdown": "SHUTDOWN_PHASE_DURATION_TICKS_XPCOM_WILL_SHUTDOWN",
|
||||
};
|
||||
|
||||
add_task(function* init() {
|
||||
do_get_profile();
|
||||
PATH = Path.join(Constants.Path.localProfileDir, "ShutdownDuration.json");
|
||||
});
|
||||
|
||||
add_task(function* test_reload() {
|
||||
do_print("Forging data");
|
||||
let data = {};
|
||||
let telemetrySnapshots = Services.telemetry.histogramSnapshots;
|
||||
let i = 0;
|
||||
for (let k of Object.keys(HISTOGRAMS)) {
|
||||
let id = HISTOGRAMS[k];
|
||||
data[k] = i++;
|
||||
Assert.equal(telemetrySnapshots[id] || undefined, undefined, "Histogram " + id + " is empty");
|
||||
}
|
||||
|
||||
|
||||
yield OS.File.writeAtomic(PATH, JSON.stringify(data));
|
||||
|
||||
const TOPIC = "shutdown-terminator-telemetry-updated";
|
||||
|
||||
let wait = new Promise(resolve =>
|
||||
Services.obs.addObserver(
|
||||
function observer() {
|
||||
do_print("Telemetry has been updated");
|
||||
Services.obs.removeObserver(observer, TOPIC);
|
||||
resolve();
|
||||
},
|
||||
TOPIC,
|
||||
false));
|
||||
|
||||
do_print("Starting nsTerminatorTelemetry");
|
||||
let tt = Cc["@mozilla.org/toolkit/shutdown-terminator-telemetry;1"].
|
||||
createInstance(Ci.nsIObserver);
|
||||
tt.observe(null, "profile-after-change", "");
|
||||
|
||||
do_print("Waiting until telemetry is updated");
|
||||
// Now wait until Telemetry is updated
|
||||
yield wait;
|
||||
|
||||
telemetrySnapshots = Services.telemetry.histogramSnapshots;
|
||||
for (let k of Object.keys(HISTOGRAMS)) {
|
||||
let id = HISTOGRAMS[k];
|
||||
do_print("Testing histogram " + id);
|
||||
let snapshot = telemetrySnapshots[id];
|
||||
let count = 0;
|
||||
for (let x of snapshot.counts) {
|
||||
count += x;
|
||||
}
|
||||
Assert.equal(count, 1, "We have added one item");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
[DEFAULT]
|
||||
head=
|
||||
tail=
|
||||
|
||||
[test_terminator_record.js]
|
||||
[test_terminator_reload.js]
|
||||
skip-if = (os == "android" || appname == "b2g")
|
@ -21,6 +21,7 @@ function setup_crash() {
|
||||
// Inform the terminator that shutdown has started
|
||||
// Pick an arbitrary notification
|
||||
terminator.observe(null, "xpcom-will-shutdown", null);
|
||||
terminator.observe(null, "profile-before-change", null);
|
||||
|
||||
dump("Waiting (actively) for the crash\n");
|
||||
while(true) {
|
||||
@ -30,7 +31,8 @@ function setup_crash() {
|
||||
|
||||
|
||||
function after_crash(mdump, extra) {
|
||||
Assert.equal(extra.ShutdownProgress, "xpcom-will-shutdown");
|
||||
do_print("Crash signature: " + JSON.stringify(extra, null, "\t"));
|
||||
Assert.equal(extra.ShutdownProgress, "profile-before-change");
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
|
Loading…
Reference in New Issue
Block a user