mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 13:55:43 +00:00
Merge m-c to inbound. a=merge
This commit is contained in:
commit
fa9ac0b845
@ -15,7 +15,7 @@
|
||||
<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="83f495a1c12687970f7f2840c2729795c4b88177"/>
|
||||
<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"/>
|
||||
@ -23,7 +23,7 @@
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="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"/>
|
||||
|
@ -19,13 +19,13 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a8a6eed2ba9d66239aac789b9ee4900f911c73cb"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="83f495a1c12687970f7f2840c2729795c4b88177"/>
|
||||
<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"/>
|
||||
|
@ -17,10 +17,10 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a8a6eed2ba9d66239aac789b9ee4900f911c73cb"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="83f495a1c12687970f7f2840c2729795c4b88177"/>
|
||||
<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 -->
|
||||
|
@ -15,7 +15,7 @@
|
||||
<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="83f495a1c12687970f7f2840c2729795c4b88177"/>
|
||||
<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"/>
|
||||
@ -23,7 +23,7 @@
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="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"/>
|
||||
|
@ -19,13 +19,13 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a8a6eed2ba9d66239aac789b9ee4900f911c73cb"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="83f495a1c12687970f7f2840c2729795c4b88177"/>
|
||||
<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"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<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="83f495a1c12687970f7f2840c2729795c4b88177"/>
|
||||
<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"/>
|
||||
@ -23,7 +23,7 @@
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="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"/>
|
||||
|
@ -17,10 +17,10 @@
|
||||
</project>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a8a6eed2ba9d66239aac789b9ee4900f911c73cb"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="83f495a1c12687970f7f2840c2729795c4b88177"/>
|
||||
<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 -->
|
||||
|
@ -4,6 +4,6 @@
|
||||
"remote": "",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "736a08de0dd46c283137a289a484a6b404cb0dd1",
|
||||
"revision": "665042c75b7d6b0a1f4b8f07f79cd998abce68b0",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
@ -17,12 +17,12 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a8a6eed2ba9d66239aac789b9ee4900f911c73cb"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="83f495a1c12687970f7f2840c2729795c4b88177"/>
|
||||
<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"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a8a6eed2ba9d66239aac789b9ee4900f911c73cb"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="83f495a1c12687970f7f2840c2729795c4b88177"/>
|
||||
<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"/>
|
||||
|
@ -17,10 +17,10 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a8a6eed2ba9d66239aac789b9ee4900f911c73cb"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="83f495a1c12687970f7f2840c2729795c4b88177"/>
|
||||
<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 -->
|
||||
|
@ -17,12 +17,12 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a8a6eed2ba9d66239aac789b9ee4900f911c73cb"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="83f495a1c12687970f7f2840c2729795c4b88177"/>
|
||||
<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"/>
|
||||
|
@ -252,6 +252,11 @@ toolbar[customizing] > .overflow-button {
|
||||
|
||||
%endif
|
||||
|
||||
#main-window[inFullscreen] #global-notificationbox,
|
||||
#main-window[inFullscreen] #high-priority-global-notificationbox {
|
||||
visibility: collapse;
|
||||
}
|
||||
|
||||
/* Rules to help integrate SDK widgets */
|
||||
toolbaritem[sdkstylewidget="true"] > toolbarbutton,
|
||||
toolbarpaletteitem > toolbaritem[sdkstylewidget="true"] > iframe,
|
||||
@ -824,23 +829,15 @@ html|*#gcli-output-frame,
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.toolbarbutton-badge[badge]:not([badge=""])::after {
|
||||
content: attr(badge);
|
||||
}
|
||||
|
||||
toolbarbutton[type="badged"] {
|
||||
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#toolbarbutton-badged");
|
||||
}
|
||||
|
||||
toolbarbutton[type="socialmark"] {
|
||||
-moz-binding: url("chrome://browser/content/socialmarks.xml#toolbarbutton-marks");
|
||||
}
|
||||
|
||||
toolbarbutton[type="badged"] > .toolbarbutton-badge-container > .toolbarbutton-icon,
|
||||
toolbarbutton.badged-button > .toolbarbutton-badge-container > .toolbarbutton-icon,
|
||||
toolbarbutton[type="socialmark"] > .toolbarbutton-icon {
|
||||
max-width: 16px;
|
||||
}
|
||||
toolbarpaletteitem[place="palette"] > toolbarbutton[type="badged"] > .toolbarbutton-badge-container > .toolbarbutton-icon {
|
||||
toolbarpaletteitem[place="palette"] > toolbarbutton.badged-button > .toolbarbutton-badge-container > .toolbarbutton-icon {
|
||||
max-width: 32px;
|
||||
}
|
||||
|
||||
|
@ -95,8 +95,8 @@
|
||||
<input id="newtab-customize-button" type="button" title="&newtab.customize.title;"/>
|
||||
</div>
|
||||
|
||||
<xul:script type="text/javascript;version=1.8"
|
||||
src="chrome://browser/content/newtab/newTab.js"/>
|
||||
<xul:script type="text/javascript;version=1.8"
|
||||
src="chrome://browser/content/searchSuggestionUI.js"/>
|
||||
<xul:script type="text/javascript;version=1.8"
|
||||
src="chrome://browser/content/newtab/newTab.js"/>
|
||||
</xul:window>
|
||||
|
@ -2581,20 +2581,4 @@
|
||||
</method>
|
||||
</implementation>
|
||||
</binding>
|
||||
|
||||
<binding id="toolbarbutton-badged" display="xul:button"
|
||||
extends="chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton">
|
||||
<content>
|
||||
<children includes="observes|template|menupopup|panel|tooltip"/>
|
||||
<xul:hbox class="toolbarbutton-badge-container" align="start" pack="end">
|
||||
<xul:hbox class="toolbarbutton-badge" xbl:inherits="badge"/>
|
||||
<xul:image class="toolbarbutton-icon" xbl:inherits="validate,src=image,label"/>
|
||||
</xul:hbox>
|
||||
<xul:label class="toolbarbutton-text" crop="right" flex="1"
|
||||
xbl:inherits="value=label,accesskey,crop,wrap"/>
|
||||
<xul:label class="toolbarbutton-multiline-text" flex="1"
|
||||
xbl:inherits="xbl:text=label,accesskey,wrap"/>
|
||||
</content>
|
||||
</binding>
|
||||
|
||||
</bindings>
|
||||
|
@ -915,7 +915,7 @@ const CustomizableWidgets = [
|
||||
node.setAttribute("id", this.id);
|
||||
node.classList.add("toolbarbutton-1");
|
||||
node.classList.add("chromeclass-toolbar-additional");
|
||||
node.setAttribute("type", "badged");
|
||||
node.classList.add("badged-button");
|
||||
node.setAttribute("label", CustomizableUI.getLocalizedProperty(this, "label"));
|
||||
node.setAttribute("tooltiptext", CustomizableUI.getLocalizedProperty(this, "tooltiptext"));
|
||||
node.setAttribute("removable", "true");
|
||||
|
@ -113,6 +113,7 @@ skip-if = os == "linux" # Intemittent failures - bug 979207
|
||||
[browser_969661_character_encoding_navbar_disabled.js]
|
||||
[browser_970511_undo_restore_default.js]
|
||||
[browser_972267_customizationchange_events.js]
|
||||
[browser_973641_button_addon.js]
|
||||
[browser_973932_addonbar_currentset.js]
|
||||
[browser_975719_customtoolbars_behaviour.js]
|
||||
|
||||
|
72
browser/components/customizableui/test/browser_973641_button_addon.js
Executable file
72
browser/components/customizableui/test/browser_973641_button_addon.js
Executable file
@ -0,0 +1,72 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const kButton = "test_button_for_addon";
|
||||
let initialLocation = gBrowser.currentURI.spec;
|
||||
|
||||
add_task(function() {
|
||||
info("Check addon button functionality");
|
||||
|
||||
// create mocked addon button on the navigation bar
|
||||
let widgetSpec = {
|
||||
id: kButton,
|
||||
type: 'button',
|
||||
onClick: function() {
|
||||
gBrowser.selectedTab = gBrowser.addTab("about:addons");
|
||||
}
|
||||
};
|
||||
CustomizableUI.createWidget(widgetSpec);
|
||||
CustomizableUI.addWidgetToArea(kButton, CustomizableUI.AREA_NAVBAR);
|
||||
|
||||
// check the button's functionality in navigation bar
|
||||
let addonButton = document.getElementById(kButton);
|
||||
let navBar = document.getElementById("nav-bar");
|
||||
ok(addonButton, "Addon button exists");
|
||||
ok(navBar.contains(addonButton), "Addon button is in the navbar");
|
||||
yield checkButtonFunctionality(addonButton);
|
||||
|
||||
resetTabs();
|
||||
|
||||
//move the add-on button in the Panel Menu
|
||||
CustomizableUI.addWidgetToArea(kButton, CustomizableUI.AREA_PANEL);
|
||||
let addonButtonInNavbar = navBar.getElementsByAttribute("id", kButton);
|
||||
ok(!navBar.contains(addonButton), "Addon button was removed from the browser bar");
|
||||
|
||||
// check the addon button's functionality in the Panel Menu
|
||||
yield PanelUI.show();
|
||||
var panelMenu = document.getElementById("PanelUI-mainView");
|
||||
let addonButtonInPanel = panelMenu.getElementsByAttribute("id", kButton);
|
||||
ok(panelMenu.contains(addonButton), "Addon button was added to the Panel Menu");
|
||||
yield checkButtonFunctionality(addonButtonInPanel[0]);
|
||||
});
|
||||
|
||||
add_task(function asyncCleanup() {
|
||||
resetTabs();
|
||||
|
||||
// reset the UI to the default state
|
||||
yield resetCustomization();
|
||||
ok(CustomizableUI.inDefaultState, "The UI is in default state again.");
|
||||
|
||||
// destroy the widget
|
||||
CustomizableUI.destroyWidget(kButton);
|
||||
});
|
||||
|
||||
function resetTabs() {
|
||||
//close all opened tabs
|
||||
while(gBrowser.tabs.length > 1) {
|
||||
gBrowser.removeTab(gBrowser.selectedTab);
|
||||
}
|
||||
|
||||
//restore the initial tab
|
||||
gBrowser.addTab(initialLocation);
|
||||
gBrowser.removeTab(gBrowser.selectedTab);
|
||||
}
|
||||
|
||||
function checkButtonFunctionality(aButton) {
|
||||
aButton.click();
|
||||
yield waitForCondition(() => gBrowser.currentURI &&
|
||||
gBrowser.currentURI.spec == "about:addons");
|
||||
}
|
@ -2,14 +2,15 @@
|
||||
* 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/. */
|
||||
|
||||
const Cu = Components.utils;
|
||||
const {utils: Cu, interfaces: Ci} = Components;
|
||||
Cu.import("resource:///modules/devtools/gDevTools.jsm");
|
||||
const {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
|
||||
const {require} = devtools;
|
||||
const {ConnectionManager, Connection} = require("devtools/client/connection-manager");
|
||||
const promise = require("devtools/toolkit/deprecated-sync-thenables");
|
||||
const prefs = require('sdk/preferences/service');
|
||||
|
||||
const prefs = require("sdk/preferences/service");
|
||||
const Services = require("Services");
|
||||
const Strings = Services.strings.createBundle("chrome://browser/locale/devtools/app-manager.properties");
|
||||
|
||||
let UI = {
|
||||
_toolboxTabCursor: 0,
|
||||
@ -34,6 +35,7 @@ let UI = {
|
||||
let defaultPanel = prefs.get("devtools.appmanager.lastTab");
|
||||
let panelExists = !!document.querySelector("." + defaultPanel + "-panel");
|
||||
this.selectTab(panelExists ? defaultPanel : "projects");
|
||||
this.showDeprecationNotice();
|
||||
},
|
||||
|
||||
onUnload: function() {
|
||||
@ -178,7 +180,33 @@ let UI = {
|
||||
} else {
|
||||
return gDevTools.showToolbox(target, null, host);
|
||||
}
|
||||
},
|
||||
|
||||
showDeprecationNotice: function() {
|
||||
let message = Strings.GetStringFromName("index.deprecationNotice");
|
||||
|
||||
let buttons = [
|
||||
{
|
||||
label: Strings.GetStringFromName("index.launchWebIDE"),
|
||||
callback: gDevToolsBrowser.openWebIDE
|
||||
},
|
||||
{
|
||||
label: Strings.GetStringFromName("index.readMoreAboutWebIDE"),
|
||||
callback: () => {
|
||||
window.open("https://developer.mozilla.org/docs/Tools/WebIDE");
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
let docShell = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShell);
|
||||
let browser = docShell.chromeEventHandler;
|
||||
let nbox = browser.ownerDocument.defaultView.gBrowser
|
||||
.getNotificationBox(browser);
|
||||
nbox.appendNotification(message, "app-manager-deprecation", null,
|
||||
nbox.PRIORITY_WARNING_LOW, buttons);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
UI.init();
|
||||
|
@ -370,12 +370,14 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
|
||||
this._onContextCopyUrlCommand = this.copyUrl.bind(this);
|
||||
this._onContextCopyImageAsDataUriCommand = this.copyImageAsDataUri.bind(this);
|
||||
this._onContextResendCommand = this.cloneSelectedRequest.bind(this);
|
||||
this._onContextToggleRawHeadersCommand = this.toggleRawHeaders.bind(this);
|
||||
this._onContextPerfCommand = () => NetMonitorView.toggleFrontendMode();
|
||||
this._onReloadCommand = () => NetMonitorView.reloadPage();
|
||||
|
||||
this.sendCustomRequestEvent = this.sendCustomRequest.bind(this);
|
||||
this.closeCustomRequestEvent = this.closeCustomRequest.bind(this);
|
||||
this.cloneSelectedRequestEvent = this.cloneSelectedRequest.bind(this);
|
||||
this.toggleRawHeadersEvent = this.toggleRawHeaders.bind(this);
|
||||
|
||||
$("#toolbar-labels").addEventListener("click", this.requestsMenuSortEvent, false);
|
||||
$("#requests-menu-footer").addEventListener("click", this.requestsMenuFilterEvent, false);
|
||||
@ -384,6 +386,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
|
||||
$("#request-menu-context-newtab").addEventListener("command", this._onContextNewTabCommand, false);
|
||||
$("#request-menu-context-copy-url").addEventListener("command", this._onContextCopyUrlCommand, false);
|
||||
$("#request-menu-context-copy-image-as-data-uri").addEventListener("command", this._onContextCopyImageAsDataUriCommand, false);
|
||||
$("#toggle-raw-headers").addEventListener("click", this.toggleRawHeadersEvent, false);
|
||||
|
||||
window.once("connected", this._onConnect.bind(this));
|
||||
},
|
||||
@ -447,6 +450,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
|
||||
$("#custom-request-send-button").removeEventListener("click", this.sendCustomRequestEvent, false);
|
||||
$("#custom-request-close-button").removeEventListener("click", this.closeCustomRequestEvent, false);
|
||||
$("#headers-summary-resend").removeEventListener("click", this.cloneSelectedRequestEvent, false);
|
||||
$("#toggle-raw-headers").removeEventListener("click", this.toggleRawHeadersEvent, false);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -638,6 +642,28 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
|
||||
NetMonitorView.Sidebar.toggle(false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Shows raw request/response headers in textboxes.
|
||||
*/
|
||||
toggleRawHeaders: function() {
|
||||
let requestTextarea = $("#raw-request-headers-textarea");
|
||||
let responseTextare = $("#raw-response-headers-textarea");
|
||||
let rawHeadersHidden = $("#raw-headers").getAttribute("hidden");
|
||||
|
||||
if (rawHeadersHidden) {
|
||||
let selected = this.selectedItem.attachment;
|
||||
let selectedRequestHeaders = selected.requestHeaders.headers;
|
||||
let selectedResponseHeaders = selected.responseHeaders.headers;
|
||||
requestTextarea.value = writeHeaderText(selectedRequestHeaders);
|
||||
responseTextare.value = writeHeaderText(selectedResponseHeaders);
|
||||
$("#raw-headers").hidden = false;
|
||||
} else {
|
||||
requestTextarea.value = null;
|
||||
responseTextare.value = null;
|
||||
$("#raw-headers").hidden = true;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Filters all network requests in this container by a specified type.
|
||||
*
|
||||
@ -2013,6 +2039,7 @@ NetworkDetailsView.prototype = {
|
||||
$("#response-content-info-header").hidden = true;
|
||||
$("#response-content-json-box").hidden = true;
|
||||
$("#response-content-textarea-box").hidden = true;
|
||||
$("#raw-headers").hidden = true;
|
||||
$("#response-content-image-box").hidden = true;
|
||||
|
||||
let isHtml = RequestsMenuView.prototype.isHtml({ attachment: aData });
|
||||
|
@ -307,6 +307,9 @@
|
||||
<button id="headers-summary-resend"
|
||||
class="devtools-toolbarbutton"
|
||||
label="&netmonitorUI.summary.editAndResend;"/>
|
||||
<button id="toggle-raw-headers"
|
||||
class="devtools-toolbarbutton"
|
||||
label="&netmonitorUI.summary.rawHeaders;"/>
|
||||
</hbox>
|
||||
<hbox id="headers-summary-version"
|
||||
class="tabpanel-summary-container"
|
||||
@ -318,6 +321,25 @@
|
||||
crop="end"
|
||||
flex="1"/>
|
||||
</hbox>
|
||||
<hbox id="raw-headers"
|
||||
class="tabpanel-summary-container"
|
||||
align="center"
|
||||
hidden="true">
|
||||
<vbox id="raw-request-headers-textarea-box" flex="1" hidden="false">
|
||||
<label class="plain tabpanel-summary-label"
|
||||
value="&netmonitorUI.summary.rawHeaders.requestHeaders;"/>
|
||||
<textbox id="raw-request-headers-textarea"
|
||||
class="raw-response-textarea"
|
||||
flex="1" multiline="true" readonly="true"/>
|
||||
</vbox>
|
||||
<vbox id="raw-response-headers-textarea-box" flex="1" hidden="false">
|
||||
<label class="plain tabpanel-summary-label"
|
||||
value="&netmonitorUI.summary.rawHeaders.responseHeaders;"/>
|
||||
<textbox id="raw-response-headers-textarea"
|
||||
class="raw-response-textarea"
|
||||
flex="1" multiline="true" readonly="true"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
<vbox id="all-headers" flex="1"/>
|
||||
</vbox>
|
||||
</tabpanel>
|
||||
|
@ -77,6 +77,7 @@ skip-if= buildapp == 'mulet'
|
||||
[browser_net_post-data-03.js]
|
||||
[browser_net_prefs-and-l10n.js]
|
||||
[browser_net_prefs-reload.js]
|
||||
[browser_net_raw_headers.js]
|
||||
[browser_net_reload-button.js]
|
||||
[browser_net_req-resp-bodies.js]
|
||||
[browser_net_resend.js]
|
||||
|
72
browser/devtools/netmonitor/test/browser_net_raw_headers.js
Normal file
72
browser/devtools/netmonitor/test/browser_net_raw_headers.js
Normal file
@ -0,0 +1,72 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
let gPanelWin;
|
||||
let gPanelDoc;
|
||||
|
||||
/**
|
||||
* Tests if showing raw headers works.
|
||||
*/
|
||||
|
||||
function test() {
|
||||
initNetMonitor(POST_DATA_URL).then(([aTab, aDebuggee, aMonitor]) => {
|
||||
info("Starting test... ");
|
||||
|
||||
gPanelWin = aMonitor.panelWin;
|
||||
gPanelDoc = gPanelWin.document;
|
||||
|
||||
let { document, Editor, NetMonitorView } = gPanelWin;
|
||||
let { RequestsMenu } = NetMonitorView;
|
||||
let TAB_UPDATED = gPanelWin.EVENTS.TAB_UPDATED;
|
||||
|
||||
RequestsMenu.lazyUpdate = false;
|
||||
|
||||
waitForNetworkEvents(aMonitor, 0, 2).then(() => {
|
||||
let origItem = RequestsMenu.getItemAtIndex(0);
|
||||
RequestsMenu.selectedItem = origItem;
|
||||
|
||||
waitFor(aMonitor.panelWin, TAB_UPDATED).then(() => {
|
||||
EventUtils.sendMouseEvent({ type: "click" }, document.getElementById("toggle-raw-headers"));
|
||||
testShowRawHeaders(origItem.attachment);
|
||||
EventUtils.sendMouseEvent({ type: "click" }, document.getElementById("toggle-raw-headers"));
|
||||
testHideRawHeaders(document);
|
||||
finishUp(aMonitor);
|
||||
});
|
||||
});
|
||||
|
||||
aDebuggee.performRequests();
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests that raw headers were displayed correctly
|
||||
*/
|
||||
function testShowRawHeaders(aData) {
|
||||
let requestHeaders = gPanelDoc.getElementById("raw-request-headers-textarea").value;
|
||||
for (let header of aData.requestHeaders.headers) {
|
||||
ok(requestHeaders.indexOf(header.name + ": " + header.value) >= 0, "textarea contains request headers");
|
||||
}
|
||||
let responseHeaders = gPanelDoc.getElementById("raw-response-headers-textarea").value;
|
||||
for (let header of aData.responseHeaders.headers) {
|
||||
ok(responseHeaders.indexOf(header.name + ": " + header.value) >= 0, "textarea contains response headers");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests that raw headers textareas are hidden and empty
|
||||
*/
|
||||
function testHideRawHeaders(document) {
|
||||
let rawHeadersHidden = document.getElementById("raw-headers").getAttribute("hidden");
|
||||
let requestTextarea = document.getElementById("raw-request-headers-textarea");
|
||||
let responseTextare = document.getElementById("raw-response-headers-textarea");
|
||||
ok(rawHeadersHidden, "raw headers textareas are hidden");
|
||||
ok(requestTextarea.value == '', "raw request headers textarea is empty");
|
||||
ok(responseTextare.value == '', "raw response headers textarea is empty");
|
||||
}
|
||||
|
||||
function finishUp(aMonitor) {
|
||||
gPanelWin = null;
|
||||
gPanelDoc = null;
|
||||
|
||||
teardown(aMonitor).then(finish);
|
||||
}
|
@ -107,11 +107,19 @@
|
||||
<label class="plain call-tree-header"
|
||||
type="duration"
|
||||
crop="end"
|
||||
value="&profilerUI.table.duration;"/>
|
||||
value="&profilerUI.table.totalDuration;"/>
|
||||
<label class="plain call-tree-header"
|
||||
type="self-duration"
|
||||
crop="end"
|
||||
value="&profilerUI.table.selfDuration;"/>
|
||||
<label class="plain call-tree-header"
|
||||
type="percentage"
|
||||
crop="end"
|
||||
value="&profilerUI.table.percentage;"/>
|
||||
value="&profilerUI.table.totalPercentage;"/>
|
||||
<label class="plain call-tree-header"
|
||||
type="self-percentage"
|
||||
crop="end"
|
||||
value="&profilerUI.table.selfPercentage;"/>
|
||||
<label class="plain call-tree-header"
|
||||
type="samples"
|
||||
crop="end"
|
||||
|
@ -22,9 +22,9 @@ function test() {
|
||||
is(container.childNodes[0].className, "call-tree-item",
|
||||
"The root node in the tree has the correct class name.");
|
||||
|
||||
is(container.childNodes[0].childNodes.length, 4,
|
||||
is(container.childNodes[0].childNodes.length, 6,
|
||||
"The root node in the tree has the correct number of children.");
|
||||
is(container.childNodes[0].querySelectorAll(".call-tree-cell").length, 4,
|
||||
is(container.childNodes[0].querySelectorAll(".call-tree-cell").length, 6,
|
||||
"The root node in the tree has only 'call-tree-cell' children.");
|
||||
|
||||
is(container.childNodes[0].childNodes[0].getAttribute("type"), "duration",
|
||||
@ -32,19 +32,29 @@ function test() {
|
||||
is(container.childNodes[0].childNodes[0].getAttribute("value"), "18",
|
||||
"The root node in the tree has the correct duration cell value.");
|
||||
|
||||
is(container.childNodes[0].childNodes[1].getAttribute("type"), "percentage",
|
||||
is(container.childNodes[0].childNodes[1].getAttribute("type"), "self-duration",
|
||||
"The root node in the tree has a self-duration cell.");
|
||||
is(container.childNodes[0].childNodes[1].getAttribute("value"), "0",
|
||||
"The root node in the tree has the correct self-duration cell value.");
|
||||
|
||||
is(container.childNodes[0].childNodes[2].getAttribute("type"), "percentage",
|
||||
"The root node in the tree has a percentage cell.");
|
||||
is(container.childNodes[0].childNodes[1].getAttribute("value"), "100%",
|
||||
is(container.childNodes[0].childNodes[2].getAttribute("value"), "100%",
|
||||
"The root node in the tree has the correct percentage cell value.");
|
||||
|
||||
is(container.childNodes[0].childNodes[2].getAttribute("type"), "samples",
|
||||
is(container.childNodes[0].childNodes[3].getAttribute("type"), "self-percentage",
|
||||
"The root node in the tree has a self-percentage cell.");
|
||||
is(container.childNodes[0].childNodes[3].getAttribute("value"), "0%",
|
||||
"The root node in the tree has the correct self-percentage cell value.");
|
||||
|
||||
is(container.childNodes[0].childNodes[4].getAttribute("type"), "samples",
|
||||
"The root node in the tree has an samples cell.");
|
||||
is(container.childNodes[0].childNodes[2].getAttribute("value"), "3",
|
||||
is(container.childNodes[0].childNodes[4].getAttribute("value"), "3",
|
||||
"The root node in the tree has the correct samples cell value.");
|
||||
|
||||
is(container.childNodes[0].childNodes[3].getAttribute("type"), "function",
|
||||
is(container.childNodes[0].childNodes[5].getAttribute("type"), "function",
|
||||
"The root node in the tree has a function cell.");
|
||||
is(container.childNodes[0].childNodes[3].style.MozMarginStart, "0px",
|
||||
is(container.childNodes[0].childNodes[5].style.MozMarginStart, "0px",
|
||||
"The root node in the tree has the correct indentation.");
|
||||
|
||||
finish();
|
||||
|
@ -42,18 +42,22 @@ function test() {
|
||||
ok(!A.target.querySelector(".call-tree-category").hidden,
|
||||
"The .A.B.C node's category label cell should not be hidden.");
|
||||
|
||||
is(C.target.childNodes.length, 4,
|
||||
is(C.target.childNodes.length, 6,
|
||||
"The number of columns displayed for tree items is correct.");
|
||||
is(C.target.childNodes[0].getAttribute("type"), "duration",
|
||||
"The first column displayed for tree items is correct.");
|
||||
is(C.target.childNodes[1].getAttribute("type"), "percentage",
|
||||
is(C.target.childNodes[1].getAttribute("type"), "self-duration",
|
||||
"The second column displayed for tree items is correct.");
|
||||
is(C.target.childNodes[2].getAttribute("type"), "samples",
|
||||
is(C.target.childNodes[2].getAttribute("type"), "percentage",
|
||||
"The third column displayed for tree items is correct.");
|
||||
is(C.target.childNodes[3].getAttribute("type"), "function",
|
||||
is(C.target.childNodes[3].getAttribute("type"), "self-percentage",
|
||||
"The fourth column displayed for tree items is correct.");
|
||||
is(C.target.childNodes[4].getAttribute("type"), "samples",
|
||||
"The fifth column displayed for tree items is correct.");
|
||||
is(C.target.childNodes[5].getAttribute("type"), "function",
|
||||
"The sixth column displayed for tree items is correct.");
|
||||
|
||||
let functionCell = C.target.childNodes[3];
|
||||
let functionCell = C.target.childNodes[5];
|
||||
|
||||
is(functionCell.childNodes.length, 8,
|
||||
"The number of columns displayed for function cells is correct.");
|
||||
|
@ -18,6 +18,9 @@ const ZOOM_BUTTON_TOOLTIP = L10N.getStr("table.zoom.tooltiptext");
|
||||
const CALL_TREE_INDENTATION = 16; // px
|
||||
const CALL_TREE_AUTO_EXPAND = 3; // depth
|
||||
|
||||
const clamp = (val, min, max) => Math.max(min, Math.min(max, val));
|
||||
const sum = vals => vals.reduce((a, b) => a + b, 0);
|
||||
|
||||
exports.CallView = CallView;
|
||||
|
||||
/**
|
||||
@ -63,10 +66,17 @@ CallView.prototype = Heritage.extend(AbstractTreeItem.prototype, {
|
||||
this.document = document;
|
||||
|
||||
let frameInfo = this.frame.getInfo();
|
||||
let framePercentage = this.frame.samples / this.root.frame.samples * 100;
|
||||
let framePercentage = this._getPercentage(this.frame.samples);
|
||||
let childrenPercentage = sum([this._getPercentage(c.samples)
|
||||
for (c of this._getChildCalls())]);
|
||||
let selfPercentage = clamp(framePercentage - childrenPercentage, 0, 100);
|
||||
let selfDuration = this.frame.duration - sum([c.duration
|
||||
for (c of this._getChildCalls())]);
|
||||
|
||||
let durationCell = this._createTimeCell(this.frame.duration);
|
||||
let selfDurationCell = this._createTimeCell(selfDuration, true);
|
||||
let percentageCell = this._createExecutionCell(framePercentage);
|
||||
let selfPercentageCell = this._createExecutionCell(selfPercentage, true);
|
||||
let samplesCell = this._createSamplesCell(this.frame.samples);
|
||||
let functionCell = this._createFunctionCell(arrowNode, frameInfo, this.level);
|
||||
|
||||
@ -83,13 +93,29 @@ CallView.prototype = Heritage.extend(AbstractTreeItem.prototype, {
|
||||
}
|
||||
|
||||
targetNode.appendChild(durationCell);
|
||||
targetNode.appendChild(selfDurationCell);
|
||||
targetNode.appendChild(percentageCell);
|
||||
targetNode.appendChild(selfPercentageCell);
|
||||
targetNode.appendChild(samplesCell);
|
||||
targetNode.appendChild(functionCell);
|
||||
|
||||
return targetNode;
|
||||
},
|
||||
|
||||
/**
|
||||
* Calculate what percentage of all samples the given number of samples is.
|
||||
*/
|
||||
_getPercentage: function (samples) {
|
||||
return samples / this.root.frame.samples * 100;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return an array of this frame's child calls.
|
||||
*/
|
||||
_getChildCalls: function () {
|
||||
return Object.keys(this.frame.calls).map(k => this.frame.calls[k]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Populates this node in the call tree with the corresponding "callees".
|
||||
* These are defined in the `frame` data source for this call view.
|
||||
@ -98,7 +124,7 @@ CallView.prototype = Heritage.extend(AbstractTreeItem.prototype, {
|
||||
_populateSelf: function(children) {
|
||||
let newLevel = this.level + 1;
|
||||
|
||||
for (let [, newFrame] of _Iterator(this.frame.calls)) {
|
||||
for (let newFrame of this._getChildCalls()) {
|
||||
children.push(new CallView({
|
||||
caller: this,
|
||||
frame: newFrame,
|
||||
@ -114,18 +140,18 @@ CallView.prototype = Heritage.extend(AbstractTreeItem.prototype, {
|
||||
* Functions creating each cell in this call view.
|
||||
* Invoked by `_displaySelf`.
|
||||
*/
|
||||
_createTimeCell: function(duration) {
|
||||
_createTimeCell: function(duration, isSelf = false) {
|
||||
let cell = this.document.createElement("label");
|
||||
cell.className = "plain call-tree-cell";
|
||||
cell.setAttribute("type", "duration");
|
||||
cell.setAttribute("type", isSelf ? "self-duration" : "duration");
|
||||
cell.setAttribute("crop", "end");
|
||||
cell.setAttribute("value", L10N.numberWithDecimals(duration, 2));
|
||||
return cell;
|
||||
},
|
||||
_createExecutionCell: function(percentage) {
|
||||
_createExecutionCell: function(percentage, isSelf = false) {
|
||||
let cell = this.document.createElement("label");
|
||||
cell.className = "plain call-tree-cell";
|
||||
cell.setAttribute("type", "percentage");
|
||||
cell.setAttribute("type", isSelf ? "self-percentage" : "percentage");
|
||||
cell.setAttribute("crop", "end");
|
||||
cell.setAttribute("value", L10N.numberWithDecimals(percentage, 2) + "%");
|
||||
return cell;
|
||||
|
@ -752,6 +752,7 @@ let UI = {
|
||||
let playCmd = document.querySelector("#cmd_play");
|
||||
let stopCmd = document.querySelector("#cmd_stop");
|
||||
let debugCmd = document.querySelector("#cmd_toggleToolbox");
|
||||
let playButton = document.querySelector('#action-button-play');
|
||||
|
||||
if (!AppManager.selectedProject || AppManager.connection.status != Connection.Status.CONNECTED) {
|
||||
playCmd.setAttribute("disabled", "true");
|
||||
@ -760,9 +761,11 @@ let UI = {
|
||||
} else {
|
||||
let isProjectRunning = AppManager.isProjectRunning();
|
||||
if (isProjectRunning) {
|
||||
playButton.classList.add("reload");
|
||||
stopCmd.removeAttribute("disabled");
|
||||
debugCmd.removeAttribute("disabled");
|
||||
} else {
|
||||
playButton.classList.remove("reload");
|
||||
stopCmd.setAttribute("disabled", "true");
|
||||
debugCmd.setAttribute("disabled", "true");
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 29 KiB |
@ -54,13 +54,13 @@ window.busy-determined #action-busy-undetermined {
|
||||
|
||||
.panel-button-anchor {
|
||||
list-style-image: url('icons.png');
|
||||
-moz-image-region: rect(0px,391px,16px,364px);
|
||||
-moz-image-region: rect(0px,491px,16px,464px);
|
||||
width: 12px;
|
||||
height: 7px;
|
||||
}
|
||||
|
||||
.panel-button:hover > .panel-button-anchor {
|
||||
-moz-image-region: rect(0px,445px,16px,418px);
|
||||
-moz-image-region: rect(0px,545px,16px,518px);
|
||||
}
|
||||
|
||||
/* Panel buttons - projects */
|
||||
@ -83,7 +83,7 @@ window.busy-determined #action-busy-undetermined {
|
||||
|
||||
#project-panel-button.no-project > .panel-button-image {
|
||||
list-style-image: url("icons.png");
|
||||
-moz-image-region: rect(260px,338px,286px,312px);
|
||||
-moz-image-region: rect(260px,438px,286px,412px);
|
||||
}
|
||||
|
||||
#project-panel-button > .panel-button-label {
|
||||
@ -94,13 +94,13 @@ window.busy-determined #action-busy-undetermined {
|
||||
|
||||
#runtime-panel-button > .panel-button-image {
|
||||
list-style-image: url('icons.png');
|
||||
-moz-image-region: rect(78px,338px,104px,312px);
|
||||
-moz-image-region: rect(78px,438px,104px,412px);
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
}
|
||||
|
||||
#runtime-panel-button[active="true"] > .panel-button-image {
|
||||
-moz-image-region: rect(78px,364px,104px,338px);
|
||||
-moz-image-region: rect(78px,464px,104px,438px);
|
||||
}
|
||||
|
||||
/* Action buttons */
|
||||
@ -134,6 +134,9 @@ window.busy-determined #action-busy-undetermined {
|
||||
#action-button-stop:not([disabled="true"]):hover { -moz-image-region: rect(200px,200px,300px,100px) }
|
||||
#action-button-debug:not([disabled="true"]):not([active="true"]):hover { -moz-image-region: rect(200px,300px,300px,200px) }
|
||||
|
||||
#action-button-play.reload { -moz-image-region: rect(0,400px,100px,303px) }
|
||||
#action-button-play.reload:hover { -moz-image-region: rect(200px,400px,300px,303px) }
|
||||
|
||||
#action-button-debug[active="true"] { -moz-image-region: rect(100px,300px,200px,200px) }
|
||||
|
||||
/* Panels */
|
||||
@ -196,9 +199,9 @@ panel > .panel-arrowcontainer > .panel-arrowcontent {
|
||||
list-style-image: url("icons.png");
|
||||
}
|
||||
|
||||
.project-panel-item-newapp { -moz-image-region: rect(234px,338px,260px,312px) }
|
||||
.project-panel-item-openpackaged { -moz-image-region: rect(260px,338px,286px,312px) }
|
||||
.project-panel-item-openhosted { -moz-image-region: rect(208px,338px,234px,312px) }
|
||||
.project-panel-item-newapp { -moz-image-region: rect(234px,438px,260px,412px) }
|
||||
.project-panel-item-openpackaged { -moz-image-region: rect(260px,438px,286px,412px) }
|
||||
.project-panel-item-openhosted { -moz-image-region: rect(208px,438px,234px,412px) }
|
||||
|
||||
/* runtime panel */
|
||||
|
||||
@ -224,17 +227,17 @@ panel > .panel-arrowcontainer > .panel-arrowcontent {
|
||||
list-style-image: url("icons.png");
|
||||
}
|
||||
|
||||
#runtime-details { -moz-image-region: rect(156px,338px,182px,312px) }
|
||||
#runtime-screenshot { -moz-image-region: rect(130px,338px,156px,312px) }
|
||||
#runtime-permissions { -moz-image-region: rect(104px,338px,130px,312px) }
|
||||
#runtime-disconnect { -moz-image-region: rect(52px,338px,78px,312px) }
|
||||
#runtime-panel-nousbdevice { -moz-image-region: rect(156px,338px,182px,312px) }
|
||||
#runtime-panel-noadbhelper { -moz-image-region: rect(234px,338px,260px,312px) }
|
||||
#runtime-panel-installsimulator { -moz-image-region: rect(0px,338px,26px,312px) }
|
||||
.runtime-panel-item-usb { -moz-image-region: rect(52px,338px,78px,312px) }
|
||||
.runtime-panel-item-wifi { -moz-image-region: rect(208px,338px,234px,312px) }
|
||||
.runtime-panel-item-custom { -moz-image-region: rect(26px,338px,52px,312px) }
|
||||
.runtime-panel-item-simulator { -moz-image-region: rect(0px,338px,26px,312px) }
|
||||
#runtime-details { -moz-image-region: rect(156px,438px,182px,412px) }
|
||||
#runtime-screenshot { -moz-image-region: rect(130px,438px,156px,412px) }
|
||||
#runtime-permissions { -moz-image-region: rect(104px,438px,130px,412px) }
|
||||
#runtime-disconnect { -moz-image-region: rect(52px,438px,78px,412px) }
|
||||
#runtime-panel-nousbdevice { -moz-image-region: rect(156px,438px,182px,412px) }
|
||||
#runtime-panel-noadbhelper { -moz-image-region: rect(234px,438px,260px,412px) }
|
||||
#runtime-panel-installsimulator { -moz-image-region: rect(0px,438px,26px,412px) }
|
||||
.runtime-panel-item-usb { -moz-image-region: rect(52px,438px,78px,412px) }
|
||||
.runtime-panel-item-wifi { -moz-image-region: rect(208px,438px,234px,412px) }
|
||||
.runtime-panel-item-custom { -moz-image-region: rect(26px,438px,52px,412px) }
|
||||
.runtime-panel-item-simulator { -moz-image-region: rect(0px,438px,26px,412px) }
|
||||
|
||||
#runtime-actions {
|
||||
border-top: 1px solid rgba(221,221,221,1);
|
||||
|
@ -2,6 +2,9 @@
|
||||
# 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/.
|
||||
|
||||
index.deprecationNotice=The App Manager will be removed in a future release. Your projects have been migrated to WebIDE.
|
||||
index.launchWebIDE=Launch WebIDE
|
||||
index.readMoreAboutWebIDE=Read More
|
||||
# LOCALIZATION NOTE (device.deviceSize): %1$S is the device's width, %2$S is
|
||||
# the device's height, %3$S is the device's pixel density.
|
||||
# Example: 800x480 (86 DPI).
|
||||
|
@ -231,6 +231,19 @@
|
||||
- for the "Edit and Resend" menu item displayed in the context menu for a request -->
|
||||
<!ENTITY netmonitorUI.summary.editAndResend.accesskey "R">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.summary.rawHeaders): This is the label displayed
|
||||
- on the button in the headers tab that toggle view for raw request/response headers
|
||||
from the currently displayed request -->
|
||||
<!ENTITY netmonitorUI.summary.rawHeaders "Raw headers">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.summary.rawHeaders.requestHeaders): This is the label displayed
|
||||
- in the network details headers tab identifying the raw request headers textarea -->
|
||||
<!ENTITY netmonitorUI.summary.rawHeaders.requestHeaders "Request headers:">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.summary.rawHeaders.responseHeaders): This is the label displayed
|
||||
- in the network details headers tab identifying the raw response headers textarea -->
|
||||
<!ENTITY netmonitorUI.summary.rawHeaders.responseHeaders "Response headers:">
|
||||
|
||||
<!-- LOCALIZATION NOTE (netmonitorUI.context.newTab): This is the label
|
||||
- for the Open in New Tab menu item displayed in the context menu of the
|
||||
- network container -->
|
||||
|
@ -39,10 +39,12 @@
|
||||
|
||||
<!-- LOCALIZATION NOTE (profilerUI.table.*): These strings are displayed
|
||||
- in the call tree headers for a recording. -->
|
||||
<!ENTITY profilerUI.table.duration "Time (ms)">
|
||||
<!ENTITY profilerUI.table.percentage "Cost">
|
||||
<!ENTITY profilerUI.table.samples "Samples">
|
||||
<!ENTITY profilerUI.table.function "Function">
|
||||
<!ENTITY profilerUI.table.totalDuration "Total Time (ms)">
|
||||
<!ENTITY profilerUI.table.selfDuration "Self Time (ms)">
|
||||
<!ENTITY profilerUI.table.totalPercentage "Total Cost">
|
||||
<!ENTITY profilerUI.table.selfPercentage "Self Cost">
|
||||
<!ENTITY profilerUI.table.samples "Samples">
|
||||
<!ENTITY profilerUI.table.function "Function">
|
||||
|
||||
<!-- LOCALIZATION NOTE (profilerUI.newtab.tooltiptext): The tooltiptext shown
|
||||
- on the "+" (new tab) button for a profile when a selection is available. -->
|
||||
|
@ -271,8 +271,7 @@ function CreateSocialStatusWidget(aId, aProvider) {
|
||||
onBuild: function(aDocument) {
|
||||
let node = aDocument.createElement('toolbarbutton');
|
||||
node.id = this.id;
|
||||
node.setAttribute('class', 'toolbarbutton-1 chromeclass-toolbar-additional social-status-button');
|
||||
node.setAttribute('type', "badged");
|
||||
node.setAttribute('class', 'toolbarbutton-1 chromeclass-toolbar-additional social-status-button badged-button');
|
||||
node.style.listStyleImage = "url(" + (aProvider.icon32URL || aProvider.iconURL) + ")";
|
||||
node.setAttribute("origin", aProvider.origin);
|
||||
node.setAttribute("label", aProvider.name);
|
||||
|
@ -565,7 +565,7 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
|
||||
padding: 3px 7px;
|
||||
}
|
||||
|
||||
toolbarbutton[type="badged"] > .toolbarbutton-badge-container > .toolbarbutton-icon,
|
||||
toolbarbutton.badged-button > .toolbarbutton-badge-container > .toolbarbutton-icon,
|
||||
toolbarbutton[type="socialmark"] > .toolbarbutton-icon {
|
||||
max-width: 32px !important;
|
||||
}
|
||||
@ -2077,35 +2077,6 @@ toolbarbutton.chevron > .toolbarbutton-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.toolbarbutton-badge-container {
|
||||
margin: 5px 3px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
toolbar[iconsize="small"] .toolbarbutton-badge-container {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.toolbarbutton-badge[badge]:not([badge=""])::after {
|
||||
/* The |content| property is set in the content stylesheet. */
|
||||
font-size: 9px;
|
||||
font-weight: bold;
|
||||
padding: 0 1px;
|
||||
color: #fff;
|
||||
background-color: rgb(240,61,37);
|
||||
border: 1px solid rgb(216,55,34);
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 1px 0 rgba(0,39,121,0.77);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.toolbarbutton-badge[badge]:not([badge=""]):-moz-locale-dir(rtl)::after {
|
||||
left: 2px;
|
||||
right: auto;
|
||||
}
|
||||
|
||||
.popup-notification-icon[popupid="servicesInstall"] {
|
||||
list-style-image: url(chrome://browser/skin/social/services-64.png);
|
||||
}
|
||||
|
@ -8,6 +8,10 @@
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
#toggle-raw-headers {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.requests-menu-status-and-method {
|
||||
width: 9em;
|
||||
}
|
||||
|
@ -4419,48 +4419,6 @@ menulist.translate-infobar-element > .menulist-dropmarker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.toolbarbutton-badge-container {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.toolbarbutton-badge[badge]:not([badge=""]) {
|
||||
/* The |content| property is set in the content stylesheet. */
|
||||
font-size: 9px;
|
||||
font-weight: bold;
|
||||
padding: 0 1px;
|
||||
color: #fff;
|
||||
background-color: rgb(240,61,37);
|
||||
border: 1px solid rgb(216,55,34);
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 1px 0 rgba(0,39,121,0.77);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.toolbarbutton-badge[badge]:not([badge=""]):-moz-window-inactive {
|
||||
background-color: rgb(230,230,230);
|
||||
box-shadow: none;
|
||||
border: 1px solid rgb(206,206,206);
|
||||
color: rgb(192,192,192);
|
||||
}
|
||||
|
||||
.toolbarbutton-badge[badge]:not([badge=""]):-moz-locale-dir(rtl) {
|
||||
left: 0;
|
||||
right: auto;
|
||||
}
|
||||
|
||||
toolbar[mode="icons"] > *|* > .toolbarbutton-badge[badge]:not([badge=""]) {
|
||||
right: -2px;
|
||||
}
|
||||
|
||||
toolbar[mode="icons"] > *|* > .toolbarbutton-badge[badge]:not([badge=""]):-moz-locale-dir(rtl) {
|
||||
left: -2px;
|
||||
}
|
||||
|
||||
.popup-notification-icon[popupid="servicesInstall"] {
|
||||
list-style-image: url(chrome://browser/skin/social/services-64.png);
|
||||
}
|
||||
|
@ -485,6 +485,15 @@ label.requests-menu-status-code {
|
||||
-moz-margin-end: 6px;
|
||||
}
|
||||
|
||||
#toggle-raw-headers {
|
||||
margin-top: -10px;
|
||||
-moz-margin-end: 6px;
|
||||
}
|
||||
|
||||
.raw-response-textarea {
|
||||
height: 50vh;
|
||||
}
|
||||
|
||||
/* Response tabpanel */
|
||||
|
||||
#response-content-info-header {
|
||||
|
@ -251,13 +251,17 @@
|
||||
}
|
||||
|
||||
.call-tree-header[type="duration"],
|
||||
.call-tree-cell[type="duration"] {
|
||||
width: 7em;
|
||||
.call-tree-cell[type="duration"],
|
||||
.call-tree-header[type="self-duration"],
|
||||
.call-tree-cell[type="self-duration"] {
|
||||
width: 9em;
|
||||
}
|
||||
|
||||
.call-tree-header[type="percentage"],
|
||||
.call-tree-cell[type="percentage"] {
|
||||
width: 5em;
|
||||
.call-tree-cell[type="percentage"],
|
||||
.call-tree-header[type="self-percentage"],
|
||||
.call-tree-cell[type="self-percentage"] {
|
||||
width: 6em;
|
||||
}
|
||||
|
||||
.call-tree-header[type="samples"],
|
||||
|
@ -2699,59 +2699,6 @@ toolbarpaletteitem[place="palette"] > #switch-to-metro-button {
|
||||
list-style-image: url(chrome://browser/skin/Metro_Glyph-menuPanel.png);
|
||||
}
|
||||
|
||||
.toolbarbutton-badge-container {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#nav-bar .toolbarbutton-1 > .toolbarbutton-badge-container {
|
||||
padding: 2px 5px;
|
||||
}
|
||||
|
||||
.toolbarbutton-1 > .toolbarbutton-badge-container > .toolbar-icon {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 2px;
|
||||
}
|
||||
|
||||
.toolbarbutton-badge-container > .toolbarbutton-icon[label]:not([label=""]) {
|
||||
-moz-margin-end: 0;
|
||||
}
|
||||
|
||||
.toolbarbutton-badge[badge=""] {
|
||||
display: none;
|
||||
}
|
||||
.toolbarbutton-badge[badge]:not([badge=""])::after {
|
||||
/* The |content| property is set in the content stylesheet. */
|
||||
font-size: 9px;
|
||||
font-weight: bold;
|
||||
padding: 0 1px;
|
||||
color: #fff;
|
||||
background-color: rgb(240,61,37);
|
||||
border: 1px solid rgb(216,55,34);
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 1px 0 rgba(0,39,121,0.77);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
#nav-bar .toolbarbutton-badge[badge]:not([badge=""])::after {
|
||||
top: 1px;
|
||||
right: 1px;
|
||||
}
|
||||
|
||||
.toolbarbutton-badge[badge]:not([badge=""]):-moz-locale-dir(rtl)::after {
|
||||
left: 0;
|
||||
right: auto;
|
||||
}
|
||||
|
||||
#nav-bar .toolbarbutton-badge[badge]:not([badge=""]):-moz-locale-dir(rtl)::after {
|
||||
left: 1px;
|
||||
right: auto;
|
||||
}
|
||||
|
||||
.popup-notification-icon[popupid="servicesInstall"] {
|
||||
list-style-image: url(chrome://browser/skin/social/services-64.png);
|
||||
}
|
||||
|
10
configure.in
10
configure.in
@ -3852,6 +3852,7 @@ MOZ_ANDROID_SEARCH_ACTIVITY=
|
||||
MOZ_ANDROID_DOWNLOADS_INTEGRATION=
|
||||
MOZ_ANDROID_MLS_STUMBLER=
|
||||
MOZ_ANDROID_SHARE_OVERLAY=
|
||||
MOZ_ANDROID_NEW_TABLET_UI=
|
||||
ACCESSIBILITY=1
|
||||
MOZ_TIME_MANAGER=
|
||||
MOZ_PAY=
|
||||
@ -4911,6 +4912,14 @@ if test -n "$MOZ_ANDROID_SHARE_OVERLAY"; then
|
||||
AC_DEFINE(MOZ_ANDROID_SHARE_OVERLAY)
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Include New Tablet UI on Android
|
||||
dnl = Temporary build flag to allow development in Nightly
|
||||
dnl ========================================================
|
||||
if test -n "$MOZ_ANDROID_NEW_TABLET_UI"; then
|
||||
AC_DEFINE(MOZ_ANDROID_NEW_TABLET_UI)
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Enable IPDL's "expensive" unit tests
|
||||
dnl ========================================================
|
||||
@ -8520,6 +8529,7 @@ AC_SUBST(MOZ_LOCALE_SWITCHER)
|
||||
AC_SUBST(MOZ_DISABLE_GECKOVIEW)
|
||||
AC_SUBST(MOZ_ANDROID_SEARCH_ACTIVITY)
|
||||
AC_SUBST(MOZ_ANDROID_SHARE_OVERLAY)
|
||||
AC_SUBST(MOZ_ANDROID_NEW_TABLET_UI)
|
||||
AC_SUBST(MOZ_ANDROID_MLS_STUMBLER)
|
||||
AC_SUBST(MOZ_ANDROID_DOWNLOADS_INTEGRATION)
|
||||
AC_SUBST(ENABLE_STRIP)
|
||||
|
@ -18,10 +18,10 @@
|
||||
#define RTSPURI_SCHEME "rtsp"
|
||||
|
||||
class nsIDOMBlob;
|
||||
class nsIDOMMediaStream;
|
||||
class nsIPrincipal;
|
||||
|
||||
namespace mozilla {
|
||||
class DOMMediaStream;
|
||||
namespace dom {
|
||||
class MediaSource;
|
||||
}
|
||||
@ -122,7 +122,7 @@ 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);
|
||||
|
@ -699,6 +699,7 @@ 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")
|
||||
@ -748,6 +749,7 @@ 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")
|
||||
@ -817,10 +819,12 @@ 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")
|
||||
@ -831,6 +835,7 @@ 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")
|
||||
@ -848,6 +853,7 @@ 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")
|
||||
|
@ -11,7 +11,7 @@
|
||||
#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"
|
||||
@ -24,7 +24,7 @@ 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;
|
||||
@ -605,20 +605,12 @@ NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** 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
|
||||
|
@ -520,6 +520,7 @@ public:
|
||||
already_AddRefed<DOMMediaStream> GetMozSrcObject() const;
|
||||
|
||||
void SetMozSrcObject(DOMMediaStream& aValue);
|
||||
void SetMozSrcObject(DOMMediaStream* aValue);
|
||||
|
||||
bool MozPreservesPitch() const
|
||||
{
|
||||
|
@ -509,14 +509,6 @@ HTMLMediaElement::GetMozSrcObject() const
|
||||
return stream.forget();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLMediaElement::GetMozSrcObject(nsIDOMMediaStream** aStream)
|
||||
{
|
||||
nsRefPtr<DOMMediaStream> stream = GetMozSrcObject();
|
||||
stream.forget(aStream);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
HTMLMediaElement::SetMozSrcObject(DOMMediaStream& aValue)
|
||||
{
|
||||
@ -524,12 +516,10 @@ HTMLMediaElement::SetMozSrcObject(DOMMediaStream& 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; */
|
||||
@ -1148,7 +1138,7 @@ nsresult HTMLMediaElement::LoadResource()
|
||||
}
|
||||
|
||||
if (IsMediaStreamURI(mLoadingSrc)) {
|
||||
nsCOMPtr<nsIDOMMediaStream> stream;
|
||||
nsRefPtr<DOMMediaStream> stream;
|
||||
rv = NS_GetStreamForMediaStreamURI(mLoadingSrc, getter_AddRefs(stream));
|
||||
if (NS_FAILED(rv)) {
|
||||
nsCString specUTF8;
|
||||
@ -1158,7 +1148,7 @@ nsresult HTMLMediaElement::LoadResource()
|
||||
ReportLoadError("MediaLoadInvalidURI", params, ArrayLength(params));
|
||||
return rv;
|
||||
}
|
||||
SetupSrcMediaStreamPlayback(static_cast<DOMMediaStream*>(stream.get()));
|
||||
SetupSrcMediaStreamPlayback(stream);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1877,13 +1867,6 @@ HTMLMediaElement::MozCaptureStream(ErrorResult& aRv)
|
||||
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)
|
||||
{
|
||||
@ -1896,13 +1879,6 @@ HTMLMediaElement::MozCaptureStreamUntilEnded(ErrorResult& aRv)
|
||||
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();
|
||||
|
@ -140,14 +140,17 @@
|
||||
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>
|
||||
|
@ -19,34 +19,20 @@
|
||||
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_COLLECTION_INHERITED(DOMMediaStream,
|
||||
DOMEventTargetHelper,
|
||||
mWindow,
|
||||
mTracks,
|
||||
mConsumersToKeepAlive);
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMMediaStream)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMMediaStream)
|
||||
NS_IMPL_ADDREF_INHERITED(DOMMediaStream, DOMEventTargetHelper)
|
||||
NS_IMPL_RELEASE_INHERITED(DOMMediaStream, DOMEventTargetHelper)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(DOMMediaStream)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DOMMediaStream)
|
||||
NS_INTERFACE_MAP_ENTRY(DOMMediaStream)
|
||||
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
||||
|
||||
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_ISUPPORTS_INHERITED(DOMLocalMediaStream, DOMMediaStream,
|
||||
nsIDOMLocalMediaStream)
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(DOMLocalMediaStream, DOMMediaStream)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(DOMAudioNodeMediaStream, DOMMediaStream,
|
||||
mStreamNode)
|
||||
@ -93,8 +79,12 @@ public:
|
||||
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;
|
||||
}
|
||||
|
@ -6,13 +6,13 @@
|
||||
#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;
|
||||
|
||||
@ -48,11 +48,14 @@ 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;
|
||||
@ -69,8 +72,11 @@ public:
|
||||
|
||||
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
|
||||
{
|
||||
@ -295,13 +301,20 @@ private:
|
||||
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;
|
||||
|
||||
@ -325,6 +338,9 @@ protected:
|
||||
virtual ~DOMLocalMediaStream();
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(DOMLocalMediaStream,
|
||||
NS_DOMLOCALMEDIASTREAM_IID)
|
||||
|
||||
class DOMAudioNodeMediaStream : public DOMMediaStream
|
||||
{
|
||||
typedef dom::AudioNode AudioNode;
|
||||
|
@ -7,10 +7,9 @@
|
||||
#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"
|
||||
|
@ -3,11 +3,10 @@
|
||||
* 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"
|
||||
|
@ -8,6 +8,14 @@
|
||||
|
||||
#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"
|
||||
|
||||
|
@ -934,8 +934,11 @@ NS_IMPL_ISUPPORTS(SpeechRecognition::GetUserMediaSuccessCallback, nsIDOMGetUserM
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "nsIDOMDeviceStorage.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsDOMFile.h"
|
||||
#include "Navigator.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "DOMCameraManager.h"
|
||||
@ -27,9 +28,16 @@
|
||||
#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"
|
||||
@ -40,7 +48,6 @@ 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)
|
||||
@ -49,6 +56,12 @@ NS_IMPL_RELEASE_INHERITED(nsDOMCameraControl, DOMMediaStream)
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(nsDOMCameraControl, DOMMediaStream,
|
||||
mCapabilities,
|
||||
mWindow,
|
||||
mGetCameraPromise,
|
||||
mAutoFocusPromise,
|
||||
mTakePicturePromise,
|
||||
mStartRecordingPromise,
|
||||
mReleasePromise,
|
||||
mSetConfigurationPromise,
|
||||
mGetCameraOnSuccessCb,
|
||||
mGetCameraOnErrorCb,
|
||||
mAutoFocusOnSuccessCb,
|
||||
@ -135,10 +148,12 @@ 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)
|
||||
@ -159,10 +174,12 @@ nsDOMCameraControl::nsDOMCameraControl(uint32_t aCameraId,
|
||||
, 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 =
|
||||
@ -683,28 +700,29 @@ protected:
|
||||
};
|
||||
|
||||
// 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"));
|
||||
@ -727,11 +745,15 @@ nsDOMCameraControl::StartRecording(const CameraStartRecordingOptions& aOptions,
|
||||
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();
|
||||
@ -740,6 +762,7 @@ nsDOMCameraControl::StartRecording(const CameraStartRecordingOptions& aOptions,
|
||||
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
|
||||
@ -794,7 +817,7 @@ nsDOMCameraControl::ResumePreview(ErrorResult& aRv)
|
||||
aRv = mCameraControl->StartPreview();
|
||||
}
|
||||
|
||||
void
|
||||
already_AddRefed<Promise>
|
||||
nsDOMCameraControl::SetConfiguration(const CameraConfiguration& aConfiguration,
|
||||
const Optional<OwningNonNull<CameraSetConfigurationCallback> >& aOnSuccess,
|
||||
const Optional<OwningNonNull<CameraErrorCallback> >& aOnError,
|
||||
@ -802,19 +825,21 @@ nsDOMCameraControl::SetConfiguration(const CameraConfiguration& aConfiguration,
|
||||
{
|
||||
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;
|
||||
@ -826,6 +851,12 @@ nsDOMCameraControl::SetConfiguration(const CameraConfiguration& aConfiguration,
|
||||
config.mMode = ICameraControl::kVideoMode;
|
||||
}
|
||||
|
||||
aRv = mCameraControl->SetConfiguration(config);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mSetConfigurationPromise = promise;
|
||||
mSetConfigurationOnSuccessCb = nullptr;
|
||||
if (aOnSuccess.WasPassed()) {
|
||||
mSetConfigurationOnSuccessCb = &aOnSuccess.Value();
|
||||
@ -834,32 +865,51 @@ nsDOMCameraControl::SetConfiguration(const CameraConfiguration& aConfiguration,
|
||||
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
|
||||
@ -876,26 +926,28 @@ nsDOMCameraControl::StopFaceDetection(ErrorResult& aRv)
|
||||
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();
|
||||
}
|
||||
|
||||
{
|
||||
@ -921,22 +973,41 @@ nsDOMCameraControl::TakePicture(const CameraPictureOptions& aOptions,
|
||||
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();
|
||||
@ -945,8 +1016,7 @@ nsDOMCameraControl::ReleaseHardware(const Optional<OwningNonNull<CameraReleaseCa
|
||||
if (aOnError.WasPassed()) {
|
||||
mReleaseOnErrorCb = &aOnError.Value();
|
||||
}
|
||||
|
||||
aRv = mCameraControl->Stop();
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
void
|
||||
@ -965,6 +1035,12 @@ nsDOMCameraControl::Shutdown()
|
||||
// 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;
|
||||
@ -1001,6 +1077,63 @@ nsDOMCameraControl::NotifyRecordingStatusChange(const nsString& aMsg)
|
||||
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)
|
||||
@ -1012,26 +1145,46 @@ nsDOMCameraControl::OnHardwareStateChange(CameraControlListener::HardwareState a
|
||||
|
||||
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;
|
||||
|
||||
@ -1052,6 +1205,8 @@ nsDOMCameraControl::OnShutter()
|
||||
ErrorResult ignored;
|
||||
cb->Call(ignored);
|
||||
}
|
||||
|
||||
DispatchTrustedEvent(NS_LITERAL_STRING("shutter"));
|
||||
}
|
||||
|
||||
void
|
||||
@ -1059,10 +1214,7 @@ nsDOMCameraControl::OnPreviewStateChange(CameraControlListener::PreviewState aSt
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!mOnPreviewStateChangeCb) {
|
||||
return;
|
||||
}
|
||||
|
||||
mPreviewState = aState;
|
||||
nsString state;
|
||||
switch (aState) {
|
||||
case CameraControlListener::kPreviewStarted:
|
||||
@ -1075,8 +1227,12 @@ nsDOMCameraControl::OnPreviewStateChange(CameraControlListener::PreviewState aSt
|
||||
}
|
||||
|
||||
nsRefPtr<CameraPreviewStateChange> cb = mOnPreviewStateChangeCb;
|
||||
ErrorResult ignored;
|
||||
cb->Call(state, ignored);
|
||||
if (cb) {
|
||||
ErrorResult ignored;
|
||||
cb->Call(state, ignored);
|
||||
}
|
||||
|
||||
DispatchPreviewStateEvent(aState);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1091,12 +1247,19 @@ nsDOMCameraControl::OnRecorderStateChange(CameraControlListener::RecorderState a
|
||||
|
||||
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:
|
||||
@ -1139,12 +1302,15 @@ nsDOMCameraControl::OnRecorderStateChange(CameraControlListener::RecorderState a
|
||||
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;
|
||||
@ -1161,12 +1327,31 @@ nsDOMCameraControl::OnConfigurationChange(DOMCameraConfiguration* aConfiguration
|
||||
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
|
||||
@ -1174,6 +1359,11 @@ 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) {
|
||||
@ -1186,6 +1376,12 @@ nsDOMCameraControl::OnAutoFocusComplete(bool aAutoFocusSucceeded)
|
||||
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
|
||||
@ -1198,6 +1394,10 @@ nsDOMCameraControl::OnAutoFocusMoving(bool aIsMoving)
|
||||
ErrorResult ignored;
|
||||
cb->Call(aIsMoving, ignored);
|
||||
}
|
||||
|
||||
if (aIsMoving) {
|
||||
DispatchStateEvent(NS_LITERAL_STRING("focus"), NS_LITERAL_STRING("focusing"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -1206,11 +1406,6 @@ 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();
|
||||
|
||||
@ -1222,27 +1417,50 @@ nsDOMCameraControl::OnFacesDetected(const nsTArray<ICameraControl::Face>& aFaces
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@ -1250,35 +1468,43 @@ nsDOMCameraControl::OnUserError(CameraControlListener::UserContext aContext, nsr
|
||||
{
|
||||
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;
|
||||
@ -1340,52 +1566,57 @@ nsDOMCameraControl::OnUserError(CameraControlListener::UserContext aContext, nsr
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
#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"
|
||||
@ -53,6 +54,7 @@ public:
|
||||
const dom::CameraConfiguration& aInitialConfig,
|
||||
dom::GetCameraCallback* aOnSuccess,
|
||||
dom::CameraErrorCallback* aOnError,
|
||||
dom::Promise* aPromise,
|
||||
nsPIDOMWindow* aWindow);
|
||||
|
||||
void Shutdown();
|
||||
@ -102,10 +104,10 @@ public:
|
||||
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);
|
||||
@ -114,30 +116,39 @@ public:
|
||||
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();
|
||||
|
||||
@ -179,6 +190,12 @@ protected:
|
||||
|
||||
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.
|
||||
@ -190,6 +207,14 @@ protected:
|
||||
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;
|
||||
@ -226,6 +251,7 @@ protected:
|
||||
|
||||
dom::CameraStartRecordingOptions mOptions;
|
||||
nsRefPtr<DeviceStorageFileDescriptor> mDSFileDescriptor;
|
||||
DOMCameraControlListener::PreviewState mPreviewState;
|
||||
|
||||
private:
|
||||
nsDOMCameraControl(const nsDOMCameraControl&) MOZ_DELETE;
|
||||
|
@ -146,7 +146,8 @@ public:
|
||||
uint32_t aCameraId,
|
||||
const CameraConfiguration& aInitialConfig,
|
||||
nsRefPtr<GetCameraCallback> aOnSuccess,
|
||||
nsRefPtr<CameraErrorCallback> aOnError)
|
||||
nsRefPtr<CameraErrorCallback> aOnError,
|
||||
nsRefPtr<Promise> aPromise)
|
||||
: mPrincipal(aPrincipal)
|
||||
, mWindow(aWindow)
|
||||
, mCameraManager(aManager)
|
||||
@ -154,6 +155,7 @@ public:
|
||||
, mInitialConfig(aInitialConfig)
|
||||
, mOnSuccess(aOnSuccess)
|
||||
, mOnError(aOnError)
|
||||
, mPromise(aPromise)
|
||||
{
|
||||
}
|
||||
|
||||
@ -172,9 +174,13 @@ protected:
|
||||
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)
|
||||
@ -240,13 +246,13 @@ CameraPermissionRequest::DispatchCallback(uint32_t aPermission)
|
||||
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
|
||||
@ -259,10 +265,10 @@ CameraPermissionRequest::GetTypes(nsIArray** aTypes)
|
||||
aTypes);
|
||||
}
|
||||
|
||||
void
|
||||
already_AddRefed<Promise>
|
||||
nsDOMCameraManager::GetCamera(const nsAString& aCamera,
|
||||
const CameraConfiguration& aInitialConfig,
|
||||
GetCameraCallback& aOnSuccess,
|
||||
const OptionalNonNullGetCameraCallback& aOnSuccess,
|
||||
const OptionalNonNullCameraErrorCallback& aOnError,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
@ -273,43 +279,61 @@ nsDOMCameraManager::GetCamera(const nsAString& aCamera,
|
||||
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);
|
||||
}
|
||||
@ -318,10 +342,12 @@ 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);
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define DOM_CAMERA_DOMCAMERAMANAGER_H
|
||||
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsIObserver.h"
|
||||
@ -32,7 +33,9 @@ namespace mozilla {
|
||||
|
||||
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
|
||||
@ -64,19 +67,22 @@ public:
|
||||
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; }
|
||||
|
97
dom/camera/test/callback/test_bug1022766.html
Normal file
97
dom/camera/test/callback/test_bug1022766.html
Normal file
@ -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>
|
223
dom/camera/test/callback/test_bug975472.html
Normal file
223
dom/camera/test/callback/test_bug975472.html
Normal file
@ -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>
|
242
dom/camera/test/callback/test_camera.html
Normal file
242
dom/camera/test/callback/test_camera.html
Normal file
@ -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>
|
200
dom/camera/test/callback/test_camera_2.html
Normal file
200
dom/camera/test/callback/test_camera_2.html
Normal file
@ -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>
|
76
dom/camera/test/callback/test_camera_3.html
Normal file
76
dom/camera/test/callback/test_camera_3.html
Normal file
@ -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>
|
@ -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>
|
@ -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>
|
145
dom/camera/test/callback/test_camera_hardware_failures.html
Normal file
145
dom/camera/test/callback/test_camera_hardware_failures.html
Normal file
@ -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>
|
@ -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>
|
@ -122,6 +122,7 @@ var CameraTest = (function() {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
function cleanUpTestEnabled() {
|
||||
var next = allCleanedUp;
|
||||
if (oldTestEnabled) {
|
||||
|
@ -1,6 +1,15 @@
|
||||
[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]
|
||||
|
@ -23,7 +23,7 @@ var config = {
|
||||
};
|
||||
|
||||
function onError(e) {
|
||||
ok(false, "Error" + JSON.stringify(e));
|
||||
ok(false, "Error " + e);
|
||||
}
|
||||
|
||||
var Camera = {
|
||||
@ -49,7 +49,7 @@ var Camera = {
|
||||
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();
|
||||
@ -67,7 +67,8 @@ var Camera = {
|
||||
},
|
||||
|
||||
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();
|
||||
@ -75,11 +76,11 @@ var Camera = {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,9 @@ var Camera = {
|
||||
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();
|
||||
@ -59,10 +61,10 @@ var Camera = {
|
||||
"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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ var options = {
|
||||
};
|
||||
|
||||
function onError(e) {
|
||||
ok(false, "Error" + JSON.stringify(e));
|
||||
ok(false, "Error " + e);
|
||||
}
|
||||
function next() {
|
||||
Camera.nextTest();
|
||||
@ -49,7 +49,7 @@ var tests = [
|
||||
function onError(error) {
|
||||
ok(false, "release() failed with: " + error);
|
||||
}
|
||||
camera.release(onSuccess, onError);
|
||||
camera.release().then(onSuccess, onError);
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -87,10 +87,10 @@ var tests = [
|
||||
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);
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -100,10 +100,10 @@ var tests = [
|
||||
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);
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -113,7 +113,7 @@ var tests = [
|
||||
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 = {
|
||||
@ -122,8 +122,7 @@ var tests = [
|
||||
};
|
||||
camera.startRecording(recordingOptions,
|
||||
navigator.getDeviceStorage('videos'),
|
||||
'bug975472.mp4',
|
||||
onSuccess, onError);
|
||||
'bug975472.mp4').then(onSuccess, onError);
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -140,10 +139,10 @@ var tests = [
|
||||
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);
|
||||
}
|
||||
},
|
||||
];
|
||||
@ -183,8 +182,17 @@ var Camera = {
|
||||
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,
|
||||
@ -195,15 +203,8 @@ var Camera = {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ var config = {
|
||||
};
|
||||
|
||||
function onError(e) {
|
||||
ok(false, "Error" + JSON.stringify(e));
|
||||
ok(false, "Error " + e);
|
||||
}
|
||||
|
||||
var capabilities = [ 'previewSizes', 'pictureSizes', 'fileFormats', 'maxFocusAreas', 'minExposureCompensation',
|
||||
@ -102,12 +102,17 @@ var Camera = {
|
||||
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) {
|
||||
@ -196,7 +201,7 @@ var Camera = {
|
||||
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);
|
||||
@ -205,24 +210,27 @@ var Camera = {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ var config = {
|
||||
};
|
||||
|
||||
function onError(e) {
|
||||
ok(false, "Error" + JSON.stringify(e));
|
||||
ok(false, "Error " + e);
|
||||
}
|
||||
|
||||
var capabilities = [ 'previewSizes', 'pictureSizes', 'fileFormats', 'maxFocusAreas', 'minExposureCompensation',
|
||||
@ -113,11 +113,19 @@ var Camera = {
|
||||
},
|
||||
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 = {};
|
||||
@ -125,7 +133,7 @@ var Camera = {
|
||||
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];
|
||||
@ -157,30 +165,25 @@ var Camera = {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ var options = {
|
||||
};
|
||||
|
||||
function onError(e) {
|
||||
ok(false, "Error" + JSON.stringify(e));
|
||||
ok(false, "Error " + e);
|
||||
}
|
||||
|
||||
var Camera = {
|
||||
@ -31,32 +31,33 @@ var Camera = {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ var cameraObj = null;
|
||||
|
||||
// Shorthand functions
|
||||
function onError(e) {
|
||||
ok(false, "Error" + JSON.stringify(e));
|
||||
ok(false, "Error " + e);
|
||||
}
|
||||
|
||||
function end() {
|
||||
@ -427,20 +427,19 @@ CameraTest.begin("hardware", function(test) {
|
||||
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) {
|
||||
|
@ -53,25 +53,16 @@ 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() {
|
||||
@ -100,13 +91,13 @@ CameraTest.begin("hardware", function(test) {
|
||||
} 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();
|
||||
@ -121,7 +112,7 @@ CameraTest.begin("hardware", function(test) {
|
||||
ok(false, "getCamera() failed with: " + error);
|
||||
end();
|
||||
}
|
||||
navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError);
|
||||
navigator.mozCameras.getCamera(whichCamera, initialConfig).then(onSuccess, onError);
|
||||
})
|
||||
});
|
||||
|
||||
|
@ -150,12 +150,16 @@ var tests = [
|
||||
}
|
||||
} ]
|
||||
};
|
||||
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();
|
||||
}
|
||||
},
|
||||
@ -208,12 +212,16 @@ var tests = [
|
||||
}
|
||||
} ]
|
||||
};
|
||||
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();
|
||||
}
|
||||
},
|
||||
@ -235,12 +243,16 @@ var tests = [
|
||||
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();
|
||||
}
|
||||
},
|
||||
@ -250,12 +262,16 @@ var tests = [
|
||||
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();
|
||||
}
|
||||
},
|
||||
@ -289,13 +305,13 @@ CameraTest.begin("hardware", function(test) {
|
||||
} 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();
|
||||
@ -310,7 +326,7 @@ CameraTest.begin("hardware", function(test) {
|
||||
ok(false, "getCamera() failed with: " + error);
|
||||
end();
|
||||
}
|
||||
navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError);
|
||||
navigator.mozCameras.getCamera(whichCamera, initialConfig).then(onSuccess, onError);
|
||||
})
|
||||
});
|
||||
|
||||
|
@ -50,7 +50,7 @@ var tests = [
|
||||
ok(true, "autoFocus() failed correctly with: " + error);
|
||||
next();
|
||||
}
|
||||
camera.autoFocus(onSuccess, onError);
|
||||
camera.autoFocus().then(onSuccess, onError);
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -69,7 +69,7 @@ var tests = [
|
||||
ok(false, "autoFocus() process failed incorrectly with: " + error);
|
||||
end();
|
||||
}
|
||||
camera.autoFocus(onSuccess, onError);
|
||||
camera.autoFocus().then(onSuccess, onError);
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -83,7 +83,7 @@ var tests = [
|
||||
ok(true, "takePicture() failed correctly with: " + error);
|
||||
next();
|
||||
}
|
||||
camera.takePicture(null, onSuccess, onError);
|
||||
camera.takePicture(null).then(onSuccess, onError);
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -97,7 +97,7 @@ var tests = [
|
||||
ok(true, "takePicture() process failed correctly with: " + error);
|
||||
next();
|
||||
}
|
||||
camera.takePicture(null, onSuccess, onError);
|
||||
camera.takePicture(null).then(onSuccess, onError);
|
||||
}
|
||||
},
|
||||
];
|
||||
@ -115,13 +115,13 @@ window.addEventListener('beforeunload', function() {
|
||||
});
|
||||
|
||||
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();
|
||||
@ -136,7 +136,7 @@ CameraTest.begin("hardware", function(test) {
|
||||
ok(false, "getCamera() failed with: " + error);
|
||||
end();
|
||||
}
|
||||
navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError);
|
||||
navigator.mozCameras.getCamera(whichCamera, initialConfig).then(onSuccess, onError);
|
||||
});
|
||||
|
||||
</script>
|
||||
|
@ -34,9 +34,9 @@ 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) {
|
||||
@ -44,7 +44,7 @@ var tests = [
|
||||
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
|
||||
@ -53,9 +53,9 @@ var tests = [
|
||||
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) {
|
||||
@ -63,7 +63,7 @@ var tests = [
|
||||
test.next();
|
||||
}
|
||||
info("Running test: init-success");
|
||||
navigator.mozCameras.getCamera(whichCamera, initialConfig, onSuccess, onError)
|
||||
navigator.mozCameras.getCamera(whichCamera, initialConfig).then(onSuccess, onError)
|
||||
}
|
||||
}
|
||||
];
|
||||
|
@ -76,6 +76,18 @@ const kEventConstructors = {
|
||||
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);
|
||||
},
|
||||
|
@ -8,8 +8,6 @@
|
||||
#include "nsIDOMMediaError.idl"
|
||||
#include "nsIDOMTimeRanges.idl"
|
||||
|
||||
interface nsIDOMMediaStream;
|
||||
|
||||
/**
|
||||
* The nsIDOMHTMLMediaElement interface is an interface to be implemented by the HTML
|
||||
* <audio> and <video> elements.
|
||||
@ -35,7 +33,6 @@ interface nsIDOMHTMLMediaElement : nsISupports
|
||||
|
||||
// network state
|
||||
attribute DOMString src;
|
||||
attribute nsIDOMMediaStream mozSrcObject;
|
||||
readonly attribute DOMString currentSrc;
|
||||
const unsigned short NETWORK_EMPTY = 0;
|
||||
const unsigned short NETWORK_IDLE = 1;
|
||||
@ -79,8 +76,6 @@ interface nsIDOMHTMLMediaElement : nsISupports
|
||||
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
|
||||
|
@ -2,7 +2,6 @@
|
||||
#include "nsIDOMWindow.idl"
|
||||
#include "nsIPropertyBag2.idl"
|
||||
|
||||
interface nsIDOMMediaStream;
|
||||
interface nsIDOMDataChannel;
|
||||
|
||||
/*
|
||||
|
@ -17,7 +17,6 @@ if CONFIG['MOZ_WEBRTC']:
|
||||
WEBRTC_SIGNALLING_TEST_MANIFESTS += ['tests/mochitest/steeplechase.ini']
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'nsIDOMMediaStream.idl',
|
||||
'nsIDOMNavigatorUserMedia.idl',
|
||||
'nsIMediaManager.idl',
|
||||
]
|
||||
|
@ -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. */
|
||||
};
|
@ -4,7 +4,6 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "nsIVariant.idl"
|
||||
#include "nsIDOMMediaStream.idl"
|
||||
|
||||
[scriptable, builtinclass, uuid(4af2bdb7-1547-4d10-8886-02a78c3c0b83)]
|
||||
interface nsIMediaDevice : nsISupports
|
||||
@ -27,7 +26,7 @@ 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);
|
||||
};
|
||||
|
@ -199,12 +199,12 @@ static void ProcessDelayedAudioRoute(SwitchState aState)
|
||||
sSwitchDone = true;
|
||||
}
|
||||
|
||||
static void ProcessDelayedA2dpRoute(audio_policy_dev_state_t aState, const char *aAddress)
|
||||
static void ProcessDelayedA2dpRoute(audio_policy_dev_state_t aState, const nsCString aAddress)
|
||||
{
|
||||
if (sA2dpSwitchDone)
|
||||
return;
|
||||
AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
|
||||
aState, aAddress);
|
||||
aState, aAddress.get());
|
||||
String8 cmd("bluetooth_enabled=false");
|
||||
AudioSystem::setParameters(0, cmd);
|
||||
cmd.setTo("A2dpSuspended=true");
|
||||
@ -280,7 +280,7 @@ AudioManager::HandleBluetoothStatusChanged(nsISupports* aSubject,
|
||||
} else if (!strcmp(aTopic, BLUETOOTH_A2DP_STATUS_CHANGED_ID)) {
|
||||
if (audioState == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE && sA2dpSwitchDone) {
|
||||
MessageLoop::current()->PostDelayedTask(
|
||||
FROM_HERE, NewRunnableFunction(&ProcessDelayedA2dpRoute, audioState, aAddress.get()), 1000);
|
||||
FROM_HERE, NewRunnableFunction(&ProcessDelayedA2dpRoute, audioState, aAddress), 1000);
|
||||
sA2dpSwitchDone = false;
|
||||
} else {
|
||||
AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
|
||||
|
@ -600,8 +600,8 @@ Telephony::EnumerateCallState(uint32_t aServiceId, uint32_t aCallIndex,
|
||||
// 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;
|
||||
}
|
||||
|
@ -200,12 +200,18 @@ var interfaceNamesInGlobalScope =
|
||||
{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!
|
||||
|
20
dom/webidl/CameraConfigurationEvent.webidl
Normal file
20
dom/webidl/CameraConfigurationEvent.webidl
Normal file
@ -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;
|
||||
};
|
@ -235,20 +235,48 @@ interface CameraControl : MediaStream
|
||||
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. */
|
||||
@ -287,7 +315,25 @@ interface CameraControl : MediaStream
|
||||
|
||||
/* 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
|
||||
@ -309,18 +355,23 @@ interface CameraControl : MediaStream
|
||||
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);
|
||||
|
||||
/* start recording video; 'aOptions' is a
|
||||
CameraStartRecordingOptions object. */
|
||||
/* 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.
|
||||
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]
|
||||
@ -341,8 +392,8 @@ interface CameraControl : MediaStream
|
||||
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.
|
||||
@ -353,9 +404,18 @@ interface CameraControl : MediaStream
|
||||
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
|
||||
@ -457,4 +517,8 @@ partial interface CameraControl
|
||||
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;
|
||||
};
|
||||
|
18
dom/webidl/CameraFacesDetectedEvent.webidl
Normal file
18
dom/webidl/CameraFacesDetectedEvent.webidl
Normal file
@ -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;
|
||||
};
|
@ -36,10 +36,10 @@ interface CameraManager
|
||||
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" ]
|
||||
|
16
dom/webidl/CameraStateChangeEvent.webidl
Normal file
16
dom/webidl/CameraStateChangeEvent.webidl
Normal file
@ -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 = "";
|
||||
};
|
12
dom/webidl/CameraUtil.webidl
Normal file
12
dom/webidl/CameraUtil.webidl
Normal file
@ -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;
|
||||
};
|
@ -21,7 +21,7 @@ dictionary MediaStreamConstraints {
|
||||
DOMString? peerIdentity = null;
|
||||
};
|
||||
|
||||
interface MediaStream {
|
||||
interface MediaStream : EventTarget {
|
||||
// readonly attribute DOMString id;
|
||||
sequence<AudioStreamTrack> getAudioTracks();
|
||||
sequence<VideoStreamTrack> getVideoTracks();
|
||||
|
@ -57,6 +57,7 @@ WEBIDL_FILES = [
|
||||
'CameraCapabilities.webidl',
|
||||
'CameraControl.webidl',
|
||||
'CameraManager.webidl',
|
||||
'CameraUtil.webidl',
|
||||
'CanvasRenderingContext2D.webidl',
|
||||
'CaretPosition.webidl',
|
||||
'CDATASection.webidl',
|
||||
@ -652,6 +653,9 @@ GENERATED_EVENTS_WEBIDL_FILES = [
|
||||
'BlobEvent.webidl',
|
||||
'CallEvent.webidl',
|
||||
'CallGroupErrorEvent.webidl',
|
||||
'CameraConfigurationEvent.webidl',
|
||||
'CameraFacesDetectedEvent.webidl',
|
||||
'CameraStateChangeEvent.webidl',
|
||||
'CFStateChangeEvent.webidl',
|
||||
'CloseEvent.webidl',
|
||||
'CSSFontFaceLoadEvent.webidl',
|
||||
|
@ -703,7 +703,7 @@ PeerConnectionImpl::GetFingerprintHexValue() const
|
||||
|
||||
|
||||
nsresult
|
||||
PeerConnectionImpl::CreateFakeMediaStream(uint32_t aHint, nsIDOMMediaStream** aRetval)
|
||||
PeerConnectionImpl::CreateFakeMediaStream(uint32_t aHint, DOMMediaStream** aRetval)
|
||||
{
|
||||
MOZ_ASSERT(aRetval);
|
||||
PC_AUTO_ENTER_API_CALL(false);
|
||||
|
@ -54,7 +54,6 @@ class Fake_MediaStreamTrack;
|
||||
#endif
|
||||
|
||||
class nsGlobalWindow;
|
||||
class nsIDOMMediaStream;
|
||||
class nsDOMDataChannel;
|
||||
|
||||
namespace mozilla {
|
||||
@ -295,7 +294,7 @@ public:
|
||||
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();
|
||||
|
@ -295,7 +295,7 @@ nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_serv
|
||||
}
|
||||
|
||||
nsresult
|
||||
PeerConnectionMedia::AddStream(nsIDOMMediaStream* aMediaStream,
|
||||
PeerConnectionMedia::AddStream(DOMMediaStream* aMediaStream,
|
||||
uint32_t hints,
|
||||
uint32_t *stream_id)
|
||||
{
|
||||
@ -306,8 +306,6 @@ PeerConnectionMedia::AddStream(nsIDOMMediaStream* aMediaStream,
|
||||
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
|
||||
@ -336,14 +334,14 @@ PeerConnectionMedia::AddStream(nsIDOMMediaStream* aMediaStream,
|
||||
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;
|
||||
}
|
||||
@ -359,21 +357,19 @@ PeerConnectionMedia::AddStream(nsIDOMMediaStream* aMediaStream,
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -312,11 +312,11 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user