--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -10,25 +10,25 @@
<!--original fetch url was git://codeaurora.org/-->
<remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
- <project name="gaia" path="gaia" remote="mozillaorg" revision="a8a6eed2ba9d66239aac789b9ee4900f911c73cb"/>
+ <project name="gaia" path="gaia" remote="mozillaorg" revision="e58fe34a63a85f51da0d7e35d3b6af290ba0662b"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
- <project name="apitrace" path="external/apitrace" remote="apitrace" revision="4bc3cfde42118081268690217172d7b577867c65"/>
+ <project name="apitrace" path="external/apitrace" remote="apitrace" revision="693382a5630079f9debfe55c59f8197d432f47ff"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
<project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
<project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/>
<project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/>
<project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="83760d213fb3bec7b4117d266fcfbf6fe2ba14ab"/>
<project name="device/common" path="device/common" revision="6a2995683de147791e516aae2ccb31fdfbe2ad30"/>
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,23 +14,23 @@
<!--original fetch url was git://github.com/apitrace/-->
<remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
<default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
<!-- Gonk specific things and forks -->
<project name="platform_build" path="build" remote="b2g" revision="84923f1940625c47ff4c1fdf01b10fde3b7d909e">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
- <project name="gaia.git" path="gaia" remote="mozillaorg" revision="a8a6eed2ba9d66239aac789b9ee4900f911c73cb"/>
+ <project name="gaia.git" path="gaia" remote="mozillaorg" revision="e58fe34a63a85f51da0d7e35d3b6af290ba0662b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c058843242068d0df7c107e09da31b53d2e08fa6"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
- <project name="apitrace" path="external/apitrace" remote="apitrace" revision="4bc3cfde42118081268690217172d7b577867c65"/>
+ <project name="apitrace" path="external/apitrace" remote="apitrace" revision="693382a5630079f9debfe55c59f8197d432f47ff"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
<project name="platform/bootable/recovery" path="bootable/recovery" revision="425f8b5fadf5889834c5acd27d23c9e0b2129c28"/>
<project name="device/common" path="device/common" revision="42b808b7e93d0619286ae8e59110b176b7732389"/>
<project name="device/sample" path="device/sample" revision="237bd668d0f114d801a8d6455ef5e02cc3577587"/>
<project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
<project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="52a1a862a8bac319652b8f82d9541ba40bfa45ce"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,20 +12,20 @@
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="8986df0f82e15ac2798df0b6c2ee3435400677ac">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
- <project name="gaia" path="gaia" remote="mozillaorg" revision="a8a6eed2ba9d66239aac789b9ee4900f911c73cb"/>
+ <project name="gaia" path="gaia" remote="mozillaorg" revision="e58fe34a63a85f51da0d7e35d3b6af290ba0662b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
- <project name="apitrace" path="external/apitrace" remote="apitrace" revision="4bc3cfde42118081268690217172d7b577867c65"/>
+ <project name="apitrace" path="external/apitrace" remote="apitrace" revision="693382a5630079f9debfe55c59f8197d432f47ff"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
<project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
<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="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
<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="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
<project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,25 +10,25 @@
<!--original fetch url was git://codeaurora.org/-->
<remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
- <project name="gaia" path="gaia" remote="mozillaorg" revision="a8a6eed2ba9d66239aac789b9ee4900f911c73cb"/>
+ <project name="gaia" path="gaia" remote="mozillaorg" revision="e58fe34a63a85f51da0d7e35d3b6af290ba0662b"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
- <project name="apitrace" path="external/apitrace" remote="apitrace" revision="4bc3cfde42118081268690217172d7b577867c65"/>
+ <project name="apitrace" path="external/apitrace" remote="apitrace" revision="693382a5630079f9debfe55c59f8197d432f47ff"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>
<project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="1950e4760fa14688b83cdbb5acaa1af9f82ef434"/>
<project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="ac6eb97a37035c09fb5ede0852f0881e9aadf9ad"/>
<project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="737f591c5f95477148d26602c7be56cbea0cdeb9"/>
<project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="51da9b1981be481b92a59a826d4d78dc73d0989a"/>
<project name="device/common" path="device/common" revision="798a3664597e6041985feab9aef42e98d458bc3d"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,23 +14,23 @@
<!--original fetch url was git://github.com/apitrace/-->
<remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
<default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
<!-- Gonk specific things and forks -->
<project name="platform_build" path="build" remote="b2g" revision="84923f1940625c47ff4c1fdf01b10fde3b7d909e">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
- <project name="gaia.git" path="gaia" remote="mozillaorg" revision="a8a6eed2ba9d66239aac789b9ee4900f911c73cb"/>
+ <project name="gaia.git" path="gaia" remote="mozillaorg" revision="e58fe34a63a85f51da0d7e35d3b6af290ba0662b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c058843242068d0df7c107e09da31b53d2e08fa6"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
- <project name="apitrace" path="external/apitrace" remote="apitrace" revision="4bc3cfde42118081268690217172d7b577867c65"/>
+ <project name="apitrace" path="external/apitrace" remote="apitrace" revision="693382a5630079f9debfe55c59f8197d432f47ff"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
<project name="platform/bootable/recovery" path="bootable/recovery" revision="425f8b5fadf5889834c5acd27d23c9e0b2129c28"/>
<project name="device/common" path="device/common" revision="42b808b7e93d0619286ae8e59110b176b7732389"/>
<project name="device/sample" path="device/sample" revision="237bd668d0f114d801a8d6455ef5e02cc3577587"/>
<project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
<project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="52a1a862a8bac319652b8f82d9541ba40bfa45ce"/>
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -10,25 +10,25 @@
<!--original fetch url was git://codeaurora.org/-->
<remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
- <project name="gaia" path="gaia" remote="mozillaorg" revision="a8a6eed2ba9d66239aac789b9ee4900f911c73cb"/>
+ <project name="gaia" path="gaia" remote="mozillaorg" revision="e58fe34a63a85f51da0d7e35d3b6af290ba0662b"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
- <project name="apitrace" path="external/apitrace" remote="apitrace" revision="4bc3cfde42118081268690217172d7b577867c65"/>
+ <project name="apitrace" path="external/apitrace" remote="apitrace" revision="693382a5630079f9debfe55c59f8197d432f47ff"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
<project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
<project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/>
<project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/>
<project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="a32003194f707f66a2d8cdb913ed1869f1926c5d"/>
<project name="device/common" path="device/common" revision="96d4d2006c4fcb2f19a3fa47ab10cb409faa017b"/>
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -12,20 +12,20 @@
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="8986df0f82e15ac2798df0b6c2ee3435400677ac">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
- <project name="gaia" path="gaia" remote="mozillaorg" revision="a8a6eed2ba9d66239aac789b9ee4900f911c73cb"/>
+ <project name="gaia" path="gaia" remote="mozillaorg" revision="e58fe34a63a85f51da0d7e35d3b6af290ba0662b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
- <project name="apitrace" path="external/apitrace" remote="apitrace" revision="4bc3cfde42118081268690217172d7b577867c65"/>
+ <project name="apitrace" path="external/apitrace" remote="apitrace" revision="693382a5630079f9debfe55c59f8197d432f47ff"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="e95b4ce22c825da44d14299e1190ea39a5260bde"/>
<project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="471afab478649078ad7c75ec6b252481a59e19b8"/>
<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,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
{
"git": {
"git_revision": "",
"remote": "",
"branch": ""
},
- "revision": "736a08de0dd46c283137a289a484a6b404cb0dd1",
+ "revision": "3ff9cbe0526a865d1d9abec3e8138ceb839464a0",
"repo_path": "/integration/gaia-central"
}
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -12,22 +12,22 @@
<!--original fetch url was git://github.com/apitrace/-->
<remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
<default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
<!-- Gonk specific things and forks -->
<project name="platform_build" path="build" remote="b2g" revision="84923f1940625c47ff4c1fdf01b10fde3b7d909e">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
- <project name="gaia.git" path="gaia" remote="mozillaorg" revision="a8a6eed2ba9d66239aac789b9ee4900f911c73cb"/>
+ <project name="gaia.git" path="gaia" remote="mozillaorg" revision="e58fe34a63a85f51da0d7e35d3b6af290ba0662b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
- <project name="apitrace" path="external/apitrace" remote="apitrace" revision="4bc3cfde42118081268690217172d7b577867c65"/>
+ <project name="apitrace" path="external/apitrace" remote="apitrace" revision="693382a5630079f9debfe55c59f8197d432f47ff"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
<project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
<project name="platform/bootable/recovery" path="bootable/recovery" revision="746bc48f34f5060f90801925dcdd964030c1ab6d"/>
<project name="platform/development" path="development" revision="2460485184bc8535440bb63876d4e63ec1b4770c"/>
<project name="device/common" path="device/common" revision="0dcc1e03659db33b77392529466f9eb685cdd3c7"/>
<project name="device/sample" path="device/sample" revision="68b1cb978a20806176123b959cb05d4fa8adaea4"/>
<project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -10,17 +10,17 @@
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
<!-- Gonk specific things and forks -->
<project name="platform_build" path="build" remote="b2g" revision="84923f1940625c47ff4c1fdf01b10fde3b7d909e">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
- <project name="gaia.git" path="gaia" remote="mozillaorg" revision="a8a6eed2ba9d66239aac789b9ee4900f911c73cb"/>
+ <project name="gaia.git" path="gaia" remote="mozillaorg" revision="e58fe34a63a85f51da0d7e35d3b6af290ba0662b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
<project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -12,20 +12,20 @@
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="8986df0f82e15ac2798df0b6c2ee3435400677ac">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
- <project name="gaia" path="gaia" remote="mozillaorg" revision="a8a6eed2ba9d66239aac789b9ee4900f911c73cb"/>
+ <project name="gaia" path="gaia" remote="mozillaorg" revision="e58fe34a63a85f51da0d7e35d3b6af290ba0662b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
- <project name="apitrace" path="external/apitrace" remote="apitrace" revision="4bc3cfde42118081268690217172d7b577867c65"/>
+ <project name="apitrace" path="external/apitrace" remote="apitrace" revision="693382a5630079f9debfe55c59f8197d432f47ff"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
<project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
<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="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
<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="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
<project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -12,22 +12,22 @@
<!--original fetch url was git://github.com/apitrace/-->
<remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
<default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
<!-- Gonk specific things and forks -->
<project name="platform_build" path="build" remote="b2g" revision="84923f1940625c47ff4c1fdf01b10fde3b7d909e">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
- <project name="gaia.git" path="gaia" remote="mozillaorg" revision="a8a6eed2ba9d66239aac789b9ee4900f911c73cb"/>
+ <project name="gaia.git" path="gaia" remote="mozillaorg" revision="e58fe34a63a85f51da0d7e35d3b6af290ba0662b"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
- <project name="apitrace" path="external/apitrace" remote="apitrace" revision="4bc3cfde42118081268690217172d7b577867c65"/>
+ <project name="apitrace" path="external/apitrace" remote="apitrace" revision="693382a5630079f9debfe55c59f8197d432f47ff"/>
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
<project name="platform/bionic" path="bionic" revision="cd5dfce80bc3f0139a56b58aca633202ccaee7f8"/>
<project name="platform/bootable/recovery" path="bootable/recovery" revision="e0a9ac010df3afaa47ba107192c05ac8b5516435"/>
<project name="platform/development" path="development" revision="a384622f5fcb1d2bebb9102591ff7ae91fe8ed2d"/>
<project name="device/common" path="device/common" revision="7c65ea240157763b8ded6154a17d3c033167afb7"/>
<project name="device/sample" path="device/sample" revision="c328f3d4409db801628861baa8d279fb8855892f"/>
--- a/content/base/public/nsHostObjectProtocolHandler.h
+++ b/content/base/public/nsHostObjectProtocolHandler.h
@@ -13,20 +13,20 @@
#define BLOBURI_SCHEME "blob"
#define MEDIASTREAMURI_SCHEME "mediastream"
#define MEDIASOURCEURI_SCHEME "mediasource"
#define FONTTABLEURI_SCHEME "moz-fonttable"
#define RTSPURI_SCHEME "rtsp"
class nsIDOMBlob;
-class nsIDOMMediaStream;
class nsIPrincipal;
namespace mozilla {
+class DOMMediaStream;
namespace dom {
class MediaSource;
}
}
class nsHostObjectProtocolHandler : public nsIProtocolHandler
{
public:
@@ -117,17 +117,17 @@ inline bool IsFontTableURI(nsIURI* aUri)
bool isFont;
return NS_SUCCEEDED(aUri->SchemeIs(FONTTABLEURI_SCHEME, &isFont)) && isFont;
}
extern nsresult
NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream);
extern nsresult
-NS_GetStreamForMediaStreamURI(nsIURI* aURI, nsIDOMMediaStream** aStream);
+NS_GetStreamForMediaStreamURI(nsIURI* aURI, mozilla::DOMMediaStream** aStream);
extern nsresult
NS_GetSourceForMediaSourceURI(nsIURI* aURI, mozilla::dom::MediaSource** aSource);
#define NS_BLOBPROTOCOLHANDLER_CID \
{ 0xb43964aa, 0xa078, 0x44b2, \
{ 0xb0, 0x6b, 0xfd, 0x4d, 0x1b, 0x17, 0x2e, 0x66 } }
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -694,16 +694,17 @@ GK_ATOM(onclick, "onclick")
GK_ATOM(onclirmodechange, "onclirmodechange")
GK_ATOM(onclose, "onclose")
GK_ATOM(oncommand, "oncommand")
GK_ATOM(oncommandupdate, "oncommandupdate")
GK_ATOM(oncomplete, "oncomplete")
GK_ATOM(oncompositionend, "oncompositionend")
GK_ATOM(oncompositionstart, "oncompositionstart")
GK_ATOM(oncompositionupdate, "oncompositionupdate")
+GK_ATOM(onconfigurationchange, "onconfigurationchange")
GK_ATOM(onconnect, "onconnect")
GK_ATOM(onconnected, "onconnected")
GK_ATOM(onconnecting, "onconnecting")
GK_ATOM(oncontextmenu, "oncontextmenu")
GK_ATOM(oncopy, "oncopy")
GK_ATOM(oncut, "oncut")
GK_ATOM(ondatachange, "ondatachange")
GK_ATOM(ondataerror, "ondataerror")
@@ -743,16 +744,17 @@ GK_ATOM(ondragleave, "ondragleave")
GK_ATOM(ondragover, "ondragover")
GK_ATOM(ondragstart, "ondragstart")
GK_ATOM(ondrop, "ondrop")
GK_ATOM(onenabled, "onenabled")
GK_ATOM(onenterpincodereq, "onenterpincodereq")
GK_ATOM(onemergencycbmodechange, "onemergencycbmodechange")
GK_ATOM(onerror, "onerror")
GK_ATOM(onevicted, "onevicted")
+GK_ATOM(onfacesdetected, "onfacesdetected")
GK_ATOM(onfailed, "onfailed")
GK_ATOM(onfetch, "onfetch")
GK_ATOM(onfocus, "onfocus")
GK_ATOM(onfrequencychange, "onfrequencychange")
GK_ATOM(onspeakerforcedchange, "onspeakerforcedchange")
GK_ATOM(onget, "onget")
GK_ATOM(ongroupchange, "ongroupchange")
GK_ATOM(onhashchange, "onhashchange")
@@ -812,30 +814,33 @@ GK_ATOM(onpagehide, "onpagehide")
GK_ATOM(onpageshow, "onpageshow")
GK_ATOM(onpaint, "onpaint")
GK_ATOM(onpairedstatuschanged, "onpairedstatuschanged")
GK_ATOM(onpairingconfirmationreq, "onpairingconfirmationreq")
GK_ATOM(onpairingconsentreq, "onpairingconsentreq")
GK_ATOM(onpaste, "onpaste")
GK_ATOM(onpendingchange, "onpendingchange")
GK_ATOM(onpichange, "onpichange")
+GK_ATOM(onpicture, "onpicture")
GK_ATOM(onpopuphidden, "onpopuphidden")
GK_ATOM(onpopuphiding, "onpopuphiding")
GK_ATOM(onpopupshowing, "onpopupshowing")
GK_ATOM(onpopupshown, "onpopupshown")
+GK_ATOM(onpreviewstatechange, "onpreviewstatechange")
GK_ATOM(onpschange, "onpschange")
GK_ATOM(onptychange, "onptychange")
GK_ATOM(onradiostatechange, "onradiostatechange")
GK_ATOM(onrdsdisabled, "onrdsdisabled")
GK_ATOM(onrdsenabled, "onrdsenabled")
GK_ATOM(onreaderror, "onreaderror")
GK_ATOM(onreadsuccess, "onreadsuccess")
GK_ATOM(onready, "onready")
GK_ATOM(onreadystatechange, "onreadystatechange")
GK_ATOM(onreceived, "onreceived")
+GK_ATOM(onrecorderstatechange, "onrecorderstatechange")
GK_ATOM(onremoteheld, "onremoteheld")
GK_ATOM(onremoteresumed, "onremoteresumed")
GK_ATOM(onresourcetimingbufferfull, "onresourcetimingbufferfull")
GK_ATOM(onretrieving, "onretrieving")
GK_ATOM(onRequest, "onRequest")
GK_ATOM(onrequestmediaplaystatus, "onrequestmediaplaystatus")
GK_ATOM(onreset, "onreset")
GK_ATOM(onresuming, "onresuming")
@@ -843,16 +848,17 @@ GK_ATOM(onresize, "onresize")
GK_ATOM(onrtchange, "onrtchange")
GK_ATOM(onscostatuschanged, "onscostatuschanged")
GK_ATOM(onscroll, "onscroll")
GK_ATOM(onselect, "onselect")
GK_ATOM(onsending, "onsending")
GK_ATOM(onsent, "onsent")
GK_ATOM(onset, "onset")
GK_ATOM(onshow, "onshow")
+GK_ATOM(onshutter, "onshutter")
GK_ATOM(onstatechange, "onstatechange")
GK_ATOM(onstatuschanged, "onstatuschanged")
GK_ATOM(onstkcommand, "onstkcommand")
GK_ATOM(onstksessionend, "onstksessionend")
GK_ATOM(onsubmit, "onsubmit")
GK_ATOM(onsuccess, "onsuccess")
GK_ATOM(ontypechange, "ontypechange")
GK_ATOM(ontext, "ontext")
--- a/content/base/src/nsHostObjectProtocolHandler.cpp
+++ b/content/base/src/nsHostObjectProtocolHandler.cpp
@@ -6,30 +6,30 @@
#include "nsHostObjectProtocolHandler.h"
#include "nsHostObjectURI.h"
#include "nsError.h"
#include "nsClassHashtable.h"
#include "nsNetUtil.h"
#include "nsIPrincipal.h"
#include "nsDOMFile.h"
-#include "nsIDOMMediaStream.h"
+#include "DOMMediaStream.h"
#include "mozilla/dom/MediaSource.h"
#include "nsIMemoryReporter.h"
#include "mozilla/Preferences.h"
#include "mozilla/LoadInfo.h"
using mozilla::dom::DOMFileImpl;
using mozilla::LoadInfo;
// -----------------------------------------------------------------------
// Hash table
struct DataInfo
{
- // mObject is expected to be an nsIDOMBlob, nsIDOMMediaStream, or MediaSource
+ // mObject is expected to be an nsIDOMBlob, DOMMediaStream, or MediaSource
nsCOMPtr<nsISupports> mObject;
nsCOMPtr<nsIPrincipal> mPrincipal;
nsCString mStack;
};
static nsClassHashtable<nsCStringHashKey, DataInfo>* gDataTable;
// Memory reporting for the hash table.
@@ -600,30 +600,22 @@ NS_GetStreamForBlobURI(nsIURI* aURI, nsI
return NS_ERROR_DOM_BAD_URI;
}
DOMFileImpl* blob = static_cast<DOMFileImpl*>(blobImpl.get());
return blob->GetInternalStream(aStream);
}
nsresult
-NS_GetStreamForMediaStreamURI(nsIURI* aURI, nsIDOMMediaStream** aStream)
+NS_GetStreamForMediaStreamURI(nsIURI* aURI, mozilla::DOMMediaStream** aStream)
{
NS_ASSERTION(IsMediaStreamURI(aURI), "Only call this with mediastream URIs");
*aStream = nullptr;
-
- nsCOMPtr<nsIDOMMediaStream> stream = do_QueryInterface(GetDataObject(aURI));
- if (!stream) {
- return NS_ERROR_DOM_BAD_URI;
- }
-
- *aStream = stream;
- NS_ADDREF(*aStream);
- return NS_OK;
+ return CallQueryInterface(GetDataObject(aURI), aStream);
}
NS_IMETHODIMP
nsFontTableProtocolHandler::NewURI(const nsACString& aSpec,
const char *aCharset,
nsIURI *aBaseURI,
nsIURI **aResult)
{
--- a/content/html/content/public/HTMLMediaElement.h
+++ b/content/html/content/public/HTMLMediaElement.h
@@ -515,16 +515,17 @@ public:
void SetMozIsCasting(bool aShow)
{
mIsCasting = aShow;
}
already_AddRefed<DOMMediaStream> GetMozSrcObject() const;
void SetMozSrcObject(DOMMediaStream& aValue);
+ void SetMozSrcObject(DOMMediaStream* aValue);
bool MozPreservesPitch() const
{
return mPreservesPitch;
}
// XPCOM MozPreservesPitch() is OK
--- a/content/html/content/src/HTMLMediaElement.cpp
+++ b/content/html/content/src/HTMLMediaElement.cpp
@@ -504,37 +504,27 @@ already_AddRefed<DOMMediaStream>
HTMLMediaElement::GetMozSrcObject() const
{
NS_ASSERTION(!mSrcAttrStream || mSrcAttrStream->GetStream(),
"MediaStream should have been set up properly");
nsRefPtr<DOMMediaStream> stream = mSrcAttrStream;
return stream.forget();
}
-NS_IMETHODIMP
-HTMLMediaElement::GetMozSrcObject(nsIDOMMediaStream** aStream)
-{
- nsRefPtr<DOMMediaStream> stream = GetMozSrcObject();
- stream.forget(aStream);
- return NS_OK;
-}
-
void
HTMLMediaElement::SetMozSrcObject(DOMMediaStream& aValue)
{
mSrcAttrStream = &aValue;
Load();
}
-NS_IMETHODIMP
-HTMLMediaElement::SetMozSrcObject(nsIDOMMediaStream* aStream)
+void
+HTMLMediaElement::SetMozSrcObject(DOMMediaStream* aValue)
{
- DOMMediaStream* stream = static_cast<DOMMediaStream*>(aStream);
- SetMozSrcObject(*stream);
- return NS_OK;
+ SetMozSrcObject(*aValue);
}
/* readonly attribute nsIDOMHTMLMediaElement mozAutoplayEnabled; */
NS_IMETHODIMP HTMLMediaElement::GetMozAutoplayEnabled(bool *aAutoplayEnabled)
{
*aAutoplayEnabled = mAutoplayEnabled;
return NS_OK;
@@ -1143,27 +1133,27 @@ nsresult HTMLMediaElement::LoadResource(
if (other && other->mDecoder) {
// Clone it.
nsresult rv = InitializeDecoderAsClone(other->mDecoder);
if (NS_SUCCEEDED(rv))
return rv;
}
if (IsMediaStreamURI(mLoadingSrc)) {
- nsCOMPtr<nsIDOMMediaStream> stream;
+ nsRefPtr<DOMMediaStream> stream;
rv = NS_GetStreamForMediaStreamURI(mLoadingSrc, getter_AddRefs(stream));
if (NS_FAILED(rv)) {
nsCString specUTF8;
mLoadingSrc->GetSpec(specUTF8);
NS_ConvertUTF8toUTF16 spec(specUTF8);
const char16_t* params[] = { spec.get() };
ReportLoadError("MediaLoadInvalidURI", params, ArrayLength(params));
return rv;
}
- SetupSrcMediaStreamPlayback(static_cast<DOMMediaStream*>(stream.get()));
+ SetupSrcMediaStreamPlayback(stream);
return NS_OK;
}
if (IsMediaSourceURI(mLoadingSrc)) {
nsRefPtr<MediaSource> source;
rv = NS_GetSourceForMediaSourceURI(mLoadingSrc, getter_AddRefs(source));
if (NS_FAILED(rv)) {
nsCString specUTF8;
@@ -1872,42 +1862,28 @@ HTMLMediaElement::MozCaptureStream(Error
if (!stream) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
return stream.forget();
}
-NS_IMETHODIMP HTMLMediaElement::MozCaptureStream(nsIDOMMediaStream** aStream)
-{
- ErrorResult rv;
- *aStream = MozCaptureStream(rv).take();
- return rv.ErrorCode();
-}
-
already_AddRefed<DOMMediaStream>
HTMLMediaElement::MozCaptureStreamUntilEnded(ErrorResult& aRv)
{
nsRefPtr<DOMMediaStream> stream = CaptureStreamInternal(true);
if (!stream) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
return stream.forget();
}
-NS_IMETHODIMP HTMLMediaElement::MozCaptureStreamUntilEnded(nsIDOMMediaStream** aStream)
-{
- ErrorResult rv;
- *aStream = MozCaptureStreamUntilEnded(rv).take();
- return rv.ErrorCode();
-}
-
NS_IMETHODIMP HTMLMediaElement::GetMozAudioCaptured(bool* aCaptured)
{
*aCaptured = MozAudioCaptured();
return NS_OK;
}
class MediaElementSetForURI : public nsURIHashKey {
public:
--- a/content/html/content/test/test_ignoreuserfocus.html
+++ b/content/html/content/test/test_ignoreuserfocus.html
@@ -135,20 +135,23 @@
document.body.appendChild(witness);
document.body.appendChild(iframe);
document.body.appendChild(witness2);
iframe.setAttribute("src", "file_ignoreuserfocus.html");
}
addEventListener("load", function() {
- SpecialPowers.addPermission("browser", true, document);
- SpecialPowers.pushPrefEnv({
- "set": [
- ["dom.mozBrowserFramesEnabled", true]
- ]
- }, function() {
- SimpleTest.waitForFocus(runTest);
- });
+ SpecialPowers.pushPermissions(
+ [{'type': 'browser', 'allow': true, 'context': document}],
+ function() {
+ SpecialPowers.pushPrefEnv({
+ "set": [
+ ["dom.mozBrowserFramesEnabled", true]
+ ]
+ }, function() {
+ SimpleTest.waitForFocus(runTest);
+ });
+ });
});
</script>
</body>
</html>
--- a/content/media/DOMMediaStream.cpp
+++ b/content/media/DOMMediaStream.cpp
@@ -14,44 +14,30 @@
#include "mozilla/dom/VideoTrackList.h"
#include "MediaStreamGraph.h"
#include "AudioStreamTrack.h"
#include "VideoStreamTrack.h"
using namespace mozilla;
using namespace mozilla::dom;
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMMediaStream)
- NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
- NS_INTERFACE_MAP_ENTRY(nsISupports)
- NS_INTERFACE_MAP_ENTRY(nsIDOMMediaStream)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMMediaStream)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMMediaStream)
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(DOMMediaStream)
+NS_IMPL_CYCLE_COLLECTION_INHERITED(DOMMediaStream,
+ DOMEventTargetHelper,
+ mWindow,
+ mTracks,
+ mConsumersToKeepAlive);
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMMediaStream)
- tmp->Destroy();
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow)
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mTracks)
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mConsumersToKeepAlive)
- NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMMediaStream)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTracks)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConsumersToKeepAlive)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(DOMMediaStream)
+NS_IMPL_ADDREF_INHERITED(DOMMediaStream, DOMEventTargetHelper)
+NS_IMPL_RELEASE_INHERITED(DOMMediaStream, DOMEventTargetHelper)
-NS_IMPL_ISUPPORTS_INHERITED(DOMLocalMediaStream, DOMMediaStream,
- nsIDOMLocalMediaStream)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DOMMediaStream)
+ NS_INTERFACE_MAP_ENTRY(DOMMediaStream)
+NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
+
+NS_IMPL_ISUPPORTS_INHERITED0(DOMLocalMediaStream, DOMMediaStream)
NS_IMPL_CYCLE_COLLECTION_INHERITED(DOMAudioNodeMediaStream, DOMMediaStream,
mStreamNode)
NS_IMPL_ADDREF_INHERITED(DOMAudioNodeMediaStream, DOMMediaStream)
NS_IMPL_RELEASE_INHERITED(DOMAudioNodeMediaStream, DOMMediaStream)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DOMAudioNodeMediaStream)
@@ -88,18 +74,22 @@ public:
nsRefPtr<MediaStreamTrack> track;
if (mEvents & MediaStreamListener::TRACK_EVENT_CREATED) {
track = stream->CreateDOMTrack(mID, mType);
stream->NotifyMediaStreamTrackCreated(track);
} else {
track = stream->GetDOMTrackFor(mID);
}
if (mEvents & MediaStreamListener::TRACK_EVENT_ENDED) {
- track->NotifyEnded();
- stream->NotifyMediaStreamTrackEnded(track);
+ if (track) {
+ track->NotifyEnded();
+ stream->NotifyMediaStreamTrackEnded(track);
+ } else {
+ NS_ERROR("track ended but not found");
+ }
}
return NS_OK;
}
StreamTime mEndTime;
nsRefPtr<StreamListener> mListener;
TrackID mID;
uint32_t mEvents;
--- a/content/media/DOMMediaStream.h
+++ b/content/media/DOMMediaStream.h
@@ -1,23 +1,23 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef NSDOMMEDIASTREAM_H_
#define NSDOMMEDIASTREAM_H_
-#include "nsIDOMMediaStream.h"
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
#include "StreamBuffer.h"
#include "nsIDOMWindow.h"
#include "nsIPrincipal.h"
#include "mozilla/PeerIdentity.h"
+#include "mozilla/DOMEventTargetHelper.h"
class nsXPCClassInfo;
// GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
// GetTickCount() and conflicts with NS_DECL_NSIDOMMEDIASTREAM, containing
// currentTime getter.
#ifdef GetCurrentTime
#undef GetCurrentTime
@@ -43,39 +43,45 @@ class AudioTrack;
class VideoTrack;
class AudioTrackList;
class VideoTrackList;
class MediaTrackListListener;
}
class MediaStreamDirectListener;
+#define NS_DOMMEDIASTREAM_IID \
+{ 0x8cb65468, 0x66c0, 0x444e, \
+ { 0x89, 0x9f, 0x89, 0x1d, 0x9e, 0xd2, 0xbe, 0x7c } }
+
/**
* DOM wrapper for MediaStreams.
*/
-class DOMMediaStream : public nsIDOMMediaStream,
- public nsWrapperCache
+class DOMMediaStream : public DOMEventTargetHelper
{
friend class DOMLocalMediaStream;
typedef dom::MediaStreamTrack MediaStreamTrack;
typedef dom::AudioStreamTrack AudioStreamTrack;
typedef dom::VideoStreamTrack VideoStreamTrack;
typedef dom::AudioTrack AudioTrack;
typedef dom::VideoTrack VideoTrack;
typedef dom::AudioTrackList AudioTrackList;
typedef dom::VideoTrackList VideoTrackList;
typedef dom::MediaTrackListListener MediaTrackListListener;
public:
typedef uint8_t TrackTypeHints;
DOMMediaStream();
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMMediaStream)
- NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_ISUPPORTS_INHERITED
+ NS_REALLY_FORWARD_NSIDOMEVENTTARGET(DOMEventTargetHelper)
+ NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DOMMediaStream,
+ DOMEventTargetHelper)
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOMMEDIASTREAM_IID)
nsIDOMWindow* GetParentObject() const
{
return mWindow;
}
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
// WebIDL
@@ -290,23 +296,30 @@ private:
// If null, this stream can be used by anyone because it has no content yet.
nsCOMPtr<nsIPrincipal> mPrincipal;
nsTArray<PrincipalChangeObserver*> mPrincipalChangeObservers;
// this is used in gUM and WebRTC to identify peers that this stream
// is allowed to be sent to
nsAutoPtr<PeerIdentity> mPeerIdentity;
};
-class DOMLocalMediaStream : public DOMMediaStream,
- public nsIDOMLocalMediaStream
+NS_DEFINE_STATIC_IID_ACCESSOR(DOMMediaStream,
+ NS_DOMMEDIASTREAM_IID)
+
+#define NS_DOMLOCALMEDIASTREAM_IID \
+{ 0xb1437260, 0xec61, 0x4dfa, \
+ { 0x92, 0x54, 0x04, 0x44, 0xe2, 0xb5, 0x94, 0x9c } }
+
+class DOMLocalMediaStream : public DOMMediaStream
{
public:
DOMLocalMediaStream() {}
NS_DECL_ISUPPORTS_INHERITED
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOMLOCALMEDIASTREAM_IID)
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
virtual void Stop();
virtual MediaEngineSource* GetMediaEngine(TrackID aTrackID) { return nullptr; }
/**
@@ -320,16 +333,19 @@ public:
*/
static already_AddRefed<DOMLocalMediaStream>
CreateTrackUnionStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents = 0);
protected:
virtual ~DOMLocalMediaStream();
};
+NS_DEFINE_STATIC_IID_ACCESSOR(DOMLocalMediaStream,
+ NS_DOMLOCALMEDIASTREAM_IID)
+
class DOMAudioNodeMediaStream : public DOMMediaStream
{
typedef dom::AudioNode AudioNode;
public:
explicit DOMAudioNodeMediaStream(AudioNode* aNode);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DOMAudioNodeMediaStream, DOMMediaStream)
--- a/content/media/directshow/DirectShowReader.cpp
+++ b/content/media/directshow/DirectShowReader.cpp
@@ -2,20 +2,19 @@
/* vim: set ts=8 sts=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 "DirectShowReader.h"
#include "MediaDecoderReader.h"
#include "mozilla/RefPtr.h"
-#include "dshow.h"
+#include "DirectShowUtils.h"
#include "AudioSinkFilter.h"
#include "SourceFilter.h"
-#include "DirectShowUtils.h"
#include "SampleSink.h"
#include "MediaResource.h"
#include "VideoUtils.h"
namespace mozilla {
#ifdef PR_LOGGING
--- a/content/media/directshow/DirectShowUtils.cpp
+++ b/content/media/directshow/DirectShowUtils.cpp
@@ -1,18 +1,17 @@
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "dshow.h"
+#include "DirectShowUtils.h"
#include "dmodshow.h"
#include "wmcodecdsp.h"
#include "dmoreg.h"
-#include "DirectShowUtils.h"
#include "nsAutoPtr.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/RefPtr.h"
#include "nsPrintfCString.h"
#define WARN(...) NS_WARNING(nsPrintfCString(__VA_ARGS__).get())
namespace mozilla {
--- a/content/media/directshow/DirectShowUtils.h
+++ b/content/media/directshow/DirectShowUtils.h
@@ -3,16 +3,24 @@
* 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 _DirectShowUtils_h_
#define _DirectShowUtils_h_
#include <stdint.h>
#include "dshow.h"
+
+// XXXbz windowsx.h defines GetFirstChild, GetNextSibling,
+// GetPrevSibling are macros, apparently... Eeevil. We have functions
+// called that on some classes, so undef them.
+#undef GetFirstChild
+#undef GetNextSibling
+#undef GetPrevSibling
+
#include "DShowTools.h"
#include "prlog.h"
namespace mozilla {
// Win32 "Event" wrapper. Must be paired with a CriticalSection to create a
// Java-style "monitor".
class Signal {
--- a/content/media/webspeech/recognition/SpeechRecognition.cpp
+++ b/content/media/webspeech/recognition/SpeechRecognition.cpp
@@ -929,18 +929,21 @@ SpeechEvent::Run()
return NS_OK;
}
NS_IMPL_ISUPPORTS(SpeechRecognition::GetUserMediaSuccessCallback, nsIDOMGetUserMediaSuccessCallback)
NS_IMETHODIMP
SpeechRecognition::GetUserMediaSuccessCallback::OnSuccess(nsISupports* aStream)
{
- nsCOMPtr<nsIDOMLocalMediaStream> localStream = do_QueryInterface(aStream);
- mRecognition->StartRecording(static_cast<DOMLocalMediaStream*>(localStream.get()));
+ DOMLocalMediaStream *localStream = nullptr;
+ nsresult rv = CallQueryInterface(aStream, &localStream);
+ if (NS_SUCCEEDED(rv)) {
+ mRecognition->StartRecording(localStream);
+ }
return NS_OK;
}
NS_IMPL_ISUPPORTS(SpeechRecognition::GetUserMediaErrorCallback, nsIDOMGetUserMediaErrorCallback)
NS_IMETHODIMP
SpeechRecognition::GetUserMediaErrorCallback::OnError(const nsAString& aError)
{
--- a/dom/camera/DOMCameraControl.cpp
+++ b/dom/camera/DOMCameraControl.cpp
@@ -15,45 +15,58 @@
#include "mozilla/MediaManager.h"
#include "mozilla/Services.h"
#include "mozilla/unused.h"
#include "nsIAppsService.h"
#include "nsIObserverService.h"
#include "nsIDOMDeviceStorage.h"
#include "nsIDOMEventListener.h"
#include "nsIScriptSecurityManager.h"
+#include "nsDOMFile.h"
#include "Navigator.h"
#include "nsXULAppAPI.h"
#include "DOMCameraManager.h"
#include "DOMCameraCapabilities.h"
#include "CameraCommon.h"
#include "nsGlobalWindow.h"
#include "CameraPreviewMediaStream.h"
+#include "mozilla/dom/CameraUtilBinding.h"
#include "mozilla/dom/CameraControlBinding.h"
#include "mozilla/dom/CameraManagerBinding.h"
#include "mozilla/dom/CameraCapabilitiesBinding.h"
+#include "mozilla/dom/CameraConfigurationEvent.h"
+#include "mozilla/dom/CameraConfigurationEventBinding.h"
+#include "mozilla/dom/CameraFacesDetectedEvent.h"
+#include "mozilla/dom/CameraFacesDetectedEventBinding.h"
+#include "mozilla/dom/CameraStateChangeEvent.h"
+#include "mozilla/dom/BlobEvent.h"
#include "DOMCameraDetectedFace.h"
#include "mozilla/dom/BindingUtils.h"
#include "nsPrintfCString.h"
using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::ipc;
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMCameraControl)
NS_INTERFACE_MAP_ENTRY(nsISupports)
- NS_INTERFACE_MAP_ENTRY(nsIDOMMediaStream)
NS_INTERFACE_MAP_END_INHERITING(DOMMediaStream)
NS_IMPL_ADDREF_INHERITED(nsDOMCameraControl, DOMMediaStream)
NS_IMPL_RELEASE_INHERITED(nsDOMCameraControl, DOMMediaStream)
NS_IMPL_CYCLE_COLLECTION_INHERITED(nsDOMCameraControl, DOMMediaStream,
mCapabilities,
mWindow,
+ mGetCameraPromise,
+ mAutoFocusPromise,
+ mTakePicturePromise,
+ mStartRecordingPromise,
+ mReleasePromise,
+ mSetConfigurationPromise,
mGetCameraOnSuccessCb,
mGetCameraOnErrorCb,
mAutoFocusOnSuccessCb,
mAutoFocusOnErrorCb,
mTakePictureOnSuccessCb,
mTakePictureOnErrorCb,
mStartRecordingOnSuccessCb,
mStartRecordingOnErrorCb,
@@ -130,20 +143,22 @@ nsDOMCameraControl::DOMCameraConfigurati
{
MOZ_COUNT_DTOR(nsDOMCameraControl::DOMCameraConfiguration);
}
nsDOMCameraControl::nsDOMCameraControl(uint32_t aCameraId,
const CameraConfiguration& aInitialConfig,
GetCameraCallback* aOnSuccess,
CameraErrorCallback* aOnError,
+ Promise* aPromise,
nsPIDOMWindow* aWindow)
: DOMMediaStream()
, mCameraControl(nullptr)
, mAudioChannelAgent(nullptr)
+ , mGetCameraPromise(aPromise)
, mGetCameraOnSuccessCb(aOnSuccess)
, mGetCameraOnErrorCb(aOnError)
, mAutoFocusOnSuccessCb(nullptr)
, mAutoFocusOnErrorCb(nullptr)
, mTakePictureOnSuccessCb(nullptr)
, mTakePictureOnErrorCb(nullptr)
, mStartRecordingOnSuccessCb(nullptr)
, mStartRecordingOnErrorCb(nullptr)
@@ -154,20 +169,22 @@ nsDOMCameraControl::nsDOMCameraControl(u
, mOnShutterCb(nullptr)
, mOnClosedCb(nullptr)
, mOnRecorderStateChangeCb(nullptr)
, mOnPreviewStateChangeCb(nullptr)
, mOnAutoFocusMovingCb(nullptr)
, mOnAutoFocusCompletedCb(nullptr)
, mOnFacesDetectedCb(nullptr)
, mWindow(aWindow)
+ , mPreviewState(CameraControlListener::kPreviewStopped)
{
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
mInput = new CameraPreviewMediaStream(this);
+ BindToOwner(aWindow);
SetIsDOMBinding();
nsRefPtr<DOMCameraConfiguration> initialConfig =
new DOMCameraConfiguration(aInitialConfig);
// Create and initialize the underlying camera.
ICameraControl::Configuration config;
bool haveInitialConfig = false;
@@ -678,38 +695,39 @@ public:
}
protected:
nsRefPtr<CameraErrorCallback> mCallback;
nsString mMessage;
};
// Methods.
-void
+already_AddRefed<Promise>
nsDOMCameraControl::StartRecording(const CameraStartRecordingOptions& aOptions,
nsDOMDeviceStorage& aStorageArea,
const nsAString& aFilename,
- CameraStartRecordingCallback& aOnSuccess,
+ const Optional<OwningNonNull<CameraStartRecordingCallback> >& aOnSuccess,
const Optional<OwningNonNull<CameraErrorCallback> >& aOnError,
ErrorResult& aRv)
{
MOZ_ASSERT(mCameraControl);
- nsRefPtr<CameraStartRecordingCallback> cb = mStartRecordingOnSuccessCb;
- if (cb) {
+ nsRefPtr<Promise> promise = CreatePromise(aRv);
+ if (aRv.Failed()) {
+ return nullptr;
+ }
+
+ if (mStartRecordingPromise) {
+ 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")));
- } else {
- DOM_CAMERA_LOGT("%s:onError NS_ERROR_FAILURE\n", __func__);
- // Only throw if no error callback was passed in.
- aRv = NS_ERROR_FAILURE;
}
- return;
+ return promise.forget();
}
NotifyRecordingStatusChange(NS_LITERAL_STRING("starting"));
#ifdef MOZ_B2G
if (!mAudioChannelAgent) {
mAudioChannelAgent = do_CreateInstance("@mozilla.org/audiochannelagent;1");
if (mAudioChannelAgent) {
@@ -722,29 +740,34 @@ nsDOMCameraControl::StartRecording(const
}
#endif
nsCOMPtr<nsIDOMDOMRequest> request;
mDSFileDescriptor = new DeviceStorageFileDescriptor();
aRv = aStorageArea.CreateFileDescriptor(aFilename, mDSFileDescriptor.get(),
getter_AddRefs(request));
if (aRv.Failed()) {
- return;
+ return nullptr;
}
+ mStartRecordingPromise = promise;
mOptions = aOptions;
- mStartRecordingOnSuccessCb = &aOnSuccess;
+ mStartRecordingOnSuccessCb = nullptr;
+ if (aOnSuccess.WasPassed()) {
+ mStartRecordingOnSuccessCb = &aOnSuccess.Value();
+ }
mStartRecordingOnErrorCb = nullptr;
if (aOnError.WasPassed()) {
mStartRecordingOnErrorCb = &aOnError.Value();
}
nsCOMPtr<nsIDOMEventListener> listener = new StartRecordingHelper(this);
request->AddEventListener(NS_LITERAL_STRING("success"), listener, false);
request->AddEventListener(NS_LITERAL_STRING("error"), listener, false);
+ return promise.forget();
}
void
nsDOMCameraControl::OnCreatedFileDescriptor(bool aSucceeded)
{
nsresult rv = NS_ERROR_FAILURE;
if (aSucceeded && mDSFileDescriptor->mFileDescriptor.IsValid()) {
@@ -789,118 +812,147 @@ nsDOMCameraControl::StopRecording(ErrorR
void
nsDOMCameraControl::ResumePreview(ErrorResult& aRv)
{
MOZ_ASSERT(mCameraControl);
aRv = mCameraControl->StartPreview();
}
-void
+already_AddRefed<Promise>
nsDOMCameraControl::SetConfiguration(const CameraConfiguration& aConfiguration,
const Optional<OwningNonNull<CameraSetConfigurationCallback> >& aOnSuccess,
const Optional<OwningNonNull<CameraErrorCallback> >& aOnError,
ErrorResult& aRv)
{
MOZ_ASSERT(mCameraControl);
- nsRefPtr<CameraTakePictureCallback> cb = mTakePictureOnSuccessCb;
- if (cb) {
+ nsRefPtr<Promise> promise = CreatePromise(aRv);
+ if (aRv.Failed()) {
+ return nullptr;
+ }
+
+ if (mTakePicturePromise) {
+ promise->MaybeReject(NS_ERROR_IN_PROGRESS);
// We're busy taking a picture, can't change modes right now.
if (aOnError.WasPassed()) {
// 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")));
- } else {
- // Only throw if no error callback was passed in.
- aRv = NS_ERROR_FAILURE;
}
- return;
+ return promise.forget();
}
ICameraControl::Configuration config;
config.mRecorderProfile = aConfiguration.mRecorderProfile;
config.mPreviewSize.width = aConfiguration.mPreviewSize.mWidth;
config.mPreviewSize.height = aConfiguration.mPreviewSize.mHeight;
config.mMode = ICameraControl::kPictureMode;
if (aConfiguration.mMode == CameraMode::Video) {
config.mMode = ICameraControl::kVideoMode;
}
+ aRv = mCameraControl->SetConfiguration(config);
+ if (aRv.Failed()) {
+ return nullptr;
+ }
+
+ mSetConfigurationPromise = promise;
mSetConfigurationOnSuccessCb = nullptr;
if (aOnSuccess.WasPassed()) {
mSetConfigurationOnSuccessCb = &aOnSuccess.Value();
}
mSetConfigurationOnErrorCb = nullptr;
if (aOnError.WasPassed()) {
mSetConfigurationOnErrorCb = &aOnError.Value();
}
-
- aRv = mCameraControl->SetConfiguration(config);
+ return promise.forget();
}
-void
-nsDOMCameraControl::AutoFocus(CameraAutoFocusCallback& aOnSuccess,
+already_AddRefed<Promise>
+nsDOMCameraControl::AutoFocus(const Optional<OwningNonNull<CameraAutoFocusCallback> >& aOnSuccess,
const Optional<OwningNonNull<CameraErrorCallback> >& aOnError,
ErrorResult& aRv)
{
MOZ_ASSERT(mCameraControl);
- nsRefPtr<CameraErrorCallback> ecb = mAutoFocusOnErrorCb.forget();
- if (ecb) {
+ nsRefPtr<Promise> promise = mAutoFocusPromise.forget();
+ if (promise) {
// There is already a call to AutoFocus() in progress, cancel it and
// invoke the error callback (if one was passed in).
- NS_DispatchToMainThread(new ImmediateErrorCallback(ecb,
- NS_LITERAL_STRING("AutoFocusInterrupted")));
+ promise->MaybeReject(NS_ERROR_IN_PROGRESS);
+ mAutoFocusOnSuccessCb = nullptr;
+ nsRefPtr<CameraErrorCallback> ecb = mAutoFocusOnErrorCb.forget();
+ if (ecb) {
+ NS_DispatchToMainThread(new ImmediateErrorCallback(ecb,
+ NS_LITERAL_STRING("AutoFocusInterrupted")));
+ }
}
- mAutoFocusOnSuccessCb = &aOnSuccess;
+ promise = CreatePromise(aRv);
+ if (aRv.Failed()) {
+ return nullptr;
+ }
+
+ aRv = mCameraControl->AutoFocus();
+ if (aRv.Failed()) {
+ return nullptr;
+ }
+
+ DispatchStateEvent(NS_LITERAL_STRING("focus"), NS_LITERAL_STRING("focusing"));
+
+ mAutoFocusPromise = promise;
+ mAutoFocusOnSuccessCb = nullptr;
+ if (aOnSuccess.WasPassed()) {
+ mAutoFocusOnSuccessCb = &aOnSuccess.Value();
+ }
mAutoFocusOnErrorCb = nullptr;
if (aOnError.WasPassed()) {
mAutoFocusOnErrorCb = &aOnError.Value();
}
-
- aRv = mCameraControl->AutoFocus();
+ return promise.forget();
}
void
nsDOMCameraControl::StartFaceDetection(ErrorResult& aRv)
{
MOZ_ASSERT(mCameraControl);
aRv = mCameraControl->StartFaceDetection();
}
void
nsDOMCameraControl::StopFaceDetection(ErrorResult& aRv)
{
MOZ_ASSERT(mCameraControl);
aRv = mCameraControl->StopFaceDetection();
}
-void
+already_AddRefed<Promise>
nsDOMCameraControl::TakePicture(const CameraPictureOptions& aOptions,
- CameraTakePictureCallback& aOnSuccess,
+ const Optional<OwningNonNull<CameraTakePictureCallback> >& aOnSuccess,
const Optional<OwningNonNull<CameraErrorCallback> >& aOnError,
ErrorResult& aRv)
{
MOZ_ASSERT(mCameraControl);
- nsRefPtr<CameraTakePictureCallback> cb = mTakePictureOnSuccessCb;
- if (cb) {
+ nsRefPtr<Promise> promise = CreatePromise(aRv);
+ if (aRv.Failed()) {
+ return nullptr;
+ }
+
+ if (mTakePicturePromise) {
+ // There is already a call to TakePicture() in progress, abort this new
+ // one and invoke the error callback (if one was passed in).
+ promise->MaybeReject(NS_ERROR_IN_PROGRESS);
if (aOnError.WasPassed()) {
- // There is already a call to TakePicture() in progress, abort this new
- // one and invoke the error callback (if one was passed in).
NS_DispatchToMainThread(new ImmediateErrorCallback(&aOnError.Value(),
NS_LITERAL_STRING("TakePictureAlreadyInProgress")));
- } else {
- // Only throw if no error callback was passed in.
- aRv = NS_ERROR_FAILURE;
}
- return;
+ return promise.forget();
}
{
ICameraControlParameterSetAutoEnter batch(mCameraControl);
// XXXmikeh - remove this: see bug 931155
ICameraControl::Size s;
s.width = aOptions.mPictureSize.mWidth;
@@ -916,42 +968,60 @@ nsDOMCameraControl::TakePicture(const Ca
mCameraControl->Set(CAMERA_PARAM_PICTURE_SIZE, s);
}
mCameraControl->Set(CAMERA_PARAM_PICTURE_ROTATION, aOptions.mRotation);
mCameraControl->Set(CAMERA_PARAM_PICTURE_FILEFORMAT, aOptions.mFileFormat);
mCameraControl->Set(CAMERA_PARAM_PICTURE_DATETIME, aOptions.mDateTime);
mCameraControl->SetLocation(p);
}
- mTakePictureOnSuccessCb = &aOnSuccess;
+ aRv = mCameraControl->TakePicture();
+ if (aRv.Failed()) {
+ return nullptr;
+ }
+
+ mTakePicturePromise = promise;
+ mTakePictureOnSuccessCb = nullptr;
+ if (aOnSuccess.WasPassed()) {
+ mTakePictureOnSuccessCb = &aOnSuccess.Value();
+ }
mTakePictureOnErrorCb = nullptr;
if (aOnError.WasPassed()) {
mTakePictureOnErrorCb = &aOnError.Value();
}
-
- aRv = mCameraControl->TakePicture();
+ return promise.forget();
}
-void
+already_AddRefed<Promise>
nsDOMCameraControl::ReleaseHardware(const Optional<OwningNonNull<CameraReleaseCallback> >& aOnSuccess,
const Optional<OwningNonNull<CameraErrorCallback> >& aOnError,
ErrorResult& aRv)
{
MOZ_ASSERT(mCameraControl);
+ nsRefPtr<Promise> promise = CreatePromise(aRv);
+ if (aRv.Failed()) {
+ return nullptr;
+ }
+
+ aRv = mCameraControl->Stop();
+ if (aRv.Failed()) {
+ return nullptr;
+ }
+
+ mReleasePromise = promise;
mReleaseOnSuccessCb = nullptr;
if (aOnSuccess.WasPassed()) {
mReleaseOnSuccessCb = &aOnSuccess.Value();
}
mReleaseOnErrorCb = nullptr;
if (aOnError.WasPassed()) {
mReleaseOnErrorCb = &aOnError.Value();
}
-
- aRv = mCameraControl->Stop();
+ return promise.forget();
}
void
nsDOMCameraControl::ResumeContinuousFocus(ErrorResult& aRv)
{
MOZ_ASSERT(mCameraControl);
aRv = mCameraControl->ResumeContinuousFocus();
}
@@ -960,16 +1030,22 @@ void
nsDOMCameraControl::Shutdown()
{
DOM_CAMERA_LOGI("%s:%d\n", __func__, __LINE__);
MOZ_ASSERT(mCameraControl);
// Remove any pending solicited event handlers; these
// reference our window object, which in turn references
// us. If we don't remove them, we can leak DOM objects.
+ AbortPromise(mGetCameraPromise);
+ AbortPromise(mAutoFocusPromise);
+ AbortPromise(mTakePicturePromise);
+ AbortPromise(mStartRecordingPromise);
+ AbortPromise(mReleasePromise);
+ AbortPromise(mSetConfigurationPromise);
mGetCameraOnSuccessCb = nullptr;
mGetCameraOnErrorCb = nullptr;
mAutoFocusOnSuccessCb = nullptr;
mAutoFocusOnErrorCb = nullptr;
mTakePictureOnSuccessCb = nullptr;
mTakePictureOnErrorCb = nullptr;
mStartRecordingOnSuccessCb = nullptr;
mStartRecordingOnErrorCb = nullptr;
@@ -996,47 +1072,124 @@ nsDOMCameraControl::NotifyRecordingStatu
NS_ENSURE_TRUE(mWindow, NS_ERROR_FAILURE);
return MediaManager::NotifyRecordingStatusChange(mWindow,
aMsg,
true /* aIsAudio */,
true /* aIsVideo */);
}
+already_AddRefed<Promise>
+nsDOMCameraControl::CreatePromise(ErrorResult& aRv)
+{
+ nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mWindow);
+ if (!global) {
+ aRv.Throw(NS_ERROR_FAILURE);
+ return nullptr;
+ }
+ return Promise::Create(global, aRv);
+}
+
+void
+nsDOMCameraControl::AbortPromise(nsRefPtr<Promise>& aPromise)
+{
+ nsRefPtr<Promise> promise = aPromise.forget();
+ if (promise) {
+ promise->MaybeReject(NS_ERROR_NOT_AVAILABLE);
+ }
+}
+
+void
+nsDOMCameraControl::EventListenerAdded(nsIAtom* aType)
+{
+ if (aType == nsGkAtoms::onpreviewstatechange) {
+ DispatchPreviewStateEvent(mPreviewState);
+ }
+}
+
+void
+nsDOMCameraControl::DispatchPreviewStateEvent(CameraControlListener::PreviewState aState)
+{
+ nsString state;
+ switch (aState) {
+ case CameraControlListener::kPreviewStarted:
+ state = NS_LITERAL_STRING("started");
+ break;
+
+ default:
+ state = NS_LITERAL_STRING("stopped");
+ break;
+ }
+
+ DispatchStateEvent(NS_LITERAL_STRING("previewstatechange"), state);
+}
+
+void
+nsDOMCameraControl::DispatchStateEvent(const nsString& aType, const nsString& aState)
+{
+ CameraStateChangeEventInit eventInit;
+ eventInit.mNewState = aState;
+
+ nsRefPtr<CameraStateChangeEvent> event =
+ CameraStateChangeEvent::Constructor(this, aType, eventInit);
+
+ DispatchTrustedEvent(event);
+}
+
// Camera Control event handlers--must only be called from the Main Thread!
void
nsDOMCameraControl::OnHardwareStateChange(CameraControlListener::HardwareState aState)
{
MOZ_ASSERT(NS_IsMainThread());
ErrorResult ignored;
DOM_CAMERA_LOGI("DOM OnHardwareStateChange(%d)\n", aState);
switch (aState) {
case CameraControlListener::kHardwareOpen:
- // The hardware is open, so we can return a camera to JS, even if
- // the preview hasn't started yet.
- if (mGetCameraOnSuccessCb) {
+ {
+ // The hardware is open, so we can return a camera to JS, even if
+ // the preview hasn't started yet.
+ nsRefPtr<Promise> promise = mGetCameraPromise.forget();
+ if (promise) {
+ CameraGetPromiseData data;
+ data.mCamera = this;
+ data.mConfiguration = *mCurrentConfiguration;
+ promise->MaybeResolve(data);
+ }
nsRefPtr<GetCameraCallback> cb = mGetCameraOnSuccessCb.forget();
- ErrorResult ignored;
mGetCameraOnErrorCb = nullptr;
- cb->Call(*this, *mCurrentConfiguration, ignored);
+ if (cb) {
+ ErrorResult ignored;
+ cb->Call(*this, *mCurrentConfiguration, ignored);
+ }
}
break;
case CameraControlListener::kHardwareClosed:
- if (mReleaseOnSuccessCb) {
- // If we have this event handler, this was a solicited hardware close.
- nsRefPtr<CameraReleaseCallback> cb = mReleaseOnSuccessCb.forget();
- mReleaseOnErrorCb = nullptr;
- cb->Call(ignored);
- } else if(mOnClosedCb) {
- // If not, something else closed the hardware.
- nsRefPtr<CameraClosedCallback> cb = mOnClosedCb;
- cb->Call(ignored);
+ {
+ nsRefPtr<Promise> promise = mReleasePromise.forget();
+ if (promise || mReleaseOnSuccessCb) {
+ // If we have this event handler, this was a solicited hardware close.
+ if (promise) {
+ promise->MaybeResolve(JS::UndefinedHandleValue);
+ }
+ nsRefPtr<CameraReleaseCallback> cb = mReleaseOnSuccessCb.forget();
+ mReleaseOnErrorCb = nullptr;
+ if (cb) {
+ cb->Call(ignored);
+ }
+ } else {
+ // If not, something else closed the hardware.
+ nsRefPtr<CameraClosedCallback> cb = mOnClosedCb;
+ if (cb) {
+ cb->Call(ignored);
+ }
+ }
+ DispatchTrustedEvent(NS_LITERAL_STRING("close"));
}
break;
default:
MOZ_ASSERT_UNREACHABLE("Unanticipated camera hardware state");
}
}
@@ -1047,61 +1200,71 @@ nsDOMCameraControl::OnShutter()
DOM_CAMERA_LOGI("DOM ** SNAP **\n");
nsRefPtr<CameraShutterCallback> cb = mOnShutterCb;
if (cb) {
ErrorResult ignored;
cb->Call(ignored);
}
+
+ DispatchTrustedEvent(NS_LITERAL_STRING("shutter"));
}
void
nsDOMCameraControl::OnPreviewStateChange(CameraControlListener::PreviewState aState)
{
MOZ_ASSERT(NS_IsMainThread());
- if (!mOnPreviewStateChangeCb) {
- return;
- }
-
+ mPreviewState = aState;
nsString state;
switch (aState) {
case CameraControlListener::kPreviewStarted:
state = NS_LITERAL_STRING("started");
break;
default:
state = NS_LITERAL_STRING("stopped");
break;
}
nsRefPtr<CameraPreviewStateChange> cb = mOnPreviewStateChangeCb;
- ErrorResult ignored;
- cb->Call(state, ignored);
+ if (cb) {
+ ErrorResult ignored;
+ cb->Call(state, ignored);
+ }
+
+ DispatchPreviewStateEvent(aState);
}
void
nsDOMCameraControl::OnRecorderStateChange(CameraControlListener::RecorderState aState,
int32_t aArg, int32_t aTrackNum)
{
// For now, we do nothing with 'aStatus' and 'aTrackNum'.
MOZ_ASSERT(NS_IsMainThread());
ErrorResult ignored;
nsString state;
switch (aState) {
case CameraControlListener::kRecorderStarted:
- if (mStartRecordingOnSuccessCb) {
- nsRefPtr<CameraStartRecordingCallback> cb = mStartRecordingOnSuccessCb.forget();
+ {
+ nsRefPtr<Promise> promise = mStartRecordingPromise.forget();
+ if (promise) {
+ promise->MaybeResolve(JS::UndefinedHandleValue);
+ }
+
+ nsRefPtr<CameraStartRecordingCallback> scb = mStartRecordingOnSuccessCb.forget();
mStartRecordingOnErrorCb = nullptr;
- cb->Call(ignored);
+ if (scb) {
+ scb->Call(ignored);
+ }
+ state = NS_LITERAL_STRING("Started");
}
- state = NS_LITERAL_STRING("Started");
break;
case CameraControlListener::kRecorderStopped:
NotifyRecordingStatusChange(NS_LITERAL_STRING("shutdown"));
state = NS_LITERAL_STRING("Stopped");
break;
#ifdef MOZ_B2G_CAMERA
@@ -1134,156 +1297,219 @@ nsDOMCameraControl::OnRecorderStateChang
MOZ_ASSERT_UNREACHABLE("Unanticipated video recorder error");
return;
}
nsRefPtr<CameraRecorderStateChange> cb = mOnRecorderStateChangeCb;
if (cb) {
cb->Call(state, ignored);
}
+
+ DispatchStateEvent(NS_LITERAL_STRING("recorderstatechange"), state);
}
void
nsDOMCameraControl::OnConfigurationChange(DOMCameraConfiguration* aConfiguration)
{
MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(aConfiguration != nullptr);
// Update our record of the current camera configuration
mCurrentConfiguration = aConfiguration;
DOM_CAMERA_LOGI("DOM OnConfigurationChange: this=%p\n", this);
DOM_CAMERA_LOGI(" mode : %s\n",
mCurrentConfiguration->mMode == CameraMode::Video ? "video" : "picture");
DOM_CAMERA_LOGI(" maximum focus areas : %d\n",
mCurrentConfiguration->mMaxFocusAreas);
DOM_CAMERA_LOGI(" maximum metering areas : %d\n",
mCurrentConfiguration->mMaxMeteringAreas);
DOM_CAMERA_LOGI(" preview size (w x h) : %d x %d\n",
mCurrentConfiguration->mPreviewSize.mWidth, mCurrentConfiguration->mPreviewSize.mHeight);
DOM_CAMERA_LOGI(" recorder profile : %s\n",
NS_ConvertUTF16toUTF8(mCurrentConfiguration->mRecorderProfile).get());
+ nsRefPtr<Promise> promise = mSetConfigurationPromise.forget();
+ if (promise) {
+ promise->MaybeResolve(*aConfiguration);
+ }
+
nsRefPtr<CameraSetConfigurationCallback> cb = mSetConfigurationOnSuccessCb.forget();
mSetConfigurationOnErrorCb = nullptr;
if (cb) {
ErrorResult ignored;
cb->Call(*mCurrentConfiguration, ignored);
}
+
+ CameraConfigurationEventInit eventInit;
+ eventInit.mMode = mCurrentConfiguration->mMode;
+ eventInit.mRecorderProfile = mCurrentConfiguration->mRecorderProfile;
+ eventInit.mPreviewSize = new DOMRect(this, 0, 0,
+ mCurrentConfiguration->mPreviewSize.mWidth,
+ mCurrentConfiguration->mPreviewSize.mHeight);
+
+ nsRefPtr<CameraConfigurationEvent> event =
+ CameraConfigurationEvent::Constructor(this,
+ NS_LITERAL_STRING("configurationchanged"),
+ eventInit);
+
+ DispatchTrustedEvent(event);
}
void
nsDOMCameraControl::OnAutoFocusComplete(bool aAutoFocusSucceeded)
{
MOZ_ASSERT(NS_IsMainThread());
+ nsRefPtr<Promise> promise = mAutoFocusPromise.forget();
+ if (promise) {
+ 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) {
+ DispatchStateEvent(NS_LITERAL_STRING("focus"), NS_LITERAL_STRING("focused"));
+ } else {
+ DispatchStateEvent(NS_LITERAL_STRING("focus"), NS_LITERAL_STRING("unfocused"));
+ }
}
void
nsDOMCameraControl::OnAutoFocusMoving(bool aIsMoving)
{
MOZ_ASSERT(NS_IsMainThread());
nsRefPtr<CameraAutoFocusMovingCallback> cb = mOnAutoFocusMovingCb;
if (cb) {
ErrorResult ignored;
cb->Call(aIsMoving, ignored);
}
+
+ if (aIsMoving) {
+ DispatchStateEvent(NS_LITERAL_STRING("focus"), NS_LITERAL_STRING("focusing"));
+ }
}
void
nsDOMCameraControl::OnFacesDetected(const nsTArray<ICameraControl::Face>& aFaces)
{
DOM_CAMERA_LOGI("DOM OnFacesDetected %u face(s)\n", aFaces.Length());
MOZ_ASSERT(NS_IsMainThread());
- nsRefPtr<CameraFaceDetectionCallback> cb = mOnFacesDetectedCb;
- if (!cb) {
- return;
- }
-
Sequence<OwningNonNull<DOMCameraDetectedFace> > faces;
uint32_t len = aFaces.Length();
if (faces.SetCapacity(len)) {
nsRefPtr<DOMCameraDetectedFace> f;
for (uint32_t i = 0; i < len; ++i) {
f = new DOMCameraDetectedFace(this, aFaces[i]);
*faces.AppendElement() = f.forget().take();
}
}
- ErrorResult ignored;
- cb->Call(faces, ignored);
+ nsRefPtr<CameraFaceDetectionCallback> cb = mOnFacesDetectedCb;
+ if (cb) {
+ ErrorResult ignored;
+ cb->Call(faces, ignored);
+ }
+
+ CameraFacesDetectedEventInit eventInit;
+ eventInit.mFaces.SetValue(faces);
+
+ nsRefPtr<CameraFacesDetectedEvent> event =
+ CameraFacesDetectedEvent::Constructor(this,
+ NS_LITERAL_STRING("facesdetected"),
+ eventInit);
+
+ DispatchTrustedEvent(event);
}
void
nsDOMCameraControl::OnTakePictureComplete(nsIDOMBlob* aPicture)
{
MOZ_ASSERT(NS_IsMainThread());
+ MOZ_ASSERT(aPicture != nullptr);
+
+ nsRefPtr<Promise> promise = mTakePicturePromise.forget();
+ if (promise) {
+ nsCOMPtr<nsIDOMBlob> picture = aPicture;
+ promise->MaybeResolve(picture);
+ }
nsRefPtr<CameraTakePictureCallback> cb = mTakePictureOnSuccessCb.forget();
mTakePictureOnErrorCb = nullptr;
- if (!cb) {
- // Warn because it shouldn't be possible to get here without
- // having passed a success callback into takePicture(), even
- // though we guard against a nullptr dereference.
- NS_WARNING("DOM Null success callback in OnTakePictureComplete()");
- return;
+ if (cb) {
+ ErrorResult ignored;
+ cb->Call(aPicture, ignored);
}
- ErrorResult ignored;
- cb->Call(aPicture, ignored);
+ BlobEventInit eventInit;
+ eventInit.mData = aPicture;
+
+ nsRefPtr<BlobEvent> event = BlobEvent::Constructor(this,
+ NS_LITERAL_STRING("picture"),
+ eventInit);
+
+ DispatchTrustedEvent(event);
}
void
nsDOMCameraControl::OnUserError(CameraControlListener::UserContext aContext, nsresult aError)
{
MOZ_ASSERT(NS_IsMainThread());
+ nsRefPtr<Promise> promise;
nsRefPtr<CameraErrorCallback> errorCb;
switch (aContext) {
case CameraControlListener::kInStartCamera:
+ promise = mGetCameraPromise.forget();
mGetCameraOnSuccessCb = nullptr;
errorCb = mGetCameraOnErrorCb.forget();
break;
case CameraControlListener::kInStopCamera:
+ promise = mReleasePromise.forget();
mReleaseOnSuccessCb = nullptr;
errorCb = mReleaseOnErrorCb.forget();
break;
case CameraControlListener::kInSetConfiguration:
+ promise = mSetConfigurationPromise.forget();
mSetConfigurationOnSuccessCb = nullptr;
errorCb = mSetConfigurationOnErrorCb.forget();
break;
case CameraControlListener::kInAutoFocus:
+ promise = mAutoFocusPromise.forget();
mAutoFocusOnSuccessCb = nullptr;
errorCb = mAutoFocusOnErrorCb.forget();
+ DispatchStateEvent(NS_LITERAL_STRING("focus"), NS_LITERAL_STRING("unfocused"));
break;
case CameraControlListener::kInTakePicture:
+ promise = mTakePicturePromise.forget();
mTakePictureOnSuccessCb = nullptr;
errorCb = mTakePictureOnErrorCb.forget();
break;
case CameraControlListener::kInStartRecording:
+ promise = mStartRecordingPromise.forget();
mStartRecordingOnSuccessCb = nullptr;
errorCb = mStartRecordingOnErrorCb.forget();
break;
case CameraControlListener::kInStartFaceDetection:
// This method doesn't have any callbacks, so all we can do is log the
// failure. This only happens after the hardware has been released.
NS_WARNING("Failed to start face detection");
@@ -1335,57 +1561,62 @@ nsDOMCameraControl::OnUserError(CameraCo
{
nsPrintfCString msg("Unhandled aContext=%u, aError=0x%x\n", aContext, aError);
NS_WARNING(msg.get());
}
MOZ_ASSERT_UNREACHABLE("Unhandled user error");
return;
}
- if (!errorCb) {
+ if (!promise && !errorCb) {
DOM_CAMERA_LOGW("DOM No error handler for aError=0x%x in aContext=%u\n",
aError, aContext);
return;
}
- 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;
+ DOM_CAMERA_LOGI("DOM OnUserError aContext=%u, aError=0x%x\n", aContext, aError);
+ if (promise) {
+ promise->MaybeReject(aError);
}
- DOM_CAMERA_LOGI("DOM OnUserError aContext=%u, error='%s'\n", aContext,
- NS_ConvertUTF16toUTF8(error).get());
- ErrorResult ignored;
- errorCb->Call(error, ignored);
+ 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);
+ }
}
--- a/dom/camera/DOMCameraControl.h
+++ b/dom/camera/DOMCameraControl.h
@@ -4,16 +4,17 @@
#ifndef DOM_CAMERA_DOMCAMERACONTROL_H
#define DOM_CAMERA_DOMCAMERACONTROL_H
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "mozilla/dom/CameraControlBinding.h"
+#include "mozilla/dom/Promise.h"
#include "ICameraControl.h"
#include "CameraCommon.h"
#include "DOMMediaStream.h"
#include "AudioChannelAgent.h"
#include "nsProxyRelease.h"
#include "nsHashPropertyBag.h"
#include "DeviceStorage.h"
#include "DOMCameraControlListener.h"
@@ -48,16 +49,17 @@ public:
// HasSupport() method in each header. We can get rid of these with the
// Great Renaming proposed in bug 983177.
static bool HasSupport(JSContext* aCx, JSObject* aGlobal);
nsDOMCameraControl(uint32_t aCameraId,
const dom::CameraConfiguration& aInitialConfig,
dom::GetCameraCallback* aOnSuccess,
dom::CameraErrorCallback* aOnError,
+ dom::Promise* aPromise,
nsPIDOMWindow* aWindow);
void Shutdown();
nsPIDOMWindow* GetParentObject() const { return mWindow; }
// Attributes.
void GetEffect(nsString& aEffect, ErrorResult& aRv);
@@ -97,52 +99,61 @@ public:
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.
- void SetConfiguration(const dom::CameraConfiguration& aConfiguration,
- const dom::Optional<dom::OwningNonNull<dom::CameraSetConfigurationCallback> >& aOnSuccess,
- const dom::Optional<dom::OwningNonNull<dom::CameraErrorCallback> >& aOnError,
- ErrorResult& aRv);
+ 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);
void GetMeteringAreas(nsTArray<dom::CameraRegion>& aAreas, ErrorResult& aRv);
void SetMeteringAreas(const dom::Optional<dom::Sequence<dom::CameraRegion> >& aAreas, ErrorResult& aRv);
void GetFocusAreas(nsTArray<dom::CameraRegion>& aAreas, ErrorResult& aRv);
void SetFocusAreas(const dom::Optional<dom::Sequence<dom::CameraRegion> >& aAreas, ErrorResult& aRv);
void GetPictureSize(dom::CameraSize& aSize, ErrorResult& aRv);
void SetPictureSize(const dom::CameraSize& aSize, ErrorResult& aRv);
void GetThumbnailSize(dom::CameraSize& aSize, ErrorResult& aRv);
void SetThumbnailSize(const dom::CameraSize& aSize, ErrorResult& aRv);
- void AutoFocus(dom::CameraAutoFocusCallback& aOnSuccess,
- const dom::Optional<dom::OwningNonNull<dom::CameraErrorCallback> >& aOnError,
- ErrorResult& aRv);
+ already_AddRefed<dom::Promise> AutoFocus(const dom::Optional<dom::OwningNonNull<dom::CameraAutoFocusCallback> >& aOnSuccess,
+ const dom::Optional<dom::OwningNonNull<dom::CameraErrorCallback> >& aOnError,
+ ErrorResult& aRv);
void StartFaceDetection(ErrorResult& aRv);
void StopFaceDetection(ErrorResult& aRv);
- void TakePicture(const dom::CameraPictureOptions& aOptions,
- dom::CameraTakePictureCallback& aOnSuccess,
- const dom::Optional<dom::OwningNonNull<dom::CameraErrorCallback> >& aOnError,
- ErrorResult& aRv);
- void StartRecording(const dom::CameraStartRecordingOptions& aOptions,
- nsDOMDeviceStorage& storageArea,
- const nsAString& filename,
- dom::CameraStartRecordingCallback& aOnSuccess,
- const dom::Optional<dom::OwningNonNull<dom::CameraErrorCallback> >& aOnError,
- ErrorResult& aRv);
+ 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);
+ already_AddRefed<dom::Promise> StartRecording(const dom::CameraStartRecordingOptions& aOptions,
+ nsDOMDeviceStorage& storageArea,
+ const nsAString& filename,
+ const dom::Optional<dom::OwningNonNull<dom::CameraStartRecordingCallback> >& aOnSuccess,
+ const dom::Optional<dom::OwningNonNull<dom::CameraErrorCallback> >& aOnError,
+ ErrorResult& aRv);
void StopRecording(ErrorResult& aRv);
void ResumePreview(ErrorResult& aRv);
- void ReleaseHardware(const dom::Optional<dom::OwningNonNull<dom::CameraReleaseCallback> >& aOnSuccess,
- const dom::Optional<dom::OwningNonNull<dom::CameraErrorCallback> >& aOnError,
- ErrorResult& aRv);
+ already_AddRefed<dom::Promise> ReleaseHardware(const dom::Optional<dom::OwningNonNull<dom::CameraReleaseCallback> >& aOnSuccess,
+ const dom::Optional<dom::OwningNonNull<dom::CameraErrorCallback> >& aOnError,
+ ErrorResult& aRv);
void ResumeContinuousFocus(ErrorResult& aRv);
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+ IMPL_EVENT_HANDLER(facesdetected)
+ IMPL_EVENT_HANDLER(shutter)
+ IMPL_EVENT_HANDLER(close)
+ IMPL_EVENT_HANDLER(recorderstatechange)
+ IMPL_EVENT_HANDLER(previewstatechange)
+ IMPL_EVENT_HANDLER(focus)
+ IMPL_EVENT_HANDLER(picture)
+ IMPL_EVENT_HANDLER(configurationchange)
+
protected:
virtual ~nsDOMCameraControl();
class DOMCameraConfiguration MOZ_FINAL : public dom::CameraConfiguration
{
public:
NS_INLINE_DECL_REFCOUNTING(DOMCameraConfiguration)
@@ -174,27 +185,41 @@ protected:
void OnConfigurationChange(DOMCameraConfiguration* aConfiguration);
void OnShutter();
void OnUserError(CameraControlListener::UserContext aContext, nsresult aError);
bool IsWindowStillActive();
nsresult NotifyRecordingStatusChange(const nsString& aMsg);
+ already_AddRefed<dom::Promise> CreatePromise(ErrorResult& aRv);
+ void AbortPromise(nsRefPtr<dom::Promise>& aPromise);
+ virtual void EventListenerAdded(nsIAtom* aType) MOZ_OVERRIDE;
+ void DispatchPreviewStateEvent(DOMCameraControlListener::PreviewState aState);
+ void DispatchStateEvent(const nsString& aType, const nsString& aState);
+
nsRefPtr<ICameraControl> mCameraControl; // non-DOM camera control
// An agent used to join audio channel service.
nsCOMPtr<nsIAudioChannelAgent> mAudioChannelAgent;
nsresult Set(uint32_t aKey, const dom::Optional<dom::Sequence<dom::CameraRegion> >& aValue, uint32_t aLimit);
nsresult Get(uint32_t aKey, nsTArray<dom::CameraRegion>& aValue);
nsRefPtr<DOMCameraConfiguration> mCurrentConfiguration;
nsRefPtr<dom::CameraCapabilities> mCapabilities;
+ // camera control pending promises
+ nsRefPtr<dom::Promise> mGetCameraPromise;
+ nsRefPtr<dom::Promise> mAutoFocusPromise;
+ nsRefPtr<dom::Promise> mTakePicturePromise;
+ nsRefPtr<dom::Promise> mStartRecordingPromise;
+ nsRefPtr<dom::Promise> mReleasePromise;
+ 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;
@@ -221,16 +246,17 @@ protected:
// our viewfinder stream
nsRefPtr<CameraPreviewMediaStream> mInput;
// set once when this object is created
nsCOMPtr<nsPIDOMWindow> mWindow;
dom::CameraStartRecordingOptions mOptions;
nsRefPtr<DeviceStorageFileDescriptor> mDSFileDescriptor;
+ DOMCameraControlListener::PreviewState mPreviewState;
private:
nsDOMCameraControl(const nsDOMCameraControl&) MOZ_DELETE;
nsDOMCameraControl& operator=(const nsDOMCameraControl&) MOZ_DELETE;
};
} // namespace mozilla
--- a/dom/camera/DOMCameraManager.cpp
+++ b/dom/camera/DOMCameraManager.cpp
@@ -141,24 +141,26 @@ public:
nsIContentPermissionRequest)
CameraPermissionRequest(nsIPrincipal* aPrincipal,
nsPIDOMWindow* aWindow,
nsRefPtr<nsDOMCameraManager> aManager,
uint32_t aCameraId,
const CameraConfiguration& aInitialConfig,
nsRefPtr<GetCameraCallback> aOnSuccess,
- nsRefPtr<CameraErrorCallback> aOnError)
+ nsRefPtr<CameraErrorCallback> aOnError,
+ nsRefPtr<Promise> aPromise)
: mPrincipal(aPrincipal)
, mWindow(aWindow)
, mCameraManager(aManager)
, mCameraId(aCameraId)
, mInitialConfig(aInitialConfig)
, mOnSuccess(aOnSuccess)
, mOnError(aOnError)
+ , mPromise(aPromise)
{
}
protected:
virtual ~CameraPermissionRequest()
{
}
@@ -167,19 +169,23 @@ protected:
void CallCancel();
nsCOMPtr<nsIPrincipal> mPrincipal;
nsCOMPtr<nsPIDOMWindow> mWindow;
nsRefPtr<nsDOMCameraManager> mCameraManager;
uint32_t mCameraId;
CameraConfiguration mInitialConfig;
nsRefPtr<GetCameraCallback> mOnSuccess;
nsRefPtr<CameraErrorCallback> mOnError;
+ nsRefPtr<Promise> mPromise;
};
-NS_IMPL_CYCLE_COLLECTION(CameraPermissionRequest, mWindow, mOnSuccess, mOnError)
+NS_IMPL_CYCLE_COLLECTION(CameraPermissionRequest, mWindow,
+ mOnSuccess,
+ mOnError,
+ mPromise)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CameraPermissionRequest)
NS_INTERFACE_MAP_ENTRY(nsIContentPermissionRequest)
NS_INTERFACE_MAP_ENTRY(nsIRunnable)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContentPermissionRequest)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(CameraPermissionRequest)
@@ -235,98 +241,118 @@ CameraPermissionRequest::DispatchCallbac
callbackRunnable = NS_NewRunnableMethod(this, &CameraPermissionRequest::CallCancel);
}
return NS_DispatchToMainThread(callbackRunnable);
}
void
CameraPermissionRequest::CallAllow()
{
- mCameraManager->PermissionAllowed(mCameraId, mInitialConfig, mOnSuccess, mOnError);
+ mCameraManager->PermissionAllowed(mCameraId, mInitialConfig, mOnSuccess, mOnError, mPromise);
}
void
CameraPermissionRequest::CallCancel()
{
- mCameraManager->PermissionCancelled(mCameraId, mInitialConfig, mOnSuccess, mOnError);
+ mCameraManager->PermissionCancelled(mCameraId, mInitialConfig, mOnSuccess, mOnError, mPromise);
}
NS_IMETHODIMP
CameraPermissionRequest::GetTypes(nsIArray** aTypes)
{
nsTArray<nsString> emptyOptions;
return nsContentPermissionUtils::CreatePermissionArray(NS_LITERAL_CSTRING("camera"),
NS_LITERAL_CSTRING("unused"),
emptyOptions,
aTypes);
}
-void
+already_AddRefed<Promise>
nsDOMCameraManager::GetCamera(const nsAString& aCamera,
const CameraConfiguration& aInitialConfig,
- GetCameraCallback& aOnSuccess,
+ const OptionalNonNullGetCameraCallback& aOnSuccess,
const OptionalNonNullCameraErrorCallback& aOnError,
ErrorResult& aRv)
{
DOM_CAMERA_LOGT("%s:%d\n", __func__, __LINE__);
uint32_t cameraId = 0; // back (or forward-facing) camera by default
if (aCamera.EqualsLiteral("front")) {
cameraId = 1;
}
- nsRefPtr<CameraErrorCallback> errorCallback = nullptr;
+ nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mWindow);
+ if (!global) {
+ aRv.Throw(NS_ERROR_FAILURE);
+ return nullptr;
+ }
+
+ nsRefPtr<Promise> promise = Promise::Create(global, aRv);
+ if (aRv.Failed()) {
+ 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) {
- PermissionAllowed(cameraId, aInitialConfig, &aOnSuccess, errorCallback);
- return;
+ PermissionAllowed(cameraId, aInitialConfig, successCallback, errorCallback, promise);
+ return promise.forget();
}
nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(mWindow);
if (!sop) {
aRv.Throw(NS_ERROR_UNEXPECTED);
- return;
+ return nullptr;
}
nsCOMPtr<nsIPrincipal> principal = sop->GetPrincipal();
nsCOMPtr<nsIRunnable> permissionRequest =
new CameraPermissionRequest(principal, mWindow, this, cameraId, aInitialConfig,
- &aOnSuccess, errorCallback);
+ successCallback, errorCallback, promise);
NS_DispatchToMainThread(permissionRequest);
+ return promise.forget();
}
void
nsDOMCameraManager::PermissionAllowed(uint32_t aCameraId,
const CameraConfiguration& aInitialConfig,
GetCameraCallback* aOnSuccess,
- CameraErrorCallback* aOnError)
+ CameraErrorCallback* aOnError,
+ Promise* aPromise)
{
mPermission = nsIPermissionManager::ALLOW_ACTION;
// Creating this object will trigger the aOnSuccess callback
// (or the aOnError one, if it fails).
nsRefPtr<nsDOMCameraControl> cameraControl =
- new nsDOMCameraControl(aCameraId, aInitialConfig, aOnSuccess, aOnError, mWindow);
+ new nsDOMCameraControl(aCameraId, aInitialConfig, aOnSuccess, aOnError, aPromise, mWindow);
Register(cameraControl);
}
void
nsDOMCameraManager::PermissionCancelled(uint32_t aCameraId,
const CameraConfiguration& aInitialConfig,
GetCameraCallback* aOnSuccess,
- CameraErrorCallback* aOnError)
+ CameraErrorCallback* aOnError,
+ Promise* aPromise)
{
mPermission = nsIPermissionManager::DENY_ACTION;
+ aPromise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
if (aOnError) {
ErrorResult ignored;
aOnError->Call(NS_LITERAL_STRING("Permission denied."), ignored);
}
}
void
nsDOMCameraManager::Register(nsDOMCameraControl* aDOMCameraControl)
--- a/dom/camera/DOMCameraManager.h
+++ b/dom/camera/DOMCameraManager.h
@@ -3,16 +3,17 @@
/* 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 DOM_CAMERA_DOMCAMERAMANAGER_H
#define DOM_CAMERA_DOMCAMERAMANAGER_H
#include "mozilla/dom/BindingDeclarations.h"
+#include "mozilla/dom/Promise.h"
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "nsIObserver.h"
#include "nsHashKeys.h"
#include "nsWrapperCache.h"
#include "nsWeakReference.h"
#include "nsClassHashtable.h"
#include "nsCycleCollectionParticipant.h"
@@ -27,17 +28,19 @@ namespace mozilla {
struct CameraConfiguration;
class GetCameraCallback;
class CameraErrorCallback;
}
}
typedef nsTArray<nsRefPtr<mozilla::nsDOMCameraControl> > CameraControls;
typedef nsClassHashtable<nsUint64HashKey, CameraControls> WindowTable;
-typedef mozilla::dom::Optional<mozilla::dom::OwningNonNull<mozilla::dom::CameraErrorCallback>>
+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
: public nsIObserver
, public nsSupportsWeakReference
, public nsWrapperCache
{
public:
@@ -59,29 +62,32 @@ public:
static bool IsWindowStillActive(uint64_t aWindowId);
void Register(mozilla::nsDOMCameraControl* aDOMCameraControl);
void OnNavigation(uint64_t aWindowId);
void PermissionAllowed(uint32_t aCameraId,
const mozilla::dom::CameraConfiguration& aOptions,
mozilla::dom::GetCameraCallback* aOnSuccess,
- mozilla::dom::CameraErrorCallback* aOnError);
+ mozilla::dom::CameraErrorCallback* aOnError,
+ mozilla::dom::Promise* aPromise);
void PermissionCancelled(uint32_t aCameraId,
const mozilla::dom::CameraConfiguration& aOptions,
mozilla::dom::GetCameraCallback* aOnSuccess,
- mozilla::dom::CameraErrorCallback* aOnError);
+ mozilla::dom::CameraErrorCallback* aOnError,
+ mozilla::dom::Promise* aPromise);
// WebIDL
- void GetCamera(const nsAString& aCamera,
- const mozilla::dom::CameraConfiguration& aOptions,
- mozilla::dom::GetCameraCallback& aOnSuccess,
- const OptionalNonNullCameraErrorCallback& aOnError,
- mozilla::ErrorResult& aRv);
+ already_AddRefed<mozilla::dom::Promise>
+ GetCamera(const nsAString& aCamera,
+ const mozilla::dom::CameraConfiguration& aOptions,
+ const OptionalNonNullGetCameraCallback& aOnSuccess,
+ const OptionalNonNullCameraErrorCallback& aOnError,
+ mozilla::ErrorResult& aRv);
void GetListOfCameras(nsTArray<nsString>& aList, mozilla::ErrorResult& aRv);
nsPIDOMWindow* GetParentObject() const { return mWindow; }
virtual JSObject* WrapObject(JSContext* aCx)
MOZ_OVERRIDE;
protected:
void XpComShutdown();
new file mode 100644
--- /dev/null
+++ b/dom/camera/test/callback/test_bug1022766.html
@@ -0,0 +1,97 @@
+<!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>
new file mode 100644
--- /dev/null
+++ b/dom/camera/test/callback/test_bug975472.html
@@ -0,0 +1,223 @@
+<!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>
new file mode 100644
--- /dev/null
+++ b/dom/camera/test/callback/test_camera.html
@@ -0,0 +1,242 @@
+<!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>
new file mode 100644
--- /dev/null
+++ b/dom/camera/test/callback/test_camera_2.html
@@ -0,0 +1,200 @@
+<!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>
new file mode 100644
--- /dev/null
+++ b/dom/camera/test/callback/test_camera_3.html
@@ -0,0 +1,76 @@
+<!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>
new file mode 100644
--- /dev/null
+++ b/dom/camera/test/callback/test_camera_hardware_auto_focus_moving_cb.html
@@ -0,0 +1,131 @@
+<!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>
new file mode 100644
--- /dev/null
+++ b/dom/camera/test/callback/test_camera_hardware_face_detection.html
@@ -0,0 +1,320 @@
+<!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>
new file mode 100644
--- /dev/null
+++ b/dom/camera/test/callback/test_camera_hardware_failures.html
@@ -0,0 +1,145 @@
+<!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>
new file mode 100644
--- /dev/null
+++ b/dom/camera/test/callback/test_camera_hardware_init_failure.html
@@ -0,0 +1,96 @@
+<!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)
+ }
+ }
+];
+
+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>
--- a/dom/camera/test/camera_common.js
+++ b/dom/camera/test/camera_common.js
@@ -117,16 +117,17 @@ var CameraTest = (function() {
function testEnd(callback) {
// A chain of clean-up functions....
function allCleanedUp() {
SimpleTest.finish();
if (callback) {
callback();
}
}
+
function cleanUpTestEnabled() {
var next = allCleanedUp;
if (oldTestEnabled) {
SpecialPowers.pushPrefEnv({'set': [[PREF_TEST_ENABLED, oldTestEnabled]]}, next);
} else {
SpecialPowers.pushPrefEnv({'clear': [[PREF_TEST_ENABLED]]}, next);
}
}
--- a/dom/camera/test/mochitest.ini
+++ b/dom/camera/test/mochitest.ini
@@ -1,11 +1,20 @@
[DEFAULT]
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]
[test_camera.html]
[test_camera_2.html]
[test_camera_3.html]
[test_camera_hardware_init_failure.html]
[test_camera_hardware_failures.html]
[test_bug975472.html]
[test_camera_fake_parameters.html]
[test_camera_hardware_face_detection.html]
--- a/dom/camera/test/test_bug1022766.html
+++ b/dom/camera/test/test_bug1022766.html
@@ -18,17 +18,17 @@ var config = {
recorderProfile: 'cif',
previewSize: {
width: 352,
height: 288
}
};
function onError(e) {
- ok(false, "Error" + JSON.stringify(e));
+ ok(false, "Error " + e);
}
var Camera = {
cameraObj: null,
_otherPictureSize: null,
get viewfinder() {
return document.getElementById('viewfinder');
},
@@ -44,17 +44,17 @@ var Camera = {
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: "
+ ok(error.name == "NS_ERROR_IN_PROGRESS", "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();
@@ -62,29 +62,30 @@ var Camera = {
failureTwo: function test_failureTwo(error) {
ok(false, "Second call to autoFocus() failed unexpectedly with: " + error);
},
callback: function test_callback(focused) {
Camera.callbackTriggered = true;
},
start: function test_start() {
- function onSuccess(camera, config) {
+ function onSuccess(d) {
+ var camera = d.camera;
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.onAutoFocusCompleted = Camera.callback;
- camera.autoFocus(Camera.successOne, Camera.failureOne);
- camera.autoFocus(Camera.successTwo, Camera.failureTwo);
+ camera.autoFocus().then(Camera.successOne, Camera.failureOne);
+ camera.autoFocus().then(Camera.successTwo, Camera.failureTwo);
};
- navigator.mozCameras.getCamera(whichCamera, config, onSuccess, onError);
+ navigator.mozCameras.getCamera(whichCamera, config).then(onSuccess, onError);
}
}
window.addEventListener('beforeunload', function() {
Camera.viewfinder.mozSrcObject = null;
if (Camera.cameraObj) {
Camera.cameraObj.release();
Camera.cameraObj = null;
--- a/dom/camera/test/test_bug1037322.html
+++ b/dom/camera/test/test_bug1037322.html
@@ -41,33 +41,35 @@ var Camera = {
cfg.previewSize.height === config.previewSize.height,
"Configured preview size = " + cfg.previewSize.width + "x" + cfg.previewSize.height);
ok(cfg.recorderProfile === config.recorderProfile,
"Configured recorder profile = '" + cfg.recorderProfile + "'");
SimpleTest.finish();
}
- function getCamera_onSuccess(camera, cfg) {
+ function getCamera_onSuccess(d) {
+ var camera = d.camera;
+ var cfg = d.configuration;
Camera.cameraObj = camera;
Camera.viewfinder.mozSrcObject = camera;
Camera.viewfinder.play();
// Check the default configuration
ok(cfg.mode === "unspecified", "Initial mode = " + cfg.mode);
ok(cfg.previewSize.width === 0 && cfg.previewSize.height === 0,
"Initial preview size = " + cfg.previewSize.width + "x" + cfg.previewSize.height);
ok(cfg.recorderProfile === "",
"Initial recorder profile = '" + cfg.recorderProfile + "'");
// Apply our specific configuration
- camera.setConfiguration(config, setConfig_onSuccess, onError);
+ camera.setConfiguration(config).then(setConfig_onSuccess, onError);
}
- navigator.mozCameras.getCamera(whichCamera, {}, getCamera_onSuccess, onError);
+ navigator.mozCameras.getCamera(whichCamera, {}).then(getCamera_onSuccess, onError);
}
}
SimpleTest.waitForExplicitFinish();
window.addEventListener('beforeunload', function() {
Camera.viewfinder.mozSrcObject = null;
if (Camera.cameraObj) {
--- a/dom/camera/test/test_bug975472.html
+++ b/dom/camera/test/test_bug975472.html
@@ -26,17 +26,17 @@ var options = {
position: {
latitude: 43.645687,
longitude: -79.393661
},
dateTime: Date.now()
};
function onError(e) {
- ok(false, "Error" + JSON.stringify(e));
+ ok(false, "Error " + e);
}
function next() {
Camera.nextTest();
}
// The array of tests
var tests = [
{
@@ -44,17 +44,17 @@ var tests = [
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);
+ camera.release().then(onSuccess, onError);
}
},
{
key: "set-picture-size-after-release",
func: function testSetPictureSize(camera) {
camera.setPictureSize({ width: 0, height: 0 });
next();
}
@@ -82,73 +82,72 @@ var tests = [
},
{
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);
+ ok(error.name === "NS_ERROR_NOT_INITIALIZED", "autoFocus() failed with: " + error);
next();
}
- camera.autoFocus(onSuccess, onError);
+ camera.autoFocus().then(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);
+ ok(error.name === "NS_ERROR_NOT_INITIALIZED", "takePicture() failed with: " + error);
next();
}
- camera.takePicture(null, onSuccess, onError);
+ camera.takePicture(null).then(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);
+ ok(error.name === "NS_ERROR_FAILURE", "startRecording() failed with: " + error);
next();
}
var recordingOptions = {
profile: 'cif',
rotation: 0
};
camera.startRecording(recordingOptions,
navigator.getDeviceStorage('videos'),
- 'bug975472.mp4',
- onSuccess, onError);
+ 'bug975472.mp4').then(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);
+ ok(error.name === "NS_ERROR_NOT_INITIALIZED", "setConfiguration() failed with: " + error);
next();
}
- camera.setConfiguration(config, onSuccess, onError);
+ camera.setConfiguration(config).then(onSuccess, onError);
}
},
];
var testGenerator = function() {
for (var i = 0; i < tests.length; ++i ) {
yield tests[i];
}
@@ -178,37 +177,39 @@ var Camera = {
// 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) {
+ function onSuccess(d) {
+ var camera = d.camera;
Camera.cameraObj = camera;
+ var onPreviewStateChange = function(e) {
+ if (e.newState === 'started') {
+ info("viewfinder is ready and playing");
+ Camera.cameraObj.removeEventListener('previewstatechange', onPreviewStateChange);
+ Camera.onCameraReady();
+ }
+ };
+ camera.addEventListener('previewstatechange', onPreviewStateChange);
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);
+ navigator.mozCameras.getCamera(whichCamera, config).then(onSuccess, onError);
}
}
SimpleTest.waitForExplicitFinish();
window.addEventListener('beforeunload', function() {
Camera.viewfinder.mozSrcObject = null;
Camera.cameraObj.release();
--- a/dom/camera/test/test_camera.html
+++ b/dom/camera/test/test_camera.html
@@ -24,17 +24,17 @@ var options = {
var config = {
dateTime: Date.now() / 1000,
pictureSize: null,
fileFormat: 'jpeg',
rotation: 90
};
function onError(e) {
- ok(false, "Error" + JSON.stringify(e));
+ ok(false, "Error " + e);
}
var capabilities = [ 'previewSizes', 'pictureSizes', 'fileFormats', 'maxFocusAreas', 'minExposureCompensation',
'maxExposureCompensation', 'stepExposureCompensation', 'maxMeteringAreas', 'videoSizes',
'recorderProfiles', 'zoomRatios', 'isoModes'];
var Camera = {
cameraObj: null,
@@ -97,22 +97,27 @@ var Camera = {
},
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) {
+ ok(blob.size > 100 , "Blob Size Gathered = " + blob.size);
+ ok("image/" + test.fileFormat == blob.type, "Blob Type = " + blob.type);
+ },
+ takePictureEvent: function taken_foto_evt(e) {
+ var blob = e.data;
var img = new Image();
var test = this._currentTest;
img.onload = function Imgsize() {
- ok(this.width == test.pictureSize.width, "The image taken has the width " +
+ 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 " +
+ 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();
}
@@ -191,43 +196,46 @@ var Camera = {
},
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);
+ Camera.cameraObj.takePicture(config).then(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);
},
+ onPreviewStateChange: function onPreviewStateChange(e) {
+ if (e.newState === 'started') {
+ ok(true, "viewfinder is ready and playing");
+ Camera.cameraObj.removeEventListener('previewstatechange', Camera.onPreviewStateChange);
+ Camera.onReady();
+ }
+ },
setUp: function setup_tests() {
- function onSuccess(camera) {
- Camera.cameraObj = camera;
- Camera.viewfinder.mozSrcObject = camera;
+ function onSuccess(d) {
+ Camera.cameraObj = d.camera;
+ Camera.cameraObj.addEventListener('previewstatechange', Camera.onPreviewStateChange);
+ Camera.cameraObj.addEventListener('configurationchanged', Camera.onConfigChange);
+ Camera.cameraObj.addEventListener('shutter', Camera.shutter);
+ Camera.cameraObj.addEventListener('picture', Camera.takePictureEvent.bind(Camera));
+ Camera.viewfinder.mozSrcObject = d.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;
+ Camera.cameraObj.setConfiguration(options).then(Camera.onConfigChange, onError);
};
- navigator.mozCameras.getCamera(whichCamera, null, onSuccess, onError);
+ navigator.mozCameras.getCamera(whichCamera, null).then(onSuccess, onError);
}
}
SimpleTest.waitForExplicitFinish();
window.addEventListener('beforeunload', function() {
Camera.viewfinder.mozSrcObject = null;
Camera.cameraObj.release();
--- a/dom/camera/test/test_camera_2.html
+++ b/dom/camera/test/test_camera_2.html
@@ -24,17 +24,17 @@ var options = {
var config = {
dateTime: Date.now() / 1000,
pictureSize: null,
fileFormat: 'jpeg',
rotation: 90
};
function onError(e) {
- ok(false, "Error" + JSON.stringify(e));
+ ok(false, "Error " + e);
}
var capabilities = [ 'previewSizes', 'pictureSizes', 'fileFormats', 'maxFocusAreas', 'minExposureCompensation',
'maxExposureCompensation', 'stepExposureCompensation', 'maxMeteringAreas', 'videoSizes',
'recorderProfiles'];
var Camera = {
cameraObj: null,
@@ -108,29 +108,37 @@ var Camera = {
}
}
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");
},
+ onPreviewStateChange: function onPreviewStateChange(e) {
+ ok(true, "viewfinder state change " + e);
+ if (e.newState === 'started') {
+ ok(true, "viewfinder is ready and playing");
+ Camera.cameraObj.removeEventListener('previewstatechange', Camera.onPreviewStateChange);
+ Camera.onReady();
+ }
+ },
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();
@@ -152,40 +160,35 @@ var Camera = {
},
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);
+ Camera.cameraObj.takePicture(config).then(this.takePictureSuccess.bind(this), onError);
},
setUp: function setup_tests() {
- function onSuccess(camera, config) {
+ function onSuccess(d) {
+ var config = d.configuration;
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.cameraObj = d.camera;
+ Camera.cameraObj.addEventListener('previewstatechange', Camera.onPreviewStateChange);
+ Camera.cameraObj.addEventListener('shutter', Camera.shutter);
+ Camera.viewfinder.mozSrcObject = d.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);
+ navigator.mozCameras.getCamera(whichCamera, options).then(onSuccess, onError);
}
}
SimpleTest.waitForExplicitFinish();
window.addEventListener('beforeunload', function() {
Camera.viewfinder.mozSrcObject = null;
Camera.cameraObj.release();
--- a/dom/camera/test/test_camera_3.html
+++ b/dom/camera/test/test_camera_3.html
@@ -17,51 +17,52 @@ var options = {
recorderProfile: 'cif',
previewSize: {
width: 352,
height: 288
}
};
function onError(e) {
- ok(false, "Error" + JSON.stringify(e));
+ ok(false, "Error " + 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 onSuccess(d) {
+ ok(false, "Unexpectedly got second camera instance: " + d.config.toSource);
}
function onFailure(error) {
ok(true, "Correctly failed to get camera again");
SimpleTest.finish();
}
- navigator.mozCameras.getCamera(whichCamera, options, onSuccess, onFailure);
+ navigator.mozCameras.getCamera(whichCamera, options).then(onSuccess, onFailure);
+ },
+ onPreviewStateChange: function onPreviewStateChange(e) {
+ if (e.newState === 'started') {
+ ok(true, "viewfinder is ready and playing");
+ Camera.cameraObj.removeEventListener('previewstatechange', Camera.onPreviewStateChange);
+ Camera.onReady();
+ }
},
release: function release() {
cameraObj = null;
},
start: function run_test() {
- function onSuccess(camera, config) {
- Camera.cameraObj = camera;
- Camera.viewfinder.mozSrcObject = camera;
+ function onSuccess(d) {
+ Camera.cameraObj = d.camera;
+ Camera.cameraObj.addEventListener('previewstatechange', Camera.onPreviewStateChange);
+ Camera.viewfinder.mozSrcObject = d.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);
+ navigator.mozCameras.getCamera(whichCamera, options).then(onSuccess, onError);
}
}
SimpleTest.waitForExplicitFinish();
window.addEventListener('beforeunload', function() {
Camera.viewfinder.mozSrcObject = null;
Camera.cameraObj.release();
--- a/dom/camera/test/test_camera_fake_parameters.html
+++ b/dom/camera/test/test_camera_fake_parameters.html
@@ -23,17 +23,17 @@ var initialConfig = {
height: 288
}
};
var cameraObj = null;
// Shorthand functions
function onError(e) {
- ok(false, "Error" + JSON.stringify(e));
+ ok(false, "Error " + e);
}
function end() {
CameraTest.end();
}
function next() {
if (cameraObj) {
cameraObj.release(
@@ -422,30 +422,29 @@ CameraTest.begin("hardware", function(te
ok(false, "getCamera() failed with: " + error);
end();
}
CameraTest.next = function() {
try {
var t = testGenerator.next();
info("test: " + t.key);
- function onSuccess(camera, config) {
- cameraObj = camera;
- document.getElementById('viewfinder').mozSrcObject = camera;
- camera.onPreviewStateChange = function (state) {
- if (state === "started") {
- t.test(camera, camera.capabilities);
- } else {
- ok(false, "preview started (state = '" + state + "')");
+ function onSuccess(d) {
+ cameraObj = d.camera;
+ document.getElementById('viewfinder').mozSrcObject = d.camera;
+ var onPreviewStateChange = function (evt) {
+ if (evt.newState === "started") {
+ cameraObj.removeEventListener('previewstatechange', onPreviewStateChange);
+ t.test(cameraObj, cameraObj.capabilities);
}
- camera.onPreviewStateChange = null;
};
+ cameraObj.addEventListener('previewstatechange', onPreviewStateChange);
}
CameraTest.run = function() {
- navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError);
+ navigator.mozCameras.getCamera(whichCamera, initialConfig).then(onSuccess, onError);
};
t.prep(test);
} catch(e) {
if (e instanceof StopIteration) {
end();
} else {
throw e;
}
--- a/dom/camera/test/test_camera_hardware_auto_focus_moving_cb.html
+++ b/dom/camera/test/test_camera_hardware_auto_focus_moving_cb.html
@@ -48,35 +48,26 @@ function end() {
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");
+ var handler = function(evt) {
+ camera.removeEventListener("focus", handler);
+ ok(evt.newState == "focusing", "autofocus event state focusing == " + evt.newState);
camera.focusMode = 'auto';
next();
}
+ camera.addEventListener("focus", handler);
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];
}
}();
@@ -95,37 +86,37 @@ CameraTest.begin("hardware", function(te
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;
+ function onSuccess(d) {
+ document.getElementById('viewfinder').mozSrcObject = d.camera;
+ cameraObj = d.camera;
CameraTest.next = function() {
try {
var t = testGenerator.next();
- test.set(t.key, t.func.bind(undefined, camera));
+ test.set(t.key, t.func.bind(undefined, d.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);
+ navigator.mozCameras.getCamera(whichCamera, initialConfig).then(onSuccess, onError);
})
});
</script>
</body>
</html>
--- a/dom/camera/test/test_camera_hardware_face_detection.html
+++ b/dom/camera/test/test_camera_hardware_face_detection.html
@@ -145,22 +145,26 @@ var tests = [
y: 10
},
mouth: {
x: 11,
y: 12
}
} ]
};
- camera.onFacesDetected = function(aFaces) {
- ok(compareFaces(aFaces, expected),
- "onFaceDetected received the detected faces correctly");
+
+ var handler = function(evt) {
+ ok(compareFaces(evt.faces, expected),
+ "facedetected event received the detected faces correctly");
camera.stopFaceDetection();
+ camera.removeEventListener('facesdetected', handler);
next();
- }
+ };
+
+ camera.addEventListener('facesdetected', handler);
camera.startFaceDetection();
}
},
{
key: "face-detection-detected-two-faces",
func: function testFaceDetectionFoundTwoFace(camera) {
var expected = {
faces: [ {
@@ -203,22 +207,26 @@ var tests = [
y: 22
},
mouth: {
x: 23,
y: 24
}
} ]
};
- camera.onFacesDetected = function(aFaces) {
- ok(compareFaces(aFaces, expected),
- "onFaceDetected received the detected faces correctly");
+
+ var handler = function(evt) {
+ ok(compareFaces(evt.faces, expected),
+ "facedetected event received the detected faces correctly");
camera.stopFaceDetection();
+ camera.removeEventListener('facesdetected', handler);
next();
- }
+ };
+
+ camera.addEventListener('facesdetected', handler);
camera.startFaceDetection();
}
},
{
key: "face-detection-detected-one-face-no-features",
func: function (camera) {
var expected = {
faces: [ {
@@ -230,37 +238,45 @@ var tests = [
right: 5,
bottom: 6
},
leftEye: null,
rightEye: null,
mouth: null
} ]
};
- camera.onFacesDetected = function(aFaces) {
- ok(compareFaces(aFaces, expected),
- "onFaceDetected received the detected faces correctly");
+
+ var handler = function(evt) {
+ ok(compareFaces(evt.faces, expected),
+ "facedetected event received the detected faces correctly");
camera.stopFaceDetection();
+ camera.removeEventListener('facesdetected', handler);
next();
- }
+ };
+
+ camera.addEventListener('facesdetected', handler);
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");
+
+ var handler = function(evt) {
+ ok(compareFaces(evt.faces, expected),
+ "facedetected event received the detected faces correctly");
camera.stopFaceDetection();
+ camera.removeEventListener('facesdetected', handler);
next();
- }
+ };
+
+ camera.addEventListener('facesdetected', handler);
camera.startFaceDetection();
}
},
];
var testGenerator = function() {
for (var i = 0; i < tests.length; ++i ) {
yield tests[i];
@@ -284,37 +300,37 @@ CameraTest.begin("hardware", function(te
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;
+ function onSuccess(d) {
+ cameraObj = d.camera;
+ document.getElementById('viewfinder').mozSrcObject = cameraObj;
CameraTest.next = function() {
try {
var t = testGenerator.next();
- test.set(t.key, t.func.bind(undefined, camera));
+ test.set(t.key, t.func.bind(undefined, cameraObj));
} 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);
+ navigator.mozCameras.getCamera(whichCamera, initialConfig).then(onSuccess, onError);
})
});
</script>
</body>
</html>
--- a/dom/camera/test/test_camera_hardware_failures.html
+++ b/dom/camera/test/test_camera_hardware_failures.html
@@ -45,17 +45,17 @@ var tests = [
function onSuccess(success) {
ok(false, "autoFocus() succeeded incorrectly");
end();
}
function onError(error) {
ok(true, "autoFocus() failed correctly with: " + error);
next();
}
- camera.autoFocus(onSuccess, onError);
+ camera.autoFocus().then(onSuccess, onError);
}
},
{
key: "auto-focus-process-failure",
func: function testAutoFocusProcessFailure(camera) {
function onSuccess(success) {
if (success) {
ok(false, "autoFocus() process succeeded incorrectly");
@@ -64,45 +64,45 @@ var tests = [
ok(true, "autoFocus() process failed correctly");
next();
}
}
function onError(error) {
ok(false, "autoFocus() process failed incorrectly with: " + error);
end();
}
- camera.autoFocus(onSuccess, onError);
+ camera.autoFocus().then(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);
+ camera.takePicture(null).then(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);
+ camera.takePicture(null).then(onSuccess, onError);
}
},
];
var testGenerator = function() {
for (var i = 0; i < tests.length; ++i ) {
yield tests[i];
}
@@ -110,36 +110,36 @@ var testGenerator = function() {
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;
+ function onSuccess(d) {
+ cameraObj = d.camera;
+ document.getElementById('viewfinder').mozSrcObject = cameraObj;
CameraTest.next = function() {
try {
var t = testGenerator.next();
- test.set(t.key, t.func.bind(undefined, camera));
+ test.set(t.key, t.func.bind(undefined, cameraObj));
} 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);
+ navigator.mozCameras.getCamera(whichCamera, initialConfig).then(onSuccess, onError);
});
</script>
</body>
</html>
--- a/dom/camera/test/test_camera_hardware_init_failure.html
+++ b/dom/camera/test/test_camera_hardware_init_failure.html
@@ -29,46 +29,46 @@ var initialConfig = {
}
};
var tests = [
{
name: "init-failure",
key: "init-failure",
func: function testInitFailure(test) {
- function onSuccess(camera, config) {
+ function onSuccess(d) {
ok(false, "onSuccess called incorrectly");
- camera.release();
+ d.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);
+ navigator.mozCameras.getCamera(whichCamera, initialConfig).then(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) {
+ function onSuccess(d) {
ok(true, "onSuccess called correctly");
- camera.release();
+ d.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)
+ navigator.mozCameras.getCamera(whichCamera, initialConfig).then(onSuccess, onError)
}
}
];
var testGenerator = function() {
for (var i = 0; i < tests.length; ++i ) {
yield tests[i];
}
--- a/dom/events/test/test_all_synthetic_events.html
+++ b/dom/events/test/test_all_synthetic_events.html
@@ -71,16 +71,28 @@ const kEventConstructors = {
CallEvent: { create: function (aName, aProps) {
return new CallEvent(aName, aProps);
},
},
CallGroupErrorEvent: { create: function (aName, aProps) {
return new CallGroupErrorEvent(aName, aProps);
},
},
+ CameraConfigurationEvent: { create: function (aName, aProps) {
+ return new CameraConfigurationEvent(aName, aProps);
+ },
+ },
+ CameraFacesDetectedEvent: { create: function (aName, aProps) {
+ return new CameraFacesDetectedEvent(aName, aProps);
+ },
+ },
+ CameraStateChangeEvent: { create: function (aName, aProps) {
+ return new CameraStateChangeEvent(aName, aProps);
+ },
+ },
CFStateChangeEvent: { create: function (aName, aProps) {
return new CFStateChangeEvent(aName, aProps);
},
},
CloseEvent: { create: function (aName, aProps) {
return new CloseEvent(aName, aProps);
},
},
--- a/dom/interfaces/html/nsIDOMHTMLMediaElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLMediaElement.idl
@@ -3,18 +3,16 @@
/* 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 "nsIDOMHTMLElement.idl"
#include "nsIDOMMediaError.idl"
#include "nsIDOMTimeRanges.idl"
-interface nsIDOMMediaStream;
-
/**
* The nsIDOMHTMLMediaElement interface is an interface to be implemented by the HTML
* <audio> and <video> elements.
*
* For more information on this interface, please see
* http://www.whatwg.org/specs/web-apps/current-work/#htmlmediaelement
*
* @status UNDER_DEVELOPMENT
@@ -30,17 +28,16 @@ interface nsIDOMMediaStream;
[uuid(c041d76c-15ce-47ad-b61d-e8755a6db638)]
interface nsIDOMHTMLMediaElement : nsISupports
{
// error state
readonly attribute nsIDOMMediaError error;
// network state
attribute DOMString src;
- attribute nsIDOMMediaStream mozSrcObject;
readonly attribute DOMString currentSrc;
const unsigned short NETWORK_EMPTY = 0;
const unsigned short NETWORK_IDLE = 1;
const unsigned short NETWORK_LOADING = 2;
const unsigned short NETWORK_NO_SOURCE = 3;
readonly attribute unsigned short networkState;
attribute DOMString preload;
readonly attribute nsIDOMTimeRanges buffered;
@@ -74,18 +71,16 @@ interface nsIDOMHTMLMediaElement : nsISu
// controls
attribute boolean controls;
attribute double volume;
attribute boolean muted;
attribute boolean defaultMuted;
// Mozilla extension: stream capture
- nsIDOMMediaStream mozCaptureStream();
- nsIDOMMediaStream mozCaptureStreamUntilEnded();
readonly attribute boolean mozAudioCaptured;
// Mozilla extension: return embedded metadata from the stream as a
// JSObject with key:value pairs for each tag. This can be used by
// player interfaces to display the song title, artist, etc.
[implicit_jscontext]
jsval mozGetMetadata();
--- a/dom/media/bridge/IPeerConnection.idl
+++ b/dom/media/bridge/IPeerConnection.idl
@@ -1,13 +1,12 @@
#include "nsIThread.idl"
#include "nsIDOMWindow.idl"
#include "nsIPropertyBag2.idl"
-interface nsIDOMMediaStream;
interface nsIDOMDataChannel;
/*
* Manager interface to PeerConnection.js so it is accessible from C++.
*/
[scriptable, uuid(c2218bd2-2648-4701-8fa6-305d3379e9f8)]
interface IPeerConnectionManager : nsISupports
{
--- a/dom/media/moz.build
+++ b/dom/media/moz.build
@@ -12,17 +12,16 @@ if CONFIG['MOZ_WEBRTC']:
'/media/webrtc/signaling/src/common',
'/media/webrtc/trunk',
]
MOCHITEST_MANIFESTS += ['tests/mochitest/mochitest.ini']
WEBRTC_SIGNALLING_TEST_MANIFESTS += ['tests/mochitest/steeplechase.ini']
XPIDL_SOURCES += [
- 'nsIDOMMediaStream.idl',
'nsIDOMNavigatorUserMedia.idl',
'nsIMediaManager.idl',
]
XPIDL_MODULE = 'dom_media'
EXPORTS.mozilla.dom += [
'GetUserMediaRequest.h',
deleted file mode 100644
--- a/dom/media/nsIDOMMediaStream.idl
+++ /dev/null
@@ -1,27 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-
-// undef the GetCurrentTime macro defined in WinBase.h from the MS Platform SDK
-%{C++
-#ifdef GetCurrentTime
-#undef GetCurrentTime
-#endif
-%}
-
-[builtinclass, uuid(3ef760bb-ff19-4dbb-b552-af27ab84b9b8)]
-interface nsIDOMMediaStream : nsISupports
-{
- /* Placeholder interface only; will be removed after further WebIDL conversion.
- Do not add anything here. */
-};
-
-[builtinclass, uuid(dd37150a-9823-4605-ac4c-3516629a8aaf)]
-interface nsIDOMLocalMediaStream : nsIDOMMediaStream
-{
- /* Placeholder interface only; will be removed after further WebIDL conversion.
- Do not add anything here. */
-};
--- a/dom/media/nsIDOMNavigatorUserMedia.idl
+++ b/dom/media/nsIDOMNavigatorUserMedia.idl
@@ -1,15 +1,14 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
#include "nsIVariant.idl"
-#include "nsIDOMMediaStream.idl"
[scriptable, builtinclass, uuid(4af2bdb7-1547-4d10-8886-02a78c3c0b83)]
interface nsIMediaDevice : nsISupports
{
readonly attribute DOMString type;
readonly attribute DOMString name;
readonly attribute DOMString id;
readonly attribute DOMString facingMode;
@@ -22,17 +21,17 @@ interface nsIGetUserMediaDevicesSuccessC
void onSuccess(in nsIVariant devices);
};
[scriptable, function, uuid(f2a144fc-3534-4761-8c5d-989ae720f89a)]
interface nsIDOMGetUserMediaSuccessCallback : nsISupports
{
/*
* value must be a nsIDOMBlob if picture is true and a
- * nsIDOMLocalMediaStream if either audio or video are true.
+ * DOMLocalMediaStream if either audio or video are true.
*/
void onSuccess(in nsISupports value);
};
[scriptable, function, uuid(2614bbcf-85cc-43e5-8740-964f52bdc7ca)]
interface nsIDOMGetUserMediaErrorCallback : nsISupports
{
void onError(in DOMString error);
--- a/dom/telephony/Telephony.cpp
+++ b/dom/telephony/Telephony.cpp
@@ -595,18 +595,18 @@ Telephony::EnumerateCallState(uint32_t a
nsRefPtr<TelephonyCall> call = GetCallFromEverywhere(aServiceId, aCallIndex);
if (call) {
return NS_OK;
}
// Didn't know anything about this call before now.
nsRefPtr<TelephonyCallId> id = CreateCallId(aNumber, aNumberPresentation,
aName, aNamePresentation);
- CreateCall(id, aServiceId, aCallIndex, aCallState,
- aIsEmergency, aIsConference, aIsSwitchable, aIsMergeable);
+ call = CreateCall(id, aServiceId, aCallIndex, aCallState,
+ aIsEmergency, aIsConference, aIsSwitchable, aIsMergeable);
return NS_OK;
}
NS_IMETHODIMP
Telephony::SupplementaryServiceNotification(uint32_t aServiceId,
int32_t aCallIndex,
uint16_t aNotification)
--- a/dom/tests/mochitest/general/test_interfaces.html
+++ b/dom/tests/mochitest/general/test_interfaces.html
@@ -196,22 +196,28 @@ var interfaceNamesInGlobalScope =
{name: "BoxObject", xbl: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "CallEvent", b2g: true, pref: "dom.telephony.enabled"},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "CallGroupErrorEvent", b2g: true, pref: "dom.telephony.enabled"},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "CameraCapabilities", b2g: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
+ {name: "CameraConfigurationEvent", b2g: true},
+// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "CameraControl", b2g: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "CameraDetectedFace", b2g: true, pref: "camera.control.face_detection.enabled"},
// IMPORTANT: Do not change this list without review from a DOM peer!
+ {name: "CameraFacesDetectedEvent", b2g: true, pref: "camera.control.face_detection.enabled"},
+// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "CameraManager", b2g: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
+ {name: "CameraStateChangeEvent", b2g: true},
+// IMPORTANT: Do not change this list without review from a DOM peer!
"CanvasGradient",
// IMPORTANT: Do not change this list without review from a DOM peer!
"CanvasPattern",
// IMPORTANT: Do not change this list without review from a DOM peer!
"CanvasRenderingContext2D",
// IMPORTANT: Do not change this list without review from a DOM peer!
"CaretPosition",
// IMPORTANT: Do not change this list without review from a DOM peer!
new file mode 100644
--- /dev/null
+++ b/dom/webidl/CameraConfigurationEvent.webidl
@@ -0,0 +1,20 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+[Func="Navigator::HasCameraSupport",
+ Constructor(DOMString type, optional CameraConfigurationEventInit eventInitDict)]
+interface CameraConfigurationEvent : Event
+{
+ readonly attribute CameraMode mode;
+ readonly attribute DOMString recorderProfile;
+ readonly attribute DOMRectReadOnly? previewSize;
+};
+
+dictionary CameraConfigurationEventInit : EventInit
+{
+ CameraMode mode = "picture";
+ DOMString recorderProfile = "cif";
+ DOMRectReadOnly? previewSize = null;
+};
--- a/dom/webidl/CameraControl.webidl
+++ b/dom/webidl/CameraControl.webidl
@@ -230,30 +230,58 @@ interface CameraControl : MediaStream
value is "auto" if supported. */
[Throws]
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
+ a shutter sound and/or a visual shutter indicator.
+
+ contains no event-specific data. */
+ attribute EventHandler onshutter;
+
/* the function to call when the camera hardware is closed
by the underlying framework, e.g. when another app makes a more
recent call to get the camera. */
attribute CameraClosedCallback? onClosed;
+ /* the event dispatched when the camera hardware is closed
+ by the underlying framework, e.g. when another app makes a more
+ recent call to get the camera.
+
+ contains no event-specific data. */
+ 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 recording process encountered an error, or because one of the
+ recording limits (see CameraStartRecordingOptions) was reached.
+
+ event type is CameraStateChangeEvent where:
+ 'newState' is the new recorder state */
+ 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,
+ useful for synchronizing other UI elements.
+
+ event type is CameraStateChangeEvent where:
+ 'newState' is the new preview state */
+ attribute EventHandler onpreviewstatechange;
+
/* the size of the picture to be returned by a call to takePicture();
an object with 'height' and 'width' properties that corresponds to
one of the options returned by capabilities.pictureSizes. */
[Throws]
CameraSize getPictureSize();
[Throws]
void setPictureSize(optional CameraSize size);
@@ -282,17 +310,35 @@ interface CameraControl : MediaStream
/* the angle, in degrees, that the image sensor is mounted relative
to the display; e.g. if 'sensorAngle' is 270 degrees (or -90 degrees),
then the preview stream needs to be rotated +90 degrees to have the
same orientation as the real world. */
readonly attribute long sensorAngle;
/* tell the camera to attempt to focus the image */
[Throws]
- void autoFocus(CameraAutoFocusCallback onSuccess, optional CameraErrorCallback onError);
+ Promise<boolean> autoFocus(optional CameraAutoFocusCallback onSuccess,
+ optional CameraErrorCallback onError);
+
+ /* the event dispatched whenever the focus state changes due to calling
+ autoFocus or due to continuous autofocus.
+
+ if continuous autofocus is supported and focusMode is set to enable it,
+ then this event is dispatched 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.
+
+ event type is CameraStateChangeEvent where:
+ 'newState' is one of the following states:
+ 'focused' if the focus is now set
+ 'focusing' if the focus is moving
+ 'unfocused' if last attempt to focus failed */
+ 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"]
@@ -304,28 +350,33 @@ interface CameraControl : MediaStream
/* 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
already recording video.
invoking this function will stop the preview stream, which must be
manually restarted (e.g. by calling .play() on it). */
[Throws]
- void takePicture(CameraPictureOptions aOptions,
- CameraTakePictureCallback onSuccess,
- optional CameraErrorCallback onError);
+ Promise<Blob> takePicture(optional CameraPictureOptions aOptions,
+ optional CameraTakePictureCallback onSuccess,
+ optional CameraErrorCallback onError);
+
+ /* the event dispatched when a picture is successfully taken; it is of the
+ type BlobEvent, where the data attribute contains the picture. */
+ attribute EventHandler onpicture;
- /* start recording video; 'aOptions' is a
- CameraStartRecordingOptions object. */
+ /* start recording video; 'aOptions' is a CameraStartRecordingOptions object.
+ If the success/error callbacks are not used, one may determine success by
+ waiting for the recorderstatechange event. */
[Throws]
- void startRecording(CameraStartRecordingOptions aOptions,
- DeviceStorage storageArea,
- DOMString filename,
- CameraStartRecordingCallback onSuccess,
- optional CameraErrorCallback onError);
+ Promise<void> startRecording(CameraStartRecordingOptions aOptions,
+ DeviceStorage storageArea,
+ DOMString filename,
+ optional CameraStartRecordingCallback onSuccess,
+ optional CameraErrorCallback onError);
/* stop precording video. */
[Throws]
void stopRecording();
/* call in or after the takePicture() onSuccess callback to
resume the camera preview stream. */
[Throws]
@@ -336,31 +387,40 @@ interface CameraControl : MediaStream
(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
defunct; a new instance will need to be created to access the camera. */
[Throws]
- void release(optional CameraReleaseCallback onSuccess,
- optional CameraErrorCallback onError);
+ Promise<void> release(optional CameraReleaseCallback onSuccess,
+ optional CameraErrorCallback onError);
/* 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]
- void setConfiguration(optional CameraConfiguration configuration,
- optional CameraSetConfigurationCallback onSuccess,
- optional CameraErrorCallback onError);
+ Promise<CameraConfiguration> setConfiguration(optional CameraConfiguration configuration,
+ optional CameraSetConfigurationCallback onSuccess,
+ optional CameraErrorCallback onError);
+
+ /* the event dispatched when the camera is successfully configured.
+
+ event type is CameraConfigurationEvent where:
+ 'mode' is the selected camera mode
+ 'recorderProfile' is the selected profile
+ 'width' contains the preview width
+ 'height' contains the preview height */
+ attribute EventHandler onconfigurationchange;
/* if focusMode is set to either 'continuous-picture' or 'continuous-video',
then calling autoFocus() will trigger its onSuccess callback immediately
if the camera was either successfully focused, or if no focus could be
acquired; if the focus acquisition is still in progress, the onSuccess
callback will be invoked later, its argument indicating success or
failure.
@@ -452,9 +512,13 @@ partial interface CameraControl
*/
[Throws, Pref="camera.control.face_detection.enabled"]
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 */
+ [Pref="camera.control.face_detection.enabled"]
+ attribute EventHandler onfacesdetected;
};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/CameraFacesDetectedEvent.webidl
@@ -0,0 +1,18 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+[Pref="camera.control.face_detection.enabled",
+ Func="Navigator::HasCameraSupport",
+ Constructor(DOMString type, optional CameraFacesDetectedEventInit eventInitDict)]
+interface CameraFacesDetectedEvent : Event
+{
+ [Pure, Cached]
+ readonly attribute sequence<CameraDetectedFace>? faces;
+};
+
+dictionary CameraFacesDetectedEventInit : EventInit
+{
+ sequence<CameraDetectedFace>? faces = null;
+};
--- a/dom/webidl/CameraManager.webidl
+++ b/dom/webidl/CameraManager.webidl
@@ -31,19 +31,19 @@ callback GetCameraCallback = void (Camer
[Func="nsDOMCameraManager::HasSupport"]
interface CameraManager
{
/* get a camera instance; 'camera' is one of the camera
identifiers returned by getListOfCameras() below.
*/
[Throws]
- void getCamera(DOMString camera,
- CameraConfiguration initialConfiguration,
- GetCameraCallback callback,
- optional CameraErrorCallback errorCallback);
+ Promise<CameraGetPromiseData> getCamera(DOMString camera,
+ optional CameraConfiguration initialConfiguration,
+ optional GetCameraCallback callback,
+ optional CameraErrorCallback errorCallback);
/* return an array of camera identifiers, e.g.
[ "front", "back" ]
*/
[Throws]
sequence<DOMString> getListOfCameras();
};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/CameraStateChangeEvent.webidl
@@ -0,0 +1,16 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+[Func="Navigator::HasCameraSupport",
+ Constructor(DOMString type, optional CameraStateChangeEventInit eventInitDict)]
+interface CameraStateChangeEvent : Event
+{
+ readonly attribute DOMString newState;
+};
+
+dictionary CameraStateChangeEventInit : EventInit
+{
+ DOMString newState = "";
+};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/CameraUtil.webidl
@@ -0,0 +1,12 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ */
+
+dictionary CameraGetPromiseData
+{
+ CameraControl? camera = null;
+ CameraConfiguration configuration;
+};
--- a/dom/webidl/MediaStream.webidl
+++ b/dom/webidl/MediaStream.webidl
@@ -16,17 +16,17 @@
dictionary MediaStreamConstraints {
(boolean or MediaTrackConstraints) audio = false;
(boolean or MediaTrackConstraints) video = false;
boolean picture = false; // Mozilla legacy
boolean fake = false; // for testing
DOMString? peerIdentity = null;
};
-interface MediaStream {
+interface MediaStream : EventTarget {
// readonly attribute DOMString id;
sequence<AudioStreamTrack> getAudioTracks();
sequence<VideoStreamTrack> getVideoTracks();
sequence<MediaStreamTrack> getTracks();
// MediaStreamTrack getTrackById (DOMString trackId);
// void addTrack (MediaStreamTrack track);
// void removeTrack (MediaStreamTrack track);
// attribute boolean ended;
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -52,16 +52,17 @@ WEBIDL_FILES = [
'BeforeUnloadEvent.webidl',
'BiquadFilterNode.webidl',
'Blob.webidl',
'BrowserElementDictionaries.webidl',
'CallsList.webidl',
'CameraCapabilities.webidl',
'CameraControl.webidl',
'CameraManager.webidl',
+ 'CameraUtil.webidl',
'CanvasRenderingContext2D.webidl',
'CaretPosition.webidl',
'CDATASection.webidl',
'ChannelMergerNode.webidl',
'ChannelSplitterNode.webidl',
'CharacterData.webidl',
'ChildNode.webidl',
'ChromeNotifications.webidl',
@@ -644,16 +645,19 @@ if CONFIG['MOZ_B2G_FM']:
'FMRadio.webidl',
]
GENERATED_EVENTS_WEBIDL_FILES = [
'AutocompleteErrorEvent.webidl',
'BlobEvent.webidl',
'CallEvent.webidl',
'CallGroupErrorEvent.webidl',
+ 'CameraConfigurationEvent.webidl',
+ 'CameraFacesDetectedEvent.webidl',
+ 'CameraStateChangeEvent.webidl',
'CFStateChangeEvent.webidl',
'CloseEvent.webidl',
'CSSFontFaceLoadEvent.webidl',
'DataErrorEvent.webidl',
'DataStoreChangeEvent.webidl',
'DeviceLightEvent.webidl',
'DeviceOrientationEvent.webidl',
'DeviceProximityEvent.webidl',
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -698,17 +698,17 @@ PeerConnectionImpl::GetFingerprintHexVal
if (NS_SUCCEEDED(FingerprintSplitHelper(fp, spc))) {
return fp.substr(spc + 1);
}
return "";
}
nsresult
-PeerConnectionImpl::CreateFakeMediaStream(uint32_t aHint, nsIDOMMediaStream** aRetval)
+PeerConnectionImpl::CreateFakeMediaStream(uint32_t aHint, DOMMediaStream** aRetval)
{
MOZ_ASSERT(aRetval);
PC_AUTO_ENTER_API_CALL(false);
bool mute = false;
// Hack to allow you to mute the stream
if (aHint & MEDIA_STREAM_MUTE) {
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
@@ -49,17 +49,16 @@ class AFakePCObserver;
}
#ifdef USE_FAKE_MEDIA_STREAMS
class Fake_DOMMediaStream;
class Fake_MediaStreamTrack;
#endif
class nsGlobalWindow;
-class nsIDOMMediaStream;
class nsDOMDataChannel;
namespace mozilla {
class DataChannel;
class DtlsIdentity;
class NrIceCtx;
class NrIceMediaStream;
class NrIceStunServer;
@@ -290,17 +289,17 @@ public:
// Get the DTLS identity (local side)
mozilla::RefPtr<DtlsIdentity> const GetIdentity() const;
std::string GetFingerprint() const;
std::string GetFingerprintAlgorithm() const;
std::string GetFingerprintHexValue() const;
// Create a fake media stream
- nsresult CreateFakeMediaStream(uint32_t hint, nsIDOMMediaStream** retval);
+ nsresult CreateFakeMediaStream(uint32_t hint, mozilla::DOMMediaStream** retval);
nsPIDOMWindow* GetWindow() const {
PC_AUTO_ENTER_API_CALL_NO_CHECK();
return mWindow;
}
// Initialize PeerConnection from an IceConfiguration object (unit-tests)
nsresult Initialize(PeerConnectionObserver& aObserver,
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
@@ -290,29 +290,27 @@ nsresult PeerConnectionMedia::Init(const
// figure out how to report that StartGathering failed. Bug 827982.
RUN_ON_THREAD(mIceCtx->thread(),
WrapRunnable(mIceCtx, &NrIceCtx::StartGathering), NS_DISPATCH_NORMAL);
return NS_OK;
}
nsresult
-PeerConnectionMedia::AddStream(nsIDOMMediaStream* aMediaStream,
+PeerConnectionMedia::AddStream(DOMMediaStream* aMediaStream,
uint32_t hints,
uint32_t *stream_id)
{
ASSERT_ON_THREAD(mMainThread);
if (!aMediaStream) {
CSFLogError(logTag, "%s - aMediaStream is NULL", __FUNCTION__);
return NS_ERROR_FAILURE;
}
- DOMMediaStream* stream = static_cast<DOMMediaStream*>(aMediaStream);
-
CSFLogDebug(logTag, "%s: MediaStream: %p", __FUNCTION__, aMediaStream);
// Adding tracks here based on nsDOMMediaStream expectation settings
#ifdef MOZILLA_INTERNAL_API
if (!Preferences::GetBool("media.peerconnection.video.enabled", true)) {
hints &= ~(DOMMediaStream::HINT_CONTENTS_VIDEO);
}
#endif
@@ -331,54 +329,52 @@ PeerConnectionMedia::AddStream(nsIDOMMed
for (uint32_t u = 0; u < mLocalSourceStreams.Length(); u++) {
auto& lss = mLocalSourceStreams[u];
if (((hints & DOMMediaStream::HINT_CONTENTS_AUDIO) && lss->AudioTrackCount()) ||
((hints & DOMMediaStream::HINT_CONTENTS_VIDEO) && lss->VideoTrackCount())) {
CSFLogError(logTag, "Only one stream of any given type allowed");
return NS_ERROR_FAILURE;
}
- if (stream == lss->GetMediaStream()) {
+ if (aMediaStream == lss->GetMediaStream()) {
localSourceStream = lss;
*stream_id = u;
break;
}
}
if (!localSourceStream) {
- localSourceStream = new LocalSourceStreamInfo(stream, this);
+ localSourceStream = new LocalSourceStreamInfo(aMediaStream, this);
mLocalSourceStreams.AppendElement(localSourceStream);
*stream_id = mLocalSourceStreams.Length() - 1;
}
if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) {
localSourceStream->ExpectAudio(TRACK_AUDIO);
}
if (hints & DOMMediaStream::HINT_CONTENTS_VIDEO) {
localSourceStream->ExpectVideo(TRACK_VIDEO);
}
return NS_OK;
}
nsresult
-PeerConnectionMedia::RemoveStream(nsIDOMMediaStream* aMediaStream,
+PeerConnectionMedia::RemoveStream(DOMMediaStream* aMediaStream,
uint32_t hints,
uint32_t *stream_id)
{
MOZ_ASSERT(aMediaStream);
ASSERT_ON_THREAD(mMainThread);
- DOMMediaStream* stream = static_cast<DOMMediaStream*>(aMediaStream);
-
CSFLogDebug(logTag, "%s: MediaStream: %p",
__FUNCTION__, aMediaStream);
for (uint32_t u = 0; u < mLocalSourceStreams.Length(); u++) {
nsRefPtr<LocalSourceStreamInfo> localSourceStream = mLocalSourceStreams[u];
- if (localSourceStream->GetMediaStream() == stream) {
+ if (localSourceStream->GetMediaStream() == aMediaStream) {
*stream_id = u;
if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) {
localSourceStream->RemoveAudio(TRACK_AUDIO);
}
if (hints & DOMMediaStream::HINT_CONTENTS_VIDEO) {
localSourceStream->RemoveAudio(TRACK_VIDEO);
}
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
@@ -307,21 +307,21 @@ class PeerConnectionMedia : public sigsl
return mIceStreams[i];
}
size_t num_ice_media_streams() const {
return mIceStreams.size();
}
// Add a stream (main thread only)
- nsresult AddStream(nsIDOMMediaStream* aMediaStream, uint32_t hints,
+ nsresult AddStream(DOMMediaStream* aMediaStream, uint32_t hints,
uint32_t *stream_id);
// Remove a stream (main thread only)
- nsresult RemoveStream(nsIDOMMediaStream* aMediaStream,
+ nsresult RemoveStream(DOMMediaStream* aMediaStream,
uint32_t hints,
uint32_t *stream_id);
// Get a specific local stream
uint32_t LocalStreamsLength()
{
return mLocalSourceStreams.Length();
}
--- a/media/webrtc/signaling/test/FakeMediaStreams.h
+++ b/media/webrtc/signaling/test/FakeMediaStreams.h
@@ -17,17 +17,16 @@
#include "mozilla/Mutex.h"
#include "mozilla/RefPtr.h"
#include "AudioSegment.h"
#include "MediaSegment.h"
#include "StreamBuffer.h"
#include "nsTArray.h"
#include "nsIRunnable.h"
#include "nsISupportsImpl.h"
-#include "nsIDOMMediaStream.h"
class nsIDOMWindow;
namespace mozilla {
class MediaStreamGraph;
class MediaSegment;
};
@@ -227,17 +226,17 @@ public:
const Fake_MediaStreamTrack* AsAudioStreamTrack() const
{
return mIsVideo? nullptr : this;
}
private:
const bool mIsVideo;
};
-class Fake_DOMMediaStream : public nsIDOMMediaStream
+class Fake_DOMMediaStream : public nsISupports
{
protected:
virtual ~Fake_DOMMediaStream() {
// Note: memory leak
mMediaStream->Stop();
}
public:
--- a/media/webrtc/signaling/test/FakeMediaStreamsImpl.h
+++ b/media/webrtc/signaling/test/FakeMediaStreamsImpl.h
@@ -12,17 +12,17 @@
void LogTime(AsyncLatencyLogger::LatencyLogIndex index, uint64_t b, int64_t c) {}
void LogLatency(AsyncLatencyLogger::LatencyLogIndex index, uint64_t b, int64_t c) {}
static const int AUDIO_BUFFER_SIZE = 1600;
static const int NUM_CHANNELS = 2;
static const int GRAPH_RATE = 16000;
-NS_IMPL_ISUPPORTS(Fake_DOMMediaStream, nsIDOMMediaStream)
+NS_IMPL_ISUPPORTS0(Fake_DOMMediaStream)
// Fake_MediaStream
double Fake_MediaStream::StreamTimeToSeconds(mozilla::StreamTime aTime) {
return static_cast<double>(aTime)/GRAPH_RATE;
}
mozilla::StreamTime
Fake_MediaStream::TicksToTimeRoundDown(mozilla::TrackRate aRate,
--- a/media/webrtc/signaling/test/FakePCObserver.h
+++ b/media/webrtc/signaling/test/FakePCObserver.h
@@ -13,17 +13,16 @@
#include "mozilla/Mutex.h"
#include "AudioSegment.h"
#include "MediaSegment.h"
#include "StreamBuffer.h"
#include "nsTArray.h"
#include "nsIRunnable.h"
#include "nsISupportsImpl.h"
-#include "nsIDOMMediaStream.h"
#include "mozilla/dom/PeerConnectionObserverEnumsBinding.h"
#include "PeerConnectionImpl.h"
#include "nsWeakReference.h"
namespace sipcc {
class PeerConnectionImpl;
}
@@ -75,17 +74,17 @@ public:
virtual NS_IMETHODIMP OnCreateAnswerError(uint32_t code, const char *msg, ER&) = 0;
virtual NS_IMETHODIMP OnSetLocalDescriptionSuccess(ER&) = 0;
virtual NS_IMETHODIMP OnSetRemoteDescriptionSuccess(ER&) = 0;
virtual NS_IMETHODIMP OnSetLocalDescriptionError(uint32_t code, const char *msg, ER&) = 0;
virtual NS_IMETHODIMP OnSetRemoteDescriptionError(uint32_t code, const char *msg, ER&) = 0;
virtual NS_IMETHODIMP NotifyDataChannel(nsIDOMDataChannel *channel, ER&) = 0;
virtual NS_IMETHODIMP OnStateChange(mozilla::dom::PCObserverStateType state_type, ER&,
void* = nullptr) = 0;
- virtual NS_IMETHODIMP OnAddStream(nsIDOMMediaStream *stream, ER&) = 0;
+ virtual NS_IMETHODIMP OnAddStream(mozilla::DOMMediaStream *stream, ER&) = 0;
virtual NS_IMETHODIMP OnRemoveStream(ER&) = 0;
virtual NS_IMETHODIMP OnAddTrack(ER&) = 0;
virtual NS_IMETHODIMP OnRemoveTrack(ER&) = 0;
virtual NS_IMETHODIMP OnReplaceTrackSuccess(ER&) = 0;
virtual NS_IMETHODIMP OnReplaceTrackError(uint32_t code, const char *msg, ER&) = 0;
virtual NS_IMETHODIMP OnAddIceCandidateSuccess(ER&) = 0;
virtual NS_IMETHODIMP OnAddIceCandidateError(uint32_t code, const char *msg, ER&) = 0;
virtual NS_IMETHODIMP OnIceCandidate(uint16_t level, const char *mid,
--- a/media/webrtc/signaling/test/signaling_unittests.cpp
+++ b/media/webrtc/signaling/test/signaling_unittests.cpp
@@ -264,17 +264,17 @@ public:
NS_IMETHODIMP OnCreateAnswerSuccess(const char* answer, ER&);
NS_IMETHODIMP OnCreateAnswerError(uint32_t code, const char *msg, ER&);
NS_IMETHODIMP OnSetLocalDescriptionSuccess(ER&);
NS_IMETHODIMP OnSetRemoteDescriptionSuccess(ER&);
NS_IMETHODIMP OnSetLocalDescriptionError(uint32_t code, const char *msg, ER&);
NS_IMETHODIMP OnSetRemoteDescriptionError(uint32_t code, const char *msg, ER&);
NS_IMETHODIMP NotifyDataChannel(nsIDOMDataChannel *channel, ER&);
NS_IMETHODIMP OnStateChange(PCObserverStateType state_type, ER&, void*);
- NS_IMETHODIMP OnAddStream(nsIDOMMediaStream *stream, ER&);
+ NS_IMETHODIMP OnAddStream(DOMMediaStream *stream, ER&);
NS_IMETHODIMP OnRemoveStream(ER&);
NS_IMETHODIMP OnAddTrack(ER&);
NS_IMETHODIMP OnRemoveTrack(ER&);
NS_IMETHODIMP OnReplaceTrackSuccess(ER&);
NS_IMETHODIMP OnReplaceTrackError(uint32_t code, const char *msg, ER&);
NS_IMETHODIMP OnAddIceCandidateSuccess(ER&);
NS_IMETHODIMP OnAddIceCandidateError(uint32_t code, const char *msg, ER&);
NS_IMETHODIMP OnIceCandidate(uint16_t level, const char *mid, const char *cand, ER&);
@@ -424,33 +424,31 @@ TestObserver::OnStateChange(PCObserverSt
}
lastStateType = state_type;
return NS_OK;
}
NS_IMETHODIMP
-TestObserver::OnAddStream(nsIDOMMediaStream *stream, ER&)
+TestObserver::OnAddStream(DOMMediaStream *stream, ER&)
{
PR_ASSERT(stream);
- DOMMediaStream *ms = static_cast<DOMMediaStream *>(stream);
-
- std::cout << name << ": OnAddStream called hints=" << ms->GetHintContents()
+ std::cout << name << ": OnAddStream called hints=" << stream->GetHintContents()
<< " thread=" << PR_GetCurrentThread() << std::endl ;
onAddStreamCalled = true;
- streams.push_back(ms);
+ streams.push_back(stream);
// We know that the media stream is secretly a Fake_SourceMediaStream,
// so now we can start it pulling from us
nsRefPtr<Fake_SourceMediaStream> fs =
- static_cast<Fake_SourceMediaStream *>(ms->GetStream());
+ static_cast<Fake_SourceMediaStream *>(stream->GetStream());
test_utils->sts_target()->Dispatch(
WrapRunnable(fs, &Fake_SourceMediaStream::Start),
NS_DISPATCH_NORMAL);
return NS_OK;
}
--- a/xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp
+++ b/xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp
@@ -97,17 +97,16 @@
#include "nsIDOMHTMLTableCellElement.h"
#include "nsIDOMHTMLTableElement.h"
#include "nsIDOMHTMLTextAreaElement.h"
#include "nsIDOMHTMLTitleElement.h"
#include "nsIDOMHTMLUListElement.h"
#include "nsIDOMKeyEvent.h"
#include "nsIDOMMediaError.h"
#include "nsIDOMMediaList.h"
-#include "nsIDOMMediaStream.h"
#include "nsIDOMMessageEvent.h"
#include "nsIDOMMouseEvent.h"
#include "nsIDOMMouseScrollEvent.h"
#include "nsIDOMMutationEvent.h"
#include "nsIDOMMozNamedAttrMap.h"
#include "nsIDOMNode.h"
#include "nsIDOMNodeIterator.h"
#include "nsIDOMNotifyPaintEvent.h"
@@ -231,20 +230,18 @@
#include "mozilla/dom/HTMLStyleElementBinding.h"
#include "mozilla/dom/HTMLTableCaptionElementBinding.h"
#include "mozilla/dom/HTMLTableCellElementBinding.h"
#include "mozilla/dom/HTMLTableElementBinding.h"
#include "mozilla/dom/HTMLTextAreaElementBinding.h"
#include "mozilla/dom/HTMLTitleElementBinding.h"
#include "mozilla/dom/HTMLUListElementBinding.h"
#include "mozilla/dom/KeyEventBinding.h"
-#include "mozilla/dom/LocalMediaStreamBinding.h"
#include "mozilla/dom/MediaErrorBinding.h"
#include "mozilla/dom/MediaListBinding.h"
-#include "mozilla/dom/MediaStreamBinding.h"
#include "mozilla/dom/MessageEventBinding.h"
#include "mozilla/dom/MouseEventBinding.h"
#include "mozilla/dom/MouseScrollEventBinding.h"
#include "mozilla/dom/MutationEventBinding.h"
#include "mozilla/dom/NamedNodeMapBinding.h"
#include "mozilla/dom/NodeIteratorBinding.h"
#include "mozilla/dom/NodeBinding.h"
#include "mozilla/dom/NotifyPaintEventBinding.h"
@@ -420,20 +417,18 @@ const ComponentsInterfaceShimEntry kComp
DEFINE_SHIM(HTMLStyleElement),
DEFINE_SHIM(HTMLTableCaptionElement),
DEFINE_SHIM(HTMLTableCellElement),
DEFINE_SHIM(HTMLTableElement),
DEFINE_SHIM(HTMLTextAreaElement),
DEFINE_SHIM(HTMLTitleElement),
DEFINE_SHIM(HTMLUListElement),
DEFINE_SHIM(KeyEvent),
- DEFINE_SHIM(LocalMediaStream),
DEFINE_SHIM(MediaError),
DEFINE_SHIM(MediaList),
- DEFINE_SHIM(MediaStream),
DEFINE_SHIM(MessageEvent),
DEFINE_SHIM(MouseEvent),
DEFINE_SHIM(MouseScrollEvent),
DEFINE_SHIM(MutationEvent),
DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIDOMMozNamedAttrMap, NamedNodeMap),
DEFINE_SHIM(NodeIterator),
DEFINE_SHIM(Node),
DEFINE_SHIM(NotifyPaintEvent),