mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-13 21:35:39 +00:00
Merge b2g-inbound to m-c a=merge
This commit is contained in:
commit
ccea819af8
@ -15,7 +15,7 @@
|
|||||||
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="1a956437210d2b16988d2ddbf40c9a38d8474435"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="1d9ae9cca415ad093beba9521c429350e1f2b14d"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||||
@ -23,7 +23,7 @@
|
|||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a3e4614c7fb0a6ffa8c748bf5d49b34612c9d6d4"/>
|
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="58aee9864c193acfd03fa196af399d0659ba506d"/>
|
||||||
<!-- Stock Android things -->
|
<!-- Stock Android things -->
|
||||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
|
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
|
||||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
|
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
|
||||||
|
@ -19,13 +19,13 @@
|
|||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1a956437210d2b16988d2ddbf40c9a38d8474435"/>
|
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1d9ae9cca415ad093beba9521c429350e1f2b14d"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
|
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
|
||||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="6fa7a4936414ceb4055fd27f7a30e76790f834fb"/>
|
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="6fa7a4936414ceb4055fd27f7a30e76790f834fb"/>
|
||||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a3e4614c7fb0a6ffa8c748bf5d49b34612c9d6d4"/>
|
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="58aee9864c193acfd03fa196af399d0659ba506d"/>
|
||||||
<!-- Stock Android things -->
|
<!-- Stock Android things -->
|
||||||
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
|
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
|
||||||
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
|
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
|
||||||
|
@ -17,10 +17,10 @@
|
|||||||
</project>
|
</project>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="1a956437210d2b16988d2ddbf40c9a38d8474435"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="1d9ae9cca415ad093beba9521c429350e1f2b14d"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a3e4614c7fb0a6ffa8c748bf5d49b34612c9d6d4"/>
|
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="58aee9864c193acfd03fa196af399d0659ba506d"/>
|
||||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||||
<!-- Stock Android things -->
|
<!-- Stock Android things -->
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="1a956437210d2b16988d2ddbf40c9a38d8474435"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="1d9ae9cca415ad093beba9521c429350e1f2b14d"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||||
@ -23,7 +23,7 @@
|
|||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a3e4614c7fb0a6ffa8c748bf5d49b34612c9d6d4"/>
|
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="58aee9864c193acfd03fa196af399d0659ba506d"/>
|
||||||
<!-- Stock Android things -->
|
<!-- Stock Android things -->
|
||||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
|
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
|
||||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>
|
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>
|
||||||
|
@ -19,13 +19,13 @@
|
|||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1a956437210d2b16988d2ddbf40c9a38d8474435"/>
|
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1d9ae9cca415ad093beba9521c429350e1f2b14d"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
|
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
|
||||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="6fa7a4936414ceb4055fd27f7a30e76790f834fb"/>
|
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="6fa7a4936414ceb4055fd27f7a30e76790f834fb"/>
|
||||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a3e4614c7fb0a6ffa8c748bf5d49b34612c9d6d4"/>
|
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="58aee9864c193acfd03fa196af399d0659ba506d"/>
|
||||||
<!-- Stock Android things -->
|
<!-- Stock Android things -->
|
||||||
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
|
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
|
||||||
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
|
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="1a956437210d2b16988d2ddbf40c9a38d8474435"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="1d9ae9cca415ad093beba9521c429350e1f2b14d"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||||
@ -23,7 +23,7 @@
|
|||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a3e4614c7fb0a6ffa8c748bf5d49b34612c9d6d4"/>
|
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="58aee9864c193acfd03fa196af399d0659ba506d"/>
|
||||||
<!-- Stock Android things -->
|
<!-- Stock Android things -->
|
||||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
|
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
|
||||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
|
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
|
||||||
|
@ -17,10 +17,10 @@
|
|||||||
</project>
|
</project>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="1a956437210d2b16988d2ddbf40c9a38d8474435"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="1d9ae9cca415ad093beba9521c429350e1f2b14d"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a3e4614c7fb0a6ffa8c748bf5d49b34612c9d6d4"/>
|
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="58aee9864c193acfd03fa196af399d0659ba506d"/>
|
||||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||||
<!-- Stock Android things -->
|
<!-- Stock Android things -->
|
||||||
|
@ -4,6 +4,6 @@
|
|||||||
"remote": "",
|
"remote": "",
|
||||||
"branch": ""
|
"branch": ""
|
||||||
},
|
},
|
||||||
"revision": "e832f7bc675f2a5f4903400f11a8429f916aa20b",
|
"revision": "f1f983cfb1e42dbc6723c192f73c16bf098b6b4b",
|
||||||
"repo_path": "integration/gaia-central"
|
"repo_path": "integration/gaia-central"
|
||||||
}
|
}
|
||||||
|
@ -17,11 +17,11 @@
|
|||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1a956437210d2b16988d2ddbf40c9a38d8474435"/>
|
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1d9ae9cca415ad093beba9521c429350e1f2b14d"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a3e4614c7fb0a6ffa8c748bf5d49b34612c9d6d4"/>
|
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="58aee9864c193acfd03fa196af399d0659ba506d"/>
|
||||||
<!-- Stock Android things -->
|
<!-- Stock Android things -->
|
||||||
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
|
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
|
||||||
<project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
|
<project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1a956437210d2b16988d2ddbf40c9a38d8474435"/>
|
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1d9ae9cca415ad093beba9521c429350e1f2b14d"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||||
|
@ -17,10 +17,10 @@
|
|||||||
</project>
|
</project>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="1a956437210d2b16988d2ddbf40c9a38d8474435"/>
|
<project name="gaia" path="gaia" remote="mozillaorg" revision="1d9ae9cca415ad093beba9521c429350e1f2b14d"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a3e4614c7fb0a6ffa8c748bf5d49b34612c9d6d4"/>
|
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="58aee9864c193acfd03fa196af399d0659ba506d"/>
|
||||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||||
<!-- Stock Android things -->
|
<!-- Stock Android things -->
|
||||||
|
@ -17,12 +17,12 @@
|
|||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1a956437210d2b16988d2ddbf40c9a38d8474435"/>
|
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1d9ae9cca415ad093beba9521c429350e1f2b14d"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="a3e4614c7fb0a6ffa8c748bf5d49b34612c9d6d4"/>
|
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="58aee9864c193acfd03fa196af399d0659ba506d"/>
|
||||||
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
|
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
|
||||||
<!-- Stock Android things -->
|
<!-- Stock Android things -->
|
||||||
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
|
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
|
||||||
|
429
dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp
Normal file
429
dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp
Normal file
@ -0,0 +1,429 @@
|
|||||||
|
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "BluetoothDaemonA2dpInterface.h"
|
||||||
|
#include "BluetoothDaemonSetupInterface.h"
|
||||||
|
#include "mozilla/unused.h"
|
||||||
|
|
||||||
|
BEGIN_BLUETOOTH_NAMESPACE
|
||||||
|
|
||||||
|
//
|
||||||
|
// A2DP module
|
||||||
|
//
|
||||||
|
|
||||||
|
BluetoothA2dpNotificationHandler*
|
||||||
|
BluetoothDaemonA2dpModule::sNotificationHandler;
|
||||||
|
|
||||||
|
void
|
||||||
|
BluetoothDaemonA2dpModule::SetNotificationHandler(
|
||||||
|
BluetoothA2dpNotificationHandler* aNotificationHandler)
|
||||||
|
{
|
||||||
|
sNotificationHandler = aNotificationHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
BluetoothDaemonA2dpModule::Send(BluetoothDaemonPDU* aPDU,
|
||||||
|
BluetoothA2dpResultHandler* aRes)
|
||||||
|
{
|
||||||
|
aRes->AddRef(); // Keep reference for response
|
||||||
|
return Send(aPDU, static_cast<void*>(aRes));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BluetoothDaemonA2dpModule::HandleSvc(const BluetoothDaemonPDUHeader& aHeader,
|
||||||
|
BluetoothDaemonPDU& aPDU, void* aUserData)
|
||||||
|
{
|
||||||
|
static void (BluetoothDaemonA2dpModule::* const HandleOp[])(
|
||||||
|
const BluetoothDaemonPDUHeader&, BluetoothDaemonPDU&, void*) = {
|
||||||
|
INIT_ARRAY_AT(0, &BluetoothDaemonA2dpModule::HandleRsp),
|
||||||
|
INIT_ARRAY_AT(1, &BluetoothDaemonA2dpModule::HandleNtf),
|
||||||
|
};
|
||||||
|
|
||||||
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
|
|
||||||
|
// negate twice to map bit to 0/1
|
||||||
|
unsigned int isNtf = !!(aHeader.mOpcode & 0x80);
|
||||||
|
|
||||||
|
(this->*(HandleOp[isNtf]))(aHeader, aPDU, aUserData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Commands
|
||||||
|
//
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
BluetoothDaemonA2dpModule::ConnectCmd(
|
||||||
|
const nsAString& aRemoteAddr, BluetoothA2dpResultHandler* aRes)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
nsAutoPtr<BluetoothDaemonPDU> pdu(new BluetoothDaemonPDU(SERVICE_ID,
|
||||||
|
OPCODE_CONNECT,
|
||||||
|
6)); // Address
|
||||||
|
nsresult rv = PackPDU(
|
||||||
|
PackConversion<nsAString, BluetoothAddress>(aRemoteAddr), *pdu);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
rv = Send(pdu, aRes);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
unused << pdu.forget();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
BluetoothDaemonA2dpModule::DisconnectCmd(
|
||||||
|
const nsAString& aRemoteAddr, BluetoothA2dpResultHandler* aRes)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
nsAutoPtr<BluetoothDaemonPDU> pdu(new BluetoothDaemonPDU(SERVICE_ID,
|
||||||
|
OPCODE_DISCONNECT,
|
||||||
|
6)); // Address
|
||||||
|
nsresult rv = PackPDU(
|
||||||
|
PackConversion<nsAString, BluetoothAddress>(aRemoteAddr), *pdu);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
rv = Send(pdu, aRes);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
unused << pdu.forget();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Responses
|
||||||
|
//
|
||||||
|
|
||||||
|
void
|
||||||
|
BluetoothDaemonA2dpModule::ErrorRsp(
|
||||||
|
const BluetoothDaemonPDUHeader& aHeader,
|
||||||
|
BluetoothDaemonPDU& aPDU, BluetoothA2dpResultHandler* aRes)
|
||||||
|
{
|
||||||
|
ErrorRunnable::Dispatch(
|
||||||
|
aRes, &BluetoothA2dpResultHandler::OnError, UnpackPDUInitOp(aPDU));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BluetoothDaemonA2dpModule::ConnectRsp(
|
||||||
|
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||||
|
BluetoothA2dpResultHandler* aRes)
|
||||||
|
{
|
||||||
|
ResultRunnable::Dispatch(
|
||||||
|
aRes, &BluetoothA2dpResultHandler::Connect, UnpackPDUInitOp(aPDU));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BluetoothDaemonA2dpModule::DisconnectRsp(
|
||||||
|
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||||
|
BluetoothA2dpResultHandler* aRes)
|
||||||
|
{
|
||||||
|
ResultRunnable::Dispatch(
|
||||||
|
aRes, &BluetoothA2dpResultHandler::Disconnect, UnpackPDUInitOp(aPDU));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BluetoothDaemonA2dpModule::HandleRsp(
|
||||||
|
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||||
|
void* aUserData)
|
||||||
|
{
|
||||||
|
static void (BluetoothDaemonA2dpModule::* const HandleRsp[])(
|
||||||
|
const BluetoothDaemonPDUHeader&,
|
||||||
|
BluetoothDaemonPDU&,
|
||||||
|
BluetoothA2dpResultHandler*) = {
|
||||||
|
INIT_ARRAY_AT(OPCODE_ERROR,
|
||||||
|
&BluetoothDaemonA2dpModule::ErrorRsp),
|
||||||
|
INIT_ARRAY_AT(OPCODE_CONNECT,
|
||||||
|
&BluetoothDaemonA2dpModule::ConnectRsp),
|
||||||
|
INIT_ARRAY_AT(OPCODE_DISCONNECT,
|
||||||
|
&BluetoothDaemonA2dpModule::DisconnectRsp),
|
||||||
|
};
|
||||||
|
|
||||||
|
MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
|
||||||
|
|
||||||
|
if (NS_WARN_IF(!(aHeader.mOpcode < MOZ_ARRAY_LENGTH(HandleRsp))) ||
|
||||||
|
NS_WARN_IF(!HandleRsp[aHeader.mOpcode])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<BluetoothA2dpResultHandler> res =
|
||||||
|
already_AddRefed<BluetoothA2dpResultHandler>(
|
||||||
|
static_cast<BluetoothA2dpResultHandler*>(aUserData));
|
||||||
|
|
||||||
|
if (!res) {
|
||||||
|
return; // Return early if no result handler has been set for response
|
||||||
|
}
|
||||||
|
|
||||||
|
(this->*(HandleRsp[aHeader.mOpcode]))(aHeader, aPDU, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notifications
|
||||||
|
//
|
||||||
|
|
||||||
|
// Returns the current notification handler to a notification runnable
|
||||||
|
class BluetoothDaemonA2dpModule::NotificationHandlerWrapper MOZ_FINAL
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef BluetoothA2dpNotificationHandler ObjectType;
|
||||||
|
|
||||||
|
static ObjectType* GetInstance()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
return sNotificationHandler;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Init operator class for ConnectionStateNotification
|
||||||
|
class BluetoothDaemonA2dpModule::ConnectionStateInitOp MOZ_FINAL
|
||||||
|
: private PDUInitOp
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConnectionStateInitOp(BluetoothDaemonPDU& aPDU)
|
||||||
|
: PDUInitOp(aPDU)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
operator () (BluetoothA2dpConnectionState& aArg1, nsString& aArg2) const
|
||||||
|
{
|
||||||
|
BluetoothDaemonPDU& pdu = GetPDU();
|
||||||
|
|
||||||
|
/* Read state */
|
||||||
|
nsresult rv = UnpackPDU(pdu, aArg1);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read address */
|
||||||
|
rv = UnpackPDU(
|
||||||
|
pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
WarnAboutTrailingData();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
BluetoothDaemonA2dpModule::ConnectionStateNtf(
|
||||||
|
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||||
|
{
|
||||||
|
ConnectionStateNotification::Dispatch(
|
||||||
|
&BluetoothA2dpNotificationHandler::ConnectionStateNotification,
|
||||||
|
ConnectionStateInitOp(aPDU));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init operator class for AudioStateNotification
|
||||||
|
class BluetoothDaemonA2dpModule::AudioStateInitOp MOZ_FINAL
|
||||||
|
: private PDUInitOp
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AudioStateInitOp(BluetoothDaemonPDU& aPDU)
|
||||||
|
: PDUInitOp(aPDU)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
operator () (BluetoothA2dpAudioState& aArg1,
|
||||||
|
nsString& aArg2) const
|
||||||
|
{
|
||||||
|
BluetoothDaemonPDU& pdu = GetPDU();
|
||||||
|
|
||||||
|
/* Read state */
|
||||||
|
nsresult rv = UnpackPDU(pdu, aArg1);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read address */
|
||||||
|
rv = UnpackPDU(
|
||||||
|
pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
WarnAboutTrailingData();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
BluetoothDaemonA2dpModule::AudioStateNtf(
|
||||||
|
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
|
||||||
|
{
|
||||||
|
AudioStateNotification::Dispatch(
|
||||||
|
&BluetoothA2dpNotificationHandler::AudioStateNotification,
|
||||||
|
AudioStateInitOp(aPDU));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BluetoothDaemonA2dpModule::HandleNtf(
|
||||||
|
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||||
|
void* aUserData)
|
||||||
|
{
|
||||||
|
static void (BluetoothDaemonA2dpModule::* const HandleNtf[])(
|
||||||
|
const BluetoothDaemonPDUHeader&, BluetoothDaemonPDU&) = {
|
||||||
|
INIT_ARRAY_AT(0, &BluetoothDaemonA2dpModule::ConnectionStateNtf),
|
||||||
|
INIT_ARRAY_AT(1, &BluetoothDaemonA2dpModule::AudioStateNtf),
|
||||||
|
};
|
||||||
|
|
||||||
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
|
|
||||||
|
uint8_t index = aHeader.mOpcode - 0x81;
|
||||||
|
|
||||||
|
if (NS_WARN_IF(!(index < MOZ_ARRAY_LENGTH(HandleNtf))) ||
|
||||||
|
NS_WARN_IF(!HandleNtf[index])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
(this->*(HandleNtf[index]))(aHeader, aPDU);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// A2DP interface
|
||||||
|
//
|
||||||
|
|
||||||
|
BluetoothDaemonA2dpInterface::BluetoothDaemonA2dpInterface(
|
||||||
|
BluetoothDaemonA2dpModule* aModule)
|
||||||
|
: mModule(aModule)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
BluetoothDaemonA2dpInterface::~BluetoothDaemonA2dpInterface()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
class BluetoothDaemonA2dpInterface::InitResultHandler MOZ_FINAL
|
||||||
|
: public BluetoothSetupResultHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
InitResultHandler(BluetoothA2dpResultHandler* aRes)
|
||||||
|
: mRes(aRes)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
mRes->OnError(aStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterModule() MOZ_OVERRIDE
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
mRes->Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsRefPtr<BluetoothA2dpResultHandler> mRes;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
BluetoothDaemonA2dpInterface::Init(
|
||||||
|
BluetoothA2dpNotificationHandler* aNotificationHandler,
|
||||||
|
BluetoothA2dpResultHandler* aRes)
|
||||||
|
{
|
||||||
|
// Set notification handler _before_ registering the module. It could
|
||||||
|
// happen that we receive notifications, before the result handler runs.
|
||||||
|
mModule->SetNotificationHandler(aNotificationHandler);
|
||||||
|
|
||||||
|
InitResultHandler* res;
|
||||||
|
|
||||||
|
if (aRes) {
|
||||||
|
res = new InitResultHandler(aRes);
|
||||||
|
} else {
|
||||||
|
// We don't need a result handler if the caller is not interested.
|
||||||
|
res = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv = mModule->RegisterModule(BluetoothDaemonA2dpModule::SERVICE_ID,
|
||||||
|
0x00, res);
|
||||||
|
if (NS_FAILED(rv) && aRes) {
|
||||||
|
DispatchError(aRes, STATUS_FAIL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BluetoothDaemonA2dpInterface::CleanupResultHandler MOZ_FINAL
|
||||||
|
: public BluetoothSetupResultHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CleanupResultHandler(BluetoothDaemonA2dpModule* aModule,
|
||||||
|
BluetoothA2dpResultHandler* aRes)
|
||||||
|
: mModule(aModule)
|
||||||
|
, mRes(aRes)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mModule);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
if (mRes) {
|
||||||
|
mRes->OnError(aStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnregisterModule() MOZ_OVERRIDE
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
// Clear notification handler _after_ module has been
|
||||||
|
// unregistered. While unregistering the module, we might
|
||||||
|
// still receive notifications.
|
||||||
|
mModule->SetNotificationHandler(nullptr);
|
||||||
|
|
||||||
|
if (mRes) {
|
||||||
|
mRes->Cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
BluetoothDaemonA2dpModule* mModule;
|
||||||
|
nsRefPtr<BluetoothA2dpResultHandler> mRes;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
BluetoothDaemonA2dpInterface::Cleanup(
|
||||||
|
BluetoothA2dpResultHandler* aRes)
|
||||||
|
{
|
||||||
|
mModule->UnregisterModule(BluetoothDaemonA2dpModule::SERVICE_ID,
|
||||||
|
new CleanupResultHandler(mModule, aRes));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connect / Disconnect */
|
||||||
|
|
||||||
|
void
|
||||||
|
BluetoothDaemonA2dpInterface::Connect(
|
||||||
|
const nsAString& aBdAddr, BluetoothA2dpResultHandler* aRes)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mModule);
|
||||||
|
|
||||||
|
mModule->ConnectCmd(aBdAddr, aRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BluetoothDaemonA2dpInterface::Disconnect(
|
||||||
|
const nsAString& aBdAddr, BluetoothA2dpResultHandler* aRes)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mModule);
|
||||||
|
|
||||||
|
mModule->DisconnectCmd(aBdAddr, aRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BluetoothDaemonA2dpInterface::DispatchError(
|
||||||
|
BluetoothA2dpResultHandler* aRes, BluetoothStatus aStatus)
|
||||||
|
{
|
||||||
|
BluetoothResultRunnable1<BluetoothA2dpResultHandler, void,
|
||||||
|
BluetoothStatus, BluetoothStatus>::Dispatch(
|
||||||
|
aRes, &BluetoothA2dpResultHandler::OnError,
|
||||||
|
ConstantInitOp1<BluetoothStatus>(aStatus));
|
||||||
|
}
|
||||||
|
|
||||||
|
END_BLUETOOTH_NAMESPACE
|
152
dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.h
Normal file
152
dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.h
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef mozilla_dom_bluetooth_bluetoothdaemona2dpinterface_h
|
||||||
|
#define mozilla_dom_bluetooth_bluetoothdaemona2dpinterface_h
|
||||||
|
|
||||||
|
#include "BluetoothDaemonHelpers.h"
|
||||||
|
#include "BluetoothInterface.h"
|
||||||
|
#include "BluetoothInterfaceHelpers.h"
|
||||||
|
|
||||||
|
BEGIN_BLUETOOTH_NAMESPACE
|
||||||
|
|
||||||
|
class BluetoothSetupResultHandler;
|
||||||
|
|
||||||
|
class BluetoothDaemonA2dpModule
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
SERVICE_ID = 0x06
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
OPCODE_ERROR = 0x00,
|
||||||
|
OPCODE_CONNECT = 0x01,
|
||||||
|
OPCODE_DISCONNECT = 0x02
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual nsresult Send(BluetoothDaemonPDU* aPDU, void* aUserData) = 0;
|
||||||
|
|
||||||
|
virtual nsresult RegisterModule(uint8_t aId, uint8_t aMode,
|
||||||
|
BluetoothSetupResultHandler* aRes) = 0;
|
||||||
|
|
||||||
|
virtual nsresult UnregisterModule(uint8_t aId,
|
||||||
|
BluetoothSetupResultHandler* aRes) = 0;
|
||||||
|
|
||||||
|
void SetNotificationHandler(
|
||||||
|
BluetoothA2dpNotificationHandler* aNotificationHandler);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Commands
|
||||||
|
//
|
||||||
|
|
||||||
|
nsresult ConnectCmd(const nsAString& aBdAddr,
|
||||||
|
BluetoothA2dpResultHandler* aRes);
|
||||||
|
nsresult DisconnectCmd(const nsAString& aBdAddr,
|
||||||
|
BluetoothA2dpResultHandler* aRes);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
nsresult Send(BluetoothDaemonPDU* aPDU,
|
||||||
|
BluetoothA2dpResultHandler* aRes);
|
||||||
|
|
||||||
|
void HandleSvc(const BluetoothDaemonPDUHeader& aHeader,
|
||||||
|
BluetoothDaemonPDU& aPDU, void* aUserData);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Responses
|
||||||
|
//
|
||||||
|
|
||||||
|
typedef BluetoothResultRunnable0<BluetoothA2dpResultHandler, void>
|
||||||
|
ResultRunnable;
|
||||||
|
|
||||||
|
typedef BluetoothResultRunnable1<BluetoothA2dpResultHandler, void,
|
||||||
|
BluetoothStatus, BluetoothStatus>
|
||||||
|
ErrorRunnable;
|
||||||
|
|
||||||
|
void ErrorRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||||
|
BluetoothDaemonPDU& aPDU,
|
||||||
|
BluetoothA2dpResultHandler* aRes);
|
||||||
|
|
||||||
|
void ConnectRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||||
|
BluetoothDaemonPDU& aPDU,
|
||||||
|
BluetoothA2dpResultHandler* aRes);
|
||||||
|
|
||||||
|
void DisconnectRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||||
|
BluetoothDaemonPDU& aPDU,
|
||||||
|
BluetoothA2dpResultHandler* aRes);
|
||||||
|
|
||||||
|
void HandleRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||||
|
BluetoothDaemonPDU& aPDU,
|
||||||
|
void* aUserData);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Notifications
|
||||||
|
//
|
||||||
|
|
||||||
|
class NotificationHandlerWrapper;
|
||||||
|
|
||||||
|
typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
|
||||||
|
BluetoothA2dpConnectionState,
|
||||||
|
nsString,
|
||||||
|
BluetoothA2dpConnectionState,
|
||||||
|
const nsAString&>
|
||||||
|
ConnectionStateNotification;
|
||||||
|
|
||||||
|
typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
|
||||||
|
BluetoothA2dpAudioState,
|
||||||
|
nsString,
|
||||||
|
BluetoothA2dpAudioState,
|
||||||
|
const nsAString&>
|
||||||
|
AudioStateNotification;
|
||||||
|
|
||||||
|
class AudioStateInitOp;
|
||||||
|
class ConnectionStateInitOp;
|
||||||
|
|
||||||
|
void ConnectionStateNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||||
|
BluetoothDaemonPDU& aPDU);
|
||||||
|
|
||||||
|
void AudioStateNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||||
|
BluetoothDaemonPDU& aPDU);
|
||||||
|
|
||||||
|
void HandleNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||||
|
BluetoothDaemonPDU& aPDU,
|
||||||
|
void* aUserData);
|
||||||
|
|
||||||
|
static BluetoothA2dpNotificationHandler* sNotificationHandler;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BluetoothDaemonA2dpInterface MOZ_FINAL
|
||||||
|
: public BluetoothA2dpInterface
|
||||||
|
{
|
||||||
|
class CleanupResultHandler;
|
||||||
|
class InitResultHandler;
|
||||||
|
|
||||||
|
public:
|
||||||
|
BluetoothDaemonA2dpInterface(BluetoothDaemonA2dpModule* aModule);
|
||||||
|
~BluetoothDaemonA2dpInterface();
|
||||||
|
|
||||||
|
void Init(
|
||||||
|
BluetoothA2dpNotificationHandler* aNotificationHandler,
|
||||||
|
BluetoothA2dpResultHandler* aRes);
|
||||||
|
void Cleanup(BluetoothA2dpResultHandler* aRes);
|
||||||
|
|
||||||
|
/* Connect / Disconnect */
|
||||||
|
|
||||||
|
void Connect(const nsAString& aBdAddr,
|
||||||
|
BluetoothA2dpResultHandler* aRes);
|
||||||
|
void Disconnect(const nsAString& aBdAddr,
|
||||||
|
BluetoothA2dpResultHandler* aRes);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DispatchError(BluetoothA2dpResultHandler* aRes,
|
||||||
|
BluetoothStatus aStatus);
|
||||||
|
|
||||||
|
BluetoothDaemonA2dpModule* mModule;
|
||||||
|
};
|
||||||
|
|
||||||
|
END_BLUETOOTH_NAMESPACE
|
||||||
|
|
||||||
|
#endif
|
@ -97,6 +97,37 @@ Convert(uint8_t aIn, int& aOut)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
Convert(uint8_t aIn, BluetoothA2dpAudioState& aOut)
|
||||||
|
{
|
||||||
|
static const BluetoothA2dpAudioState sAudioState[] = {
|
||||||
|
CONVERT(0x00, A2DP_AUDIO_STATE_REMOTE_SUSPEND),
|
||||||
|
CONVERT(0x01, A2DP_AUDIO_STATE_STOPPED),
|
||||||
|
CONVERT(0x02, A2DP_AUDIO_STATE_STARTED)
|
||||||
|
};
|
||||||
|
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sAudioState))) {
|
||||||
|
return NS_ERROR_ILLEGAL_VALUE;
|
||||||
|
}
|
||||||
|
aOut = sAudioState[aIn];
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
Convert(uint8_t aIn, BluetoothA2dpConnectionState& aOut)
|
||||||
|
{
|
||||||
|
static const BluetoothA2dpConnectionState sConnectionState[] = {
|
||||||
|
CONVERT(0x00, A2DP_CONNECTION_STATE_DISCONNECTED),
|
||||||
|
CONVERT(0x01, A2DP_CONNECTION_STATE_CONNECTING),
|
||||||
|
CONVERT(0x02, A2DP_CONNECTION_STATE_CONNECTED),
|
||||||
|
CONVERT(0x03, A2DP_CONNECTION_STATE_DISCONNECTING)
|
||||||
|
};
|
||||||
|
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sConnectionState))) {
|
||||||
|
return NS_ERROR_ILLEGAL_VALUE;
|
||||||
|
}
|
||||||
|
aOut = sConnectionState[aIn];
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
Convert(uint8_t aIn, BluetoothAclState& aOut)
|
Convert(uint8_t aIn, BluetoothAclState& aOut)
|
||||||
{
|
{
|
||||||
@ -934,6 +965,20 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, char& aOut)
|
|||||||
return UnpackPDU(aPDU, UnpackConversion<uint8_t, char>(aOut));
|
return UnpackPDU(aPDU, UnpackConversion<uint8_t, char>(aOut));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothA2dpAudioState& aOut)
|
||||||
|
{
|
||||||
|
return UnpackPDU(
|
||||||
|
aPDU, UnpackConversion<uint8_t, BluetoothA2dpAudioState>(aOut));
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothA2dpConnectionState& aOut)
|
||||||
|
{
|
||||||
|
return UnpackPDU(
|
||||||
|
aPDU, UnpackConversion<uint8_t, BluetoothA2dpConnectionState>(aOut));
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothAclState& aOut)
|
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothAclState& aOut)
|
||||||
{
|
{
|
||||||
|
@ -118,6 +118,12 @@ Convert(uint8_t aIn, char& aOut);
|
|||||||
nsresult
|
nsresult
|
||||||
Convert(uint8_t aIn, int& aOut);
|
Convert(uint8_t aIn, int& aOut);
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
Convert(uint8_t aIn, BluetoothA2dpAudioState& aOut);
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
Convert(uint8_t aIn, BluetoothA2dpConnectionState& aOut);
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
Convert(uint8_t aIn, BluetoothAclState& aOut);
|
Convert(uint8_t aIn, BluetoothAclState& aOut);
|
||||||
|
|
||||||
@ -554,6 +560,12 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, bool& aOut);
|
|||||||
nsresult
|
nsresult
|
||||||
UnpackPDU(BluetoothDaemonPDU& aPDU, char& aOut);
|
UnpackPDU(BluetoothDaemonPDU& aPDU, char& aOut);
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothA2dpAudioState& aOut);
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothA2dpConnectionState& aOut);
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothAclState& aOut);
|
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothAclState& aOut);
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "BluetoothDaemonInterface.h"
|
#include "BluetoothDaemonInterface.h"
|
||||||
|
#include "BluetoothDaemonA2dpInterface.h"
|
||||||
#include "BluetoothDaemonHandsfreeInterface.h"
|
#include "BluetoothDaemonHandsfreeInterface.h"
|
||||||
#include "BluetoothDaemonHelpers.h"
|
#include "BluetoothDaemonHelpers.h"
|
||||||
#include "BluetoothDaemonSetupInterface.h"
|
#include "BluetoothDaemonSetupInterface.h"
|
||||||
@ -1361,6 +1362,7 @@ class BluetoothDaemonProtocol MOZ_FINAL
|
|||||||
, public BluetoothDaemonCoreModule
|
, public BluetoothDaemonCoreModule
|
||||||
, public BluetoothDaemonSocketModule
|
, public BluetoothDaemonSocketModule
|
||||||
, public BluetoothDaemonHandsfreeModule
|
, public BluetoothDaemonHandsfreeModule
|
||||||
|
, public BluetoothDaemonA2dpModule
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BluetoothDaemonProtocol(BluetoothDaemonConnection* aConnection);
|
BluetoothDaemonProtocol(BluetoothDaemonConnection* aConnection);
|
||||||
@ -1394,6 +1396,8 @@ private:
|
|||||||
BluetoothDaemonPDU& aPDU, void* aUserData);
|
BluetoothDaemonPDU& aPDU, void* aUserData);
|
||||||
void HandleHandsfreeSvc(const BluetoothDaemonPDUHeader& aHeader,
|
void HandleHandsfreeSvc(const BluetoothDaemonPDUHeader& aHeader,
|
||||||
BluetoothDaemonPDU& aPDU, void* aUserData);
|
BluetoothDaemonPDU& aPDU, void* aUserData);
|
||||||
|
void HandleA2dpSvc(const BluetoothDaemonPDUHeader& aHeader,
|
||||||
|
BluetoothDaemonPDU& aPDU, void* aUserData);
|
||||||
|
|
||||||
BluetoothDaemonConnection* mConnection;
|
BluetoothDaemonConnection* mConnection;
|
||||||
nsTArray<void*> mUserDataQ;
|
nsTArray<void*> mUserDataQ;
|
||||||
@ -1462,6 +1466,14 @@ BluetoothDaemonProtocol::HandleHandsfreeSvc(
|
|||||||
BluetoothDaemonHandsfreeModule::HandleSvc(aHeader, aPDU, aUserData);
|
BluetoothDaemonHandsfreeModule::HandleSvc(aHeader, aPDU, aUserData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BluetoothDaemonProtocol::HandleA2dpSvc(
|
||||||
|
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||||
|
void* aUserData)
|
||||||
|
{
|
||||||
|
BluetoothDaemonA2dpModule::HandleSvc(aHeader, aPDU, aUserData);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BluetoothDaemonProtocol::Handle(BluetoothDaemonPDU& aPDU)
|
BluetoothDaemonProtocol::Handle(BluetoothDaemonPDU& aPDU)
|
||||||
{
|
{
|
||||||
@ -1473,7 +1485,9 @@ BluetoothDaemonProtocol::Handle(BluetoothDaemonPDU& aPDU)
|
|||||||
INIT_ARRAY_AT(0x03, nullptr), // HID host
|
INIT_ARRAY_AT(0x03, nullptr), // HID host
|
||||||
INIT_ARRAY_AT(0x04, nullptr), // PAN
|
INIT_ARRAY_AT(0x04, nullptr), // PAN
|
||||||
INIT_ARRAY_AT(BluetoothDaemonHandsfreeModule::SERVICE_ID,
|
INIT_ARRAY_AT(BluetoothDaemonHandsfreeModule::SERVICE_ID,
|
||||||
&BluetoothDaemonProtocol::HandleHandsfreeSvc)
|
&BluetoothDaemonProtocol::HandleHandsfreeSvc),
|
||||||
|
INIT_ARRAY_AT(BluetoothDaemonA2dpModule::SERVICE_ID,
|
||||||
|
&BluetoothDaemonProtocol::HandleA2dpSvc)
|
||||||
};
|
};
|
||||||
|
|
||||||
BluetoothDaemonPDUHeader header;
|
BluetoothDaemonPDUHeader header;
|
||||||
@ -2053,7 +2067,13 @@ BluetoothDaemonInterface::GetBluetoothHandsfreeInterface()
|
|||||||
BluetoothA2dpInterface*
|
BluetoothA2dpInterface*
|
||||||
BluetoothDaemonInterface::GetBluetoothA2dpInterface()
|
BluetoothDaemonInterface::GetBluetoothA2dpInterface()
|
||||||
{
|
{
|
||||||
return nullptr;
|
if (mA2dpInterface) {
|
||||||
|
return mA2dpInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
mA2dpInterface = new BluetoothDaemonA2dpInterface(mProtocol);
|
||||||
|
|
||||||
|
return mA2dpInterface;
|
||||||
}
|
}
|
||||||
|
|
||||||
BluetoothAvrcpInterface*
|
BluetoothAvrcpInterface*
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
BEGIN_BLUETOOTH_NAMESPACE
|
BEGIN_BLUETOOTH_NAMESPACE
|
||||||
|
|
||||||
class BluetoothDaemonChannel;
|
class BluetoothDaemonChannel;
|
||||||
|
class BluetoothDaemonA2dpInterface;
|
||||||
class BluetoothDaemonHandsfreeInterface;
|
class BluetoothDaemonHandsfreeInterface;
|
||||||
class BluetoothDaemonProtocol;
|
class BluetoothDaemonProtocol;
|
||||||
class BluetoothDaemonSocketInterface;
|
class BluetoothDaemonSocketInterface;
|
||||||
@ -127,6 +128,7 @@ private:
|
|||||||
|
|
||||||
nsAutoPtr<BluetoothDaemonSocketInterface> mSocketInterface;
|
nsAutoPtr<BluetoothDaemonSocketInterface> mSocketInterface;
|
||||||
nsAutoPtr<BluetoothDaemonHandsfreeInterface> mHandsfreeInterface;
|
nsAutoPtr<BluetoothDaemonHandsfreeInterface> mHandsfreeInterface;
|
||||||
|
nsAutoPtr<BluetoothDaemonA2dpInterface> mA2dpInterface;
|
||||||
};
|
};
|
||||||
|
|
||||||
END_BLUETOOTH_NAMESPACE
|
END_BLUETOOTH_NAMESPACE
|
||||||
|
@ -48,6 +48,7 @@ if CONFIG['MOZ_B2G_BT']:
|
|||||||
'bluedroid/BluetoothA2dpHALInterface.cpp',
|
'bluedroid/BluetoothA2dpHALInterface.cpp',
|
||||||
'bluedroid/BluetoothA2dpManager.cpp',
|
'bluedroid/BluetoothA2dpManager.cpp',
|
||||||
'bluedroid/BluetoothAvrcpHALInterface.cpp',
|
'bluedroid/BluetoothAvrcpHALInterface.cpp',
|
||||||
|
'bluedroid/BluetoothDaemonA2dpInterface.cpp',
|
||||||
'bluedroid/BluetoothDaemonHandsfreeInterface.cpp',
|
'bluedroid/BluetoothDaemonHandsfreeInterface.cpp',
|
||||||
'bluedroid/BluetoothDaemonHelpers.cpp',
|
'bluedroid/BluetoothDaemonHelpers.cpp',
|
||||||
'bluedroid/BluetoothDaemonInterface.cpp',
|
'bluedroid/BluetoothDaemonInterface.cpp',
|
||||||
|
@ -657,6 +657,7 @@ BrowserElementChild.prototype = {
|
|||||||
zoomFactor: zoomFactor,
|
zoomFactor: zoomFactor,
|
||||||
states: e.states,
|
states: e.states,
|
||||||
isCollapsed: (e.selectedText.length == 0),
|
isCollapsed: (e.selectedText.length == 0),
|
||||||
|
visible: e.visible,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get correct geometry information if we have nested iframe.
|
// Get correct geometry information if we have nested iframe.
|
||||||
|
@ -68,26 +68,7 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(nsDOMCameraControl, DOMMediaStream,
|
|||||||
mTakePicturePromise,
|
mTakePicturePromise,
|
||||||
mStartRecordingPromise,
|
mStartRecordingPromise,
|
||||||
mReleasePromise,
|
mReleasePromise,
|
||||||
mSetConfigurationPromise,
|
mSetConfigurationPromise)
|
||||||
mGetCameraOnSuccessCb,
|
|
||||||
mGetCameraOnErrorCb,
|
|
||||||
mAutoFocusOnSuccessCb,
|
|
||||||
mAutoFocusOnErrorCb,
|
|
||||||
mTakePictureOnSuccessCb,
|
|
||||||
mTakePictureOnErrorCb,
|
|
||||||
mStartRecordingOnSuccessCb,
|
|
||||||
mStartRecordingOnErrorCb,
|
|
||||||
mReleaseOnSuccessCb,
|
|
||||||
mReleaseOnErrorCb,
|
|
||||||
mSetConfigurationOnSuccessCb,
|
|
||||||
mSetConfigurationOnErrorCb,
|
|
||||||
mOnShutterCb,
|
|
||||||
mOnClosedCb,
|
|
||||||
mOnRecorderStateChangeCb,
|
|
||||||
mOnPreviewStateChangeCb,
|
|
||||||
mOnAutoFocusMovingCb,
|
|
||||||
mOnAutoFocusCompletedCb,
|
|
||||||
mOnFacesDetectedCb)
|
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
bool
|
bool
|
||||||
@ -207,33 +188,12 @@ nsDOMCameraControl::DiscardCachedCameraInstance(nsITimer* aTimer, void* aClosure
|
|||||||
|
|
||||||
nsDOMCameraControl::nsDOMCameraControl(uint32_t aCameraId,
|
nsDOMCameraControl::nsDOMCameraControl(uint32_t aCameraId,
|
||||||
const CameraConfiguration& aInitialConfig,
|
const CameraConfiguration& aInitialConfig,
|
||||||
GetCameraCallback* aOnSuccess,
|
|
||||||
CameraErrorCallback* aOnError,
|
|
||||||
Promise* aPromise,
|
Promise* aPromise,
|
||||||
nsPIDOMWindow* aWindow)
|
nsPIDOMWindow* aWindow)
|
||||||
: DOMMediaStream()
|
: DOMMediaStream()
|
||||||
, mCameraControl(nullptr)
|
, mCameraControl(nullptr)
|
||||||
, mAudioChannelAgent(nullptr)
|
, mAudioChannelAgent(nullptr)
|
||||||
, mGetCameraPromise(aPromise)
|
, mGetCameraPromise(aPromise)
|
||||||
, mGetCameraOnSuccessCb(aOnSuccess)
|
|
||||||
, mGetCameraOnErrorCb(aOnError)
|
|
||||||
, mAutoFocusOnSuccessCb(nullptr)
|
|
||||||
, mAutoFocusOnErrorCb(nullptr)
|
|
||||||
, mTakePictureOnSuccessCb(nullptr)
|
|
||||||
, mTakePictureOnErrorCb(nullptr)
|
|
||||||
, mStartRecordingOnSuccessCb(nullptr)
|
|
||||||
, mStartRecordingOnErrorCb(nullptr)
|
|
||||||
, mReleaseOnSuccessCb(nullptr)
|
|
||||||
, mReleaseOnErrorCb(nullptr)
|
|
||||||
, mSetConfigurationOnSuccessCb(nullptr)
|
|
||||||
, mSetConfigurationOnErrorCb(nullptr)
|
|
||||||
, mOnShutterCb(nullptr)
|
|
||||||
, mOnClosedCb(nullptr)
|
|
||||||
, mOnRecorderStateChangeCb(nullptr)
|
|
||||||
, mOnPreviewStateChangeCb(nullptr)
|
|
||||||
, mOnAutoFocusMovingCb(nullptr)
|
|
||||||
, mOnAutoFocusCompletedCb(nullptr)
|
|
||||||
, mOnFacesDetectedCb(nullptr)
|
|
||||||
, mWindow(aWindow)
|
, mWindow(aWindow)
|
||||||
, mPreviewState(CameraControlListener::kPreviewStopped)
|
, mPreviewState(CameraControlListener::kPreviewStopped)
|
||||||
{
|
{
|
||||||
@ -665,85 +625,6 @@ nsDOMCameraControl::SensorAngle()
|
|||||||
return angle;
|
return angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback attributes
|
|
||||||
|
|
||||||
CameraShutterCallback*
|
|
||||||
nsDOMCameraControl::GetOnShutter()
|
|
||||||
{
|
|
||||||
return mOnShutterCb;
|
|
||||||
}
|
|
||||||
void
|
|
||||||
nsDOMCameraControl::SetOnShutter(CameraShutterCallback* aCb)
|
|
||||||
{
|
|
||||||
mOnShutterCb = aCb;
|
|
||||||
}
|
|
||||||
|
|
||||||
CameraClosedCallback*
|
|
||||||
nsDOMCameraControl::GetOnClosed()
|
|
||||||
{
|
|
||||||
return mOnClosedCb;
|
|
||||||
}
|
|
||||||
void
|
|
||||||
nsDOMCameraControl::SetOnClosed(CameraClosedCallback* aCb)
|
|
||||||
{
|
|
||||||
mOnClosedCb = aCb;
|
|
||||||
}
|
|
||||||
|
|
||||||
CameraRecorderStateChange*
|
|
||||||
nsDOMCameraControl::GetOnRecorderStateChange()
|
|
||||||
{
|
|
||||||
return mOnRecorderStateChangeCb;
|
|
||||||
}
|
|
||||||
void
|
|
||||||
nsDOMCameraControl::SetOnRecorderStateChange(CameraRecorderStateChange* aCb)
|
|
||||||
{
|
|
||||||
mOnRecorderStateChangeCb = aCb;
|
|
||||||
}
|
|
||||||
|
|
||||||
CameraPreviewStateChange*
|
|
||||||
nsDOMCameraControl::GetOnPreviewStateChange()
|
|
||||||
{
|
|
||||||
return mOnPreviewStateChangeCb;
|
|
||||||
}
|
|
||||||
void
|
|
||||||
nsDOMCameraControl::SetOnPreviewStateChange(CameraPreviewStateChange* aCb)
|
|
||||||
{
|
|
||||||
mOnPreviewStateChangeCb = aCb;
|
|
||||||
}
|
|
||||||
|
|
||||||
CameraAutoFocusMovingCallback*
|
|
||||||
nsDOMCameraControl::GetOnAutoFocusMoving()
|
|
||||||
{
|
|
||||||
return mOnAutoFocusMovingCb;
|
|
||||||
}
|
|
||||||
void
|
|
||||||
nsDOMCameraControl::SetOnAutoFocusMoving(CameraAutoFocusMovingCallback* aCb)
|
|
||||||
{
|
|
||||||
mOnAutoFocusMovingCb = aCb;
|
|
||||||
}
|
|
||||||
|
|
||||||
CameraAutoFocusCallback*
|
|
||||||
nsDOMCameraControl::GetOnAutoFocusCompleted()
|
|
||||||
{
|
|
||||||
return mOnAutoFocusCompletedCb;
|
|
||||||
}
|
|
||||||
void
|
|
||||||
nsDOMCameraControl::SetOnAutoFocusCompleted(CameraAutoFocusCallback* aCb)
|
|
||||||
{
|
|
||||||
mOnAutoFocusCompletedCb = aCb;
|
|
||||||
}
|
|
||||||
|
|
||||||
CameraFaceDetectionCallback*
|
|
||||||
nsDOMCameraControl::GetOnFacesDetected()
|
|
||||||
{
|
|
||||||
return mOnFacesDetectedCb;
|
|
||||||
}
|
|
||||||
void
|
|
||||||
nsDOMCameraControl::SetOnFacesDetected(CameraFaceDetectionCallback* aCb)
|
|
||||||
{
|
|
||||||
mOnFacesDetectedCb = aCb;
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<dom::CameraCapabilities>
|
already_AddRefed<dom::CameraCapabilities>
|
||||||
nsDOMCameraControl::Capabilities()
|
nsDOMCameraControl::Capabilities()
|
||||||
{
|
{
|
||||||
@ -757,35 +638,11 @@ nsDOMCameraControl::Capabilities()
|
|||||||
return caps.forget();
|
return caps.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
class ImmediateErrorCallback : public nsRunnable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ImmediateErrorCallback(CameraErrorCallback* aCallback, const nsAString& aMessage)
|
|
||||||
: mCallback(aCallback)
|
|
||||||
, mMessage(aMessage)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
Run()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
ErrorResult ignored;
|
|
||||||
mCallback->Call(mMessage, ignored);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
nsRefPtr<CameraErrorCallback> mCallback;
|
|
||||||
nsString mMessage;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Methods.
|
// Methods.
|
||||||
already_AddRefed<Promise>
|
already_AddRefed<Promise>
|
||||||
nsDOMCameraControl::StartRecording(const CameraStartRecordingOptions& aOptions,
|
nsDOMCameraControl::StartRecording(const CameraStartRecordingOptions& aOptions,
|
||||||
nsDOMDeviceStorage& aStorageArea,
|
nsDOMDeviceStorage& aStorageArea,
|
||||||
const nsAString& aFilename,
|
const nsAString& aFilename,
|
||||||
const Optional<OwningNonNull<CameraStartRecordingCallback> >& aOnSuccess,
|
|
||||||
const Optional<OwningNonNull<CameraErrorCallback> >& aOnError,
|
|
||||||
ErrorResult& aRv)
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mCameraControl);
|
MOZ_ASSERT(mCameraControl);
|
||||||
@ -797,11 +654,6 @@ nsDOMCameraControl::StartRecording(const CameraStartRecordingOptions& aOptions,
|
|||||||
|
|
||||||
if (mStartRecordingPromise) {
|
if (mStartRecordingPromise) {
|
||||||
promise->MaybeReject(NS_ERROR_IN_PROGRESS);
|
promise->MaybeReject(NS_ERROR_IN_PROGRESS);
|
||||||
if (aOnError.WasPassed()) {
|
|
||||||
DOM_CAMERA_LOGT("%s:onError WasPassed\n", __func__);
|
|
||||||
NS_DispatchToMainThread(new ImmediateErrorCallback(&aOnError.Value(),
|
|
||||||
NS_LITERAL_STRING("StartRecordingInProgress")));
|
|
||||||
}
|
|
||||||
return promise.forget();
|
return promise.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -830,14 +682,6 @@ nsDOMCameraControl::StartRecording(const CameraStartRecordingOptions& aOptions,
|
|||||||
|
|
||||||
mStartRecordingPromise = promise;
|
mStartRecordingPromise = promise;
|
||||||
mOptions = aOptions;
|
mOptions = aOptions;
|
||||||
mStartRecordingOnSuccessCb = nullptr;
|
|
||||||
if (aOnSuccess.WasPassed()) {
|
|
||||||
mStartRecordingOnSuccessCb = &aOnSuccess.Value();
|
|
||||||
}
|
|
||||||
mStartRecordingOnErrorCb = nullptr;
|
|
||||||
if (aOnError.WasPassed()) {
|
|
||||||
mStartRecordingOnErrorCb = &aOnError.Value();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMEventListener> listener = new StartRecordingHelper(this);
|
nsCOMPtr<nsIDOMEventListener> listener = new StartRecordingHelper(this);
|
||||||
request->AddEventListener(NS_LITERAL_STRING("success"), listener, false);
|
request->AddEventListener(NS_LITERAL_STRING("success"), listener, false);
|
||||||
@ -899,8 +743,6 @@ nsDOMCameraControl::ResumePreview(ErrorResult& aRv)
|
|||||||
|
|
||||||
already_AddRefed<Promise>
|
already_AddRefed<Promise>
|
||||||
nsDOMCameraControl::SetConfiguration(const CameraConfiguration& aConfiguration,
|
nsDOMCameraControl::SetConfiguration(const CameraConfiguration& aConfiguration,
|
||||||
const Optional<OwningNonNull<CameraSetConfigurationCallback> >& aOnSuccess,
|
|
||||||
const Optional<OwningNonNull<CameraErrorCallback> >& aOnError,
|
|
||||||
ErrorResult& aRv)
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mCameraControl);
|
MOZ_ASSERT(mCameraControl);
|
||||||
@ -911,14 +753,8 @@ nsDOMCameraControl::SetConfiguration(const CameraConfiguration& aConfiguration,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mTakePicturePromise) {
|
if (mTakePicturePromise) {
|
||||||
promise->MaybeReject(NS_ERROR_IN_PROGRESS);
|
|
||||||
// We're busy taking a picture, can't change modes right now.
|
// We're busy taking a picture, can't change modes right now.
|
||||||
if (aOnError.WasPassed()) {
|
promise->MaybeReject(NS_ERROR_IN_PROGRESS);
|
||||||
// There is already a call to TakePicture() in progress, abort this
|
|
||||||
// call and invoke the error callback (if one was passed in).
|
|
||||||
NS_DispatchToMainThread(new ImmediateErrorCallback(&aOnError.Value(),
|
|
||||||
NS_LITERAL_STRING("TakePictureInProgress")));
|
|
||||||
}
|
|
||||||
return promise.forget();
|
return promise.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -937,21 +773,11 @@ nsDOMCameraControl::SetConfiguration(const CameraConfiguration& aConfiguration,
|
|||||||
}
|
}
|
||||||
|
|
||||||
mSetConfigurationPromise = promise;
|
mSetConfigurationPromise = promise;
|
||||||
mSetConfigurationOnSuccessCb = nullptr;
|
|
||||||
if (aOnSuccess.WasPassed()) {
|
|
||||||
mSetConfigurationOnSuccessCb = &aOnSuccess.Value();
|
|
||||||
}
|
|
||||||
mSetConfigurationOnErrorCb = nullptr;
|
|
||||||
if (aOnError.WasPassed()) {
|
|
||||||
mSetConfigurationOnErrorCb = &aOnError.Value();
|
|
||||||
}
|
|
||||||
return promise.forget();
|
return promise.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<Promise>
|
already_AddRefed<Promise>
|
||||||
nsDOMCameraControl::AutoFocus(const Optional<OwningNonNull<CameraAutoFocusCallback> >& aOnSuccess,
|
nsDOMCameraControl::AutoFocus(ErrorResult& aRv)
|
||||||
const Optional<OwningNonNull<CameraErrorCallback> >& aOnError,
|
|
||||||
ErrorResult& aRv)
|
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mCameraControl);
|
MOZ_ASSERT(mCameraControl);
|
||||||
|
|
||||||
@ -960,12 +786,6 @@ nsDOMCameraControl::AutoFocus(const Optional<OwningNonNull<CameraAutoFocusCallba
|
|||||||
// There is already a call to AutoFocus() in progress, cancel it and
|
// There is already a call to AutoFocus() in progress, cancel it and
|
||||||
// invoke the error callback (if one was passed in).
|
// invoke the error callback (if one was passed in).
|
||||||
promise->MaybeReject(NS_ERROR_IN_PROGRESS);
|
promise->MaybeReject(NS_ERROR_IN_PROGRESS);
|
||||||
mAutoFocusOnSuccessCb = nullptr;
|
|
||||||
nsRefPtr<CameraErrorCallback> ecb = mAutoFocusOnErrorCb.forget();
|
|
||||||
if (ecb) {
|
|
||||||
NS_DispatchToMainThread(new ImmediateErrorCallback(ecb,
|
|
||||||
NS_LITERAL_STRING("AutoFocusInterrupted")));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
promise = CreatePromise(aRv);
|
promise = CreatePromise(aRv);
|
||||||
@ -981,14 +801,6 @@ nsDOMCameraControl::AutoFocus(const Optional<OwningNonNull<CameraAutoFocusCallba
|
|||||||
DispatchStateEvent(NS_LITERAL_STRING("focus"), NS_LITERAL_STRING("focusing"));
|
DispatchStateEvent(NS_LITERAL_STRING("focus"), NS_LITERAL_STRING("focusing"));
|
||||||
|
|
||||||
mAutoFocusPromise = promise;
|
mAutoFocusPromise = promise;
|
||||||
mAutoFocusOnSuccessCb = nullptr;
|
|
||||||
if (aOnSuccess.WasPassed()) {
|
|
||||||
mAutoFocusOnSuccessCb = &aOnSuccess.Value();
|
|
||||||
}
|
|
||||||
mAutoFocusOnErrorCb = nullptr;
|
|
||||||
if (aOnError.WasPassed()) {
|
|
||||||
mAutoFocusOnErrorCb = &aOnError.Value();
|
|
||||||
}
|
|
||||||
return promise.forget();
|
return promise.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1008,8 +820,6 @@ nsDOMCameraControl::StopFaceDetection(ErrorResult& aRv)
|
|||||||
|
|
||||||
already_AddRefed<Promise>
|
already_AddRefed<Promise>
|
||||||
nsDOMCameraControl::TakePicture(const CameraPictureOptions& aOptions,
|
nsDOMCameraControl::TakePicture(const CameraPictureOptions& aOptions,
|
||||||
const Optional<OwningNonNull<CameraTakePictureCallback> >& aOnSuccess,
|
|
||||||
const Optional<OwningNonNull<CameraErrorCallback> >& aOnError,
|
|
||||||
ErrorResult& aRv)
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mCameraControl);
|
MOZ_ASSERT(mCameraControl);
|
||||||
@ -1023,10 +833,6 @@ nsDOMCameraControl::TakePicture(const CameraPictureOptions& aOptions,
|
|||||||
// There is already a call to TakePicture() in progress, abort this new
|
// There is already a call to TakePicture() in progress, abort this new
|
||||||
// one and invoke the error callback (if one was passed in).
|
// one and invoke the error callback (if one was passed in).
|
||||||
promise->MaybeReject(NS_ERROR_IN_PROGRESS);
|
promise->MaybeReject(NS_ERROR_IN_PROGRESS);
|
||||||
if (aOnError.WasPassed()) {
|
|
||||||
NS_DispatchToMainThread(new ImmediateErrorCallback(&aOnError.Value(),
|
|
||||||
NS_LITERAL_STRING("TakePictureAlreadyInProgress")));
|
|
||||||
}
|
|
||||||
return promise.forget();
|
return promise.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1059,21 +865,11 @@ nsDOMCameraControl::TakePicture(const CameraPictureOptions& aOptions,
|
|||||||
}
|
}
|
||||||
|
|
||||||
mTakePicturePromise = promise;
|
mTakePicturePromise = promise;
|
||||||
mTakePictureOnSuccessCb = nullptr;
|
|
||||||
if (aOnSuccess.WasPassed()) {
|
|
||||||
mTakePictureOnSuccessCb = &aOnSuccess.Value();
|
|
||||||
}
|
|
||||||
mTakePictureOnErrorCb = nullptr;
|
|
||||||
if (aOnError.WasPassed()) {
|
|
||||||
mTakePictureOnErrorCb = &aOnError.Value();
|
|
||||||
}
|
|
||||||
return promise.forget();
|
return promise.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<Promise>
|
already_AddRefed<Promise>
|
||||||
nsDOMCameraControl::ReleaseHardware(const Optional<OwningNonNull<CameraReleaseCallback> >& aOnSuccess,
|
nsDOMCameraControl::ReleaseHardware(ErrorResult& aRv)
|
||||||
const Optional<OwningNonNull<CameraErrorCallback> >& aOnError,
|
|
||||||
ErrorResult& aRv)
|
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mCameraControl);
|
MOZ_ASSERT(mCameraControl);
|
||||||
|
|
||||||
@ -1088,14 +884,6 @@ nsDOMCameraControl::ReleaseHardware(const Optional<OwningNonNull<CameraReleaseCa
|
|||||||
}
|
}
|
||||||
|
|
||||||
mReleasePromise = promise;
|
mReleasePromise = promise;
|
||||||
mReleaseOnSuccessCb = nullptr;
|
|
||||||
if (aOnSuccess.WasPassed()) {
|
|
||||||
mReleaseOnSuccessCb = &aOnSuccess.Value();
|
|
||||||
}
|
|
||||||
mReleaseOnErrorCb = nullptr;
|
|
||||||
if (aOnError.WasPassed()) {
|
|
||||||
mReleaseOnErrorCb = &aOnError.Value();
|
|
||||||
}
|
|
||||||
return promise.forget();
|
return promise.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1121,27 +909,6 @@ nsDOMCameraControl::Shutdown()
|
|||||||
AbortPromise(mStartRecordingPromise);
|
AbortPromise(mStartRecordingPromise);
|
||||||
AbortPromise(mReleasePromise);
|
AbortPromise(mReleasePromise);
|
||||||
AbortPromise(mSetConfigurationPromise);
|
AbortPromise(mSetConfigurationPromise);
|
||||||
mGetCameraOnSuccessCb = nullptr;
|
|
||||||
mGetCameraOnErrorCb = nullptr;
|
|
||||||
mAutoFocusOnSuccessCb = nullptr;
|
|
||||||
mAutoFocusOnErrorCb = nullptr;
|
|
||||||
mTakePictureOnSuccessCb = nullptr;
|
|
||||||
mTakePictureOnErrorCb = nullptr;
|
|
||||||
mStartRecordingOnSuccessCb = nullptr;
|
|
||||||
mStartRecordingOnErrorCb = nullptr;
|
|
||||||
mReleaseOnSuccessCb = nullptr;
|
|
||||||
mReleaseOnErrorCb = nullptr;
|
|
||||||
mSetConfigurationOnSuccessCb = nullptr;
|
|
||||||
mSetConfigurationOnErrorCb = nullptr;
|
|
||||||
|
|
||||||
// Remove all of the unsolicited event handlers too.
|
|
||||||
mOnShutterCb = nullptr;
|
|
||||||
mOnClosedCb = nullptr;
|
|
||||||
mOnRecorderStateChangeCb = nullptr;
|
|
||||||
mOnPreviewStateChangeCb = nullptr;
|
|
||||||
mOnAutoFocusMovingCb = nullptr;
|
|
||||||
mOnAutoFocusCompletedCb = nullptr;
|
|
||||||
mOnFacesDetectedCb = nullptr;
|
|
||||||
|
|
||||||
mCameraControl->Shutdown();
|
mCameraControl->Shutdown();
|
||||||
}
|
}
|
||||||
@ -1236,12 +1003,6 @@ nsDOMCameraControl::OnHardwareStateChange(CameraControlListener::HardwareState a
|
|||||||
data.mConfiguration = *mCurrentConfiguration;
|
data.mConfiguration = *mCurrentConfiguration;
|
||||||
promise->MaybeResolve(data);
|
promise->MaybeResolve(data);
|
||||||
}
|
}
|
||||||
nsRefPtr<GetCameraCallback> cb = mGetCameraOnSuccessCb.forget();
|
|
||||||
mGetCameraOnErrorCb = nullptr;
|
|
||||||
if (cb) {
|
|
||||||
ErrorResult ignored;
|
|
||||||
cb->Call(*this, *mCurrentConfiguration, ignored);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1253,13 +1014,6 @@ nsDOMCameraControl::OnHardwareStateChange(CameraControlListener::HardwareState a
|
|||||||
promise->MaybeResolve(JS::UndefinedHandleValue);
|
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<CameraReleaseCallback> rcb = mReleaseOnSuccessCb.forget();
|
|
||||||
mReleaseOnErrorCb = nullptr;
|
|
||||||
if (rcb) {
|
|
||||||
ErrorResult ignored;
|
|
||||||
rcb->Call(ignored);
|
|
||||||
}
|
|
||||||
|
|
||||||
CameraClosedEventInit eventInit;
|
CameraClosedEventInit eventInit;
|
||||||
switch (aReason) {
|
switch (aReason) {
|
||||||
case NS_OK:
|
case NS_OK:
|
||||||
@ -1281,10 +1035,6 @@ nsDOMCameraControl::OnHardwareStateChange(CameraControlListener::HardwareState a
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<CameraClosedCallback> cb = mOnClosedCb;
|
|
||||||
if (cb) {
|
|
||||||
cb->Call(eventInit.mReason, ignored);
|
|
||||||
}
|
|
||||||
nsRefPtr<CameraClosedEvent> event =
|
nsRefPtr<CameraClosedEvent> event =
|
||||||
CameraClosedEvent::Constructor(this,
|
CameraClosedEvent::Constructor(this,
|
||||||
NS_LITERAL_STRING("close"),
|
NS_LITERAL_STRING("close"),
|
||||||
@ -1311,13 +1061,6 @@ nsDOMCameraControl::OnShutter()
|
|||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
DOM_CAMERA_LOGI("DOM ** SNAP **\n");
|
DOM_CAMERA_LOGI("DOM ** SNAP **\n");
|
||||||
|
|
||||||
nsRefPtr<CameraShutterCallback> cb = mOnShutterCb;
|
|
||||||
if (cb) {
|
|
||||||
ErrorResult ignored;
|
|
||||||
cb->Call(ignored);
|
|
||||||
}
|
|
||||||
|
|
||||||
DispatchTrustedEvent(NS_LITERAL_STRING("shutter"));
|
DispatchTrustedEvent(NS_LITERAL_STRING("shutter"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1338,12 +1081,6 @@ nsDOMCameraControl::OnPreviewStateChange(CameraControlListener::PreviewState aSt
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<CameraPreviewStateChange> cb = mOnPreviewStateChangeCb;
|
|
||||||
if (cb) {
|
|
||||||
ErrorResult ignored;
|
|
||||||
cb->Call(state, ignored);
|
|
||||||
}
|
|
||||||
|
|
||||||
DispatchPreviewStateEvent(aState);
|
DispatchPreviewStateEvent(aState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1365,11 +1102,6 @@ nsDOMCameraControl::OnRecorderStateChange(CameraControlListener::RecorderState a
|
|||||||
promise->MaybeResolve(JS::UndefinedHandleValue);
|
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<CameraStartRecordingCallback> scb = mStartRecordingOnSuccessCb.forget();
|
|
||||||
mStartRecordingOnErrorCb = nullptr;
|
|
||||||
if (scb) {
|
|
||||||
scb->Call(ignored);
|
|
||||||
}
|
|
||||||
state = NS_LITERAL_STRING("Started");
|
state = NS_LITERAL_STRING("Started");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1410,11 +1142,6 @@ nsDOMCameraControl::OnRecorderStateChange(CameraControlListener::RecorderState a
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<CameraRecorderStateChange> cb = mOnRecorderStateChangeCb;
|
|
||||||
if (cb) {
|
|
||||||
cb->Call(state, ignored);
|
|
||||||
}
|
|
||||||
|
|
||||||
DispatchStateEvent(NS_LITERAL_STRING("recorderstatechange"), state);
|
DispatchStateEvent(NS_LITERAL_STRING("recorderstatechange"), state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1444,13 +1171,6 @@ nsDOMCameraControl::OnConfigurationChange(DOMCameraConfiguration* aConfiguration
|
|||||||
promise->MaybeResolve(*aConfiguration);
|
promise->MaybeResolve(*aConfiguration);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<CameraSetConfigurationCallback> cb = mSetConfigurationOnSuccessCb.forget();
|
|
||||||
mSetConfigurationOnErrorCb = nullptr;
|
|
||||||
if (cb) {
|
|
||||||
ErrorResult ignored;
|
|
||||||
cb->Call(*mCurrentConfiguration, ignored);
|
|
||||||
}
|
|
||||||
|
|
||||||
CameraConfigurationEventInit eventInit;
|
CameraConfigurationEventInit eventInit;
|
||||||
eventInit.mMode = mCurrentConfiguration->mMode;
|
eventInit.mMode = mCurrentConfiguration->mMode;
|
||||||
eventInit.mRecorderProfile = mCurrentConfiguration->mRecorderProfile;
|
eventInit.mRecorderProfile = mCurrentConfiguration->mRecorderProfile;
|
||||||
@ -1476,19 +1196,6 @@ nsDOMCameraControl::OnAutoFocusComplete(bool aAutoFocusSucceeded)
|
|||||||
promise->MaybeResolve(aAutoFocusSucceeded);
|
promise->MaybeResolve(aAutoFocusSucceeded);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<CameraAutoFocusCallback> cb = mAutoFocusOnSuccessCb.forget();
|
|
||||||
mAutoFocusOnErrorCb = nullptr;
|
|
||||||
if (cb) {
|
|
||||||
ErrorResult ignored;
|
|
||||||
cb->Call(aAutoFocusSucceeded, ignored);
|
|
||||||
}
|
|
||||||
|
|
||||||
cb = mOnAutoFocusCompletedCb;
|
|
||||||
if (cb) {
|
|
||||||
ErrorResult ignored;
|
|
||||||
cb->Call(aAutoFocusSucceeded, ignored);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aAutoFocusSucceeded) {
|
if (aAutoFocusSucceeded) {
|
||||||
DispatchStateEvent(NS_LITERAL_STRING("focus"), NS_LITERAL_STRING("focused"));
|
DispatchStateEvent(NS_LITERAL_STRING("focus"), NS_LITERAL_STRING("focused"));
|
||||||
} else {
|
} else {
|
||||||
@ -1501,12 +1208,6 @@ nsDOMCameraControl::OnAutoFocusMoving(bool aIsMoving)
|
|||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
nsRefPtr<CameraAutoFocusMovingCallback> cb = mOnAutoFocusMovingCb;
|
|
||||||
if (cb) {
|
|
||||||
ErrorResult ignored;
|
|
||||||
cb->Call(aIsMoving, ignored);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aIsMoving) {
|
if (aIsMoving) {
|
||||||
DispatchStateEvent(NS_LITERAL_STRING("focus"), NS_LITERAL_STRING("focusing"));
|
DispatchStateEvent(NS_LITERAL_STRING("focus"), NS_LITERAL_STRING("focusing"));
|
||||||
}
|
}
|
||||||
@ -1529,12 +1230,6 @@ nsDOMCameraControl::OnFacesDetected(const nsTArray<ICameraControl::Face>& aFaces
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<CameraFaceDetectionCallback> cb = mOnFacesDetectedCb;
|
|
||||||
if (cb) {
|
|
||||||
ErrorResult ignored;
|
|
||||||
cb->Call(faces, ignored);
|
|
||||||
}
|
|
||||||
|
|
||||||
CameraFacesDetectedEventInit eventInit;
|
CameraFacesDetectedEventInit eventInit;
|
||||||
eventInit.mFaces.SetValue(faces);
|
eventInit.mFaces.SetValue(faces);
|
||||||
|
|
||||||
@ -1559,14 +1254,6 @@ nsDOMCameraControl::OnTakePictureComplete(nsIDOMBlob* aPicture)
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<File> blob = static_cast<File*>(aPicture);
|
nsRefPtr<File> blob = static_cast<File*>(aPicture);
|
||||||
|
|
||||||
nsRefPtr<CameraTakePictureCallback> cb = mTakePictureOnSuccessCb.forget();
|
|
||||||
mTakePictureOnErrorCb = nullptr;
|
|
||||||
if (cb) {
|
|
||||||
ErrorResult ignored;
|
|
||||||
cb->Call(*blob, ignored);
|
|
||||||
}
|
|
||||||
|
|
||||||
BlobEventInit eventInit;
|
BlobEventInit eventInit;
|
||||||
eventInit.mData = blob;
|
eventInit.mData = blob;
|
||||||
|
|
||||||
@ -1580,21 +1267,18 @@ nsDOMCameraControl::OnTakePictureComplete(nsIDOMBlob* aPicture)
|
|||||||
void
|
void
|
||||||
nsDOMCameraControl::OnUserError(CameraControlListener::UserContext aContext, nsresult aError)
|
nsDOMCameraControl::OnUserError(CameraControlListener::UserContext aContext, nsresult aError)
|
||||||
{
|
{
|
||||||
|
DOM_CAMERA_LOGI("DOM OnUserError aContext=%u, aError=0x%x\n", aContext, aError);
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
nsRefPtr<Promise> promise;
|
nsRefPtr<Promise> promise;
|
||||||
nsRefPtr<CameraErrorCallback> errorCb;
|
|
||||||
|
|
||||||
switch (aContext) {
|
switch (aContext) {
|
||||||
case CameraControlListener::kInStartCamera:
|
case CameraControlListener::kInStartCamera:
|
||||||
promise = mGetCameraPromise.forget();
|
promise = mGetCameraPromise.forget();
|
||||||
mGetCameraOnSuccessCb = nullptr;
|
|
||||||
errorCb = mGetCameraOnErrorCb.forget();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CameraControlListener::kInStopCamera:
|
case CameraControlListener::kInStopCamera:
|
||||||
promise = mReleasePromise.forget();
|
promise = mReleasePromise.forget();
|
||||||
errorCb = mReleaseOnErrorCb.forget();
|
|
||||||
if (aError == NS_ERROR_NOT_INITIALIZED) {
|
if (aError == NS_ERROR_NOT_INITIALIZED) {
|
||||||
// This value indicates that the hardware is already closed; which for
|
// This value indicates that the hardware is already closed; which for
|
||||||
// kInStopCamera, is not actually an error.
|
// kInStopCamera, is not actually an error.
|
||||||
@ -1602,41 +1286,25 @@ nsDOMCameraControl::OnUserError(CameraControlListener::UserContext aContext, nsr
|
|||||||
promise->MaybeResolve(JS::UndefinedHandleValue);
|
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<CameraReleaseCallback> cb = mReleaseOnSuccessCb.forget();
|
|
||||||
mReleaseOnErrorCb = nullptr;
|
|
||||||
if (cb) {
|
|
||||||
ErrorResult ignored;
|
|
||||||
cb->Call(ignored);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mReleaseOnSuccessCb = nullptr;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CameraControlListener::kInSetConfiguration:
|
case CameraControlListener::kInSetConfiguration:
|
||||||
promise = mSetConfigurationPromise.forget();
|
promise = mSetConfigurationPromise.forget();
|
||||||
mSetConfigurationOnSuccessCb = nullptr;
|
|
||||||
errorCb = mSetConfigurationOnErrorCb.forget();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CameraControlListener::kInAutoFocus:
|
case CameraControlListener::kInAutoFocus:
|
||||||
promise = mAutoFocusPromise.forget();
|
promise = mAutoFocusPromise.forget();
|
||||||
mAutoFocusOnSuccessCb = nullptr;
|
|
||||||
errorCb = mAutoFocusOnErrorCb.forget();
|
|
||||||
DispatchStateEvent(NS_LITERAL_STRING("focus"), NS_LITERAL_STRING("unfocused"));
|
DispatchStateEvent(NS_LITERAL_STRING("focus"), NS_LITERAL_STRING("unfocused"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CameraControlListener::kInTakePicture:
|
case CameraControlListener::kInTakePicture:
|
||||||
promise = mTakePicturePromise.forget();
|
promise = mTakePicturePromise.forget();
|
||||||
mTakePictureOnSuccessCb = nullptr;
|
|
||||||
errorCb = mTakePictureOnErrorCb.forget();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CameraControlListener::kInStartRecording:
|
case CameraControlListener::kInStartRecording:
|
||||||
promise = mStartRecordingPromise.forget();
|
promise = mStartRecordingPromise.forget();
|
||||||
mStartRecordingOnSuccessCb = nullptr;
|
|
||||||
errorCb = mStartRecordingOnErrorCb.forget();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CameraControlListener::kInStartFaceDetection:
|
case CameraControlListener::kInStartFaceDetection:
|
||||||
@ -1696,57 +1364,11 @@ nsDOMCameraControl::OnUserError(CameraControlListener::UserContext aContext, nsr
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!promise && !errorCb) {
|
if (!promise) {
|
||||||
DOM_CAMERA_LOGW("DOM No error handler for aError=0x%x in aContext=%u\n",
|
DOM_CAMERA_LOGW("DOM No error handler for aError=0x%x in aContext=%u\n",
|
||||||
aError, aContext);
|
aError, aContext);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DOM_CAMERA_LOGI("DOM OnUserError aContext=%u, aError=0x%x\n", aContext, aError);
|
promise->MaybeReject(aError);
|
||||||
if (promise) {
|
|
||||||
promise->MaybeReject(aError);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errorCb) {
|
|
||||||
nsString error;
|
|
||||||
switch (aError) {
|
|
||||||
case NS_ERROR_INVALID_ARG:
|
|
||||||
error = NS_LITERAL_STRING("InvalidArgument");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NS_ERROR_NOT_AVAILABLE:
|
|
||||||
error = NS_LITERAL_STRING("NotAvailable");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NS_ERROR_NOT_IMPLEMENTED:
|
|
||||||
error = NS_LITERAL_STRING("NotImplemented");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NS_ERROR_NOT_INITIALIZED:
|
|
||||||
error = NS_LITERAL_STRING("HardwareClosed");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NS_ERROR_ALREADY_INITIALIZED:
|
|
||||||
error = NS_LITERAL_STRING("HardwareAlreadyOpen");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NS_ERROR_OUT_OF_MEMORY:
|
|
||||||
error = NS_LITERAL_STRING("OutOfMemory");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
nsPrintfCString msg("Reporting aError=0x%x as generic\n", aError);
|
|
||||||
NS_WARNING(msg.get());
|
|
||||||
}
|
|
||||||
// fallthrough
|
|
||||||
|
|
||||||
case NS_ERROR_FAILURE:
|
|
||||||
error = NS_LITERAL_STRING("GeneralFailure");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ErrorResult ignored;
|
|
||||||
errorCb->Call(error, ignored);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -55,8 +55,6 @@ public:
|
|||||||
|
|
||||||
nsDOMCameraControl(uint32_t aCameraId,
|
nsDOMCameraControl(uint32_t aCameraId,
|
||||||
const dom::CameraConfiguration& aInitialConfig,
|
const dom::CameraConfiguration& aInitialConfig,
|
||||||
dom::GetCameraCallback* aOnSuccess,
|
|
||||||
dom::CameraErrorCallback* aOnError,
|
|
||||||
dom::Promise* aPromise,
|
dom::Promise* aPromise,
|
||||||
nsPIDOMWindow* aWindow);
|
nsPIDOMWindow* aWindow);
|
||||||
|
|
||||||
@ -90,26 +88,8 @@ public:
|
|||||||
double GetPictureQuality(ErrorResult& aRv);
|
double GetPictureQuality(ErrorResult& aRv);
|
||||||
void SetPictureQuality(double aQuality, ErrorResult& aRv);
|
void SetPictureQuality(double aQuality, ErrorResult& aRv);
|
||||||
|
|
||||||
// Unsolicited event handlers.
|
|
||||||
dom::CameraShutterCallback* GetOnShutter();
|
|
||||||
void SetOnShutter(dom::CameraShutterCallback* aCb);
|
|
||||||
dom::CameraClosedCallback* GetOnClosed();
|
|
||||||
void SetOnClosed(dom::CameraClosedCallback* aCb);
|
|
||||||
dom::CameraRecorderStateChange* GetOnRecorderStateChange();
|
|
||||||
void SetOnRecorderStateChange(dom::CameraRecorderStateChange* aCb);
|
|
||||||
dom::CameraPreviewStateChange* GetOnPreviewStateChange();
|
|
||||||
void SetOnPreviewStateChange(dom::CameraPreviewStateChange* aCb);
|
|
||||||
dom::CameraAutoFocusMovingCallback* GetOnAutoFocusMoving();
|
|
||||||
void SetOnAutoFocusMoving(dom::CameraAutoFocusMovingCallback* aCb);
|
|
||||||
dom::CameraAutoFocusCallback* GetOnAutoFocusCompleted();
|
|
||||||
void SetOnAutoFocusCompleted(dom::CameraAutoFocusCallback* aCb);
|
|
||||||
dom::CameraFaceDetectionCallback* GetOnFacesDetected();
|
|
||||||
void SetOnFacesDetected(dom::CameraFaceDetectionCallback* aCb);
|
|
||||||
|
|
||||||
// Methods.
|
// Methods.
|
||||||
already_AddRefed<dom::Promise> SetConfiguration(const dom::CameraConfiguration& aConfiguration,
|
already_AddRefed<dom::Promise> SetConfiguration(const dom::CameraConfiguration& aConfiguration,
|
||||||
const dom::Optional<dom::OwningNonNull<dom::CameraSetConfigurationCallback> >& aOnSuccess,
|
|
||||||
const dom::Optional<dom::OwningNonNull<dom::CameraErrorCallback> >& aOnError,
|
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
void GetMeteringAreas(nsTArray<dom::CameraRegion>& aAreas, ErrorResult& aRv);
|
void GetMeteringAreas(nsTArray<dom::CameraRegion>& aAreas, ErrorResult& aRv);
|
||||||
void SetMeteringAreas(const dom::Optional<dom::Sequence<dom::CameraRegion> >& aAreas, ErrorResult& aRv);
|
void SetMeteringAreas(const dom::Optional<dom::Sequence<dom::CameraRegion> >& aAreas, ErrorResult& aRv);
|
||||||
@ -119,26 +99,18 @@ public:
|
|||||||
void SetPictureSize(const dom::CameraSize& aSize, ErrorResult& aRv);
|
void SetPictureSize(const dom::CameraSize& aSize, ErrorResult& aRv);
|
||||||
void GetThumbnailSize(dom::CameraSize& aSize, ErrorResult& aRv);
|
void GetThumbnailSize(dom::CameraSize& aSize, ErrorResult& aRv);
|
||||||
void SetThumbnailSize(const dom::CameraSize& aSize, ErrorResult& aRv);
|
void SetThumbnailSize(const dom::CameraSize& aSize, ErrorResult& aRv);
|
||||||
already_AddRefed<dom::Promise> AutoFocus(const dom::Optional<dom::OwningNonNull<dom::CameraAutoFocusCallback> >& aOnSuccess,
|
already_AddRefed<dom::Promise> AutoFocus(ErrorResult& aRv);
|
||||||
const dom::Optional<dom::OwningNonNull<dom::CameraErrorCallback> >& aOnError,
|
|
||||||
ErrorResult& aRv);
|
|
||||||
void StartFaceDetection(ErrorResult& aRv);
|
void StartFaceDetection(ErrorResult& aRv);
|
||||||
void StopFaceDetection(ErrorResult& aRv);
|
void StopFaceDetection(ErrorResult& aRv);
|
||||||
already_AddRefed<dom::Promise> TakePicture(const dom::CameraPictureOptions& aOptions,
|
already_AddRefed<dom::Promise> TakePicture(const dom::CameraPictureOptions& aOptions,
|
||||||
const dom::Optional<dom::OwningNonNull<dom::CameraTakePictureCallback> >& aOnSuccess,
|
|
||||||
const dom::Optional<dom::OwningNonNull<dom::CameraErrorCallback> >& aOnError,
|
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
already_AddRefed<dom::Promise> StartRecording(const dom::CameraStartRecordingOptions& aOptions,
|
already_AddRefed<dom::Promise> StartRecording(const dom::CameraStartRecordingOptions& aOptions,
|
||||||
nsDOMDeviceStorage& storageArea,
|
nsDOMDeviceStorage& storageArea,
|
||||||
const nsAString& filename,
|
const nsAString& filename,
|
||||||
const dom::Optional<dom::OwningNonNull<dom::CameraStartRecordingCallback> >& aOnSuccess,
|
|
||||||
const dom::Optional<dom::OwningNonNull<dom::CameraErrorCallback> >& aOnError,
|
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
void StopRecording(ErrorResult& aRv);
|
void StopRecording(ErrorResult& aRv);
|
||||||
void ResumePreview(ErrorResult& aRv);
|
void ResumePreview(ErrorResult& aRv);
|
||||||
already_AddRefed<dom::Promise> ReleaseHardware(const dom::Optional<dom::OwningNonNull<dom::CameraReleaseCallback> >& aOnSuccess,
|
already_AddRefed<dom::Promise> ReleaseHardware(ErrorResult& aRv);
|
||||||
const dom::Optional<dom::OwningNonNull<dom::CameraErrorCallback> >& aOnError,
|
|
||||||
ErrorResult& aRv);
|
|
||||||
void ResumeContinuousFocus(ErrorResult& aRv);
|
void ResumeContinuousFocus(ErrorResult& aRv);
|
||||||
|
|
||||||
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||||
@ -223,29 +195,6 @@ protected:
|
|||||||
nsRefPtr<dom::Promise> mReleasePromise;
|
nsRefPtr<dom::Promise> mReleasePromise;
|
||||||
nsRefPtr<dom::Promise> mSetConfigurationPromise;
|
nsRefPtr<dom::Promise> mSetConfigurationPromise;
|
||||||
|
|
||||||
// solicited camera control event handlers
|
|
||||||
nsRefPtr<dom::GetCameraCallback> mGetCameraOnSuccessCb;
|
|
||||||
nsRefPtr<dom::CameraErrorCallback> mGetCameraOnErrorCb;
|
|
||||||
nsRefPtr<dom::CameraAutoFocusCallback> mAutoFocusOnSuccessCb;
|
|
||||||
nsRefPtr<dom::CameraErrorCallback> mAutoFocusOnErrorCb;
|
|
||||||
nsRefPtr<dom::CameraTakePictureCallback> mTakePictureOnSuccessCb;
|
|
||||||
nsRefPtr<dom::CameraErrorCallback> mTakePictureOnErrorCb;
|
|
||||||
nsRefPtr<dom::CameraStartRecordingCallback> mStartRecordingOnSuccessCb;
|
|
||||||
nsRefPtr<dom::CameraErrorCallback> mStartRecordingOnErrorCb;
|
|
||||||
nsRefPtr<dom::CameraReleaseCallback> mReleaseOnSuccessCb;
|
|
||||||
nsRefPtr<dom::CameraErrorCallback> mReleaseOnErrorCb;
|
|
||||||
nsRefPtr<dom::CameraSetConfigurationCallback> mSetConfigurationOnSuccessCb;
|
|
||||||
nsRefPtr<dom::CameraErrorCallback> mSetConfigurationOnErrorCb;
|
|
||||||
|
|
||||||
// unsolicited event handlers
|
|
||||||
nsRefPtr<dom::CameraShutterCallback> mOnShutterCb;
|
|
||||||
nsRefPtr<dom::CameraClosedCallback> mOnClosedCb;
|
|
||||||
nsRefPtr<dom::CameraRecorderStateChange> mOnRecorderStateChangeCb;
|
|
||||||
nsRefPtr<dom::CameraPreviewStateChange> mOnPreviewStateChangeCb;
|
|
||||||
nsRefPtr<dom::CameraAutoFocusMovingCallback> mOnAutoFocusMovingCb;
|
|
||||||
nsRefPtr<dom::CameraAutoFocusCallback> mOnAutoFocusCompletedCb;
|
|
||||||
nsRefPtr<dom::CameraFaceDetectionCallback> mOnFacesDetectedCb;
|
|
||||||
|
|
||||||
// Camera event listener; we only need this weak reference so that
|
// Camera event listener; we only need this weak reference so that
|
||||||
// we can remove the listener from the camera when we're done
|
// we can remove the listener from the camera when we're done
|
||||||
// with it.
|
// with it.
|
||||||
|
@ -144,24 +144,17 @@ public:
|
|||||||
nsRefPtr<nsDOMCameraManager> aManager,
|
nsRefPtr<nsDOMCameraManager> aManager,
|
||||||
uint32_t aCameraId,
|
uint32_t aCameraId,
|
||||||
const CameraConfiguration& aInitialConfig,
|
const CameraConfiguration& aInitialConfig,
|
||||||
nsRefPtr<GetCameraCallback> aOnSuccess,
|
|
||||||
nsRefPtr<CameraErrorCallback> aOnError,
|
|
||||||
nsRefPtr<Promise> aPromise)
|
nsRefPtr<Promise> aPromise)
|
||||||
: mPrincipal(aPrincipal)
|
: mPrincipal(aPrincipal)
|
||||||
, mWindow(aWindow)
|
, mWindow(aWindow)
|
||||||
, mCameraManager(aManager)
|
, mCameraManager(aManager)
|
||||||
, mCameraId(aCameraId)
|
, mCameraId(aCameraId)
|
||||||
, mInitialConfig(aInitialConfig)
|
, mInitialConfig(aInitialConfig)
|
||||||
, mOnSuccess(aOnSuccess)
|
|
||||||
, mOnError(aOnError)
|
|
||||||
, mPromise(aPromise)
|
, mPromise(aPromise)
|
||||||
{
|
{ }
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~CameraPermissionRequest()
|
virtual ~CameraPermissionRequest() { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult DispatchCallback(uint32_t aPermission);
|
nsresult DispatchCallback(uint32_t aPermission);
|
||||||
void CallAllow();
|
void CallAllow();
|
||||||
@ -171,15 +164,10 @@ protected:
|
|||||||
nsRefPtr<nsDOMCameraManager> mCameraManager;
|
nsRefPtr<nsDOMCameraManager> mCameraManager;
|
||||||
uint32_t mCameraId;
|
uint32_t mCameraId;
|
||||||
CameraConfiguration mInitialConfig;
|
CameraConfiguration mInitialConfig;
|
||||||
nsRefPtr<GetCameraCallback> mOnSuccess;
|
|
||||||
nsRefPtr<CameraErrorCallback> mOnError;
|
|
||||||
nsRefPtr<Promise> mPromise;
|
nsRefPtr<Promise> mPromise;
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION(CameraPermissionRequest, mWindow,
|
NS_IMPL_CYCLE_COLLECTION(CameraPermissionRequest, mWindow, mPromise)
|
||||||
mOnSuccess,
|
|
||||||
mOnError,
|
|
||||||
mPromise)
|
|
||||||
|
|
||||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CameraPermissionRequest)
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CameraPermissionRequest)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIContentPermissionRequest)
|
NS_INTERFACE_MAP_ENTRY(nsIContentPermissionRequest)
|
||||||
@ -245,13 +233,13 @@ CameraPermissionRequest::DispatchCallback(uint32_t aPermission)
|
|||||||
void
|
void
|
||||||
CameraPermissionRequest::CallAllow()
|
CameraPermissionRequest::CallAllow()
|
||||||
{
|
{
|
||||||
mCameraManager->PermissionAllowed(mCameraId, mInitialConfig, mOnSuccess, mOnError, mPromise);
|
mCameraManager->PermissionAllowed(mCameraId, mInitialConfig, mPromise);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CameraPermissionRequest::CallCancel()
|
CameraPermissionRequest::CallCancel()
|
||||||
{
|
{
|
||||||
mCameraManager->PermissionCancelled(mCameraId, mInitialConfig, mOnSuccess, mOnError, mPromise);
|
mCameraManager->PermissionCancelled(mCameraId, mInitialConfig, mPromise);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
@ -275,8 +263,6 @@ nsDOMCameraManager::PreinitCameraHardware()
|
|||||||
already_AddRefed<Promise>
|
already_AddRefed<Promise>
|
||||||
nsDOMCameraManager::GetCamera(const nsAString& aCamera,
|
nsDOMCameraManager::GetCamera(const nsAString& aCamera,
|
||||||
const CameraConfiguration& aInitialConfig,
|
const CameraConfiguration& aInitialConfig,
|
||||||
const OptionalNonNullGetCameraCallback& aOnSuccess,
|
|
||||||
const OptionalNonNullCameraErrorCallback& aOnError,
|
|
||||||
ErrorResult& aRv)
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
DOM_CAMERA_LOGT("%s:%d\n", __func__, __LINE__);
|
DOM_CAMERA_LOGT("%s:%d\n", __func__, __LINE__);
|
||||||
@ -297,18 +283,8 @@ nsDOMCameraManager::GetCamera(const nsAString& aCamera,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<GetCameraCallback> successCallback;
|
|
||||||
if (aOnSuccess.WasPassed()) {
|
|
||||||
successCallback = &aOnSuccess.Value();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<CameraErrorCallback> errorCallback;
|
|
||||||
if (aOnError.WasPassed()) {
|
|
||||||
errorCallback = &aOnError.Value();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mPermission == nsIPermissionManager::ALLOW_ACTION) {
|
if (mPermission == nsIPermissionManager::ALLOW_ACTION) {
|
||||||
PermissionAllowed(cameraId, aInitialConfig, successCallback, errorCallback, promise);
|
PermissionAllowed(cameraId, aInitialConfig, promise);
|
||||||
return promise.forget();
|
return promise.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,13 +300,13 @@ nsDOMCameraManager::GetCamera(const nsAString& aCamera,
|
|||||||
uint16_t status = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
|
uint16_t status = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
|
||||||
principal->GetAppStatus(&status);
|
principal->GetAppStatus(&status);
|
||||||
if (status == nsIPrincipal::APP_STATUS_CERTIFIED && CheckPermission(mWindow)) {
|
if (status == nsIPrincipal::APP_STATUS_CERTIFIED && CheckPermission(mWindow)) {
|
||||||
PermissionAllowed(cameraId, aInitialConfig, successCallback, errorCallback, promise);
|
PermissionAllowed(cameraId, aInitialConfig, promise);
|
||||||
return promise.forget();
|
return promise.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIRunnable> permissionRequest =
|
nsCOMPtr<nsIRunnable> permissionRequest =
|
||||||
new CameraPermissionRequest(principal, mWindow, this, cameraId, aInitialConfig,
|
new CameraPermissionRequest(principal, mWindow, this, cameraId,
|
||||||
successCallback, errorCallback, promise);
|
aInitialConfig, promise);
|
||||||
|
|
||||||
NS_DispatchToMainThread(permissionRequest);
|
NS_DispatchToMainThread(permissionRequest);
|
||||||
return promise.forget();
|
return promise.forget();
|
||||||
@ -339,8 +315,6 @@ nsDOMCameraManager::GetCamera(const nsAString& aCamera,
|
|||||||
void
|
void
|
||||||
nsDOMCameraManager::PermissionAllowed(uint32_t aCameraId,
|
nsDOMCameraManager::PermissionAllowed(uint32_t aCameraId,
|
||||||
const CameraConfiguration& aInitialConfig,
|
const CameraConfiguration& aInitialConfig,
|
||||||
GetCameraCallback* aOnSuccess,
|
|
||||||
CameraErrorCallback* aOnError,
|
|
||||||
Promise* aPromise)
|
Promise* aPromise)
|
||||||
{
|
{
|
||||||
mPermission = nsIPermissionManager::ALLOW_ACTION;
|
mPermission = nsIPermissionManager::ALLOW_ACTION;
|
||||||
@ -348,7 +322,7 @@ nsDOMCameraManager::PermissionAllowed(uint32_t aCameraId,
|
|||||||
// Creating this object will trigger the aOnSuccess callback
|
// Creating this object will trigger the aOnSuccess callback
|
||||||
// (or the aOnError one, if it fails).
|
// (or the aOnError one, if it fails).
|
||||||
nsRefPtr<nsDOMCameraControl> cameraControl =
|
nsRefPtr<nsDOMCameraControl> cameraControl =
|
||||||
new nsDOMCameraControl(aCameraId, aInitialConfig, aOnSuccess, aOnError, aPromise, mWindow);
|
new nsDOMCameraControl(aCameraId, aInitialConfig, aPromise, mWindow);
|
||||||
|
|
||||||
Register(cameraControl);
|
Register(cameraControl);
|
||||||
}
|
}
|
||||||
@ -356,17 +330,10 @@ nsDOMCameraManager::PermissionAllowed(uint32_t aCameraId,
|
|||||||
void
|
void
|
||||||
nsDOMCameraManager::PermissionCancelled(uint32_t aCameraId,
|
nsDOMCameraManager::PermissionCancelled(uint32_t aCameraId,
|
||||||
const CameraConfiguration& aInitialConfig,
|
const CameraConfiguration& aInitialConfig,
|
||||||
GetCameraCallback* aOnSuccess,
|
|
||||||
CameraErrorCallback* aOnError,
|
|
||||||
Promise* aPromise)
|
Promise* aPromise)
|
||||||
{
|
{
|
||||||
mPermission = nsIPermissionManager::DENY_ACTION;
|
mPermission = nsIPermissionManager::DENY_ACTION;
|
||||||
|
|
||||||
aPromise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
|
aPromise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
|
||||||
if (aOnError) {
|
|
||||||
ErrorResult ignored;
|
|
||||||
aOnError->Call(NS_LITERAL_STRING("Permission denied."), ignored);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -26,17 +26,11 @@ namespace mozilla {
|
|||||||
class nsDOMCameraControl;
|
class nsDOMCameraControl;
|
||||||
namespace dom {
|
namespace dom {
|
||||||
struct CameraConfiguration;
|
struct CameraConfiguration;
|
||||||
class GetCameraCallback;
|
|
||||||
class CameraErrorCallback;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef nsTArray<nsRefPtr<mozilla::nsDOMCameraControl> > CameraControls;
|
typedef nsTArray<nsRefPtr<mozilla::nsDOMCameraControl> > CameraControls;
|
||||||
typedef nsClassHashtable<nsUint64HashKey, CameraControls> WindowTable;
|
typedef nsClassHashtable<nsUint64HashKey, CameraControls> WindowTable;
|
||||||
typedef mozilla::dom::Optional<mozilla::dom::OwningNonNull<mozilla::dom::GetCameraCallback> >
|
|
||||||
OptionalNonNullGetCameraCallback;
|
|
||||||
typedef mozilla::dom::Optional<mozilla::dom::OwningNonNull<mozilla::dom::CameraErrorCallback> >
|
|
||||||
OptionalNonNullCameraErrorCallback;
|
|
||||||
|
|
||||||
class nsDOMCameraManager MOZ_FINAL
|
class nsDOMCameraManager MOZ_FINAL
|
||||||
: public nsIObserver
|
: public nsIObserver
|
||||||
@ -66,28 +60,21 @@ public:
|
|||||||
|
|
||||||
void PermissionAllowed(uint32_t aCameraId,
|
void PermissionAllowed(uint32_t aCameraId,
|
||||||
const mozilla::dom::CameraConfiguration& aOptions,
|
const mozilla::dom::CameraConfiguration& aOptions,
|
||||||
mozilla::dom::GetCameraCallback* aOnSuccess,
|
|
||||||
mozilla::dom::CameraErrorCallback* aOnError,
|
|
||||||
mozilla::dom::Promise* aPromise);
|
mozilla::dom::Promise* aPromise);
|
||||||
|
|
||||||
void PermissionCancelled(uint32_t aCameraId,
|
void PermissionCancelled(uint32_t aCameraId,
|
||||||
const mozilla::dom::CameraConfiguration& aOptions,
|
const mozilla::dom::CameraConfiguration& aOptions,
|
||||||
mozilla::dom::GetCameraCallback* aOnSuccess,
|
|
||||||
mozilla::dom::CameraErrorCallback* aOnError,
|
|
||||||
mozilla::dom::Promise* aPromise);
|
mozilla::dom::Promise* aPromise);
|
||||||
|
|
||||||
// WebIDL
|
// WebIDL
|
||||||
already_AddRefed<mozilla::dom::Promise>
|
already_AddRefed<mozilla::dom::Promise>
|
||||||
GetCamera(const nsAString& aCamera,
|
GetCamera(const nsAString& aCamera,
|
||||||
const mozilla::dom::CameraConfiguration& aOptions,
|
const mozilla::dom::CameraConfiguration& aOptions,
|
||||||
const OptionalNonNullGetCameraCallback& aOnSuccess,
|
|
||||||
const OptionalNonNullCameraErrorCallback& aOnError,
|
|
||||||
mozilla::ErrorResult& aRv);
|
mozilla::ErrorResult& aRv);
|
||||||
void GetListOfCameras(nsTArray<nsString>& aList, mozilla::ErrorResult& aRv);
|
void GetListOfCameras(nsTArray<nsString>& aList, mozilla::ErrorResult& aRv);
|
||||||
|
|
||||||
nsPIDOMWindow* GetParentObject() const { return mWindow; }
|
nsPIDOMWindow* GetParentObject() const { return mWindow; }
|
||||||
virtual JSObject* WrapObject(JSContext* aCx)
|
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||||
MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_GONK
|
#ifdef MOZ_WIDGET_GONK
|
||||||
static void PreinitCameraHardware();
|
static void PreinitCameraHardware();
|
||||||
|
@ -1,97 +0,0 @@
|
|||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Test for bug 1022766</title>
|
|
||||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
|
||||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<script type="text/javascript" src="../camera_common.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<video id="viewfinder" width="200" height="200" autoplay></video>
|
|
||||||
<img src="#" alt="This image is going to load" id="testimage"/>
|
|
||||||
<script class="testbody" type="text/javascript;version=1.7">
|
|
||||||
|
|
||||||
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
|
|
||||||
var config = {
|
|
||||||
mode: 'picture',
|
|
||||||
recorderProfile: 'cif',
|
|
||||||
previewSize: {
|
|
||||||
width: 352,
|
|
||||||
height: 288
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function onError(e) {
|
|
||||||
ok(false, "Error" + JSON.stringify(e));
|
|
||||||
}
|
|
||||||
|
|
||||||
var Camera = {
|
|
||||||
cameraObj: null,
|
|
||||||
_otherPictureSize: null,
|
|
||||||
get viewfinder() {
|
|
||||||
return document.getElementById('viewfinder');
|
|
||||||
},
|
|
||||||
|
|
||||||
firstCallFailed: false,
|
|
||||||
secondCallSucceeded: false,
|
|
||||||
checkForDone: function test_checkForDone() {
|
|
||||||
if (Camera.firstCallFailed && Camera.secondCallSucceeded) {
|
|
||||||
Camera.cameraObj.release();
|
|
||||||
Camera.cameraObj = null;
|
|
||||||
CameraTest.end();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
successOne: function test_successOne(focused) {
|
|
||||||
ok(false, "First call to autoFocus() succeeded unexpectedly");
|
|
||||||
},
|
|
||||||
failureOne: function test_failureOne(error) {
|
|
||||||
ok(error == "AutoFocusInterrupted", "First call to autoFocus() failed with: "
|
|
||||||
+ error);
|
|
||||||
Camera.firstCallFailed = true;
|
|
||||||
Camera.checkForDone();
|
|
||||||
},
|
|
||||||
successTwo: function test_successTwo(focused) {
|
|
||||||
ok(true, "Second call to autoFocus() succeeded");
|
|
||||||
Camera.secondCallSucceeded = true;
|
|
||||||
Camera.checkForDone();
|
|
||||||
},
|
|
||||||
failureTwo: function test_failureTwo(error) {
|
|
||||||
ok(false, "Second call to autoFocus() failed unexpectedly with: " + error);
|
|
||||||
},
|
|
||||||
|
|
||||||
start: function test_start() {
|
|
||||||
function onSuccess(camera, config) {
|
|
||||||
Camera.cameraObj = camera;
|
|
||||||
Camera.viewfinder.mozSrcObject = camera;
|
|
||||||
Camera.viewfinder.play();
|
|
||||||
|
|
||||||
// It doesn't matter if the emulator supports focus or not;
|
|
||||||
// this is just testing the sequencing.
|
|
||||||
camera.autoFocus(Camera.successOne, Camera.failureOne);
|
|
||||||
camera.autoFocus(Camera.successTwo, Camera.failureTwo);
|
|
||||||
};
|
|
||||||
|
|
||||||
navigator.mozCameras.getCamera(whichCamera, config, onSuccess, onError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener('beforeunload', function() {
|
|
||||||
Camera.viewfinder.mozSrcObject = null;
|
|
||||||
if (Camera.cameraObj) {
|
|
||||||
Camera.cameraObj.release();
|
|
||||||
Camera.cameraObj = null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
CameraTest.begin("hardware", function(test) {
|
|
||||||
test.set("auto-focus-process-failure", function() {
|
|
||||||
Camera.start();
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,107 +0,0 @@
|
|||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Test for bug 1099390</title>
|
|
||||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
|
||||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<script type="text/javascript" src="camera_common.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<video id="viewfinder" width="200" height="200" autoplay></video>
|
|
||||||
<img src="#" alt="This image is going to load" id="testimage"/>
|
|
||||||
<script class="testbody" type="text/javascript;version=1.7">
|
|
||||||
|
|
||||||
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
|
|
||||||
var config = {
|
|
||||||
mode: 'picture',
|
|
||||||
recorderProfile: 'cif',
|
|
||||||
previewSize: {
|
|
||||||
width: 352,
|
|
||||||
height: 288
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function onError(e) {
|
|
||||||
ok(false, "Error " + e);
|
|
||||||
}
|
|
||||||
|
|
||||||
var Camera = {
|
|
||||||
_cameraObj: null,
|
|
||||||
|
|
||||||
get viewfinder() {
|
|
||||||
return document.getElementById('viewfinder');
|
|
||||||
},
|
|
||||||
|
|
||||||
release: function release() {
|
|
||||||
viewfinder.mozSrcObject = null;
|
|
||||||
if (Camera._cameraObj) {
|
|
||||||
Camera._cameraObj.release();
|
|
||||||
Camera._cameraObj = null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
test: function test(cam) {
|
|
||||||
var gotCloseEvent = false;
|
|
||||||
var gotReleaseCallback = false;
|
|
||||||
|
|
||||||
function gotAll() {
|
|
||||||
var all = gotCloseEvent && gotReleaseCallback;
|
|
||||||
if (all) {
|
|
||||||
info("Got all expected notifications");
|
|
||||||
}
|
|
||||||
return all;
|
|
||||||
};
|
|
||||||
|
|
||||||
cam.onClosed = function(reason) {
|
|
||||||
cam.onClosed = null;
|
|
||||||
ok(!gotCloseEvent, "gotCloseEvent was " + gotCloseEvent);
|
|
||||||
ok(reason === "HardwareReleased", "onClosed reason is: " + reason);
|
|
||||||
gotCloseEvent = true;
|
|
||||||
if (gotAll()) {
|
|
||||||
SimpleTest.finish();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var onSuccess = function() {
|
|
||||||
ok(!gotReleaseCallback, "gotReleaseCallback was " + gotReleaseCallback);
|
|
||||||
gotReleaseCallback = true;
|
|
||||||
if (gotAll()) {
|
|
||||||
SimpleTest.finish();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
cam.release(onSuccess, onError);
|
|
||||||
}, // test()
|
|
||||||
|
|
||||||
start: function start() {
|
|
||||||
function onSuccess(cam) {
|
|
||||||
Camera._cameraObj = cam;
|
|
||||||
Camera.viewfinder.mozSrcObject = cam;
|
|
||||||
Camera.viewfinder.play();
|
|
||||||
|
|
||||||
var onPreviewStateChange = function(e) {
|
|
||||||
if (e.newState === 'started') {
|
|
||||||
cam.removeEventListener('previewstatechange', onPreviewStateChange);
|
|
||||||
Camera.test(cam);
|
|
||||||
}
|
|
||||||
}; // onPreviewStateChange
|
|
||||||
cam.addEventListener('previewstatechange', onPreviewStateChange);
|
|
||||||
}; // onSuccess()
|
|
||||||
|
|
||||||
navigator.mozCameras.getCamera(whichCamera, config, onSuccess, onError);
|
|
||||||
}, // start()
|
|
||||||
}
|
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
|
|
||||||
window.addEventListener('beforeunload', function() {
|
|
||||||
Camera.release();
|
|
||||||
});
|
|
||||||
|
|
||||||
Camera.start();
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,223 +0,0 @@
|
|||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Test for bug 975472</title>
|
|
||||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
|
||||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<script type="text/javascript" src="../camera_common.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<video id="viewfinder" width="200" height="200" autoplay></video>
|
|
||||||
<img src="#" alt="This image is going to load" id="testimage"/>
|
|
||||||
<script class="testbody" type="text/javascript;version=1.7">
|
|
||||||
|
|
||||||
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
|
|
||||||
var config = {
|
|
||||||
mode: 'picture',
|
|
||||||
recorderProfile: 'cif',
|
|
||||||
previewSize: {
|
|
||||||
width: 352,
|
|
||||||
height: 288
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var options = {
|
|
||||||
rotation: 0,
|
|
||||||
position: {
|
|
||||||
latitude: 43.645687,
|
|
||||||
longitude: -79.393661
|
|
||||||
},
|
|
||||||
dateTime: Date.now()
|
|
||||||
};
|
|
||||||
|
|
||||||
function onError(e) {
|
|
||||||
ok(false, "Error" + JSON.stringify(e));
|
|
||||||
}
|
|
||||||
function next() {
|
|
||||||
Camera.nextTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
// The array of tests
|
|
||||||
var tests = [
|
|
||||||
{
|
|
||||||
key: "release-after-release",
|
|
||||||
func: function testAutoFocus(camera) {
|
|
||||||
function onSuccess(success) {
|
|
||||||
ok(true, "release() succeeded");
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
function onError(error) {
|
|
||||||
ok(false, "release() failed with: " + error);
|
|
||||||
}
|
|
||||||
camera.release(onSuccess, onError);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "set-picture-size-after-release",
|
|
||||||
func: function testSetPictureSize(camera) {
|
|
||||||
camera.setPictureSize({ width: 0, height: 0 });
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "set-thumbnail-size-after-release",
|
|
||||||
func: function testSetThumbnailSize(camera) {
|
|
||||||
camera.setThumbnailSize({ width: 0, height: 0 });
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "get-sensor-angle-after-release",
|
|
||||||
func: function testGetSensorAngle(camera) {
|
|
||||||
ok(camera.sensorAngle == 0, "camera.sensorAngle = " + camera.sensorAngle);
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "resume-preview-after-release",
|
|
||||||
func: function testResumePreview(camera) {
|
|
||||||
camera.resumePreview();
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "auto-focus-after-release",
|
|
||||||
func: function testAutoFocus(camera) {
|
|
||||||
function onSuccess(success) {
|
|
||||||
ok(false, "autoFocus() succeeded incorrectly");
|
|
||||||
}
|
|
||||||
function onError(error) {
|
|
||||||
ok(error === "HardwareClosed", "autoFocus() failed with: " + error);
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
camera.autoFocus(onSuccess, onError);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "take-picture-after-release",
|
|
||||||
func: function testTakePicture(camera) {
|
|
||||||
function onSuccess(picture) {
|
|
||||||
ok(false, "takePicture() succeeded incorrectly");
|
|
||||||
}
|
|
||||||
function onError(error) {
|
|
||||||
ok(error === "HardwareClosed", "takePicture() failed with: " + error);
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
camera.takePicture(null, onSuccess, onError);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "start-recording-after-release",
|
|
||||||
func: function testStartRecording(camera) {
|
|
||||||
function onSuccess(picture) {
|
|
||||||
ok(false, "startRecording() process succeeded incorrectly");
|
|
||||||
}
|
|
||||||
function onError(error) {
|
|
||||||
ok(error === "GeneralFailure", "startRecording() failed with: " + error);
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
var recordingOptions = {
|
|
||||||
profile: 'cif',
|
|
||||||
rotation: 0
|
|
||||||
};
|
|
||||||
camera.startRecording(recordingOptions,
|
|
||||||
navigator.getDeviceStorage('videos'),
|
|
||||||
'bug975472.mp4',
|
|
||||||
onSuccess, onError);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "stop-recording-after-release",
|
|
||||||
func: function testStopRecording(camera) {
|
|
||||||
camera.stopRecording();
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "set-configuration-after-release",
|
|
||||||
func: function testSetConfiguration(camera) {
|
|
||||||
function onSuccess(picture) {
|
|
||||||
ok(false, "setConfiguration() process succeeded incorrectly");
|
|
||||||
}
|
|
||||||
function onError(error) {
|
|
||||||
ok(error === "HardwareClosed", "setConfiguration() failed with: " + error);
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
camera.setConfiguration(config, onSuccess, onError);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
var testGenerator = function() {
|
|
||||||
for (var i = 0; i < tests.length; ++i ) {
|
|
||||||
yield tests[i];
|
|
||||||
}
|
|
||||||
}();
|
|
||||||
|
|
||||||
var Camera = {
|
|
||||||
cameraObj: null,
|
|
||||||
_otherPictureSize: null,
|
|
||||||
get viewfinder() {
|
|
||||||
return document.getElementById('viewfinder');
|
|
||||||
},
|
|
||||||
onCameraReady: function () {
|
|
||||||
Camera.nextTest = function() {
|
|
||||||
try {
|
|
||||||
var t = testGenerator.next();
|
|
||||||
info("test: " + t.key);
|
|
||||||
t.func(Camera.cameraObj);
|
|
||||||
} catch(e) {
|
|
||||||
if (e instanceof StopIteration) {
|
|
||||||
CameraTest.end();
|
|
||||||
} else {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// Release the camera hardware, and call all of the asynchronous methods
|
|
||||||
// to make sure they properly handle being in this state.
|
|
||||||
Camera.cameraObj.release();
|
|
||||||
next();
|
|
||||||
},
|
|
||||||
release: function release() {
|
|
||||||
cameraObj = null;
|
|
||||||
},
|
|
||||||
start: function run_test() {
|
|
||||||
function onSuccess(camera, config) {
|
|
||||||
Camera.cameraObj = camera;
|
|
||||||
Camera.viewfinder.mozSrcObject = camera;
|
|
||||||
Camera.viewfinder.play();
|
|
||||||
ok(camera.capabilities.pictureSizes.length > 0,
|
|
||||||
"capabilities.pictureSizes.length = " +
|
|
||||||
camera.capabilities.pictureSizes.length);
|
|
||||||
Camera._otherPictureSize = camera.capabilities.pictureSizes.slice(-1)[0];
|
|
||||||
camera.setPictureSize(camera.capabilities.pictureSizes[0]);
|
|
||||||
options.pictureSize = Camera._otherPictureSize;
|
|
||||||
options.fileFormat = camera.capabilities.fileFormats[0];
|
|
||||||
info("getCamera callback, setting pictureSize = " + options.pictureSize.toSource());
|
|
||||||
Camera.cameraObj.onPreviewStateChange = function(state) {
|
|
||||||
if (state === 'started') {
|
|
||||||
info("viewfinder is ready and playing");
|
|
||||||
Camera.cameraObj.onPreviewStateChange = null;
|
|
||||||
Camera.onCameraReady();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
navigator.mozCameras.getCamera(whichCamera, config, onSuccess, onError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
|
|
||||||
window.addEventListener('beforeunload', function() {
|
|
||||||
Camera.viewfinder.mozSrcObject = null;
|
|
||||||
Camera.cameraObj.release();
|
|
||||||
Camera.cameraObj = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
Camera.start();
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,242 +0,0 @@
|
|||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Test for mozCameras.getCamera() with separate .setConfiguration() call</title>
|
|
||||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
|
||||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<video id="viewfinder" width="200" height="200" autoplay></video>
|
|
||||||
<img src="#" alt="This image is going to load" id="testimage"/>
|
|
||||||
<script class="testbody" type="text/javascript;version=1.7">
|
|
||||||
|
|
||||||
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
|
|
||||||
var options = {
|
|
||||||
mode: 'picture',
|
|
||||||
recorderProfile: 'cif',
|
|
||||||
previewSize: {
|
|
||||||
width: 352,
|
|
||||||
height: 288
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var config = {
|
|
||||||
dateTime: Date.now() / 1000,
|
|
||||||
pictureSize: null,
|
|
||||||
fileFormat: 'jpeg',
|
|
||||||
rotation: 90
|
|
||||||
};
|
|
||||||
|
|
||||||
function onError(e) {
|
|
||||||
ok(false, "Error" + JSON.stringify(e));
|
|
||||||
}
|
|
||||||
|
|
||||||
var capabilities = [ 'previewSizes', 'pictureSizes', 'fileFormats', 'maxFocusAreas', 'minExposureCompensation',
|
|
||||||
'maxExposureCompensation', 'stepExposureCompensation', 'maxMeteringAreas', 'videoSizes',
|
|
||||||
'recorderProfiles', 'zoomRatios', 'isoModes'];
|
|
||||||
|
|
||||||
var Camera = {
|
|
||||||
cameraObj: null,
|
|
||||||
_recording: false,
|
|
||||||
_currentTest: null,
|
|
||||||
_autoFocusSupported: 0,
|
|
||||||
_manuallyFocused: false,
|
|
||||||
_flashmodes: null,
|
|
||||||
_pictureSizes: null,
|
|
||||||
_previewSizes: null,
|
|
||||||
_whiteBalanceModes: null,
|
|
||||||
_zoomRatios: null,
|
|
||||||
_sceneModes: null,
|
|
||||||
_focusModes: null,
|
|
||||||
_zoomRatios: null,
|
|
||||||
_testsCompleted: 0,
|
|
||||||
_shutter: 0,
|
|
||||||
_config: {
|
|
||||||
dateTime: Date.now() / 1000,
|
|
||||||
pictureSize: null,
|
|
||||||
fileFormat: 'jpeg',
|
|
||||||
rotation: 90
|
|
||||||
},
|
|
||||||
_tests: null,
|
|
||||||
get viewfinder() {
|
|
||||||
return document.getElementById('viewfinder');
|
|
||||||
},
|
|
||||||
setFlashMode: function camera_setFlash(mode) {
|
|
||||||
this.cameraObj.flashMode = mode;
|
|
||||||
},
|
|
||||||
setFocus: function camera_setfocus(mode) {
|
|
||||||
this.cameraObj.focus = mode;
|
|
||||||
},
|
|
||||||
setZoom: function camera_setZoom(zoom) {
|
|
||||||
this.cameraObj.zoom = zoom;
|
|
||||||
},
|
|
||||||
getZoom: function camera_getZoom() {
|
|
||||||
return this.cameraObj.zoom;
|
|
||||||
},
|
|
||||||
getFileFormats: function camera_formats() {
|
|
||||||
this._fileFormats = this.cameraObj.capabilities.fileFormats;
|
|
||||||
},
|
|
||||||
getFlashModes: function camera_getFlash() {
|
|
||||||
this._flashmodes = this.cameraObj.capabilities.flashModes;
|
|
||||||
},
|
|
||||||
getFocusModes: function camera_getFocus() {
|
|
||||||
this._focusModes = this.cameraObj.capabilities.focusModes;
|
|
||||||
},
|
|
||||||
getSceneModes: function camera_getScene() {
|
|
||||||
this._sceneModes = this.cameraObj.capabilities.sceneModes;
|
|
||||||
},
|
|
||||||
getZoomRatios: function camera_getZoom() {
|
|
||||||
this._zoomRatios = this.cameraObj.capabilities.zoomRatios;
|
|
||||||
},
|
|
||||||
getWhiteBalance: function camera_white() {
|
|
||||||
this._whitebalanceModes = this.cameraObj.capabilities.whiteBalanceModes;
|
|
||||||
},
|
|
||||||
getPictureSizes: function camera_sizes() {
|
|
||||||
this._pictureSizes = this.cameraObj.capabilities.pictureSizes;
|
|
||||||
},
|
|
||||||
getPreviewSizes: function camera_preview() {
|
|
||||||
this._previewSizes = this.cameraObj.capabilities.previewSizes;
|
|
||||||
},
|
|
||||||
getZoomRatios: function camera_preview() {
|
|
||||||
this._zoomRatios = this.cameraObj.capabilities.zoomRatios;
|
|
||||||
},
|
|
||||||
takePictureSuccess: function taken_foto(blob) {
|
|
||||||
var img = new Image();
|
|
||||||
var test = this._currentTest;
|
|
||||||
img.onload = function Imgsize() {
|
|
||||||
ok(this.width == test.pictureSize.width, "The image taken has the width " +
|
|
||||||
this.width + " pictureSize width = " + test.pictureSize.width);
|
|
||||||
ok(this.height == test.pictureSize.height, "The image taken has the height " +
|
|
||||||
this.height + " picturesize height = " + test.pictureSize.height);
|
|
||||||
Camera._testsCompleted++;
|
|
||||||
if(Camera._testsCompleted == Camera._tests.length) {
|
|
||||||
ok(true, "test finishing");
|
|
||||||
SimpleTest.finish();
|
|
||||||
} else {
|
|
||||||
Camera.runTests();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ok(blob.size > 100 , "Blob Size Gathered = " + blob.size);
|
|
||||||
ok("image/" + test.fileFormat == blob.type, "Blob Type = " + blob.type);
|
|
||||||
img.src = window.URL.createObjectURL(blob);
|
|
||||||
},
|
|
||||||
shutter: function onShutter () {
|
|
||||||
Camera._shutter++;
|
|
||||||
|
|
||||||
ok(Camera._shutter == (Camera._testsCompleted + 1), "on Shutter has been called " +
|
|
||||||
Camera._shutter + " times");
|
|
||||||
|
|
||||||
},
|
|
||||||
onReady: function onReady() {
|
|
||||||
var camcap = Camera.cameraObj.capabilities;
|
|
||||||
var tests = {};
|
|
||||||
for (var prop in capabilities) {
|
|
||||||
prop = capabilities[prop];
|
|
||||||
ok(camcap[prop] || isFinite(camcap[prop]) || camcap[prop] == null, "Camera Capability: " +
|
|
||||||
prop + " is exposed, value = " + JSON.stringify(camcap[prop]));
|
|
||||||
}
|
|
||||||
ok(camcap.maxMeteringAreas >= 0, "maxMeteringAreas = " + camcap.maxMeteringAreas);
|
|
||||||
ok(camcap.maxFocusAreas >= 0, "maxFocusAreas = " + camcap.maxFocusAreas);
|
|
||||||
for (var prop in camcap) {
|
|
||||||
if(camcap[prop] && camcap[prop].length > 1) {
|
|
||||||
tests[prop] = camcap[prop];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Camera.getPictureSizes();
|
|
||||||
Camera.getPreviewSizes();
|
|
||||||
Camera.getFileFormats();
|
|
||||||
Camera.getFocusModes();
|
|
||||||
Camera.getZoomRatios();
|
|
||||||
ok(Camera._previewSizes.length > 0, "previewSizes length = " + Camera._previewSizes.length);
|
|
||||||
ok(Camera._pictureSizes.length > 0, "picturesizes length = " + Camera._pictureSizes.length);
|
|
||||||
ok(Camera._fileFormats.length > 0, "file formats length = " + Camera._fileFormats.length);
|
|
||||||
ok(camcap.isoModes.length == 0, "ISO modes length = " + camcap.isoModes.length);
|
|
||||||
|
|
||||||
// The emulator doesn't support zoom, so these parameters will be very constrained
|
|
||||||
// For more ambitious tests, see test_camera_fake_parameters.html
|
|
||||||
ok(Camera._zoomRatios.length == 1, "zoom ratios length = " + Camera._zoomRatios.length);
|
|
||||||
ok(Camera.cameraObj.zoom == 1.0, "zoom = " + Camera.cameraObj.zoom);
|
|
||||||
// Test snapping to supported values
|
|
||||||
Camera.cameraObj.zoom = 0.9;
|
|
||||||
ok(Camera.cameraObj.zoom == 1.0, "zoom (lower limit) = " + Camera.cameraObj.zoom);
|
|
||||||
Camera.cameraObj.zoom = 1.1;
|
|
||||||
ok(Camera.cameraObj.zoom == 1.0, "zoom (upper limit) = " + Camera.cameraObj.zoom);
|
|
||||||
|
|
||||||
// Check image quality handling
|
|
||||||
Camera.cameraObj.pictureQuality = 0.0;
|
|
||||||
ok(Camera.cameraObj.pictureQuality == 0.0, "picture quality = " + Camera.cameraObj.pictureQuality);
|
|
||||||
Camera.cameraObj.pictureQuality = -0.1;
|
|
||||||
ok(Camera.cameraObj.pictureQuality == 0.0, "picture quality (minimum limit) = " + Camera.cameraObj.pictureQuality);
|
|
||||||
Camera.cameraObj.pictureQuality = -Math.pow(2, 80);
|
|
||||||
ok(Camera.cameraObj.pictureQuality == 0.0, "picture quality (BIG negative) = " + Camera.cameraObj.pictureQuality);
|
|
||||||
Camera.cameraObj.pictureQuality = 1.0;
|
|
||||||
ok(Camera.cameraObj.pictureQuality == 1.0, "picture quality = " + Camera.cameraObj.pictureQuality);
|
|
||||||
Camera.cameraObj.pictureQuality = 1.1;
|
|
||||||
ok(Camera.cameraObj.pictureQuality == 1.0, "picture quality (maximum limit) = " + Camera.cameraObj.pictureQuality);
|
|
||||||
Camera.cameraObj.pictureQuality = Math.pow(2, 80);
|
|
||||||
ok(Camera.cameraObj.pictureQuality == 1.0, "picture quality (BIG positive) = " + Camera.cameraObj.pictureQuality);
|
|
||||||
|
|
||||||
Camera._tests = new Array();
|
|
||||||
for (var i in Camera._pictureSizes) {
|
|
||||||
for (var l in Camera._fileFormats) {
|
|
||||||
var config = {
|
|
||||||
pictureSize: Camera._pictureSizes[i],
|
|
||||||
fileFormat: Camera._fileFormats[l]
|
|
||||||
};
|
|
||||||
Camera._tests.push(config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Camera.runTests();
|
|
||||||
},
|
|
||||||
runTests: function run_tests() {
|
|
||||||
var test = this._tests[this._testsCompleted];
|
|
||||||
this._currentTest = test;
|
|
||||||
Camera.setFlashMode(test.flashMode);
|
|
||||||
config.fileFormat = test.fileFormat;
|
|
||||||
config.pictureSize = test.pictureSize;
|
|
||||||
ok(true, "testing picture size " + JSON.stringify(config.pictureSize));
|
|
||||||
Camera.cameraObj.takePicture(config, this.takePictureSuccess.bind(this), onError);
|
|
||||||
},
|
|
||||||
onConfigChange: function onConfigChange(config) {
|
|
||||||
ok(config.mode === options.mode, "configuration mode = " + config.mode);
|
|
||||||
ok(config.recorderProfile === options.recorderProfile, "recorder profile = " + config.recorderProfile);
|
|
||||||
ok(config.previewSize.width === options.previewSize.width &&
|
|
||||||
config.previewSize.height === options.previewSize.height,
|
|
||||||
"preview size (w x h) = " + config.previewSize.width + " x " + config.previewSize.height);
|
|
||||||
},
|
|
||||||
setUp: function setup_tests() {
|
|
||||||
function onSuccess(camera) {
|
|
||||||
Camera.cameraObj = camera;
|
|
||||||
Camera.viewfinder.mozSrcObject = camera;
|
|
||||||
Camera.viewfinder.play();
|
|
||||||
Camera.cameraObj.onPreviewStateChange = function(state) {
|
|
||||||
if (state === 'started') {
|
|
||||||
ok(true, "viewfinder is ready and playing");
|
|
||||||
Camera.cameraObj.onPreviewStateChange = null;
|
|
||||||
Camera.onReady();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
SimpleTest.expectAssertions(0);
|
|
||||||
ok(true, "Camera Control object has been successfully initialized");
|
|
||||||
Camera.cameraObj.setConfiguration(options, Camera.onConfigChange, onError);
|
|
||||||
Camera.cameraObj.onShutter = Camera.shutter;
|
|
||||||
};
|
|
||||||
navigator.mozCameras.getCamera(whichCamera, null, onSuccess, onError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
|
|
||||||
window.addEventListener('beforeunload', function() {
|
|
||||||
Camera.viewfinder.mozSrcObject = null;
|
|
||||||
Camera.cameraObj.release();
|
|
||||||
Camera.cameraObj = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
Camera.setUp();
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,200 +0,0 @@
|
|||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Test for mozCameras.getCamera() using an initial configuration</title>
|
|
||||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
|
||||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<video id="viewfinder" width="200" height="200" autoplay></video>
|
|
||||||
<img src="#" alt="This image is going to load" id="testimage"/>
|
|
||||||
<script class="testbody" type="text/javascript;version=1.7">
|
|
||||||
|
|
||||||
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
|
|
||||||
var options = {
|
|
||||||
mode: 'picture',
|
|
||||||
recorderProfile: 'cif',
|
|
||||||
previewSize: {
|
|
||||||
width: 352,
|
|
||||||
height: 288
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var config = {
|
|
||||||
dateTime: Date.now() / 1000,
|
|
||||||
pictureSize: null,
|
|
||||||
fileFormat: 'jpeg',
|
|
||||||
rotation: 90
|
|
||||||
};
|
|
||||||
|
|
||||||
function onError(e) {
|
|
||||||
ok(false, "Error" + JSON.stringify(e));
|
|
||||||
}
|
|
||||||
|
|
||||||
var capabilities = [ 'previewSizes', 'pictureSizes', 'fileFormats', 'maxFocusAreas', 'minExposureCompensation',
|
|
||||||
'maxExposureCompensation', 'stepExposureCompensation', 'maxMeteringAreas', 'videoSizes',
|
|
||||||
'recorderProfiles'];
|
|
||||||
|
|
||||||
var Camera = {
|
|
||||||
cameraObj: null,
|
|
||||||
_recording: false,
|
|
||||||
_currentTest: null,
|
|
||||||
_autoFocusSupported: 0,
|
|
||||||
_manuallyFocused: false,
|
|
||||||
_flashmodes: null,
|
|
||||||
_pictureSizes: null,
|
|
||||||
_previewSizes: null,
|
|
||||||
_whiteBalanceModes: null,
|
|
||||||
_zoomRatios: null,
|
|
||||||
_sceneModes: null,
|
|
||||||
_focusModes: null,
|
|
||||||
_testsCompleted: 0,
|
|
||||||
_shutter: 0,
|
|
||||||
_config: {
|
|
||||||
dateTime: Date.now() / 1000,
|
|
||||||
pictureSize: null,
|
|
||||||
fileFormat: 'jpeg',
|
|
||||||
rotation: 90
|
|
||||||
},
|
|
||||||
_tests: null,
|
|
||||||
get viewfinder() {
|
|
||||||
return document.getElementById('viewfinder');
|
|
||||||
},
|
|
||||||
setFlashMode: function camera_setFlash(mode) {
|
|
||||||
this.cameraObj.flashMode = mode;
|
|
||||||
},
|
|
||||||
setFocus: function camera_setfocus(mode) {
|
|
||||||
this.cameraObj.focus = mode;
|
|
||||||
},
|
|
||||||
getFileFormats: function camera_formats() {
|
|
||||||
this._fileFormats = this.cameraObj.capabilities.fileFormats;
|
|
||||||
},
|
|
||||||
getFlashModes: function camera_getFlash() {
|
|
||||||
this._flashmodes = this.cameraObj.capabilities.flashModes;
|
|
||||||
},
|
|
||||||
getFocusModes: function camera_getFocus() {
|
|
||||||
this._focusModes = this.cameraObj.capabilities.focusModes;
|
|
||||||
},
|
|
||||||
getSceneModes: function camera_getScene() {
|
|
||||||
this._sceneModes = this.cameraObj.capabilities.sceneModes;
|
|
||||||
},
|
|
||||||
getZoomRatios: function camera_getZoom() {
|
|
||||||
this._zoomRatios = this.cameraObj.capabilities.zoomRatios;
|
|
||||||
},
|
|
||||||
getWhiteBalance: function camera_white() {
|
|
||||||
this._whitebalanceModes = this.cameraObj.capabilities.whiteBalanceModes;
|
|
||||||
},
|
|
||||||
getPictureSizes: function camera_sizes() {
|
|
||||||
this._pictureSizes = this.cameraObj.capabilities.pictureSizes;
|
|
||||||
},
|
|
||||||
getPreviewSizes: function camera_preview() {
|
|
||||||
this._previewSizes = this.cameraObj.capabilities.previewSizes;
|
|
||||||
},
|
|
||||||
takePictureSuccess: function taken_foto(blob) {
|
|
||||||
var img = new Image();
|
|
||||||
var test = this._currentTest;
|
|
||||||
img.onload = function Imgsize() {
|
|
||||||
ok(this.width == test.pictureSize.width, "The image taken has the width " +
|
|
||||||
this.width + " pictureSize width = " + test.pictureSize.width);
|
|
||||||
ok(this.height == test.pictureSize.height, "The image taken has the height " +
|
|
||||||
this.height + " picturesize height = " + test.pictureSize.height);
|
|
||||||
Camera._testsCompleted++;
|
|
||||||
if(Camera._testsCompleted == Camera._tests.length) {
|
|
||||||
ok(true, "test finishing");
|
|
||||||
SimpleTest.finish();
|
|
||||||
} else {
|
|
||||||
Camera.runTests();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ok(blob.size > 100 , "Blob Size Gathered = " + blob.size);
|
|
||||||
ok("image/" + test.fileFormat == blob.type, "Blob Type = " + blob.type);
|
|
||||||
img.src = window.URL.createObjectURL(blob);
|
|
||||||
},
|
|
||||||
shutter: function onShutter () {
|
|
||||||
Camera._shutter++;
|
|
||||||
|
|
||||||
ok(Camera._shutter == (Camera._testsCompleted + 1), "on Shutter has been called " +
|
|
||||||
Camera._shutter + " times");
|
|
||||||
|
|
||||||
},
|
|
||||||
onReady: function onReady() {
|
|
||||||
var camcap = Camera.cameraObj.capabilities;
|
|
||||||
var tests = {};
|
|
||||||
for (var prop in capabilities) {
|
|
||||||
prop = capabilities[prop];
|
|
||||||
ok(camcap[prop] || isFinite(camcap[prop]) || camcap[prop] == null, "Camera Capability: " +
|
|
||||||
prop + " is exposed, value = " + JSON.stringify(camcap[prop]));
|
|
||||||
}
|
|
||||||
for (var prop in camcap) {
|
|
||||||
if(camcap[prop] && camcap[prop].length > 1) {
|
|
||||||
tests[prop] = camcap[prop];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Camera.getPictureSizes();
|
|
||||||
Camera.getPreviewSizes();
|
|
||||||
Camera.getFileFormats();
|
|
||||||
Camera.getFocusModes();
|
|
||||||
ok(Camera._previewSizes.length > 0, "previewSizes length = " + Camera._previewSizes.length);
|
|
||||||
ok(Camera._pictureSizes.length > 0, "picturesizes length = " + Camera._pictureSizes.length);
|
|
||||||
ok(Camera._fileFormats.length > 0, "file formats length = " + Camera._fileFormats.length);
|
|
||||||
Camera._tests = new Array();
|
|
||||||
for (var i in Camera._pictureSizes) {
|
|
||||||
for (var l in Camera._fileFormats) {
|
|
||||||
var config = {
|
|
||||||
pictureSize: Camera._pictureSizes[i],
|
|
||||||
fileFormat: Camera._fileFormats[l]
|
|
||||||
};
|
|
||||||
Camera._tests.push(config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Camera.runTests();
|
|
||||||
},
|
|
||||||
runTests: function run_tests() {
|
|
||||||
var test = this._tests[this._testsCompleted];
|
|
||||||
this._currentTest = test;
|
|
||||||
Camera.setFlashMode(test.flashMode);
|
|
||||||
config.fileFormat = test.fileFormat;
|
|
||||||
config.pictureSize = test.pictureSize;
|
|
||||||
ok(true, "testing picture size " + JSON.stringify(config.pictureSize));
|
|
||||||
Camera.cameraObj.takePicture(config, this.takePictureSuccess.bind(this), onError);
|
|
||||||
},
|
|
||||||
setUp: function setup_tests() {
|
|
||||||
function onSuccess(camera, config) {
|
|
||||||
ok(true, "Camera Control object has been successfully initialized");
|
|
||||||
ok(config.mode === options.mode, "configuration mode = " + config.mode);
|
|
||||||
ok(config.recorderProfile === options.recorderProfile, "recorder profile = " + config.recorderProfile);
|
|
||||||
ok(config.previewSize.width === options.previewSize.width &&
|
|
||||||
config.previewSize.height === options.previewSize.height,
|
|
||||||
"preview size (w x h) = " + config.previewSize.width + " x " + config.previewSize.height);
|
|
||||||
Camera.cameraObj = camera;
|
|
||||||
Camera.viewfinder.mozSrcObject = camera;
|
|
||||||
Camera.viewfinder.play();
|
|
||||||
Camera.cameraObj.onPreviewStateChange = function(state) {
|
|
||||||
if (state === 'started') {
|
|
||||||
ok(true, "viewfinder is ready and playing");
|
|
||||||
Camera.cameraObj.onPreviewStateChange = null;
|
|
||||||
Camera.onReady();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
SimpleTest.expectAssertions(0);
|
|
||||||
Camera.cameraObj.onShutter = Camera.shutter;
|
|
||||||
};
|
|
||||||
navigator.mozCameras.getCamera(whichCamera, options, onSuccess, onError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
|
|
||||||
window.addEventListener('beforeunload', function() {
|
|
||||||
Camera.viewfinder.mozSrcObject = null;
|
|
||||||
Camera.cameraObj.release();
|
|
||||||
Camera.cameraObj = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
Camera.setUp();
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,76 +0,0 @@
|
|||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Test for multiple calls to mozCameras.getCamera()</title>
|
|
||||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
|
||||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<video id="viewfinder" width="200" height="200" autoplay></video>
|
|
||||||
<img src="#" alt="This image is going to load" id="testimage"/>
|
|
||||||
<script class="testbody" type="text/javascript;version=1.7">
|
|
||||||
|
|
||||||
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
|
|
||||||
var options = {
|
|
||||||
mode: 'picture',
|
|
||||||
recorderProfile: 'cif',
|
|
||||||
previewSize: {
|
|
||||||
width: 352,
|
|
||||||
height: 288
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function onError(e) {
|
|
||||||
ok(false, "Error" + JSON.stringify(e));
|
|
||||||
}
|
|
||||||
|
|
||||||
var Camera = {
|
|
||||||
cameraObj: null,
|
|
||||||
get viewfinder() {
|
|
||||||
return document.getElementById('viewfinder');
|
|
||||||
},
|
|
||||||
onReady: function take_two() {
|
|
||||||
function onSuccess(camera, config) {
|
|
||||||
ok(false, "Unexpectedly got second camera instance: " + config.toSource);
|
|
||||||
}
|
|
||||||
function onFailure(error) {
|
|
||||||
ok(true, "Correctly failed to get camera again");
|
|
||||||
SimpleTest.finish();
|
|
||||||
}
|
|
||||||
navigator.mozCameras.getCamera(whichCamera, options, onSuccess, onFailure);
|
|
||||||
},
|
|
||||||
release: function release() {
|
|
||||||
cameraObj = null;
|
|
||||||
},
|
|
||||||
start: function run_test() {
|
|
||||||
function onSuccess(camera, config) {
|
|
||||||
Camera.cameraObj = camera;
|
|
||||||
Camera.viewfinder.mozSrcObject = camera;
|
|
||||||
Camera.viewfinder.play();
|
|
||||||
Camera.cameraObj.onPreviewStateChange = function(state) {
|
|
||||||
if (state === 'started') {
|
|
||||||
ok(true, "viewfinder is ready and playing");
|
|
||||||
Camera.cameraObj.onPreviewStateChange = null;
|
|
||||||
Camera.onReady();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
navigator.mozCameras.getCamera(whichCamera, options, onSuccess, onError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
|
|
||||||
window.addEventListener('beforeunload', function() {
|
|
||||||
Camera.viewfinder.mozSrcObject = null;
|
|
||||||
Camera.cameraObj.release();
|
|
||||||
Camera.cameraObj = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
Camera.start();
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,131 +0,0 @@
|
|||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<!--
|
|
||||||
https://bugzilla.mozilla.org/show_bug.cgi?id=965421
|
|
||||||
-->
|
|
||||||
<head>
|
|
||||||
<title>Bug 965421 - Test camera hardware API for Auto focus moving Callback</title>
|
|
||||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
|
||||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<script type="text/javascript" src="../camera_common.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=965421">Mozilla Bug 965421</a>
|
|
||||||
<video id="viewfinder" width = "200" height = "200" autoplay></video>
|
|
||||||
<img src="#" alt="This image is going to load" id="testimage"/>
|
|
||||||
|
|
||||||
<script class="testbody" type="text/javascript;version=1.7">
|
|
||||||
|
|
||||||
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
|
|
||||||
var initialConfig = {
|
|
||||||
mode: 'picture',
|
|
||||||
recorderProfile: 'cif',
|
|
||||||
previewSize: {
|
|
||||||
width: 352,
|
|
||||||
height: 288
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const PREF_AUTOFOCUSCALLBACK_ENABLED = "camera.control.autofocus_moving_callback.enabled";
|
|
||||||
|
|
||||||
var cameraObj;
|
|
||||||
var oldPref;
|
|
||||||
|
|
||||||
// Shorthand functions
|
|
||||||
function end() {
|
|
||||||
function reallyEnd() {
|
|
||||||
CameraTest.end();
|
|
||||||
}
|
|
||||||
if (oldPref) {
|
|
||||||
SpecialPowers.pushPrefEnv(
|
|
||||||
{'set': [[PREF_AUTOFOCUSCALLBACK_ENABLED, oldPref]]}, reallyEnd);
|
|
||||||
} else {
|
|
||||||
SpecialPowers.pushPrefEnv(
|
|
||||||
{'clear': [[PREF_AUTOFOCUSCALLBACK_ENABLED]]}, reallyEnd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function next() {
|
|
||||||
CameraTest.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
var tests = [
|
|
||||||
{
|
|
||||||
key: "autofocus-moving-true",
|
|
||||||
func: function testAutoFocusMovingIsTrue(camera) {
|
|
||||||
camera.onAutoFocusMoving = function(aIsMoving) {
|
|
||||||
ok(aIsMoving == true,"onAutoFocusMoving callback received true correctly");
|
|
||||||
camera.focusMode = 'auto';
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
camera.focusMode = 'continuous-picture';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "autofocus-moving-false",
|
|
||||||
func: function testAutoFocusMovingIsFalse(camera) {
|
|
||||||
camera.onAutoFocusMoving = function(aIsMoving) {
|
|
||||||
ok(aIsMoving == false, "onAutoFocusMoving callback received false correctly");
|
|
||||||
camera.focusMode = 'auto';
|
|
||||||
end();
|
|
||||||
}
|
|
||||||
camera.focusMode = 'continuous-video';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
var testGenerator = function() {
|
|
||||||
for (var i = 0; i < tests.length; ++i ) {
|
|
||||||
yield tests[i];
|
|
||||||
}
|
|
||||||
}();
|
|
||||||
|
|
||||||
window.addEventListener('beforeunload', function() {
|
|
||||||
document.getElementById('viewfinder').mozSrcObject = null;
|
|
||||||
cameraObj.release();
|
|
||||||
cameraObj = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Must call CameraTest.begin() before any other async methods.
|
|
||||||
CameraTest.begin("hardware", function(test) {
|
|
||||||
// If the pref doesn't exist, this get will fail; catch it and continue.
|
|
||||||
try {
|
|
||||||
oldPref = SpecialPowers.getBoolPref(PREF_AUTOFOCUSCALLBACK_ENABLED);
|
|
||||||
} catch(e) { }
|
|
||||||
|
|
||||||
SpecialPowers.pushPrefEnv({'set': [[PREF_AUTOFOCUSCALLBACK_ENABLED, true]]}, function() {
|
|
||||||
var enabled;
|
|
||||||
try {
|
|
||||||
enabled = SpecialPowers.getBoolPref(PREF_AUTOFOCUSCALLBACK_ENABLED);
|
|
||||||
} catch(e) { }
|
|
||||||
ok(enabled, PREF_AUTOFOCUSCALLBACK_ENABLED + " is " + enabled);
|
|
||||||
|
|
||||||
function onSuccess(camera, config) {
|
|
||||||
document.getElementById('viewfinder').mozSrcObject = camera;
|
|
||||||
cameraObj = camera;
|
|
||||||
CameraTest.next = function() {
|
|
||||||
try {
|
|
||||||
var t = testGenerator.next();
|
|
||||||
test.set(t.key, t.func.bind(undefined, camera));
|
|
||||||
} catch(e) {
|
|
||||||
if (e instanceof StopIteration) {
|
|
||||||
end();
|
|
||||||
} else {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
function onError(error) {
|
|
||||||
ok(false, "getCamera() failed with: " + error);
|
|
||||||
end();
|
|
||||||
}
|
|
||||||
navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError);
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,320 +0,0 @@
|
|||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<!--
|
|
||||||
https://bugzilla.mozilla.org/show_bug.cgi?id=965420
|
|
||||||
-->
|
|
||||||
<head>
|
|
||||||
<title>Bug 965420 - Test camera hardware API for face detection</title>
|
|
||||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
|
||||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<script type="text/javascript" src="../camera_common.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=965420">Mozilla Bug 965420</a>
|
|
||||||
<video id="viewfinder" width = "200" height = "200" autoplay></video>
|
|
||||||
<img src="#" alt="This image is going to load" id="testimage"/>
|
|
||||||
|
|
||||||
<script class="testbody" type="text/javascript;version=1.7">
|
|
||||||
|
|
||||||
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
|
|
||||||
var initialConfig = {
|
|
||||||
mode: 'picture',
|
|
||||||
recorderProfile: 'cif',
|
|
||||||
previewSize: {
|
|
||||||
width: 352,
|
|
||||||
height: 288
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const PREF_FACEDETECTION_ENABLED = "camera.control.face_detection.enabled";
|
|
||||||
|
|
||||||
var cameraObj;
|
|
||||||
var oldPref;
|
|
||||||
|
|
||||||
// Shorthand functions
|
|
||||||
function end() {
|
|
||||||
function reallyEnd() {
|
|
||||||
CameraTest.end();
|
|
||||||
}
|
|
||||||
if (oldPref) {
|
|
||||||
SpecialPowers.pushPrefEnv(
|
|
||||||
{'set': [[PREF_FACEDETECTION_ENABLED, oldPref]]}, reallyEnd);
|
|
||||||
} else {
|
|
||||||
SpecialPowers.pushPrefEnv(
|
|
||||||
{'clear': [[PREF_FACEDETECTION_ENABLED]]}, reallyEnd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function next() {
|
|
||||||
CameraTest.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
function compareFaces(aFaces, expected)
|
|
||||||
{
|
|
||||||
ok(aFaces, "have detected faces object");
|
|
||||||
ok(aFaces.length == expected.faces.length,
|
|
||||||
"expected=" + expected.faces.length + ", got=" + aFaces.length);
|
|
||||||
aFaces.forEach(function (face, index) {
|
|
||||||
let result = compareFace(face, expected.faces[index]);
|
|
||||||
ok(result === "ok", "face check: " + result);
|
|
||||||
if (result !== "ok") {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function compareFace(aFace, expected)
|
|
||||||
{
|
|
||||||
if (aFace.id != expected.id) {
|
|
||||||
return "expected face.id=" + expected.id + ", got=" + aFace.id;
|
|
||||||
}
|
|
||||||
if (aFace.score != expected.score) {
|
|
||||||
return "expected face.score=" + expected.score + ", got=" + aFace.score;
|
|
||||||
}
|
|
||||||
if (!aFace.bounds) {
|
|
||||||
return "face.bounds is missing";
|
|
||||||
}
|
|
||||||
if (aFace.bounds.left != expected.bounds.left ||
|
|
||||||
aFace.bounds.top != expected.bounds.top ||
|
|
||||||
aFace.bounds.right != expected.bounds.right ||
|
|
||||||
aFace.bounds.bottom != expected.bounds.bottom) {
|
|
||||||
return "expected face.bounds=" + expected.bounds.toSource() +
|
|
||||||
", got=({left:" + aFace.bounds.left + ", top:" + aFace.bounds.top + ", right:" + aFace.bounds.right + ", bottom:" + aFace.bounds.bottom + "})";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aFace.leftEye && !expected.leftEye) {
|
|
||||||
return "expected null face.leftEye, got=({x:" + aFace.leftEye.x + ", y:" + aFace.leftEye.y + "})";
|
|
||||||
}
|
|
||||||
if (!aFace.leftEye && expected.leftEye) {
|
|
||||||
return "expected face.leftEye=" + expected.leftEye.toSource() + ", got null leftEye";
|
|
||||||
}
|
|
||||||
if (aFace.leftEye && expected.leftEye &&
|
|
||||||
(aFace.leftEye.x != expected.leftEye.x || aFace.leftEye.y != expected.leftEye.y)) {
|
|
||||||
return "expected face.leftEye=" + expected.leftEye.toSource() +
|
|
||||||
", got=({x:" + aFace.leftEye.x + ", y:" + aFace.leftEye.y + "})";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aFace.rightEye && !expected.rightEye) {
|
|
||||||
return "expected null face.rightEye, got=({x:" + aFace.rightEye.x + ", y:" + aFace.rightEye.y + "})";
|
|
||||||
}
|
|
||||||
if (!aFace.rightEye && expected.rightEye) {
|
|
||||||
return "expected face.rightEye=" + expected.rightEye.toSource() + ", got null rightEye";
|
|
||||||
}
|
|
||||||
if (aFace.rightEye && expected.rightEye &&
|
|
||||||
(aFace.rightEye.x != expected.rightEye.x || aFace.rightEye.y != expected.rightEye.y)) {
|
|
||||||
return "expected face.rightEye=" + expected.rightEye.toSource() +
|
|
||||||
", got=({x:" + aFace.rightEye.x + ", y:" + aFace.rightEye.y + "})";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aFace.mouth && !expected.mouth) {
|
|
||||||
return "expected null face.mouth, got=({x:" + aFace.mouth.x + ", y:" + aFace.mouth.y + "})";
|
|
||||||
}
|
|
||||||
if (!aFace.mouth && expected.mouth) {
|
|
||||||
return "expected face.mouth=" + expected.mouth.toSource() + ", got null mouth";
|
|
||||||
}
|
|
||||||
if (aFace.mouth && expected.mouth &&
|
|
||||||
(aFace.mouth.x != expected.mouth.x || aFace.mouth.y != expected.mouth.y)) {
|
|
||||||
return "expected face.mouth=" + expected.mouth.toSource() +
|
|
||||||
", got=({x:" + aFace.mouth.x + ", y:" + aFace.mouth.y + "})";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "ok";
|
|
||||||
}
|
|
||||||
|
|
||||||
var tests = [
|
|
||||||
{
|
|
||||||
key: "face-detection-detected-one-face",
|
|
||||||
func: function testFaceDetectionFoundOneFace(camera) {
|
|
||||||
var expected = {
|
|
||||||
faces: [ {
|
|
||||||
id: 1,
|
|
||||||
score: 2,
|
|
||||||
bounds: {
|
|
||||||
left: 3,
|
|
||||||
top: 4,
|
|
||||||
right: 5,
|
|
||||||
bottom: 6
|
|
||||||
},
|
|
||||||
leftEye: {
|
|
||||||
x: 7,
|
|
||||||
y: 8
|
|
||||||
},
|
|
||||||
rightEye: {
|
|
||||||
x: 9,
|
|
||||||
y: 10
|
|
||||||
},
|
|
||||||
mouth: {
|
|
||||||
x: 11,
|
|
||||||
y: 12
|
|
||||||
}
|
|
||||||
} ]
|
|
||||||
};
|
|
||||||
camera.onFacesDetected = function(aFaces) {
|
|
||||||
ok(compareFaces(aFaces, expected),
|
|
||||||
"onFaceDetected received the detected faces correctly");
|
|
||||||
camera.stopFaceDetection();
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
camera.startFaceDetection();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "face-detection-detected-two-faces",
|
|
||||||
func: function testFaceDetectionFoundTwoFace(camera) {
|
|
||||||
var expected = {
|
|
||||||
faces: [ {
|
|
||||||
id: 1,
|
|
||||||
score: 2,
|
|
||||||
bounds: {
|
|
||||||
left: 3,
|
|
||||||
top: 4,
|
|
||||||
right: 5,
|
|
||||||
bottom: 6
|
|
||||||
},
|
|
||||||
leftEye: {
|
|
||||||
x: 7,
|
|
||||||
y: 8
|
|
||||||
},
|
|
||||||
rightEye: {
|
|
||||||
x: 9,
|
|
||||||
y: 10
|
|
||||||
},
|
|
||||||
mouth: {
|
|
||||||
x: 11,
|
|
||||||
y: 12
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 13,
|
|
||||||
score: 14,
|
|
||||||
bounds: {
|
|
||||||
left: 15,
|
|
||||||
top: 16,
|
|
||||||
right: 17,
|
|
||||||
bottom: 18
|
|
||||||
},
|
|
||||||
leftEye: {
|
|
||||||
x: 19,
|
|
||||||
y: 20
|
|
||||||
},
|
|
||||||
rightEye: {
|
|
||||||
x: 21,
|
|
||||||
y: 22
|
|
||||||
},
|
|
||||||
mouth: {
|
|
||||||
x: 23,
|
|
||||||
y: 24
|
|
||||||
}
|
|
||||||
} ]
|
|
||||||
};
|
|
||||||
camera.onFacesDetected = function(aFaces) {
|
|
||||||
ok(compareFaces(aFaces, expected),
|
|
||||||
"onFaceDetected received the detected faces correctly");
|
|
||||||
camera.stopFaceDetection();
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
camera.startFaceDetection();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "face-detection-detected-one-face-no-features",
|
|
||||||
func: function (camera) {
|
|
||||||
var expected = {
|
|
||||||
faces: [ {
|
|
||||||
id: 1,
|
|
||||||
score: 100,
|
|
||||||
bounds: {
|
|
||||||
left: 3,
|
|
||||||
top: 4,
|
|
||||||
right: 5,
|
|
||||||
bottom: 6
|
|
||||||
},
|
|
||||||
leftEye: null,
|
|
||||||
rightEye: null,
|
|
||||||
mouth: null
|
|
||||||
} ]
|
|
||||||
};
|
|
||||||
camera.onFacesDetected = function(aFaces) {
|
|
||||||
ok(compareFaces(aFaces, expected),
|
|
||||||
"onFaceDetected received the detected faces correctly");
|
|
||||||
camera.stopFaceDetection();
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
camera.startFaceDetection();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "face-detection-no-faces-detected",
|
|
||||||
func: function (camera) {
|
|
||||||
var expected = {
|
|
||||||
faces: []
|
|
||||||
};
|
|
||||||
camera.onFacesDetected = function(aFaces) {
|
|
||||||
ok(compareFaces(aFaces, expected),
|
|
||||||
"onFaceDetected received the detected faces correctly");
|
|
||||||
camera.stopFaceDetection();
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
camera.startFaceDetection();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
var testGenerator = function() {
|
|
||||||
for (var i = 0; i < tests.length; ++i ) {
|
|
||||||
yield tests[i];
|
|
||||||
}
|
|
||||||
}();
|
|
||||||
|
|
||||||
window.addEventListener('beforeunload', function() {
|
|
||||||
document.getElementById('viewfinder').mozSrcObject = null;
|
|
||||||
if (cameraObj) {
|
|
||||||
cameraObj.release();
|
|
||||||
cameraObj = null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Must call CameraTest.begin() before any other async methods.
|
|
||||||
CameraTest.begin("hardware", function(test) {
|
|
||||||
// If the pref doesn't exist, this get will fail; catch it and continue.
|
|
||||||
try {
|
|
||||||
oldPref = SpecialPowers.getBoolPref(PREF_FACEDETECTION_ENABLED);
|
|
||||||
} catch(e) { }
|
|
||||||
|
|
||||||
SpecialPowers.pushPrefEnv({'set': [[PREF_FACEDETECTION_ENABLED, true]]}, function() {
|
|
||||||
var enabled;
|
|
||||||
try {
|
|
||||||
enabled = SpecialPowers.getBoolPref(PREF_FACEDETECTION_ENABLED);
|
|
||||||
} catch(e) { }
|
|
||||||
ok(enabled, PREF_FACEDETECTION_ENABLED + " is " + enabled);
|
|
||||||
|
|
||||||
function onSuccess(camera, config) {
|
|
||||||
document.getElementById('viewfinder').mozSrcObject = camera;
|
|
||||||
cameraObj = camera;
|
|
||||||
CameraTest.next = function() {
|
|
||||||
try {
|
|
||||||
var t = testGenerator.next();
|
|
||||||
test.set(t.key, t.func.bind(undefined, camera));
|
|
||||||
} catch(e) {
|
|
||||||
if (e instanceof StopIteration) {
|
|
||||||
end();
|
|
||||||
} else {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
function onError(error) {
|
|
||||||
ok(false, "getCamera() failed with: " + error);
|
|
||||||
end();
|
|
||||||
}
|
|
||||||
navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError);
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,145 +0,0 @@
|
|||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<!--
|
|
||||||
https://bugzilla.mozilla.org/show_bug.cgi?id=940424
|
|
||||||
-->
|
|
||||||
<head>
|
|
||||||
<title>Bug 940424 - Test camera hardware API failure handling</title>
|
|
||||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
|
||||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<script type="text/javascript" src="../camera_common.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=940424">Mozilla Bug 940424</a>
|
|
||||||
<video id="viewfinder" width = "200" height = "200" autoplay></video>
|
|
||||||
<img src="#" alt="This image is going to load" id="testimage"/>
|
|
||||||
|
|
||||||
<script class="testbody" type="text/javascript;version=1.7">
|
|
||||||
|
|
||||||
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
|
|
||||||
var initialConfig = {
|
|
||||||
mode: 'picture',
|
|
||||||
recorderProfile: 'cif',
|
|
||||||
previewSize: {
|
|
||||||
width: 352,
|
|
||||||
height: 288
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var cameraObj;
|
|
||||||
|
|
||||||
// Shorthand functions
|
|
||||||
function end() {
|
|
||||||
CameraTest.end();
|
|
||||||
}
|
|
||||||
function next() {
|
|
||||||
CameraTest.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
// The array of tests
|
|
||||||
var tests = [
|
|
||||||
{
|
|
||||||
key: "auto-focus-failure",
|
|
||||||
func: function testAutoFocusApiFailure(camera) {
|
|
||||||
function onSuccess(success) {
|
|
||||||
ok(false, "autoFocus() succeeded incorrectly");
|
|
||||||
end();
|
|
||||||
}
|
|
||||||
function onError(error) {
|
|
||||||
ok(true, "autoFocus() failed correctly with: " + error);
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
camera.autoFocus(onSuccess, onError);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "auto-focus-process-failure",
|
|
||||||
func: function testAutoFocusProcessFailure(camera) {
|
|
||||||
function onSuccess(success) {
|
|
||||||
if (success) {
|
|
||||||
ok(false, "autoFocus() process succeeded incorrectly");
|
|
||||||
end();
|
|
||||||
} else {
|
|
||||||
ok(true, "autoFocus() process failed correctly");
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function onError(error) {
|
|
||||||
ok(false, "autoFocus() process failed incorrectly with: " + error);
|
|
||||||
end();
|
|
||||||
}
|
|
||||||
camera.autoFocus(onSuccess, onError);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "take-picture-failure",
|
|
||||||
func: function testTakePictureApiFailure(camera) {
|
|
||||||
function onSuccess(picture) {
|
|
||||||
ok(false, "takePicture() succeeded incorrectly");
|
|
||||||
end();
|
|
||||||
}
|
|
||||||
function onError(error) {
|
|
||||||
ok(true, "takePicture() failed correctly with: " + error);
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
camera.takePicture(null, onSuccess, onError);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "take-picture-process-failure",
|
|
||||||
func: function testTakePictureProcessFailure(camera) {
|
|
||||||
function onSuccess(picture) {
|
|
||||||
ok(false, "takePicture() process succeeded incorrectly");
|
|
||||||
end();
|
|
||||||
}
|
|
||||||
function onError(error) {
|
|
||||||
ok(true, "takePicture() process failed correctly with: " + error);
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
camera.takePicture(null, onSuccess, onError);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
var testGenerator = function() {
|
|
||||||
for (var i = 0; i < tests.length; ++i ) {
|
|
||||||
yield tests[i];
|
|
||||||
}
|
|
||||||
}();
|
|
||||||
|
|
||||||
window.addEventListener('beforeunload', function() {
|
|
||||||
document.getElementById('viewfinder').mozSrcObject = null;
|
|
||||||
cameraObj.release();
|
|
||||||
cameraObj = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
CameraTest.begin("hardware", function(test) {
|
|
||||||
function onSuccess(camera, config) {
|
|
||||||
document.getElementById('viewfinder').mozSrcObject = camera;
|
|
||||||
cameraObj = camera;
|
|
||||||
CameraTest.next = function() {
|
|
||||||
try {
|
|
||||||
var t = testGenerator.next();
|
|
||||||
test.set(t.key, t.func.bind(undefined, camera));
|
|
||||||
} catch(e) {
|
|
||||||
if (e instanceof StopIteration) {
|
|
||||||
end();
|
|
||||||
} else {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
function onError(error) {
|
|
||||||
ok(false, "getCamera() failed with: " + error);
|
|
||||||
end();
|
|
||||||
}
|
|
||||||
navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError);
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,149 +0,0 @@
|
|||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<!--
|
|
||||||
https://bugzilla.mozilla.org/show_bug.cgi?id=940424
|
|
||||||
-->
|
|
||||||
<head>
|
|
||||||
<title>Bug 940424 - Test camera hardware init failure handling</title>
|
|
||||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
|
||||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<script type="text/javascript" src="../camera_common.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=940424">Mozilla Bug 940424</a>
|
|
||||||
<video id="viewfinder" width="200" height="200" autoplay></video>
|
|
||||||
<img src="#" alt="This image is going to load" id="testimage"/>
|
|
||||||
|
|
||||||
<script class="testbody" type="text/javascript;version=1.7">
|
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
|
|
||||||
var whichCamera = navigator.mozCameras.getListOfCameras()[0];
|
|
||||||
var initialConfig = {
|
|
||||||
mode: 'picture',
|
|
||||||
recorderProfile: 'cif',
|
|
||||||
previewSize: {
|
|
||||||
width: 352,
|
|
||||||
height: 288
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var tests = [
|
|
||||||
{
|
|
||||||
name: "init-failure",
|
|
||||||
key: "init-failure",
|
|
||||||
func: function testInitFailure(test) {
|
|
||||||
function onSuccess(camera, config) {
|
|
||||||
ok(false, "onSuccess called incorrectly");
|
|
||||||
camera.release();
|
|
||||||
test.next();
|
|
||||||
}
|
|
||||||
function onError(error) {
|
|
||||||
ok(true, "onError called correctly on init failure");
|
|
||||||
test.next();
|
|
||||||
}
|
|
||||||
info("Running test: init-failure");
|
|
||||||
navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/* This test case (init-success) *must* follow the preceeding test case
|
|
||||||
(init-failure) in order for the desired condition to be verified */
|
|
||||||
{
|
|
||||||
name: "init-success",
|
|
||||||
key: "",
|
|
||||||
func: function(test) {
|
|
||||||
function onSuccess(camera, config) {
|
|
||||||
ok(true, "onSuccess called correctly");
|
|
||||||
camera.release();
|
|
||||||
test.next();
|
|
||||||
}
|
|
||||||
function onError(error) {
|
|
||||||
ok(false, "onError called incorrectly: " + error);
|
|
||||||
test.next();
|
|
||||||
}
|
|
||||||
info("Running test: init-success");
|
|
||||||
navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/* Test for bug 1099390 to make sure events related to the underlying
|
|
||||||
platform failing are generated and handled properly. */
|
|
||||||
{
|
|
||||||
name: "post-init-system-failure",
|
|
||||||
key: "post-init-system-failure",
|
|
||||||
func: function(test) {
|
|
||||||
var gotReleaseCallback = false;
|
|
||||||
var gotCloseCallback = false;
|
|
||||||
|
|
||||||
function gotAll() {
|
|
||||||
var all = gotReleaseCallback && gotCloseCallback;
|
|
||||||
if (all) {
|
|
||||||
info("Got all expected notifications");
|
|
||||||
}
|
|
||||||
return all;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onSuccess(camera, config) {
|
|
||||||
camera.onClosed = function(reason) {
|
|
||||||
camera.onClosed = null;
|
|
||||||
ok(reason === "SystemFailure", "reason is: " + reason);
|
|
||||||
ok(!gotCloseCallback, "gotCloseCallback was " + gotCloseCallback);
|
|
||||||
gotCloseCallback = true;
|
|
||||||
if (gotAll()) {
|
|
||||||
test.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
camera.release(
|
|
||||||
function success() {
|
|
||||||
ok(true, "Got release() success callback");
|
|
||||||
ok(!gotReleaseCallback, "gotReleaseCallback was " + gotReleaseCallback);
|
|
||||||
gotReleaseCallback = true;
|
|
||||||
if (gotAll()) {
|
|
||||||
test.next();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
function error(e) {
|
|
||||||
ok(false, "Unexpected release() onError callback: " + e);
|
|
||||||
test.next();
|
|
||||||
}
|
|
||||||
); // release()
|
|
||||||
} // onClosed
|
|
||||||
} // onSuccess
|
|
||||||
|
|
||||||
function onError(error) {
|
|
||||||
ok(false, "onError called incorrectly: " + error);
|
|
||||||
test.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
info("Running test: post-init-system-failure");
|
|
||||||
navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
var testGenerator = function() {
|
|
||||||
for (var i = 0; i < tests.length; ++i) {
|
|
||||||
yield tests[i];
|
|
||||||
}
|
|
||||||
}();
|
|
||||||
|
|
||||||
CameraTest.begin("hardware", function(test) {
|
|
||||||
CameraTest.next = function() {
|
|
||||||
try {
|
|
||||||
var t = testGenerator.next();
|
|
||||||
test.set(t.key, t.func.bind(undefined, CameraTest));
|
|
||||||
} catch(e) {
|
|
||||||
if (e instanceof StopIteration) {
|
|
||||||
CameraTest.end();
|
|
||||||
} else {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
CameraTest.next();
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,16 +1,6 @@
|
|||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
support-files = camera_common.js
|
support-files = camera_common.js
|
||||||
|
|
||||||
[callback/test_camera.html]
|
|
||||||
[callback/test_camera_2.html]
|
|
||||||
[callback/test_camera_3.html]
|
|
||||||
[callback/test_camera_hardware_init_failure.html]
|
|
||||||
[callback/test_camera_hardware_failures.html]
|
|
||||||
[callback/test_bug975472.html]
|
|
||||||
[callback/test_camera_hardware_face_detection.html]
|
|
||||||
[callback/test_camera_hardware_auto_focus_moving_cb.html]
|
|
||||||
[callback/test_bug1022766.html]
|
|
||||||
[callback/test_bug1099390.html]
|
|
||||||
[test_camera.html]
|
[test_camera.html]
|
||||||
[test_camera_2.html]
|
[test_camera_2.html]
|
||||||
[test_camera_3.html]
|
[test_camera_3.html]
|
||||||
|
@ -38,7 +38,7 @@ var Camera = {
|
|||||||
callbackTriggered: false,
|
callbackTriggered: false,
|
||||||
checkForDone: function test_checkForDone() {
|
checkForDone: function test_checkForDone() {
|
||||||
if (Camera.firstCallFailed && Camera.secondCallSucceeded) {
|
if (Camera.firstCallFailed && Camera.secondCallSucceeded) {
|
||||||
ok(Camera.callbackTriggered, "Async callback triggered");
|
ok(Camera.callbackTriggered, "Async callback triggered?");
|
||||||
Camera.cameraObj.release();
|
Camera.cameraObj.release();
|
||||||
Camera.cameraObj = null;
|
Camera.cameraObj = null;
|
||||||
CameraTest.end();
|
CameraTest.end();
|
||||||
@ -50,7 +50,7 @@ var Camera = {
|
|||||||
},
|
},
|
||||||
failureOne: function test_failureOne(error) {
|
failureOne: function test_failureOne(error) {
|
||||||
ok(error.name == "NS_ERROR_IN_PROGRESS", "First call to autoFocus() failed with: "
|
ok(error.name == "NS_ERROR_IN_PROGRESS", "First call to autoFocus() failed with: "
|
||||||
+ error);
|
+ error.name);
|
||||||
Camera.firstCallFailed = true;
|
Camera.firstCallFailed = true;
|
||||||
Camera.checkForDone();
|
Camera.checkForDone();
|
||||||
},
|
},
|
||||||
@ -62,7 +62,8 @@ var Camera = {
|
|||||||
failureTwo: function test_failureTwo(error) {
|
failureTwo: function test_failureTwo(error) {
|
||||||
ok(false, "Second call to autoFocus() failed unexpectedly with: " + error);
|
ok(false, "Second call to autoFocus() failed unexpectedly with: " + error);
|
||||||
},
|
},
|
||||||
callback: function test_callback(focused) {
|
callback: function test_callback(e) {
|
||||||
|
Camera.cameraObj.removeEventListener('focus', Camera.callback);
|
||||||
Camera.callbackTriggered = true;
|
Camera.callbackTriggered = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -75,7 +76,7 @@ var Camera = {
|
|||||||
|
|
||||||
// It doesn't matter if the emulator supports focus or not;
|
// It doesn't matter if the emulator supports focus or not;
|
||||||
// this is just testing the sequencing.
|
// this is just testing the sequencing.
|
||||||
camera.onAutoFocusCompleted = Camera.callback;
|
camera.addEventListener('focus', Camera.callback);
|
||||||
camera.autoFocus().then(Camera.successOne, Camera.failureOne);
|
camera.autoFocus().then(Camera.successOne, Camera.failureOne);
|
||||||
camera.autoFocus().then(Camera.successTwo, Camera.failureTwo);
|
camera.autoFocus().then(Camera.successTwo, Camera.failureTwo);
|
||||||
};
|
};
|
||||||
|
@ -103,7 +103,7 @@ var Camera = {
|
|||||||
},
|
},
|
||||||
takePictureSuccess: function taken_foto(blob) {
|
takePictureSuccess: function taken_foto(blob) {
|
||||||
ok(blob.size > 100 , "Blob Size Gathered = " + blob.size);
|
ok(blob.size > 100 , "Blob Size Gathered = " + blob.size);
|
||||||
ok("image/" + test.fileFormat == blob.type, "Blob Type = " + blob.type);
|
ok("image/" + this._currentTest.fileFormat === blob.type, "Blob Type = " + blob.type);
|
||||||
},
|
},
|
||||||
takePictureEvent: function taken_foto_evt(e) {
|
takePictureEvent: function taken_foto_evt(e) {
|
||||||
var blob = e.data;
|
var blob = e.data;
|
||||||
|
@ -36,7 +36,7 @@ function end() {
|
|||||||
}
|
}
|
||||||
function next() {
|
function next() {
|
||||||
if (cameraObj) {
|
if (cameraObj) {
|
||||||
cameraObj.release(
|
cameraObj.release().then(
|
||||||
function success() {
|
function success() {
|
||||||
CameraTest.next();
|
CameraTest.next();
|
||||||
},
|
},
|
||||||
@ -345,7 +345,7 @@ var tests = [
|
|||||||
run();
|
run();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
test: function testFakeFocusAreas(cam, cap) {
|
test: function testFakePictureSizes(cam, cap) {
|
||||||
// validate the capability attribute
|
// validate the capability attribute
|
||||||
ok(cap.pictureSizes.length == 3, "pictureSizes.length = " + cap.pictureSizes.length);
|
ok(cap.pictureSizes.length == 3, "pictureSizes.length = " + cap.pictureSizes.length);
|
||||||
var found = 0;
|
var found = 0;
|
||||||
@ -368,7 +368,7 @@ var tests = [
|
|||||||
// settings are applied. Yes--this is an ugly hack.
|
// settings are applied. Yes--this is an ugly hack.
|
||||||
cam.setConfiguration({ mode: 'video',
|
cam.setConfiguration({ mode: 'video',
|
||||||
recorderProfile: 'weird-unsupported-profile'
|
recorderProfile: 'weird-unsupported-profile'
|
||||||
}, resolve, resolve);
|
}).then(resolve, resolve);
|
||||||
});
|
});
|
||||||
var sizeGenerator = function() {
|
var sizeGenerator = function() {
|
||||||
var sizes = [ { height: 3264, width: 1836 },
|
var sizes = [ { height: 3264, width: 1836 },
|
||||||
|
@ -49,7 +49,7 @@ public:
|
|||||||
// ChannelMediaResource, it has a "cache" that can store the whole streaming
|
// ChannelMediaResource, it has a "cache" that can store the whole streaming
|
||||||
// data so the |GetBuffered| function can retrieve useful time ranges.
|
// data so the |GetBuffered| function can retrieve useful time ranges.
|
||||||
virtual nsresult GetBuffered(dom::TimeRanges* aBuffered) MOZ_OVERRIDE {
|
virtual nsresult GetBuffered(dom::TimeRanges* aBuffered) MOZ_OVERRIDE {
|
||||||
return NS_OK;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void SetIdle() MOZ_OVERRIDE;
|
virtual void SetIdle() MOZ_OVERRIDE;
|
||||||
|
@ -59,7 +59,7 @@ public:
|
|||||||
// ChannelMediaResource, it has a "cache" that can store the whole streaming
|
// ChannelMediaResource, it has a "cache" that can store the whole streaming
|
||||||
// data so the |GetBuffered| function can retrieve useful time ranges.
|
// data so the |GetBuffered| function can retrieve useful time ranges.
|
||||||
virtual nsresult GetBuffered(mozilla::dom::TimeRanges* aBuffered) MOZ_FINAL MOZ_OVERRIDE {
|
virtual nsresult GetBuffered(mozilla::dom::TimeRanges* aBuffered) MOZ_FINAL MOZ_OVERRIDE {
|
||||||
return NS_OK;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void SetIdle() MOZ_OVERRIDE;
|
virtual void SetIdle() MOZ_OVERRIDE;
|
||||||
|
@ -2876,6 +2876,7 @@ this.MMI_KS_SC_PUK = "scPuk";
|
|||||||
this.MMI_KS_SC_PUK2 = "scPuk2";
|
this.MMI_KS_SC_PUK2 = "scPuk2";
|
||||||
this.MMI_KS_SC_IMEI = "scImei";
|
this.MMI_KS_SC_IMEI = "scImei";
|
||||||
this.MMI_KS_SC_USSD = "scUssd";
|
this.MMI_KS_SC_USSD = "scUssd";
|
||||||
|
this.MMI_KS_SC_CALL = "scCall";
|
||||||
|
|
||||||
// MMI error messages key strings.
|
// MMI error messages key strings.
|
||||||
this.MMI_ERROR_KS_ERROR = "emMmiError";
|
this.MMI_ERROR_KS_ERROR = "emMmiError";
|
||||||
@ -2905,6 +2906,7 @@ this.MMI_SM_KS_CLIR_DEFAULT_ON_NEXT_CALL_ON = "smClirDefaultOnNextCallOn";
|
|||||||
this.MMI_SM_KS_CLIR_DEFAULT_ON_NEXT_CALL_OFF = "smClirDefaultOnNextCallOff";
|
this.MMI_SM_KS_CLIR_DEFAULT_ON_NEXT_CALL_OFF = "smClirDefaultOnNextCallOff";
|
||||||
this.MMI_SM_KS_CLIR_DEFAULT_OFF_NEXT_CALL_ON = "smClirDefaultOffNextCallOn";
|
this.MMI_SM_KS_CLIR_DEFAULT_OFF_NEXT_CALL_ON = "smClirDefaultOffNextCallOn";
|
||||||
this.MMI_SM_KS_CLIR_DEFAULT_OFF_NEXT_CALL_OFF = "smClirDefaultOffNextCallOff";
|
this.MMI_SM_KS_CLIR_DEFAULT_OFF_NEXT_CALL_OFF = "smClirDefaultOffNextCallOff";
|
||||||
|
this.MMI_SM_KS_CALL_CONTROL = "smCallControl";
|
||||||
|
|
||||||
// MMI Service class
|
// MMI Service class
|
||||||
this.MMI_KS_SERVICE_CLASS_VOICE = "serviceClassVoice";
|
this.MMI_KS_SERVICE_CLASS_VOICE = "serviceClassVoice";
|
||||||
|
@ -222,10 +222,9 @@ const TELEPHONY_REQUESTS = [
|
|||||||
REQUEST_UDUB
|
REQUEST_UDUB
|
||||||
];
|
];
|
||||||
|
|
||||||
function TelephonyRequestEntry(request, action, options) {
|
function TelephonyRequestEntry(request, callback) {
|
||||||
this.request = request;
|
this.request = request;
|
||||||
this.action = action;
|
this.callback = callback;
|
||||||
this.options = options;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function TelephonyRequestQueue(ril) {
|
function TelephonyRequestQueue(ril) {
|
||||||
@ -274,7 +273,7 @@ TelephonyRequestQueue.prototype = {
|
|||||||
|
|
||||||
_executeEntry: function(entry) {
|
_executeEntry: function(entry) {
|
||||||
if (DEBUG) this.debug("execute " + this._getRequestName(entry.request));
|
if (DEBUG) this.debug("execute " + this._getRequestName(entry.request));
|
||||||
entry.action.call(this.ril, entry.options);
|
entry.callback();
|
||||||
},
|
},
|
||||||
|
|
||||||
_getRequestName: function(request) {
|
_getRequestName: function(request) {
|
||||||
@ -290,7 +289,7 @@ TelephonyRequestQueue.prototype = {
|
|||||||
return TELEPHONY_REQUESTS.indexOf(request) !== -1;
|
return TELEPHONY_REQUESTS.indexOf(request) !== -1;
|
||||||
},
|
},
|
||||||
|
|
||||||
push: function(request, action, options) {
|
push: function(request, callback) {
|
||||||
if (!this.isValidRequest(request)) {
|
if (!this.isValidRequest(request)) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
this.debug("Error: " + this._getRequestName(request) +
|
this.debug("Error: " + this._getRequestName(request) +
|
||||||
@ -300,7 +299,7 @@ TelephonyRequestQueue.prototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (DEBUG) this.debug("push " + this._getRequestName(request));
|
if (DEBUG) this.debug("push " + this._getRequestName(request));
|
||||||
let entry = new TelephonyRequestEntry(request, action, options);
|
let entry = new TelephonyRequestEntry(request, callback);
|
||||||
let queue = this._getQueue(request);
|
let queue = this._getQueue(request);
|
||||||
queue.push(entry);
|
queue.push(entry);
|
||||||
|
|
||||||
@ -1545,18 +1544,6 @@ RilObject.prototype = {
|
|||||||
Buf.sendParcel();
|
Buf.sendParcel();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Get current calls.
|
|
||||||
*/
|
|
||||||
getCurrentCalls: function() {
|
|
||||||
this.telephonyRequestQueue.push(REQUEST_GET_CURRENT_CALLS,
|
|
||||||
this.sendRilRequestGetCurrentCalls, null);
|
|
||||||
},
|
|
||||||
|
|
||||||
sendRilRequestGetCurrentCalls: function() {
|
|
||||||
this.context.Buf.simpleRequest(REQUEST_GET_CURRENT_CALLS);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the signal strength.
|
* Get the signal strength.
|
||||||
*/
|
*/
|
||||||
@ -1631,20 +1618,24 @@ RilObject.prototype = {
|
|||||||
let isRadioOff = (this.radioState === GECKO_RADIOSTATE_DISABLED);
|
let isRadioOff = (this.radioState === GECKO_RADIOSTATE_DISABLED);
|
||||||
|
|
||||||
if (options.isEmergency) {
|
if (options.isEmergency) {
|
||||||
|
options.request = RILQUIRKS_REQUEST_USE_DIAL_EMERGENCY_CALL ?
|
||||||
|
REQUEST_DIAL_EMERGENCY_CALL : REQUEST_DIAL;
|
||||||
|
|
||||||
if (isRadioOff) {
|
if (isRadioOff) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
this.context.debug("Automatically enable radio for an emergency call.");
|
this.context.debug("Automatically enable radio for an emergency call.");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.cachedDialRequest = {
|
this.cachedDialRequest = {
|
||||||
callback: this.dialEmergencyNumber.bind(this, options),
|
callback: this.dialInternal.bind(this, options),
|
||||||
onerror: onerror
|
onerror: onerror
|
||||||
};
|
};
|
||||||
|
|
||||||
this.setRadioEnabled({enabled: true});
|
this.setRadioEnabled({enabled: true});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.dialEmergencyNumber(options);
|
this.dialInternal(options);
|
||||||
} else {
|
} else {
|
||||||
// Notify error in establishing the call without radio.
|
// Notify error in establishing the call without radio.
|
||||||
if (isRadioOff) {
|
if (isRadioOff) {
|
||||||
@ -1658,70 +1649,39 @@ RilObject.prototype = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.dialNonEmergencyNumber(options);
|
// Exit emergency callback mode when user dial a non-emergency call.
|
||||||
|
if (this._isInEmergencyCbMode) {
|
||||||
|
this.exitEmergencyCbMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
options.request = REQUEST_DIAL;
|
||||||
|
|
||||||
|
this.dialInternal(options);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
dialInternal: function(options) {
|
||||||
* Dial a non-emergency number.
|
// Make a Cdma 3way call.
|
||||||
*
|
|
||||||
* @param number
|
|
||||||
* String containing the number to dial.
|
|
||||||
* @param clirMode
|
|
||||||
* Integer for showing/hidding the caller Id to the called party.
|
|
||||||
* @param uusInfo
|
|
||||||
* Integer doing something XXX TODO
|
|
||||||
*/
|
|
||||||
dialNonEmergencyNumber: function(options) {
|
|
||||||
// Exit emergency callback mode when user dial a non-emergency call.
|
|
||||||
if (this._isInEmergencyCbMode) {
|
|
||||||
this.exitEmergencyCbMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
options.request = REQUEST_DIAL;
|
|
||||||
this.sendDialRequest(options);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dial an emergency number.
|
|
||||||
*
|
|
||||||
* @param number
|
|
||||||
* String containing the number to dial.
|
|
||||||
* @param clirMode
|
|
||||||
* Integer for showing/hidding the caller Id to the called party.
|
|
||||||
* @param uusInfo
|
|
||||||
* Integer doing something XXX TODO
|
|
||||||
*/
|
|
||||||
dialEmergencyNumber: function(options) {
|
|
||||||
options.request = RILQUIRKS_REQUEST_USE_DIAL_EMERGENCY_CALL ?
|
|
||||||
REQUEST_DIAL_EMERGENCY_CALL : REQUEST_DIAL;
|
|
||||||
this.sendDialRequest(options);
|
|
||||||
},
|
|
||||||
|
|
||||||
sendDialRequest: function(options) {
|
|
||||||
if (this._isCdma && Object.keys(this.currentCalls).length == 1) {
|
if (this._isCdma && Object.keys(this.currentCalls).length == 1) {
|
||||||
// Make a Cdma 3way call.
|
|
||||||
options.featureStr = options.number;
|
options.featureStr = options.number;
|
||||||
this.sendCdmaFlashCommand(options);
|
this.cdmaFlash(options);
|
||||||
} else {
|
return;
|
||||||
this.telephonyRequestQueue.push(options.request, this.sendRilRequestDial,
|
|
||||||
options);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.telephonyRequestQueue.push(options.request, () => {
|
||||||
|
let Buf = this.context.Buf;
|
||||||
|
Buf.newParcel(options.request, options);
|
||||||
|
Buf.writeString(options.number);
|
||||||
|
Buf.writeInt32(options.clirMode || 0);
|
||||||
|
Buf.writeInt32(options.uusInfo || 0);
|
||||||
|
// TODO Why do we need this extra 0? It was put it in to make this
|
||||||
|
// match the format of the binary message.
|
||||||
|
Buf.writeInt32(0);
|
||||||
|
Buf.sendParcel();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
sendRilRequestDial: function(options) {
|
cdmaFlash: function(options) {
|
||||||
let Buf = this.context.Buf;
|
|
||||||
Buf.newParcel(options.request, options);
|
|
||||||
Buf.writeString(options.number);
|
|
||||||
Buf.writeInt32(options.clirMode || 0);
|
|
||||||
Buf.writeInt32(options.uusInfo || 0);
|
|
||||||
// TODO Why do we need this extra 0? It was put it in to make this
|
|
||||||
// match the format of the binary message.
|
|
||||||
Buf.writeInt32(0);
|
|
||||||
Buf.sendParcel();
|
|
||||||
},
|
|
||||||
|
|
||||||
sendCdmaFlashCommand: function(options) {
|
|
||||||
let Buf = this.context.Buf;
|
let Buf = this.context.Buf;
|
||||||
options.isCdma = true;
|
options.isCdma = true;
|
||||||
options.request = REQUEST_CDMA_FLASH;
|
options.request = REQUEST_CDMA_FLASH;
|
||||||
@ -1753,58 +1713,43 @@ RilObject.prototype = {
|
|||||||
|
|
||||||
call.hangUpLocal = true;
|
call.hangUpLocal = true;
|
||||||
if (call.state === CALL_STATE_HOLDING) {
|
if (call.state === CALL_STATE_HOLDING) {
|
||||||
this.sendHangUpBackgroundRequest();
|
this.hangUpBackground(options);
|
||||||
} else {
|
} else {
|
||||||
this.sendHangUpRequest(options);
|
this.telephonyRequestQueue.push(REQUEST_HANGUP, () => {
|
||||||
|
let Buf = this.context.Buf;
|
||||||
|
Buf.newParcel(REQUEST_HANGUP, options);
|
||||||
|
Buf.writeInt32(1);
|
||||||
|
Buf.writeInt32(options.callIndex);
|
||||||
|
Buf.sendParcel();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
sendHangUpRequest: function(options) {
|
hangUpForeground: function(options) {
|
||||||
this.telephonyRequestQueue.push(REQUEST_HANGUP, this.sendRilRequestHangUp,
|
this.telephonyRequestQueue.push(REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND, () => {
|
||||||
options);
|
this.context.Buf.simpleRequest(REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND,
|
||||||
|
options);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
sendRilRequestHangUp: function(options) {
|
hangUpBackground: function(options) {
|
||||||
let Buf = this.context.Buf;
|
this.telephonyRequestQueue.push(REQUEST_HANGUP_WAITING_OR_BACKGROUND, () => {
|
||||||
Buf.newParcel(REQUEST_HANGUP, options);
|
this.context.Buf.simpleRequest(REQUEST_HANGUP_WAITING_OR_BACKGROUND,
|
||||||
Buf.writeInt32(1);
|
options);
|
||||||
Buf.writeInt32(options.callIndex);
|
});
|
||||||
Buf.sendParcel();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
sendHangUpForegroundRequest: function(options) {
|
switchActiveCall: function(options) {
|
||||||
this.telephonyRequestQueue.push(REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND,
|
this.telephonyRequestQueue.push(REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE, () => {
|
||||||
this.sendRilRequestHangUpForeground,
|
this.context.Buf.simpleRequest(REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE,
|
||||||
options);
|
options);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
sendRilRequestHangUpForeground: function(options) {
|
udub: function(options) {
|
||||||
this.context.Buf.simpleRequest(REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND,
|
this.telephonyRequestQueue.push(REQUEST_UDUB, () => {
|
||||||
options);
|
this.context.Buf.simpleRequest(REQUEST_UDUB, options);
|
||||||
},
|
});
|
||||||
|
|
||||||
sendHangUpBackgroundRequest: function(options) {
|
|
||||||
this.telephonyRequestQueue.push(REQUEST_HANGUP_WAITING_OR_BACKGROUND,
|
|
||||||
this.sendRilRequestHangUpWaiting, options);
|
|
||||||
},
|
|
||||||
|
|
||||||
sendRilRequestHangUpWaiting: function(options) {
|
|
||||||
this.context.Buf.simpleRequest(REQUEST_HANGUP_WAITING_OR_BACKGROUND,
|
|
||||||
options);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mute or unmute the radio.
|
|
||||||
*
|
|
||||||
* @param mute
|
|
||||||
* Boolean to indicate whether to mute or unmute the radio.
|
|
||||||
*/
|
|
||||||
setMute: function(options) {
|
|
||||||
let Buf = this.context.Buf;
|
|
||||||
Buf.newParcel(REQUEST_SET_MUTE);
|
|
||||||
Buf.writeInt32(1);
|
|
||||||
Buf.writeInt32(options.muted ? 1 : 0);
|
|
||||||
Buf.sendParcel();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1814,40 +1759,28 @@ RilObject.prototype = {
|
|||||||
* Call index of the call to answer.
|
* Call index of the call to answer.
|
||||||
*/
|
*/
|
||||||
answerCall: function(options) {
|
answerCall: function(options) {
|
||||||
// Check for races. Since we dispatched the incoming/waiting call
|
|
||||||
// notification the incoming/waiting call may have changed. The main
|
|
||||||
// thread thinks that it is answering the call with the given index,
|
|
||||||
// so only answer if that is still incoming/waiting.
|
|
||||||
let call = this.currentCalls[options.callIndex];
|
let call = this.currentCalls[options.callIndex];
|
||||||
if (!call) {
|
if (!call) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for races. Since we dispatched the incoming/waiting call
|
||||||
|
// notification the incoming/waiting call may have changed. The main
|
||||||
|
// thread thinks that it is answering the call with the given index,
|
||||||
|
// so only answer if that is still incoming/waiting.
|
||||||
switch (call.state) {
|
switch (call.state) {
|
||||||
case CALL_STATE_INCOMING:
|
case CALL_STATE_INCOMING:
|
||||||
this.telephonyRequestQueue.push(REQUEST_ANSWER, this.sendRilRequestAnswer,
|
this.telephonyRequestQueue.push(REQUEST_ANSWER, () => {
|
||||||
null);
|
this.context.Buf.simpleRequest(REQUEST_ANSWER);
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
case CALL_STATE_WAITING:
|
case CALL_STATE_WAITING:
|
||||||
// Answer the waiting (second) call, and hold the first call.
|
// Answer the waiting (second) call, and hold the first call.
|
||||||
this.sendSwitchWaitingRequest();
|
this.switchActiveCall(options);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
sendRilRequestAnswer: function() {
|
|
||||||
this.context.Buf.simpleRequest(REQUEST_ANSWER);
|
|
||||||
},
|
|
||||||
|
|
||||||
sendSwitchWaitingRequest: function() {
|
|
||||||
this.telephonyRequestQueue.push(REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE,
|
|
||||||
this.sendRilRequestSwitch, null);
|
|
||||||
},
|
|
||||||
|
|
||||||
sendRilRequestSwitch: function() {
|
|
||||||
this.context.Buf.simpleRequest(REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reject an incoming/waiting call.
|
* Reject an incoming/waiting call.
|
||||||
*
|
*
|
||||||
@ -1868,26 +1801,21 @@ RilObject.prototype = {
|
|||||||
|
|
||||||
if (this._isCdma) {
|
if (this._isCdma) {
|
||||||
// AT+CHLD=0 means "release held or UDUB."
|
// AT+CHLD=0 means "release held or UDUB."
|
||||||
this.sendHangUpBackgroundRequest();
|
this.hangUpBackground(options);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (call.state) {
|
switch (call.state) {
|
||||||
case CALL_STATE_INCOMING:
|
case CALL_STATE_INCOMING:
|
||||||
this.telephonyRequestQueue.push(REQUEST_UDUB, this.sendRilRequestUdub,
|
this.udub(options);
|
||||||
null);
|
|
||||||
break;
|
break;
|
||||||
case CALL_STATE_WAITING:
|
case CALL_STATE_WAITING:
|
||||||
// Reject the waiting (second) call, and remain the first call.
|
// Reject the waiting (second) call, and remain the first call.
|
||||||
this.sendHangUpBackgroundRequest();
|
this.hangUpBackground(options);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
sendRilRequestUdub: function() {
|
|
||||||
this.context.Buf.simpleRequest(REQUEST_UDUB);
|
|
||||||
},
|
|
||||||
|
|
||||||
holdCall: function(options) {
|
holdCall: function(options) {
|
||||||
let call = this.currentCalls[options.callIndex];
|
let call = this.currentCalls[options.callIndex];
|
||||||
if (!call) {
|
if (!call) {
|
||||||
@ -1900,9 +1828,9 @@ RilObject.prototype = {
|
|||||||
let Buf = this.context.Buf;
|
let Buf = this.context.Buf;
|
||||||
if (this._isCdma) {
|
if (this._isCdma) {
|
||||||
options.featureStr = "";
|
options.featureStr = "";
|
||||||
this.sendCdmaFlashCommand(options);
|
this.cdmaFlash(options);
|
||||||
} else if (call.state == CALL_STATE_ACTIVE) {
|
} else if (call.state == CALL_STATE_ACTIVE) {
|
||||||
this.sendSwitchWaitingRequest();
|
this.switchActiveCall(options);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -1918,24 +1846,22 @@ RilObject.prototype = {
|
|||||||
let Buf = this.context.Buf;
|
let Buf = this.context.Buf;
|
||||||
if (this._isCdma) {
|
if (this._isCdma) {
|
||||||
options.featureStr = "";
|
options.featureStr = "";
|
||||||
this.sendCdmaFlashCommand(options);
|
this.cdmaFlash(options);
|
||||||
} else if (call.state == CALL_STATE_HOLDING) {
|
} else if (call.state == CALL_STATE_HOLDING) {
|
||||||
this.sendSwitchWaitingRequest();
|
this.switchActiveCall(options);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
conferenceCall: function(options) {
|
conferenceCall: function(options) {
|
||||||
if (this._isCdma) {
|
if (this._isCdma) {
|
||||||
options.featureStr = "";
|
options.featureStr = "";
|
||||||
this.sendCdmaFlashCommand(options);
|
this.cdmaFlash(options);
|
||||||
} else {
|
return;
|
||||||
this.telephonyRequestQueue.push(REQUEST_CONFERENCE,
|
|
||||||
this.sendRilRequestConference, options);
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
sendRilRequestConference: function(options) {
|
this.telephonyRequestQueue.push(REQUEST_CONFERENCE, () => {
|
||||||
this.context.Buf.simpleRequest(REQUEST_CONFERENCE, options);
|
this.context.Buf.simpleRequest(REQUEST_CONFERENCE, options);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
separateCall: function(options) {
|
separateCall: function(options) {
|
||||||
@ -1950,20 +1876,17 @@ RilObject.prototype = {
|
|||||||
|
|
||||||
if (this._isCdma) {
|
if (this._isCdma) {
|
||||||
options.featureStr = "";
|
options.featureStr = "";
|
||||||
this.sendCdmaFlashCommand(options);
|
this.cdmaFlash(options);
|
||||||
} else {
|
return;
|
||||||
this.telephonyRequestQueue.push(REQUEST_SEPARATE_CONNECTION,
|
|
||||||
this.sendRilRequestSeparateConnection,
|
|
||||||
options);
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
sendRilRequestSeparateConnection: function(options) {
|
this.telephonyRequestQueue.push(REQUEST_SEPARATE_CONNECTION, () => {
|
||||||
let Buf = this.context.Buf;
|
let Buf = this.context.Buf;
|
||||||
Buf.newParcel(REQUEST_SEPARATE_CONNECTION, options);
|
Buf.newParcel(REQUEST_SEPARATE_CONNECTION, options);
|
||||||
Buf.writeInt32(1);
|
Buf.writeInt32(1);
|
||||||
Buf.writeInt32(options.callIndex);
|
Buf.writeInt32(options.callIndex);
|
||||||
Buf.sendParcel();
|
Buf.sendParcel();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
hangUpConference: function(options) {
|
hangUpConference: function(options) {
|
||||||
@ -1976,31 +1899,56 @@ RilObject.prototype = {
|
|||||||
this.sendChromeMessage(options);
|
this.sendChromeMessage(options);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
call.hangUpLocal = true;
|
|
||||||
this.sendHangUpRequest(1);
|
options.callIndex = 1;
|
||||||
|
this.hangUp(options);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.currentConferenceState === CALL_STATE_ACTIVE) {
|
||||||
|
this.hangUpForeground(options);
|
||||||
} else {
|
} else {
|
||||||
if (this.currentConferenceState === CALL_STATE_ACTIVE) {
|
this.hangUpBackground(options);
|
||||||
this.sendHangUpForegroundRequest(options);
|
|
||||||
} else {
|
|
||||||
this.sendHangUpBackgroundRequest(options);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
holdConference: function() {
|
holdConference: function(options) {
|
||||||
if (this._isCdma) {
|
if (this._isCdma) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.sendSwitchWaitingRequest();
|
this.switchActiveCall(options);
|
||||||
},
|
},
|
||||||
|
|
||||||
resumeConference: function() {
|
resumeConference: function(options) {
|
||||||
if (this._isCdma) {
|
if (this._isCdma) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.sendSwitchWaitingRequest();
|
this.switchActiveCall(options);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get current calls.
|
||||||
|
*/
|
||||||
|
getCurrentCalls: function() {
|
||||||
|
this.telephonyRequestQueue.push(REQUEST_GET_CURRENT_CALLS, () => {
|
||||||
|
this.context.Buf.simpleRequest(REQUEST_GET_CURRENT_CALLS);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mute or unmute the radio.
|
||||||
|
*
|
||||||
|
* @param mute
|
||||||
|
* Boolean to indicate whether to mute or unmute the radio.
|
||||||
|
*/
|
||||||
|
setMute: function(options) {
|
||||||
|
let Buf = this.context.Buf;
|
||||||
|
Buf.newParcel(REQUEST_SET_MUTE);
|
||||||
|
Buf.writeInt32(1);
|
||||||
|
Buf.writeInt32(options.muted ? 1 : 0);
|
||||||
|
Buf.sendParcel();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2687,10 +2635,6 @@ RilObject.prototype = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.sendRilRequestSendUSSD(options);
|
|
||||||
},
|
|
||||||
|
|
||||||
sendRilRequestSendUSSD: function(options) {
|
|
||||||
let Buf = this.context.Buf;
|
let Buf = this.context.Buf;
|
||||||
Buf.newParcel(REQUEST_SEND_USSD, options);
|
Buf.newParcel(REQUEST_SEND_USSD, options);
|
||||||
Buf.writeString(options.ussd);
|
Buf.writeString(options.ussd);
|
||||||
@ -3936,6 +3880,8 @@ RilObject.prototype = {
|
|||||||
* Helpers for processing call state changes.
|
* Helpers for processing call state changes.
|
||||||
*/
|
*/
|
||||||
_processCalls: function(newCalls, failCause) {
|
_processCalls: function(newCalls, failCause) {
|
||||||
|
if (DEBUG) this.context.debug("_processCalls: " + JSON.stringify(newCalls));
|
||||||
|
|
||||||
// Let's get the failCause first if there are removed calls. Otherwise, we
|
// Let's get the failCause first if there are removed calls. Otherwise, we
|
||||||
// need to trigger another async request when removing call and it cause
|
// need to trigger another async request when removing call and it cause
|
||||||
// the order of callDisconnected and conferenceCallStateChanged
|
// the order of callDisconnected and conferenceCallStateChanged
|
||||||
@ -5464,7 +5410,7 @@ RilObject.prototype[REQUEST_GET_IMSI] = function REQUEST_GET_IMSI(length, option
|
|||||||
this.sendChromeMessage(options);
|
this.sendChromeMessage(options);
|
||||||
};
|
};
|
||||||
RilObject.prototype[REQUEST_HANGUP] = function REQUEST_HANGUP(length, options) {
|
RilObject.prototype[REQUEST_HANGUP] = function REQUEST_HANGUP(length, options) {
|
||||||
options.success = options.rilRequestError === 0;
|
options.success = (options.rilRequestError === 0);
|
||||||
options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
|
options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
|
||||||
this.sendChromeMessage(options);
|
this.sendChromeMessage(options);
|
||||||
};
|
};
|
||||||
@ -5475,6 +5421,9 @@ RilObject.prototype[REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND] = function REQU
|
|||||||
RilObject.prototype[REQUEST_HANGUP].call(this, length, options);
|
RilObject.prototype[REQUEST_HANGUP].call(this, length, options);
|
||||||
};
|
};
|
||||||
RilObject.prototype[REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE] = function REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE(length, options) {
|
RilObject.prototype[REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE] = function REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE(length, options) {
|
||||||
|
options.success = (options.rilRequestError === 0);
|
||||||
|
options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
|
||||||
|
this.sendChromeMessage(options);
|
||||||
};
|
};
|
||||||
RilObject.prototype[REQUEST_CONFERENCE] = function REQUEST_CONFERENCE(length, options) {
|
RilObject.prototype[REQUEST_CONFERENCE] = function REQUEST_CONFERENCE(length, options) {
|
||||||
options.success = (options.rilRequestError === 0);
|
options.success = (options.rilRequestError === 0);
|
||||||
|
@ -122,9 +122,9 @@ add_test(function test_request_exit_emergencyCbMode_when_dial() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Dial non-emergency call.
|
// Dial non-emergency call.
|
||||||
context.RIL.dialNonEmergencyNumber({number: "0912345678",
|
context.RIL.dial({number: "0912345678",
|
||||||
isEmergency: false,
|
isEmergency: false,
|
||||||
isDialEmergency: false});
|
isDialEmergency: false});
|
||||||
|
|
||||||
// Should clear timeout event.
|
// Should clear timeout event.
|
||||||
do_check_eq(context.RIL._exitEmergencyCbModeTimeoutID, null);
|
do_check_eq(context.RIL._exitEmergencyCbModeTimeoutID, null);
|
||||||
@ -167,4 +167,3 @@ add_test(function test_request_exit_emergencyCbMode_explicitly() {
|
|||||||
|
|
||||||
run_next_test();
|
run_next_test();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -515,24 +515,59 @@ TelephonyService.prototype = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mmi = this._parseMMI(aNumber, this._hasCalls(aClientId));
|
if (this._hasCalls(aClientId)) {
|
||||||
if (!mmi) {
|
// 3GPP TS 22.030 6.5.5
|
||||||
this._dialCall(aClientId,
|
// Handling of supplementary services within a call.
|
||||||
{ number: aNumber,
|
|
||||||
isDialEmergency: aIsDialEmergency }, aCallback);
|
|
||||||
} else if (this._isTemporaryCLIR(mmi)) {
|
|
||||||
this._dialCall(aClientId,
|
|
||||||
{ number: mmi.dialNumber,
|
|
||||||
clirMode: this._getTemporaryCLIRMode(mmi.procedure),
|
|
||||||
isDialEmergency: aIsDialEmergency }, aCallback);
|
|
||||||
} else {
|
|
||||||
// Reject MMI code from dialEmergency api.
|
|
||||||
if (aIsDialEmergency) {
|
|
||||||
aCallback.notifyError(DIAL_ERROR_BAD_NUMBER);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._dialMMI(aClientId, mmi, aCallback, true);
|
let mmiCallback = response => {
|
||||||
|
aCallback.notifyDialMMI(RIL.MMI_KS_SC_CALL);
|
||||||
|
if (!response.success) {
|
||||||
|
aCallback.notifyDialMMIError(RIL.MMI_ERROR_KS_ERROR);
|
||||||
|
} else {
|
||||||
|
aCallback.notifyDialMMISuccess(RIL.MMI_SM_KS_CALL_CONTROL);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (aNumber === "0") {
|
||||||
|
this._sendToRilWorker(aClientId, "hangUpBackground", null, mmiCallback);
|
||||||
|
} else if (aNumber === "1") {
|
||||||
|
this._sendToRilWorker(aClientId, "hangUpForeground", null, mmiCallback);
|
||||||
|
} else if (aNumber[0] === "1" && aNumber.length === 2) {
|
||||||
|
this._sendToRilWorker(aClientId, "hangUp",
|
||||||
|
{ callIndex: parseInt(aNumber[1]) }, mmiCallback);
|
||||||
|
} else if (aNumber === "2") {
|
||||||
|
this._sendToRilWorker(aClientId, "switchActiveCall", null, mmiCallback);
|
||||||
|
} else if (aNumber[0] === "2" && aNumber.length === 2) {
|
||||||
|
this._sendToRilWorker(aClientId, "separateCall",
|
||||||
|
{ callIndex: parseInt(aNumber[1]) }, mmiCallback);
|
||||||
|
} else if (aNumber === "3") {
|
||||||
|
this._sendToRilWorker(aClientId, "conferenceCall", null, mmiCallback);
|
||||||
|
} else {
|
||||||
|
// Entering "Directory Number"
|
||||||
|
this._dialCall(aClientId,
|
||||||
|
{ number: aNumber,
|
||||||
|
isDialEmergency: aIsDialEmergency }, aCallback);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let mmi = this._parseMMI(aNumber);
|
||||||
|
if (!mmi) {
|
||||||
|
this._dialCall(aClientId,
|
||||||
|
{ number: aNumber,
|
||||||
|
isDialEmergency: aIsDialEmergency }, aCallback);
|
||||||
|
} else if (this._isTemporaryCLIR(mmi)) {
|
||||||
|
this._dialCall(aClientId,
|
||||||
|
{ number: mmi.dialNumber,
|
||||||
|
clirMode: this._getTemporaryCLIRMode(mmi.procedure),
|
||||||
|
isDialEmergency: aIsDialEmergency }, aCallback);
|
||||||
|
} else {
|
||||||
|
// Reject MMI code from dialEmergency api.
|
||||||
|
if (aIsDialEmergency) {
|
||||||
|
aCallback.notifyError(DIAL_ERROR_BAD_NUMBER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._dialMMI(aClientId, mmi, aCallback, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -682,7 +717,7 @@ TelephonyService.prototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// No additional information
|
// No additional information
|
||||||
if (response.additionalInformation == undefined) {
|
if (response.additionalInformation === undefined) {
|
||||||
aCallback.notifyDialMMISuccess(response.statusMessage);
|
aCallback.notifyDialMMISuccess(response.statusMessage);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -791,15 +826,11 @@ TelephonyService.prototype = {
|
|||||||
/**
|
/**
|
||||||
* Helper to parse short string. TS.22.030 Figure 3.5.3.2.
|
* Helper to parse short string. TS.22.030 Figure 3.5.3.2.
|
||||||
*/
|
*/
|
||||||
_isShortString: function(aMmiString, hasCalls) {
|
_isShortString: function(aMmiString) {
|
||||||
if (aMmiString.length > 2) {
|
if (aMmiString.length > 2) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasCalls) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Input string is
|
// Input string is
|
||||||
// - emergency number or
|
// - emergency number or
|
||||||
// - 2 digits starting with a "1"
|
// - 2 digits starting with a "1"
|
||||||
@ -814,7 +845,7 @@ TelephonyService.prototype = {
|
|||||||
/**
|
/**
|
||||||
* Helper to parse MMI/USSD string. TS.22.030 Figure 3.5.3.2.
|
* Helper to parse MMI/USSD string. TS.22.030 Figure 3.5.3.2.
|
||||||
*/
|
*/
|
||||||
_parseMMI: function(aMmiString, hasCalls) {
|
_parseMMI: function(aMmiString) {
|
||||||
if (!aMmiString) {
|
if (!aMmiString) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -833,8 +864,7 @@ TelephonyService.prototype = {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._isPoundString(aMmiString) ||
|
if (this._isPoundString(aMmiString) || this._isShortString(aMmiString)) {
|
||||||
this._isShortString(aMmiString, hasCalls)) {
|
|
||||||
return {
|
return {
|
||||||
fullMMI: aMmiString
|
fullMMI: aMmiString
|
||||||
};
|
};
|
||||||
|
@ -1025,6 +1025,9 @@ let emulator = (function() {
|
|||||||
|
|
||||||
this.gDelay = delay;
|
this.gDelay = delay;
|
||||||
this.gWaitForEvent = waitForEvent;
|
this.gWaitForEvent = waitForEvent;
|
||||||
|
this.gWaitForCallsChangedEvent = waitForCallsChangedEvent;
|
||||||
|
this.gWaitForNamedStateEvent = waitForNamedStateEvent;
|
||||||
|
this.gWaitForStateChangeEvent = waitForStateChangeEvent;
|
||||||
this.gCheckInitialState = checkInitialState;
|
this.gCheckInitialState = checkInitialState;
|
||||||
this.gClearCalls = clearCalls;
|
this.gClearCalls = clearCalls;
|
||||||
this.gOutCallStrPool = outCallStrPool;
|
this.gOutCallStrPool = outCallStrPool;
|
||||||
|
@ -67,3 +67,6 @@ disabled = Bug 821958
|
|||||||
[test_mmi.js]
|
[test_mmi.js]
|
||||||
[test_mmi_change_pin.js]
|
[test_mmi_change_pin.js]
|
||||||
[test_mmi_call_forwarding.js]
|
[test_mmi_call_forwarding.js]
|
||||||
|
[test_incall_mmi_call_waiting.js]
|
||||||
|
[test_incall_mmi_call_hold.js]
|
||||||
|
[test_incall_mmi_conference.js]
|
||||||
|
88
dom/telephony/test/marionette/test_incall_mmi_call_hold.js
Normal file
88
dom/telephony/test/marionette/test_incall_mmi_call_hold.js
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
MARIONETTE_TIMEOUT = 60000;
|
||||||
|
MARIONETTE_HEAD_JS = 'head.js';
|
||||||
|
|
||||||
|
const call1Number = "0900000001";
|
||||||
|
const call2Number = "0900000002";
|
||||||
|
const call1Info = gOutCallStrPool(call1Number);
|
||||||
|
const call2Info = gOutCallStrPool(call2Number);
|
||||||
|
|
||||||
|
// call1 is held, call2 is active
|
||||||
|
function setupTwoCalls() {
|
||||||
|
let call1;
|
||||||
|
let call2;
|
||||||
|
|
||||||
|
return gDial(call1Number)
|
||||||
|
.then(call => call1 = call)
|
||||||
|
.then(() => gRemoteAnswer(call1))
|
||||||
|
.then(() => gDial(call2Number))
|
||||||
|
.then(call => call2 = call)
|
||||||
|
.then(() => gRemoteAnswer(call2))
|
||||||
|
.then(() => gCheckAll(call2, [call1, call2], "", [],
|
||||||
|
[call1Info.held, call2Info.active]))
|
||||||
|
.then(() => [call1, call2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testInCallMMI_0() {
|
||||||
|
log('= testInCallMMI_0 =');
|
||||||
|
|
||||||
|
return setupTwoCalls()
|
||||||
|
.then(calls => [call1, call2] = calls)
|
||||||
|
// Hangup held call.
|
||||||
|
.then(() => gSendMMI("0"))
|
||||||
|
.then(() => gWaitForNamedStateEvent(call1, "disconnected"))
|
||||||
|
.then(() => gCheckAll(call2, [call2], "", [], [call2Info.active]))
|
||||||
|
.then(() => gRemoteHangUpCalls([call2]));
|
||||||
|
}
|
||||||
|
|
||||||
|
function testInCallMMI_1() {
|
||||||
|
log('= testInCallMMI_1 =');
|
||||||
|
|
||||||
|
return setupTwoCalls()
|
||||||
|
.then(calls => [call1, call2] = calls)
|
||||||
|
// Hangup current call, resume held call.
|
||||||
|
.then(() => gSendMMI("1"))
|
||||||
|
.then(() => {
|
||||||
|
let p1 = gWaitForNamedStateEvent(call1, "connected");
|
||||||
|
let p2 = gWaitForNamedStateEvent(call2, "disconnected");
|
||||||
|
return Promise.all([p1, p2]);
|
||||||
|
})
|
||||||
|
.then(() => gCheckAll(call1, [call1], "", [], [call1Info.active]))
|
||||||
|
.then(() => gRemoteHangUpCalls([call1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
function testInCallMMI_2() {
|
||||||
|
log('= testInCallMMI_2 =');
|
||||||
|
|
||||||
|
return setupTwoCalls()
|
||||||
|
.then(calls => [call1, call2] = calls)
|
||||||
|
// Hold current call, resume held call.
|
||||||
|
.then(() => gSendMMI("2"))
|
||||||
|
.then(() => {
|
||||||
|
let p1 = gWaitForNamedStateEvent(call1, "connected");
|
||||||
|
let p2 = gWaitForNamedStateEvent(call2, "held");
|
||||||
|
return Promise.all([p1, p2]);
|
||||||
|
})
|
||||||
|
.then(() => gCheckAll(call1, [call1, call2], "", [],
|
||||||
|
[call1Info.active, call2Info.held]))
|
||||||
|
// Hold current call, resume held call.
|
||||||
|
.then(() => gSendMMI("2"))
|
||||||
|
.then(() => {
|
||||||
|
let p1 = gWaitForNamedStateEvent(call1, "held");
|
||||||
|
let p2 = gWaitForNamedStateEvent(call2, "connected");
|
||||||
|
return Promise.all([p1, p2]);
|
||||||
|
})
|
||||||
|
.then(() => gCheckAll(call2, [call1, call2], "", [],
|
||||||
|
[call1Info.held, call2Info.active]))
|
||||||
|
.then(() => gRemoteHangUpCalls([call1, call2]));
|
||||||
|
}
|
||||||
|
|
||||||
|
startTest(function() {
|
||||||
|
testInCallMMI_0()
|
||||||
|
.then(() => testInCallMMI_1())
|
||||||
|
.then(() => testInCallMMI_2())
|
||||||
|
.catch(error => ok(false, "Promise reject: " + error))
|
||||||
|
.then(finish);
|
||||||
|
});
|
@ -0,0 +1,77 @@
|
|||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
MARIONETTE_TIMEOUT = 60000;
|
||||||
|
MARIONETTE_HEAD_JS = 'head.js';
|
||||||
|
|
||||||
|
const outNumber = "0900000001";
|
||||||
|
const inNumber = "0900000002";
|
||||||
|
const outInfo = gOutCallStrPool(outNumber);
|
||||||
|
const inInfo = gInCallStrPool(inNumber);
|
||||||
|
|
||||||
|
function setupTwoCalls() {
|
||||||
|
let outCall;
|
||||||
|
let inCall;
|
||||||
|
|
||||||
|
return gDial(outNumber)
|
||||||
|
.then(call => outCall = call)
|
||||||
|
.then(() => gRemoteAnswer(outCall))
|
||||||
|
.then(() => gRemoteDial(inNumber))
|
||||||
|
.then(call => inCall = call)
|
||||||
|
.then(() => gCheckAll(outCall, [outCall, inCall], "", [],
|
||||||
|
[outInfo.active, inInfo.waiting]))
|
||||||
|
.then(() => [outCall, inCall]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testInCallMMI_0() {
|
||||||
|
log('= testInCallMMI_0 =');
|
||||||
|
|
||||||
|
return setupTwoCalls()
|
||||||
|
.then(calls => [outCall, inCall] = calls)
|
||||||
|
// Hangup waiting call.
|
||||||
|
.then(() => gSendMMI("0"))
|
||||||
|
.then(() => gWaitForNamedStateEvent(inCall, "disconnected"))
|
||||||
|
.then(() => gCheckAll(outCall, [outCall], "", [], [outInfo.active]))
|
||||||
|
.then(() => gRemoteHangUpCalls([outCall]));
|
||||||
|
}
|
||||||
|
|
||||||
|
function testInCallMMI_1() {
|
||||||
|
log('= testInCallMMI_1 =');
|
||||||
|
|
||||||
|
return setupTwoCalls()
|
||||||
|
.then(calls => [outCall, inCall] = calls)
|
||||||
|
// Hangup current call, accept waiting call.
|
||||||
|
.then(() => gSendMMI("1"))
|
||||||
|
.then(() => {
|
||||||
|
let p1 = gWaitForNamedStateEvent(outCall, "disconnected");
|
||||||
|
let p2 = gWaitForNamedStateEvent(inCall, "connected");
|
||||||
|
return Promise.all([p1, p2]);
|
||||||
|
})
|
||||||
|
.then(() => gCheckAll(inCall, [inCall], "", [], [inInfo.active]))
|
||||||
|
.then(() => gRemoteHangUpCalls([inCall]));
|
||||||
|
}
|
||||||
|
|
||||||
|
function testInCallMMI_2() {
|
||||||
|
log('= testInCallMMI_2 =');
|
||||||
|
|
||||||
|
return setupTwoCalls()
|
||||||
|
.then(calls => [outCall, inCall] = calls)
|
||||||
|
// Hold current call, accept waiting call.
|
||||||
|
.then(() => gSendMMI("2"))
|
||||||
|
.then(() => {
|
||||||
|
let p1 = gWaitForNamedStateEvent(outCall, "held");
|
||||||
|
let p2 = gWaitForNamedStateEvent(inCall, "connected");
|
||||||
|
return Promise.all([p1, p2]);
|
||||||
|
})
|
||||||
|
.then(() => gCheckAll(inCall, [outCall, inCall], "", [],
|
||||||
|
[outInfo.held, inInfo.active]))
|
||||||
|
.then(() => gRemoteHangUpCalls([outCall, inCall]));
|
||||||
|
}
|
||||||
|
|
||||||
|
startTest(function() {
|
||||||
|
testInCallMMI_0()
|
||||||
|
.then(() => testInCallMMI_1())
|
||||||
|
.then(() => testInCallMMI_2())
|
||||||
|
.catch(error => ok(false, "Promise reject: " + error))
|
||||||
|
.then(finish);
|
||||||
|
});
|
90
dom/telephony/test/marionette/test_incall_mmi_conference.js
Normal file
90
dom/telephony/test/marionette/test_incall_mmi_conference.js
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
MARIONETTE_TIMEOUT = 60000;
|
||||||
|
MARIONETTE_HEAD_JS = 'head.js';
|
||||||
|
|
||||||
|
const call1Number = "0900000001";
|
||||||
|
const call2Number = "0900000002";
|
||||||
|
const call3Number = "0900000003";
|
||||||
|
const call1Info = gOutCallStrPool(call1Number);
|
||||||
|
const call2Info = gOutCallStrPool(call2Number);
|
||||||
|
const call3Info = gOutCallStrPool(call3Number);
|
||||||
|
|
||||||
|
function setupTwoCalls() {
|
||||||
|
let call1;
|
||||||
|
let call2;
|
||||||
|
|
||||||
|
return gDial(call1Number)
|
||||||
|
.then(call => call1 = call)
|
||||||
|
.then(() => gRemoteAnswer(call1))
|
||||||
|
.then(() => gDial(call2Number))
|
||||||
|
.then(call => call2 = call)
|
||||||
|
.then(() => gRemoteAnswer(call2))
|
||||||
|
.then(() => gCheckAll(call2, [call1, call2], "", [],
|
||||||
|
[call1Info.held, call2Info.active]))
|
||||||
|
.then(() => [call1, call2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testInCallMMI() {
|
||||||
|
log('= testInCallMMI =');
|
||||||
|
|
||||||
|
return setupTwoCalls()
|
||||||
|
.then(calls => [call1, call2] = calls)
|
||||||
|
// Conference two calls.
|
||||||
|
.then(() => log("- Conference two calls."))
|
||||||
|
.then(() => gSendMMI("3"))
|
||||||
|
.then(() => gWaitForNamedStateEvent(conference, "connected"))
|
||||||
|
.then(() => gCheckAll(conference, [], "connected", [call1, call2],
|
||||||
|
[call1Info.active, call2Info.active]))
|
||||||
|
|
||||||
|
// Make third call.
|
||||||
|
.then(() => log("- Make third call."))
|
||||||
|
.then(() => gDial(call3Number))
|
||||||
|
.then(call => call3 = call)
|
||||||
|
.then(() => gRemoteAnswer(call3))
|
||||||
|
.then(() => gCheckAll(call3, [call3], "held", [call1, call2],
|
||||||
|
[call1Info.held, call2Info.held, call3Info.active]))
|
||||||
|
|
||||||
|
// Enlarge the conference.
|
||||||
|
.then(() => log("- Enlarge the conference."))
|
||||||
|
.then(() => gSendMMI("3"))
|
||||||
|
.then(() => gWaitForNamedStateEvent(conference, "connected"))
|
||||||
|
.then(() => gCheckAll(conference, [], "connected", [call1, call2, call3],
|
||||||
|
[call1Info.active, call2Info.active, call3Info.active]))
|
||||||
|
|
||||||
|
// Separate call 2.
|
||||||
|
.then(() => log("- Separate call 2."))
|
||||||
|
.then(() => gSendMMI("22"))
|
||||||
|
.then(() => gWaitForNamedStateEvent(conference, "held"))
|
||||||
|
.then(() => gCheckAll(call2, [call2], "held", [call1, call3],
|
||||||
|
[call1Info.held, call2Info.active, call3Info.held]))
|
||||||
|
|
||||||
|
// Switch active.
|
||||||
|
.then(() => log("- Switch active."))
|
||||||
|
.then(() => gSendMMI("2"))
|
||||||
|
.then(() => gWaitForNamedStateEvent(conference, "connected"))
|
||||||
|
.then(() => gCheckAll(conference, [call2], "connected", [call1, call3],
|
||||||
|
[call1Info.active, call2Info.held, call3Info.active]))
|
||||||
|
|
||||||
|
// Release call 2.
|
||||||
|
.then(() => log("- Release call 2."))
|
||||||
|
.then(() => gSendMMI("12"))
|
||||||
|
.then(() => gWaitForNamedStateEvent(call2, "disconnected"))
|
||||||
|
.then(() => gCheckAll(conference, [], "connected", [call1, call3],
|
||||||
|
[call1Info.active, call3Info.active]))
|
||||||
|
|
||||||
|
// Release call 1.
|
||||||
|
.then(() => log("- Release call 1."))
|
||||||
|
.then(() => gSendMMI("11"))
|
||||||
|
.then(() => gWaitForStateChangeEvent(conference, ""))
|
||||||
|
.then(() => gCheckAll(call3, [call3], "", [], [call3Info.active]))
|
||||||
|
|
||||||
|
.then(() => gRemoteHangUpCalls([call3]));
|
||||||
|
}
|
||||||
|
|
||||||
|
startTest(function() {
|
||||||
|
testInCallMMI()
|
||||||
|
.catch(error => ok(false, "Promise reject: " + error))
|
||||||
|
.then(finish);
|
||||||
|
});
|
@ -12,7 +12,7 @@ function run_test() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function parseMMI(mmiString) {
|
function parseMMI(mmiString) {
|
||||||
return NS.TelephonyService.prototype._parseMMI(mmiString, false);
|
return NS.TelephonyService.prototype._parseMMI(mmiString);
|
||||||
}
|
}
|
||||||
|
|
||||||
add_test(function test_parseMMI_empty() {
|
add_test(function test_parseMMI_empty() {
|
||||||
|
@ -111,17 +111,6 @@ dictionary CameraStartRecordingOptions
|
|||||||
boolean autoEnableLowLightTorch = false;
|
boolean autoEnableLowLightTorch = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
callback CameraSetConfigurationCallback = void (CameraConfiguration configuration);
|
|
||||||
callback CameraAutoFocusCallback = void (boolean focused);
|
|
||||||
callback CameraTakePictureCallback = void (Blob picture);
|
|
||||||
callback CameraStartRecordingCallback = void ();
|
|
||||||
callback CameraShutterCallback = void ();
|
|
||||||
callback CameraClosedCallback = void (DOMString reason);
|
|
||||||
callback CameraReleaseCallback = void ();
|
|
||||||
callback CameraRecorderStateChange = void (DOMString newState);
|
|
||||||
callback CameraPreviewStateChange = void (DOMString newState);
|
|
||||||
callback CameraAutoFocusMovingCallback = void (boolean isMoving);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
attributes here affect the preview, any pictures taken, and/or
|
attributes here affect the preview, any pictures taken, and/or
|
||||||
any video recorded by the camera.
|
any video recorded by the camera.
|
||||||
@ -231,26 +220,11 @@ interface CameraControl : MediaStream
|
|||||||
[Throws]
|
[Throws]
|
||||||
attribute DOMString isoMode;
|
attribute DOMString isoMode;
|
||||||
|
|
||||||
/* the function to call on the camera's shutter event, to trigger
|
|
||||||
a shutter sound and/or a visual shutter indicator. */
|
|
||||||
attribute CameraShutterCallback? onShutter;
|
|
||||||
|
|
||||||
/* the event dispatched on the camera's shutter event, to trigger
|
/* the event dispatched on the camera's shutter event, to trigger
|
||||||
a shutter sound and/or a visual shutter indicator.
|
a shutter sound and/or a visual shutter indicator.
|
||||||
|
|
||||||
contains no event-specific data. */
|
contains no event-specific data. */
|
||||||
attribute EventHandler onshutter;
|
attribute EventHandler onshutter;
|
||||||
|
|
||||||
/* the function to call when the camera hardware is closed; this may
|
|
||||||
be due to a system failure, another process taking over the camera,
|
|
||||||
or a call to release().
|
|
||||||
|
|
||||||
The 'reason' will be one of the following string values:
|
|
||||||
- SystemFailure : the camera subsystem failed and was closed;
|
|
||||||
- HardwareReleased : a call to release() was successful;
|
|
||||||
- NotAvailable : the camera hardware is in use by another process.
|
|
||||||
*/
|
|
||||||
attribute CameraClosedCallback? onClosed;
|
|
||||||
|
|
||||||
/* the event dispatched when the camera hardware is closed; this may
|
/* the event dispatched when the camera hardware is closed; this may
|
||||||
be due to a system failure, another process taking over the camera,
|
be due to a system failure, another process taking over the camera,
|
||||||
@ -262,12 +236,7 @@ interface CameraControl : MediaStream
|
|||||||
- HardwareReleased : a call to release() was successful;
|
- HardwareReleased : a call to release() was successful;
|
||||||
- NotAvailable : the camera hardware is in use by another process.
|
- NotAvailable : the camera hardware is in use by another process.
|
||||||
*/
|
*/
|
||||||
attribute EventHandler onclose;
|
attribute EventHandler onclose;
|
||||||
|
|
||||||
/* the function to call when the recorder changes state, either because
|
|
||||||
the recording process encountered an error, or because one of the
|
|
||||||
recording limits (see CameraStartRecordingOptions) was reached. */
|
|
||||||
attribute CameraRecorderStateChange? onRecorderStateChange;
|
|
||||||
|
|
||||||
/* the event dispatched when the recorder changes state, either because
|
/* the event dispatched when the recorder changes state, either because
|
||||||
the recording process encountered an error, or because one of the
|
the recording process encountered an error, or because one of the
|
||||||
@ -275,18 +244,14 @@ interface CameraControl : MediaStream
|
|||||||
|
|
||||||
event type is CameraStateChangeEvent where:
|
event type is CameraStateChangeEvent where:
|
||||||
'newState' is the new recorder state */
|
'newState' is the new recorder state */
|
||||||
attribute EventHandler onrecorderstatechange;
|
attribute EventHandler onrecorderstatechange;
|
||||||
|
|
||||||
/* the function to call when the viewfinder stops or starts,
|
|
||||||
useful for synchronizing other UI elements. */
|
|
||||||
attribute CameraPreviewStateChange? onPreviewStateChange;
|
|
||||||
|
|
||||||
/* the event dispatched when the viewfinder stops or starts,
|
/* the event dispatched when the viewfinder stops or starts,
|
||||||
useful for synchronizing other UI elements.
|
useful for synchronizing other UI elements.
|
||||||
|
|
||||||
event type is CameraStateChangeEvent where:
|
event type is CameraStateChangeEvent where:
|
||||||
'newState' is the new preview state */
|
'newState' is the new preview state */
|
||||||
attribute EventHandler onpreviewstatechange;
|
attribute EventHandler onpreviewstatechange;
|
||||||
|
|
||||||
/* the size of the picture to be returned by a call to takePicture();
|
/* the size of the picture to be returned by a call to takePicture();
|
||||||
an object with 'height' and 'width' properties that corresponds to
|
an object with 'height' and 'width' properties that corresponds to
|
||||||
@ -304,7 +269,7 @@ interface CameraControl : MediaStream
|
|||||||
'get' the exact value that was previously 'set'. If this setting is
|
'get' the exact value that was previously 'set'. If this setting is
|
||||||
not supported, it is ignored. */
|
not supported, it is ignored. */
|
||||||
[Throws]
|
[Throws]
|
||||||
attribute double pictureQuality;
|
attribute double pictureQuality;
|
||||||
|
|
||||||
/* the size of the thumbnail to be included in the picture returned
|
/* the size of the thumbnail to be included in the picture returned
|
||||||
by a call to takePicture(), assuming the chosen fileFormat supports
|
by a call to takePicture(), assuming the chosen fileFormat supports
|
||||||
@ -326,8 +291,7 @@ interface CameraControl : MediaStream
|
|||||||
|
|
||||||
/* tell the camera to attempt to focus the image */
|
/* tell the camera to attempt to focus the image */
|
||||||
[Throws]
|
[Throws]
|
||||||
Promise<boolean> autoFocus(optional CameraAutoFocusCallback onSuccess,
|
Promise<boolean> autoFocus();
|
||||||
optional CameraErrorCallback onError);
|
|
||||||
|
|
||||||
/* the event dispatched whenever the focus state changes due to calling
|
/* the event dispatched whenever the focus state changes due to calling
|
||||||
autoFocus or due to continuous autofocus.
|
autoFocus or due to continuous autofocus.
|
||||||
@ -344,45 +308,28 @@ interface CameraControl : MediaStream
|
|||||||
'focused' if the focus is now set
|
'focused' if the focus is now set
|
||||||
'focusing' if the focus is moving
|
'focusing' if the focus is moving
|
||||||
'unfocused' if last attempt to focus failed */
|
'unfocused' if last attempt to focus failed */
|
||||||
attribute EventHandler onfocus;
|
attribute EventHandler onfocus;
|
||||||
|
|
||||||
/* if continuous autofocus is supported and focusMode is set to enable it,
|
|
||||||
then this function is called whenever the camera decides to start and
|
|
||||||
stop moving the focus position; it can be used to update a UI element to
|
|
||||||
indicate that the camera is still trying to focus, or has finished. Some
|
|
||||||
platforms do not support this event, in which case the callback is never
|
|
||||||
invoked. */
|
|
||||||
[Pref="camera.control.autofocus_moving_callback.enabled"]
|
|
||||||
attribute CameraAutoFocusMovingCallback? onAutoFocusMoving;
|
|
||||||
|
|
||||||
/* this function is called whenever auto focus completes, due to continuous
|
|
||||||
autofocus or a solicited auto focus. */
|
|
||||||
attribute CameraAutoFocusCallback? onAutoFocusCompleted;
|
|
||||||
|
|
||||||
/* capture an image and return it as a blob to the 'onSuccess' callback;
|
/* capture an image and return it as a blob to the 'onSuccess' callback;
|
||||||
if the camera supports it, this may be invoked while the camera is
|
if the camera supports it, this may be invoked while the camera is
|
||||||
already recording video.
|
already recording video.
|
||||||
|
|
||||||
invoking this function will stop the preview stream, which must be
|
invoking this function will stop the preview stream, which must be
|
||||||
manually restarted (e.g. by calling .play() on it). */
|
manually restarted by calling resumePreview(). */
|
||||||
[Throws]
|
[Throws]
|
||||||
Promise<Blob> takePicture(optional CameraPictureOptions aOptions,
|
Promise<Blob> takePicture(optional CameraPictureOptions options);
|
||||||
optional CameraTakePictureCallback onSuccess,
|
|
||||||
optional CameraErrorCallback onError);
|
|
||||||
|
|
||||||
/* the event dispatched when a picture is successfully taken; it is of the
|
/* the event dispatched when a picture is successfully taken; it is of the
|
||||||
type BlobEvent, where the data attribute contains the picture. */
|
type BlobEvent, where the data attribute contains the picture. */
|
||||||
attribute EventHandler onpicture;
|
attribute EventHandler onpicture;
|
||||||
|
|
||||||
/* start recording video; 'aOptions' is a CameraStartRecordingOptions object.
|
/* start recording video; 'options' is a CameraStartRecordingOptions object.
|
||||||
If the success/error callbacks are not used, one may determine success by
|
If the success/error callbacks are not used, one may determine success by
|
||||||
waiting for the recorderstatechange event. */
|
waiting for the recorderstatechange event. */
|
||||||
[Throws]
|
[Throws]
|
||||||
Promise<void> startRecording(CameraStartRecordingOptions aOptions,
|
Promise<void> startRecording(CameraStartRecordingOptions options,
|
||||||
DeviceStorage storageArea,
|
DeviceStorage storageArea,
|
||||||
DOMString filename,
|
DOMString filename);
|
||||||
optional CameraStartRecordingCallback onSuccess,
|
|
||||||
optional CameraErrorCallback onError);
|
|
||||||
|
|
||||||
/* stop precording video. */
|
/* stop precording video. */
|
||||||
[Throws]
|
[Throws]
|
||||||
@ -397,27 +344,14 @@ interface CameraControl : MediaStream
|
|||||||
probably call this whenever the camera is not longer in the foreground
|
probably call this whenever the camera is not longer in the foreground
|
||||||
(depending on your usage model).
|
(depending on your usage model).
|
||||||
|
|
||||||
the callbacks are optional, unless you really need to know when
|
|
||||||
the hardware is ultimately released.
|
|
||||||
|
|
||||||
once this is called, the camera control object is to be considered
|
once this is called, the camera control object is to be considered
|
||||||
defunct; a new instance will need to be created to access the camera. */
|
defunct; a new instance will need to be created to access the camera. */
|
||||||
[Throws]
|
[Throws]
|
||||||
Promise<void> release(optional CameraReleaseCallback onSuccess,
|
Promise<void> release();
|
||||||
optional CameraErrorCallback onError);
|
|
||||||
|
|
||||||
/* changes the camera configuration on the fly;
|
/* changes the camera configuration on the fly. */
|
||||||
'configuration' is of type CameraConfiguration.
|
|
||||||
|
|
||||||
XXXmikeh the 'configuration' argument needs to be optional, else
|
|
||||||
the WebIDL compiler throws: "WebIDL.WebIDLError: error: Dictionary
|
|
||||||
argument or union argument containing a dictionary not followed by
|
|
||||||
a required argument must be optional"
|
|
||||||
*/
|
|
||||||
[Throws]
|
[Throws]
|
||||||
Promise<CameraConfiguration> setConfiguration(optional CameraConfiguration configuration,
|
Promise<CameraConfiguration> setConfiguration(optional CameraConfiguration configuration);
|
||||||
optional CameraSetConfigurationCallback onSuccess,
|
|
||||||
optional CameraErrorCallback onError);
|
|
||||||
|
|
||||||
/* the event dispatched when the camera is successfully configured.
|
/* the event dispatched when the camera is successfully configured.
|
||||||
|
|
||||||
@ -524,12 +458,7 @@ partial interface CameraControl
|
|||||||
[Throws, Pref="camera.control.face_detection.enabled"]
|
[Throws, Pref="camera.control.face_detection.enabled"]
|
||||||
void stopFaceDetection();
|
void stopFaceDetection();
|
||||||
|
|
||||||
/* Callback for faces detected in the preview frame. If no faces are
|
|
||||||
detected, the callback is invoked with an empty sequence. */
|
|
||||||
[Pref="camera.control.face_detection.enabled"]
|
|
||||||
attribute CameraFaceDetectionCallback? onFacesDetected;
|
|
||||||
|
|
||||||
/* CameraFacesDetectedEvent */
|
/* CameraFacesDetectedEvent */
|
||||||
[Pref="camera.control.face_detection.enabled"]
|
[Pref="camera.control.face_detection.enabled"]
|
||||||
attribute EventHandler onfacesdetected;
|
attribute EventHandler onfacesdetected;
|
||||||
};
|
};
|
||||||
|
@ -24,11 +24,6 @@ dictionary CameraConfiguration
|
|||||||
// CameraControl.capabilities.recorderProfiles
|
// CameraControl.capabilities.recorderProfiles
|
||||||
};
|
};
|
||||||
|
|
||||||
callback CameraErrorCallback = void (DOMString error);
|
|
||||||
|
|
||||||
callback GetCameraCallback = void (CameraControl camera,
|
|
||||||
CameraConfiguration configuration);
|
|
||||||
|
|
||||||
[Func="nsDOMCameraManager::HasSupport"]
|
[Func="nsDOMCameraManager::HasSupport"]
|
||||||
interface CameraManager
|
interface CameraManager
|
||||||
{
|
{
|
||||||
@ -37,9 +32,7 @@ interface CameraManager
|
|||||||
*/
|
*/
|
||||||
[Throws]
|
[Throws]
|
||||||
Promise<CameraGetPromiseData> getCamera(DOMString camera,
|
Promise<CameraGetPromiseData> getCamera(DOMString camera,
|
||||||
optional CameraConfiguration initialConfiguration,
|
optional CameraConfiguration initialConfiguration);
|
||||||
optional GetCameraCallback callback,
|
|
||||||
optional CameraErrorCallback errorCallback);
|
|
||||||
|
|
||||||
/* return an array of camera identifiers, e.g.
|
/* return an array of camera identifiers, e.g.
|
||||||
[ "front", "back" ]
|
[ "front", "back" ]
|
||||||
|
@ -12,10 +12,12 @@ enum SelectionState {
|
|||||||
"selectall",
|
"selectall",
|
||||||
"collapsetostart",
|
"collapsetostart",
|
||||||
"collapsetoend",
|
"collapsetoend",
|
||||||
"blur"
|
"blur",
|
||||||
|
"updateposition"
|
||||||
};
|
};
|
||||||
|
|
||||||
dictionary SelectionStateChangedEventInit : EventInit {
|
dictionary SelectionStateChangedEventInit : EventInit {
|
||||||
|
boolean visible = true;
|
||||||
DOMString selectedText = "";
|
DOMString selectedText = "";
|
||||||
DOMRectReadOnly? boundingClientRect = null;
|
DOMRectReadOnly? boundingClientRect = null;
|
||||||
sequence<SelectionState> states = [];
|
sequence<SelectionState> states = [];
|
||||||
@ -24,6 +26,7 @@ dictionary SelectionStateChangedEventInit : EventInit {
|
|||||||
[Constructor(DOMString type, optional SelectionStateChangedEventInit eventInit),
|
[Constructor(DOMString type, optional SelectionStateChangedEventInit eventInit),
|
||||||
ChromeOnly]
|
ChromeOnly]
|
||||||
interface SelectionStateChangedEvent : Event {
|
interface SelectionStateChangedEvent : Event {
|
||||||
|
readonly attribute boolean visible;
|
||||||
readonly attribute DOMString selectedText;
|
readonly attribute DOMString selectedText;
|
||||||
readonly attribute DOMRectReadOnly? boundingClientRect;
|
readonly attribute DOMRectReadOnly? boundingClientRect;
|
||||||
[Cached, Pure] readonly attribute sequence<SelectionState> states;
|
[Cached, Pure] readonly attribute sequence<SelectionState> states;
|
||||||
|
@ -1,247 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* vim: set sw=2 ts=8 et tw=80 : */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#ifndef mozilla_layers_InputBlockState_h
|
|
||||||
#define mozilla_layers_InputBlockState_h
|
|
||||||
|
|
||||||
#include "nsTArray.h" // for nsTArray
|
|
||||||
#include "InputData.h" // for MultiTouchInput
|
|
||||||
#include "nsAutoPtr.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace layers {
|
|
||||||
|
|
||||||
class AsyncPanZoomController;
|
|
||||||
class OverscrollHandoffChain;
|
|
||||||
class CancelableBlockState;
|
|
||||||
class TouchBlockState;
|
|
||||||
class WheelBlockState;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A base class that stores state common to various input blocks.
|
|
||||||
* Currently, it just stores the overscroll handoff chain.
|
|
||||||
*/
|
|
||||||
class InputBlockState
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static const uint64_t NO_BLOCK_ID = 0;
|
|
||||||
|
|
||||||
explicit InputBlockState(const nsRefPtr<AsyncPanZoomController>& aTargetApzc,
|
|
||||||
bool aTargetConfirmed);
|
|
||||||
virtual ~InputBlockState()
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool SetConfirmedTargetApzc(const nsRefPtr<AsyncPanZoomController>& aTargetApzc);
|
|
||||||
const nsRefPtr<AsyncPanZoomController>& GetTargetApzc() const;
|
|
||||||
const nsRefPtr<const OverscrollHandoffChain>& GetOverscrollHandoffChain() const;
|
|
||||||
uint64_t GetBlockId() const;
|
|
||||||
|
|
||||||
bool IsTargetConfirmed() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
nsRefPtr<AsyncPanZoomController> mTargetApzc;
|
|
||||||
nsRefPtr<const OverscrollHandoffChain> mOverscrollHandoffChain;
|
|
||||||
bool mTargetConfirmed;
|
|
||||||
const uint64_t mBlockId;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class represents a set of events that can be cancelled by web content
|
|
||||||
* via event listeners.
|
|
||||||
*
|
|
||||||
* Each cancelable input block can be cancelled by web content, and
|
|
||||||
* this information is stored in the mPreventDefault flag. Because web
|
|
||||||
* content runs on the Gecko main thread, we cannot always wait for web content's
|
|
||||||
* response. Instead, there is a timeout that sets this flag in the case
|
|
||||||
* where web content doesn't respond in time. The mContentResponded
|
|
||||||
* and mContentResponseTimerExpired flags indicate which of these scenarios
|
|
||||||
* occurred.
|
|
||||||
*/
|
|
||||||
class CancelableBlockState : public InputBlockState
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CancelableBlockState(const nsRefPtr<AsyncPanZoomController>& aTargetApzc,
|
|
||||||
bool aTargetConfirmed);
|
|
||||||
|
|
||||||
virtual TouchBlockState *AsTouchBlock() {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Record whether or not content cancelled this block of events.
|
|
||||||
* @param aPreventDefault true iff the block is cancelled.
|
|
||||||
* @return false if this block has already received a response from
|
|
||||||
* web content, true if not.
|
|
||||||
*/
|
|
||||||
bool SetContentResponse(bool aPreventDefault);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Record that content didn't respond in time.
|
|
||||||
* @return false if this block already timed out, true if not.
|
|
||||||
*/
|
|
||||||
bool TimeoutContentResponse();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true iff web content cancelled this block of events.
|
|
||||||
*/
|
|
||||||
bool IsDefaultPrevented() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true iff this block has received all the information needed
|
|
||||||
* to properly dispatch the events in the block.
|
|
||||||
*/
|
|
||||||
virtual bool IsReadyForHandling() const;
|
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
private:
|
|
||||||
=======
|
|
||||||
/**
|
|
||||||
* Returns whether or not this block has pending events.
|
|
||||||
*/
|
|
||||||
virtual bool HasEvents() const = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Throw away all the events in this input block.
|
|
||||||
*/
|
|
||||||
virtual void DropEvents() = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process all events given an apzc, leaving ths block depleted.
|
|
||||||
*/
|
|
||||||
virtual void HandleEvents(const nsRefPtr<AsyncPanZoomController>& aTarget) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return true if this input block must stay active if it would otherwise
|
|
||||||
* be removed as the last item in the pending queue.
|
|
||||||
*/
|
|
||||||
virtual bool MustStayActive() = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a descriptive name for the block kind.
|
|
||||||
*/
|
|
||||||
virtual const char* Type() = 0;
|
|
||||||
|
|
||||||
private:
|
|
||||||
>>>>>>> 80325be... Refactor InputQueue to hold more than touch events. (bug 1013432 part 2, r=kats)
|
|
||||||
bool mPreventDefault;
|
|
||||||
bool mContentResponded;
|
|
||||||
bool mContentResponseTimerExpired;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class represents a single touch block. A touch block is
|
|
||||||
* a set of touch events that can be cancelled by web content via
|
|
||||||
* touch event listeners.
|
|
||||||
*
|
|
||||||
* Every touch-start event creates a new touch block. In this case, the
|
|
||||||
* touch block consists of the touch-start, followed by all touch events
|
|
||||||
* up to but not including the next touch-start (except in the case where
|
|
||||||
* a long-tap happens, see below). Note that in particular we cannot know
|
|
||||||
* when a touch block ends until the next one is started. Most touch
|
|
||||||
* blocks are created by receipt of a touch-start event.
|
|
||||||
*
|
|
||||||
* Every long-tap event also creates a new touch block, since it can also
|
|
||||||
* be consumed by web content. In this case, when the long-tap event is
|
|
||||||
* dispatched to web content, a new touch block is started to hold the remaining
|
|
||||||
* touch events, up to but not including the next touch start (or long-tap).
|
|
||||||
*
|
|
||||||
* Additionally, if touch-action is enabled, each touch block should
|
|
||||||
* have a set of allowed touch behavior flags; one for each touch point.
|
|
||||||
* This also requires running code on the Gecko main thread, and so may
|
|
||||||
* be populated with some latency. The mAllowedTouchBehaviorSet and
|
|
||||||
* mAllowedTouchBehaviors variables track this information.
|
|
||||||
*/
|
|
||||||
class TouchBlockState : public CancelableBlockState
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef uint32_t TouchBehaviorFlags;
|
|
||||||
|
|
||||||
explicit TouchBlockState(const nsRefPtr<AsyncPanZoomController>& aTargetApzc,
|
|
||||||
bool aTargetConfirmed);
|
|
||||||
|
|
||||||
TouchBlockState *AsTouchBlock() MOZ_OVERRIDE {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the allowed touch behavior flags for this block.
|
|
||||||
* @return false if this block already has these flags set, true if not.
|
|
||||||
*/
|
|
||||||
bool SetAllowedTouchBehaviors(const nsTArray<TouchBehaviorFlags>& aBehaviors);
|
|
||||||
/**
|
|
||||||
* Copy the allowed touch behavior flags from another block.
|
|
||||||
* @return false if this block already has these flags set, true if not.
|
|
||||||
*/
|
|
||||||
bool CopyAllowedTouchBehaviorsFrom(const TouchBlockState& aOther);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true iff this block has received all the information needed
|
|
||||||
* to properly dispatch the events in the block.
|
|
||||||
*/
|
|
||||||
bool IsReadyForHandling() const MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a flag that disables setting the single-tap flag on this block.
|
|
||||||
*/
|
|
||||||
void DisallowSingleTap();
|
|
||||||
/**
|
|
||||||
* Set a flag that indicates that this touch block triggered a single tap event.
|
|
||||||
* @return true iff DisallowSingleTap was not previously called.
|
|
||||||
*/
|
|
||||||
bool SetSingleTapOccurred();
|
|
||||||
/**
|
|
||||||
* @return true iff SetSingleTapOccurred was previously called on this block.
|
|
||||||
*/
|
|
||||||
bool SingleTapOccurred() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a new touch event to the queue of events in this input block.
|
|
||||||
*/
|
|
||||||
void AddEvent(const MultiTouchInput& aEvent);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return false iff touch-action is enabled and the allowed touch behaviors for
|
|
||||||
* this touch block do not allow pinch-zooming.
|
|
||||||
*/
|
|
||||||
bool TouchActionAllowsPinchZoom() const;
|
|
||||||
/**
|
|
||||||
* @return false iff touch-action is enabled and the allowed touch behaviors for
|
|
||||||
* this touch block do not allow double-tap zooming.
|
|
||||||
*/
|
|
||||||
bool TouchActionAllowsDoubleTapZoom() const;
|
|
||||||
/**
|
|
||||||
* @return false iff touch-action is enabled and the allowed touch behaviors for
|
|
||||||
* the first touch point do not allow panning in the specified direction(s).
|
|
||||||
*/
|
|
||||||
bool TouchActionAllowsPanningX() const;
|
|
||||||
bool TouchActionAllowsPanningY() const;
|
|
||||||
bool TouchActionAllowsPanningXY() const;
|
|
||||||
|
|
||||||
bool HasEvents() const MOZ_OVERRIDE;
|
|
||||||
void DropEvents() MOZ_OVERRIDE;
|
|
||||||
void HandleEvents(const nsRefPtr<AsyncPanZoomController>& aTarget) MOZ_OVERRIDE;
|
|
||||||
bool MustStayActive() MOZ_OVERRIDE;
|
|
||||||
const char* Type() MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* @return the first event in the queue. The event is removed from the queue
|
|
||||||
* before it is returned.
|
|
||||||
*/
|
|
||||||
MultiTouchInput RemoveFirstEvent();
|
|
||||||
|
|
||||||
private:
|
|
||||||
nsTArray<TouchBehaviorFlags> mAllowedTouchBehaviors;
|
|
||||||
bool mAllowedTouchBehaviorSet;
|
|
||||||
bool mSingleTapDisallowed;
|
|
||||||
bool mSingleTapOccurred;
|
|
||||||
nsTArray<MultiTouchInput> mEvents;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace layers
|
|
||||||
} // namespace mozilla
|
|
||||||
|
|
||||||
#endif // mozilla_layers_InputBlockState_h
|
|
@ -28,7 +28,6 @@
|
|||||||
#include "mozilla/dom/DOMRect.h"
|
#include "mozilla/dom/DOMRect.h"
|
||||||
#include "mozilla/dom/Element.h"
|
#include "mozilla/dom/Element.h"
|
||||||
#include "mozilla/dom/ScrollViewChangeEvent.h"
|
#include "mozilla/dom/ScrollViewChangeEvent.h"
|
||||||
#include "mozilla/dom/SelectionStateChangedEvent.h"
|
|
||||||
#include "mozilla/dom/Selection.h"
|
#include "mozilla/dom/Selection.h"
|
||||||
#include "mozilla/dom/TreeWalker.h"
|
#include "mozilla/dom/TreeWalker.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
@ -88,6 +87,7 @@ SelectionCarets::SelectionCarets(nsIPresShell* aPresShell)
|
|||||||
, mAsyncPanZoomEnabled(false)
|
, mAsyncPanZoomEnabled(false)
|
||||||
, mEndCaretVisible(false)
|
, mEndCaretVisible(false)
|
||||||
, mStartCaretVisible(false)
|
, mStartCaretVisible(false)
|
||||||
|
, mSelectionVisibleInScrollFrames(true)
|
||||||
, mVisible(false)
|
, mVisible(false)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
@ -488,43 +488,40 @@ SelectionCarets::UpdateSelectionCarets()
|
|||||||
}
|
}
|
||||||
|
|
||||||
mPresShell->FlushPendingNotifications(Flush_Layout);
|
mPresShell->FlushPendingNotifications(Flush_Layout);
|
||||||
nsRect firstRectInRootFrame =
|
|
||||||
|
// If the selection is not visible, we should dispatch a event.
|
||||||
|
nsIFrame* commonAncestorFrame =
|
||||||
|
nsLayoutUtils::FindNearestCommonAncestorFrame(startFrame, endFrame);
|
||||||
|
|
||||||
|
nsRect selectionRectInRootFrame = GetSelectionBoundingRect(selection);
|
||||||
|
nsRect selectionRectInCommonAncestorFrame = selectionRectInRootFrame;
|
||||||
|
nsLayoutUtils::TransformRect(rootFrame, commonAncestorFrame,
|
||||||
|
selectionRectInCommonAncestorFrame);
|
||||||
|
|
||||||
|
mSelectionVisibleInScrollFrames =
|
||||||
|
nsLayoutUtils::IsRectVisibleInScrollFrames(commonAncestorFrame,
|
||||||
|
selectionRectInCommonAncestorFrame);
|
||||||
|
SELECTIONCARETS_LOG("Selection visibility %s",
|
||||||
|
(mSelectionVisibleInScrollFrames ? "shown" : "hidden"));
|
||||||
|
|
||||||
|
|
||||||
|
nsRect firstRectInStartFrame =
|
||||||
nsCaret::GetGeometryForFrame(startFrame, startOffset, nullptr);
|
nsCaret::GetGeometryForFrame(startFrame, startOffset, nullptr);
|
||||||
nsRect lastRectInRootFrame =
|
nsRect lastRectInEndFrame =
|
||||||
nsCaret::GetGeometryForFrame(endFrame, endOffset, nullptr);
|
nsCaret::GetGeometryForFrame(endFrame, endOffset, nullptr);
|
||||||
|
|
||||||
// GetGeometryForFrame may return a rect that outside frame's rect. So
|
bool startFrameVisible =
|
||||||
// constrain rect inside frame's rect.
|
nsLayoutUtils::IsRectVisibleInScrollFrames(startFrame, firstRectInStartFrame);
|
||||||
firstRectInRootFrame = firstRectInRootFrame.ForceInside(startFrame->GetRectRelativeToSelf());
|
bool endFrameVisible =
|
||||||
lastRectInRootFrame = lastRectInRootFrame.ForceInside(endFrame->GetRectRelativeToSelf());
|
nsLayoutUtils::IsRectVisibleInScrollFrames(endFrame, lastRectInEndFrame);
|
||||||
nsRect firstRectInCanvasFrame = firstRectInRootFrame;
|
|
||||||
nsRect lastRectInCanvasFrame =lastRectInRootFrame;
|
nsRect firstRectInCanvasFrame = firstRectInStartFrame;
|
||||||
nsLayoutUtils::TransformRect(startFrame, rootFrame, firstRectInRootFrame);
|
nsRect lastRectInCanvasFrame = lastRectInEndFrame;
|
||||||
nsLayoutUtils::TransformRect(endFrame, rootFrame, lastRectInRootFrame);
|
|
||||||
nsLayoutUtils::TransformRect(startFrame, canvasFrame, firstRectInCanvasFrame);
|
nsLayoutUtils::TransformRect(startFrame, canvasFrame, firstRectInCanvasFrame);
|
||||||
nsLayoutUtils::TransformRect(endFrame, canvasFrame, lastRectInCanvasFrame);
|
nsLayoutUtils::TransformRect(endFrame, canvasFrame, lastRectInCanvasFrame);
|
||||||
|
|
||||||
firstRectInRootFrame.Inflate(AppUnitsPerCSSPixel(), 0);
|
SetStartFrameVisibility(startFrameVisible);
|
||||||
lastRectInRootFrame.Inflate(AppUnitsPerCSSPixel(), 0);
|
SetEndFrameVisibility(endFrameVisible);
|
||||||
|
|
||||||
nsAutoTArray<nsIFrame*, 16> hitFramesInFirstRect;
|
|
||||||
nsLayoutUtils::GetFramesForArea(rootFrame,
|
|
||||||
firstRectInRootFrame,
|
|
||||||
hitFramesInFirstRect,
|
|
||||||
nsLayoutUtils::IGNORE_PAINT_SUPPRESSION |
|
|
||||||
nsLayoutUtils::IGNORE_CROSS_DOC |
|
|
||||||
nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME);
|
|
||||||
|
|
||||||
nsAutoTArray<nsIFrame*, 16> hitFramesInLastRect;
|
|
||||||
nsLayoutUtils::GetFramesForArea(rootFrame,
|
|
||||||
lastRectInRootFrame,
|
|
||||||
hitFramesInLastRect,
|
|
||||||
nsLayoutUtils::IGNORE_PAINT_SUPPRESSION |
|
|
||||||
nsLayoutUtils::IGNORE_CROSS_DOC |
|
|
||||||
nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME);
|
|
||||||
|
|
||||||
SetStartFrameVisibility(hitFramesInFirstRect.Contains(startFrame));
|
|
||||||
SetEndFrameVisibility(hitFramesInLastRect.Contains(endFrame));
|
|
||||||
|
|
||||||
SetStartFramePos(firstRectInCanvasFrame.BottomLeft());
|
SetStartFramePos(firstRectInCanvasFrame.BottomLeft());
|
||||||
SetEndFramePos(lastRectInCanvasFrame.BottomRight());
|
SetEndFramePos(lastRectInCanvasFrame.BottomRight());
|
||||||
@ -936,7 +933,15 @@ SelectionCarets::GetFrameSelection()
|
|||||||
if (!focusFrame) {
|
if (!focusFrame) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return focusFrame->GetFrameSelection();
|
|
||||||
|
// Prevent us from touching the nsFrameSelection associated to other
|
||||||
|
// PresShell.
|
||||||
|
nsRefPtr<nsFrameSelection> fs = focusFrame->GetFrameSelection();
|
||||||
|
if (!fs || fs->GetShell() != mPresShell) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fs.forget();
|
||||||
} else {
|
} else {
|
||||||
return mPresShell->FrameSelection();
|
return mPresShell->FrameSelection();
|
||||||
}
|
}
|
||||||
@ -970,15 +975,14 @@ GetSelectionStates(int16_t aReason)
|
|||||||
return states;
|
return states;
|
||||||
}
|
}
|
||||||
|
|
||||||
static nsRect
|
nsRect
|
||||||
GetSelectionBoundingRect(Selection* aSel, nsIPresShell* aShell)
|
SelectionCarets::GetSelectionBoundingRect(Selection* aSel)
|
||||||
{
|
{
|
||||||
nsRect res;
|
nsRect res;
|
||||||
// Bounding client rect may be empty after calling GetBoundingClientRect
|
// Bounding client rect may be empty after calling GetBoundingClientRect
|
||||||
// when range is collapsed. So we get caret's rect when range is
|
// when range is collapsed. So we get caret's rect when range is
|
||||||
// collapsed.
|
// collapsed.
|
||||||
if (aSel->IsCollapsed()) {
|
if (aSel->IsCollapsed()) {
|
||||||
aShell->FlushPendingNotifications(Flush_Layout);
|
|
||||||
nsIFrame* frame = nsCaret::GetGeometry(aSel, &res);
|
nsIFrame* frame = nsCaret::GetGeometry(aSel, &res);
|
||||||
if (frame) {
|
if (frame) {
|
||||||
nsIFrame* relativeTo =
|
nsIFrame* relativeTo =
|
||||||
@ -1002,27 +1006,37 @@ GetSelectionBoundingRect(Selection* aSel, nsIPresShell* aShell)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
DispatchSelectionStateChangedEvent(nsIPresShell* aPresShell,
|
SelectionCarets::DispatchSelectionStateChangedEvent(Selection* aSelection,
|
||||||
nsISelection* aSel,
|
SelectionState aState)
|
||||||
const dom::Sequence<SelectionState>& aStates)
|
|
||||||
{
|
{
|
||||||
nsIDocument* doc = aPresShell->GetDocument();
|
dom::Sequence<SelectionState> state;
|
||||||
|
state.AppendElement(aState);
|
||||||
|
DispatchSelectionStateChangedEvent(aSelection, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SelectionCarets::DispatchSelectionStateChangedEvent(Selection* aSelection,
|
||||||
|
const Sequence<SelectionState>& aStates)
|
||||||
|
{
|
||||||
|
nsIDocument* doc = mPresShell->GetDocument();
|
||||||
|
|
||||||
MOZ_ASSERT(doc);
|
MOZ_ASSERT(doc);
|
||||||
|
|
||||||
SelectionStateChangedEventInit init;
|
SelectionStateChangedEventInit init;
|
||||||
init.mBubbles = true;
|
init.mBubbles = true;
|
||||||
|
|
||||||
if (aSel) {
|
if (aSelection) {
|
||||||
Selection* selection = static_cast<Selection*>(aSel);
|
// XXX: Do we need to flush layout?
|
||||||
nsRect rect = GetSelectionBoundingRect(selection, doc->GetShell());
|
mPresShell->FlushPendingNotifications(Flush_Layout);
|
||||||
|
nsRect rect = GetSelectionBoundingRect(aSelection);
|
||||||
nsRefPtr<DOMRect>domRect = new DOMRect(ToSupports(doc));
|
nsRefPtr<DOMRect>domRect = new DOMRect(ToSupports(doc));
|
||||||
|
|
||||||
domRect->SetLayoutRect(rect);
|
domRect->SetLayoutRect(rect);
|
||||||
init.mBoundingClientRect = domRect;
|
init.mBoundingClientRect = domRect;
|
||||||
|
init.mVisible = mSelectionVisibleInScrollFrames;
|
||||||
|
|
||||||
selection->Stringify(init.mSelectedText);
|
aSelection->Stringify(init.mSelectedText);
|
||||||
}
|
}
|
||||||
init.mStates = aStates;
|
init.mStates = aStates;
|
||||||
|
|
||||||
@ -1039,10 +1053,7 @@ void
|
|||||||
SelectionCarets::NotifyBlur()
|
SelectionCarets::NotifyBlur()
|
||||||
{
|
{
|
||||||
SetVisibility(false);
|
SetVisibility(false);
|
||||||
|
DispatchSelectionStateChangedEvent(nullptr, SelectionState::Blur);
|
||||||
dom::Sequence<SelectionState> state;
|
|
||||||
state.AppendElement(dom::SelectionState::Blur);
|
|
||||||
DispatchSelectionStateChangedEvent(mPresShell, nullptr, state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
@ -1059,7 +1070,8 @@ SelectionCarets::NotifySelectionChanged(nsIDOMDocument* aDoc,
|
|||||||
UpdateSelectionCarets();
|
UpdateSelectionCarets();
|
||||||
}
|
}
|
||||||
|
|
||||||
DispatchSelectionStateChangedEvent(mPresShell, aSel, GetSelectionStates(aReason));
|
DispatchSelectionStateChangedEvent(static_cast<Selection*>(aSel),
|
||||||
|
GetSelectionStates(aReason));
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1097,10 +1109,16 @@ SelectionCarets::AsyncPanZoomStarted(const mozilla::CSSIntPoint aScrollPos)
|
|||||||
void
|
void
|
||||||
SelectionCarets::AsyncPanZoomStopped(const mozilla::CSSIntPoint aScrollPos)
|
SelectionCarets::AsyncPanZoomStopped(const mozilla::CSSIntPoint aScrollPos)
|
||||||
{
|
{
|
||||||
|
SELECTIONCARETS_LOG("Update selection carets after APZ is stopped!");
|
||||||
UpdateSelectionCarets();
|
UpdateSelectionCarets();
|
||||||
|
|
||||||
|
// SelectionStateChangedEvent should be dispatched before ScrollViewChangeEvent.
|
||||||
|
DispatchSelectionStateChangedEvent(GetSelection(),
|
||||||
|
SelectionState::Updateposition);
|
||||||
|
|
||||||
SELECTIONCARETS_LOG("Dispatch scroll stopped with position x=%d, y=%d",
|
SELECTIONCARETS_LOG("Dispatch scroll stopped with position x=%d, y=%d",
|
||||||
aScrollPos.x, aScrollPos.y);
|
aScrollPos.x, aScrollPos.y);
|
||||||
|
|
||||||
DispatchScrollViewChangeEvent(mPresShell, dom::ScrollState::Stopped, aScrollPos);
|
DispatchScrollViewChangeEvent(mPresShell, dom::ScrollState::Stopped, aScrollPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1190,6 +1208,8 @@ SelectionCarets::FireScrollEnd(nsITimer* aTimer, void* aSelectionCarets)
|
|||||||
SELECTIONCARETS_LOG_STATIC("Update selection carets!");
|
SELECTIONCARETS_LOG_STATIC("Update selection carets!");
|
||||||
self->SetVisibility(true);
|
self->SetVisibility(true);
|
||||||
self->UpdateSelectionCarets();
|
self->UpdateSelectionCarets();
|
||||||
|
self->DispatchSelectionStateChangedEvent(self->GetSelection(),
|
||||||
|
SelectionState::Updateposition);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
@ -1198,6 +1218,9 @@ SelectionCarets::Reflow(DOMHighResTimeStamp aStart, DOMHighResTimeStamp aEnd)
|
|||||||
if (mVisible) {
|
if (mVisible) {
|
||||||
SELECTIONCARETS_LOG("Update selection carets after reflow!");
|
SELECTIONCARETS_LOG("Update selection carets after reflow!");
|
||||||
UpdateSelectionCarets();
|
UpdateSelectionCarets();
|
||||||
|
|
||||||
|
DispatchSelectionStateChangedEvent(GetSelection(),
|
||||||
|
SelectionState::Updateposition);
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "nsWeakPtr.h"
|
#include "nsWeakPtr.h"
|
||||||
#include "nsWeakReference.h"
|
#include "nsWeakReference.h"
|
||||||
#include "Units.h"
|
#include "Units.h"
|
||||||
|
#include "mozilla/dom/SelectionStateChangedEvent.h"
|
||||||
#include "mozilla/EventForwards.h"
|
#include "mozilla/EventForwards.h"
|
||||||
#include "mozilla/WeakPtr.h"
|
#include "mozilla/WeakPtr.h"
|
||||||
|
|
||||||
@ -198,10 +199,15 @@ private:
|
|||||||
*/
|
*/
|
||||||
void SetTilted(bool aIsTilt);
|
void SetTilted(bool aIsTilt);
|
||||||
|
|
||||||
// Utility function
|
// Utility functions
|
||||||
dom::Selection* GetSelection();
|
dom::Selection* GetSelection();
|
||||||
already_AddRefed<nsFrameSelection> GetFrameSelection();
|
already_AddRefed<nsFrameSelection> GetFrameSelection();
|
||||||
nsIContent* GetFocusedContent();
|
nsIContent* GetFocusedContent();
|
||||||
|
void DispatchSelectionStateChangedEvent(dom::Selection* aSelection,
|
||||||
|
dom::SelectionState aState);
|
||||||
|
void DispatchSelectionStateChangedEvent(dom::Selection* aSelection,
|
||||||
|
const dom::Sequence<dom::SelectionState>& aStates);
|
||||||
|
nsRect GetSelectionBoundingRect(dom::Selection* aSel);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detecting long tap using timer
|
* Detecting long tap using timer
|
||||||
@ -242,6 +248,7 @@ private:
|
|||||||
|
|
||||||
bool mEndCaretVisible;
|
bool mEndCaretVisible;
|
||||||
bool mStartCaretVisible;
|
bool mStartCaretVisible;
|
||||||
|
bool mSelectionVisibleInScrollFrames;
|
||||||
bool mVisible;
|
bool mVisible;
|
||||||
|
|
||||||
// Preference
|
// Preference
|
||||||
|
@ -458,7 +458,7 @@ TouchCaret::IsDisplayable()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsCaretShowingInScrollFrame()) {
|
if (!nsLayoutUtils::IsRectVisibleInScrollFrames(focusFrame, focusRect)) {
|
||||||
TOUCHCARET_LOG("Caret does not show in the scrollable frame!");
|
TOUCHCARET_LOG("Caret does not show in the scrollable frame!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -494,37 +494,6 @@ TouchCaret::GetTouchCaretPosition()
|
|||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
TouchCaret::IsCaretShowingInScrollFrame()
|
|
||||||
{
|
|
||||||
nsRect caretRect;
|
|
||||||
nsIFrame* caretFrame = GetCaretFocusFrame(&caretRect);
|
|
||||||
|
|
||||||
nsIFrame* closestScrollFrame =
|
|
||||||
nsLayoutUtils::GetClosestFrameOfType(caretFrame, nsGkAtoms::scrollFrame);
|
|
||||||
|
|
||||||
while (closestScrollFrame) {
|
|
||||||
nsIScrollableFrame* sf = do_QueryFrame(closestScrollFrame);
|
|
||||||
nsRect scrollPortRect = sf->GetScrollPortRect();
|
|
||||||
|
|
||||||
nsRect caretRectRelativeToScrollFrame = caretRect;
|
|
||||||
nsLayoutUtils::TransformRect(caretFrame, closestScrollFrame,
|
|
||||||
caretRectRelativeToScrollFrame);
|
|
||||||
|
|
||||||
// Check whether nsCaret appears in the scroll frame or not.
|
|
||||||
if (!scrollPortRect.Intersects(caretRectRelativeToScrollFrame)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get next ancestor scroll frame.
|
|
||||||
closestScrollFrame =
|
|
||||||
nsLayoutUtils::GetClosestFrameOfType(closestScrollFrame->GetParent(),
|
|
||||||
nsGkAtoms::scrollFrame);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsPoint
|
nsPoint
|
||||||
TouchCaret::ClampPositionToScrollFrame(const nsPoint& aPosition)
|
TouchCaret::ClampPositionToScrollFrame(const nsPoint& aPosition)
|
||||||
{
|
{
|
||||||
|
@ -117,12 +117,6 @@ private:
|
|||||||
*/
|
*/
|
||||||
nsPoint GetTouchCaretPosition();
|
nsPoint GetTouchCaretPosition();
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether nsCaret shows in the scroll frame boundary, i.e. its rect
|
|
||||||
* intersects scroll frame's rect.
|
|
||||||
*/
|
|
||||||
bool IsCaretShowingInScrollFrame();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clamp the position of the touch caret to the scroll frame boundary.
|
* Clamp the position of the touch caret to the scroll frame boundary.
|
||||||
* The returned point is relative to the canvas frame.
|
* The returned point is relative to the canvas frame.
|
||||||
|
@ -2295,8 +2295,8 @@ nsLayoutUtils::GetTransformToAncestorScale(nsIFrame* aFrame)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static nsIFrame*
|
nsIFrame*
|
||||||
FindNearestCommonAncestorFrame(nsIFrame* aFrame1, nsIFrame* aFrame2)
|
nsLayoutUtils::FindNearestCommonAncestorFrame(nsIFrame* aFrame1, nsIFrame* aFrame2)
|
||||||
{
|
{
|
||||||
nsAutoTArray<nsIFrame*,100> ancestors1;
|
nsAutoTArray<nsIFrame*,100> ancestors1;
|
||||||
nsAutoTArray<nsIFrame*,100> ancestors2;
|
nsAutoTArray<nsIFrame*,100> ancestors2;
|
||||||
@ -2452,6 +2452,34 @@ nsLayoutUtils::ContainsPoint(const nsRect& aRect, const nsPoint& aPoint,
|
|||||||
return rect.Contains(aPoint);
|
return rect.Contains(aPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsLayoutUtils::IsRectVisibleInScrollFrames(nsIFrame* aFrame, const nsRect& aRect)
|
||||||
|
{
|
||||||
|
nsIFrame* closestScrollFrame =
|
||||||
|
nsLayoutUtils::GetClosestFrameOfType(aFrame, nsGkAtoms::scrollFrame);
|
||||||
|
|
||||||
|
while (closestScrollFrame) {
|
||||||
|
nsIScrollableFrame* sf = do_QueryFrame(closestScrollFrame);
|
||||||
|
nsRect scrollPortRect = sf->GetScrollPortRect();
|
||||||
|
|
||||||
|
nsRect rectRelativeToScrollFrame = aRect;
|
||||||
|
nsLayoutUtils::TransformRect(aFrame, closestScrollFrame,
|
||||||
|
rectRelativeToScrollFrame);
|
||||||
|
|
||||||
|
// Check whether aRect is visible in the scroll frame or not.
|
||||||
|
if (!scrollPortRect.Intersects(rectRelativeToScrollFrame)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get next ancestor scroll frame.
|
||||||
|
closestScrollFrame =
|
||||||
|
nsLayoutUtils::GetClosestFrameOfType(closestScrollFrame->GetParent(),
|
||||||
|
nsGkAtoms::scrollFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
nsLayoutUtils::GetLayerTransformForFrame(nsIFrame* aFrame,
|
nsLayoutUtils::GetLayerTransformForFrame(nsIFrame* aFrame,
|
||||||
Matrix4x4* aTransform)
|
Matrix4x4* aTransform)
|
||||||
|
@ -794,6 +794,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
static gfxSize GetTransformToAncestorScale(nsIFrame* aFrame);
|
static gfxSize GetTransformToAncestorScale(nsIFrame* aFrame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the nearest common ancestor frame for aFrame1 and aFrame2. The
|
||||||
|
* ancestor frame could be cross-doc.
|
||||||
|
*/
|
||||||
|
static nsIFrame* FindNearestCommonAncestorFrame(nsIFrame* aFrame1,
|
||||||
|
nsIFrame* aFrame2);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transforms a list of CSSPoints from aFromFrame to aToFrame, taking into
|
* Transforms a list of CSSPoints from aFromFrame to aToFrame, taking into
|
||||||
* account all relevant transformations on the frames up to (but excluding)
|
* account all relevant transformations on the frames up to (but excluding)
|
||||||
@ -841,6 +848,13 @@ public:
|
|||||||
static bool ContainsPoint(const nsRect& aRect, const nsPoint& aPoint,
|
static bool ContainsPoint(const nsRect& aRect, const nsPoint& aPoint,
|
||||||
nscoord aInflateSize);
|
nscoord aInflateSize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether aRect is visible in the boundary of the scroll frames
|
||||||
|
* boundary.
|
||||||
|
*/
|
||||||
|
static bool IsRectVisibleInScrollFrames(nsIFrame* aFrame,
|
||||||
|
const nsRect& aRect);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if a "layer transform" could be computed for aFrame,
|
* Return true if a "layer transform" could be computed for aFrame,
|
||||||
* and optionally return the computed transform. The returned
|
* and optionally return the computed transform. The returned
|
||||||
|
@ -4390,7 +4390,6 @@ pref("beacon.enabled", true);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Camera prefs
|
// Camera prefs
|
||||||
pref("camera.control.autofocus_moving_callback.enabled", true);
|
|
||||||
pref("camera.control.face_detection.enabled", true);
|
pref("camera.control.face_detection.enabled", true);
|
||||||
|
|
||||||
// Fetch API.
|
// Fetch API.
|
||||||
|
@ -50,10 +50,13 @@ config = {
|
|||||||
"--testvars=%(testvars)s",
|
"--testvars=%(testvars)s",
|
||||||
"--profile=%(profile)s",
|
"--profile=%(profile)s",
|
||||||
"--symbols-path=%(symbols_path)s",
|
"--symbols-path=%(symbols_path)s",
|
||||||
|
"--gecko-log=%(gecko_log)s",
|
||||||
"--xml-output=%(xml_output)s",
|
"--xml-output=%(xml_output)s",
|
||||||
"--html-output=%(html_output)s",
|
"--html-output=%(html_output)s",
|
||||||
"--log-raw=%(raw_log_file)s",
|
"--log-raw=%(raw_log_file)s",
|
||||||
"--binary=%(binary)s",
|
"--binary=%(binary)s",
|
||||||
"--address=%(address)s",
|
"--address=%(address)s",
|
||||||
|
"--total-chunks=%(total_chunks)s",
|
||||||
|
"--this-chunk=%(this_chunk)s",
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user