зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to fx-team
This commit is contained in:
Коммит
778d930067
|
@ -251,6 +251,8 @@ GetAccService()
|
|||
inline bool
|
||||
IPCAccessibilityActive()
|
||||
{
|
||||
// XXX temporarily disable ipc accessibility because of crashes.
|
||||
return false;
|
||||
#ifdef MOZ_B2G
|
||||
return false;
|
||||
#else
|
||||
|
|
|
@ -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="0da467aba9ecf354b905f9cc08dfa1a4169659e4"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e64428c5b2dce5db90b75a5055077a04f4bd4819"/>
|
||||
<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="93935064318f39906400a9e9fd636dd9528f5c16"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="b6f8267794b8c7f2a33236d46a857a84388b8485"/>
|
||||
<!-- 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="0da467aba9ecf354b905f9cc08dfa1a4169659e4"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e64428c5b2dce5db90b75a5055077a04f4bd4819"/>
|
||||
<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="d5d3f93914558b6f168447b805cd799c8233e300"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="a47dd04f8f66e42fd331711140f2c3e2fed0767d"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="93935064318f39906400a9e9fd636dd9528f5c16"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="b6f8267794b8c7f2a33236d46a857a84388b8485"/>
|
||||
<!-- 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="0da467aba9ecf354b905f9cc08dfa1a4169659e4"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e64428c5b2dce5db90b75a5055077a04f4bd4819"/>
|
||||
<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="93935064318f39906400a9e9fd636dd9528f5c16"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="b6f8267794b8c7f2a33236d46a857a84388b8485"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -134,7 +134,7 @@
|
|||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c5f8d282efe4a4e8b1e31a37300944e338e60e4f"/>
|
||||
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9f28c4faea3b2f01db227b2467b08aeba96d9bec"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="5502ba6f3f7606d0142cf38b1067d3d0a669f314"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="7e257a260fb6a6c3811f9c396cfe3ccf191241f6"/>
|
||||
<project name="android-sdk" path="sdk" remote="b2g" revision="8b1365af38c9a653df97349ee53a3f5d64fd590a"/>
|
||||
<project name="darwinstreamingserver" path="system/darwinstreamingserver" remote="b2g" revision="cf85968c7f85e0ec36e72c87ceb4837a943b8af6"/>
|
||||
</manifest>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="0da467aba9ecf354b905f9cc08dfa1a4169659e4"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e64428c5b2dce5db90b75a5055077a04f4bd4819"/>
|
||||
<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="93935064318f39906400a9e9fd636dd9528f5c16"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="b6f8267794b8c7f2a33236d46a857a84388b8485"/>
|
||||
<!-- 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="0da467aba9ecf354b905f9cc08dfa1a4169659e4"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e64428c5b2dce5db90b75a5055077a04f4bd4819"/>
|
||||
<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="d5d3f93914558b6f168447b805cd799c8233e300"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="a47dd04f8f66e42fd331711140f2c3e2fed0767d"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="93935064318f39906400a9e9fd636dd9528f5c16"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="b6f8267794b8c7f2a33236d46a857a84388b8485"/>
|
||||
<!-- 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="0da467aba9ecf354b905f9cc08dfa1a4169659e4"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e64428c5b2dce5db90b75a5055077a04f4bd4819"/>
|
||||
<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="93935064318f39906400a9e9fd636dd9528f5c16"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="b6f8267794b8c7f2a33236d46a857a84388b8485"/>
|
||||
<!-- 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"/>
|
||||
|
@ -153,7 +153,7 @@
|
|||
<project name="platform/hardware/ril" path="hardware/ril" revision="12b1977cc704b35f2e9db2bb423fa405348bc2f3"/>
|
||||
<project name="platform/system/bluetooth" path="system/bluetooth" revision="985bf15264d865fe7b9c5b45f61c451cbaafa43d"/>
|
||||
<project name="platform/system/core" path="system/core" revision="350eac5403124dacb2a5fd9e28ac290a59fc3b8e"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="5502ba6f3f7606d0142cf38b1067d3d0a669f314"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="7e257a260fb6a6c3811f9c396cfe3ccf191241f6"/>
|
||||
<project name="platform/system/qcom" path="system/qcom" revision="63e3f6f176caad587d42bba4c16b66d953fb23c2"/>
|
||||
<project name="platform/vendor/qcom-opensource/wlan/prima" path="vendor/qcom/opensource/wlan/prima" revision="d8952a42771045fca73ec600e2b42a4c7129d723"/>
|
||||
<project name="platform/vendor/qcom/msm8610" path="device/qcom/msm8610" revision="018b44e52b2bac5d3631d559550e88a4b68c6e67"/>
|
||||
|
|
|
@ -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="0da467aba9ecf354b905f9cc08dfa1a4169659e4"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e64428c5b2dce5db90b75a5055077a04f4bd4819"/>
|
||||
<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="93935064318f39906400a9e9fd636dd9528f5c16"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="b6f8267794b8c7f2a33236d46a857a84388b8485"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -145,7 +145,7 @@
|
|||
<project name="platform/hardware/ril" path="hardware/ril" revision="c4e2ac95907a5519a0e09f01a0d8e27fec101af0"/>
|
||||
<project name="platform/system/bluetooth" path="system/bluetooth" revision="e1eb226fa3ad3874ea7b63c56a9dc7012d7ff3c2"/>
|
||||
<project name="platform/system/core" path="system/core" revision="adc485d8755af6a61641d197de7cfef667722580"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="5502ba6f3f7606d0142cf38b1067d3d0a669f314"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="7e257a260fb6a6c3811f9c396cfe3ccf191241f6"/>
|
||||
<project name="platform/system/qcom" path="system/qcom" revision="1cdab258b15258b7f9657da70e6f06ebd5a2fc25"/>
|
||||
<project name="platform/vendor/qcom/msm8610" path="device/qcom/msm8610" revision="4ae5df252123591d5b941191790e7abed1bce5a4"/>
|
||||
<project name="platform/vendor/qcom-opensource/wlan/prima" path="vendor/qcom/opensource/wlan/prima" revision="ce18b47b4a4f93a581d672bbd5cb6d12fe796ca9"/>
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
"remote": "",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "4f3818d9c5577c26d8368fad5e87e546519c4b13",
|
||||
"revision": "f155f8ab67a65c066730976e0b7cef0d39579a24",
|
||||
"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="0da467aba9ecf354b905f9cc08dfa1a4169659e4"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e64428c5b2dce5db90b75a5055077a04f4bd4819"/>
|
||||
<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="93935064318f39906400a9e9fd636dd9528f5c16"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="b6f8267794b8c7f2a33236d46a857a84388b8485"/>
|
||||
<!-- 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="0da467aba9ecf354b905f9cc08dfa1a4169659e4"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e64428c5b2dce5db90b75a5055077a04f4bd4819"/>
|
||||
<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="0da467aba9ecf354b905f9cc08dfa1a4169659e4"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="e64428c5b2dce5db90b75a5055077a04f4bd4819"/>
|
||||
<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="93935064318f39906400a9e9fd636dd9528f5c16"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="b6f8267794b8c7f2a33236d46a857a84388b8485"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -129,7 +129,7 @@
|
|||
<project name="device-mako" path="device/lge/mako" remote="b2g" revision="78d17f0c117f0c66dd55ee8d5c5dde8ccc93ecba"/>
|
||||
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="3a9a17613cc685aa232432566ad6cc607eab4ec1"/>
|
||||
<project name="device/lge/mako-kernel" path="device/lge/mako-kernel" revision="d1729e53d71d711c8fde25eab8728ff2b9b4df0e"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="5502ba6f3f7606d0142cf38b1067d3d0a669f314"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="7e257a260fb6a6c3811f9c396cfe3ccf191241f6"/>
|
||||
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/>
|
||||
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
|
||||
<project name="platform/hardware/broadcom/wlan" path="hardware/broadcom/wlan" revision="0e1929fa3aa38bf9d40e9e953d619fab8164c82e"/>
|
||||
|
|
|
@ -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="0da467aba9ecf354b905f9cc08dfa1a4169659e4"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="e64428c5b2dce5db90b75a5055077a04f4bd4819"/>
|
||||
<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="93935064318f39906400a9e9fd636dd9528f5c16"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="b6f8267794b8c7f2a33236d46a857a84388b8485"/>
|
||||
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
|
||||
|
|
|
@ -1666,7 +1666,7 @@ pref("loop.CSP", "default-src 'self' about: file: chrome:; img-src 'self' data:
|
|||
#endif
|
||||
pref("loop.oauth.google.redirect_uri", "urn:ietf:wg:oauth:2.0:oob:auto");
|
||||
pref("loop.oauth.google.scope", "https://www.google.com/m8/feeds");
|
||||
pref("loop.rooms.enabled", false);
|
||||
pref("loop.rooms.enabled", true);
|
||||
pref("loop.fxa_oauth.tokendata", "");
|
||||
pref("loop.fxa_oauth.profile", "");
|
||||
|
||||
|
|
|
@ -627,7 +627,10 @@ nsContextMenu.prototype = {
|
|||
this.onCanvas = true;
|
||||
}
|
||||
else if (this.target instanceof HTMLVideoElement) {
|
||||
this.mediaURL = this.target.currentSrc || this.target.src;
|
||||
let mediaURL = this.target.currentSrc || this.target.src;
|
||||
if (this.isMediaURLReusable(mediaURL)) {
|
||||
this.mediaURL = mediaURL;
|
||||
}
|
||||
// Firefox always creates a HTMLVideoElement when loading an ogg file
|
||||
// directly. If the media is actually audio, be smarter and provide a
|
||||
// context menu with audio operations.
|
||||
|
@ -640,7 +643,10 @@ nsContextMenu.prototype = {
|
|||
}
|
||||
else if (this.target instanceof HTMLAudioElement) {
|
||||
this.onAudio = true;
|
||||
this.mediaURL = this.target.currentSrc || this.target.src;
|
||||
let mediaURL = this.target.currentSrc || this.target.src;
|
||||
if (this.isMediaURLReusable(mediaURL)) {
|
||||
this.mediaURL = mediaURL;
|
||||
}
|
||||
}
|
||||
else if (editFlags & (SpellCheckHelper.INPUT | SpellCheckHelper.TEXTAREA)) {
|
||||
this.onTextInput = (editFlags & SpellCheckHelper.TEXTINPUT) !== 0;
|
||||
|
@ -1504,6 +1510,10 @@ nsContextMenu.prototype = {
|
|||
return !this.focusedWindow.getSelection().isCollapsed;
|
||||
},
|
||||
|
||||
isMediaURLReusable: function(aURL) {
|
||||
return !/^(?:blob|mediasource):/.test(aURL);
|
||||
},
|
||||
|
||||
toString: function () {
|
||||
return "contextMenu.target = " + this.target + "\n" +
|
||||
"contextMenu.onImage = " + this.onImage + "\n" +
|
||||
|
|
|
@ -435,7 +435,6 @@ skip-if = e10s # Bug ?????? - test needs to be updated for e10s (captures a stac
|
|||
skip-if = e10s # Bug 1100664 - test relies on linkedBrowser.docShell
|
||||
[browser_tabs_owner.js]
|
||||
[browser_trackingUI.js]
|
||||
skip-if = e10s # Bug 1093155 - tries to use context menu from browser-chrome and gets in a mess when in e10s mode
|
||||
support-files =
|
||||
trackingPage.html
|
||||
benignPage.html
|
||||
|
|
|
@ -77,6 +77,11 @@ function promiseGetMozLoopAPI() {
|
|||
* This assumes that the tests are running in a generatorTest.
|
||||
*/
|
||||
function loadLoopPanel(aOverrideOptions = {}) {
|
||||
Services.prefs.setBoolPref("loop.rooms.enabled", false);
|
||||
registerCleanupFunction(function() {
|
||||
Services.prefs.clearUserPref("loop.rooms.enabled");
|
||||
});
|
||||
|
||||
// Set prefs to ensure we don't access the network externally.
|
||||
Services.prefs.setCharPref("services.push.serverURL", aOverrideOptions.pushURL || "ws://localhost/");
|
||||
Services.prefs.setCharPref("loop.server", aOverrideOptions.loopURL || "http://localhost/");
|
||||
|
|
|
@ -108,7 +108,8 @@ class MachCommands(MachCommandBase):
|
|||
'--num-callers=36',
|
||||
'--leak-check=full',
|
||||
'--show-possibly-lost=no',
|
||||
'--track-origins=yes'
|
||||
'--track-origins=yes',
|
||||
'--trace-children=yes',
|
||||
]
|
||||
|
||||
for s in suppressions:
|
||||
|
|
|
@ -71,7 +71,7 @@ GCONF_VERSION=1.2.1
|
|||
GIO_VERSION=2.20
|
||||
STARTUP_NOTIFICATION_VERSION=0.8
|
||||
DBUS_VERSION=0.60
|
||||
SQLITE_VERSION=3.8.7.1
|
||||
SQLITE_VERSION=3.8.7.2
|
||||
|
||||
MSMANIFEST_TOOL=
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
This is SQLite 3.8.7.1
|
||||
|
||||
-- Ryan VanderMeulen <ryanvm@gmail.com>, 11/2014
|
||||
This is SQLite 3.8.7.2
|
||||
|
||||
See http://www.sqlite.org/ for more info.
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
** This file is an amalgamation of many separate C source files from SQLite
|
||||
** version 3.8.7.1. By combining all the individual C code files into this
|
||||
** version 3.8.7.2. By combining all the individual C code files into this
|
||||
** single large file, the entire code can be compiled as a single translation
|
||||
** unit. This allows many compilers to do optimizations that would not be
|
||||
** possible if the files were compiled separately. Performance improvements
|
||||
|
@ -231,9 +231,9 @@ extern "C" {
|
|||
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
||||
** [sqlite_version()] and [sqlite_source_id()].
|
||||
*/
|
||||
#define SQLITE_VERSION "3.8.7.1"
|
||||
#define SQLITE_VERSION "3.8.7.2"
|
||||
#define SQLITE_VERSION_NUMBER 3008007
|
||||
#define SQLITE_SOURCE_ID "2014-10-29 13:59:56 3b7b72c4685aa5cf5e675c2c47ebec10d9704221"
|
||||
#define SQLITE_SOURCE_ID "2014-11-18 20:57:56 2ab564bf9655b7c7b97ab85cafc8a48329b27f93"
|
||||
|
||||
/*
|
||||
** CAPI3REF: Run-Time Library Version Numbers
|
||||
|
@ -9013,7 +9013,7 @@ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int);
|
|||
SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster);
|
||||
SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree*, int);
|
||||
SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*);
|
||||
SQLITE_PRIVATE int sqlite3BtreeRollback(Btree*,int);
|
||||
SQLITE_PRIVATE int sqlite3BtreeRollback(Btree*,int,int);
|
||||
SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree*,int);
|
||||
SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree*, int*, int flags);
|
||||
SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree*);
|
||||
|
@ -9046,7 +9046,7 @@ SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *);
|
|||
SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree*, int, int*);
|
||||
SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree*, int, int*);
|
||||
SQLITE_PRIVATE int sqlite3BtreeClearTableOfCursor(BtCursor*);
|
||||
SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree*, int);
|
||||
SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree*, int, int);
|
||||
|
||||
SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue);
|
||||
SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
|
||||
|
@ -13062,7 +13062,7 @@ SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);
|
|||
SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, char*, int, int);
|
||||
SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int);
|
||||
SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum*,const char*);
|
||||
SQLITE_PRIVATE void sqlite3AppendSpace(StrAccum*,int);
|
||||
SQLITE_PRIVATE void sqlite3AppendChar(StrAccum*,int,char);
|
||||
SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*);
|
||||
SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum*);
|
||||
SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int);
|
||||
|
@ -20947,7 +20947,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
|
|||
const et_info *infop; /* Pointer to the appropriate info structure */
|
||||
char *zOut; /* Rendering buffer */
|
||||
int nOut; /* Size of the rendering buffer */
|
||||
char *zExtra; /* Malloced memory used by some conversion */
|
||||
char *zExtra = 0; /* Malloced memory used by some conversion */
|
||||
#ifndef SQLITE_OMIT_FLOATING_POINT
|
||||
int exp, e2; /* exponent of real numbers */
|
||||
int nsd; /* Number of significant digits returned */
|
||||
|
@ -21064,7 +21064,6 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
|
|||
break;
|
||||
}
|
||||
}
|
||||
zExtra = 0;
|
||||
|
||||
/*
|
||||
** At this point, variables are initialized as follows:
|
||||
|
@ -21355,13 +21354,16 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
|
|||
}else{
|
||||
c = va_arg(ap,int);
|
||||
}
|
||||
buf[0] = (char)c;
|
||||
if( precision>=0 ){
|
||||
for(idx=1; idx<precision; idx++) buf[idx] = (char)c;
|
||||
length = precision;
|
||||
}else{
|
||||
length =1;
|
||||
if( precision>1 ){
|
||||
width -= precision-1;
|
||||
if( width>1 && !flag_leftjustify ){
|
||||
sqlite3AppendChar(pAccum, width-1, ' ');
|
||||
width = 0;
|
||||
}
|
||||
sqlite3AppendChar(pAccum, precision-1, c);
|
||||
}
|
||||
length = 1;
|
||||
buf[0] = c;
|
||||
bufpt = buf;
|
||||
break;
|
||||
case etSTRING:
|
||||
|
@ -21462,11 +21464,14 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
|
|||
** the output.
|
||||
*/
|
||||
width -= length;
|
||||
if( width>0 && !flag_leftjustify ) sqlite3AppendSpace(pAccum, width);
|
||||
if( width>0 && !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
|
||||
sqlite3StrAccumAppend(pAccum, bufpt, length);
|
||||
if( width>0 && flag_leftjustify ) sqlite3AppendSpace(pAccum, width);
|
||||
if( width>0 && flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
|
||||
|
||||
if( zExtra ) sqlite3_free(zExtra);
|
||||
if( zExtra ){
|
||||
sqlite3_free(zExtra);
|
||||
zExtra = 0;
|
||||
}
|
||||
}/* End for loop over the format string */
|
||||
} /* End of function */
|
||||
|
||||
|
@ -21519,11 +21524,11 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
|
|||
}
|
||||
|
||||
/*
|
||||
** Append N space characters to the given string buffer.
|
||||
** Append N copies of character c to the given string buffer.
|
||||
*/
|
||||
SQLITE_PRIVATE void sqlite3AppendSpace(StrAccum *p, int N){
|
||||
SQLITE_PRIVATE void sqlite3AppendChar(StrAccum *p, int N, char c){
|
||||
if( p->nChar+N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ) return;
|
||||
while( (N--)>0 ) p->zText[p->nChar++] = ' ';
|
||||
while( (N--)>0 ) p->zText[p->nChar++] = c;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -50636,7 +50641,6 @@ SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *p
|
|||
}
|
||||
if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal);
|
||||
}
|
||||
assert( rc==SQLITE_OK );
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -51715,6 +51719,11 @@ struct CellInfo {
|
|||
**
|
||||
** Fields in this structure are accessed under the BtShared.mutex
|
||||
** found at self->pBt->mutex.
|
||||
**
|
||||
** skipNext meaning:
|
||||
** eState==SKIPNEXT && skipNext>0: Next sqlite3BtreeNext() is no-op.
|
||||
** eState==SKIPNEXT && skipNext<0: Next sqlite3BtreePrevious() is no-op.
|
||||
** eState==FAULT: Cursor fault with skipNext as error code.
|
||||
*/
|
||||
struct BtCursor {
|
||||
Btree *pBtree; /* The Btree to which this cursor belongs */
|
||||
|
@ -51727,7 +51736,8 @@ struct BtCursor {
|
|||
void *pKey; /* Saved key that was cursor last known position */
|
||||
Pgno pgnoRoot; /* The root page of this tree */
|
||||
int nOvflAlloc; /* Allocated size of aOverflow[] array */
|
||||
int skipNext; /* Prev() is noop if negative. Next() is noop if positive */
|
||||
int skipNext; /* Prev() is noop if negative. Next() is noop if positive.
|
||||
** Error code if eState==CURSOR_FAULT */
|
||||
u8 curFlags; /* zero or more BTCF_* flags defined below */
|
||||
u8 eState; /* One of the CURSOR_XXX constants (see below) */
|
||||
u8 hints; /* As configured by CursorSetHints() */
|
||||
|
@ -51773,7 +51783,7 @@ struct BtCursor {
|
|||
** on a different connection that shares the BtShared cache with this
|
||||
** cursor. The error has left the cache in an inconsistent state.
|
||||
** Do nothing else with this cursor. Any attempt to use the cursor
|
||||
** should return the error code stored in BtCursor.skip
|
||||
** should return the error code stored in BtCursor.skipNext
|
||||
*/
|
||||
#define CURSOR_INVALID 0
|
||||
#define CURSOR_VALID 1
|
||||
|
@ -54355,7 +54365,7 @@ SQLITE_PRIVATE int sqlite3BtreeClose(Btree *p){
|
|||
** The call to sqlite3BtreeRollback() drops any table-locks held by
|
||||
** this handle.
|
||||
*/
|
||||
sqlite3BtreeRollback(p, SQLITE_OK);
|
||||
sqlite3BtreeRollback(p, SQLITE_OK, 0);
|
||||
sqlite3BtreeLeave(p);
|
||||
|
||||
/* If there are still other outstanding references to the shared-btree
|
||||
|
@ -55648,60 +55658,91 @@ SQLITE_PRIVATE int sqlite3BtreeCommit(Btree *p){
|
|||
|
||||
/*
|
||||
** This routine sets the state to CURSOR_FAULT and the error
|
||||
** code to errCode for every cursor on BtShared that pBtree
|
||||
** references.
|
||||
** code to errCode for every cursor on any BtShared that pBtree
|
||||
** references. Or if the writeOnly flag is set to 1, then only
|
||||
** trip write cursors and leave read cursors unchanged.
|
||||
**
|
||||
** Every cursor is tripped, including cursors that belong
|
||||
** to other database connections that happen to be sharing
|
||||
** the cache with pBtree.
|
||||
** Every cursor is a candidate to be tripped, including cursors
|
||||
** that belong to other database connections that happen to be
|
||||
** sharing the cache with pBtree.
|
||||
**
|
||||
** This routine gets called when a rollback occurs.
|
||||
** All cursors using the same cache must be tripped
|
||||
** to prevent them from trying to use the btree after
|
||||
** the rollback. The rollback may have deleted tables
|
||||
** or moved root pages, so it is not sufficient to
|
||||
** save the state of the cursor. The cursor must be
|
||||
** invalidated.
|
||||
** This routine gets called when a rollback occurs. If the writeOnly
|
||||
** flag is true, then only write-cursors need be tripped - read-only
|
||||
** cursors save their current positions so that they may continue
|
||||
** following the rollback. Or, if writeOnly is false, all cursors are
|
||||
** tripped. In general, writeOnly is false if the transaction being
|
||||
** rolled back modified the database schema. In this case b-tree root
|
||||
** pages may be moved or deleted from the database altogether, making
|
||||
** it unsafe for read cursors to continue.
|
||||
**
|
||||
** If the writeOnly flag is true and an error is encountered while
|
||||
** saving the current position of a read-only cursor, all cursors,
|
||||
** including all read-cursors are tripped.
|
||||
**
|
||||
** SQLITE_OK is returned if successful, or if an error occurs while
|
||||
** saving a cursor position, an SQLite error code.
|
||||
*/
|
||||
SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode){
|
||||
SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode, int writeOnly){
|
||||
BtCursor *p;
|
||||
if( pBtree==0 ) return;
|
||||
sqlite3BtreeEnter(pBtree);
|
||||
for(p=pBtree->pBt->pCursor; p; p=p->pNext){
|
||||
int i;
|
||||
sqlite3BtreeClearCursor(p);
|
||||
p->eState = CURSOR_FAULT;
|
||||
p->skipNext = errCode;
|
||||
for(i=0; i<=p->iPage; i++){
|
||||
releasePage(p->apPage[i]);
|
||||
p->apPage[i] = 0;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
assert( (writeOnly==0 || writeOnly==1) && BTCF_WriteFlag==1 );
|
||||
if( pBtree ){
|
||||
sqlite3BtreeEnter(pBtree);
|
||||
for(p=pBtree->pBt->pCursor; p; p=p->pNext){
|
||||
int i;
|
||||
if( writeOnly && (p->curFlags & BTCF_WriteFlag)==0 ){
|
||||
if( p->eState==CURSOR_VALID ){
|
||||
rc = saveCursorPosition(p);
|
||||
if( rc!=SQLITE_OK ){
|
||||
(void)sqlite3BtreeTripAllCursors(pBtree, rc, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
sqlite3BtreeClearCursor(p);
|
||||
p->eState = CURSOR_FAULT;
|
||||
p->skipNext = errCode;
|
||||
}
|
||||
for(i=0; i<=p->iPage; i++){
|
||||
releasePage(p->apPage[i]);
|
||||
p->apPage[i] = 0;
|
||||
}
|
||||
}
|
||||
sqlite3BtreeLeave(pBtree);
|
||||
}
|
||||
sqlite3BtreeLeave(pBtree);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Rollback the transaction in progress. All cursors will be
|
||||
** invalided by this operation. Any attempt to use a cursor
|
||||
** that was open at the beginning of this operation will result
|
||||
** in an error.
|
||||
** Rollback the transaction in progress.
|
||||
**
|
||||
** If tripCode is not SQLITE_OK then cursors will be invalidated (tripped).
|
||||
** Only write cursors are tripped if writeOnly is true but all cursors are
|
||||
** tripped if writeOnly is false. Any attempt to use
|
||||
** a tripped cursor will result in an error.
|
||||
**
|
||||
** This will release the write lock on the database file. If there
|
||||
** are no active cursors, it also releases the read lock.
|
||||
*/
|
||||
SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p, int tripCode){
|
||||
SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p, int tripCode, int writeOnly){
|
||||
int rc;
|
||||
BtShared *pBt = p->pBt;
|
||||
MemPage *pPage1;
|
||||
|
||||
assert( writeOnly==1 || writeOnly==0 );
|
||||
assert( tripCode==SQLITE_ABORT_ROLLBACK || tripCode==SQLITE_OK );
|
||||
sqlite3BtreeEnter(p);
|
||||
if( tripCode==SQLITE_OK ){
|
||||
rc = tripCode = saveAllCursors(pBt, 0, 0);
|
||||
if( rc ) writeOnly = 0;
|
||||
}else{
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
if( tripCode ){
|
||||
sqlite3BtreeTripAllCursors(p, tripCode);
|
||||
int rc2 = sqlite3BtreeTripAllCursors(p, tripCode, writeOnly);
|
||||
assert( rc==SQLITE_OK || (writeOnly==0 && rc2==SQLITE_OK) );
|
||||
if( rc2!=SQLITE_OK ) rc = rc2;
|
||||
}
|
||||
btreeIntegrity(p);
|
||||
|
||||
|
@ -56036,13 +56077,9 @@ SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor *pCur){
|
|||
*/
|
||||
SQLITE_PRIVATE int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
|
||||
if( pCur->eState!=CURSOR_VALID ){
|
||||
*pSize = 0;
|
||||
}else{
|
||||
getCellInfo(pCur);
|
||||
*pSize = pCur->info.nKey;
|
||||
}
|
||||
assert( pCur->eState==CURSOR_VALID );
|
||||
getCellInfo(pCur);
|
||||
*pSize = pCur->info.nKey;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
@ -61466,7 +61503,7 @@ SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
|
|||
}
|
||||
|
||||
/* If a transaction is still open on the Btree, roll it back. */
|
||||
sqlite3BtreeRollback(p->pDest, SQLITE_OK);
|
||||
sqlite3BtreeRollback(p->pDest, SQLITE_OK, 0);
|
||||
|
||||
/* Set the error code of the destination database handle. */
|
||||
rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc;
|
||||
|
@ -71304,7 +71341,7 @@ case OP_Column: {
|
|||
pC->payloadSize = pC->szRow = avail = pReg->n;
|
||||
pC->aRow = (u8*)pReg->z;
|
||||
}else{
|
||||
MemSetTypeFlag(pDest, MEM_Null);
|
||||
sqlite3VdbeMemSetNull(pDest);
|
||||
goto op_column_out;
|
||||
}
|
||||
}else{
|
||||
|
@ -71828,11 +71865,18 @@ case OP_Savepoint: {
|
|||
db->isTransactionSavepoint = 0;
|
||||
rc = p->rc;
|
||||
}else{
|
||||
int isSchemaChange;
|
||||
iSavepoint = db->nSavepoint - iSavepoint - 1;
|
||||
if( p1==SAVEPOINT_ROLLBACK ){
|
||||
isSchemaChange = (db->flags & SQLITE_InternChanges)!=0;
|
||||
for(ii=0; ii<db->nDb; ii++){
|
||||
sqlite3BtreeTripAllCursors(db->aDb[ii].pBt, SQLITE_ABORT);
|
||||
rc = sqlite3BtreeTripAllCursors(db->aDb[ii].pBt,
|
||||
SQLITE_ABORT_ROLLBACK,
|
||||
isSchemaChange==0);
|
||||
if( rc!=SQLITE_OK ) goto abort_due_to_error;
|
||||
}
|
||||
}else{
|
||||
isSchemaChange = 0;
|
||||
}
|
||||
for(ii=0; ii<db->nDb; ii++){
|
||||
rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint);
|
||||
|
@ -71840,7 +71884,7 @@ case OP_Savepoint: {
|
|||
goto abort_due_to_error;
|
||||
}
|
||||
}
|
||||
if( p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
|
||||
if( isSchemaChange ){
|
||||
sqlite3ExpirePreparedStatements(db);
|
||||
sqlite3ResetAllSchemasOfConnection(db);
|
||||
db->flags = (db->flags | SQLITE_InternChanges);
|
||||
|
@ -72237,7 +72281,7 @@ case OP_OpenWrite: {
|
|||
|| p->readOnly==0 );
|
||||
|
||||
if( p->expired ){
|
||||
rc = SQLITE_ABORT;
|
||||
rc = SQLITE_ABORT_ROLLBACK;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -73404,6 +73448,10 @@ case OP_Rowid: { /* out2-prerelease */
|
|||
assert( pC->pCursor!=0 );
|
||||
rc = sqlite3VdbeCursorRestore(pC);
|
||||
if( rc ) goto abort_due_to_error;
|
||||
if( pC->nullRow ){
|
||||
pOut->flags = MEM_Null;
|
||||
break;
|
||||
}
|
||||
rc = sqlite3BtreeKeySize(pC->pCursor, &v);
|
||||
assert( rc==SQLITE_OK ); /* Always so because of CursorRestore() above */
|
||||
}
|
||||
|
@ -82435,7 +82483,6 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
|
|||
assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
|
||||
pSelect->iLimit = 0;
|
||||
testcase( pSelect->selFlags & SF_Distinct );
|
||||
pSelect->selFlags &= ~SF_Distinct;
|
||||
testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
|
||||
if( sqlite3Select(pParse, pSelect, &dest) ){
|
||||
sqlite3KeyInfoUnref(pKeyInfo);
|
||||
|
@ -125927,13 +125974,15 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
|
|||
|
||||
/*
|
||||
** Rollback all database files. If tripCode is not SQLITE_OK, then
|
||||
** any open cursors are invalidated ("tripped" - as in "tripping a circuit
|
||||
** any write cursors are invalidated ("tripped" - as in "tripping a circuit
|
||||
** breaker") and made to return tripCode if there are any further
|
||||
** attempts to use that cursor.
|
||||
** attempts to use that cursor. Read cursors remain open and valid
|
||||
** but are "saved" in case the table pages are moved around.
|
||||
*/
|
||||
SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){
|
||||
int i;
|
||||
int inTrans = 0;
|
||||
int schemaChange;
|
||||
assert( sqlite3_mutex_held(db->mutex) );
|
||||
sqlite3BeginBenignMalloc();
|
||||
|
||||
|
@ -125944,6 +125993,7 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){
|
|||
** the database rollback and schema reset, which can cause false
|
||||
** corruption reports in some cases. */
|
||||
sqlite3BtreeEnterAll(db);
|
||||
schemaChange = (db->flags & SQLITE_InternChanges)!=0 && db->init.busy==0;
|
||||
|
||||
for(i=0; i<db->nDb; i++){
|
||||
Btree *p = db->aDb[i].pBt;
|
||||
|
@ -125951,7 +126001,7 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){
|
|||
if( sqlite3BtreeIsInTrans(p) ){
|
||||
inTrans = 1;
|
||||
}
|
||||
sqlite3BtreeRollback(p, tripCode);
|
||||
sqlite3BtreeRollback(p, tripCode, !schemaChange);
|
||||
}
|
||||
}
|
||||
sqlite3VtabRollback(db);
|
||||
|
|
|
@ -107,9 +107,9 @@ extern "C" {
|
|||
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
||||
** [sqlite_version()] and [sqlite_source_id()].
|
||||
*/
|
||||
#define SQLITE_VERSION "3.8.7.1"
|
||||
#define SQLITE_VERSION "3.8.7.2"
|
||||
#define SQLITE_VERSION_NUMBER 3008007
|
||||
#define SQLITE_SOURCE_ID "2014-10-29 13:59:56 3b7b72c4685aa5cf5e675c2c47ebec10d9704221"
|
||||
#define SQLITE_SOURCE_ID "2014-11-18 20:57:56 2ab564bf9655b7c7b97ab85cafc8a48329b27f93"
|
||||
|
||||
/*
|
||||
** CAPI3REF: Run-Time Library Version Numbers
|
||||
|
|
|
@ -2533,5 +2533,43 @@ Navigator::GetUserAgent(nsPIDOMWindow* aWindow, nsIURI* aURI,
|
|||
return siteSpecificUA->GetUserAgentForURIAndWindow(aURI, aWindow, aUserAgent);
|
||||
}
|
||||
|
||||
#ifdef MOZ_EME
|
||||
already_AddRefed<Promise>
|
||||
Navigator::RequestMediaKeySystemAccess(const nsAString& aKeySystem,
|
||||
const Optional<Sequence<MediaKeySystemOptions>>& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
|
||||
nsRefPtr<Promise> p = Promise::Create(go, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aKeySystem.IsEmpty() ||
|
||||
(aOptions.WasPassed() && aOptions.Value().IsEmpty())) {
|
||||
p->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
||||
return p.forget();
|
||||
}
|
||||
|
||||
if (!MediaKeySystemAccess::IsKeySystemSupported(aKeySystem)) {
|
||||
p->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return p.forget();
|
||||
}
|
||||
|
||||
// TODO: Wait (async) until the CDM is downloaded, if it's not already.
|
||||
|
||||
if (!aOptions.WasPassed() ||
|
||||
MediaKeySystemAccess::IsSupported(aKeySystem, aOptions.Value())) {
|
||||
nsRefPtr<MediaKeySystemAccess> access(new MediaKeySystemAccess(mWindow, aKeySystem));
|
||||
p->MaybeResolve(access);
|
||||
return p.forget();
|
||||
}
|
||||
|
||||
p->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
|
||||
return p.forget();
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
#include "nsInterfaceHashtable.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
#ifdef MOZ_EME
|
||||
#include "mozilla/dom/MediaKeySystemAccess.h"
|
||||
#endif
|
||||
|
||||
class nsPluginArray;
|
||||
class nsMimeTypeArray;
|
||||
|
@ -316,6 +319,13 @@ public:
|
|||
|
||||
virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
|
||||
|
||||
#ifdef MOZ_EME
|
||||
already_AddRefed<Promise>
|
||||
RequestMediaKeySystemAccess(const nsAString& aKeySystem,
|
||||
const Optional<Sequence<MediaKeySystemOptions>>& aOptions,
|
||||
ErrorResult& aRv);
|
||||
#endif
|
||||
|
||||
private:
|
||||
virtual ~Navigator();
|
||||
|
||||
|
|
|
@ -108,7 +108,6 @@
|
|||
#include "FMRadio.h"
|
||||
#endif
|
||||
|
||||
#include "nsIDOMGlobalObjectConstructor.h"
|
||||
#include "nsDebug.h"
|
||||
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
|
@ -1351,65 +1350,6 @@ BaseStubConstructor(nsIWeakReference* aWeakOwner,
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMGlobalObjectConstructor> constructor(do_QueryInterface(native));
|
||||
if (constructor) {
|
||||
// Initialize object using the current inner window, but only if
|
||||
// the caller can access it.
|
||||
nsCOMPtr<nsPIDOMWindow> owner = do_QueryReferent(aWeakOwner);
|
||||
nsPIDOMWindow* outerWindow = owner ? owner->GetOuterWindow() : nullptr;
|
||||
nsPIDOMWindow* currentInner =
|
||||
outerWindow ? outerWindow->GetCurrentInnerWindow() : nullptr;
|
||||
if (!currentInner ||
|
||||
(owner != currentInner &&
|
||||
!nsContentUtils::CanCallerAccess(currentInner))) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS = do_QueryInterface(native);
|
||||
|
||||
JS::Rooted<JSObject*> thisObject(cx, wrappedJS->GetJSObject());
|
||||
if (!thisObject) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
JSAutoCompartment ac(cx, thisObject);
|
||||
|
||||
JS::Rooted<JS::Value> funval(cx);
|
||||
if (!JS_GetProperty(cx, thisObject, "constructor", &funval) ||
|
||||
!funval.isObject()) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
// Check if the object is even callable.
|
||||
NS_ENSURE_STATE(JS::IsCallable(&funval.toObject()));
|
||||
{
|
||||
// wrap parameters in the target compartment
|
||||
// we also pass in the calling window as the first argument
|
||||
unsigned argc = args.length() + 1;
|
||||
JS::AutoValueVector argv(cx);
|
||||
if (!argv.resize(argc)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> currentWin(do_GetInterface(currentInner));
|
||||
rv = WrapNative(cx, currentWin, &NS_GET_IID(nsIDOMWindow),
|
||||
true, argv[0]);
|
||||
|
||||
for (size_t i = 1; i < argc; ++i) {
|
||||
argv[i].set(args[i - 1]);
|
||||
if (!JS_WrapValue(cx, argv[i]))
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> frval(cx);
|
||||
bool ret = JS_CallFunctionValue(cx, thisObject, funval, argv, &frval);
|
||||
|
||||
if (!ret) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
js::AssertSameCompartment(cx, obj);
|
||||
return WrapNative(cx, native, true, args.rval());
|
||||
}
|
||||
|
|
|
@ -866,7 +866,7 @@ nsDOMWindowUtils::SendPointerEventCommon(const nsAString& aType,
|
|||
event.height = aHeight;
|
||||
event.tiltX = aTiltX;
|
||||
event.tiltY = aTiltY;
|
||||
event.isPrimary = aIsPrimary;
|
||||
event.isPrimary = (nsIDOMMouseEvent::MOZ_SOURCE_MOUSE == aInputSourceArg) ? true : aIsPrimary;
|
||||
event.clickCount = aClickCount;
|
||||
event.time = PR_IntervalNow();
|
||||
event.mFlags.mIsSynthesizedForTests = aOptionalArgCount >= 10 ? aIsSynthesized : true;
|
||||
|
|
|
@ -194,6 +194,7 @@
|
|||
|
||||
#include "mozilla/dom/SelectionChangeEvent.h"
|
||||
|
||||
#include "mozilla/AddonPathService.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "nsLocation.h"
|
||||
|
@ -651,7 +652,7 @@ public:
|
|||
JS::AutoIdVector &props) const MOZ_OVERRIDE;
|
||||
virtual bool iterate(JSContext *cx, JS::Handle<JSObject*> proxy,
|
||||
unsigned flags,
|
||||
JS::MutableHandle<JS::Value> vp) const MOZ_OVERRIDE;
|
||||
JS::MutableHandle<JSObject*> objp) const MOZ_OVERRIDE;
|
||||
virtual const char *className(JSContext *cx,
|
||||
JS::Handle<JSObject*> wrapper) const MOZ_OVERRIDE;
|
||||
|
||||
|
@ -942,14 +943,13 @@ nsOuterWindowProxy::getEnumerablePropertyKeys(JSContext *cx, JS::Handle<JSObject
|
|||
return js::AppendUnique(cx, props, innerProps);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
nsOuterWindowProxy::iterate(JSContext *cx, JS::Handle<JSObject*> proxy,
|
||||
unsigned flags, JS::MutableHandle<JS::Value> vp) const
|
||||
unsigned flags, JS::MutableHandle<JSObject*> objp) const
|
||||
{
|
||||
// BaseProxyHandler::iterate seems to do what we want here: fall
|
||||
// back on the property names returned from keys() and enumerate().
|
||||
return js::BaseProxyHandler::iterate(cx, proxy, flags, vp);
|
||||
return js::BaseProxyHandler::iterate(cx, proxy, flags, objp);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -2270,6 +2270,14 @@ CreateNativeGlobalForInner(JSContext* aCx,
|
|||
top = aNewInner->GetTop();
|
||||
}
|
||||
JS::CompartmentOptions options;
|
||||
|
||||
// Sometimes add-ons load their own XUL windows, either as separate top-level
|
||||
// windows or inside a browser element. In such cases we want to tag the
|
||||
// window's compartment with the add-on ID. See bug 1092156.
|
||||
if (nsContentUtils::IsSystemPrincipal(aPrincipal)) {
|
||||
options.setAddonId(MapURIToAddonID(aURI));
|
||||
}
|
||||
|
||||
if (top) {
|
||||
if (top->GetGlobalJSObject()) {
|
||||
options.setSameZoneAs(top->GetGlobalJSObject());
|
||||
|
|
|
@ -253,11 +253,7 @@ nsJSUtils::EvaluateString(JSContext* aCx,
|
|||
ok = false;
|
||||
}
|
||||
} else if (ok) {
|
||||
if (!aCompileOptions.noScriptRval) {
|
||||
ok = JS::Evaluate(aCx, scopeChain, aCompileOptions, aSrcBuf, aRetValue);
|
||||
} else {
|
||||
ok = JS::Evaluate(aCx, scopeChain, aCompileOptions, aSrcBuf);
|
||||
}
|
||||
ok = JS::Evaluate(aCx, scopeChain, aCompileOptions, aSrcBuf, aRetValue);
|
||||
}
|
||||
|
||||
if (ok && aEvaluateOptions.coerceToString && !aRetValue.isUndefined()) {
|
||||
|
|
|
@ -1735,6 +1735,12 @@ CanvasRenderingContext2D::SetTransform(double m11, double m12,
|
|||
mTarget->SetTransform(matrix);
|
||||
}
|
||||
|
||||
void
|
||||
CanvasRenderingContext2D::ResetTransform(ErrorResult& error)
|
||||
{
|
||||
SetTransform(1.0, 0.0, 0.0, 1.0, 0.0, 0.0, error);
|
||||
}
|
||||
|
||||
static void
|
||||
MatrixToJSObject(JSContext* cx, const Matrix& matrix,
|
||||
JS::MutableHandle<JSObject*> result, ErrorResult& error)
|
||||
|
|
|
@ -148,6 +148,7 @@ public:
|
|||
double dy, mozilla::ErrorResult& error);
|
||||
void SetTransform(double m11, double m12, double m21, double m22, double dx,
|
||||
double dy, mozilla::ErrorResult& error);
|
||||
void ResetTransform(mozilla::ErrorResult& error);
|
||||
|
||||
double GlobalAlpha()
|
||||
{
|
||||
|
|
|
@ -19182,6 +19182,7 @@ isPixel(ctx, 50,25, 0,255,0,255, 0);
|
|||
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<!-- [[[ test_2d.transformation.transform.multiply.html ]]] -->
|
||||
|
@ -19558,6 +19559,9 @@ if (ctx.transform) { // (avoid spurious failures, since the aim here is not to t
|
|||
if (ctx.setTransform) {
|
||||
ok(ctx.setTransform(1, 0, 0, 1, 0, 0) === undefined, "ctx.setTransform(1, 0, 0, 1, 0, 0) === undefined");
|
||||
}
|
||||
if (ctx.resetTransform) {
|
||||
ok(ctx.resetTransform() === undefined, "ctx.resetTransform() === undefined");
|
||||
}
|
||||
ok(ctx.clearRect(0, 0, 0, 0) === undefined, "ctx.clearRect(0, 0, 0, 0) === undefined");
|
||||
ok(ctx.fillRect(0, 0, 0, 0) === undefined, "ctx.fillRect(0, 0, 0, 0) === undefined");
|
||||
ok(ctx.strokeRect(0, 0, 0, 0) === undefined, "ctx.strokeRect(0, 0, 0, 0) === undefined");
|
||||
|
@ -21552,6 +21556,31 @@ function test_opaque() {
|
|||
}
|
||||
</script>
|
||||
|
||||
<p>Canvas test: 2d.transformation.transform.identity</p>
|
||||
<!-- Testing: resetTransform() changes to the identity matrix -->
|
||||
<canvas id="c689" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
|
||||
<script>
|
||||
|
||||
|
||||
function test_2d_transformation_reset_transform() {
|
||||
|
||||
var canvas = document.getElementById('c689');
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
ctx.fillStyle = '#f00';
|
||||
ctx.fillRect(0, 0, 100, 50);
|
||||
|
||||
ctx.setTransform(0.1, 0.0, 0.0, 0.1, 80.0, 30.0);
|
||||
ctx.resetTransform();
|
||||
ctx.fillStyle = '#0f0';
|
||||
ctx.fillRect(0, 0, 100, 50);
|
||||
isPixel(ctx, 50,25, 0,255,0,255, 0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<script>
|
||||
|
||||
function asyncTestsDone() {
|
||||
|
@ -24844,6 +24873,11 @@ try {
|
|||
throw e;
|
||||
ok(false, "unexpected exception thrown in: test_opaque");
|
||||
}
|
||||
try {
|
||||
test_2d_transformation_reset_transform();
|
||||
} catch (e) {
|
||||
ok(false, "unexpected exception thrown in: test_2d_transformation_reset_transform");
|
||||
}
|
||||
try {
|
||||
// run this test last since it replaces the getContext method
|
||||
test_type_replace();
|
||||
|
|
|
@ -1240,8 +1240,14 @@ BackgroundDatabaseChild::RecvPBackgroundIDBVersionChangeTransactionConstructor(
|
|||
|
||||
auto actor = static_cast<BackgroundVersionChangeTransactionChild*>(aActor);
|
||||
|
||||
nsRefPtr<IDBOpenDBRequest> request = mOpenRequestActor->GetOpenDBRequest();
|
||||
MOZ_ASSERT(request);
|
||||
|
||||
nsRefPtr<IDBTransaction> transaction =
|
||||
IDBTransaction::CreateVersionChange(mDatabase, actor, aNextObjectStoreId,
|
||||
IDBTransaction::CreateVersionChange(mDatabase,
|
||||
actor,
|
||||
request,
|
||||
aNextObjectStoreId,
|
||||
aNextIndexId);
|
||||
if (NS_WARN_IF(!transaction)) {
|
||||
return false;
|
||||
|
@ -1253,9 +1259,6 @@ BackgroundDatabaseChild::RecvPBackgroundIDBVersionChangeTransactionConstructor(
|
|||
|
||||
mDatabase->EnterSetVersionTransaction(aRequestedVersion);
|
||||
|
||||
nsRefPtr<IDBOpenDBRequest> request = mOpenRequestActor->GetOpenDBRequest();
|
||||
MOZ_ASSERT(request);
|
||||
|
||||
request->SetTransaction(transaction);
|
||||
|
||||
nsCOMPtr<nsIDOMEvent> upgradeNeededEvent =
|
||||
|
@ -1316,7 +1319,7 @@ BackgroundDatabaseChild::RecvVersionChange(const uint64_t& aOldVersion,
|
|||
if (shouldAbortAndClose) {
|
||||
// Invalidate() doesn't close the database in the parent, so we have
|
||||
// to call Close() and AbortTransactions() manually.
|
||||
mDatabase->AbortTransactions();
|
||||
mDatabase->AbortTransactions(/* aShouldWarn */ false);
|
||||
mDatabase->Close();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -39,9 +39,12 @@
|
|||
#include "mozilla/ipc/InputStreamParams.h"
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIConsoleService.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "ProfilerHelpers.h"
|
||||
|
@ -314,7 +317,7 @@ IDBDatabase::InvalidateInternal()
|
|||
AssertIsOnOwningThread();
|
||||
|
||||
InvalidateMutableFiles();
|
||||
AbortTransactions();
|
||||
AbortTransactions(/* aShouldWarn */ true);
|
||||
|
||||
CloseInternal();
|
||||
}
|
||||
|
@ -751,7 +754,7 @@ IDBDatabase::UnregisterTransaction(IDBTransaction* aTransaction)
|
|||
}
|
||||
|
||||
void
|
||||
IDBDatabase::AbortTransactions()
|
||||
IDBDatabase::AbortTransactions(bool aShouldWarn)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
|
@ -759,27 +762,31 @@ IDBDatabase::AbortTransactions()
|
|||
{
|
||||
public:
|
||||
static void
|
||||
AbortTransactions(nsTHashtable<nsPtrHashKey<IDBTransaction>>& aTable)
|
||||
AbortTransactions(nsTHashtable<nsPtrHashKey<IDBTransaction>>& aTable,
|
||||
nsTArray<nsRefPtr<IDBTransaction>>& aAbortedTransactions)
|
||||
{
|
||||
const uint32_t count = aTable.Count();
|
||||
if (!count) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsTArray<nsRefPtr<IDBTransaction>> transactions;
|
||||
nsAutoTArray<nsRefPtr<IDBTransaction>, 20> transactions;
|
||||
transactions.SetCapacity(count);
|
||||
|
||||
aTable.EnumerateEntries(Collect, &transactions);
|
||||
|
||||
MOZ_ASSERT(transactions.Length() == count);
|
||||
|
||||
IDB_REPORT_INTERNAL_ERR();
|
||||
|
||||
for (uint32_t index = 0; index < count; index++) {
|
||||
nsRefPtr<IDBTransaction> transaction = transactions[index].forget();
|
||||
nsRefPtr<IDBTransaction> transaction = Move(transactions[index]);
|
||||
MOZ_ASSERT(transaction);
|
||||
|
||||
transaction->Abort(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
// We only care about warning for write transactions.
|
||||
if (transaction->GetMode() != IDBTransaction::READ_ONLY) {
|
||||
aAbortedTransactions.AppendElement(Move(transaction));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -798,7 +805,25 @@ IDBDatabase::AbortTransactions()
|
|||
}
|
||||
};
|
||||
|
||||
Helper::AbortTransactions(mTransactions);
|
||||
nsAutoTArray<nsRefPtr<IDBTransaction>, 5> abortedTransactions;
|
||||
Helper::AbortTransactions(mTransactions, abortedTransactions);
|
||||
|
||||
if (aShouldWarn && !abortedTransactions.IsEmpty()) {
|
||||
static const char kWarningMessage[] = "IndexedDBTransactionAbortNavigation";
|
||||
|
||||
for (uint32_t count = abortedTransactions.Length(), index = 0;
|
||||
index < count;
|
||||
index++) {
|
||||
nsRefPtr<IDBTransaction>& transaction = abortedTransactions[index];
|
||||
MOZ_ASSERT(transaction);
|
||||
|
||||
nsString filename;
|
||||
uint32_t lineNo;
|
||||
transaction->GetCallerLocation(filename, &lineNo);
|
||||
|
||||
LogWarning(kWarningMessage, filename, lineNo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PBackgroundIDBDatabaseFileChild*
|
||||
|
@ -1155,6 +1180,65 @@ IDBDatabase::Invalidate()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
IDBDatabase::LogWarning(const char* aMessageName,
|
||||
const nsAString& aFilename,
|
||||
uint32_t aLineNumber)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aMessageName);
|
||||
|
||||
// For now this is main-thread only.
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsXPIDLString localizedMessage;
|
||||
if (NS_WARN_IF(NS_FAILED(
|
||||
nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
||||
aMessageName,
|
||||
localizedMessage)))) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoCString category;
|
||||
if (mFactory->IsChrome()) {
|
||||
category.AssignLiteral("chrome ");
|
||||
} else {
|
||||
category.AssignLiteral("content ");
|
||||
}
|
||||
category.AppendLiteral("javascript");
|
||||
|
||||
nsCOMPtr<nsIConsoleService> consoleService =
|
||||
do_GetService(NS_CONSOLESERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(consoleService);
|
||||
|
||||
nsCOMPtr<nsIScriptError> scriptError =
|
||||
do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
|
||||
MOZ_ASSERT(consoleService);
|
||||
|
||||
if (mFactory->GetParentObject()) {
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
|
||||
scriptError->InitWithWindowID(localizedMessage,
|
||||
aFilename,
|
||||
/* aSourceLine */ EmptyString(),
|
||||
aLineNumber,
|
||||
/* aColumnNumber */ 0,
|
||||
nsIScriptError::warningFlag,
|
||||
category,
|
||||
mFactory->InnerWindowID())));
|
||||
} else {
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
|
||||
scriptError->Init(localizedMessage,
|
||||
aFilename,
|
||||
/* aSourceLine */ EmptyString(),
|
||||
aLineNumber,
|
||||
/* aColumnNumber */ 0,
|
||||
nsIScriptError::warningFlag,
|
||||
category.get())));
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(consoleService->LogMessage(scriptError)));
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(IDBDatabase, IDBWrapperCache)
|
||||
NS_IMPL_RELEASE_INHERITED(IDBDatabase, IDBWrapperCache)
|
||||
|
||||
|
|
|
@ -171,7 +171,7 @@ public:
|
|||
UnregisterTransaction(IDBTransaction* aTransaction);
|
||||
|
||||
void
|
||||
AbortTransactions();
|
||||
AbortTransactions(bool aShouldWarn);
|
||||
|
||||
PBackgroundIDBDatabaseFileChild*
|
||||
GetOrCreateFileActorForBlob(File* aBlob);
|
||||
|
@ -299,6 +299,11 @@ private:
|
|||
|
||||
void
|
||||
InvalidateMutableFiles();
|
||||
|
||||
void
|
||||
LogWarning(const char* aMessageName,
|
||||
const nsAString& aFilename,
|
||||
uint32_t aLineNumber);
|
||||
};
|
||||
|
||||
} // namespace indexedDB
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include "ActorsChild.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "nsContentUtils.h" // For IsCallerChrome assertions.
|
||||
#include "nsContentUtils.h" // For assertions.
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -110,6 +110,7 @@ struct IDBFactory::PendingRequestInfo
|
|||
IDBFactory::IDBFactory()
|
||||
: mOwningObject(nullptr)
|
||||
, mBackgroundActor(nullptr)
|
||||
, mInnerWindowID(0)
|
||||
, mBackgroundActorFailed(false)
|
||||
, mPrivateBrowsingMode(false)
|
||||
{
|
||||
|
@ -183,6 +184,7 @@ IDBFactory::CreateForWindow(nsPIDOMWindow* aWindow,
|
|||
factory->mPrincipalInfo = Move(principalInfo);
|
||||
factory->mWindow = aWindow;
|
||||
factory->mTabChild = TabChild::GetFrom(aWindow);
|
||||
factory->mInnerWindowID = aWindow->WindowID();
|
||||
factory->mPrivateBrowsingMode = privateBrowsingMode;
|
||||
|
||||
factory.forget(aFactory);
|
||||
|
@ -285,6 +287,15 @@ IDBFactory::AssertIsOnOwningThread() const
|
|||
|
||||
#endif // DEBUG
|
||||
|
||||
bool
|
||||
IDBFactory::IsChrome() const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(mPrincipalInfo);
|
||||
|
||||
return mPrincipalInfo->type() == PrincipalInfo::TSystemPrincipalInfo;
|
||||
}
|
||||
|
||||
void
|
||||
IDBFactory::SetBackgroundActor(BackgroundFactoryChild* aBackgroundActor)
|
||||
{
|
||||
|
@ -524,19 +535,20 @@ IDBFactory::OpenInternal(nsIPrincipal* aPrincipal,
|
|||
nsRefPtr<IDBOpenDBRequest> request;
|
||||
|
||||
if (mWindow) {
|
||||
if (NS_WARN_IF(!autoJS.Init(mWindow))) {
|
||||
AutoJSContext cx;
|
||||
if (NS_WARN_IF(!autoJS.Init(mWindow, cx))) {
|
||||
IDB_REPORT_INTERNAL_ERR();
|
||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> scriptOwner(autoJS.cx(),
|
||||
JS::Rooted<JSObject*> scriptOwner(cx,
|
||||
static_cast<nsGlobalWindow*>(mWindow.get())->FastGetGlobalJSObject());
|
||||
MOZ_ASSERT(scriptOwner);
|
||||
|
||||
request = IDBOpenDBRequest::CreateForWindow(this, mWindow, scriptOwner);
|
||||
} else {
|
||||
autoJS.Init();
|
||||
autoJS.Init(mOwningObject.get());
|
||||
JS::Rooted<JSObject*> scriptOwner(autoJS.cx(), mOwningObject);
|
||||
|
||||
request = IDBOpenDBRequest::CreateForJS(this, scriptOwner);
|
||||
|
|
|
@ -73,6 +73,8 @@ class IDBFactory MOZ_FINAL
|
|||
PRThread* mOwningThread;
|
||||
#endif
|
||||
|
||||
uint64_t mInnerWindowID;
|
||||
|
||||
bool mBackgroundActorFailed;
|
||||
bool mPrivateBrowsingMode;
|
||||
|
||||
|
@ -130,6 +132,17 @@ public:
|
|||
return mPrincipalInfo;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
InnerWindowID() const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
return mInnerWindowID;
|
||||
}
|
||||
|
||||
bool
|
||||
IsChrome() const;
|
||||
|
||||
already_AddRefed<IDBOpenDBRequest>
|
||||
Open(const nsAString& aName,
|
||||
uint64_t aVersion,
|
||||
|
|
|
@ -99,12 +99,11 @@ IDBRequest::Create(IDBDatabase* aDatabase,
|
|||
aDatabase->AssertIsOnOwningThread();
|
||||
|
||||
nsRefPtr<IDBRequest> request = new IDBRequest(aDatabase);
|
||||
CaptureCaller(request->mFilename, &request->mLineNo);
|
||||
|
||||
request->mTransaction = aTransaction;
|
||||
request->SetScriptOwner(aDatabase->GetScriptOwner());
|
||||
|
||||
request->CaptureCaller();
|
||||
|
||||
return request.forget();
|
||||
}
|
||||
|
||||
|
@ -140,6 +139,26 @@ IDBRequest::Create(IDBIndex* aSourceAsIndex,
|
|||
return request.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
IDBRequest::CaptureCaller(nsAString& aFilename, uint32_t* aLineNo)
|
||||
{
|
||||
MOZ_ASSERT(aFilename.IsEmpty());
|
||||
MOZ_ASSERT(aLineNo);
|
||||
|
||||
ThreadsafeAutoJSContext cx;
|
||||
|
||||
const char* filename = nullptr;
|
||||
uint32_t lineNo = 0;
|
||||
if (!nsJSUtils::GetCallingLocation(cx, &filename, &lineNo)) {
|
||||
*aLineNo = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
aFilename.Assign(NS_ConvertUTF8toUTF16(filename));
|
||||
*aLineNo = lineNo;
|
||||
}
|
||||
|
||||
void
|
||||
IDBRequest::GetSource(
|
||||
Nullable<OwningIDBObjectStoreOrIDBIndexOrIDBCursor>& aSource) const
|
||||
|
@ -227,25 +246,13 @@ IDBRequest::GetErrorCode() const
|
|||
#endif // DEBUG
|
||||
|
||||
void
|
||||
IDBRequest::CaptureCaller()
|
||||
IDBRequest::GetCallerLocation(nsAString& aFilename, uint32_t* aLineNo) const
|
||||
{
|
||||
AutoJSContext cx;
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aLineNo);
|
||||
|
||||
const char* filename = nullptr;
|
||||
uint32_t lineNo = 0;
|
||||
if (!nsJSUtils::GetCallingLocation(cx, &filename, &lineNo)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mFilename.Assign(NS_ConvertUTF8toUTF16(filename));
|
||||
mLineNo = lineNo;
|
||||
}
|
||||
|
||||
void
|
||||
IDBRequest::FillScriptErrorEvent(ErrorEventInit& aEventInit) const
|
||||
{
|
||||
aEventInit.mLineno = mLineNo;
|
||||
aEventInit.mFilename = mFilename;
|
||||
aFilename = mFilename;
|
||||
*aLineNo = mLineNo;
|
||||
}
|
||||
|
||||
IDBRequestReadyState
|
||||
|
@ -301,7 +308,6 @@ IDBRequest::SetResultCallback(ResultCallback* aCallback)
|
|||
|
||||
// See if our window is still valid.
|
||||
if (NS_WARN_IF(NS_FAILED(CheckInnerWindowCorrectness()))) {
|
||||
IDB_REPORT_INTERNAL_ERR();
|
||||
SetError(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
return;
|
||||
}
|
||||
|
@ -424,7 +430,7 @@ IDBOpenDBRequest::CreateForWindow(IDBFactory* aFactory,
|
|||
MOZ_ASSERT(aScriptOwner);
|
||||
|
||||
nsRefPtr<IDBOpenDBRequest> request = new IDBOpenDBRequest(aFactory, aOwner);
|
||||
request->CaptureCaller();
|
||||
CaptureCaller(request->mFilename, &request->mLineNo);
|
||||
|
||||
request->SetScriptOwner(aScriptOwner);
|
||||
|
||||
|
@ -441,7 +447,7 @@ IDBOpenDBRequest::CreateForJS(IDBFactory* aFactory,
|
|||
MOZ_ASSERT(aScriptOwner);
|
||||
|
||||
nsRefPtr<IDBOpenDBRequest> request = new IDBOpenDBRequest(aFactory, nullptr);
|
||||
request->CaptureCaller();
|
||||
CaptureCaller(request->mFilename, &request->mLineNo);
|
||||
|
||||
request->SetScriptOwner(aScriptOwner);
|
||||
|
||||
|
|
|
@ -81,6 +81,9 @@ public:
|
|||
IDBDatabase* aDatabase,
|
||||
IDBTransaction* aTransaction);
|
||||
|
||||
static void
|
||||
CaptureCaller(nsAString& aFilename, uint32_t* aLineNo);
|
||||
|
||||
// nsIDOMEventTarget
|
||||
virtual nsresult
|
||||
PreHandleEvent(EventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
|
||||
|
@ -114,7 +117,7 @@ public:
|
|||
GetError(ErrorResult& aRv);
|
||||
|
||||
void
|
||||
FillScriptErrorEvent(ErrorEventInit& aEventInit) const;
|
||||
GetCallerLocation(nsAString& aFilename, uint32_t* aLineNo) const;
|
||||
|
||||
bool
|
||||
IsPending() const
|
||||
|
@ -189,9 +192,6 @@ protected:
|
|||
|
||||
void
|
||||
ConstructResult();
|
||||
|
||||
void
|
||||
CaptureCaller();
|
||||
};
|
||||
|
||||
class NS_NO_VTABLE IDBRequest::ResultCallback
|
||||
|
|
|
@ -48,6 +48,7 @@ IDBTransaction::IDBTransaction(IDBDatabase* aDatabase,
|
|||
, mNextIndexId(0)
|
||||
, mAbortCode(NS_OK)
|
||||
, mPendingRequestCount(0)
|
||||
, mLineNo(0)
|
||||
, mReadyState(IDBTransaction::INITIAL)
|
||||
, mMode(aMode)
|
||||
, mCreating(false)
|
||||
|
@ -127,12 +128,14 @@ already_AddRefed<IDBTransaction>
|
|||
IDBTransaction::CreateVersionChange(
|
||||
IDBDatabase* aDatabase,
|
||||
BackgroundVersionChangeTransactionChild* aActor,
|
||||
IDBOpenDBRequest* aOpenRequest,
|
||||
int64_t aNextObjectStoreId,
|
||||
int64_t aNextIndexId)
|
||||
{
|
||||
MOZ_ASSERT(aDatabase);
|
||||
aDatabase->AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aActor);
|
||||
MOZ_ASSERT(aOpenRequest);
|
||||
MOZ_ASSERT(aNextObjectStoreId > 0);
|
||||
MOZ_ASSERT(aNextIndexId > 0);
|
||||
|
||||
|
@ -140,6 +143,8 @@ IDBTransaction::CreateVersionChange(
|
|||
|
||||
nsRefPtr<IDBTransaction> transaction =
|
||||
new IDBTransaction(aDatabase, emptyObjectStoreNames, VERSION_CHANGE);
|
||||
aOpenRequest->GetCallerLocation(transaction->mFilename,
|
||||
&transaction->mLineNo);
|
||||
|
||||
transaction->SetScriptOwner(aDatabase->GetScriptOwner());
|
||||
transaction->mBackgroundActor.mVersionChangeBackgroundActor = aActor;
|
||||
|
@ -175,6 +180,7 @@ IDBTransaction::Create(IDBDatabase* aDatabase,
|
|||
|
||||
nsRefPtr<IDBTransaction> transaction =
|
||||
new IDBTransaction(aDatabase, aObjectStoreNames, aMode);
|
||||
IDBRequest::CaptureCaller(transaction->mFilename, &transaction->mLineNo);
|
||||
|
||||
transaction->SetScriptOwner(aDatabase->GetScriptOwner());
|
||||
|
||||
|
@ -391,6 +397,16 @@ IDBTransaction::IsOpen() const
|
|||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
IDBTransaction::GetCallerLocation(nsAString& aFilename, uint32_t* aLineNo) const
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aLineNo);
|
||||
|
||||
aFilename = mFilename;
|
||||
*aLineNo = mLineNo;
|
||||
}
|
||||
|
||||
already_AddRefed<IDBObjectStore>
|
||||
IDBTransaction::CreateObjectStore(const ObjectStoreSpec& aSpec)
|
||||
{
|
||||
|
|
|
@ -37,6 +37,7 @@ class BackgroundTransactionChild;
|
|||
class BackgroundVersionChangeTransactionChild;
|
||||
class IDBDatabase;
|
||||
class IDBObjectStore;
|
||||
class IDBOpenDBRequest;
|
||||
class IDBRequest;
|
||||
class IndexMetadata;
|
||||
class ObjectStoreSpec;
|
||||
|
@ -94,6 +95,9 @@ private:
|
|||
nsresult mAbortCode;
|
||||
uint32_t mPendingRequestCount;
|
||||
|
||||
nsString mFilename;
|
||||
uint32_t mLineNo;
|
||||
|
||||
ReadyState mReadyState;
|
||||
Mode mMode;
|
||||
|
||||
|
@ -109,6 +113,7 @@ public:
|
|||
static already_AddRefed<IDBTransaction>
|
||||
CreateVersionChange(IDBDatabase* aDatabase,
|
||||
BackgroundVersionChangeTransactionChild* aActor,
|
||||
IDBOpenDBRequest* aOpenRequest,
|
||||
int64_t aNextObjectStoreId,
|
||||
int64_t aNextIndexId);
|
||||
|
||||
|
@ -184,6 +189,9 @@ public:
|
|||
return NS_FAILED(mAbortCode);
|
||||
}
|
||||
|
||||
void
|
||||
GetCallerLocation(nsAString& aFilename, uint32_t* aLineNo) const;
|
||||
|
||||
// 'Get' prefix is to avoid name collisions with the enum
|
||||
Mode
|
||||
GetMode() const
|
||||
|
|
|
@ -366,7 +366,7 @@ IndexedDatabaseManager::FireWindowOnError(nsPIDOMWindow* aOwner,
|
|||
|
||||
ThreadsafeAutoJSContext cx;
|
||||
RootedDictionary<ErrorEventInit> init(cx);
|
||||
request->FillScriptErrorEvent(init);
|
||||
request->GetCallerLocation(init.mFilename, &init.mLineno);
|
||||
|
||||
init.mMessage = errorName;
|
||||
init.mCancelable = true;
|
||||
|
|
|
@ -17,7 +17,6 @@ XPIDL_SOURCES += [
|
|||
'nsIDOMClientRectList.idl',
|
||||
'nsIDOMConstructor.idl',
|
||||
'nsIDOMCrypto.idl',
|
||||
'nsIDOMGlobalObjectConstructor.idl',
|
||||
'nsIDOMGlobalPropertyInitializer.idl',
|
||||
'nsIDOMHistory.idl',
|
||||
'nsIDOMJSWindow.idl',
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "domstubs.idl"
|
||||
|
||||
[scriptable, uuid(cb439c73-0129-4289-a349-c5216e6b912a)]
|
||||
interface nsIDOMGlobalObjectConstructor : nsISupports
|
||||
{
|
||||
/*
|
||||
* JS use only
|
||||
*
|
||||
* The constructor() method will be called with any parameters passed
|
||||
* to the object constructor.
|
||||
* If the JS implementation returns a value, it will be ignored.
|
||||
*/
|
||||
void constructor();
|
||||
};
|
|
@ -209,3 +209,5 @@ KeyNameZoomWarning=KeyboardEvent.key value "Zoom" is obsolete and will be rename
|
|||
KeyNameDeadKeysWarning=KeyboardEvent.key values starting with "Dead" are obsolete and will be merged into just "Dead". For more help https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent.key
|
||||
ImportXULIntoContentWarning=Importing XUL nodes into a content document is deprecated. This functionality may be removed soon.
|
||||
XMLDocumentLoadPrincipalMismatch=Use of document.load forbidden on Documents that come from other Windows. Only the Window in which a Document was created is allowed to call .load on that Document. Preferably, use XMLHttpRequest instead.
|
||||
# LOCALIZATION NOTE: Do not translate "IndexedDB".
|
||||
IndexedDBTransactionAbortNavigation=An IndexedDB transaction that was not yet complete has been aborted due to page navigation.
|
|
@ -335,8 +335,9 @@ IsMP4SupportedType(const nsACString& aType,
|
|||
#ifdef MOZ_OMX_DECODER
|
||||
return false;
|
||||
#else
|
||||
bool haveAAC, haveMP3, haveH264;
|
||||
return Preferences::GetBool("media.fragmented-mp4.exposed", false) &&
|
||||
MP4Decoder::CanHandleMediaType(aType, aCodecs);
|
||||
MP4Decoder::CanHandleMediaType(aType, aCodecs, haveAAC, haveH264, haveMP3);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,7 @@ class TimeRanges;
|
|||
|
||||
class RequestSampleCallback;
|
||||
class MediaDecoderReader;
|
||||
class SharedDecoderManager;
|
||||
|
||||
// Encapsulates the decoding and reading of media data. Reading can either
|
||||
// synchronous and done on the calling "decode" thread, or asynchronous and
|
||||
|
@ -47,6 +48,7 @@ public:
|
|||
// Release media resources they should be released in dormant state
|
||||
// The reader can be made usable again by calling ReadMetadata().
|
||||
virtual void ReleaseMediaResources() {};
|
||||
virtual void SetSharedDecoderManager(SharedDecoderManager* aManager) {}
|
||||
// Breaks reference-counted cycles. Called during shutdown.
|
||||
// WARNING: If you override this, you must call the base implementation
|
||||
// in your override.
|
||||
|
|
|
@ -0,0 +1,212 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/MediaKeySystemAccess.h"
|
||||
#include "mozilla/dom/MediaKeySystemAccessBinding.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsContentTypeParser.h"
|
||||
#ifdef MOZ_FMP4
|
||||
#include "MP4Decoder.h"
|
||||
#endif
|
||||
#ifdef XP_WIN
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
#endif
|
||||
#include "nsContentCID.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "mozIGeckoMediaPluginService.h"
|
||||
#include "VideoUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(MediaKeySystemAccess,
|
||||
mParent)
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaKeySystemAccess)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaKeySystemAccess)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaKeySystemAccess)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
MediaKeySystemAccess::MediaKeySystemAccess(nsPIDOMWindow* aParent,
|
||||
const nsAString& aKeySystem)
|
||||
: mParent(aParent)
|
||||
, mKeySystem(aKeySystem)
|
||||
{
|
||||
}
|
||||
|
||||
MediaKeySystemAccess::~MediaKeySystemAccess()
|
||||
{
|
||||
}
|
||||
|
||||
JSObject*
|
||||
MediaKeySystemAccess::WrapObject(JSContext* aCx)
|
||||
{
|
||||
return MediaKeySystemAccessBinding::Wrap(aCx, this);
|
||||
}
|
||||
|
||||
nsPIDOMWindow*
|
||||
MediaKeySystemAccess::GetParentObject() const
|
||||
{
|
||||
return mParent;
|
||||
}
|
||||
|
||||
void
|
||||
MediaKeySystemAccess::GetKeySystem(nsString& aRetVal) const
|
||||
{
|
||||
aRetVal = mKeySystem;
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
MediaKeySystemAccess::CreateMediaKeys(ErrorResult& aRv)
|
||||
{
|
||||
nsRefPtr<MediaKeys> keys(new MediaKeys(mParent, mKeySystem));
|
||||
return keys->Init(aRv);
|
||||
}
|
||||
|
||||
static bool
|
||||
HaveGMPFor(mozIGeckoMediaPluginService* aGMPService,
|
||||
const nsCString& aKeySystem,
|
||||
const nsCString& aAPI,
|
||||
const nsCString& aTag = EmptyCString())
|
||||
{
|
||||
nsTArray<nsCString> tags;
|
||||
tags.AppendElement(aKeySystem);
|
||||
if (!aTag.IsEmpty()) {
|
||||
tags.AppendElement(aTag);
|
||||
}
|
||||
// Note: EME plugins need a non-null nodeId here, as they must
|
||||
// not be shared across origins.
|
||||
bool hasPlugin = false;
|
||||
if (NS_FAILED(aGMPService->HasPluginForAPI(aAPI,
|
||||
&tags,
|
||||
&hasPlugin))) {
|
||||
return false;
|
||||
}
|
||||
return hasPlugin;
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
MediaKeySystemAccess::IsKeySystemSupported(const nsAString& aKeySystem)
|
||||
{
|
||||
nsCOMPtr<mozIGeckoMediaPluginService> mps =
|
||||
do_GetService("@mozilla.org/gecko-media-plugin-service;1");
|
||||
if (NS_WARN_IF(!mps)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aKeySystem.EqualsLiteral("org.w3.clearkey") &&
|
||||
HaveGMPFor(mps,
|
||||
NS_LITERAL_CSTRING("org.w3.clearkey"),
|
||||
NS_LITERAL_CSTRING("eme-decrypt"))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
if (aKeySystem.EqualsLiteral("com.adobe.access") &&
|
||||
Preferences::GetBool("media.eme.adobe-access.enabled", false) &&
|
||||
IsVistaOrLater() && // Win Vista and later only.
|
||||
HaveGMPFor(mps,
|
||||
NS_LITERAL_CSTRING("com.adobe.access"),
|
||||
NS_LITERAL_CSTRING("eme-decrypt"))) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsPlayableWithGMP(mozIGeckoMediaPluginService* aGMPS,
|
||||
const nsAString& aKeySystem,
|
||||
const nsAString& aContentType)
|
||||
{
|
||||
#ifdef MOZ_FMP4
|
||||
nsContentTypeParser parser(aContentType);
|
||||
nsAutoString mimeType;
|
||||
nsresult rv = parser.GetType(mimeType);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mimeType.EqualsLiteral("audio/mp4") &&
|
||||
!mimeType.EqualsLiteral("audio/x-m4a") &&
|
||||
!mimeType.EqualsLiteral("video/mp4")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsAutoString codecs;
|
||||
parser.GetParameter("codecs", codecs);
|
||||
|
||||
NS_ConvertUTF16toUTF8 mimeTypeUTF8(mimeType);
|
||||
bool hasAAC = false;
|
||||
bool hasH264 = false;
|
||||
bool hasMP3 = false;
|
||||
if (!MP4Decoder::CanHandleMediaType(mimeTypeUTF8,
|
||||
codecs,
|
||||
hasAAC,
|
||||
hasH264,
|
||||
hasMP3) ||
|
||||
hasMP3) {
|
||||
return false;
|
||||
}
|
||||
return (!hasAAC || !HaveGMPFor(aGMPS,
|
||||
NS_ConvertUTF16toUTF8(aKeySystem),
|
||||
NS_LITERAL_CSTRING("eme-decrypt"),
|
||||
NS_LITERAL_CSTRING("aac"))) &&
|
||||
(!hasH264 || !HaveGMPFor(aGMPS,
|
||||
NS_ConvertUTF16toUTF8(aKeySystem),
|
||||
NS_LITERAL_CSTRING("eme-decrypt"),
|
||||
NS_LITERAL_CSTRING("h264")));
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
MediaKeySystemAccess::IsSupported(const nsAString& aKeySystem,
|
||||
const Sequence<MediaKeySystemOptions>& aOptions)
|
||||
{
|
||||
nsCOMPtr<mozIGeckoMediaPluginService> mps =
|
||||
do_GetService("@mozilla.org/gecko-media-plugin-service;1");
|
||||
if (NS_WARN_IF(!mps)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < aOptions.Length(); i++) {
|
||||
const MediaKeySystemOptions& options = aOptions[i];
|
||||
if (!options.mInitDataType.EqualsLiteral("cenc")) {
|
||||
continue;
|
||||
}
|
||||
if (!options.mAudioCapability.IsEmpty() ||
|
||||
!options.mVideoCapability.IsEmpty()) {
|
||||
// Don't support any capabilites until we know we have a CDM with
|
||||
// capabilities...
|
||||
continue;
|
||||
}
|
||||
if (!options.mAudioType.IsEmpty() &&
|
||||
!IsPlayableWithGMP(mps, aKeySystem, options.mAudioType)) {
|
||||
continue;
|
||||
}
|
||||
if (!options.mVideoType.IsEmpty() &&
|
||||
!IsPlayableWithGMP(mps, aKeySystem, options.mVideoType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Our sandbox provides an origin specific unique identifier, and the
|
||||
// ability to persist data. We don't yet have a way to turn those off
|
||||
// and on for specific GMPs/CDMs, so we don't check the uniqueidentifier
|
||||
// and stateful attributes here.
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,58 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_MediaKeySystemAccess_h
|
||||
#define mozilla_dom_MediaKeySystemAccess_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/MediaKeySystemAccessBinding.h"
|
||||
#include "js/TypeDecls.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class MediaKeySystemAccess MOZ_FINAL : public nsISupports,
|
||||
public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MediaKeySystemAccess)
|
||||
|
||||
public:
|
||||
explicit MediaKeySystemAccess(nsPIDOMWindow* aParent,
|
||||
const nsAString& aKeySystem);
|
||||
|
||||
protected:
|
||||
~MediaKeySystemAccess();
|
||||
|
||||
public:
|
||||
nsPIDOMWindow* GetParentObject() const;
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||
|
||||
void GetKeySystem(nsString& aRetVal) const;
|
||||
|
||||
already_AddRefed<Promise> CreateMediaKeys(ErrorResult& aRv);
|
||||
|
||||
static bool IsKeySystemSupported(const nsAString& aKeySystem);
|
||||
|
||||
static bool IsSupported(const nsAString& aKeySystem,
|
||||
const Sequence<MediaKeySystemOptions>& aOptions);
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsPIDOMWindow> mParent;
|
||||
const nsString mKeySystem;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_MediaKeySystemAccess_h
|
|
@ -114,111 +114,6 @@ MediaKeys::SetServerCertificate(const ArrayBufferViewOrArrayBuffer& aCert, Error
|
|||
return promise.forget();
|
||||
}
|
||||
|
||||
static bool
|
||||
HaveGMPFor(const nsCString& aKeySystem,
|
||||
const nsCString& aAPI,
|
||||
const nsCString& aTag = EmptyCString())
|
||||
{
|
||||
nsCOMPtr<mozIGeckoMediaPluginService> mps =
|
||||
do_GetService("@mozilla.org/gecko-media-plugin-service;1");
|
||||
if (NS_WARN_IF(!mps)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsTArray<nsCString> tags;
|
||||
tags.AppendElement(aKeySystem);
|
||||
if (!aTag.IsEmpty()) {
|
||||
tags.AppendElement(aTag);
|
||||
}
|
||||
// Note: EME plugins need a non-null nodeId here, as they must
|
||||
// not be shared across origins.
|
||||
bool hasPlugin = false;
|
||||
if (NS_FAILED(mps->HasPluginForAPI(aAPI,
|
||||
&tags,
|
||||
&hasPlugin))) {
|
||||
return false;
|
||||
}
|
||||
return hasPlugin;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsPlayableMP4Type(const nsAString& aContentType)
|
||||
{
|
||||
#ifdef MOZ_FMP4
|
||||
nsContentTypeParser parser(aContentType);
|
||||
nsAutoString mimeType;
|
||||
nsresult rv = parser.GetType(mimeType);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
nsAutoString codecs;
|
||||
parser.GetParameter("codecs", codecs);
|
||||
|
||||
NS_ConvertUTF16toUTF8 mimeTypeUTF8(mimeType);
|
||||
return MP4Decoder::CanHandleMediaType(mimeTypeUTF8, codecs);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
MediaKeys::IsTypeSupported(const nsAString& aKeySystem,
|
||||
const Optional<nsAString>& aInitDataType,
|
||||
const Optional<nsAString>& aContentType)
|
||||
{
|
||||
if (aKeySystem.EqualsLiteral("org.w3.clearkey") &&
|
||||
(!aInitDataType.WasPassed() || aInitDataType.Value().EqualsLiteral("cenc")) &&
|
||||
(!aContentType.WasPassed() || IsPlayableMP4Type(aContentType.Value())) &&
|
||||
HaveGMPFor(NS_LITERAL_CSTRING("org.w3.clearkey"),
|
||||
NS_LITERAL_CSTRING("eme-decrypt"))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
// Note: Adobe Access's GMP uses WMF to decode, so anything our MP4Reader
|
||||
// thinks it can play on Windows, the Access GMP should be able to play.
|
||||
if (aKeySystem.EqualsLiteral("com.adobe.access") &&
|
||||
Preferences::GetBool("media.eme.adobe-access.enabled", false) &&
|
||||
IsVistaOrLater() && // Win Vista and later only.
|
||||
(!aInitDataType.WasPassed() || aInitDataType.Value().EqualsLiteral("cenc")) &&
|
||||
(!aContentType.WasPassed() || IsPlayableMP4Type(aContentType.Value())) &&
|
||||
HaveGMPFor(NS_LITERAL_CSTRING("com.adobe.access"),
|
||||
NS_LITERAL_CSTRING("eme-decrypt")) &&
|
||||
HaveGMPFor(NS_LITERAL_CSTRING("com.adobe.access"),
|
||||
NS_LITERAL_CSTRING("decode-video"),
|
||||
NS_LITERAL_CSTRING("h264")) &&
|
||||
HaveGMPFor(NS_LITERAL_CSTRING("com.adobe.access"),
|
||||
NS_LITERAL_CSTRING("decode-audio"),
|
||||
NS_LITERAL_CSTRING("aac"))) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* static */
|
||||
IsTypeSupportedResult
|
||||
MediaKeys::IsTypeSupported(const GlobalObject& aGlobal,
|
||||
const nsAString& aKeySystem,
|
||||
const Optional<nsAString>& aInitDataType,
|
||||
const Optional<nsAString>& aContentType,
|
||||
const Optional<nsAString>& aCapability)
|
||||
{
|
||||
// TODO: Should really get spec changed to this is async, so we can wait
|
||||
// for user to consent to running plugin.
|
||||
bool supported = IsTypeSupported(aKeySystem, aInitDataType, aContentType);
|
||||
|
||||
EME_LOG("MediaKeys::IsTypeSupported keySystem='%s' initDataType='%s' contentType='%s' supported=%d",
|
||||
NS_ConvertUTF16toUTF8(aKeySystem).get(),
|
||||
(aInitDataType.WasPassed() ? NS_ConvertUTF16toUTF8(aInitDataType.Value()).get() : ""),
|
||||
(aContentType.WasPassed() ? NS_ConvertUTF16toUTF8(aContentType.Value()).get() : ""),
|
||||
supported);
|
||||
|
||||
return supported ? IsTypeSupportedResult::Probably
|
||||
: IsTypeSupportedResult::_empty;
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
MediaKeys::MakePromise(ErrorResult& aRv)
|
||||
{
|
||||
|
@ -303,24 +198,6 @@ MediaKeys::ResolvePromise(PromiseId aId)
|
|||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<Promise>
|
||||
MediaKeys::Create(const GlobalObject& aGlobal,
|
||||
const nsAString& aKeySystem,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
// CDMProxy keeps MediaKeys alive until it resolves the promise and thus
|
||||
// returns the MediaKeys object to JS.
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
if (!window || !window->GetExtantDoc()) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<MediaKeys> keys = new MediaKeys(window, aKeySystem);
|
||||
return keys->Init(aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
MediaKeys::Init(ErrorResult& aRv)
|
||||
{
|
||||
|
@ -329,11 +206,6 @@ MediaKeys::Init(ErrorResult& aRv)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (!IsTypeSupported(mKeySystem)) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
mProxy = new CDMProxy(this, mKeySystem);
|
||||
|
||||
// Determine principal (at creation time) of the MediaKeys object.
|
||||
|
|
|
@ -53,6 +53,8 @@ public:
|
|||
|
||||
MediaKeys(nsPIDOMWindow* aParentWindow, const nsAString& aKeySystem);
|
||||
|
||||
already_AddRefed<Promise> Init(ErrorResult& aRv);
|
||||
|
||||
nsPIDOMWindow* GetParentObject() const;
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||
|
@ -70,19 +72,6 @@ public:
|
|||
already_AddRefed<Promise> SetServerCertificate(const ArrayBufferViewOrArrayBuffer& aServerCertificate,
|
||||
ErrorResult& aRv);
|
||||
|
||||
// JavaScript: MediaKeys.create()
|
||||
static
|
||||
already_AddRefed<Promise> Create(const GlobalObject& aGlobal,
|
||||
const nsAString& aKeySystem,
|
||||
ErrorResult& aRv);
|
||||
|
||||
// JavaScript: MediaKeys.IsTypeSupported()
|
||||
static IsTypeSupportedResult IsTypeSupported(const GlobalObject& aGlobal,
|
||||
const nsAString& aKeySystem,
|
||||
const Optional<nsAString>& aInitDataType,
|
||||
const Optional<nsAString>& aContentType,
|
||||
const Optional<nsAString>& aCapability);
|
||||
|
||||
already_AddRefed<MediaKeySession> GetSession(const nsAString& aSessionId);
|
||||
|
||||
// Called once a Create() operation succeeds.
|
||||
|
@ -128,12 +117,7 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
static bool IsTypeSupported(const nsAString& aKeySystem,
|
||||
const Optional<nsAString>& aInitDataType = Optional<nsAString>(),
|
||||
const Optional<nsAString>& aContentType = Optional<nsAString>());
|
||||
|
||||
bool IsInPrivateBrowsing();
|
||||
already_AddRefed<Promise> Init(ErrorResult& aRv);
|
||||
|
||||
// Removes promise from mPromises, and returns it.
|
||||
already_AddRefed<Promise> RetrievePromise(PromiseId aId);
|
||||
|
|
|
@ -10,6 +10,7 @@ EXPORTS.mozilla.dom += [
|
|||
'MediaKeyMessageEvent.h',
|
||||
'MediaKeys.h',
|
||||
'MediaKeySession.h',
|
||||
'MediaKeySystemAccess.h',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla += [
|
||||
|
@ -29,6 +30,7 @@ UNIFIED_SOURCES += [
|
|||
'MediaKeyMessageEvent.cpp',
|
||||
'MediaKeys.cpp',
|
||||
'MediaKeySession.cpp',
|
||||
'MediaKeySystemAccess.cpp',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
|
|
@ -54,14 +54,25 @@ MP4Decoder::SetCDMProxy(CDMProxy* aProxy)
|
|||
#endif
|
||||
|
||||
static bool
|
||||
IsSupportedAudioCodec(const nsAString& aCodec)
|
||||
IsSupportedAudioCodec(const nsAString& aCodec,
|
||||
bool& aOutContainsAAC,
|
||||
bool& aOutContainsMP3)
|
||||
{
|
||||
// AAC-LC, HE-AAC or MP3 in M4A.
|
||||
return aCodec.EqualsASCII("mp4a.40.2") ||
|
||||
// AAC-LC or HE-AAC in M4A.
|
||||
aOutContainsAAC = aCodec.EqualsASCII("mp4a.40.2") ||
|
||||
aCodec.EqualsASCII("mp4a.40.5");
|
||||
if (aOutContainsAAC) {
|
||||
return true;
|
||||
}
|
||||
#ifndef MOZ_GONK_MEDIACODEC // B2G doesn't support MP3 in MP4 yet.
|
||||
aCodec.EqualsASCII("mp3") ||
|
||||
aOutContainsMP3 = aCodec.EqualsASCII("mp3");
|
||||
if (aOutContainsMP3) {
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
aOutContainsMP3 = false;
|
||||
#endif
|
||||
aCodec.EqualsASCII("mp4a.40.5");
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -92,14 +103,20 @@ IsSupportedH264Codec(const nsAString& aCodec)
|
|||
/* static */
|
||||
bool
|
||||
MP4Decoder::CanHandleMediaType(const nsACString& aType,
|
||||
const nsAString& aCodecs)
|
||||
const nsAString& aCodecs,
|
||||
bool& aOutContainsAAC,
|
||||
bool& aOutContainsH264,
|
||||
bool& aOutContainsMP3)
|
||||
{
|
||||
if (!IsEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aType.EqualsASCII("audio/mp4") || aType.EqualsASCII("audio/x-m4a")) {
|
||||
return aCodecs.IsEmpty() || IsSupportedAudioCodec(aCodecs);
|
||||
return aCodecs.IsEmpty() ||
|
||||
IsSupportedAudioCodec(aCodecs,
|
||||
aOutContainsAAC,
|
||||
aOutContainsMP3);
|
||||
}
|
||||
|
||||
if (!aType.EqualsASCII("video/mp4")) {
|
||||
|
@ -113,7 +130,13 @@ MP4Decoder::CanHandleMediaType(const nsACString& aType,
|
|||
while (tokenizer.hasMoreTokens()) {
|
||||
const nsSubstring& token = tokenizer.nextToken();
|
||||
expectMoreTokens = tokenizer.separatorAfterCurrentToken();
|
||||
if (IsSupportedAudioCodec(token) || IsSupportedH264Codec(token)) {
|
||||
if (IsSupportedAudioCodec(token,
|
||||
aOutContainsAAC,
|
||||
aOutContainsMP3)) {
|
||||
continue;
|
||||
}
|
||||
if (IsSupportedH264Codec(token)) {
|
||||
aOutContainsH264 = true;
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
|
@ -122,8 +145,8 @@ MP4Decoder::CanHandleMediaType(const nsACString& aType,
|
|||
// Last codec name was empty
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
@ -30,9 +30,13 @@ public:
|
|||
|
||||
// Returns true if aMIMEType is a type that we think we can render with the
|
||||
// a MP4 platform decoder backend. If aCodecs is non emtpy, it is filled
|
||||
// with a comma-delimited list of codecs to check support for.
|
||||
// with a comma-delimited list of codecs to check support for. Notes in
|
||||
// out params wether the codecs string contains AAC or H.264.
|
||||
static bool CanHandleMediaType(const nsACString& aMIMEType,
|
||||
const nsAString& aCodecs = EmptyString());
|
||||
const nsAString& aCodecs,
|
||||
bool& aOutContainsAAC,
|
||||
bool& aOutContainsH264,
|
||||
bool& aOutContainsMP3);
|
||||
|
||||
// Returns true if the MP4 backend is preffed on, and we're running on a
|
||||
// platform that is likely to have decoders for the contained formats.
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "SharedThreadPool.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/dom/TimeRanges.h"
|
||||
#include "SharedDecoderManager.h"
|
||||
|
||||
#ifdef MOZ_EME
|
||||
#include "mozilla/CDMProxy.h"
|
||||
|
@ -414,12 +415,21 @@ MP4Reader::ReadMetadata(MediaInfo* aInfo,
|
|||
const VideoDecoderConfig& video = mDemuxer->VideoConfig();
|
||||
mInfo.mVideo.mDisplay =
|
||||
nsIntSize(video.display_width, video.display_height);
|
||||
mVideo.mCallback = new DecoderCallback(this, kVideo);
|
||||
mVideo.mDecoder = mPlatform->CreateH264Decoder(video,
|
||||
mLayersBackendType,
|
||||
mDecoder->GetImageContainer(),
|
||||
mVideo.mTaskQueue,
|
||||
mVideo.mCallback);
|
||||
mVideo.mCallback = new DecoderCallback(this, kVideo);
|
||||
if (mSharedDecoderManager) {
|
||||
mVideo.mDecoder =
|
||||
mSharedDecoderManager->CreateH264Decoder(video,
|
||||
mLayersBackendType,
|
||||
mDecoder->GetImageContainer(),
|
||||
mVideo.mTaskQueue,
|
||||
mVideo.mCallback);
|
||||
} else {
|
||||
mVideo.mDecoder = mPlatform->CreateH264Decoder(video,
|
||||
mLayersBackendType,
|
||||
mDecoder->GetImageContainer(),
|
||||
mVideo.mTaskQueue,
|
||||
mVideo.mCallback);
|
||||
}
|
||||
NS_ENSURE_TRUE(mVideo.mDecoder != nullptr, NS_ERROR_FAILURE);
|
||||
nsresult rv = mVideo.mDecoder->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -473,12 +483,6 @@ MP4Reader::GetDecoderData(TrackType aTrack)
|
|||
return (aTrack == kAudio) ? mAudio : mVideo;
|
||||
}
|
||||
|
||||
MediaDataDecoder*
|
||||
MP4Reader::Decoder(TrackType aTrack)
|
||||
{
|
||||
return GetDecoderData(aTrack).mDecoder;
|
||||
}
|
||||
|
||||
MP4Sample*
|
||||
MP4Reader::PopSample(TrackType aTrack)
|
||||
{
|
||||
|
@ -884,4 +888,21 @@ void MP4Reader::NotifyResourcesStatusChanged()
|
|||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
MP4Reader::SetIdle()
|
||||
{
|
||||
if (mSharedDecoderManager && mVideo.mDecoder) {
|
||||
mSharedDecoderManager->SetIdle(mVideo.mDecoder);
|
||||
NotifyResourcesStatusChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MP4Reader::SetSharedDecoderManager(SharedDecoderManager* aManager)
|
||||
{
|
||||
#ifdef MOZ_GONK_MEDIACODEC
|
||||
mSharedDecoderManager = aManager;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -62,9 +62,12 @@ public:
|
|||
virtual nsresult GetBuffered(dom::TimeRanges* aBuffered) MOZ_OVERRIDE;
|
||||
|
||||
// For Media Resource Management
|
||||
virtual void SetIdle() MOZ_OVERRIDE;
|
||||
virtual bool IsWaitingMediaResources() MOZ_OVERRIDE;
|
||||
virtual bool IsDormantNeeded() MOZ_OVERRIDE;
|
||||
virtual void ReleaseMediaResources() MOZ_OVERRIDE;
|
||||
virtual void SetSharedDecoderManager(SharedDecoderManager* aManager)
|
||||
MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult ResetDecode() MOZ_OVERRIDE;
|
||||
|
||||
|
@ -179,7 +182,6 @@ private:
|
|||
uint64_t mLastReportedNumDecodedFrames;
|
||||
|
||||
DecoderData& GetDecoderData(mp4_demuxer::TrackType aTrack);
|
||||
MediaDataDecoder* Decoder(mp4_demuxer::TrackType aTrack);
|
||||
|
||||
layers::LayersBackend mLayersBackendType;
|
||||
|
||||
|
@ -193,6 +195,7 @@ private:
|
|||
|
||||
bool mIndexReady;
|
||||
Monitor mIndexMonitor;
|
||||
nsRefPtr<SharedDecoderManager> mSharedDecoderManager;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -230,8 +230,8 @@ public:
|
|||
virtual bool IsDormantNeeded() {
|
||||
return false;
|
||||
};
|
||||
virtual void ReleaseMediaResources() {};
|
||||
virtual void ReleaseDecoder() {};
|
||||
virtual void ReleaseMediaResources() {}
|
||||
virtual void ReleaseDecoder() {}
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -0,0 +1,207 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "SharedDecoderManager.h"
|
||||
#include "mp4_demuxer/DecoderData.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class SharedDecoderCallback : public MediaDataDecoderCallback
|
||||
{
|
||||
public:
|
||||
SharedDecoderCallback(SharedDecoderManager* aManager) : mManager(aManager) {}
|
||||
|
||||
virtual void Output(MediaData* aData) MOZ_OVERRIDE
|
||||
{
|
||||
if (mManager->mActiveCallback) {
|
||||
mManager->mActiveCallback->Output(aData);
|
||||
}
|
||||
}
|
||||
virtual void Error() MOZ_OVERRIDE
|
||||
{
|
||||
if (mManager->mActiveCallback) {
|
||||
mManager->mActiveCallback->Error();
|
||||
}
|
||||
}
|
||||
virtual void InputExhausted() MOZ_OVERRIDE
|
||||
{
|
||||
if (mManager->mActiveCallback) {
|
||||
mManager->mActiveCallback->InputExhausted();
|
||||
}
|
||||
}
|
||||
virtual void DrainComplete() MOZ_OVERRIDE
|
||||
{
|
||||
if (mManager->mActiveCallback) {
|
||||
mManager->DrainComplete();
|
||||
}
|
||||
}
|
||||
virtual void NotifyResourcesStatusChanged() MOZ_OVERRIDE
|
||||
{
|
||||
if (mManager->mActiveCallback) {
|
||||
mManager->mActiveCallback->NotifyResourcesStatusChanged();
|
||||
}
|
||||
}
|
||||
virtual void ReleaseMediaResources() MOZ_OVERRIDE
|
||||
{
|
||||
if (mManager->mActiveCallback) {
|
||||
mManager->mActiveCallback->ReleaseMediaResources();
|
||||
}
|
||||
}
|
||||
|
||||
SharedDecoderManager* mManager;
|
||||
};
|
||||
|
||||
SharedDecoderManager::SharedDecoderManager()
|
||||
: mActiveProxy(nullptr)
|
||||
, mActiveCallback(nullptr)
|
||||
, mWaitForInternalDrain(false)
|
||||
, mMonitor("SharedDecoderProxy")
|
||||
{
|
||||
mCallback = new SharedDecoderCallback(this);
|
||||
}
|
||||
|
||||
SharedDecoderManager::~SharedDecoderManager() {}
|
||||
|
||||
already_AddRefed<MediaDataDecoder>
|
||||
SharedDecoderManager::CreateH264Decoder(
|
||||
const mp4_demuxer::VideoDecoderConfig& aConfig,
|
||||
layers::LayersBackend aLayersBackend, layers::ImageContainer* aImageContainer,
|
||||
MediaTaskQueue* aVideoTaskQueue, MediaDataDecoderCallback* aCallback)
|
||||
{
|
||||
if (!mDecoder) {
|
||||
nsAutoPtr<PlatformDecoderModule> platform(PlatformDecoderModule::Create());
|
||||
mDecoder = platform->CreateH264Decoder(
|
||||
aConfig, aLayersBackend, aImageContainer, aVideoTaskQueue, mCallback);
|
||||
if (!mDecoder) {
|
||||
return nullptr;
|
||||
}
|
||||
nsresult rv = mDecoder->Init();
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
}
|
||||
|
||||
nsRefPtr<SharedDecoderProxy> proxy(new SharedDecoderProxy(this, aCallback));
|
||||
return proxy.forget();
|
||||
}
|
||||
|
||||
void
|
||||
SharedDecoderManager::Select(SharedDecoderProxy* aProxy)
|
||||
{
|
||||
if (mActiveProxy == aProxy) {
|
||||
return;
|
||||
}
|
||||
SetIdle(mActiveProxy);
|
||||
|
||||
mActiveProxy = aProxy;
|
||||
mActiveCallback = aProxy->mCallback;
|
||||
}
|
||||
|
||||
void
|
||||
SharedDecoderManager::SetIdle(MediaDataDecoder* aProxy)
|
||||
{
|
||||
if (aProxy && mActiveProxy == aProxy) {
|
||||
mWaitForInternalDrain = true;
|
||||
mActiveProxy->Drain();
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
while (mWaitForInternalDrain) {
|
||||
mon.Wait();
|
||||
}
|
||||
mActiveProxy->Flush();
|
||||
mActiveProxy = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SharedDecoderManager::DrainComplete()
|
||||
{
|
||||
if (mWaitForInternalDrain) {
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
mWaitForInternalDrain = false;
|
||||
mon.NotifyAll();
|
||||
} else {
|
||||
mActiveCallback->DrainComplete();
|
||||
}
|
||||
}
|
||||
|
||||
SharedDecoderProxy::SharedDecoderProxy(
|
||||
SharedDecoderManager* aManager, MediaDataDecoderCallback* aCallback)
|
||||
: mManager(aManager), mCallback(aCallback)
|
||||
{
|
||||
}
|
||||
|
||||
SharedDecoderProxy::~SharedDecoderProxy() { Shutdown(); }
|
||||
|
||||
nsresult
|
||||
SharedDecoderProxy::Init()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
SharedDecoderProxy::Input(mp4_demuxer::MP4Sample* aSample)
|
||||
{
|
||||
if (mManager->mActiveProxy != this) {
|
||||
mManager->Select(this);
|
||||
}
|
||||
return mManager->mDecoder->Input(aSample);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
SharedDecoderProxy::Flush()
|
||||
{
|
||||
if (mManager->mActiveProxy == this) {
|
||||
return mManager->mDecoder->Flush();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
SharedDecoderProxy::Drain()
|
||||
{
|
||||
if (mManager->mActiveProxy == this) {
|
||||
return mManager->mDecoder->Drain();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
SharedDecoderProxy::Shutdown()
|
||||
{
|
||||
mManager->SetIdle(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
SharedDecoderProxy::IsWaitingMediaResources()
|
||||
{
|
||||
if (mManager->mActiveProxy == this) {
|
||||
return mManager->mDecoder->IsWaitingMediaResources();
|
||||
}
|
||||
return mManager->mActiveProxy != nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
SharedDecoderProxy::IsDormantNeeded()
|
||||
{
|
||||
return mManager->mDecoder->IsDormantNeeded();
|
||||
}
|
||||
|
||||
void
|
||||
SharedDecoderProxy::ReleaseMediaResources()
|
||||
{
|
||||
if (mManager->mActiveProxy == this) {
|
||||
mManager->mDecoder->ReleaseMediaResources();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SharedDecoderProxy::ReleaseDecoder()
|
||||
{
|
||||
if (mManager->mActiveProxy == this) {
|
||||
mManager->mDecoder->ReleaseMediaResources();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef SHARED_DECODER_MANAGER_H_
|
||||
#define SHARED_DECODER_MANAGER_H_
|
||||
|
||||
#include "PlatformDecoderModule.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
|
||||
namespace mozilla
|
||||
{
|
||||
|
||||
class MediaDataDecoder;
|
||||
class SharedDecoderProxy;
|
||||
class SharedDecoderCallback;
|
||||
|
||||
class SharedDecoderManager
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedDecoderManager)
|
||||
|
||||
SharedDecoderManager();
|
||||
|
||||
already_AddRefed<MediaDataDecoder> CreateH264Decoder(
|
||||
const mp4_demuxer::VideoDecoderConfig& aConfig,
|
||||
layers::LayersBackend aLayersBackend,
|
||||
layers::ImageContainer* aImageContainer, MediaTaskQueue* aVideoTaskQueue,
|
||||
MediaDataDecoderCallback* aCallback);
|
||||
|
||||
void SetReader(MediaDecoderReader* aReader);
|
||||
void Select(SharedDecoderProxy* aProxy);
|
||||
void SetIdle(MediaDataDecoder* aProxy);
|
||||
|
||||
friend class SharedDecoderProxy;
|
||||
friend class SharedDecoderCallback;
|
||||
|
||||
private:
|
||||
virtual ~SharedDecoderManager();
|
||||
void DrainComplete();
|
||||
|
||||
nsRefPtr<MediaDataDecoder> mDecoder;
|
||||
SharedDecoderProxy* mActiveProxy;
|
||||
MediaDataDecoderCallback* mActiveCallback;
|
||||
nsAutoPtr<MediaDataDecoderCallback> mCallback;
|
||||
bool mWaitForInternalDrain;
|
||||
Monitor mMonitor;
|
||||
};
|
||||
|
||||
class SharedDecoderProxy : public MediaDataDecoder
|
||||
{
|
||||
public:
|
||||
SharedDecoderProxy(SharedDecoderManager* aManager,
|
||||
MediaDataDecoderCallback* aCallback);
|
||||
virtual ~SharedDecoderProxy();
|
||||
|
||||
virtual nsresult Init() MOZ_OVERRIDE;
|
||||
virtual nsresult Input(mp4_demuxer::MP4Sample* aSample) MOZ_OVERRIDE;
|
||||
virtual nsresult Flush() MOZ_OVERRIDE;
|
||||
virtual nsresult Drain() MOZ_OVERRIDE;
|
||||
virtual nsresult Shutdown() MOZ_OVERRIDE;
|
||||
virtual bool IsWaitingMediaResources() MOZ_OVERRIDE;
|
||||
virtual bool IsDormantNeeded() MOZ_OVERRIDE;
|
||||
virtual void ReleaseMediaResources() MOZ_OVERRIDE;
|
||||
virtual void ReleaseDecoder() MOZ_OVERRIDE;
|
||||
|
||||
friend class SharedDecoderManager;
|
||||
|
||||
private:
|
||||
nsRefPtr<SharedDecoderManager> mManager;
|
||||
MediaDataDecoderCallback* mCallback;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
#include "MediaData.h"
|
||||
|
||||
#include "mp4_demuxer/Adts.h"
|
||||
#include "mp4_demuxer/AnnexB.h"
|
||||
#include "mp4_demuxer/DecoderData.h"
|
||||
|
||||
|
@ -50,7 +49,7 @@ public:
|
|||
nsresult Init() MOZ_OVERRIDE {
|
||||
mSurfaceTexture = AndroidSurfaceTexture::Create();
|
||||
if (!mSurfaceTexture) {
|
||||
printf_stderr("Failed to create SurfaceTexture for video decode\n");
|
||||
NS_WARNING("Failed to create SurfaceTexture for video decode\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -104,25 +103,6 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual nsresult Input(mp4_demuxer::MP4Sample* aSample) MOZ_OVERRIDE {
|
||||
if (!strcmp(mMimeType, "audio/mp4a-latm")) {
|
||||
uint32_t numChannels = mFormat->GetInteger(NS_LITERAL_CSTRING("channel-count"));
|
||||
uint32_t sampleRate = mFormat->GetInteger(NS_LITERAL_CSTRING("sample-rate"));
|
||||
uint8_t frequencyIndex =
|
||||
mp4_demuxer::Adts::GetFrequencyIndex(sampleRate);
|
||||
uint32_t aacProfile = mFormat->GetInteger(NS_LITERAL_CSTRING("aac-profile"));
|
||||
bool rv = mp4_demuxer::Adts::ConvertSample(numChannels,
|
||||
frequencyIndex,
|
||||
aacProfile,
|
||||
aSample);
|
||||
if (!rv) {
|
||||
printf_stderr("Failed to prepend ADTS header\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
return MediaCodecDataDecoder::Input(aSample);
|
||||
}
|
||||
|
||||
nsresult Output(BufferInfo* aInfo, void* aBuffer, MediaFormat* aFormat, Microseconds aDuration) {
|
||||
// The output on Android is always 16-bit signed
|
||||
|
||||
|
@ -213,11 +193,6 @@ AndroidDecoderModule::CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig&
|
|||
env->DeleteLocalRef(buffer);
|
||||
}
|
||||
|
||||
if (strcmp(aConfig.mime_type, "audio/mp4a-latm") == 0) {
|
||||
format->SetInteger(NS_LITERAL_CSTRING("is-adts"), 1);
|
||||
format->SetInteger(NS_LITERAL_CSTRING("aac-profile"), aConfig.aac_profile);
|
||||
}
|
||||
|
||||
nsRefPtr<MediaDataDecoder> decoder =
|
||||
new AudioDataDecoder(aConfig.mime_type, format, aCallback);
|
||||
|
||||
|
@ -242,6 +217,7 @@ MediaCodecDataDecoder::MediaCodecDataDecoder(MediaData::Type aType,
|
|||
, mInputBuffers(nullptr)
|
||||
, mOutputBuffers(nullptr)
|
||||
, mMonitor("MediaCodecDataDecoder::mMonitor")
|
||||
, mFlushing(false)
|
||||
, mDraining(false)
|
||||
, mStopping(false)
|
||||
{
|
||||
|
@ -309,10 +285,20 @@ nsresult MediaCodecDataDecoder::InitDecoder(jobject aSurface)
|
|||
// This is in usec, so that's 10ms
|
||||
#define DECODER_TIMEOUT 10000
|
||||
|
||||
#define HANDLE_DECODER_ERROR() \
|
||||
if (NS_FAILED(res)) { \
|
||||
NS_WARNING("exiting decoder loop due to exception"); \
|
||||
mCallback->Error(); \
|
||||
break; \
|
||||
}
|
||||
|
||||
void MediaCodecDataDecoder::DecoderLoop()
|
||||
{
|
||||
bool outputDone = false;
|
||||
|
||||
bool draining = false;
|
||||
bool waitingEOF = false;
|
||||
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
mp4_demuxer::MP4Sample* sample = nullptr;
|
||||
|
||||
|
@ -322,7 +308,7 @@ void MediaCodecDataDecoder::DecoderLoop()
|
|||
for (;;) {
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
while (!mStopping && !mDraining && mQueue.empty()) {
|
||||
while (!mStopping && !mDraining && !mFlushing && mQueue.empty()) {
|
||||
if (mQueue.empty()) {
|
||||
// We could be waiting here forever if we don't signal that we need more input
|
||||
mCallback->InputExhausted();
|
||||
|
@ -335,28 +321,40 @@ void MediaCodecDataDecoder::DecoderLoop()
|
|||
break;
|
||||
}
|
||||
|
||||
if (mDraining) {
|
||||
if (mFlushing) {
|
||||
mDecoder->Flush();
|
||||
ClearQueue();
|
||||
mDraining = false;
|
||||
mFlushing = false;
|
||||
lock.Notify();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mDraining && !sample && !waitingEOF) {
|
||||
draining = true;
|
||||
}
|
||||
|
||||
// We're not stopping or draining, so try to get a sample
|
||||
if (!mQueue.empty()) {
|
||||
sample = mQueue.front();
|
||||
}
|
||||
}
|
||||
|
||||
if (draining && !waitingEOF) {
|
||||
MOZ_ASSERT(!sample, "Shouldn't have a sample when pushing EOF frame");
|
||||
|
||||
int inputIndex = mDecoder->DequeueInputBuffer(DECODER_TIMEOUT, &res);
|
||||
HANDLE_DECODER_ERROR();
|
||||
|
||||
if (inputIndex >= 0) {
|
||||
mDecoder->QueueInputBuffer(inputIndex, 0, 0, 0, MediaCodec::getBUFFER_FLAG_END_OF_STREAM(), &res);
|
||||
waitingEOF = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (sample) {
|
||||
// We have a sample, try to feed it to the decoder
|
||||
int inputIndex = mDecoder->DequeueInputBuffer(DECODER_TIMEOUT, &res);
|
||||
if (NS_FAILED(res)) {
|
||||
printf_stderr("exiting decoder loop due to exception while dequeuing input\n");
|
||||
mCallback->Error();
|
||||
break;
|
||||
}
|
||||
HANDLE_DECODER_ERROR();
|
||||
|
||||
if (inputIndex >= 0) {
|
||||
jobject buffer = env->GetObjectArrayElement(mInputBuffers, inputIndex);
|
||||
|
@ -373,11 +371,7 @@ void MediaCodecDataDecoder::DecoderLoop()
|
|||
PodCopy((uint8_t*)directBuffer, sample->data, sample->size);
|
||||
|
||||
mDecoder->QueueInputBuffer(inputIndex, 0, sample->size, sample->composition_timestamp, 0, &res);
|
||||
if (NS_FAILED(res)) {
|
||||
printf_stderr("exiting decoder loop due to exception while queuing input\n");
|
||||
mCallback->Error();
|
||||
break;
|
||||
}
|
||||
HANDLE_DECODER_ERROR();
|
||||
|
||||
mDurations.push(sample->duration);
|
||||
|
||||
|
@ -393,31 +387,42 @@ void MediaCodecDataDecoder::DecoderLoop()
|
|||
BufferInfo bufferInfo;
|
||||
|
||||
int outputStatus = mDecoder->DequeueOutputBuffer(bufferInfo.wrappedObject(), DECODER_TIMEOUT, &res);
|
||||
if (NS_FAILED(res)) {
|
||||
printf_stderr("exiting decoder loop due to exception while dequeuing output\n");
|
||||
mCallback->Error();
|
||||
break;
|
||||
}
|
||||
HANDLE_DECODER_ERROR();
|
||||
|
||||
if (outputStatus == MediaCodec::getINFO_TRY_AGAIN_LATER()) {
|
||||
// We might want to call mCallback->InputExhausted() here, but there seems to be
|
||||
// some possible bad interactions here with the threading
|
||||
} else if (outputStatus == MediaCodec::getINFO_OUTPUT_BUFFERS_CHANGED()) {
|
||||
res = ResetOutputBuffers();
|
||||
if (NS_FAILED(res)) {
|
||||
printf_stderr("exiting decoder loop due to exception while restting output buffers\n");
|
||||
mCallback->Error();
|
||||
break;
|
||||
}
|
||||
HANDLE_DECODER_ERROR();
|
||||
} else if (outputStatus == MediaCodec::getINFO_OUTPUT_FORMAT_CHANGED()) {
|
||||
outputFormat = new MediaFormat(mDecoder->GetOutputFormat(), GetJNIForThread());
|
||||
} else if (outputStatus < 0) {
|
||||
printf_stderr("unknown error from decoder! %d\n", outputStatus);
|
||||
NS_WARNING("unknown error from decoder!");
|
||||
mCallback->Error();
|
||||
|
||||
// Don't break here just in case it's recoverable. If it's not, others stuff will fail later and
|
||||
// we'll bail out.
|
||||
} else {
|
||||
// We have a valid buffer index >= 0 here
|
||||
if (bufferInfo.getFlags() & MediaCodec::getBUFFER_FLAG_END_OF_STREAM()) {
|
||||
if (draining) {
|
||||
draining = false;
|
||||
waitingEOF = false;
|
||||
|
||||
mMonitor.Lock();
|
||||
mDraining = false;
|
||||
mMonitor.Notify();
|
||||
mMonitor.Unlock();
|
||||
|
||||
mCallback->DrainComplete();
|
||||
}
|
||||
|
||||
mDecoder->ReleaseOutputBuffer(outputStatus, false);
|
||||
outputDone = true;
|
||||
|
||||
// We only queue empty EOF frames, so we're done for now
|
||||
continue;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!mDurations.empty(), "Should have had a duration queued");
|
||||
|
@ -509,20 +514,26 @@ nsresult MediaCodecDataDecoder::ResetOutputBuffers()
|
|||
}
|
||||
|
||||
nsresult MediaCodecDataDecoder::Flush() {
|
||||
Drain();
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
mFlushing = true;
|
||||
lock.Notify();
|
||||
|
||||
while (mFlushing) {
|
||||
lock.Wait();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult MediaCodecDataDecoder::Drain() {
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
if (mDraining) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mDraining = true;
|
||||
lock.Notify();
|
||||
|
||||
while (mDraining) {
|
||||
lock.Wait();
|
||||
}
|
||||
|
||||
mCallback->DrainComplete();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -87,6 +87,7 @@ protected:
|
|||
|
||||
// Only these members are protected by mMonitor.
|
||||
Monitor mMonitor;
|
||||
bool mFlushing;
|
||||
bool mDraining;
|
||||
bool mStopping;
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ GonkMediaDataDecoder::GonkMediaDataDecoder(GonkDecoderManager* aManager,
|
|||
, mCallback(aCallback)
|
||||
, mManager(aManager)
|
||||
, mSignaledEOS(false)
|
||||
, mDrainComplete(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(GonkMediaDataDecoder);
|
||||
}
|
||||
|
@ -45,6 +46,7 @@ nsresult
|
|||
GonkMediaDataDecoder::Init()
|
||||
{
|
||||
mDecoder = mManager->Init(mCallback);
|
||||
mDrainComplete = false;
|
||||
return mDecoder.get() ? NS_OK : NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
|
@ -89,7 +91,7 @@ GonkMediaDataDecoder::ProcessOutput()
|
|||
{
|
||||
nsAutoPtr<MediaData> output;
|
||||
nsresult rv;
|
||||
while (true) {
|
||||
while (true && !mDrainComplete) {
|
||||
rv = mManager->Output(mLastStreamOffset, output);
|
||||
if (rv == NS_OK) {
|
||||
mCallback->Output(output.forget());
|
||||
|
@ -117,6 +119,7 @@ GonkMediaDataDecoder::ProcessOutput()
|
|||
}
|
||||
mCallback->DrainComplete();
|
||||
mSignaledEOS = false;
|
||||
mDrainComplete = true;
|
||||
return;
|
||||
}
|
||||
mCallback->Error();
|
||||
|
|
|
@ -92,6 +92,8 @@ private:
|
|||
int64_t mLastStreamOffset;
|
||||
// Set it ture when there is no input data
|
||||
bool mSignaledEOS;
|
||||
// Set if there is no more output data from decoder
|
||||
bool mDrainComplete;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -8,12 +8,14 @@ EXPORTS += [
|
|||
'MP4Decoder.h',
|
||||
'MP4Reader.h',
|
||||
'PlatformDecoderModule.h',
|
||||
'SharedDecoderManager.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'BlankDecoderModule.cpp',
|
||||
'MP4Decoder.cpp',
|
||||
'PlatformDecoderModule.cpp',
|
||||
'SharedDecoderManager.cpp',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "MediaSourceUtils.h"
|
||||
#include "SourceBufferDecoder.h"
|
||||
#include "TrackBuffer.h"
|
||||
#include "SharedDecoderManager.h"
|
||||
|
||||
#ifdef MOZ_FMP4
|
||||
#include "MP4Decoder.h"
|
||||
|
@ -62,6 +63,7 @@ MediaSourceReader::MediaSourceReader(MediaSourceDecoder* aDecoder)
|
|||
, mAudioIsSeeking(false)
|
||||
, mVideoIsSeeking(false)
|
||||
, mHasEssentialTrackBuffers(false)
|
||||
, mSharedDecoderManager(new SharedDecoderManager())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -371,6 +373,7 @@ MediaSourceReader::CreateSubDecoder(const nsACString& aType)
|
|||
new MediaDataDecodedListener<MediaSourceReader>(this, GetTaskQueue());
|
||||
reader->SetCallback(callback);
|
||||
reader->SetTaskQueue(GetTaskQueue());
|
||||
reader->SetSharedDecoderManager(mSharedDecoderManager);
|
||||
reader->Init(nullptr);
|
||||
|
||||
MSE_DEBUG("MediaSourceReader(%p)::CreateSubDecoder subdecoder %p subreader %p",
|
||||
|
|
|
@ -175,6 +175,7 @@ private:
|
|||
bool mVideoIsSeeking;
|
||||
|
||||
bool mHasEssentialTrackBuffers;
|
||||
nsRefPtr<SharedDecoderManager> mSharedDecoderManager;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -192,23 +192,37 @@ function SetupEME(test, token, params)
|
|||
|
||||
v.addEventListener("encrypted", function(ev) {
|
||||
Log(token, "got encrypted event");
|
||||
MediaKeys.create(KEYSYSTEM_TYPE).then(function(mediaKeys) {
|
||||
Log(token, "created MediaKeys object ok");
|
||||
mediaKeys.sessions = [];
|
||||
return v.setMediaKeys(mediaKeys);
|
||||
}, bail("failed to create MediaKeys object")).then(function() {
|
||||
Log(token, "set MediaKeys on <video> element ok");
|
||||
|
||||
var session = v.mediaKeys.createSession(test.sessionType);
|
||||
if (params && params.onsessioncreated) {
|
||||
params.onsessioncreated(session);
|
||||
var options = [
|
||||
{
|
||||
initDataType: ev.initDataType,
|
||||
videoType: test.type,
|
||||
}
|
||||
session.addEventListener("message", UpdateSessionFunc(test, token));
|
||||
session.generateRequest(ev.initDataType, ev.initData).then(function() {
|
||||
}, bail(token + " Failed to initialise MediaKeySession"));
|
||||
];
|
||||
navigator.requestMediaKeySystemAccess(KEYSYSTEM_TYPE, options)
|
||||
.then(function(keySystemAccess) {
|
||||
return keySystemAccess.createMediaKeys();
|
||||
}, bail(token + " Failed to request key system access."))
|
||||
|
||||
.then(function(mediaKeys) {
|
||||
Log(token, "created MediaKeys object ok");
|
||||
mediaKeys.sessions = [];
|
||||
return v.setMediaKeys(mediaKeys);
|
||||
}, bail("failed to create MediaKeys object"))
|
||||
|
||||
.then(function() {
|
||||
Log(token, "set MediaKeys on <video> element ok");
|
||||
|
||||
}, onSetKeysFail);
|
||||
var session = v.mediaKeys.createSession(test.sessionType);
|
||||
if (params && params.onsessioncreated) {
|
||||
params.onsessioncreated(session);
|
||||
}
|
||||
session.addEventListener("message", UpdateSessionFunc(test, token));
|
||||
return session.generateRequest(ev.initDataType, ev.initData);
|
||||
}, onSetKeysFail)
|
||||
|
||||
.then(function() {
|
||||
Log(token, "generated request");
|
||||
}, bail(token + " Failed to request key system access2."));
|
||||
});
|
||||
|
||||
return v;
|
||||
}
|
||||
|
|
|
@ -364,6 +364,8 @@ skip-if = buildapp == 'b2g' && toolkit != 'gonk' # bug 1082984
|
|||
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # bug 1043403, bug 1057908
|
||||
[test_eme_playback.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # bug 1043403, bug 1057908
|
||||
[test_eme_requestKeySystemAccess.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # bug 1043403, bug 1057908
|
||||
[test_eme_stream_capture_blocked.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # bug 1043403, bug 1057908
|
||||
[test_empty_resource.html]
|
||||
|
|
|
@ -51,8 +51,6 @@ function startTest(test, token)
|
|||
var gotPlaying = false;
|
||||
|
||||
v.addEventListener("encrypted", function(ev) {
|
||||
ok(MediaKeys.isTypeSupported(KEYSYSTEM_TYPE, ev.initDataType, test.type),
|
||||
TimeStamp(token) + " MediaKeys should support this keysystem");
|
||||
gotEncrypted = true;
|
||||
});
|
||||
|
||||
|
@ -88,23 +86,7 @@ function startTest(test, token)
|
|||
LoadTest(test, v, token).then(function(){v.play();}, bail(token + " failed to load"));
|
||||
}
|
||||
|
||||
function testIsTypeSupported()
|
||||
{
|
||||
var t = MediaKeys.isTypeSupported;
|
||||
const clearkey = "org.w3.clearkey";
|
||||
ok(!t("bogus", "bogon", "video/bogus"), "Invalid type.");
|
||||
ok(t(clearkey), "ClearKey supported.");
|
||||
ok(!t(clearkey, "bogus"), "ClearKey bogus initDataType not supported.");
|
||||
ok(t(clearkey, "cenc"), "ClearKey/cenc should be supported.");
|
||||
ok(!t(clearkey, "cenc", "bogus"), "ClearKey/cenc bogus content type should be supported.");
|
||||
ok(t(clearkey, "cenc", 'video/mp4'), "ClearKey/cenc video/mp4 supported.");
|
||||
ok(t(clearkey, "cenc", 'video/mp4; codecs="avc1.4d4015,mp4a.40.2"'), "ClearKey/cenc H.264/AAC supported.");
|
||||
ok(t(clearkey, "cenc", 'audio/mp4'), "ClearKey/cenc audio/mp4 supported.");
|
||||
ok(t(clearkey, "cenc", 'audio/mp4; codecs="mp4a.40.2"'), "ClearKey/cenc AAC LC supported.");
|
||||
}
|
||||
|
||||
function beginTest() {
|
||||
testIsTypeSupported();
|
||||
manager.runTests(gEMETests, startTest);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,293 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test Encrypted Media Extensions</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="text/javascript" src="manifest.js"></script>
|
||||
<script type="text/javascript" src="eme.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
function Test(test) {
|
||||
var name = "'" + test.name + "'";
|
||||
return new Promise(function(resolve, reject) {
|
||||
var p;
|
||||
if (test.options) {
|
||||
p = navigator.requestMediaKeySystemAccess(test.keySystem, test.options);
|
||||
} else {
|
||||
p = navigator.requestMediaKeySystemAccess(test.keySystem);
|
||||
}
|
||||
p.then(
|
||||
function(keySystemAccess) {
|
||||
ok(test.shouldPass, name + " passed and was expected to " + (test.shouldPass ? "pass" : "fail"));
|
||||
resolve();
|
||||
},
|
||||
function(ex) {
|
||||
if (test.shouldPass) {
|
||||
info(name + " failed: " + ex);
|
||||
}
|
||||
ok(!test.shouldPass, name + " failed and was expected to " + (test.shouldPass ? "pass" : "fail"));
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const CLEARKEY_ID = 'org.w3.clearkey';
|
||||
|
||||
var tests = [
|
||||
{
|
||||
name: 'Empty keySystem string',
|
||||
keySystem: '',
|
||||
options: [ ],
|
||||
shouldPass: false,
|
||||
},
|
||||
{
|
||||
name: 'Empty options specified',
|
||||
keySystem: CLEARKEY_ID,
|
||||
options: [ ],
|
||||
shouldPass: false,
|
||||
},
|
||||
{
|
||||
name: 'Undefined options',
|
||||
keySystem: CLEARKEY_ID,
|
||||
shouldPass: true,
|
||||
},
|
||||
{
|
||||
name: 'Basic MP4 cenc',
|
||||
keySystem: CLEARKEY_ID,
|
||||
options: [
|
||||
{
|
||||
initDataType: 'cenc',
|
||||
videoType: 'video/mp4',
|
||||
}
|
||||
],
|
||||
shouldPass: true,
|
||||
},
|
||||
{
|
||||
name: 'Invalid keysystem failure',
|
||||
keySystem: 'bogusKeySystem',
|
||||
options: [],
|
||||
shouldPass: false,
|
||||
},
|
||||
{
|
||||
name: 'Invalid initDataType',
|
||||
keySystem: CLEARKEY_ID,
|
||||
options: [
|
||||
{
|
||||
initDataType: 'bogus',
|
||||
}
|
||||
],
|
||||
shouldPass: false,
|
||||
},
|
||||
{
|
||||
name: 'Invalid videoType',
|
||||
keySystem: CLEARKEY_ID,
|
||||
options: [
|
||||
{
|
||||
initDataType: 'cenc',
|
||||
videoType: 'video/bogus',
|
||||
}
|
||||
],
|
||||
shouldPass: false,
|
||||
},
|
||||
{
|
||||
name: 'Invalid statefulness',
|
||||
keySystem: CLEARKEY_ID,
|
||||
options: [
|
||||
{
|
||||
initDataType: 'cenc',
|
||||
videoType: 'video/mp4',
|
||||
stateful: 'bogus',
|
||||
}
|
||||
],
|
||||
shouldPass: false,
|
||||
},
|
||||
{
|
||||
name: 'Invalid uniqueidentifier',
|
||||
keySystem: CLEARKEY_ID,
|
||||
options: [
|
||||
{
|
||||
initDataType: 'cenc',
|
||||
videoType: 'video/mp4',
|
||||
uniqueidentifier: 'bogus',
|
||||
}
|
||||
],
|
||||
shouldPass: false,
|
||||
},
|
||||
{
|
||||
name: 'Audio capabilities not supported by CLEARKEY_ID',
|
||||
keySystem: CLEARKEY_ID,
|
||||
options: [
|
||||
{
|
||||
initDataType: 'cenc',
|
||||
videoType: 'video/mp4',
|
||||
audioCapability: 'bogus',
|
||||
}
|
||||
],
|
||||
shouldPass: false,
|
||||
},
|
||||
{
|
||||
name: 'Video capabilities not supported by CLEARKEY_ID',
|
||||
keySystem: CLEARKEY_ID,
|
||||
options: [
|
||||
{
|
||||
initDataType: 'cenc',
|
||||
videoType: 'video/mp4',
|
||||
videoCapability: 'bogus',
|
||||
}
|
||||
],
|
||||
shouldPass: false,
|
||||
},
|
||||
{
|
||||
name: 'Invalid option followed by valid',
|
||||
keySystem: CLEARKEY_ID,
|
||||
options: [
|
||||
{
|
||||
bogus: 'bogon',
|
||||
},
|
||||
{
|
||||
initDataType: 'cenc',
|
||||
videoType: 'video/mp4',
|
||||
}
|
||||
],
|
||||
shouldPass: true,
|
||||
},
|
||||
{
|
||||
name: 'MP4 audio container',
|
||||
keySystem: CLEARKEY_ID,
|
||||
options: [
|
||||
{
|
||||
initDataType: 'cenc',
|
||||
audioType: 'audio/mp4',
|
||||
}
|
||||
],
|
||||
shouldPass: true,
|
||||
},
|
||||
{
|
||||
name: 'MP4 audio container with AAC-LC',
|
||||
keySystem: CLEARKEY_ID,
|
||||
options: [
|
||||
{
|
||||
initDataType: 'cenc',
|
||||
audioType: 'audio/mp4; codecs="mp4a.40.2"',
|
||||
}
|
||||
],
|
||||
shouldPass: true,
|
||||
},
|
||||
{
|
||||
name: 'MP4 audio container with invalid codecs',
|
||||
keySystem: CLEARKEY_ID,
|
||||
options: [
|
||||
{
|
||||
initDataType: 'cenc',
|
||||
audioType: 'audio/mp4; codecs="bogus"',
|
||||
}
|
||||
],
|
||||
shouldPass: false,
|
||||
},
|
||||
{
|
||||
name: 'MP4 audio container with mp3 is unsupported',
|
||||
keySystem: CLEARKEY_ID,
|
||||
options: [
|
||||
{
|
||||
initDataType: 'cenc',
|
||||
audioType: 'audio/mp4; codecs="mp3"',
|
||||
}
|
||||
],
|
||||
shouldPass: false,
|
||||
},
|
||||
{
|
||||
name: 'MP4 video container with mp3 and h264 is unsupported',
|
||||
keySystem: CLEARKEY_ID,
|
||||
options: [
|
||||
{
|
||||
initDataType: 'cenc',
|
||||
videoType: 'video/mp4; codecs="avc1.42E01E,mp3"',
|
||||
}
|
||||
],
|
||||
shouldPass: false,
|
||||
},
|
||||
{
|
||||
name: 'MP4 video container with constrained baseline h.264',
|
||||
keySystem: CLEARKEY_ID,
|
||||
options: [
|
||||
{
|
||||
initDataType: 'cenc',
|
||||
audioType: 'video/mp4; codecs="avc1.42E01E"',
|
||||
}
|
||||
],
|
||||
shouldPass: true,
|
||||
},
|
||||
{
|
||||
name: 'MP4 video container with invalid codecs',
|
||||
keySystem: CLEARKEY_ID,
|
||||
options: [
|
||||
{
|
||||
initDataType: 'cenc',
|
||||
videoType: 'video/mp4; codecs="bogus"',
|
||||
}
|
||||
],
|
||||
shouldPass: false,
|
||||
},
|
||||
{
|
||||
name: 'MP4 video container with constrained baseline h.264 and AAC-LC',
|
||||
keySystem: CLEARKEY_ID,
|
||||
options: [
|
||||
{
|
||||
initDataType: 'cenc',
|
||||
videoType: 'video/mp4; codecs="avc1.42E01E,mp4a.40.2"',
|
||||
}
|
||||
],
|
||||
shouldPass: true,
|
||||
},
|
||||
{
|
||||
name: 'MP4 audio and video type both specified',
|
||||
keySystem: CLEARKEY_ID,
|
||||
options: [
|
||||
{
|
||||
initDataType: 'cenc',
|
||||
videoType: 'video/mp4; codecs="avc1.42E01E"',
|
||||
audioType: 'audio/mp4; codecs="mp4a.40.2"',
|
||||
}
|
||||
],
|
||||
shouldPass: true,
|
||||
},
|
||||
{
|
||||
name: 'WebM CLEARKEY_ID not supported',
|
||||
keySystem: CLEARKEY_ID,
|
||||
options: [
|
||||
{
|
||||
initDataType: 'webm',
|
||||
videoType: 'video/webm',
|
||||
}
|
||||
],
|
||||
shouldPass: false,
|
||||
},
|
||||
];
|
||||
|
||||
function beginTest() {
|
||||
Promise.all(tests.map(Test)).then(function() { SimpleTest.finish(); });
|
||||
}
|
||||
|
||||
var prefs = [
|
||||
[ "media.mediasource.enabled", true ],
|
||||
[ "media.mediasource.mp4.enabled", true ],
|
||||
];
|
||||
|
||||
if (/Linux/.test(navigator.userAgent) ||
|
||||
!document.createElement('video').canPlayType("video/mp4")) {
|
||||
// XXX remove once we have mp4 PlatformDecoderModules on all platforms.
|
||||
prefs.push([ "media.fragmented-mp4.exposed", true ]);
|
||||
prefs.push([ "media.fragmented-mp4.use-blank-decoder", true ]);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({ "set" : prefs }, beginTest);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -54,6 +54,7 @@ const NFC_IPC_MSG_NAMES = [
|
|||
"NFC:ReadNDEFResponse",
|
||||
"NFC:WriteNDEFResponse",
|
||||
"NFC:MakeReadOnlyResponse",
|
||||
"NFC:FormatResponse",
|
||||
"NFC:ConnectResponse",
|
||||
"NFC:CloseResponse",
|
||||
"NFC:CheckP2PRegistrationResponse",
|
||||
|
@ -176,6 +177,18 @@ NfcContentHelper.prototype = {
|
|||
return request;
|
||||
},
|
||||
|
||||
format: function format(sessionToken) {
|
||||
let request = Services.DOMRequest.createRequest(this._window);
|
||||
let requestId = btoa(this.getRequestId(request));
|
||||
this._requestMap[requestId] = this._window;
|
||||
|
||||
cpmm.sendAsyncMessage("NFC:Format", {
|
||||
requestId: requestId,
|
||||
sessionToken: sessionToken
|
||||
});
|
||||
return request;
|
||||
},
|
||||
|
||||
connect: function connect(techType, sessionToken) {
|
||||
let request = Services.DOMRequest.createRequest(this._window);
|
||||
let requestId = btoa(this.getRequestId(request));
|
||||
|
@ -322,6 +335,7 @@ NfcContentHelper.prototype = {
|
|||
case "NFC:CloseResponse":
|
||||
case "NFC:WriteNDEFResponse":
|
||||
case "NFC:MakeReadOnlyResponse":
|
||||
case "NFC:FormatResponse":
|
||||
case "NFC:NotifySendFileStatusResponse":
|
||||
case "NFC:ChangeRFStateResponse":
|
||||
if (result.errorMsg) {
|
||||
|
|
|
@ -71,6 +71,7 @@ const NFC_IPC_READ_PERM_MSG_NAMES = [
|
|||
const NFC_IPC_WRITE_PERM_MSG_NAMES = [
|
||||
"NFC:WriteNDEF",
|
||||
"NFC:MakeReadOnly",
|
||||
"NFC:Format",
|
||||
"NFC:SendFile",
|
||||
"NFC:RegisterPeerReadyTarget",
|
||||
"NFC:UnregisterPeerReadyTarget"
|
||||
|
@ -564,6 +565,7 @@ Nfc.prototype = {
|
|||
case "CloseResponse":
|
||||
case "ReadNDEFResponse":
|
||||
case "MakeReadOnlyResponse":
|
||||
case "FormatResponse":
|
||||
case "WriteNDEFResponse":
|
||||
this.sendNfcResponse(message);
|
||||
break;
|
||||
|
@ -622,6 +624,9 @@ Nfc.prototype = {
|
|||
case "NFC:MakeReadOnly":
|
||||
this.sendToNfcService("makeReadOnly", message.data);
|
||||
break;
|
||||
case "NFC:Format":
|
||||
this.sendToNfcService("format", message.data);
|
||||
break;
|
||||
case "NFC:Connect":
|
||||
this.sendToNfcService("connect", message.data);
|
||||
break;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
namespace mozilla {
|
||||
|
||||
#define NFCD_MAJOR_VERSION 1
|
||||
#define NFCD_MINOR_VERSION 16
|
||||
#define NFCD_MINOR_VERSION 17
|
||||
|
||||
enum NfcRequest {
|
||||
ChangeRFStateReq = 0,
|
||||
|
@ -17,6 +17,7 @@ enum NfcRequest {
|
|||
ReadNDEFReq,
|
||||
WriteNDEFReq,
|
||||
MakeReadOnlyReq,
|
||||
FormatReq,
|
||||
};
|
||||
|
||||
enum NfcResponse {
|
||||
|
|
|
@ -20,6 +20,7 @@ static const char* kChangeRFStateRequest = "changeRFState";
|
|||
static const char* kReadNDEFRequest = "readNDEF";
|
||||
static const char* kWriteNDEFRequest = "writeNDEF";
|
||||
static const char* kMakeReadOnlyRequest = "makeReadOnly";
|
||||
static const char* kFormatRequest = "format";
|
||||
static const char* kConnectRequest = "connect";
|
||||
static const char* kCloseRequest = "close";
|
||||
|
||||
|
@ -27,6 +28,7 @@ static const char* kChangeRFStateResponse = "ChangeRFStateResponse";
|
|||
static const char* kReadNDEFResponse = "ReadNDEFResponse";
|
||||
static const char* kWriteNDEFResponse = "WriteNDEFResponse";
|
||||
static const char* kMakeReadOnlyResponse = "MakeReadOnlyResponse";
|
||||
static const char* kFormatResponse = "FormatResponse";
|
||||
static const char* kConnectResponse = "ConnectResponse";
|
||||
static const char* kCloseResponse = "CloseResponse";
|
||||
|
||||
|
@ -52,6 +54,9 @@ NfcMessageHandler::Marshall(Parcel& aParcel, const CommandOptions& aOptions)
|
|||
} else if (!strcmp(type, kMakeReadOnlyRequest)) {
|
||||
result = MakeReadOnlyRequest(aParcel, aOptions);
|
||||
mPendingReqQueue.AppendElement(NfcRequest::MakeReadOnlyReq);
|
||||
} else if (!strcmp(type, kFormatRequest)) {
|
||||
result = FormatRequest(aParcel, aOptions);
|
||||
mPendingReqQueue.AppendElement(NfcRequest::FormatReq);
|
||||
} else if (!strcmp(type, kConnectRequest)) {
|
||||
result = ConnectRequest(aParcel, aOptions);
|
||||
mPendingReqQueue.AppendElement(NfcRequest::ConnectReq);
|
||||
|
@ -117,6 +122,9 @@ NfcMessageHandler::GeneralResponse(const Parcel& aParcel, EventOptions& aOptions
|
|||
case NfcRequest::MakeReadOnlyReq:
|
||||
type = kMakeReadOnlyResponse;
|
||||
break;
|
||||
case NfcRequest::FormatReq:
|
||||
type = kFormatResponse;
|
||||
break;
|
||||
case NfcRequest::ConnectReq:
|
||||
type = kConnectResponse;
|
||||
break;
|
||||
|
@ -207,6 +215,15 @@ NfcMessageHandler::MakeReadOnlyRequest(Parcel& aParcel, const CommandOptions& aO
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
NfcMessageHandler::FormatRequest(Parcel& aParcel, const CommandOptions& aOptions)
|
||||
{
|
||||
aParcel.writeInt32(NfcRequest::FormatReq);
|
||||
aParcel.writeInt32(aOptions.mSessionId);
|
||||
mRequestIdQueue.AppendElement(aOptions.mRequestId);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
NfcMessageHandler::ConnectRequest(Parcel& aParcel, const CommandOptions& aOptions)
|
||||
{
|
||||
|
|
|
@ -31,6 +31,7 @@ private:
|
|||
bool ReadNDEFResponse(const android::Parcel& aParcel, EventOptions& aOptions);
|
||||
bool WriteNDEFRequest(android::Parcel& aParcel, const CommandOptions& options);
|
||||
bool MakeReadOnlyRequest(android::Parcel& aParcel, const CommandOptions& options);
|
||||
bool FormatRequest(android::Parcel& aParcel, const CommandOptions& options);
|
||||
bool ConnectRequest(android::Parcel& aParcel, const CommandOptions& options);
|
||||
bool CloseRequest(android::Parcel& aParcel, const CommandOptions& options);
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ interface nsINfcEventListener : nsISupports
|
|||
void notifyPeerLost(in DOMString sessionToken);
|
||||
};
|
||||
|
||||
[scriptable, uuid(486dff99-6755-428b-834d-3647ce276b54)]
|
||||
[scriptable, uuid(9343ae1a-6e2f-11e4-b5c4-fbb166b38b62)]
|
||||
interface nsINfcContentHelper : nsISupports
|
||||
{
|
||||
void init(in nsIDOMWindow window);
|
||||
|
@ -75,6 +75,7 @@ interface nsINfcContentHelper : nsISupports
|
|||
nsIDOMDOMRequest readNDEF(in DOMString sessionToken);
|
||||
nsIDOMDOMRequest writeNDEF(in nsIVariant records, in DOMString sessionToken);
|
||||
nsIDOMDOMRequest makeReadOnly(in DOMString sessionToken);
|
||||
nsIDOMDOMRequest format(in DOMString sessionToken);
|
||||
|
||||
nsIDOMDOMRequest connect(in unsigned long techType, in DOMString sessionToken);
|
||||
nsIDOMDOMRequest close(in DOMString sessionToken);
|
||||
|
|
|
@ -101,6 +101,19 @@ MozNFCTagImpl.prototype = {
|
|||
return this._nfcContentHelper.makeReadOnly(this.session);
|
||||
},
|
||||
|
||||
format: function format() {
|
||||
if (this.isLost) {
|
||||
throw new this._window.DOMError("InvalidStateError", "NFCTag object is invalid");
|
||||
}
|
||||
|
||||
if (!this.isFormatable) {
|
||||
throw new this._window.DOMError("InvalidAccessError",
|
||||
"NFCTag object is not formatable");
|
||||
}
|
||||
|
||||
return this._nfcContentHelper.format(this.session);
|
||||
},
|
||||
|
||||
classID: Components.ID("{4e1e2e90-3137-11e3-aa6e-0800200c9a66}"),
|
||||
contractID: "@mozilla.org/nfc/NFCTag;1",
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
|
||||
|
|
|
@ -17,6 +17,21 @@ using struct nsID from "nsID.h";
|
|||
namespace mozilla {
|
||||
namespace plugins {
|
||||
|
||||
struct PluginSettings
|
||||
{
|
||||
// These settings correspond to NPNVariable. They are fetched from
|
||||
// mozilla::plugins::parent::_getvalue.
|
||||
bool javascriptEnabled;
|
||||
bool asdEnabled;
|
||||
bool isOffline;
|
||||
bool supportsXembed;
|
||||
bool supportsWindowless;
|
||||
|
||||
// These settings come from elsewhere.
|
||||
nsCString userAgent;
|
||||
bool nativeCursorsSupported;
|
||||
};
|
||||
|
||||
intr protocol PPluginModule
|
||||
{
|
||||
bridges PContent, PPluginModule;
|
||||
|
@ -34,7 +49,7 @@ child:
|
|||
intr NP_GetEntryPoints()
|
||||
returns (NPError rv);
|
||||
|
||||
intr NP_Initialize()
|
||||
intr NP_Initialize(PluginSettings settings)
|
||||
returns (NPError rv);
|
||||
|
||||
intr PPluginInstance(nsCString aMimeType,
|
||||
|
@ -69,6 +84,8 @@ child:
|
|||
intr GeckoGetProfile()
|
||||
returns (nsCString aProfile);
|
||||
|
||||
async SettingChanged(PluginSettings settings);
|
||||
|
||||
parent:
|
||||
/**
|
||||
* This message is only used on X11 platforms.
|
||||
|
@ -83,13 +100,6 @@ parent:
|
|||
*/
|
||||
async BackUpXResources(FileDescriptor aXSocketFd);
|
||||
|
||||
intr NPN_UserAgent()
|
||||
returns (nsCString userAgent);
|
||||
|
||||
intr NPN_GetValue_WithBoolReturn(NPNVariable aVariable)
|
||||
returns (NPError aError,
|
||||
bool aBoolVal);
|
||||
|
||||
// Wake up and process a few native events. Periodically called by
|
||||
// Gtk-specific code upon detecting that the plugin process has
|
||||
// entered a nested event loop. If the browser doesn't process
|
||||
|
@ -108,7 +118,6 @@ parent:
|
|||
async ShowCursor(bool show);
|
||||
async PushCursor(NSCursorInfo cursorInfo);
|
||||
async PopCursor();
|
||||
sync GetNativeCursorsSupported() returns (bool supported);
|
||||
|
||||
sync NPN_SetException(nsCString message);
|
||||
|
||||
|
|
|
@ -821,10 +821,7 @@ PluginModuleChild::CleanUp()
|
|||
const char*
|
||||
PluginModuleChild::GetUserAgent()
|
||||
{
|
||||
if (mUserAgent.IsVoid() && !CallNPN_UserAgent(&mUserAgent))
|
||||
return nullptr;
|
||||
|
||||
return NullableStringGet(mUserAgent);
|
||||
return NullableStringGet(Settings().userAgent());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -1120,18 +1117,21 @@ _getvalue(NPP aNPP,
|
|||
#endif
|
||||
return NPERR_GENERIC_ERROR;
|
||||
|
||||
case NPNVjavascriptEnabledBool: // Intentional fall-through
|
||||
case NPNVasdEnabledBool: // Intentional fall-through
|
||||
case NPNVisOfflineBool: // Intentional fall-through
|
||||
case NPNVSupportsXEmbedBool: // Intentional fall-through
|
||||
case NPNVSupportsWindowless: { // Intentional fall-through
|
||||
NPError result;
|
||||
bool value;
|
||||
PluginModuleChild::GetChrome()->
|
||||
CallNPN_GetValue_WithBoolReturn(aVariable, &result, &value);
|
||||
*(NPBool*)aValue = value ? true : false;
|
||||
return result;
|
||||
}
|
||||
case NPNVjavascriptEnabledBool:
|
||||
*(NPBool*)aValue = PluginModuleChild::GetChrome()->Settings().javascriptEnabled();
|
||||
return NPERR_NO_ERROR;
|
||||
case NPNVasdEnabledBool:
|
||||
*(NPBool*)aValue = PluginModuleChild::GetChrome()->Settings().asdEnabled();
|
||||
return NPERR_NO_ERROR;
|
||||
case NPNVisOfflineBool:
|
||||
*(NPBool*)aValue = PluginModuleChild::GetChrome()->Settings().isOffline();
|
||||
return NPERR_NO_ERROR;
|
||||
case NPNVSupportsXEmbedBool:
|
||||
*(NPBool*)aValue = PluginModuleChild::GetChrome()->Settings().supportsXembed();
|
||||
return NPERR_NO_ERROR;
|
||||
case NPNVSupportsWindowless:
|
||||
*(NPBool*)aValue = PluginModuleChild::GetChrome()->Settings().supportsWindowless();
|
||||
return NPERR_NO_ERROR;
|
||||
#if defined(MOZ_WIDGET_GTK)
|
||||
case NPNVxDisplay: {
|
||||
if (aNPP) {
|
||||
|
@ -1834,6 +1834,13 @@ _urlredirectresponse(NPP instance, void* notifyData, NPBool allow)
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool
|
||||
PluginModuleChild::RecvSettingChanged(const PluginSettings& aSettings)
|
||||
{
|
||||
mCachedSettings = aSettings;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginModuleChild::AnswerNP_GetEntryPoints(NPError* _retval)
|
||||
{
|
||||
|
@ -1852,12 +1859,14 @@ PluginModuleChild::AnswerNP_GetEntryPoints(NPError* _retval)
|
|||
}
|
||||
|
||||
bool
|
||||
PluginModuleChild::AnswerNP_Initialize(NPError* _retval)
|
||||
PluginModuleChild::AnswerNP_Initialize(const PluginSettings& aSettings, NPError* _retval)
|
||||
{
|
||||
PLUGIN_LOG_DEBUG_METHOD;
|
||||
AssertPluginThread();
|
||||
MOZ_ASSERT(mIsChrome);
|
||||
|
||||
mCachedSettings = aSettings;
|
||||
|
||||
#ifdef OS_WIN
|
||||
SetEventHooks();
|
||||
#endif
|
||||
|
|
|
@ -72,9 +72,11 @@ protected:
|
|||
|
||||
virtual bool ShouldContinueFromReplyTimeout() MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvSettingChanged(const PluginSettings& aSettings) MOZ_OVERRIDE;
|
||||
|
||||
// Implement the PPluginModuleChild interface
|
||||
virtual bool AnswerNP_GetEntryPoints(NPError* rv) MOZ_OVERRIDE;
|
||||
virtual bool AnswerNP_Initialize(NPError* rv) MOZ_OVERRIDE;
|
||||
virtual bool AnswerNP_Initialize(const PluginSettings& aSettings, NPError* rv) MOZ_OVERRIDE;
|
||||
|
||||
virtual PPluginModuleChild*
|
||||
AllocPPluginModuleChild(mozilla::ipc::Transport* aTransport,
|
||||
|
@ -226,9 +228,7 @@ public:
|
|||
}
|
||||
|
||||
bool GetNativeCursorsSupported() {
|
||||
bool supported = false;
|
||||
SendGetNativeCursorsSupported(&supported);
|
||||
return supported;
|
||||
return Settings().nativeCursorsSupported();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -278,6 +278,8 @@ public:
|
|||
|
||||
int GetQuirks() { return mQuirks; }
|
||||
|
||||
const PluginSettings& Settings() const { return mCachedSettings; }
|
||||
|
||||
private:
|
||||
void AddQuirk(PluginQuirks quirk) {
|
||||
if (mQuirks == QUIRKS_NOT_INITIALIZED)
|
||||
|
@ -318,6 +320,8 @@ private:
|
|||
|
||||
NPPluginFuncs mFunctions;
|
||||
|
||||
PluginSettings mCachedSettings;
|
||||
|
||||
#if defined(MOZ_WIDGET_GTK)
|
||||
// If a plugin spins a nested glib event loop in response to a
|
||||
// synchronous IPC message from the browser, the loop might break
|
||||
|
|
|
@ -252,6 +252,8 @@ PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath, uint32
|
|||
Preferences::RegisterCallback(TimeoutChanged, kHangUIMinDisplayPref, this);
|
||||
#endif
|
||||
|
||||
RegisterSettingsCallbacks();
|
||||
|
||||
#ifdef MOZ_ENABLE_PROFILER_SPS
|
||||
InitPluginProfiling();
|
||||
#endif
|
||||
|
@ -295,6 +297,8 @@ PluginModuleChromeParent::~PluginModuleChromeParent()
|
|||
Preferences::UnregisterCallback(TimeoutChanged, kHangUITimeoutPref, this);
|
||||
Preferences::UnregisterCallback(TimeoutChanged, kHangUIMinDisplayPref, this);
|
||||
|
||||
UnregisterSettingsCallbacks();
|
||||
|
||||
if (mHangUIParent) {
|
||||
delete mHangUIParent;
|
||||
mHangUIParent = nullptr;
|
||||
|
@ -903,6 +907,9 @@ PluginModuleChromeParent::ActorDestroy(ActorDestroyReason why)
|
|||
#endif
|
||||
}
|
||||
|
||||
// We can't broadcast settings changes anymore.
|
||||
UnregisterSettingsCallbacks();
|
||||
|
||||
PluginModuleParent::ActorDestroy(why);
|
||||
}
|
||||
|
||||
|
@ -1156,13 +1163,6 @@ PluginModuleParent::NPP_URLRedirectNotify(NPP instance, const char* url,
|
|||
i->NPP_URLRedirectNotify(url, status, notifyData);
|
||||
}
|
||||
|
||||
bool
|
||||
PluginModuleParent::AnswerNPN_UserAgent(nsCString* userAgent)
|
||||
{
|
||||
*userAgent = NullableString(mNPNIface->uagent(nullptr));
|
||||
return true;
|
||||
}
|
||||
|
||||
PluginInstanceParent*
|
||||
PluginModuleParent::InstCast(NPP instance)
|
||||
{
|
||||
|
@ -1262,6 +1262,107 @@ PluginModuleParent::EndUpdateBackground(NPP instance,
|
|||
return i->EndUpdateBackground(aCtx, aRect);
|
||||
}
|
||||
|
||||
class OfflineObserver MOZ_FINAL : public nsIObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
explicit OfflineObserver(PluginModuleChromeParent* pmp)
|
||||
: mPmp(pmp)
|
||||
{}
|
||||
|
||||
private:
|
||||
~OfflineObserver() {}
|
||||
PluginModuleChromeParent* mPmp;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(OfflineObserver, nsIObserver)
|
||||
|
||||
NS_IMETHODIMP
|
||||
OfflineObserver::Observe(nsISupports *aSubject,
|
||||
const char *aTopic,
|
||||
const char16_t *aData)
|
||||
{
|
||||
MOZ_ASSERT(!strcmp(aTopic, "ipc:network:set-offline"));
|
||||
mPmp->CachedSettingChanged();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static const char* kSettingsPrefs[] =
|
||||
{"javascript.enabled",
|
||||
"dom.ipc.plugins.nativeCursorSupport"};
|
||||
|
||||
void
|
||||
PluginModuleChromeParent::RegisterSettingsCallbacks()
|
||||
{
|
||||
for (size_t i = 0; i < ArrayLength(kSettingsPrefs); i++) {
|
||||
Preferences::RegisterCallback(CachedSettingChanged, kSettingsPrefs[i], this);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
|
||||
if (observerService) {
|
||||
mOfflineObserver = new OfflineObserver(this);
|
||||
observerService->AddObserver(mOfflineObserver, "ipc:network:set-offline", false);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PluginModuleChromeParent::UnregisterSettingsCallbacks()
|
||||
{
|
||||
for (size_t i = 0; i < ArrayLength(kSettingsPrefs); i++) {
|
||||
Preferences::UnregisterCallback(CachedSettingChanged, kSettingsPrefs[i], this);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
|
||||
if (observerService) {
|
||||
observerService->RemoveObserver(mOfflineObserver, "ipc:network:set-offline");
|
||||
mOfflineObserver = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
PluginModuleParent::GetSetting(NPNVariable aVariable)
|
||||
{
|
||||
NPBool boolVal = false;
|
||||
mozilla::plugins::parent::_getvalue(nullptr, aVariable, &boolVal);
|
||||
return boolVal;
|
||||
}
|
||||
|
||||
void
|
||||
PluginModuleParent::GetSettings(PluginSettings* aSettings)
|
||||
{
|
||||
aSettings->javascriptEnabled() = GetSetting(NPNVjavascriptEnabledBool);
|
||||
aSettings->asdEnabled() = GetSetting(NPNVasdEnabledBool);
|
||||
aSettings->isOffline() = GetSetting(NPNVisOfflineBool);
|
||||
aSettings->supportsXembed() = GetSetting(NPNVSupportsXEmbedBool);
|
||||
aSettings->supportsWindowless() = GetSetting(NPNVSupportsWindowless);
|
||||
aSettings->userAgent() = NullableString(mNPNIface->uagent(nullptr));
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
aSettings->nativeCursorsSupported() =
|
||||
Preferences::GetBool("dom.ipc.plugins.nativeCursorSupport", false);
|
||||
#else
|
||||
// Need to initialize this to satisfy IPDL.
|
||||
aSettings->nativeCursorsSupported() = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
PluginModuleChromeParent::CachedSettingChanged()
|
||||
{
|
||||
PluginSettings settings;
|
||||
GetSettings(&settings);
|
||||
unused << SendSettingChanged(settings);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
PluginModuleChromeParent::CachedSettingChanged(const char* aPref, void* aModule)
|
||||
{
|
||||
PluginModuleChromeParent *module = static_cast<PluginModuleChromeParent*>(aModule);
|
||||
module->CachedSettingChanged();
|
||||
}
|
||||
|
||||
#if defined(XP_UNIX) && !defined(XP_MACOSX) && !defined(MOZ_WIDGET_GONK)
|
||||
nsresult
|
||||
PluginModuleParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs, NPError* error)
|
||||
|
@ -1277,7 +1378,9 @@ PluginModuleParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs
|
|||
|
||||
*error = NPERR_NO_ERROR;
|
||||
if (IsChrome()) {
|
||||
if (!CallNP_Initialize(error)) {
|
||||
PluginSettings settings;
|
||||
GetSettings(&settings);
|
||||
if (!CallNP_Initialize(settings, error)) {
|
||||
Close();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -1315,7 +1418,9 @@ PluginModuleChromeParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error)
|
|||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (!CallNP_Initialize(error)) {
|
||||
PluginSettings settings;
|
||||
GetSettings(&settings);
|
||||
if (!CallNP_Initialize(settings, error)) {
|
||||
Close();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -1539,17 +1644,6 @@ PluginModuleParent::ContentsScaleFactorChanged(NPP instance, double aContentsSca
|
|||
}
|
||||
#endif // #if defined(XP_MACOSX)
|
||||
|
||||
bool
|
||||
PluginModuleParent::AnswerNPN_GetValue_WithBoolReturn(const NPNVariable& aVariable,
|
||||
NPError* aError,
|
||||
bool* aBoolVal)
|
||||
{
|
||||
NPBool boolVal = false;
|
||||
*aError = mozilla::plugins::parent::_getvalue(nullptr, aVariable, &boolVal);
|
||||
*aBoolVal = boolVal ? true : false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(MOZ_WIDGET_QT)
|
||||
static const int kMaxtimeToProcessEvents = 30;
|
||||
bool
|
||||
|
@ -1749,21 +1843,6 @@ PluginModuleParent::RecvPopCursor()
|
|||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
PluginModuleParent::RecvGetNativeCursorsSupported(bool* supported)
|
||||
{
|
||||
PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
|
||||
#if defined(XP_MACOSX)
|
||||
*supported =
|
||||
Preferences::GetBool("dom.ipc.plugins.nativeCursorSupport", false);
|
||||
return true;
|
||||
#else
|
||||
NS_NOTREACHED(
|
||||
"PluginInstanceParent::RecvGetNativeCursorSupportLevel not implemented!");
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
PluginModuleParent::RecvNPN_SetException(const nsCString& aMessage)
|
||||
{
|
||||
|
|
|
@ -115,14 +115,6 @@ protected:
|
|||
virtual bool
|
||||
RecvBackUpXResources(const FileDescriptor& aXSocketFd) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
AnswerNPN_UserAgent(nsCString* userAgent) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
AnswerNPN_GetValue_WithBoolReturn(const NPNVariable& aVariable,
|
||||
NPError* aError,
|
||||
bool* aBoolVal) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool AnswerProcessSomeEvents() MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
|
@ -154,9 +146,6 @@ protected:
|
|||
virtual bool
|
||||
RecvPopCursor() MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
RecvGetNativeCursorsSupported(bool* supported) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
RecvNPN_SetException(const nsCString& aMessage) MOZ_OVERRIDE;
|
||||
|
||||
|
@ -242,6 +231,9 @@ protected:
|
|||
protected:
|
||||
void NotifyPluginCrashed();
|
||||
|
||||
bool GetSetting(NPNVariable aVariable);
|
||||
void GetSettings(PluginSettings* aSettings);
|
||||
|
||||
bool mIsChrome;
|
||||
bool mShutdown;
|
||||
bool mClearSiteDataSupported;
|
||||
|
@ -312,6 +304,8 @@ class PluginModuleChromeParent
|
|||
OnHangUIContinue();
|
||||
#endif // XP_WIN
|
||||
|
||||
void CachedSettingChanged();
|
||||
|
||||
private:
|
||||
virtual void
|
||||
EnteredCxxStack() MOZ_OVERRIDE;
|
||||
|
@ -360,8 +354,13 @@ private:
|
|||
void ShutdownPluginProfiling();
|
||||
#endif
|
||||
|
||||
void RegisterSettingsCallbacks();
|
||||
void UnregisterSettingsCallbacks();
|
||||
|
||||
virtual bool RecvNotifyContentModuleDestroyed() MOZ_OVERRIDE;
|
||||
|
||||
static void CachedSettingChanged(const char* aPref, void* aModule);
|
||||
|
||||
PluginProcessParent* mSubprocess;
|
||||
uint32_t mPluginId;
|
||||
|
||||
|
@ -422,6 +421,8 @@ private:
|
|||
DWORD mFlashProcess1;
|
||||
DWORD mFlashProcess2;
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIObserver> mOfflineObserver;
|
||||
};
|
||||
|
||||
} // namespace plugins
|
||||
|
|
|
@ -661,6 +661,8 @@ var interfaceNamesInGlobalScope =
|
|||
{name: "MediaKeys", pref: "media.eme.enabled"},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "MediaKeySession", pref: "media.eme.enabled"},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "MediaKeySystemAccess", pref: "media.eme.enabled"},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "MediaKeyMessageEvent", pref: "media.eme.enabled"},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
|
|
@ -47,7 +47,8 @@ interface CanvasRenderingContext2D {
|
|||
void transform(double a, double b, double c, double d, double e, double f);
|
||||
[Throws, LenientFloat]
|
||||
void setTransform(double a, double b, double c, double d, double e, double f);
|
||||
// NOT IMPLEMENTED void resetTransform();
|
||||
[Throws]
|
||||
void resetTransform();
|
||||
|
||||
// compositing
|
||||
attribute unrestricted double globalAlpha; // (default 1.0)
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/.
|
||||
*
|
||||
* The origin of this IDL file is
|
||||
* https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html
|
||||
*
|
||||
* Copyright © 2014 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved.
|
||||
* W3C liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
enum MediaKeysRequirement {
|
||||
"required",
|
||||
"optional",
|
||||
"disallowed"
|
||||
};
|
||||
|
||||
dictionary MediaKeySystemOptions {
|
||||
DOMString initDataType = "";
|
||||
DOMString audioType = "";
|
||||
DOMString audioCapability = "";
|
||||
DOMString videoType = "";
|
||||
DOMString videoCapability = "";
|
||||
MediaKeysRequirement uniqueidentifier = "optional";
|
||||
MediaKeysRequirement stateful = "optional";
|
||||
};
|
||||
|
||||
[Pref="media.eme.enabled"]
|
||||
interface MediaKeySystemAccess {
|
||||
readonly attribute DOMString keySystem;
|
||||
[NewObject, Throws]
|
||||
Promise<MediaKeys> createMediaKeys();
|
||||
};
|
|
@ -22,9 +22,4 @@ interface MediaKeys {
|
|||
|
||||
[NewObject, Throws]
|
||||
Promise<void> setServerCertificate((ArrayBufferView or ArrayBuffer) serverCertificate);
|
||||
|
||||
[Throws,NewObject]
|
||||
static Promise<MediaKeys> create(DOMString keySystem);
|
||||
static IsTypeSupportedResult isTypeSupported(DOMString keySystem, optional DOMString initDataType, optional DOMString contentType, optional DOMString capability);
|
||||
|
||||
};
|
||||
|
|
|
@ -74,6 +74,9 @@ interface MozNFCTag {
|
|||
|
||||
[Throws]
|
||||
DOMRequest makeReadOnly();
|
||||
|
||||
[Throws]
|
||||
DOMRequest format();
|
||||
};
|
||||
|
||||
// Mozilla Only
|
||||
|
|
|
@ -397,3 +397,12 @@ partial interface Navigator {
|
|||
[Pref="dom.tv.enabled", CheckPermissions="tv", Func="Navigator::HasTVSupport"]
|
||||
readonly attribute TVManager? tv;
|
||||
};
|
||||
|
||||
#ifdef MOZ_EME
|
||||
partial interface Navigator {
|
||||
[Pref="media.eme.enabled", Throws, NewObject]
|
||||
Promise<MediaKeySystemAccess>
|
||||
requestMediaKeySystemAccess(DOMString keySystem,
|
||||
optional sequence<MediaKeySystemOptions> supportedConfigurations);
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -798,4 +798,5 @@ if CONFIG['MOZ_EME']:
|
|||
'MediaKeyMessageEvent.webidl',
|
||||
'MediaKeys.webidl',
|
||||
'MediaKeySession.webidl',
|
||||
'MediaKeySystemAccess.webidl',
|
||||
]
|
||||
|
|
|
@ -758,7 +758,8 @@ ScriptExecutorRunnable::WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
|||
loadInfo.mScriptTextBuf = nullptr;
|
||||
loadInfo.mScriptTextLength = 0;
|
||||
|
||||
if (!JS::Evaluate(aCx, global, options, srcBuf)) {
|
||||
JS::Rooted<JS::Value> unused(aCx);
|
||||
if (!JS::Evaluate(aCx, global, options, srcBuf, &unused)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -5631,8 +5631,10 @@ WorkerPrivate::RunExpiredTimeouts(JSContext* aCx)
|
|||
options.setFileAndLine(info->mFilename.get(), info->mLineNumber)
|
||||
.setNoScriptRval(true);
|
||||
|
||||
JS::Rooted<JS::Value> unused(aCx);
|
||||
if ((expression.IsEmpty() ||
|
||||
!JS::Evaluate(aCx, global, options, expression.get(), expression.Length())) &&
|
||||
!JS::Evaluate(aCx, global, options,
|
||||
expression.get(), expression.Length(), &unused)) &&
|
||||
!JS_ReportPendingException(aCx)) {
|
||||
retval = false;
|
||||
break;
|
||||
|
|
|
@ -843,7 +843,7 @@ DrawTargetSkia::Init(unsigned char* aData, const IntSize &aSize, int32_t aStride
|
|||
alphaType);
|
||||
bitmap.setInfo(info, aStride);
|
||||
bitmap.setPixels(aData);
|
||||
mCanvas.adopt(new SkCanvas(new SkBitmapDevice(bitmap)));
|
||||
mCanvas.adopt(new SkCanvas(bitmap));
|
||||
|
||||
mSize = aSize;
|
||||
mFormat = aFormat;
|
||||
|
|
|
@ -156,8 +156,31 @@ HasCPUIDBit(unsigned int level, CPUIDRegister reg, unsigned int bit)
|
|||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
// XXX - Need to define an API to set this.
|
||||
GFX2D_API int sGfxLogLevel = LOG_DEBUG;
|
||||
// These values we initialize with should match those in
|
||||
// PreferenceAccess::RegisterAll method.
|
||||
int32_t PreferenceAccess::sGfxLogLevel = LOG_DEFAULT;
|
||||
|
||||
PreferenceAccess* PreferenceAccess::sAccess = nullptr;
|
||||
PreferenceAccess::~PreferenceAccess()
|
||||
{
|
||||
}
|
||||
|
||||
// Just a placeholder, the derived class will set the variable to default
|
||||
// if the preference doesn't exist.
|
||||
void PreferenceAccess::LivePref(const char* aName, int32_t* aVar, int32_t aDef)
|
||||
{
|
||||
*aVar = aDef;
|
||||
}
|
||||
|
||||
// This will be called with the derived class, so we will want to register
|
||||
// the callbacks with it.
|
||||
void PreferenceAccess::SetAccess(PreferenceAccess* aAccess) {
|
||||
sAccess = aAccess;
|
||||
if (sAccess) {
|
||||
RegisterAll();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
ID3D10Device1 *Factory::mD3D10Device;
|
||||
|
@ -795,13 +818,14 @@ Factory::SetLogForwarder(LogForwarder* aLogFwd) {
|
|||
|
||||
// static
|
||||
void
|
||||
CriticalLogger::OutputMessage(const std::string &aString, int aLevel)
|
||||
CriticalLogger::OutputMessage(const std::string &aString,
|
||||
int aLevel, bool aNoNewline)
|
||||
{
|
||||
if (Factory::GetLogForwarder()) {
|
||||
Factory::GetLogForwarder()->Log(aString);
|
||||
}
|
||||
|
||||
BasicLogger::OutputMessage(aString, aLevel);
|
||||
BasicLogger::OutputMessage(aString, aLevel, aNoNewline);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
378
gfx/2d/Logging.h
378
gfx/2d/Logging.h
|
@ -40,51 +40,136 @@ extern GFX2D_API PRLogModuleInfo *GetGFX2DLog();
|
|||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
const int LOG_DEBUG = 1;
|
||||
// Attempting to be consistent with prlog values, but that isn't critical
|
||||
// (and note that 5 has a special meaning - see the description
|
||||
// with sGfxLogLevel)
|
||||
const int LOG_CRITICAL = 1;
|
||||
const int LOG_WARNING = 2;
|
||||
const int LOG_CRITICAL = 3;
|
||||
const int LOG_DEBUG = 3;
|
||||
const int LOG_DEBUG_PRLOG = 4;
|
||||
const int LOG_EVERYTHING = 5; // This needs to be the highest value
|
||||
|
||||
#if defined(DEBUG)
|
||||
const int LOG_DEFAULT = LOG_EVERYTHING;
|
||||
#else
|
||||
const int LOG_DEFAULT = LOG_CRITICAL;
|
||||
#endif
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
|
||||
inline PRLogModuleLevel PRLogLevelForLevel(int aLevel) {
|
||||
switch (aLevel) {
|
||||
case LOG_DEBUG:
|
||||
return PR_LOG_DEBUG;
|
||||
case LOG_CRITICAL:
|
||||
return PR_LOG_ERROR;
|
||||
case LOG_WARNING:
|
||||
return PR_LOG_WARNING;
|
||||
case LOG_DEBUG:
|
||||
return PR_LOG_DEBUG;
|
||||
case LOG_DEBUG_PRLOG:
|
||||
return PR_LOG_DEBUG;
|
||||
case LOG_EVERYTHING:
|
||||
return PR_LOG_ALWAYS;
|
||||
}
|
||||
return PR_LOG_DEBUG;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
extern GFX2D_API int sGfxLogLevel;
|
||||
class PreferenceAccess
|
||||
{
|
||||
public:
|
||||
virtual ~PreferenceAccess();
|
||||
|
||||
// This should connect the variable aVar to be updated whenever a preference
|
||||
// aName is modified. aDefault would be used if the preference is undefined,
|
||||
// so that we always get the valid value for aVar.
|
||||
virtual void LivePref(const char* aName, int32_t* aVar, int32_t aDefault);
|
||||
|
||||
public:
|
||||
static void SetAccess(PreferenceAccess* aAccess);
|
||||
|
||||
public:
|
||||
// For each preference that needs to be accessed in Moz2D, add a variable
|
||||
// to hold it, as well as the call to LivePref in the RegisterAll() method
|
||||
// below.
|
||||
|
||||
// Used to choose the level of logging we get. The higher the number,
|
||||
// the more logging we get. Value of zero will give you no logging,
|
||||
// 1 just errors, 2 adds warnings and 3 adds logging/debug. 4 is used to
|
||||
// selectively enable logging on the configurations that
|
||||
// support prlog (on other systems, 3 and 4 are the same.) For prlog,
|
||||
// in addition to setting the value to 4, you will need to set an
|
||||
// environment variable NSPR_LOG_MODULES to gfx:4. See prlog.h for details.
|
||||
static int32_t sGfxLogLevel;
|
||||
|
||||
private:
|
||||
static void RegisterAll() {
|
||||
// The default values (last parameter) should match the initialization
|
||||
// values in Factory.cpp, otherwise the standalone Moz2D will get different
|
||||
// defaults.
|
||||
sAccess->LivePref("gfx.logging.level", &sGfxLogLevel, LOG_DEFAULT);
|
||||
}
|
||||
static PreferenceAccess* sAccess;
|
||||
};
|
||||
|
||||
struct BasicLogger
|
||||
{
|
||||
static void OutputMessage(const std::string &aString, int aLevel) {
|
||||
// For efficiency, this method exists and copies the logic of the
|
||||
// OutputMessage below. If making any changes here, also make it
|
||||
// in the appropriate places in that method.
|
||||
static bool ShouldOutputMessage(int aLevel) {
|
||||
if (PreferenceAccess::sGfxLogLevel >= aLevel) {
|
||||
#if defined(WIN32) && !defined(PR_LOGGING)
|
||||
if (aLevel >= sGfxLogLevel) {
|
||||
::OutputDebugStringA(aString.c_str());
|
||||
}
|
||||
#elif defined(PR_LOGGING) && !(defined(MOZ_WIDGET_GONK) || defined(MOZ_WIDGET_ANDROID))
|
||||
if (PR_LOG_TEST(GetGFX2DLog(), PRLogLevelForLevel(aLevel))) {
|
||||
PR_LogPrint(aString.c_str());
|
||||
}
|
||||
return true;
|
||||
#elif defined(MOZ_WIDGET_GONK) || defined(MOZ_WIDGET_ANDROID)
|
||||
return true;
|
||||
#elif defined(PR_LOGGING)
|
||||
if (PR_LOG_TEST(GetGFX2DLog(), PRLogLevelForLevel(aLevel))) {
|
||||
return true;
|
||||
} else if ((PreferenceAccess::sGfxLogLevel >= LOG_DEBUG_PRLOG) ||
|
||||
(aLevel < LOG_DEBUG)) {
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
if (aLevel >= sGfxLogLevel) {
|
||||
#if defined(MOZ_WIDGET_GONK) || defined(MOZ_WIDGET_ANDROID)
|
||||
printf_stderr("%s", aString.c_str());
|
||||
#else
|
||||
printf("%s", aString.c_str());
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void OutputMessage(const std::string &aString,
|
||||
int aLevel,
|
||||
bool aNoNewline) {
|
||||
// This behavior (the higher the preference, the more we log)
|
||||
// is consistent with what prlog does in general. Note that if prlog
|
||||
// is in the build, but disabled, we will printf if the preferences
|
||||
// requires us to log something (see sGfxLogLevel for the special
|
||||
// treatment of LOG_DEBUG and LOG_DEBUG_PRLOG)
|
||||
//
|
||||
// If making any logic changes to this method, you should probably
|
||||
// make the corresponding change in the ShouldOutputMessage method
|
||||
// above.
|
||||
if (PreferenceAccess::sGfxLogLevel >= aLevel) {
|
||||
#if defined(WIN32) && !defined(PR_LOGGING)
|
||||
::OutputDebugStringA((aNoNewline ? aString : aString+"\n").c_str());
|
||||
#elif defined(MOZ_WIDGET_GONK) || defined(MOZ_WIDGET_ANDROID)
|
||||
printf_stderr("%s%s", aString.c_str(), aNoNewline ? "" : "\n");
|
||||
#elif defined(PR_LOGGING)
|
||||
if (PR_LOG_TEST(GetGFX2DLog(), PRLogLevelForLevel(aLevel))) {
|
||||
PR_LogPrint("%s%s", aString.c_str(), aNoNewline ? "" : "\n");
|
||||
} else if ((PreferenceAccess::sGfxLogLevel >= LOG_DEBUG_PRLOG) ||
|
||||
(aLevel < LOG_DEBUG)) {
|
||||
printf("%s%s", aString.c_str(), aNoNewline ? "" : "\n");
|
||||
}
|
||||
#else
|
||||
printf("%s%s", aString.c_str(), aNoNewline ? "" : "\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct CriticalLogger {
|
||||
static void OutputMessage(const std::string &aString, int aLevel);
|
||||
static void OutputMessage(const std::string &aString, int aLevel, bool aNoNewline);
|
||||
};
|
||||
|
||||
// Implement this interface and init the Factory with an instance to
|
||||
|
@ -106,7 +191,8 @@ public:
|
|||
};
|
||||
|
||||
MOZ_BEGIN_ENUM_CLASS(LogOptions, int)
|
||||
NoNewline = 0x01
|
||||
NoNewline = 0x01,
|
||||
AutoPrefix = 0x02
|
||||
MOZ_END_ENUM_CLASS(LogOptions)
|
||||
|
||||
template<typename T>
|
||||
|
@ -121,58 +207,238 @@ template<int L, typename Logger = BasicLogger>
|
|||
class Log
|
||||
{
|
||||
public:
|
||||
explicit Log(LogOptions aOptions = LogOptions(0)) : mOptions(aOptions) {}
|
||||
explicit Log(int aOptions = (int)LogOptions::AutoPrefix)
|
||||
: mOptions(aOptions)
|
||||
, mLogIt(BasicLogger::ShouldOutputMessage(L))
|
||||
{
|
||||
if (mLogIt && AutoPrefix()) {
|
||||
mMessage << "[GFX" << L << "]: ";
|
||||
}
|
||||
}
|
||||
~Log() {
|
||||
Flush();
|
||||
}
|
||||
|
||||
void Flush() {
|
||||
if (!(int(mOptions) & int(LogOptions::NoNewline))) {
|
||||
mMessage << '\n';
|
||||
}
|
||||
if (MOZ_LIKELY(!LogIt())) return;
|
||||
|
||||
std::string str = mMessage.str();
|
||||
if (!str.empty()) {
|
||||
WriteLog(str);
|
||||
}
|
||||
mMessage.str("");
|
||||
if (AutoPrefix()) {
|
||||
mMessage.str("[GFX");
|
||||
mMessage << L << "]: ";
|
||||
} else {
|
||||
mMessage.str("");
|
||||
}
|
||||
mMessage.clear();
|
||||
}
|
||||
|
||||
Log &operator <<(char aChar) { mMessage << aChar; return *this; }
|
||||
Log &operator <<(const std::string &aLogText) { mMessage << aLogText; return *this; }
|
||||
Log &operator <<(const char aStr[]) { mMessage << static_cast<const char*>(aStr); return *this; }
|
||||
Log &operator <<(bool aBool) { mMessage << (aBool ? "true" : "false"); return *this; }
|
||||
Log &operator <<(int aInt) { mMessage << aInt; return *this; }
|
||||
Log &operator <<(unsigned int aInt) { mMessage << aInt; return *this; }
|
||||
Log &operator <<(long aLong) { mMessage << aLong; return *this; }
|
||||
Log &operator <<(unsigned long aLong) { mMessage << aLong; return *this; }
|
||||
Log &operator <<(long long aLong) { mMessage << aLong; return *this; }
|
||||
Log &operator <<(unsigned long long aLong) { mMessage << aLong; return *this; }
|
||||
Log &operator <<(Float aFloat) { mMessage << aFloat; return *this; }
|
||||
Log &operator <<(double aDouble) { mMessage << aDouble; return *this; }
|
||||
Log &operator <<(char aChar) {
|
||||
if (MOZ_UNLIKELY(LogIt())) {
|
||||
mMessage << aChar;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Log &operator <<(const std::string &aLogText) {
|
||||
if (MOZ_UNLIKELY(LogIt())) {
|
||||
mMessage << aLogText;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Log &operator <<(const char aStr[]) {
|
||||
if (MOZ_UNLIKELY(LogIt())) {
|
||||
mMessage << static_cast<const char*>(aStr);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Log &operator <<(bool aBool) {
|
||||
if (MOZ_UNLIKELY(LogIt())) {
|
||||
mMessage << (aBool ? "true" : "false");
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Log &operator <<(int aInt) {
|
||||
if (MOZ_UNLIKELY(LogIt())) {
|
||||
mMessage << aInt;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Log &operator <<(unsigned int aInt) {
|
||||
if (MOZ_UNLIKELY(LogIt())) {
|
||||
mMessage << aInt;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Log &operator <<(long aLong) {
|
||||
if (MOZ_UNLIKELY(LogIt())) {
|
||||
mMessage << aLong;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Log &operator <<(unsigned long aLong) {
|
||||
if (MOZ_UNLIKELY(LogIt())) {
|
||||
mMessage << aLong;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Log &operator <<(long long aLong) {
|
||||
if (MOZ_UNLIKELY(LogIt())) {
|
||||
mMessage << aLong;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Log &operator <<(unsigned long long aLong) {
|
||||
if (MOZ_UNLIKELY(LogIt())) {
|
||||
mMessage << aLong;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Log &operator <<(Float aFloat) {
|
||||
if (MOZ_UNLIKELY(LogIt())) {
|
||||
mMessage << aFloat;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Log &operator <<(double aDouble) {
|
||||
if (MOZ_UNLIKELY(LogIt())) {
|
||||
mMessage << aDouble;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
template <typename T, typename Sub, typename Coord>
|
||||
Log &operator <<(const BasePoint<T, Sub, Coord>& aPoint)
|
||||
{ mMessage << "Point" << aPoint; return *this; }
|
||||
Log &operator <<(const BasePoint<T, Sub, Coord>& aPoint) {
|
||||
if (MOZ_UNLIKELY(LogIt())) {
|
||||
mMessage << "Point" << aPoint;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
template <typename T, typename Sub>
|
||||
Log &operator <<(const BaseSize<T, Sub>& aSize)
|
||||
{ mMessage << "Size(" << aSize.width << "," << aSize.height << ")"; return *this; }
|
||||
Log &operator <<(const BaseSize<T, Sub>& aSize) {
|
||||
if (MOZ_UNLIKELY(LogIt())) {
|
||||
mMessage << "Size(" << aSize.width << "," << aSize.height << ")";
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
template <typename T, typename Sub, typename Point, typename SizeT, typename Margin>
|
||||
Log &operator <<(const BaseRect<T, Sub, Point, SizeT, Margin>& aRect)
|
||||
{ mMessage << "Rect" << aRect; return *this; }
|
||||
Log &operator<<(const Matrix& aMatrix)
|
||||
{ mMessage << "Matrix(" << aMatrix._11 << " " << aMatrix._12 << " ; " << aMatrix._21 << " " << aMatrix._22 << " ; " << aMatrix._31 << " " << aMatrix._32 << ")"; return *this; }
|
||||
Log &operator <<(const BaseRect<T, Sub, Point, SizeT, Margin>& aRect) {
|
||||
if (MOZ_UNLIKELY(LogIt())) {
|
||||
mMessage << "Rect" << aRect;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
Log &operator<<(const Matrix& aMatrix) {
|
||||
if (MOZ_UNLIKELY(LogIt())) {
|
||||
mMessage << "Matrix(" << aMatrix._11 << " " << aMatrix._12 << " ; " << aMatrix._21 << " " << aMatrix._22 << " ; " << aMatrix._31 << " " << aMatrix._32 << ")";
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
template<typename T>
|
||||
Log &operator<<(Hexa<T> aHex)
|
||||
{ mMessage << "0x" << std::hex << aHex.mVal << std::dec; return *this; }
|
||||
Log &operator<<(Hexa<T> aHex) {
|
||||
if (MOZ_UNLIKELY(LogIt())) {
|
||||
mMessage << "0x" << std::hex << aHex.mVal << std::dec;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Log& operator<<(SurfaceFormat aFormat) {
|
||||
if (MOZ_UNLIKELY(LogIt())) {
|
||||
switch(aFormat) {
|
||||
case SurfaceFormat::B8G8R8A8:
|
||||
mMessage << "SurfaceFormat::B8G8R8A8";
|
||||
break;
|
||||
case SurfaceFormat::B8G8R8X8:
|
||||
mMessage << "SurfaceFormat::B8G8R8X8";
|
||||
break;
|
||||
case SurfaceFormat::R8G8B8A8:
|
||||
mMessage << "SurfaceFormat::R8G8B8A8";
|
||||
break;
|
||||
case SurfaceFormat::R8G8B8X8:
|
||||
mMessage << "SurfaceFormat::R8G8B8X8";
|
||||
break;
|
||||
case SurfaceFormat::R5G6B5:
|
||||
mMessage << "SurfaceFormat::R5G6B5";
|
||||
break;
|
||||
case SurfaceFormat::A8:
|
||||
mMessage << "SurfaceFormat::A8";
|
||||
break;
|
||||
case SurfaceFormat::YUV:
|
||||
mMessage << "SurfaceFormat::YUV";
|
||||
break;
|
||||
case SurfaceFormat::UNKNOWN:
|
||||
mMessage << "SurfaceFormat::UNKNOWN";
|
||||
break;
|
||||
default:
|
||||
mMessage << "Invalid SurfaceFormat (" << (int)aFormat << ")";
|
||||
break;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Log& operator<<(SurfaceType aType) {
|
||||
if (MOZ_UNLIKELY(LogIt())) {
|
||||
switch(aType) {
|
||||
case SurfaceType::DATA:
|
||||
mMessage << "SurfaceType::DATA";
|
||||
break;
|
||||
case SurfaceType::D2D1_BITMAP:
|
||||
mMessage << "SurfaceType::D2D1_BITMAP";
|
||||
break;
|
||||
case SurfaceType::D2D1_DRAWTARGET:
|
||||
mMessage << "SurfaceType::D2D1_DRAWTARGET";
|
||||
break;
|
||||
case SurfaceType::CAIRO:
|
||||
mMessage << "SurfaceType::CAIRO";
|
||||
break;
|
||||
case SurfaceType::CAIRO_IMAGE:
|
||||
mMessage << "SurfaceType::CAIRO_IMAGE";
|
||||
break;
|
||||
case SurfaceType::COREGRAPHICS_IMAGE:
|
||||
mMessage << "SurfaceType::COREGRAPHICS_IMAGE";
|
||||
break;
|
||||
case SurfaceType::COREGRAPHICS_CGCONTEXT:
|
||||
mMessage << "SurfaceType::COREGRAPHICS_CGCONTEXT";
|
||||
break;
|
||||
case SurfaceType::SKIA:
|
||||
mMessage << "SurfaceType::SKIA";
|
||||
break;
|
||||
case SurfaceType::DUAL_DT:
|
||||
mMessage << "SurfaceType::DUAL_DT";
|
||||
break;
|
||||
case SurfaceType::D2D1_1_IMAGE:
|
||||
mMessage << "SurfaceType::D2D1_1_IMAGE";
|
||||
break;
|
||||
case SurfaceType::RECORDING:
|
||||
mMessage << "SurfaceType::RECORDING";
|
||||
break;
|
||||
case SurfaceType::TILED:
|
||||
mMessage << "SurfaceType::TILED";
|
||||
break;
|
||||
default:
|
||||
mMessage << "Invalid SurfaceType (" << (int)aType << ")";
|
||||
break;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool LogIt() const { return mLogIt; }
|
||||
inline bool NoNewline() const { return mOptions & int(LogOptions::NoNewline); }
|
||||
inline bool AutoPrefix() const { return mOptions & int(LogOptions::AutoPrefix); }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void WriteLog(const std::string &aString) {
|
||||
Logger::OutputMessage(aString, L);
|
||||
if (MOZ_UNLIKELY(LogIt())) {
|
||||
Logger::OutputMessage(aString, L, NoNewline());
|
||||
}
|
||||
}
|
||||
|
||||
std::stringstream mMessage;
|
||||
LogOptions mOptions;
|
||||
int mOptions;
|
||||
bool mLogIt;
|
||||
};
|
||||
|
||||
typedef Log<LOG_DEBUG> DebugLog;
|
||||
|
@ -180,18 +446,18 @@ typedef Log<LOG_WARNING> WarningLog;
|
|||
typedef Log<LOG_CRITICAL, CriticalLogger> CriticalLog;
|
||||
|
||||
#ifdef GFX_LOG_DEBUG
|
||||
#define gfxDebug DebugLog
|
||||
#define gfxDebug mozilla::gfx::DebugLog
|
||||
#else
|
||||
#define gfxDebug if (1) ; else NoLog
|
||||
#define gfxDebug if (1) ; else mozilla::gfx::NoLog
|
||||
#endif
|
||||
#ifdef GFX_LOG_WARNING
|
||||
#define gfxWarning WarningLog
|
||||
#define gfxWarning mozilla::gfx::WarningLog
|
||||
#else
|
||||
#define gfxWarning if (1) ; else NoLog
|
||||
#define gfxWarning if (1) ; else mozilla::gfx::NoLog
|
||||
#endif
|
||||
|
||||
// This log goes into crash reports, use with care.
|
||||
#define gfxCriticalError CriticalLog
|
||||
#define gfxCriticalError mozilla::gfx::CriticalLog
|
||||
|
||||
// See nsDebug.h and the NS_WARN_IF macro
|
||||
|
||||
|
@ -218,7 +484,7 @@ class TreeLog
|
|||
{
|
||||
public:
|
||||
explicit TreeLog(const std::string& aPrefix = "")
|
||||
: mLog(LogOptions::NoNewline),
|
||||
: mLog(int(LogOptions::NoNewline)),
|
||||
mPrefix(aPrefix),
|
||||
mDepth(0),
|
||||
mStartOfLine(true),
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>USE_SSE2;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>USE_SSE2;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);GFX_LOG_WARNING</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
|
|
|
@ -157,6 +157,13 @@ if CONFIG['MOZ_DEBUG']:
|
|||
DEFINES['GFX_LOG_DEBUG'] = True
|
||||
DEFINES['GFX_LOG_WARNING'] = True
|
||||
|
||||
# Define the GFX_LOG_WARNING in release builds (available, but controlled by a
|
||||
# preference), though we may want to consider only doing it in the nightly
|
||||
# build, if the size of gfxWarning() code ends up making a difference.
|
||||
# See bug 1074952.
|
||||
# if CONFIG['NIGHTLY_BUILD']:
|
||||
DEFINES['GFX_LOG_WARNING'] = True
|
||||
|
||||
CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gtk2', 'gtk3', 'gonk', 'qt'):
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
#include <algorithm>
|
||||
#include "ImageContainer.h"
|
||||
#include "gfxPrefs.h"
|
||||
#define PIXMAN_DONT_DEFINE_STDINT
|
||||
#include "pixman.h" // for pixman_f_transform, etc
|
||||
#include "skia/SkCanvas.h" // for SkCanvas
|
||||
#include "skia/SkBitmapDevice.h" // for SkBitmapDevice
|
||||
|
||||
namespace mozilla {
|
||||
using namespace mozilla::gfx;
|
||||
|
@ -168,75 +168,62 @@ DrawSurfaceWithTextureCoords(DrawTarget *aDest,
|
|||
mode, aMask, aMaskTransform, &matrix);
|
||||
}
|
||||
|
||||
static pixman_transform
|
||||
Matrix3DToPixman(const gfx3DMatrix& aMatrix)
|
||||
static SkMatrix
|
||||
Matrix3DToSkia(const gfx3DMatrix& aMatrix)
|
||||
{
|
||||
pixman_f_transform transform;
|
||||
SkMatrix transform;
|
||||
transform.setAll(aMatrix._11,
|
||||
aMatrix._21,
|
||||
aMatrix._41,
|
||||
aMatrix._12,
|
||||
aMatrix._22,
|
||||
aMatrix._42,
|
||||
aMatrix._14,
|
||||
aMatrix._24,
|
||||
aMatrix._44);
|
||||
|
||||
transform.m[0][0] = aMatrix._11;
|
||||
transform.m[0][1] = aMatrix._21;
|
||||
transform.m[0][2] = aMatrix._41;
|
||||
transform.m[1][0] = aMatrix._12;
|
||||
transform.m[1][1] = aMatrix._22;
|
||||
transform.m[1][2] = aMatrix._42;
|
||||
transform.m[2][0] = aMatrix._14;
|
||||
transform.m[2][1] = aMatrix._24;
|
||||
transform.m[2][2] = aMatrix._44;
|
||||
|
||||
pixman_transform result;
|
||||
pixman_transform_from_pixman_f_transform(&result, &transform);
|
||||
|
||||
return result;
|
||||
return transform;
|
||||
}
|
||||
|
||||
static void
|
||||
PixmanTransform(DataSourceSurface* aDest,
|
||||
DataSourceSurface* aSource,
|
||||
const gfx3DMatrix& aTransform,
|
||||
const Point& aDestOffset)
|
||||
SkiaTransform(DataSourceSurface* aDest,
|
||||
DataSourceSurface* aSource,
|
||||
const gfx3DMatrix& aTransform,
|
||||
const Point& aDestOffset)
|
||||
{
|
||||
IntSize destSize = aDest->GetSize();
|
||||
pixman_image_t* dest = pixman_image_create_bits(PIXMAN_a8r8g8b8,
|
||||
destSize.width,
|
||||
destSize.height,
|
||||
(uint32_t*)aDest->GetData(),
|
||||
aDest->Stride());
|
||||
|
||||
IntSize srcSize = aSource->GetSize();
|
||||
pixman_image_t* src = pixman_image_create_bits(PIXMAN_a8r8g8b8,
|
||||
srcSize.width,
|
||||
srcSize.height,
|
||||
(uint32_t*)aSource->GetData(),
|
||||
aSource->Stride());
|
||||
|
||||
NS_ABORT_IF_FALSE(src && dest, "Failed to create pixman images?");
|
||||
|
||||
pixman_transform pixTransform = Matrix3DToPixman(aTransform);
|
||||
pixman_transform pixTransformInverted;
|
||||
|
||||
// If the transform is singular then nothing would be drawn anyway, return here
|
||||
if (!pixman_transform_invert(&pixTransformInverted, &pixTransform)) {
|
||||
pixman_image_unref(dest);
|
||||
pixman_image_unref(src);
|
||||
if (aTransform.IsSingular()) {
|
||||
return;
|
||||
}
|
||||
pixman_image_set_transform(src, &pixTransformInverted);
|
||||
|
||||
pixman_image_composite32(PIXMAN_OP_SRC,
|
||||
src,
|
||||
nullptr,
|
||||
dest,
|
||||
aDestOffset.x,
|
||||
aDestOffset.y,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
destSize.width,
|
||||
destSize.height);
|
||||
IntSize destSize = aDest->GetSize();
|
||||
SkImageInfo destInfo = SkImageInfo::Make(destSize.width,
|
||||
destSize.height,
|
||||
kBGRA_8888_SkColorType,
|
||||
kPremul_SkAlphaType);
|
||||
SkBitmap destBitmap;
|
||||
destBitmap.setInfo(destInfo, aDest->Stride());
|
||||
destBitmap.setPixels((uint32_t*)aDest->GetData());
|
||||
SkCanvas destCanvas(destBitmap);
|
||||
|
||||
pixman_image_unref(dest);
|
||||
pixman_image_unref(src);
|
||||
IntSize srcSize = aSource->GetSize();
|
||||
SkImageInfo srcInfo = SkImageInfo::Make(srcSize.width,
|
||||
srcSize.height,
|
||||
kBGRA_8888_SkColorType,
|
||||
kPremul_SkAlphaType);
|
||||
SkBitmap src;
|
||||
src.setInfo(srcInfo, aSource->Stride());
|
||||
src.setPixels((uint32_t*)aSource->GetData());
|
||||
|
||||
gfx3DMatrix transform = aTransform;
|
||||
transform.TranslatePost(Point3D(-aDestOffset.x, -aDestOffset.y, 0));
|
||||
destCanvas.setMatrix(Matrix3DToSkia(transform));
|
||||
|
||||
SkPaint paint;
|
||||
paint.setXfermodeMode(SkXfermode::kSrc_Mode);
|
||||
paint.setAntiAlias(true);
|
||||
paint.setFilterLevel(SkPaint::kLow_FilterLevel);
|
||||
SkRect destRect = SkRect::MakeXYWH(0, 0, srcSize.width, srcSize.height);
|
||||
destCanvas.drawBitmapRectToRect(src, nullptr, destRect, &paint);
|
||||
}
|
||||
|
||||
static inline IntRect
|
||||
|
@ -377,12 +364,12 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect,
|
|||
RefPtr<SourceSurface> snapshot = dest->Snapshot();
|
||||
RefPtr<DataSourceSurface> source = snapshot->GetDataSurface();
|
||||
RefPtr<DataSourceSurface> temp =
|
||||
Factory::CreateDataSourceSurface(RoundOut(transformBounds).Size(), SurfaceFormat::B8G8R8A8);
|
||||
Factory::CreateDataSourceSurface(RoundOut(transformBounds).Size(), SurfaceFormat::B8G8R8A8, true);
|
||||
if (NS_WARN_IF(!temp)) {
|
||||
return;
|
||||
}
|
||||
|
||||
PixmanTransform(temp, source, new3DTransform, transformBounds.TopLeft());
|
||||
SkiaTransform(temp, source, new3DTransform, transformBounds.TopLeft());
|
||||
|
||||
transformBounds.MoveTo(0, 0);
|
||||
buffer->DrawSurface(temp, transformBounds, transformBounds);
|
||||
|
|
|
@ -46,9 +46,8 @@
|
|||
#include "nsRect.h" // for nsIntRect
|
||||
#include "nsRegion.h" // for nsIntRegion, etc
|
||||
#include "nsTArray.h" // for nsAutoTArray
|
||||
#define PIXMAN_DONT_DEFINE_STDINT
|
||||
#include "pixman.h" // for pixman_f_transform, etc
|
||||
|
||||
#include "skia/SkCanvas.h" // for SkCanvas
|
||||
#include "skia/SkBitmapDevice.h" // for SkBitmapDevice
|
||||
class nsIWidget;
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -605,75 +604,62 @@ BasicLayerManager::SetRoot(Layer* aLayer)
|
|||
mRoot = aLayer;
|
||||
}
|
||||
|
||||
static pixman_transform
|
||||
BasicLayerManager_Matrix3DToPixman(const gfx3DMatrix& aMatrix)
|
||||
static SkMatrix
|
||||
BasicLayerManager_Matrix3DToSkia(const gfx3DMatrix& aMatrix)
|
||||
{
|
||||
pixman_f_transform transform;
|
||||
SkMatrix transform;
|
||||
transform.setAll(aMatrix._11,
|
||||
aMatrix._21,
|
||||
aMatrix._41,
|
||||
aMatrix._12,
|
||||
aMatrix._22,
|
||||
aMatrix._42,
|
||||
aMatrix._14,
|
||||
aMatrix._24,
|
||||
aMatrix._44);
|
||||
|
||||
transform.m[0][0] = aMatrix._11;
|
||||
transform.m[0][1] = aMatrix._21;
|
||||
transform.m[0][2] = aMatrix._41;
|
||||
transform.m[1][0] = aMatrix._12;
|
||||
transform.m[1][1] = aMatrix._22;
|
||||
transform.m[1][2] = aMatrix._42;
|
||||
transform.m[2][0] = aMatrix._14;
|
||||
transform.m[2][1] = aMatrix._24;
|
||||
transform.m[2][2] = aMatrix._44;
|
||||
|
||||
pixman_transform result;
|
||||
pixman_transform_from_pixman_f_transform(&result, &transform);
|
||||
|
||||
return result;
|
||||
return transform;
|
||||
}
|
||||
|
||||
static void
|
||||
PixmanTransform(const gfxImageSurface* aDest,
|
||||
RefPtr<DataSourceSurface> aSrc,
|
||||
const gfx3DMatrix& aTransform,
|
||||
gfxPoint aDestOffset)
|
||||
SkiaTransform(const gfxImageSurface* aDest,
|
||||
RefPtr<DataSourceSurface> aSrc,
|
||||
const gfx3DMatrix& aTransform,
|
||||
gfxPoint aDestOffset)
|
||||
{
|
||||
IntSize destSize = ToIntSize(aDest->GetSize());
|
||||
pixman_image_t* dest = pixman_image_create_bits(aDest->Format() == gfxImageFormat::ARGB32 ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8,
|
||||
destSize.width,
|
||||
destSize.height,
|
||||
(uint32_t*)aDest->Data(),
|
||||
aDest->Stride());
|
||||
|
||||
IntSize srcSize = aSrc->GetSize();
|
||||
pixman_image_t* src = pixman_image_create_bits(aSrc->GetFormat() == SurfaceFormat::B8G8R8A8 ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8,
|
||||
srcSize.width,
|
||||
srcSize.height,
|
||||
(uint32_t*)aSrc->GetData(),
|
||||
aSrc->Stride());
|
||||
|
||||
NS_ABORT_IF_FALSE(src && dest, "Failed to create pixman images?");
|
||||
|
||||
pixman_transform pixTransform = BasicLayerManager_Matrix3DToPixman(aTransform);
|
||||
pixman_transform pixTransformInverted;
|
||||
|
||||
// If the transform is singular then nothing would be drawn anyway, return here
|
||||
if (!pixman_transform_invert(&pixTransformInverted, &pixTransform)) {
|
||||
pixman_image_unref(dest);
|
||||
pixman_image_unref(src);
|
||||
if (aTransform.IsSingular()) {
|
||||
return;
|
||||
}
|
||||
pixman_image_set_transform(src, &pixTransformInverted);
|
||||
|
||||
pixman_image_composite32(PIXMAN_OP_SRC,
|
||||
src,
|
||||
nullptr,
|
||||
dest,
|
||||
aDestOffset.x,
|
||||
aDestOffset.y,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
destSize.width,
|
||||
destSize.height);
|
||||
IntSize destSize = ToIntSize(aDest->GetSize());
|
||||
SkImageInfo destInfo = SkImageInfo::Make(destSize.width,
|
||||
destSize.height,
|
||||
kBGRA_8888_SkColorType,
|
||||
kPremul_SkAlphaType);
|
||||
SkBitmap destBitmap;
|
||||
destBitmap.setInfo(destInfo, aDest->Stride());
|
||||
destBitmap.setPixels((uint32_t*)aDest->Data());
|
||||
SkCanvas destCanvas(destBitmap);
|
||||
|
||||
pixman_image_unref(dest);
|
||||
pixman_image_unref(src);
|
||||
IntSize srcSize = aSrc->GetSize();
|
||||
SkImageInfo srcInfo = SkImageInfo::Make(srcSize.width,
|
||||
srcSize.height,
|
||||
kBGRA_8888_SkColorType,
|
||||
kPremul_SkAlphaType);
|
||||
SkBitmap src;
|
||||
src.setInfo(srcInfo, aSrc->Stride());
|
||||
src.setPixels((uint32_t*)aSrc->GetData());
|
||||
|
||||
gfx3DMatrix transform = aTransform;
|
||||
transform.TranslatePost(Point3D(-aDestOffset.x, -aDestOffset.y, 0));
|
||||
destCanvas.setMatrix(BasicLayerManager_Matrix3DToSkia(transform));
|
||||
|
||||
SkPaint paint;
|
||||
paint.setXfermodeMode(SkXfermode::kSrc_Mode);
|
||||
paint.setAntiAlias(true);
|
||||
paint.setFilterLevel(SkPaint::kLow_FilterLevel);
|
||||
SkRect destRect = SkRect::MakeXYWH(0, 0, srcSize.width, srcSize.height);
|
||||
destCanvas.drawBitmapRectToRect(src, nullptr, destRect, &paint);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -716,7 +702,7 @@ Transform3D(RefPtr<SourceSurface> aSource,
|
|||
gfx3DMatrix translation = gfx3DMatrix::Translation(aBounds.x, aBounds.y, 0);
|
||||
|
||||
// Transform the content and offset it such that the content begins at the origin.
|
||||
PixmanTransform(destImage, aSource->GetDataSurface(), translation * aTransform, offset);
|
||||
SkiaTransform(destImage, aSource->GetDataSurface(), translation * aTransform, offset);
|
||||
|
||||
// If we haven't actually drawn to aDest then return our temporary image so
|
||||
// that the caller can do this.
|
||||
|
|
|
@ -32,6 +32,9 @@ TextureClientPool::TextureClientPool(gfx::SurfaceFormat aFormat, gfx::IntSize aS
|
|||
, mSurfaceAllocator(aAllocator)
|
||||
{
|
||||
mTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
if (aFormat == gfx::SurfaceFormat::UNKNOWN) {
|
||||
gfxWarning() << "Creating texture pool for SurfaceFormat::UNKNOWN format";
|
||||
}
|
||||
}
|
||||
|
||||
TextureClientPool::~TextureClientPool()
|
||||
|
|
|
@ -1070,13 +1070,13 @@ CompositorD3D11::SetSamplerForFilter(Filter aFilter)
|
|||
{
|
||||
ID3D11SamplerState *sampler;
|
||||
switch (aFilter) {
|
||||
default:
|
||||
case Filter::LINEAR:
|
||||
sampler = mAttachments->mLinearSamplerState;
|
||||
break;
|
||||
case Filter::POINT:
|
||||
case Filter::POINT:
|
||||
sampler = mAttachments->mPointSamplerState;
|
||||
break;
|
||||
case Filter::LINEAR:
|
||||
default:
|
||||
sampler = mAttachments->mLinearSamplerState;
|
||||
break;
|
||||
}
|
||||
|
||||
mContext->PSSetSamplers(0, 1, &sampler);
|
||||
|
|
|
@ -288,7 +288,7 @@ TextureClientD3D11::Unlock()
|
|||
HRESULT hr = device->CreateTexture2D(&desc, nullptr, byRef(tex));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
gfx::gfxCriticalError() << "[D3D11] CreateTexture2D failure " << mSize << " Code: " << gfx::hexa(hr);
|
||||
gfxCriticalError() << "[D3D11] CreateTexture2D failure " << mSize << " Code: " << gfx::hexa(hr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -375,7 +375,7 @@ TextureClientD3D11::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlag
|
|||
}
|
||||
|
||||
if (FAILED(hr)) {
|
||||
gfx::gfxCriticalError() << "[D3D11] CreateTexture2D failure " << aSize << " Code: " << gfx::hexa(hr);
|
||||
gfxCriticalError() << "[D3D11] CreateTexture2D failure " << aSize << " Code: " << gfx::hexa(hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче