зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to fx-team
This commit is contained in:
Коммит
5dcebafc3c
|
@ -1037,6 +1037,9 @@ pref("browser.autofocus", false);
|
|||
// Enable wakelock
|
||||
pref("dom.wakelock.enabled", true);
|
||||
|
||||
// Enable webapps add-ons
|
||||
pref("dom.apps.customization.enabled", true);
|
||||
|
||||
// Enable touch caret by default
|
||||
pref("touchcaret.enabled", true);
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<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="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
|
||||
<!-- 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="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="6fa7a4936414ceb4055fd27f7a30e76790f834fb"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
|
||||
<!-- 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="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<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="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
|
||||
<!-- 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="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="6fa7a4936414ceb4055fd27f7a30e76790f834fb"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
|
||||
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<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="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
|
||||
<!-- 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="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
|
||||
<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": "99bea97a4bd9d6af1d7462e1abe15c8aaf4d7981",
|
||||
"revision": "8175c3383310bf79cbfd01d36273620dede2a111",
|
||||
"repo_path": "integration/gaia-central"
|
||||
}
|
||||
|
|
|
@ -17,11 +17,11 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
|
||||
<!-- 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="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<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="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
|
||||
<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="8ffb48c321bb9595ad437086c5eb450bc90aa714"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d22dfece04fc00457e8369c660c11f945b088d2f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="631dbd1b133f09d83f526292ab8996e46b1e7654"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="2b761dbeebac9126947315659419a0fb1f80b230"/>
|
||||
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
|
||||
|
|
|
@ -403,33 +403,6 @@ const gSessionHistoryObserver = {
|
|||
}
|
||||
};
|
||||
|
||||
const gGatherTelemetryObserver = {
|
||||
observe: function(subject, topic, data) {
|
||||
if (topic != "gather-telemetry") {
|
||||
return;
|
||||
}
|
||||
|
||||
let engine;
|
||||
try {
|
||||
engine = Services.search.defaultEngine;
|
||||
} catch (e) {}
|
||||
let name;
|
||||
|
||||
if (!engine) {
|
||||
name = "NONE";
|
||||
} else if (engine.identifier) {
|
||||
name = engine.identifier;
|
||||
} else if (engine.name) {
|
||||
name = "other-" + engine.name;
|
||||
} else {
|
||||
name = "UNDEFINED";
|
||||
}
|
||||
|
||||
let engines = Services.telemetry.getKeyedHistogramById("SEARCH_DEFAULT_ENGINE");
|
||||
engines.add(name, true)
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Given a starting docshell and a URI to look up, find the docshell the URI
|
||||
* is loaded in.
|
||||
|
@ -1213,7 +1186,6 @@ var gBrowserInit = {
|
|||
Services.obs.addObserver(gXPInstallObserver, "addon-install-blocked", false);
|
||||
Services.obs.addObserver(gXPInstallObserver, "addon-install-failed", false);
|
||||
Services.obs.addObserver(gXPInstallObserver, "addon-install-complete", false);
|
||||
Services.obs.addObserver(gGatherTelemetryObserver, "gather-telemetry", false);
|
||||
window.messageManager.addMessageListener("Browser:URIFixup", gKeywordURIFixup);
|
||||
window.messageManager.addMessageListener("Browser:LoadURI", RedirectLoad);
|
||||
|
||||
|
@ -1534,7 +1506,6 @@ var gBrowserInit = {
|
|||
Services.obs.removeObserver(gXPInstallObserver, "addon-install-blocked");
|
||||
Services.obs.removeObserver(gXPInstallObserver, "addon-install-failed");
|
||||
Services.obs.removeObserver(gXPInstallObserver, "addon-install-complete");
|
||||
Services.obs.removeObserver(gGatherTelemetryObserver, "gather-telemetry");
|
||||
window.messageManager.removeMessageListener("Browser:URIFixup", gKeywordURIFixup);
|
||||
window.messageManager.removeMessageListener("Browser:LoadURI", RedirectLoad);
|
||||
|
||||
|
|
|
@ -144,6 +144,28 @@ const BOOKMARKS_BACKUP_MIN_INTERVAL_DAYS = 1;
|
|||
// days we will try to create a new one more aggressively.
|
||||
const BOOKMARKS_BACKUP_MAX_INTERVAL_DAYS = 3;
|
||||
|
||||
// Record the current default search engine in Telemetry.
|
||||
function recordDefaultSearchEngine() {
|
||||
let engine;
|
||||
try {
|
||||
engine = Services.search.defaultEngine;
|
||||
} catch (e) {}
|
||||
let name;
|
||||
|
||||
if (!engine) {
|
||||
name = "NONE";
|
||||
} else if (engine.identifier) {
|
||||
name = engine.identifier;
|
||||
} else if (engine.name) {
|
||||
name = "other-" + engine.name;
|
||||
} else {
|
||||
name = "UNDEFINED";
|
||||
}
|
||||
|
||||
let engines = Services.telemetry.getKeyedHistogramById("SEARCH_DEFAULT_ENGINE");
|
||||
engines.add(name, true)
|
||||
}
|
||||
|
||||
// Factory object
|
||||
const BrowserGlueServiceFactory = {
|
||||
_instance: null,
|
||||
|
@ -402,12 +424,14 @@ BrowserGlue.prototype = {
|
|||
ss.defaultEngine = ss.currentEngine;
|
||||
else
|
||||
ss.currentEngine = ss.defaultEngine;
|
||||
recordDefaultSearchEngine();
|
||||
break;
|
||||
case "browser-search-service":
|
||||
if (data != "init-complete")
|
||||
return;
|
||||
Services.obs.removeObserver(this, "browser-search-service");
|
||||
this._syncSearchEngines();
|
||||
recordDefaultSearchEngine();
|
||||
break;
|
||||
#ifdef NIGHTLY_BUILD
|
||||
case "nsPref:changed":
|
||||
|
|
|
@ -152,7 +152,7 @@ PlacesTreeView.prototype = {
|
|||
// A node is removed form the view either if it has no parent or if its
|
||||
// root-ancestor is not the root node (in which case that's the node
|
||||
// for which nodeRemoved was called).
|
||||
let ancestors = [x for each (x in PlacesUtils.nodeAncestors(aNode))];
|
||||
let ancestors = [x for (x of PlacesUtils.nodeAncestors(aNode))];
|
||||
if (ancestors.length == 0 ||
|
||||
ancestors[ancestors.length - 1] != this._rootNode) {
|
||||
throw new Error("Removed node passed to _getRowForNode");
|
||||
|
@ -417,7 +417,7 @@ PlacesTreeView.prototype = {
|
|||
// However, if any of the node's ancestor is closed, the node is
|
||||
// invisible.
|
||||
let ancestors = PlacesUtils.nodeAncestors(aOldNode);
|
||||
for (let ancestor in ancestors) {
|
||||
for (let ancestor of ancestors) {
|
||||
if (!ancestor.containerOpen)
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -72,20 +72,22 @@ bool isInIgnoredNamespace(const Decl *decl) {
|
|||
ND = cast<NamespaceDecl>(ParentDC);
|
||||
}
|
||||
|
||||
const auto& name = ND->getName();
|
||||
|
||||
// namespace std and icu are ignored for now
|
||||
return ND->getName() == "std" || // standard C++ lib
|
||||
ND->getName() == "__gnu_cxx" || // gnu C++ lib
|
||||
ND->getName() == "boost" || // boost
|
||||
ND->getName() == "webrtc" || // upstream webrtc
|
||||
ND->getName() == "icu_52" || // icu
|
||||
ND->getName() == "google" || // protobuf
|
||||
ND->getName() == "google_breakpad" || // breakpad
|
||||
ND->getName() == "soundtouch" || // libsoundtouch
|
||||
ND->getName() == "stagefright" || // libstagefright
|
||||
ND->getName() == "MacFileUtilities" || // MacFileUtilities
|
||||
ND->getName() == "dwarf2reader" || // dwarf2reader
|
||||
ND->getName() == "arm_ex_to_module" || // arm_ex_to_module
|
||||
ND->getName() == "testing"; // gtest
|
||||
return name == "std" || // standard C++ lib
|
||||
name == "__gnu_cxx" || // gnu C++ lib
|
||||
name == "boost" || // boost
|
||||
name == "webrtc" || // upstream webrtc
|
||||
name == "icu_52" || // icu
|
||||
name == "google" || // protobuf
|
||||
name == "google_breakpad" || // breakpad
|
||||
name == "soundtouch" || // libsoundtouch
|
||||
name == "stagefright" || // libstagefright
|
||||
name == "MacFileUtilities" || // MacFileUtilities
|
||||
name == "dwarf2reader" || // dwarf2reader
|
||||
name == "arm_ex_to_module" || // arm_ex_to_module
|
||||
name == "testing"; // gtest
|
||||
}
|
||||
|
||||
bool isIgnoredPath(const Decl *decl) {
|
||||
|
@ -175,8 +177,10 @@ public:
|
|||
// The way that Clang checks if a method M overrides its parent method
|
||||
// is if the method has the same name but would not overload.
|
||||
if (M->getName() == (*it)->getName() &&
|
||||
!CI.getSema().IsOverload(*M, (*it), false))
|
||||
!CI.getSema().IsOverload(*M, (*it), false)) {
|
||||
overridden = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!overridden) {
|
||||
unsigned overrideID = Diag.getDiagnosticIDs()->getCustomDiagID(
|
||||
|
|
|
@ -7475,7 +7475,6 @@ fi
|
|||
dnl ========================================================
|
||||
dnl = Offer a way to disable the startup cache
|
||||
dnl ========================================================
|
||||
MOZ_DISABLE_STARTUPCACHE=
|
||||
|
||||
MOZ_ARG_DISABLE_BOOL(startupcache,
|
||||
[ --disable-startupcache Disable startup cache ],
|
||||
|
@ -7486,7 +7485,9 @@ dnl bug 988880: disable startup cache on b2g
|
|||
if test -n "$MOZ_B2G"; then
|
||||
MOZ_DISABLE_STARTUPCACHE=1
|
||||
fi
|
||||
|
||||
if test -n "$MOZ_DISABLE_STARTUPCACHE"; then
|
||||
AC_DEFINE(MOZ_DISABLE_STARTUPCACHE)
|
||||
fi
|
||||
AC_SUBST(MOZ_DISABLE_STARTUPCACHE)
|
||||
|
||||
dnl ========================================================
|
||||
|
@ -9063,7 +9064,7 @@ esac
|
|||
# Run jemalloc configure script
|
||||
|
||||
if test -z "$MOZ_NATIVE_JEMALLOC" -a "$MOZ_MEMORY" && test -n "$MOZ_JEMALLOC3" -o -n "$MOZ_REPLACE_MALLOC"; then
|
||||
ac_configure_args="--build=$build --host=$target --enable-stats --with-jemalloc-prefix=je_"
|
||||
ac_configure_args="--build=$build --host=$target --enable-stats --with-jemalloc-prefix=je_ --disable-valgrind"
|
||||
if test -n "$MOZ_REPLACE_MALLOC"; then
|
||||
# When using replace_malloc, we always want memalign and valloc exported from jemalloc.
|
||||
ac_configure_args="$ac_configure_args ac_cv_func_memalign=yes"
|
||||
|
|
|
@ -20,16 +20,23 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
|
|||
nsSecurityFlags aSecurityFlags,
|
||||
nsContentPolicyType aContentPolicyType,
|
||||
nsIURI* aBaseURI)
|
||||
: mLoadingPrincipal(aLoadingPrincipal)
|
||||
: mLoadingPrincipal(aLoadingContext ?
|
||||
aLoadingContext->NodePrincipal() : aLoadingPrincipal)
|
||||
, mTriggeringPrincipal(aTriggeringPrincipal ?
|
||||
aTriggeringPrincipal : aLoadingPrincipal)
|
||||
aTriggeringPrincipal : mLoadingPrincipal.get())
|
||||
, mLoadingContext(do_GetWeakReference(aLoadingContext))
|
||||
, mSecurityFlags(aSecurityFlags)
|
||||
, mContentPolicyType(aContentPolicyType)
|
||||
, mBaseURI(aBaseURI)
|
||||
{
|
||||
MOZ_ASSERT(aLoadingPrincipal);
|
||||
MOZ_ASSERT(mLoadingPrincipal);
|
||||
MOZ_ASSERT(mTriggeringPrincipal);
|
||||
|
||||
// if consumers pass both, aLoadingContext and aLoadingPrincipal
|
||||
// then the loadingPrincipal must be the same as the node's principal
|
||||
MOZ_ASSERT(!aLoadingContext || !aLoadingPrincipal ||
|
||||
aLoadingContext->NodePrincipal() == aLoadingPrincipal);
|
||||
|
||||
// if the load is sandboxed, we can not also inherit the principal
|
||||
if (mSecurityFlags & nsILoadInfo::SEC_SANDBOXED) {
|
||||
mSecurityFlags ^= nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
|
||||
|
|
|
@ -15,6 +15,11 @@ const Cu = Components.utils;
|
|||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
try {
|
||||
if (Services.prefs.getBoolPref("dom.apps.customization.enabled")) {
|
||||
Cu.import("resource://gre/modules/UserCustomizations.jsm");
|
||||
}
|
||||
} catch(e) {}
|
||||
|
||||
const APPS_SERVICE_CID = Components.ID("{05072afa-92fe-45bf-ae22-39b69c117058}");
|
||||
|
||||
|
|
|
@ -479,9 +479,12 @@ this.AppsUtils = {
|
|||
return true;
|
||||
},
|
||||
|
||||
allowUnsignedAddons: false, // for testing purposes.
|
||||
|
||||
/**
|
||||
* Checks if the app role is allowed.
|
||||
* Checks if the app role is allowed:
|
||||
* Only certified apps can be themes.
|
||||
* Only privileged or certified apps can be addons.
|
||||
* @param aRole : the role assigned to this app.
|
||||
* @param aStatus : the APP_STATUS_* for this app.
|
||||
*/
|
||||
|
@ -489,6 +492,12 @@ this.AppsUtils = {
|
|||
if (aRole == "theme" && aStatus !== Ci.nsIPrincipal.APP_STATUS_CERTIFIED) {
|
||||
return false;
|
||||
}
|
||||
if (!this.allowUnsignedAddons &&
|
||||
(aRole == "addon" &&
|
||||
aStatus !== Ci.nsIPrincipal.APP_STATUS_CERTIFIED &&
|
||||
aStatus !== Ci.nsIPrincipal.APP_STATUS_PRIVILEGED)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
|
@ -718,6 +727,11 @@ this.AppsUtils = {
|
|||
|
||||
// Convert the binary hash data to a hex string.
|
||||
return [toHexString(hash.charCodeAt(i)) for (i in hash)].join("");
|
||||
},
|
||||
|
||||
// Returns the hash for a JS object.
|
||||
computeObjectHash: function(aObject) {
|
||||
return this.computeHash(JSON.stringify(aObject));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,368 @@
|
|||
/* 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 Cu = Components.utils;
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["UserCustomizations"];
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/AppsUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
|
||||
"@mozilla.org/parentprocessmessagemanager;1",
|
||||
"nsIMessageBroadcaster");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
||||
"@mozilla.org/childprocessmessagemanager;1",
|
||||
"nsIMessageSender");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "console",
|
||||
"@mozilla.org/consoleservice;1",
|
||||
"nsIConsoleService");
|
||||
/**
|
||||
* Customization scripts and CSS stylesheets can be specified in an
|
||||
* application manifest with the following syntax:
|
||||
* "customizations": [
|
||||
* {
|
||||
* "filter": "http://youtube.com",
|
||||
* "css": ["file1.css", "file2.css"],
|
||||
* "scripts": ["script1.js", "script2.js"]
|
||||
* }
|
||||
* ]
|
||||
*/
|
||||
|
||||
let debug = Services.prefs.getBoolPref("dom.mozApps.debug")
|
||||
? (aMsg) => {
|
||||
dump("-*-*- UserCustomizations (" +
|
||||
(UserCustomizations._inParent ? "parent" : "child") +
|
||||
"): " + aMsg + "\n");
|
||||
}
|
||||
: (aMsg) => {};
|
||||
|
||||
function log(aStr) {
|
||||
console.logStringMessage(aStr);
|
||||
}
|
||||
|
||||
this.UserCustomizations = {
|
||||
_items: [],
|
||||
_loaded : {}, // Keep track per manifestURL of css and scripts loaded.
|
||||
_windows: null, // Set of currently opened windows.
|
||||
_enabled: false,
|
||||
|
||||
_addItem: function(aItem) {
|
||||
debug("_addItem: " + uneval(aItem));
|
||||
this._items.push(aItem);
|
||||
if (this._inParent) {
|
||||
ppmm.broadcastAsyncMessage("UserCustomizations:Add", [aItem]);
|
||||
}
|
||||
},
|
||||
|
||||
_removeItem: function(aHash) {
|
||||
debug("_removeItem: " + aHash);
|
||||
let index = -1;
|
||||
this._items.forEach((script, pos) => {
|
||||
if (script.hash == aHash ) {
|
||||
index = pos;
|
||||
}
|
||||
});
|
||||
|
||||
if (index != -1) {
|
||||
this._items.splice(index, 1);
|
||||
}
|
||||
|
||||
if (this._inParent) {
|
||||
ppmm.broadcastAsyncMessage("UserCustomizations:Remove", aHash);
|
||||
}
|
||||
},
|
||||
|
||||
register: function(aManifest, aApp) {
|
||||
debug("Starting customization registration for " + aApp.manifestURL);
|
||||
|
||||
if (!this._enabled || !aApp.enabled || aApp.role != "addon") {
|
||||
debug("Rejecting registration (global enabled=" + this._enabled +
|
||||
") (app role=" + aApp.role +
|
||||
", enabled=" + aApp.enabled + ")");
|
||||
debug(uneval(aApp));
|
||||
return;
|
||||
}
|
||||
|
||||
let customizations = aManifest.customizations;
|
||||
if (customizations === undefined || !Array.isArray(customizations)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let base = Services.io.newURI(aApp.origin, null, null);
|
||||
|
||||
customizations.forEach(item => {
|
||||
// The filter property is mandatory.
|
||||
if (!item.filter || (typeof item.filter !== "string")) {
|
||||
log("Mandatory filter property not found in this customization item: " +
|
||||
uneval(item) + " in " + aApp.manifestURL);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a new object with resolved urls and a hash that we reuse to
|
||||
// remove items.
|
||||
let custom = {
|
||||
filter: item.filter,
|
||||
status: aApp.appStatus,
|
||||
manifestURL: aApp.manifestURL,
|
||||
css: [],
|
||||
scripts: []
|
||||
};
|
||||
custom.hash = AppsUtils.computeObjectHash(item);
|
||||
|
||||
if (item.css && Array.isArray(item.css)) {
|
||||
item.css.forEach((css) => {
|
||||
custom.css.push(base.resolve(css));
|
||||
});
|
||||
}
|
||||
|
||||
if (item.scripts && Array.isArray(item.scripts)) {
|
||||
item.scripts.forEach((script) => {
|
||||
custom.scripts.push(base.resolve(script));
|
||||
});
|
||||
}
|
||||
|
||||
this._addItem(custom);
|
||||
});
|
||||
this._updateAllWindows();
|
||||
},
|
||||
|
||||
_updateAllWindows: function() {
|
||||
debug("UpdateWindows");
|
||||
if (this._inParent) {
|
||||
ppmm.broadcastAsyncMessage("UserCustomizations:UpdateWindows", {});
|
||||
}
|
||||
// Inject in all currently opened windows.
|
||||
this._windows.forEach(this._injectInWindow.bind(this));
|
||||
},
|
||||
|
||||
unregister: function(aManifest, aApp) {
|
||||
if (!this._enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
debug("Starting customization unregistration for " + aApp.manifestURL);
|
||||
let customizations = aManifest.customizations;
|
||||
if (customizations === undefined || !Array.isArray(customizations)) {
|
||||
return;
|
||||
}
|
||||
|
||||
customizations.forEach(item => {
|
||||
this._removeItem(AppsUtils.computeObjectHash(item));
|
||||
});
|
||||
this._unloadForManifestURL(aApp.manifestURL);
|
||||
},
|
||||
|
||||
_unloadForManifestURL: function(aManifestURL) {
|
||||
debug("_unloadForManifestURL " + aManifestURL);
|
||||
|
||||
if (this._inParent) {
|
||||
ppmm.broadcastAsyncMessage("UserCustomizations:Unload", aManifestURL);
|
||||
}
|
||||
|
||||
if (!this._loaded[aManifestURL]) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._loaded[aManifestURL].scripts &&
|
||||
this._loaded[aManifestURL].scripts.length > 0) {
|
||||
// We can't rollback script changes, so don't even try to unload in this
|
||||
// situation.
|
||||
return;
|
||||
}
|
||||
|
||||
this._loaded[aManifestURL].css.forEach(aItem => {
|
||||
try {
|
||||
debug("unloading " + aItem.uri.spec);
|
||||
let utils = aItem.window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
utils.removeSheet(aItem.uri, Ci.nsIDOMWindowUtils.AUTHOR_SHEET);
|
||||
} catch(e) {
|
||||
log("Error unloading stylesheet " + aItem.uri.spec + " : " + e);
|
||||
}
|
||||
});
|
||||
|
||||
this._loaded[aManifestURL] = null;
|
||||
},
|
||||
|
||||
_injectItem: function(aWindow, aItem, aInjected) {
|
||||
debug("Injecting item " + uneval(aItem) + " in " + aWindow.location.href);
|
||||
let utils = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
|
||||
let manifestURL = aItem.manifestURL;
|
||||
|
||||
// Load the stylesheets only in this window.
|
||||
aItem.css.forEach(aCss => {
|
||||
if (aInjected.indexOf(aCss) !== -1) {
|
||||
debug("Skipping duplicated css: " + aCss);
|
||||
return;
|
||||
}
|
||||
|
||||
let uri = Services.io.newURI(aCss, null, null);
|
||||
try {
|
||||
utils.loadSheet(uri, Ci.nsIDOMWindowUtils.AUTHOR_SHEET);
|
||||
if (!this._loaded[manifestURL]) {
|
||||
this._loaded[manifestURL] = { css: [], scripts: [] };
|
||||
}
|
||||
this._loaded[manifestURL].css.push({ window: aWindow, uri: uri });
|
||||
aInjected.push(aCss);
|
||||
} catch(e) {
|
||||
log("Error loading stylesheet " + aCss + " : " + e);
|
||||
}
|
||||
});
|
||||
|
||||
let sandbox;
|
||||
if (aItem.scripts.length > 0) {
|
||||
sandbox = Cu.Sandbox([aWindow],
|
||||
{ wantComponents: false,
|
||||
sandboxPrototype: aWindow });
|
||||
}
|
||||
|
||||
// Load the scripts using a sandbox.
|
||||
aItem.scripts.forEach(aScript => {
|
||||
debug("Sandboxing " + aScript);
|
||||
if (aInjected.indexOf(aScript) !== -1) {
|
||||
debug("Skipping duplicated script: " + aScript);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Services.scriptloader.loadSubScript(aScript, sandbox, "UTF-8");
|
||||
if (!this._loaded[manifestURL]) {
|
||||
this._loaded[manifestURL] = { css: [], scripts: [] };
|
||||
}
|
||||
this._loaded[manifestURL].scripts.push({ sandbox: sandbox, uri: aScript });
|
||||
aInjected.push(aScript);
|
||||
} catch(e) {
|
||||
log("Error sandboxing " + aScript + " : " + e);
|
||||
}
|
||||
});
|
||||
|
||||
// Makes sure we get rid of the sandbox.
|
||||
if (sandbox) {
|
||||
aWindow.addEventListener("unload", () => {
|
||||
Cu.nukeSandbox(sandbox);
|
||||
sandbox = null;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_injectInWindow: function(aWindow) {
|
||||
debug("_injectInWindow");
|
||||
|
||||
if (!aWindow || !aWindow.document) {
|
||||
return;
|
||||
}
|
||||
|
||||
let principal = aWindow.document.nodePrincipal;
|
||||
debug("principal status: " + principal.appStatus);
|
||||
|
||||
let href = aWindow.location.href;
|
||||
|
||||
// The list of resources loaded in this window, used to filter out
|
||||
// duplicates.
|
||||
let injected = [];
|
||||
|
||||
this._items.forEach((aItem) => {
|
||||
// We only allow customizations to apply to apps with an equal or lower
|
||||
// privilege level.
|
||||
if (principal.appStatus > aItem.status) {
|
||||
return;
|
||||
}
|
||||
|
||||
let regexp = new RegExp(aItem.filter, "g");
|
||||
if (regexp.test(href)) {
|
||||
this._injectItem(aWindow, aItem, injected);
|
||||
debug("Currently injected: " + injected.toString());
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
if (aTopic === "content-document-global-created") {
|
||||
let window = aSubject.QueryInterface(Ci.nsIDOMWindow);
|
||||
let href = window.location.href;
|
||||
if (!href || href == "about:blank") {
|
||||
return;
|
||||
}
|
||||
|
||||
let id = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils)
|
||||
.currentInnerWindowID;
|
||||
this._windows.set(id, window);
|
||||
|
||||
debug("document created: " + href);
|
||||
this._injectInWindow(window);
|
||||
} else if (aTopic === "inner-window-destroyed") {
|
||||
let winId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
|
||||
this._windows.delete(winId);
|
||||
}
|
||||
},
|
||||
|
||||
init: function() {
|
||||
this._enabled = false;
|
||||
try {
|
||||
this._enabled = Services.prefs.getBoolPref("dom.apps.customization.enabled");
|
||||
} catch(e) {}
|
||||
|
||||
if (!this._enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._windows = new Map(); // Can't be a WeakMap because we need to enumerate.
|
||||
this._inParent = Cc["@mozilla.org/xre/runtime;1"]
|
||||
.getService(Ci.nsIXULRuntime)
|
||||
.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
|
||||
|
||||
debug("init");
|
||||
|
||||
Services.obs.addObserver(this, "content-document-global-created",
|
||||
/* ownsWeak */ false);
|
||||
Services.obs.addObserver(this, "inner-window-destroyed",
|
||||
/* ownsWeak */ false);
|
||||
|
||||
if (this._inParent) {
|
||||
ppmm.addMessageListener("UserCustomizations:List", this);
|
||||
} else {
|
||||
cpmm.addMessageListener("UserCustomizations:Add", this);
|
||||
cpmm.addMessageListener("UserCustomizations:Remove", this);
|
||||
cpmm.addMessageListener("UserCustomizations:Unload", this);
|
||||
cpmm.addMessageListener("UserCustomizations:UpdateWindows", this);
|
||||
cpmm.sendAsyncMessage("UserCustomizations:List", {});
|
||||
}
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
let name = aMessage.name;
|
||||
let data = aMessage.data;
|
||||
|
||||
switch(name) {
|
||||
case "UserCustomizations:List":
|
||||
aMessage.target.sendAsyncMessage("UserCustomizations:Add", this._items);
|
||||
break;
|
||||
case "UserCustomizations:Add":
|
||||
data.forEach(this._addItem, this);
|
||||
break;
|
||||
case "UserCustomizations:Remove":
|
||||
this._removeItem(data);
|
||||
break;
|
||||
case "UserCustomizations:Unload":
|
||||
this._unloadForManifestURL(data);
|
||||
break;
|
||||
case "UserCustomizations:UpdateWindows":
|
||||
this._updateAllWindows();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UserCustomizations.init();
|
|
@ -43,6 +43,23 @@ Cu.import("resource://gre/modules/osfile.jsm");
|
|||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "UserCustomizations", function() {
|
||||
let enabled = false;
|
||||
try {
|
||||
enabled = Services.prefs.getBoolPref("dom.apps.customization.enabled");
|
||||
} catch(e) {}
|
||||
|
||||
if (enabled) {
|
||||
return Cu.import("resource://gre/modules/UserCustomizations.jsm", {})
|
||||
.UserCustomizations;
|
||||
} else {
|
||||
return {
|
||||
register: function() {},
|
||||
unregister: function() {}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "TrustedRootCertificate",
|
||||
"resource://gre/modules/StoreTrustAnchor.jsm");
|
||||
|
||||
|
@ -406,6 +423,7 @@ this.DOMApplicationRegistry = {
|
|||
app.redirects = this.sanitizeRedirects(aResult.redirects);
|
||||
}
|
||||
app.kind = this.appKind(app, aResult.manifest);
|
||||
UserCustomizations.register(aResult.manifest, app);
|
||||
});
|
||||
|
||||
// Nothing else to do but notifying we're ready.
|
||||
|
@ -1097,6 +1115,7 @@ this.DOMApplicationRegistry = {
|
|||
this._registerSystemMessages(manifest, app);
|
||||
this._registerInterAppConnections(manifest, app);
|
||||
appsToRegister.push({ manifest: manifest, app: app });
|
||||
UserCustomizations.register(manifest, app);
|
||||
});
|
||||
this._safeToClone.resolve();
|
||||
this._registerActivitiesForApps(appsToRegister, aRunUpdate);
|
||||
|
@ -1991,7 +2010,8 @@ this.DOMApplicationRegistry = {
|
|||
// Updates the redirect mapping, activities and system message handlers.
|
||||
// aOldManifest can be null if we don't have any handler to unregister.
|
||||
updateAppHandlers: function(aOldManifest, aNewManifest, aApp) {
|
||||
debug("updateAppHandlers: old=" + aOldManifest + " new=" + aNewManifest);
|
||||
debug("updateAppHandlers: old=" + uneval(aOldManifest) +
|
||||
" new=" + uneval(aNewManifest));
|
||||
this.notifyAppsRegistryStart();
|
||||
if (aApp.appStatus >= Ci.nsIPrincipal.APP_STATUS_PRIVILEGED) {
|
||||
aApp.redirects = this.sanitizeRedirects(aNewManifest.redirects);
|
||||
|
@ -2001,6 +2021,8 @@ this.DOMApplicationRegistry = {
|
|||
new ManifestHelper(aNewManifest, aApp.origin, aApp.manifestURL);
|
||||
this._saveWidgetsFullPath(manifest, aApp);
|
||||
|
||||
aApp.role = manifest.role ? manifest.role : "";
|
||||
|
||||
if (supportSystemMessages()) {
|
||||
if (aOldManifest) {
|
||||
this._unregisterActivities(aOldManifest, aApp);
|
||||
|
@ -2012,6 +2034,12 @@ this.DOMApplicationRegistry = {
|
|||
// Nothing else to do but notifying we're ready.
|
||||
this.notifyAppsRegistryReady();
|
||||
}
|
||||
|
||||
// Update user customizations.
|
||||
if (aOldManifest) {
|
||||
UserCustomizations.unregister(aOldManifest, aApp);
|
||||
}
|
||||
UserCustomizations.register(aNewManifest, aApp);
|
||||
},
|
||||
|
||||
checkForUpdate: function(aData, aMm) {
|
||||
|
@ -4019,6 +4047,7 @@ this.DOMApplicationRegistry = {
|
|||
if (supportSystemMessages()) {
|
||||
this._unregisterActivities(aApp.manifest, aApp);
|
||||
}
|
||||
UserCustomizations.unregister(aApp.manifest, aApp);
|
||||
|
||||
let dir = this._getAppDir(id);
|
||||
try {
|
||||
|
@ -4388,6 +4417,12 @@ this.DOMApplicationRegistry = {
|
|||
});
|
||||
this.broadcastMessage("Webapps:SetEnabled:Return", app);
|
||||
});
|
||||
|
||||
// Update customization.
|
||||
this.getManifestFor(app.manifestURL).then((aManifest) => {
|
||||
app.enabled ? UserCustomizations.register(aManifest, app)
|
||||
: UserCustomizations.unregister(aManifest, app);
|
||||
});
|
||||
},
|
||||
|
||||
getManifestFor: function(aManifestURL) {
|
||||
|
|
|
@ -38,6 +38,7 @@ EXTRA_JS_MODULES += [
|
|||
'PermissionsInstaller.jsm',
|
||||
'PermissionsTable.jsm',
|
||||
'StoreTrustAnchor.jsm',
|
||||
'UserCustomizations.jsm',
|
||||
]
|
||||
|
||||
EXTRA_PP_JS_MODULES += [
|
||||
|
|
Двоичный файл не отображается.
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>This page will be modified by the add-on</title>
|
||||
<script>
|
||||
function sendAlertsForNode(node) {
|
||||
alert(node.textContent);
|
||||
var color = window.getComputedStyle(node).getPropertyValue("color");
|
||||
alert(color);
|
||||
}
|
||||
|
||||
function run() {
|
||||
sendAlertsForNode(document.getElementById("header"));
|
||||
sendAlertsForNode(document.getElementById("header2"));
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="run()">
|
||||
<h1 id="header">Lorem ipsum</h1>
|
||||
<h2 id="header2">Uncustomized content</h2>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "Addon app",
|
||||
"description": "Let me inject script and css!",
|
||||
"customizations" : [
|
||||
{
|
||||
"filter": "http://mochi.test:8888/tests/dom/apps/tests/addons",
|
||||
"css": ["style.css", "style2.css", "invalid.css", "style.css"],
|
||||
"scripts": ["script.js", "script2.js", "invalid.js", "script.js"]
|
||||
}
|
||||
],
|
||||
"role": "addon"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
document.addEventListener("DOMContentLoaded", function() {
|
||||
var head = document.getElementById("header");
|
||||
head.innerHTML = "Hello World!";
|
||||
}, false);
|
|
@ -0,0 +1,3 @@
|
|||
#header {
|
||||
color: red;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"name": "Addon app",
|
||||
"description": "Let me inject script and css!",
|
||||
"package_path" : "application.zip"
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
Content-Type: application/manifest+json
|
|
@ -1,6 +1,10 @@
|
|||
[DEFAULT]
|
||||
skip-if = e10s
|
||||
support-files =
|
||||
addons/application.zip
|
||||
addons/update.webapp
|
||||
addons/update.webapp^headers^
|
||||
addons/index.html
|
||||
chromeAddCert.js
|
||||
file_app.sjs
|
||||
file_app.template.html
|
||||
|
@ -25,6 +29,8 @@ support-files =
|
|||
marketplace/*
|
||||
pkg_install_iframe.html
|
||||
|
||||
[test_app_addons.html]
|
||||
skip-if = os == "android" || toolkit == "gonk" # embed-apps doesn't work in mochitest app
|
||||
[test_app_enabled.html]
|
||||
[test_app_update.html]
|
||||
skip-if = os == "android" || toolkit == "gonk" # embed-apps doesn't work in mochitest app
|
||||
|
|
|
@ -0,0 +1,186 @@
|
|||
<!DOCTYPE HTML><!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1042881
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 923897 - Test apps as addons</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" />
|
||||
<script type="application/javascript;version=1.7">
|
||||
/**
|
||||
* Test for Bug 923897
|
||||
* This file covers testing addons.
|
||||
*
|
||||
* The setup is as follows:
|
||||
* - app is installed and offers both script and css to inject in
|
||||
* http://mochi.test:8888/tests/dom/apps/tests/addons/index.html
|
||||
*/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
let appManifestURL = "http://mochi.test:8888/tests/dom/apps/tests/addons/update.webapp";
|
||||
|
||||
let gGenerator = runTest();
|
||||
|
||||
function go() {
|
||||
gGenerator.next();
|
||||
}
|
||||
|
||||
function continueTest() {
|
||||
try {
|
||||
gGenerator.next();
|
||||
} catch (e if e instanceof StopIteration) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
function mozAppsError() {
|
||||
ok(false, "mozApps error: " + this.error.name);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
// Triggers one navigation test to the given page.
|
||||
// Waits for alert() messages before tearing down the iframe.
|
||||
function openPage(pageURL, messages) {
|
||||
info("Navigating to " + pageURL);
|
||||
let ifr = document.createElement("iframe");
|
||||
let listener = function(event) {
|
||||
let message = messages.shift();
|
||||
is(event.detail.message, message, "Checking alert message for " + pageURL);
|
||||
if (messages.length == 0) {
|
||||
ifr.removeEventListener("mozbrowsershowmodalprompt", listener);
|
||||
ifr.parentNode.removeChild(ifr);
|
||||
continueTest();
|
||||
}
|
||||
}
|
||||
|
||||
ifr.addEventListener("mozbrowsershowmodalprompt", listener, false);
|
||||
|
||||
// Open an the app url in an iframe.
|
||||
ifr.setAttribute("mozbrowser", "true");
|
||||
ifr.setAttribute("src", pageURL);
|
||||
document.getElementById("container").appendChild(ifr);
|
||||
}
|
||||
|
||||
let apps = [];
|
||||
|
||||
function installApp(manifestURL) {
|
||||
info("About to install app at " + manifestURL);
|
||||
let req = navigator.mozApps.installPackage(manifestURL);
|
||||
req.onsuccess = function() {
|
||||
apps.push(req.result);
|
||||
is(req.result.manifestURL, manifestURL, "app installed");
|
||||
if (req.result.installState == "installed") {
|
||||
is(req.result.installState, "installed", "app downloaded");
|
||||
continueTest();
|
||||
} else {
|
||||
req.result.ondownloadapplied = function() {
|
||||
is(req.result.installState, "installed", "app downloaded");
|
||||
continueTest();
|
||||
}
|
||||
}
|
||||
}
|
||||
req.onerror = mozAppsError;
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
// Set up.
|
||||
SpecialPowers.setAllAppsLaunchable(true);
|
||||
SpecialPowers.allowUnsignedAddons();
|
||||
SpecialPowers.pushPrefEnv({'set': [
|
||||
["dom.mozBrowserFramesEnabled", true],
|
||||
["dom.apps.customization.enabled", true],
|
||||
]},continueTest);
|
||||
yield undefined;
|
||||
|
||||
SpecialPowers.pushPermissions(
|
||||
[{ "type": "webapps-manage", "allow": 1, "context": document },
|
||||
{ "type": "browser", "allow": 1, "context": document } ],
|
||||
continueTest);
|
||||
yield undefined;
|
||||
|
||||
SpecialPowers.autoConfirmAppInstall(continueTest);
|
||||
yield undefined;
|
||||
|
||||
SpecialPowers.autoConfirmAppUninstall(continueTest);
|
||||
yield undefined;
|
||||
|
||||
// Opens the iframe to the test page, initial state.
|
||||
openPage("http://mochi.test:8888/tests/dom/apps/tests/addons/index.html",
|
||||
["Lorem ipsum", "rgb(0, 0, 0)",
|
||||
"Uncustomized content", "rgb(0, 0, 0)"]);
|
||||
yield undefined;
|
||||
|
||||
// Install addon app.
|
||||
installApp(appManifestURL);
|
||||
yield undefined;
|
||||
|
||||
// Opens the iframe to the test page, customized.
|
||||
openPage("http://mochi.test:8888/tests/dom/apps/tests/addons/index.html",
|
||||
["Hello World!", "rgb(255, 0, 0)",
|
||||
"Customized content", "rgb(0, 0, 255)"]);
|
||||
yield undefined;
|
||||
|
||||
// Disable the app.
|
||||
navigator.mozApps.mgmt.onenabledstatechange = function(event) {
|
||||
ok(true, "onenabledstatechange received");
|
||||
is(event.application.enabled, false, "Application is disabled");
|
||||
is(apps[0].enabled, false, "Application is disabled");
|
||||
continueTest();
|
||||
}
|
||||
|
||||
navigator.mozApps.mgmt.setEnabled(apps[0], false);
|
||||
yield undefined;
|
||||
|
||||
// Opens the iframe to the test page, back to initial state.
|
||||
openPage("http://mochi.test:8888/tests/dom/apps/tests/addons/index.html",
|
||||
["Lorem ipsum", "rgb(0, 0, 0)",
|
||||
"Uncustomized content", "rgb(0, 0, 0)"]);
|
||||
yield undefined;
|
||||
|
||||
// Re-enable the app.
|
||||
navigator.mozApps.mgmt.onenabledstatechange = function(event) {
|
||||
ok(true, "onenabledstatechange received");
|
||||
is(event.application.enabled, true, "Application is enabled");
|
||||
is(apps[0].enabled, true, "Application is enabled");
|
||||
continueTest();
|
||||
}
|
||||
|
||||
navigator.mozApps.mgmt.setEnabled(apps[0], true);
|
||||
yield undefined;
|
||||
|
||||
// Opens the iframe to the test page, customized.
|
||||
openPage("http://mochi.test:8888/tests/dom/apps/tests/addons/index.html",
|
||||
["Hello World!", "rgb(255, 0, 0)",
|
||||
"Customized content", "rgb(0, 0, 255)"]);
|
||||
yield undefined;
|
||||
|
||||
// Clean up after ourselves by uninstalling apps.
|
||||
while (apps.length) {
|
||||
let app = apps.pop();
|
||||
req = navigator.mozApps.mgmt.uninstall(app);
|
||||
req.onsuccess = continueTest;
|
||||
req.onerror = mozAppsError;
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
// Opens the iframe to the test page, back to initial state.
|
||||
openPage("http://mochi.test:8888/tests/dom/apps/tests/addons/index.html",
|
||||
["Lorem ipsum", "rgb(0, 0, 0)",
|
||||
"Uncustomized content", "rgb(0, 0, 0)"]);
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="go()">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<div id="container"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -131,7 +131,7 @@ ConsoleStructuredCloneCallbacksError(JSContext* /* aCx */,
|
|||
NS_WARNING("Failed to clone data for the Console API in workers.");
|
||||
}
|
||||
|
||||
JSStructuredCloneCallbacks gConsoleCallbacks = {
|
||||
static const JSStructuredCloneCallbacks gConsoleCallbacks = {
|
||||
ConsoleStructuredCloneCallbacksRead,
|
||||
ConsoleStructuredCloneCallbacksWrite,
|
||||
ConsoleStructuredCloneCallbacksError
|
||||
|
|
|
@ -1620,7 +1620,7 @@ ShouldClearPurple(nsIContent* aContent)
|
|||
}
|
||||
|
||||
JSObject* o = GetJSObjectChild(aContent);
|
||||
if (o && xpc_IsGrayGCThing(o)) {
|
||||
if (o && JS::ObjectIsMarkedGray(o)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -287,7 +287,7 @@ PostMessageFreeTransferStructuredClone(uint32_t aTag, JS::TransferableOwnership
|
|||
}
|
||||
}
|
||||
|
||||
JSStructuredCloneCallbacks kPostMessageCallbacks = {
|
||||
const JSStructuredCloneCallbacks kPostMessageCallbacks = {
|
||||
PostMessageReadStructuredClone,
|
||||
PostMessageWriteStructuredClone,
|
||||
nullptr,
|
||||
|
|
|
@ -1026,17 +1026,17 @@ nsDOMClassInfo::Resolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
|||
|
||||
JS::Rooted<JSObject*> global(cx, ::JS_GetGlobalForObject(cx, obj));
|
||||
|
||||
JS::Rooted<JS::Value> val(cx);
|
||||
if (!::JS_LookupProperty(cx, global, mData->mName, &val)) {
|
||||
JS::Rooted<JSPropertyDescriptor> desc(cx);
|
||||
if (!JS_GetPropertyDescriptor(cx, global, mData->mName, &desc)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
if (!val.isPrimitive()) {
|
||||
if (desc.object() && !desc.hasGetterOrSetter() && desc.value().isObject()) {
|
||||
// If val is not an (non-null) object there either is no
|
||||
// constructor for this class, or someone messed with
|
||||
// window.classname, just fall through and let the JS engine
|
||||
// return the Object constructor.
|
||||
if (!::JS_DefinePropertyById(cx, obj, id, val,
|
||||
if (!::JS_DefinePropertyById(cx, obj, id, desc.value(),
|
||||
JSPROP_ENUMERATE,
|
||||
JS_STUBGETTER, JS_STUBSETTER)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
@ -1620,16 +1620,16 @@ nsDOMConstructor::HasInstance(nsIXPConnectWrappedNative *wrapper,
|
|||
if (!name_struct) {
|
||||
// This isn't a normal DOM object, see if this constructor lives on its
|
||||
// prototype chain.
|
||||
JS::Rooted<JS::Value> val(cx);
|
||||
if (!JS_GetProperty(cx, obj, "prototype", &val)) {
|
||||
JS::Rooted<JSPropertyDescriptor> desc(cx);
|
||||
if (!JS_GetPropertyDescriptor(cx, obj, "prototype", &desc)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
if (val.isPrimitive()) {
|
||||
if (!desc.object() || desc.hasGetterOrSetter() || !desc.value().isObject()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> dot_prototype(cx, val.toObjectOrNull());
|
||||
JS::Rooted<JSObject*> dot_prototype(cx, &desc.value().toObject());
|
||||
|
||||
JS::Rooted<JSObject*> proto(cx, dom_obj);
|
||||
for (;;) {
|
||||
|
@ -1933,19 +1933,19 @@ ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindow *aWin, JSContext *cx,
|
|||
if (class_parent_name) {
|
||||
JSAutoCompartment ac(cx, winobj);
|
||||
|
||||
JS::Rooted<JS::Value> val(cx);
|
||||
if (!JS_LookupProperty(cx, winobj, CutPrefix(class_parent_name), &val)) {
|
||||
JS::Rooted<JSPropertyDescriptor> desc(cx);
|
||||
if (!JS_GetPropertyDescriptor(cx, winobj, CutPrefix(class_parent_name), &desc)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
if (val.isObject()) {
|
||||
JS::Rooted<JSObject*> obj(cx, &val.toObject());
|
||||
if (!JS_LookupProperty(cx, obj, "prototype", &val)) {
|
||||
if (desc.object() && !desc.hasGetterOrSetter() && desc.value().isObject()) {
|
||||
JS::Rooted<JSObject*> obj(cx, &desc.value().toObject());
|
||||
if (!JS_GetPropertyDescriptor(cx, obj, "prototype", &desc)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
if (val.isObject()) {
|
||||
proto = &val.toObject();
|
||||
if (desc.object() && !desc.hasGetterOrSetter() && desc.value().isObject()) {
|
||||
proto = &desc.value().toObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -621,6 +621,8 @@ public:
|
|||
virtual bool delete_(JSContext *cx, JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<jsid> id,
|
||||
bool *bp) const MOZ_OVERRIDE;
|
||||
virtual bool enumerate(JSContext *cx, JS::Handle<JSObject*> proxy,
|
||||
JS::MutableHandle<JSObject*> vp) const MOZ_OVERRIDE;
|
||||
virtual bool preventExtensions(JSContext *cx,
|
||||
JS::Handle<JSObject*> proxy,
|
||||
bool *succeeded) const MOZ_OVERRIDE;
|
||||
|
@ -648,11 +650,6 @@ public:
|
|||
JS::Handle<jsid> id, bool *bp) const MOZ_OVERRIDE;
|
||||
virtual bool getOwnEnumerablePropertyKeys(JSContext *cx, JS::Handle<JSObject*> proxy,
|
||||
JS::AutoIdVector &props) const MOZ_OVERRIDE;
|
||||
virtual bool getEnumerablePropertyKeys(JSContext *cx, JS::Handle<JSObject*> proxy,
|
||||
JS::AutoIdVector &props) const MOZ_OVERRIDE;
|
||||
virtual bool iterate(JSContext *cx, JS::Handle<JSObject*> proxy,
|
||||
unsigned flags,
|
||||
JS::MutableHandle<JSObject*> objp) const MOZ_OVERRIDE;
|
||||
virtual const char *className(JSContext *cx,
|
||||
JS::Handle<JSObject*> wrapper) const MOZ_OVERRIDE;
|
||||
|
||||
|
@ -928,28 +925,12 @@ nsOuterWindowProxy::getOwnEnumerablePropertyKeys(JSContext *cx, JS::Handle<JSObj
|
|||
}
|
||||
|
||||
bool
|
||||
nsOuterWindowProxy::getEnumerablePropertyKeys(JSContext *cx, JS::Handle<JSObject*> proxy,
|
||||
JS::AutoIdVector &props) const
|
||||
nsOuterWindowProxy::enumerate(JSContext *cx, JS::Handle<JSObject*> proxy,
|
||||
JS::MutableHandle<JSObject*> objp) const
|
||||
{
|
||||
// Just our indexed stuff followed by our "normal" own property names.
|
||||
if (!AppendIndexedPropertyNames(cx, proxy, props)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JS::AutoIdVector innerProps(cx);
|
||||
if (!js::Wrapper::getEnumerablePropertyKeys(cx, proxy, innerProps)) {
|
||||
return false;
|
||||
}
|
||||
return js::AppendUnique(cx, props, innerProps);
|
||||
}
|
||||
|
||||
bool
|
||||
nsOuterWindowProxy::iterate(JSContext *cx, JS::Handle<JSObject*> proxy,
|
||||
unsigned flags, JS::MutableHandle<JSObject*> objp) const
|
||||
{
|
||||
// BaseProxyHandler::iterate seems to do what we want here: fall
|
||||
// back on the property names returned from keys() and enumerate().
|
||||
return js::BaseProxyHandler::iterate(cx, proxy, flags, objp);
|
||||
// BaseProxyHandler::enumerate seems to do what we want here: fall
|
||||
// back on the property names returned from js::GetPropertyKeys()
|
||||
return js::BaseProxyHandler::enumerate(cx, proxy, objp);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1913,7 +1894,8 @@ nsGlobalWindow::UnmarkGrayTimers()
|
|||
if (f) {
|
||||
// Callable() already does xpc_UnmarkGrayObject.
|
||||
DebugOnly<JS::Handle<JSObject*> > o = f->Callable();
|
||||
MOZ_ASSERT(!xpc_IsGrayGCThing(o.value), "Should have been unmarked");
|
||||
MOZ_ASSERT(!JS::ObjectIsMarkedGray(o.value),
|
||||
"Should have been unmarked");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2698,7 +2680,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
|
|||
newInnerWindow->mChromeEventHandler = mChromeEventHandler;
|
||||
}
|
||||
|
||||
mContext->GC(JS::gcreason::SET_NEW_DOCUMENT);
|
||||
nsJSContext::PokeGC(JS::gcreason::SET_NEW_DOCUMENT);
|
||||
mContext->DidInitializeContext();
|
||||
|
||||
// We wait to fire the debugger hook until the window is all set up and hooked
|
||||
|
@ -2921,7 +2903,7 @@ nsGlobalWindow::DetachFromDocShell()
|
|||
mChromeEventHandler = nullptr; // force release now
|
||||
|
||||
if (mContext) {
|
||||
mContext->GC(JS::gcreason::SET_DOC_SHELL);
|
||||
nsJSContext::PokeGC(JS::gcreason::SET_DOC_SHELL);
|
||||
mContext = nullptr;
|
||||
}
|
||||
|
||||
|
@ -8072,7 +8054,7 @@ PostMessageFreeTransferStructuredClone(uint32_t aTag, JS::TransferableOwnership
|
|||
}
|
||||
}
|
||||
|
||||
JSStructuredCloneCallbacks kPostMessageCallbacks = {
|
||||
const JSStructuredCloneCallbacks kPostMessageCallbacks = {
|
||||
PostMessageReadStructuredClone,
|
||||
PostMessageWriteStructuredClone,
|
||||
nullptr,
|
||||
|
|
|
@ -27,8 +27,8 @@ class nsIDOMWindow;
|
|||
class nsIURI;
|
||||
|
||||
#define NS_ISCRIPTCONTEXT_IID \
|
||||
{ 0x274840b6, 0x7349, 0x4798, \
|
||||
{ 0xbe, 0x24, 0xbd, 0x75, 0xa6, 0x46, 0x99, 0xb7 } }
|
||||
{ 0x901f0d5e, 0x217a, 0x45fa, \
|
||||
{ 0x9a, 0xca, 0x45, 0x0f, 0xe7, 0x2f, 0x10, 0x9a } }
|
||||
|
||||
class nsIOffThreadScriptReceiver;
|
||||
|
||||
|
@ -67,19 +67,11 @@ public:
|
|||
*/
|
||||
virtual bool IsContextInitialized() = 0;
|
||||
|
||||
/**
|
||||
* For garbage collected systems, do a synchronous collection pass.
|
||||
* May be a no-op on other systems
|
||||
*
|
||||
* @return NS_OK if the method is successful
|
||||
*/
|
||||
virtual void GC(JS::gcreason::Reason aReason) = 0;
|
||||
|
||||
// SetProperty is suspect and jst believes should not be needed. Currenly
|
||||
// used only for "arguments".
|
||||
virtual nsresult SetProperty(JS::Handle<JSObject*> aTarget,
|
||||
const char* aPropName, nsISupports* aVal) = 0;
|
||||
/**
|
||||
/**
|
||||
* Called to set/get information if the script context is
|
||||
* currently processing a script tag
|
||||
*/
|
||||
|
@ -134,4 +126,3 @@ public:
|
|||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIOffThreadScriptReceiver, NS_IOFFTHREADSCRIPTRECEIVER_IID)
|
||||
|
||||
#endif // nsIScriptContext_h__
|
||||
|
||||
|
|
|
@ -2302,12 +2302,6 @@ nsJSContext::KillICCTimer()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsJSContext::GC(JS::gcreason::Reason aReason)
|
||||
{
|
||||
PokeGC(aReason);
|
||||
}
|
||||
|
||||
class NotifyGCEndRunnable : public nsRunnable
|
||||
{
|
||||
nsString mMessage;
|
||||
|
@ -2754,7 +2748,7 @@ nsJSContext::EnsureStatics()
|
|||
sPrevGCSliceCallback = JS::SetGCSliceCallback(sRuntime, DOMGCSliceCallback);
|
||||
|
||||
// Set up the structured clone callbacks.
|
||||
static JSStructuredCloneCallbacks cloneCallbacks = {
|
||||
static const JSStructuredCloneCallbacks cloneCallbacks = {
|
||||
NS_DOMReadStructuredClone,
|
||||
NS_DOMWriteStructuredClone,
|
||||
NS_DOMStructuredCloneError,
|
||||
|
@ -2765,7 +2759,7 @@ nsJSContext::EnsureStatics()
|
|||
JS_SetStructuredCloneCallbacks(sRuntime, &cloneCallbacks);
|
||||
|
||||
// Set up the asm.js cache callbacks
|
||||
static JS::AsmJSCacheOps asmJSCacheOps = {
|
||||
static const JS::AsmJSCacheOps asmJSCacheOps = {
|
||||
AsmJSCacheOpenEntryForRead,
|
||||
asmjscache::CloseEntryForRead,
|
||||
AsmJSCacheOpenEntryForWrite,
|
||||
|
|
|
@ -125,8 +125,6 @@ public:
|
|||
// Calling LikelyShortLivingObjectCreated() makes a GC more likely.
|
||||
static void LikelyShortLivingObjectCreated();
|
||||
|
||||
virtual void GC(JS::gcreason::Reason aReason) MOZ_OVERRIDE;
|
||||
|
||||
static uint32_t CleanupsSinceLastGC();
|
||||
|
||||
nsIScriptGlobalObject* GetCachedGlobalObject()
|
||||
|
|
|
@ -43,7 +43,7 @@ nsWrapperCache::ReleaseWrapper(void* aScriptObjectHolder)
|
|||
class DebugWrapperTraversalCallback : public nsCycleCollectionTraversalCallback
|
||||
{
|
||||
public:
|
||||
explicit DebugWrapperTraversalCallback(void* aWrapper)
|
||||
explicit DebugWrapperTraversalCallback(JSObject* aWrapper)
|
||||
: mFound(false)
|
||||
, mWrapper(aWrapper)
|
||||
{
|
||||
|
@ -60,12 +60,15 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD_(void) NoteJSChild(void* aChild)
|
||||
NS_IMETHOD_(void) NoteJSObject(JSObject* aChild)
|
||||
{
|
||||
if (aChild == mWrapper) {
|
||||
mFound = true;
|
||||
}
|
||||
}
|
||||
NS_IMETHOD_(void) NoteJSScript(JSScript* aChild)
|
||||
{
|
||||
}
|
||||
NS_IMETHOD_(void) NoteXPCOMChild(nsISupports* aChild)
|
||||
{
|
||||
}
|
||||
|
@ -81,15 +84,17 @@ public:
|
|||
bool mFound;
|
||||
|
||||
private:
|
||||
void* mWrapper;
|
||||
JSObject* mWrapper;
|
||||
};
|
||||
|
||||
static void
|
||||
DebugWrapperTraceCallback(void* aP, const char* aName, void* aClosure)
|
||||
DebugWrapperTraceCallback(JS::GCCellPtr aPtr, const char* aName, void* aClosure)
|
||||
{
|
||||
DebugWrapperTraversalCallback* callback =
|
||||
static_cast<DebugWrapperTraversalCallback*>(aClosure);
|
||||
callback->NoteJSChild(aP);
|
||||
if (aPtr.isObject()) {
|
||||
callback->NoteJSObject(aPtr.toObject());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -103,6 +108,10 @@ nsWrapperCache::CheckCCWrapperTraversal(void* aScriptObjectHolder,
|
|||
|
||||
DebugWrapperTraversalCallback callback(wrapper);
|
||||
|
||||
// The CC traversal machinery cannot trigger GC; however, the analysis cannot
|
||||
// see through the COM layer, so we use a suppression to help it.
|
||||
JS::AutoSuppressGCAnalysis suppress;
|
||||
|
||||
aTracer->Traverse(aScriptObjectHolder, callback);
|
||||
MOZ_ASSERT(callback.mFound,
|
||||
"Cycle collection participant didn't traverse to preserved "
|
||||
|
|
|
@ -24,11 +24,11 @@ inline bool
|
|||
nsWrapperCache::IsBlack()
|
||||
{
|
||||
JSObject* o = GetWrapperPreserveColor();
|
||||
return o && !JS::GCThingIsMarkedGray(o);
|
||||
return o && !JS::ObjectIsMarkedGray(o);
|
||||
}
|
||||
|
||||
static void
|
||||
SearchGray(void* aGCThing, const char* aName, void* aClosure)
|
||||
SearchGray(JS::GCCellPtr aGCThing, const char* aName, void* aClosure)
|
||||
{
|
||||
bool* hasGrayObjects = static_cast<bool*>(aClosure);
|
||||
if (!*hasGrayObjects && aGCThing && JS::GCThingIsMarkedGray(aGCThing)) {
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
bool HasGrayCallable() const
|
||||
{
|
||||
// Play it safe in case this gets called after unlink.
|
||||
return mCallback && xpc_IsGrayGCThing(mCallback);
|
||||
return mCallback && JS::ObjectIsMarkedGray(mCallback);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -7681,9 +7681,9 @@ class CGEnumerateHook(CGAbstractBindingMethod):
|
|||
if (rv.Failed()) {
|
||||
return ThrowMethodFailedWithDetails(cx, rv, "%s", "enumerate");
|
||||
}
|
||||
JS::Rooted<JS::Value> dummy(cx);
|
||||
bool dummy;
|
||||
for (uint32_t i = 0; i < names.Length(); ++i) {
|
||||
if (!JS_LookupUCProperty(cx, obj, names[i].get(), names[i].Length(), &dummy)) {
|
||||
if (!JS_HasUCProperty(cx, obj, names[i].get(), names[i].Length(), &dummy)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -297,16 +297,10 @@ BaseDOMProxyHandler::getOwnEnumerablePropertyKeys(JSContext* cx,
|
|||
}
|
||||
|
||||
bool
|
||||
BaseDOMProxyHandler::getEnumerablePropertyKeys(JSContext* cx,
|
||||
JS::Handle<JSObject*> proxy,
|
||||
AutoIdVector& props) const
|
||||
BaseDOMProxyHandler::enumerate(JSContext *cx, JS::Handle<JSObject*> proxy,
|
||||
JS::MutableHandle<JSObject*> objp) const
|
||||
{
|
||||
JS::Rooted<JSObject*> proto(cx);
|
||||
if (!JS_GetPrototype(cx, proxy, &proto)) {
|
||||
return false;
|
||||
}
|
||||
return getOwnEnumerablePropertyKeys(cx, proxy, props) &&
|
||||
(!proto || js::GetPropertyKeys(cx, proto, 0, &props));
|
||||
return BaseProxyHandler::enumerate(cx, proxy, objp);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -62,6 +62,8 @@ public:
|
|||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
|
||||
|
||||
virtual bool enumerate(JSContext *cx, JS::Handle<JSObject*> proxy,
|
||||
JS::MutableHandle<JSObject*> objp) const MOZ_OVERRIDE;
|
||||
|
||||
// We override getOwnEnumerablePropertyKeys() and implement it directly
|
||||
// instead of using the default implementation, which would call
|
||||
|
@ -69,8 +71,6 @@ public:
|
|||
// unnecessary work during enumeration.
|
||||
virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||
JS::AutoIdVector &props) const MOZ_OVERRIDE;
|
||||
bool getEnumerablePropertyKeys(JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||
JS::AutoIdVector& props) const MOZ_OVERRIDE;
|
||||
|
||||
bool watch(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
|
||||
JS::Handle<JSObject*> callable) const MOZ_OVERRIDE;
|
||||
|
|
|
@ -14,6 +14,10 @@ class WebGLSampler;
|
|||
class WebGLSync;
|
||||
class WebGLTransformFeedback;
|
||||
class WebGLVertexArrayObject;
|
||||
namespace dom {
|
||||
class OwningUnsignedLongOrUint32ArrayOrBoolean;
|
||||
class OwningWebGLBufferOrLongLong;
|
||||
}
|
||||
|
||||
class WebGL2Context
|
||||
: public WebGLContext
|
||||
|
@ -231,14 +235,23 @@ public:
|
|||
void BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer);
|
||||
void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer, GLintptr offset, GLsizeiptr size);
|
||||
*/
|
||||
void GetIndexedParameter(JSContext*, GLenum target, GLuint index, JS::MutableHandleValue retval);
|
||||
void GetUniformIndices(WebGLProgram* program, const dom::Sequence<nsString>& uniformNames, dom::Nullable< nsTArray<GLuint> >& retval);
|
||||
void GetActiveUniforms(WebGLProgram* program, const dom::Sequence<GLuint>& uniformIndices, GLenum pname,
|
||||
void GetIndexedParameter(GLenum target, GLuint index,
|
||||
dom::Nullable<dom::OwningWebGLBufferOrLongLong>& retval);
|
||||
void GetUniformIndices(WebGLProgram* program,
|
||||
const dom::Sequence<nsString>& uniformNames,
|
||||
dom::Nullable< nsTArray<GLuint> >& retval);
|
||||
void GetActiveUniforms(WebGLProgram* program,
|
||||
const dom::Sequence<GLuint>& uniformIndices, GLenum pname,
|
||||
dom::Nullable< nsTArray<GLint> >& retval);
|
||||
GLuint GetUniformBlockIndex(WebGLProgram* program, const nsAString& uniformBlockName);
|
||||
void GetActiveUniformBlockParameter(JSContext*, WebGLProgram* program, GLuint uniformBlockIndex, GLenum pname, JS::MutableHandleValue retval);
|
||||
void GetActiveUniformBlockName(WebGLProgram* program, GLuint uniformBlockIndex, dom::DOMString& retval);
|
||||
void UniformBlockBinding(WebGLProgram* program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
|
||||
void GetActiveUniformBlockParameter(JSContext*, WebGLProgram* program,
|
||||
GLuint uniformBlockIndex, GLenum pname,
|
||||
dom::Nullable<dom::OwningUnsignedLongOrUint32ArrayOrBoolean>& retval,
|
||||
ErrorResult& rv);
|
||||
void GetActiveUniformBlockName(WebGLProgram* program, GLuint uniformBlockIndex,
|
||||
nsAString& retval);
|
||||
void UniformBlockBinding(WebGLProgram* program, GLuint uniformBlockIndex,
|
||||
GLuint uniformBlockBinding);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
|
|
@ -5,8 +5,11 @@
|
|||
|
||||
#include "WebGL2Context.h"
|
||||
#include "GLContext.h"
|
||||
#include "WebGLContext.h"
|
||||
#include "WebGLProgram.h"
|
||||
#include "WebGLVertexArray.h"
|
||||
#include "WebGLVertexAttribData.h"
|
||||
#include "mozilla/dom/WebGL2RenderingContextBinding.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -30,38 +33,39 @@ GLfloat PuntToFloat(GLuint u)
|
|||
}
|
||||
|
||||
bool
|
||||
WebGL2Context::ValidateAttribPointerType(bool integerMode, GLenum type, GLsizei* alignment, const char* info)
|
||||
WebGL2Context::ValidateAttribPointerType(bool integerMode, GLenum type,
|
||||
GLsizei* out_alignment, const char* info)
|
||||
{
|
||||
MOZ_ASSERT(alignment);
|
||||
MOZ_ASSERT(out_alignment);
|
||||
|
||||
switch (type) {
|
||||
case LOCAL_GL_BYTE:
|
||||
case LOCAL_GL_UNSIGNED_BYTE:
|
||||
*alignment = 1;
|
||||
*out_alignment = 1;
|
||||
return true;
|
||||
|
||||
case LOCAL_GL_SHORT:
|
||||
case LOCAL_GL_UNSIGNED_SHORT:
|
||||
*alignment = 2;
|
||||
*out_alignment = 2;
|
||||
return true;
|
||||
|
||||
case LOCAL_GL_INT:
|
||||
case LOCAL_GL_UNSIGNED_INT:
|
||||
*alignment = 4;
|
||||
*out_alignment = 4;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!integerMode) {
|
||||
switch (type) {
|
||||
case LOCAL_GL_HALF_FLOAT:
|
||||
*alignment = 2;
|
||||
*out_alignment = 2;
|
||||
return true;
|
||||
|
||||
case LOCAL_GL_FLOAT:
|
||||
case LOCAL_GL_FIXED:
|
||||
case LOCAL_GL_INT_2_10_10_10_REV:
|
||||
case LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV:
|
||||
*alignment = 4;
|
||||
*out_alignment = 4;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -74,7 +78,8 @@ WebGL2Context::ValidateAttribPointerType(bool integerMode, GLenum type, GLsizei*
|
|||
// Uniforms and attributes
|
||||
|
||||
void
|
||||
WebGL2Context::VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset)
|
||||
WebGL2Context::VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride,
|
||||
GLintptr offset)
|
||||
{
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
@ -82,8 +87,11 @@ WebGL2Context::VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsiz
|
|||
if (!ValidateAttribIndex(index, "vertexAttribIPointer"))
|
||||
return;
|
||||
|
||||
if (!ValidateAttribPointer(true, index, size, type, LOCAL_GL_FALSE, stride, offset, "vertexAttribIPointer"))
|
||||
if (!ValidateAttribPointer(true, index, size, type, LOCAL_GL_FALSE, stride, offset,
|
||||
"vertexAttribIPointer"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mBoundVertexArray);
|
||||
mBoundVertexArray->EnsureAttrib(index);
|
||||
|
@ -123,103 +131,120 @@ WebGL2Context::Uniform3ui(WebGLUniformLocation* location, GLuint v0, GLuint v1,
|
|||
}
|
||||
|
||||
void
|
||||
WebGL2Context::Uniform4ui(WebGLUniformLocation* location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
|
||||
WebGL2Context::Uniform4ui(WebGLUniformLocation* location, GLuint v0, GLuint v1,
|
||||
GLuint v2, GLuint v3)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::Uniform1uiv(WebGLUniformLocation* location, const dom::Sequence<GLuint>& value)
|
||||
WebGL2Context::Uniform1uiv(WebGLUniformLocation* location,
|
||||
const dom::Sequence<GLuint>& value)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::Uniform2uiv(WebGLUniformLocation* location, const dom::Sequence<GLuint>& value)
|
||||
WebGL2Context::Uniform2uiv(WebGLUniformLocation* location,
|
||||
const dom::Sequence<GLuint>& value)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::Uniform3uiv(WebGLUniformLocation* location, const dom::Sequence<GLuint>& value)
|
||||
WebGL2Context::Uniform3uiv(WebGLUniformLocation* location,
|
||||
const dom::Sequence<GLuint>& value)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::Uniform4uiv(WebGLUniformLocation* location, const dom::Sequence<GLuint>& value)
|
||||
WebGL2Context::Uniform4uiv(WebGLUniformLocation* location,
|
||||
const dom::Sequence<GLuint>& value)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::UniformMatrix2x3fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value)
|
||||
WebGL2Context::UniformMatrix2x3fv(WebGLUniformLocation* location, bool transpose,
|
||||
const dom::Float32Array& value)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::UniformMatrix2x3fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value)
|
||||
WebGL2Context::UniformMatrix2x3fv(WebGLUniformLocation* location, bool transpose,
|
||||
const dom::Sequence<GLfloat>& value)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::UniformMatrix3x2fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value)
|
||||
WebGL2Context::UniformMatrix3x2fv(WebGLUniformLocation* location, bool transpose,
|
||||
const dom::Float32Array& value)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::UniformMatrix3x2fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value)
|
||||
WebGL2Context::UniformMatrix3x2fv(WebGLUniformLocation* location, bool transpose,
|
||||
const dom::Sequence<GLfloat>& value)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::UniformMatrix2x4fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value)
|
||||
WebGL2Context::UniformMatrix2x4fv(WebGLUniformLocation* location, bool transpose,
|
||||
const dom::Float32Array& value)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::UniformMatrix2x4fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value)
|
||||
WebGL2Context::UniformMatrix2x4fv(WebGLUniformLocation* location, bool transpose,
|
||||
const dom::Sequence<GLfloat>& value)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::UniformMatrix4x2fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value)
|
||||
WebGL2Context::UniformMatrix4x2fv(WebGLUniformLocation* location, bool transpose,
|
||||
const dom::Float32Array& value)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::UniformMatrix4x2fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value)
|
||||
WebGL2Context::UniformMatrix4x2fv(WebGLUniformLocation* location, bool transpose,
|
||||
const dom::Sequence<GLfloat>& value)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::UniformMatrix3x4fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value)
|
||||
WebGL2Context::UniformMatrix3x4fv(WebGLUniformLocation* location, bool transpose,
|
||||
const dom::Float32Array& value)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::UniformMatrix3x4fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value)
|
||||
WebGL2Context::UniformMatrix3x4fv(WebGLUniformLocation* location, bool transpose,
|
||||
const dom::Sequence<GLfloat>& value)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::UniformMatrix4x3fv(WebGLUniformLocation* location, bool transpose, const dom::Float32Array& value)
|
||||
WebGL2Context::UniformMatrix4x3fv(WebGLUniformLocation* location, bool transpose,
|
||||
const dom::Float32Array& value)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::UniformMatrix4x3fv(WebGLUniformLocation* location, bool transpose, const dom::Sequence<GLfloat>& value)
|
||||
WebGL2Context::UniformMatrix4x3fv(WebGLUniformLocation* location, bool transpose,
|
||||
const dom::Sequence<GLfloat>& value)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
}
|
||||
|
@ -309,13 +334,51 @@ WebGL2Context::VertexAttribI4uiv(GLuint index, const dom::Sequence<GLuint>& v)
|
|||
// TODO(djg): Implemented in WebGLContext
|
||||
/*
|
||||
void BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer);
|
||||
void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer, GLintptr offset, GLsizeiptr size);
|
||||
void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer,
|
||||
GLintptr offset, GLsizeiptr size);
|
||||
*/
|
||||
|
||||
/* This doesn't belong here. It's part of state querying */
|
||||
void
|
||||
WebGL2Context::GetIndexedParameter(JSContext*, GLenum target, GLuint index, JS::MutableHandleValue retval)
|
||||
WebGL2Context::GetIndexedParameter(GLenum target, GLuint index,
|
||||
dom::Nullable<dom::OwningWebGLBufferOrLongLong>& retval)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
retval.SetNull();
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
GLint64 data = 0;
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
switch (target) {
|
||||
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
|
||||
if (index >= mGLMaxTransformFeedbackSeparateAttribs)
|
||||
return ErrorInvalidValue("getIndexedParameter: index should be less than "
|
||||
"MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS");
|
||||
|
||||
retval.SetValue().SetAsWebGLBuffer() =
|
||||
mBoundTransformFeedbackBuffers[index].get();
|
||||
return;
|
||||
|
||||
case LOCAL_GL_UNIFORM_BUFFER_BINDING:
|
||||
if (index >= mGLMaxUniformBufferBindings)
|
||||
return ErrorInvalidValue("getIndexedParameter: index should be than "
|
||||
"MAX_UNIFORM_BUFFER_BINDINGS");
|
||||
|
||||
retval.SetValue().SetAsWebGLBuffer() = mBoundUniformBuffers[index].get();
|
||||
return;
|
||||
|
||||
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_START:
|
||||
case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
|
||||
case LOCAL_GL_UNIFORM_BUFFER_START:
|
||||
case LOCAL_GL_UNIFORM_BUFFER_SIZE:
|
||||
gl->fGetInteger64i_v(target, index, &data);
|
||||
retval.SetValue().SetAsLongLong() = data;
|
||||
return;
|
||||
}
|
||||
|
||||
ErrorInvalidEnumInfo("getIndexedParameter: target", target);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -323,7 +386,32 @@ WebGL2Context::GetUniformIndices(WebGLProgram* program,
|
|||
const dom::Sequence<nsString>& uniformNames,
|
||||
dom::Nullable< nsTArray<GLuint> >& retval)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
retval.SetNull();
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
if (!ValidateObject("getUniformIndices: program", program))
|
||||
return;
|
||||
|
||||
if (!uniformNames.Length())
|
||||
return;
|
||||
|
||||
GLuint progname = program->GLName();
|
||||
size_t count = uniformNames.Length();
|
||||
nsTArray<GLuint>& arr = retval.SetValue();
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
for (size_t n = 0; n < count; n++) {
|
||||
NS_LossyConvertUTF16toASCII name(uniformNames[n]);
|
||||
// const GLchar* glname = name.get();
|
||||
const GLchar* glname = nullptr;
|
||||
name.BeginReading(glname);
|
||||
|
||||
GLuint index = 0;
|
||||
gl->fGetUniformIndices(progname, 1, &glname, &index);
|
||||
arr.AppendElement(index);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -332,32 +420,162 @@ WebGL2Context::GetActiveUniforms(WebGLProgram* program,
|
|||
GLenum pname,
|
||||
dom::Nullable< nsTArray<GLint> >& retval)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
retval.SetNull();
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
if (!ValidateObject("getActiveUniforms: program", program))
|
||||
return;
|
||||
|
||||
size_t count = uniformIndices.Length();
|
||||
if (!count)
|
||||
return;
|
||||
|
||||
GLuint progname = program->GLName();
|
||||
nsTArray<GLint>& arr = retval.SetValue();
|
||||
arr.SetLength(count);
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fGetActiveUniformsiv(progname, count, uniformIndices.Elements(), pname,
|
||||
arr.Elements());
|
||||
}
|
||||
|
||||
GLuint
|
||||
WebGL2Context::GetUniformBlockIndex(WebGLProgram* program, const nsAString& uniformBlockName)
|
||||
WebGL2Context::GetUniformBlockIndex(WebGLProgram* program,
|
||||
const nsAString& uniformBlockName)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
return 0;
|
||||
if (IsContextLost())
|
||||
return 0;
|
||||
|
||||
if (!ValidateObject("getUniformBlockIndex: program", program))
|
||||
return 0;
|
||||
|
||||
if (!ValidateGLSLVariableName(uniformBlockName, "getUniformBlockIndex"))
|
||||
return 0;
|
||||
|
||||
NS_LossyConvertUTF16toASCII cname(uniformBlockName);
|
||||
nsCString mappedName;
|
||||
program->MapIdentifier(cname, &mappedName);
|
||||
|
||||
GLuint progname = program->GLName();
|
||||
|
||||
MakeContextCurrent();
|
||||
return gl->fGetUniformBlockIndex(progname, mappedName.get());
|
||||
}
|
||||
|
||||
static bool
|
||||
GetUniformBlockActiveUniforms(gl::GLContext* gl, JSContext* cx,
|
||||
WebGL2Context* owner, GLuint progname,
|
||||
GLuint uniformBlockIndex,
|
||||
JS::MutableHandleObject out_array)
|
||||
{
|
||||
GLint length = 0;
|
||||
gl->fGetActiveUniformBlockiv(progname, uniformBlockIndex,
|
||||
LOCAL_GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &length);
|
||||
JS::RootedObject obj(cx, Uint32Array::Create(cx, owner, length, nullptr));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
Uint32Array result;
|
||||
DebugOnly<bool> inited = result.Init(obj);
|
||||
MOZ_ASSERT(inited);
|
||||
result.ComputeLengthAndData();
|
||||
gl->fGetActiveUniformBlockiv(progname, uniformBlockIndex,
|
||||
LOCAL_GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES,
|
||||
(GLint*) result.Data());
|
||||
|
||||
out_array.set(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::GetActiveUniformBlockParameter(JSContext*, WebGLProgram* program,
|
||||
WebGL2Context::GetActiveUniformBlockParameter(JSContext* cx, WebGLProgram* program,
|
||||
GLuint uniformBlockIndex, GLenum pname,
|
||||
JS::MutableHandleValue retval)
|
||||
Nullable<dom::OwningUnsignedLongOrUint32ArrayOrBoolean>& retval,
|
||||
ErrorResult& rv)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
retval.SetNull();
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
if (!ValidateObject("getActiveUniformBlockParameter: program", program))
|
||||
return;
|
||||
|
||||
GLuint progname = program->GLName();
|
||||
GLint param = 0;
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
switch(pname) {
|
||||
case LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
|
||||
case LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
|
||||
gl->fGetActiveUniformBlockiv(progname, uniformBlockIndex, pname, ¶m);
|
||||
retval.SetValue().SetAsBoolean() = (param != 0);
|
||||
return;
|
||||
|
||||
case LOCAL_GL_UNIFORM_BLOCK_BINDING:
|
||||
case LOCAL_GL_UNIFORM_BLOCK_DATA_SIZE:
|
||||
case LOCAL_GL_UNIFORM_BLOCK_NAME_LENGTH:
|
||||
case LOCAL_GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
|
||||
gl->fGetActiveUniformBlockiv(progname, uniformBlockIndex, pname, ¶m);
|
||||
retval.SetValue().SetAsUnsignedLong() = param;
|
||||
return;
|
||||
|
||||
case LOCAL_GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
|
||||
JS::RootedObject array(cx);
|
||||
if (!GetUniformBlockActiveUniforms(gl, cx, this, progname, uniformBlockIndex,
|
||||
&array))
|
||||
{
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
return;
|
||||
}
|
||||
|
||||
DebugOnly<bool> inited = retval.SetValue().SetAsUint32Array().Init(array);
|
||||
MOZ_ASSERT(inited);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ErrorInvalidEnumInfo("getActiveUniformBlockParameter: parameter", pname);
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::GetActiveUniformBlockName(WebGLProgram* program, GLuint uniformBlockIndex, dom::DOMString& retval)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
}
|
||||
#define WEBGL_MAX_UNIFORM_BLOCK_NAME_LENGTH 256
|
||||
|
||||
void
|
||||
WebGL2Context::UniformBlockBinding(WebGLProgram* program, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
|
||||
WebGL2Context::GetActiveUniformBlockName(WebGLProgram* program, GLuint uniformBlockIndex,
|
||||
nsAString& retval)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
if (!ValidateObject("getActiveUniformBlockName: program", program))
|
||||
return;
|
||||
|
||||
GLuint progname = program->GLName();
|
||||
GLchar nameBuffer[WEBGL_MAX_UNIFORM_BLOCK_NAME_LENGTH];
|
||||
GLsizei length = 0;
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fGetActiveUniformBlockName(progname, uniformBlockIndex,
|
||||
WEBGL_MAX_UNIFORM_BLOCK_NAME_LENGTH, &length,
|
||||
nameBuffer);
|
||||
retval.Assign(NS_ConvertASCIItoUTF16(nsDependentCString(nameBuffer)));
|
||||
}
|
||||
|
||||
#undef WEBGL_MAX_UNIFORM_BLOCK_NAME_LENGTH
|
||||
|
||||
void
|
||||
WebGL2Context::UniformBlockBinding(WebGLProgram* program, GLuint uniformBlockIndex,
|
||||
GLuint uniformBlockBinding)
|
||||
{
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
if (!ValidateObject("uniformBlockBinding: program", program))
|
||||
return;
|
||||
|
||||
GLuint progname = program->GLName();
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fUniformBlockBinding(progname, uniformBlockIndex, uniformBlockBinding);
|
||||
}
|
||||
|
|
|
@ -11920,7 +11920,8 @@ OpenDatabaseOp::SendResults()
|
|||
nsRefPtr<OpenDatabaseOp> kungFuDeathGrip;
|
||||
|
||||
DatabaseActorInfo* info;
|
||||
if (gLiveDatabaseHashtable->Get(mDatabaseId, &info) &&
|
||||
if (gLiveDatabaseHashtable &&
|
||||
gLiveDatabaseHashtable->Get(mDatabaseId, &info) &&
|
||||
info->mWaitingFactoryOp) {
|
||||
MOZ_ASSERT(info->mWaitingFactoryOp == this);
|
||||
kungFuDeathGrip =
|
||||
|
|
|
@ -1001,7 +1001,7 @@ IDBObjectStore::DeserializeValue(JSContext* aCx,
|
|||
|
||||
JSAutoRequest ar(aCx);
|
||||
|
||||
static JSStructuredCloneCallbacks callbacks = {
|
||||
static const JSStructuredCloneCallbacks callbacks = {
|
||||
CommonStructuredCloneReadCallback<ValueDeserializationHelper>,
|
||||
nullptr,
|
||||
nullptr,
|
||||
|
@ -1042,7 +1042,7 @@ IDBObjectStore::DeserializeIndexValue(JSContext* aCx,
|
|||
|
||||
JSAutoRequest ar(aCx);
|
||||
|
||||
static JSStructuredCloneCallbacks callbacks = {
|
||||
static const JSStructuredCloneCallbacks callbacks = {
|
||||
CommonStructuredCloneReadCallback<IndexDeserializationHelper>,
|
||||
nullptr,
|
||||
nullptr
|
||||
|
|
|
@ -101,7 +101,7 @@ Write(JSContext* aCx, JSStructuredCloneWriter* aWriter,
|
|||
return NS_DOMWriteStructuredClone(aCx, aWriter, aObj, nullptr);
|
||||
}
|
||||
|
||||
JSStructuredCloneCallbacks gCallbacks = {
|
||||
const JSStructuredCloneCallbacks gCallbacks = {
|
||||
Read,
|
||||
Write,
|
||||
Error,
|
||||
|
|
|
@ -27,6 +27,11 @@ const BrowserElementIsPreloaded = true;
|
|||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/SettingsDB.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
try {
|
||||
if (Services.prefs.getBoolPref("dom.apps.customization.enabled")) {
|
||||
Cu.import("resource://gre/modules/UserCustomizations.jsm");
|
||||
}
|
||||
} catch(e) {}
|
||||
|
||||
Cc["@mozilla.org/appshell/appShellService;1"].getService(Ci["nsIAppShellService"]);
|
||||
Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci["nsIWindowMediator"]);
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef MediaDataDecodedListener_h_
|
||||
#define MediaDataDecodedListener_h_
|
||||
|
||||
#include "mozilla/Monitor.h"
|
||||
#include "MediaDecoderReader.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class MediaDecoderStateMachine;
|
||||
class MediaData;
|
||||
|
||||
// A RequestSampleCallback implementation that forwards samples onto the
|
||||
// MediaDecoderStateMachine via tasks that run on the supplied task queue.
|
||||
template<class Target>
|
||||
class MediaDataDecodedListener : public RequestSampleCallback {
|
||||
public:
|
||||
MediaDataDecodedListener(Target* aTarget,
|
||||
MediaTaskQueue* aTaskQueue)
|
||||
: mMonitor("MediaDataDecodedListener")
|
||||
, mTaskQueue(aTaskQueue)
|
||||
, mTarget(aTarget)
|
||||
{
|
||||
MOZ_ASSERT(aTarget);
|
||||
MOZ_ASSERT(aTaskQueue);
|
||||
}
|
||||
|
||||
void BreakCycles() {
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
mTarget = nullptr;
|
||||
mTaskQueue = nullptr;
|
||||
}
|
||||
|
||||
virtual void OnSeekCompleted(nsresult aResult) MOZ_OVERRIDE {
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
if (!mTarget || !mTaskQueue) {
|
||||
// We've been shutdown, abort.
|
||||
return;
|
||||
}
|
||||
RefPtr<nsIRunnable> task(NS_NewRunnableMethodWithArg<nsresult>(mTarget,
|
||||
&Target::OnSeekCompleted,
|
||||
aResult));
|
||||
if (NS_FAILED(mTaskQueue->Dispatch(task))) {
|
||||
NS_WARNING("Failed to dispatch OnSeekCompleted task");
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Monitor mMonitor;
|
||||
RefPtr<MediaTaskQueue> mTaskQueue;
|
||||
RefPtr<Target> mTarget;
|
||||
};
|
||||
|
||||
} /* namespace mozilla */
|
||||
|
||||
#endif // MediaDataDecodedListener_h_
|
|
@ -263,12 +263,6 @@ MediaDecoderReader::RequestAudioData()
|
|||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderReader::SetCallback(RequestSampleCallback* aCallback)
|
||||
{
|
||||
mSampleDecodedCallback = aCallback;
|
||||
}
|
||||
|
||||
MediaTaskQueue*
|
||||
MediaDecoderReader::EnsureTaskQueue()
|
||||
{
|
||||
|
@ -286,10 +280,6 @@ MediaDecoderReader::EnsureTaskQueue()
|
|||
void
|
||||
MediaDecoderReader::BreakCycles()
|
||||
{
|
||||
if (mSampleDecodedCallback) {
|
||||
mSampleDecodedCallback->BreakCycles();
|
||||
mSampleDecodedCallback = nullptr;
|
||||
}
|
||||
mTaskQueue = nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ namespace dom {
|
|||
class TimeRanges;
|
||||
}
|
||||
|
||||
class RequestSampleCallback;
|
||||
class MediaDecoderReader;
|
||||
class SharedDecoderManager;
|
||||
|
||||
|
@ -40,6 +39,7 @@ public:
|
|||
|
||||
typedef MediaPromise<nsRefPtr<AudioData>, NotDecodedReason> AudioDataPromise;
|
||||
typedef MediaPromise<nsRefPtr<VideoData>, NotDecodedReason> VideoDataPromise;
|
||||
typedef MediaPromise<bool, nsresult> SeekPromise;
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDecoderReader)
|
||||
|
||||
|
@ -71,7 +71,6 @@ public:
|
|||
// thread.
|
||||
virtual nsRefPtr<ShutdownPromise> Shutdown();
|
||||
|
||||
virtual void SetCallback(RequestSampleCallback* aDecodedSampleCallback);
|
||||
MediaTaskQueue* EnsureTaskQueue();
|
||||
|
||||
virtual bool OnDecodeThread()
|
||||
|
@ -131,15 +130,12 @@ public:
|
|||
// ReadUpdatedMetadata will always be called once ReadMetadata has succeeded.
|
||||
virtual void ReadUpdatedMetadata(MediaInfo* aInfo) { };
|
||||
|
||||
// Requests the Reader to seek and call OnSeekCompleted on the callback
|
||||
// once completed.
|
||||
// Moves the decode head to aTime microseconds. aStartTime and aEndTime
|
||||
// denote the start and end times of the media in usecs, and aCurrentTime
|
||||
// is the current playback position in microseconds.
|
||||
virtual void Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime) = 0;
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime, int64_t aStartTime,
|
||||
int64_t aEndTime, int64_t aCurrentTime) = 0;
|
||||
|
||||
// Called to move the reader into idle state. When the reader is
|
||||
// created it is assumed to be active (i.e. not idle). When the media
|
||||
|
@ -244,11 +240,6 @@ protected:
|
|||
return false;
|
||||
}
|
||||
|
||||
RequestSampleCallback* GetCallback() {
|
||||
MOZ_ASSERT(mSampleDecodedCallback);
|
||||
return mSampleDecodedCallback;
|
||||
}
|
||||
|
||||
// Queue of audio frames. This queue is threadsafe, and is accessed from
|
||||
// the audio, decoder, state machine, and main threads.
|
||||
MediaQueue<AudioData> mAudioQueue;
|
||||
|
@ -287,8 +278,6 @@ protected:
|
|||
bool mHitAudioDecodeError;
|
||||
|
||||
private:
|
||||
nsRefPtr<RequestSampleCallback> mSampleDecodedCallback;
|
||||
|
||||
// Promises used only for the base-class (sync->async adapter) implementation
|
||||
// of Request{Audio,Video}Data.
|
||||
MediaPromiseHolder<AudioDataPromise> mBaseAudioPromise;
|
||||
|
@ -304,23 +293,6 @@ private:
|
|||
bool mShutdown;
|
||||
};
|
||||
|
||||
// Interface that callers to MediaDecoderReader::Request{Audio,Video}Data()
|
||||
// must implement to receive the requested samples asynchronously.
|
||||
// This object is refcounted, and cycles must be broken by calling
|
||||
// BreakCycles() during shutdown.
|
||||
class RequestSampleCallback {
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RequestSampleCallback)
|
||||
|
||||
virtual void OnSeekCompleted(nsresult aResult) = 0;
|
||||
|
||||
// Called during shutdown to break any reference cycles.
|
||||
virtual void BreakCycles() = 0;
|
||||
|
||||
protected:
|
||||
virtual ~RequestSampleCallback() {}
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1098,12 +1098,6 @@ nsresult MediaDecoderStateMachine::Init(MediaDecoderStateMachine* aCloneDonor)
|
|||
nsresult rv = mScheduler->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Note: This creates a cycle, broken in shutdown.
|
||||
mMediaDecodedListener =
|
||||
new MediaDataDecodedListener<MediaDecoderStateMachine>(this,
|
||||
DecodeTaskQueue());
|
||||
mReader->SetCallback(mMediaDecodedListener);
|
||||
|
||||
rv = mReader->Init(cloneReader);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -2306,10 +2300,10 @@ void MediaDecoderStateMachine::DecodeSeek()
|
|||
// the reader, since it could do I/O or deadlock some other way.
|
||||
res = mReader->ResetDecode();
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
mReader->Seek(seekTime,
|
||||
mStartTime,
|
||||
mEndTime,
|
||||
mCurrentTimeBeforeSeek);
|
||||
mReader->Seek(seekTime, mStartTime, mEndTime, mCurrentTimeBeforeSeek)
|
||||
->Then(DecodeTaskQueue(), __func__, this,
|
||||
&MediaDecoderStateMachine::OnSeekCompleted,
|
||||
&MediaDecoderStateMachine::OnSeekFailed);
|
||||
}
|
||||
}
|
||||
if (NS_FAILED(res)) {
|
||||
|
@ -2321,14 +2315,10 @@ void MediaDecoderStateMachine::DecodeSeek()
|
|||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::OnSeekCompleted(nsresult aResult)
|
||||
MediaDecoderStateMachine::OnSeekCompleted()
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
mWaitingForDecoderSeek = false;
|
||||
if (NS_FAILED(aResult)) {
|
||||
DecodeError();
|
||||
return;
|
||||
}
|
||||
|
||||
// We must decode the first samples of active streams, so we can determine
|
||||
// the new stream time. So dispatch tasks to do that.
|
||||
|
@ -2336,6 +2326,19 @@ MediaDecoderStateMachine::OnSeekCompleted(nsresult aResult)
|
|||
DispatchDecodeTasksIfNeeded();
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::OnSeekFailed(nsresult aResult)
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
mWaitingForDecoderSeek = false;
|
||||
// Sometimes we reject the promise for non-failure reasons, like
|
||||
// when we request a second seek before the previous one has
|
||||
// completed.
|
||||
if (NS_FAILED(aResult)) {
|
||||
DecodeError();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::SeekCompleted()
|
||||
{
|
||||
|
|
|
@ -89,7 +89,6 @@ hardware (via AudioStream).
|
|||
#include "MediaDecoderReader.h"
|
||||
#include "MediaDecoderOwner.h"
|
||||
#include "MediaMetadataManager.h"
|
||||
#include "MediaDataDecodedListener.h"
|
||||
|
||||
class nsITimer;
|
||||
|
||||
|
@ -387,7 +386,8 @@ public:
|
|||
OnNotDecoded(MediaData::VIDEO_DATA, aReason);
|
||||
}
|
||||
|
||||
void OnSeekCompleted(nsresult aResult);
|
||||
void OnSeekCompleted();
|
||||
void OnSeekFailed(nsresult aResult);
|
||||
|
||||
private:
|
||||
void AcquireMonitorAndInvokeDecodeError();
|
||||
|
@ -444,8 +444,6 @@ protected:
|
|||
|
||||
nsresult FinishDecodeFirstFrame();
|
||||
|
||||
RefPtr<MediaDataDecodedListener<MediaDecoderStateMachine>> mMediaDecodedListener;
|
||||
|
||||
nsAutoPtr<MetadataTags> mMetadataTags;
|
||||
|
||||
// True if our buffers of decoded audio are not full, and we should
|
||||
|
|
|
@ -65,6 +65,24 @@ public:
|
|||
PROMISE_LOG("%s creating MediaPromise (%p)", mCreationSite, this);
|
||||
}
|
||||
|
||||
static nsRefPtr<MediaPromise<ResolveValueT, RejectValueT>>
|
||||
CreateAndResolve(ResolveValueType aResolveValue, const char* aResolveSite)
|
||||
{
|
||||
nsRefPtr<MediaPromise<ResolveValueT, RejectValueT>> p =
|
||||
new MediaPromise<ResolveValueT, RejectValueT>(aResolveSite);
|
||||
p->Resolve(aResolveValue, aResolveSite);
|
||||
return p;
|
||||
}
|
||||
|
||||
static nsRefPtr<MediaPromise<ResolveValueT, RejectValueT>>
|
||||
CreateAndReject(RejectValueType aRejectValue, const char* aRejectSite)
|
||||
{
|
||||
nsRefPtr<MediaPromise<ResolveValueT, RejectValueT>> p =
|
||||
new MediaPromise<ResolveValueT, RejectValueT>(aRejectSite);
|
||||
p->Reject(aRejectValue, aRejectSite);
|
||||
return p;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/*
|
||||
|
|
|
@ -2242,7 +2242,6 @@ MediaStream::SetTrackEnabled(TrackID aTrackID, bool aEnabled)
|
|||
void
|
||||
MediaStream::ApplyTrackDisabling(TrackID aTrackID, MediaSegment* aSegment, MediaSegment* aRawSegment)
|
||||
{
|
||||
// mMutex must be owned here if this is a SourceMediaStream
|
||||
if (!mDisabledTrackIDs.Contains(aTrackID)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -458,7 +458,7 @@ public:
|
|||
void AddListenerImpl(already_AddRefed<MediaStreamListener> aListener);
|
||||
void RemoveListenerImpl(MediaStreamListener* aListener);
|
||||
void RemoveAllListenersImpl();
|
||||
void SetTrackEnabledImpl(TrackID aTrackID, bool aEnabled);
|
||||
virtual void SetTrackEnabledImpl(TrackID aTrackID, bool aEnabled);
|
||||
/**
|
||||
* Returns true when this stream requires the contents of its inputs even if
|
||||
* its own outputs are not being consumed. This is used to signal inputs to
|
||||
|
@ -536,7 +536,7 @@ public:
|
|||
|
||||
StreamBuffer::Track* EnsureTrack(TrackID aTrack);
|
||||
|
||||
void ApplyTrackDisabling(TrackID aTrackID, MediaSegment* aSegment, MediaSegment* aRawSegment = nullptr);
|
||||
virtual void ApplyTrackDisabling(TrackID aTrackID, MediaSegment* aSegment, MediaSegment* aRawSegment = nullptr);
|
||||
|
||||
DOMMediaStream* GetWrapper()
|
||||
{
|
||||
|
@ -776,17 +776,26 @@ public:
|
|||
*/
|
||||
void FinishWithLockHeld();
|
||||
void Finish()
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
FinishWithLockHeld();
|
||||
}
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
FinishWithLockHeld();
|
||||
}
|
||||
|
||||
// Overriding allows us to hold the mMutex lock while changing the track enable status
|
||||
void SetTrackEnabledImpl(TrackID aTrackID, bool aEnabled) {
|
||||
virtual void
|
||||
SetTrackEnabledImpl(TrackID aTrackID, bool aEnabled) MOZ_OVERRIDE {
|
||||
MutexAutoLock lock(mMutex);
|
||||
MediaStream::SetTrackEnabledImpl(aTrackID, aEnabled);
|
||||
}
|
||||
|
||||
// Overriding allows us to ensure mMutex is locked while changing the track enable status
|
||||
virtual void
|
||||
ApplyTrackDisabling(TrackID aTrackID, MediaSegment* aSegment,
|
||||
MediaSegment* aRawSegment = nullptr) MOZ_OVERRIDE {
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
MediaStream::ApplyTrackDisabling(aTrackID, aSegment, aRawSegment);
|
||||
}
|
||||
|
||||
/**
|
||||
* End all tracks and Finish() this stream. Used to voluntarily revoke access
|
||||
* to a LocalMediaStream.
|
||||
|
|
|
@ -319,7 +319,8 @@ bool AndroidMediaReader::DecodeAudioData()
|
|||
source.mAudioChannels));
|
||||
}
|
||||
|
||||
void AndroidMediaReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime)
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
AndroidMediaReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime)
|
||||
{
|
||||
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
|
||||
|
||||
|
@ -339,7 +340,7 @@ void AndroidMediaReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndT
|
|||
mAudioSeekTimeUs = mVideoSeekTimeUs = aTarget;
|
||||
}
|
||||
|
||||
GetCallback()->OnSeekCompleted(NS_OK);
|
||||
return SeekPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
|
||||
AndroidMediaReader::ImageBufferCallback::ImageBufferCallback(mozilla::layers::ImageContainer *aImageContainer) :
|
||||
|
|
|
@ -69,7 +69,8 @@ public:
|
|||
|
||||
virtual nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags);
|
||||
virtual void Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime);
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsRefPtr<ShutdownPromise> Shutdown() MOZ_OVERRIDE;
|
||||
|
||||
|
|
|
@ -492,7 +492,7 @@ AppleMP3Reader::SetupDecoder()
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
AppleMP3Reader::Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
|
@ -518,8 +518,7 @@ AppleMP3Reader::Seek(int64_t aTime,
|
|||
|
||||
if (rv) {
|
||||
LOGE("Couldn't seek demuxer. Error code %x\n", rv);
|
||||
GetCallback()->OnSeekCompleted(NS_ERROR_FAILURE);
|
||||
return;
|
||||
return SeekPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
|
||||
}
|
||||
|
||||
LOGD("computed byte offset = %lld; estimated = %s\n",
|
||||
|
@ -530,7 +529,7 @@ AppleMP3Reader::Seek(int64_t aTime,
|
|||
|
||||
ResetDecode();
|
||||
|
||||
GetCallback()->OnSeekCompleted(NS_OK);
|
||||
return SeekPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -33,10 +33,11 @@ public:
|
|||
virtual nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags) MOZ_OVERRIDE;
|
||||
|
||||
virtual void Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
void AudioSampleCallback(UInt32 aNumBytes,
|
||||
UInt32 aNumPackets,
|
||||
|
|
|
@ -367,14 +367,18 @@ DirectShowReader::HasVideo()
|
|||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
DirectShowReader::Seek(int64_t aTargetUs,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime)
|
||||
{
|
||||
nsresult res = SeekInternal(aTargetUs);
|
||||
GetCallback()->OnSeekCompleted(res);
|
||||
if (NS_FAILED(res)) {
|
||||
return SeekPromise::CreateAndReject(res, __func__);
|
||||
} else {
|
||||
return SeekPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -60,10 +60,11 @@ public:
|
|||
nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags) MOZ_OVERRIDE;
|
||||
|
||||
void Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
void NotifyDataArrived(const char* aBuffer,
|
||||
uint32_t aLength,
|
||||
|
|
|
@ -470,19 +470,16 @@ MP4Reader::RequestVideoData(bool aSkipToNextKeyframe,
|
|||
MOZ_ASSERT(GetTaskQueue()->IsCurrentThreadIn());
|
||||
VLOG("RequestVideoData skip=%d time=%lld", aSkipToNextKeyframe, aTimeThreshold);
|
||||
|
||||
// Record number of frames decoded and parsed. Automatically update the
|
||||
// stats counters using the AutoNotifyDecoded stack-based class.
|
||||
uint32_t parsed = 0, decoded = 0;
|
||||
AbstractMediaDecoder::AutoNotifyDecoded autoNotify(mDecoder, parsed, decoded);
|
||||
|
||||
MOZ_ASSERT(HasVideo() && mPlatform && mVideo.mDecoder);
|
||||
|
||||
bool eos = false;
|
||||
if (aSkipToNextKeyframe) {
|
||||
uint32_t parsed = 0;
|
||||
eos = !SkipVideoDemuxToNextKeyFrame(aTimeThreshold, parsed);
|
||||
if (!eos && NS_FAILED(mVideo.mDecoder->Flush())) {
|
||||
NS_WARNING("Failed to skip/flush video when skipping-to-next-keyframe.");
|
||||
}
|
||||
mDecoder->NotifyDecodedFrames(parsed, 0);
|
||||
}
|
||||
|
||||
MonitorAutoLock lock(mVideo.mMonitor);
|
||||
|
@ -493,12 +490,6 @@ MP4Reader::RequestVideoData(bool aSkipToNextKeyframe,
|
|||
ScheduleUpdate(kVideo);
|
||||
}
|
||||
|
||||
// Report the number of "decoded" frames as the difference in the
|
||||
// mNumSamplesOutput field since the last time we were called.
|
||||
uint64_t delta = mVideo.mNumSamplesOutput - mLastReportedNumDecodedFrames;
|
||||
decoded = static_cast<uint32_t>(delta);
|
||||
mLastReportedNumDecodedFrames = mVideo.mNumSamplesOutput;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -551,6 +542,11 @@ MP4Reader::Update(TrackType aTrack)
|
|||
{
|
||||
MOZ_ASSERT(GetTaskQueue()->IsCurrentThreadIn());
|
||||
|
||||
// Record number of frames decoded and parsed. Automatically update the
|
||||
// stats counters using the AutoNotifyDecoded stack-based class.
|
||||
uint32_t parsed = 0, decoded = 0;
|
||||
AbstractMediaDecoder::AutoNotifyDecoded autoNotify(mDecoder, parsed, decoded);
|
||||
|
||||
bool needInput = false;
|
||||
bool needOutput = false;
|
||||
auto& decoder = GetDecoderData(aTrack);
|
||||
|
@ -562,6 +558,11 @@ MP4Reader::Update(TrackType aTrack)
|
|||
decoder.mInputExhausted = false;
|
||||
decoder.mNumSamplesInput++;
|
||||
}
|
||||
if (aTrack == kVideo) {
|
||||
uint64_t delta = decoder.mNumSamplesOutput - mLastReportedNumDecodedFrames;
|
||||
decoded = static_cast<uint32_t>(delta);
|
||||
mLastReportedNumDecodedFrames = decoder.mNumSamplesOutput;
|
||||
}
|
||||
if (decoder.HasPromise()) {
|
||||
needOutput = true;
|
||||
if (!decoder.mOutput.IsEmpty()) {
|
||||
|
@ -585,6 +586,9 @@ MP4Reader::Update(TrackType aTrack)
|
|||
MP4Sample* sample = PopSample(aTrack);
|
||||
if (sample) {
|
||||
decoder.mDecoder->Input(sample);
|
||||
if (aTrack == kVideo) {
|
||||
parsed++;
|
||||
}
|
||||
} else {
|
||||
{
|
||||
MonitorAutoLock lock(decoder.mMonitor);
|
||||
|
@ -783,7 +787,7 @@ MP4Reader::SkipVideoDemuxToNextKeyFrame(int64_t aTimeThreshold, uint32_t& parsed
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
MP4Reader::Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
|
@ -793,8 +797,7 @@ MP4Reader::Seek(int64_t aTime,
|
|||
MOZ_ASSERT(GetTaskQueue()->IsCurrentThreadIn());
|
||||
if (!mDecoder->GetResource()->IsTransportSeekable() || !mDemuxer->CanSeek()) {
|
||||
VLOG("Seek() END (Unseekable)");
|
||||
GetCallback()->OnSeekCompleted(NS_ERROR_FAILURE);
|
||||
return;
|
||||
return SeekPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
|
||||
}
|
||||
|
||||
mQueuedVideoSample = nullptr;
|
||||
|
@ -807,7 +810,7 @@ MP4Reader::Seek(int64_t aTime,
|
|||
mQueuedVideoSample ? mQueuedVideoSample->composition_timestamp : aTime);
|
||||
}
|
||||
LOG("MP4Reader::Seek(%lld) exit", aTime);
|
||||
GetCallback()->OnSeekCompleted(NS_OK);
|
||||
return SeekPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -55,10 +55,11 @@ public:
|
|||
|
||||
virtual void ReadUpdatedMetadata(MediaInfo* aInfo) MOZ_OVERRIDE;
|
||||
|
||||
virtual void Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool IsMediaSeekable() MOZ_OVERRIDE;
|
||||
|
||||
|
|
|
@ -787,10 +787,11 @@ bool GStreamerReader::DecodeVideoFrame(bool &aKeyFrameSkip,
|
|||
return true;
|
||||
}
|
||||
|
||||
void GStreamerReader::Seek(int64_t aTarget,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime)
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
GStreamerReader::Seek(int64_t aTarget,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime)
|
||||
{
|
||||
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
|
||||
|
||||
|
@ -804,8 +805,7 @@ void GStreamerReader::Seek(int64_t aTarget,
|
|||
static_cast<GstSeekFlags>(flags),
|
||||
seekPos)) {
|
||||
LOG(PR_LOG_ERROR, "seek failed");
|
||||
GetCallback()->OnSeekCompleted(NS_ERROR_FAILURE);
|
||||
return;
|
||||
return SeekPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
|
||||
}
|
||||
LOG(PR_LOG_DEBUG, "seek succeeded");
|
||||
GstMessage* message = gst_bus_timed_pop_filtered(mBus, GST_CLOCK_TIME_NONE,
|
||||
|
@ -813,7 +813,7 @@ void GStreamerReader::Seek(int64_t aTarget,
|
|||
gst_message_unref(message);
|
||||
LOG(PR_LOG_DEBUG, "seek completed");
|
||||
|
||||
GetCallback()->OnSeekCompleted(NS_OK);
|
||||
return SeekPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
|
||||
nsresult GStreamerReader::GetBuffered(dom::TimeRanges* aBuffered)
|
||||
|
|
|
@ -48,10 +48,11 @@ public:
|
|||
int64_t aTimeThreshold);
|
||||
virtual nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags);
|
||||
virtual void Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime);
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
virtual nsresult GetBuffered(dom::TimeRanges* aBuffered);
|
||||
|
||||
virtual void NotifyDataArrived(const char *aBuffer,
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include "prlog.h"
|
||||
#include "mozilla/dom/TimeRanges.h"
|
||||
#include "DecoderTraits.h"
|
||||
#include "MediaDataDecodedListener.h"
|
||||
#include "MediaDecoderOwner.h"
|
||||
#include "MediaSourceDecoder.h"
|
||||
#include "MediaSourceUtils.h"
|
||||
|
@ -296,6 +295,8 @@ MediaSourceReader::OnVideoNotDecoded(NotDecodedReason aReason)
|
|||
nsRefPtr<ShutdownPromise>
|
||||
MediaSourceReader::Shutdown()
|
||||
{
|
||||
mSeekPromise.RejectIfExists(NS_ERROR_FAILURE, __func__);
|
||||
|
||||
MOZ_ASSERT(mMediaSourceShutdownPromise.IsEmpty());
|
||||
nsRefPtr<ShutdownPromise> p = mMediaSourceShutdownPromise.Ensure(__func__);
|
||||
|
||||
|
@ -453,13 +454,6 @@ MediaSourceReader::CreateSubDecoder(const nsACString& aType)
|
|||
// borrowing.
|
||||
reader->SetBorrowedTaskQueue(GetTaskQueue());
|
||||
|
||||
// Set a callback on the subreader that forwards calls to this reader.
|
||||
// This reader will then forward them onto the state machine via this
|
||||
// reader's callback.
|
||||
RefPtr<MediaDataDecodedListener<MediaSourceReader>> callback =
|
||||
new MediaDataDecodedListener<MediaSourceReader>(this, reader->GetTaskQueue());
|
||||
reader->SetCallback(callback);
|
||||
|
||||
#ifdef MOZ_FMP4
|
||||
reader->SetSharedDecoderManager(mSharedDecoderManager);
|
||||
#endif
|
||||
|
@ -538,16 +532,19 @@ MediaSourceReader::NotifyTimeRangesChanged()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
MediaSourceReader::Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
|
||||
int64_t aCurrentTime)
|
||||
{
|
||||
MSE_DEBUG("MediaSourceReader(%p)::Seek(aTime=%lld, aStart=%lld, aEnd=%lld, aCurrent=%lld)",
|
||||
this, aTime, aStartTime, aEndTime, aCurrentTime);
|
||||
|
||||
mSeekPromise.RejectIfExists(NS_OK, __func__);
|
||||
nsRefPtr<SeekPromise> p = mSeekPromise.Ensure(__func__);
|
||||
|
||||
if (IsShutdown()) {
|
||||
GetCallback()->OnSeekCompleted(NS_ERROR_FAILURE);
|
||||
return;
|
||||
mSeekPromise.Reject(NS_ERROR_FAILURE, __func__);
|
||||
return p;
|
||||
}
|
||||
|
||||
// Store pending seek target in case the track buffers don't contain
|
||||
|
@ -575,20 +572,38 @@ MediaSourceReader::Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
|
|||
}
|
||||
|
||||
AttemptSeek();
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceReader::OnSeekCompleted(nsresult aResult)
|
||||
MediaSourceReader::OnSeekCompleted()
|
||||
{
|
||||
mPendingSeeks--;
|
||||
FinalizeSeek();
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceReader::OnSeekFailed(nsresult aResult)
|
||||
{
|
||||
mPendingSeeks--;
|
||||
// Keep the most recent failed result (if any)
|
||||
if (NS_FAILED(aResult)) {
|
||||
mSeekResult = aResult;
|
||||
}
|
||||
FinalizeSeek();
|
||||
}
|
||||
|
||||
void
|
||||
MediaSourceReader::FinalizeSeek()
|
||||
{
|
||||
// Only dispatch the final event onto the state machine
|
||||
// since it's only expecting one response.
|
||||
if (!mPendingSeeks) {
|
||||
GetCallback()->OnSeekCompleted(mSeekResult);
|
||||
if (NS_FAILED(mSeekResult)) {
|
||||
mSeekPromise.Reject(mSeekResult, __func__);
|
||||
} else {
|
||||
mSeekPromise.Resolve(true, __func__);
|
||||
}
|
||||
mSeekResult = NS_OK;
|
||||
}
|
||||
}
|
||||
|
@ -620,7 +635,10 @@ MediaSourceReader::AttemptSeek()
|
|||
mAudioReader->Seek(mPendingSeekTime,
|
||||
mPendingStartTime,
|
||||
mPendingEndTime,
|
||||
mPendingCurrentTime);
|
||||
mPendingCurrentTime)
|
||||
->Then(GetTaskQueue(), __func__, this,
|
||||
&MediaSourceReader::OnSeekCompleted,
|
||||
&MediaSourceReader::OnSeekFailed);
|
||||
MSE_DEBUG("MediaSourceReader(%p)::Seek audio reader=%p", this, mAudioReader.get());
|
||||
}
|
||||
if (mVideoTrack) {
|
||||
|
@ -629,7 +647,10 @@ MediaSourceReader::AttemptSeek()
|
|||
mVideoReader->Seek(mPendingSeekTime,
|
||||
mPendingStartTime,
|
||||
mPendingEndTime,
|
||||
mPendingCurrentTime);
|
||||
mPendingCurrentTime)
|
||||
->Then(GetTaskQueue(), __func__, this,
|
||||
&MediaSourceReader::OnSeekCompleted,
|
||||
&MediaSourceReader::OnSeekFailed);
|
||||
MSE_DEBUG("MediaSourceReader(%p)::Seek video reader=%p", this, mVideoReader.get());
|
||||
}
|
||||
{
|
||||
|
|
|
@ -55,7 +55,8 @@ public:
|
|||
void OnVideoDecoded(VideoData* aSample);
|
||||
void OnVideoNotDecoded(NotDecodedReason aReason);
|
||||
|
||||
void OnSeekCompleted(nsresult aResult);
|
||||
void OnSeekCompleted();
|
||||
void OnSeekFailed(nsresult aResult);
|
||||
|
||||
bool HasVideo() MOZ_OVERRIDE
|
||||
{
|
||||
|
@ -84,8 +85,9 @@ public:
|
|||
|
||||
nsresult ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags) MOZ_OVERRIDE;
|
||||
void ReadUpdatedMetadata(MediaInfo* aInfo) MOZ_OVERRIDE;
|
||||
void Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
// Acquires the decoder monitor, and is thus callable on any thread.
|
||||
nsresult GetBuffered(dom::TimeRanges* aBuffered) MOZ_OVERRIDE;
|
||||
|
@ -129,6 +131,7 @@ private:
|
|||
const nsTArray<nsRefPtr<SourceBufferDecoder>>& aTrackDecoders);
|
||||
|
||||
void AttemptSeek();
|
||||
void FinalizeSeek();
|
||||
|
||||
nsRefPtr<MediaDecoderReader> mAudioReader;
|
||||
nsRefPtr<MediaDecoderReader> mVideoReader;
|
||||
|
@ -152,6 +155,7 @@ private:
|
|||
|
||||
// Temporary seek information while we wait for the data
|
||||
// to be added to the track buffer.
|
||||
MediaPromiseHolder<SeekPromise> mSeekPromise;
|
||||
int64_t mPendingSeekTime;
|
||||
int64_t mPendingStartTime;
|
||||
int64_t mPendingEndTime;
|
||||
|
|
|
@ -98,7 +98,6 @@ EXPORTS += [
|
|||
'Latency.h',
|
||||
'MediaCache.h',
|
||||
'MediaData.h',
|
||||
'MediaDataDecodedListener.h',
|
||||
'MediaDecoder.h',
|
||||
'MediaDecoderOwner.h',
|
||||
'MediaDecoderReader.h',
|
||||
|
|
|
@ -1424,13 +1424,18 @@ nsresult OggReader::SeekInUnbuffered(int64_t aTarget,
|
|||
return SeekBisection(seekTarget, k, SEEK_FUZZ_USECS);
|
||||
}
|
||||
|
||||
void OggReader::Seek(int64_t aTarget,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime)
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
OggReader::Seek(int64_t aTarget,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime)
|
||||
{
|
||||
nsresult res = SeekInternal(aTarget, aStartTime, aEndTime, aCurrentTime);
|
||||
GetCallback()->OnSeekCompleted(res);
|
||||
if (NS_FAILED(res)) {
|
||||
return SeekPromise::CreateAndReject(res, __func__);
|
||||
} else {
|
||||
return SeekPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult OggReader::SeekInternal(int64_t aTarget,
|
||||
|
|
|
@ -75,7 +75,8 @@ public:
|
|||
|
||||
virtual nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags);
|
||||
virtual void Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime);
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
virtual nsresult GetBuffered(dom::TimeRanges* aBuffered);
|
||||
|
||||
virtual bool IsMediaSeekable() MOZ_OVERRIDE;
|
||||
|
|
|
@ -999,7 +999,7 @@ MediaCodecReader::DecodeVideoFrameSync(int64_t aTimeThreshold)
|
|||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
MediaCodecReader::Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
|
@ -1031,8 +1031,7 @@ MediaCodecReader::Seek(int64_t aTime,
|
|||
options.setSeekTo(aTime, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
|
||||
if (mVideoTrack.mSource->read(&source_buffer, &options) != OK ||
|
||||
source_buffer == nullptr) {
|
||||
GetCallback()->OnSeekCompleted(NS_ERROR_FAILURE);
|
||||
return;
|
||||
return SeekPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
|
||||
}
|
||||
sp<MetaData> format = source_buffer->meta_data();
|
||||
if (format != nullptr) {
|
||||
|
@ -1056,7 +1055,7 @@ MediaCodecReader::Seek(int64_t aTime,
|
|||
MOZ_ASSERT(mAudioTrack.mTaskQueue->IsEmpty());
|
||||
DispatchAudioTask();
|
||||
}
|
||||
GetCallback()->OnSeekCompleted(NS_OK);
|
||||
return SeekPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -100,10 +100,11 @@ public:
|
|||
// Moves the decode head to aTime microseconds. aStartTime and aEndTime
|
||||
// denote the start and end times of the media in usecs, and aCurrentTime
|
||||
// is the current playback position in microseconds.
|
||||
virtual void Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime);
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool IsMediaSeekable() MOZ_OVERRIDE;
|
||||
|
||||
|
|
|
@ -545,7 +545,8 @@ bool MediaOmxReader::DecodeAudioData()
|
|||
source.mAudioChannels));
|
||||
}
|
||||
|
||||
void MediaOmxReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime)
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
MediaOmxReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime)
|
||||
{
|
||||
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
|
||||
EnsureActive();
|
||||
|
@ -571,7 +572,7 @@ void MediaOmxReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime,
|
|||
mAudioSeekTimeUs = mVideoSeekTimeUs = aTarget;
|
||||
}
|
||||
|
||||
GetCallback()->OnSeekCompleted(NS_OK);
|
||||
return SeekPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
|
||||
void MediaOmxReader::SetIdle() {
|
||||
|
|
|
@ -98,7 +98,8 @@ public:
|
|||
virtual void PreReadMetadata() MOZ_OVERRIDE;
|
||||
virtual nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags);
|
||||
virtual void Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime);
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool IsMediaSeekable() MOZ_OVERRIDE;
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ RtspMediaCodecReader::CreateExtractor()
|
|||
return mExtractor != nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
RtspMediaCodecReader::Seek(int64_t aTime, int64_t aStartTime,
|
||||
int64_t aEndTime, int64_t aCurrentTime)
|
||||
{
|
||||
|
@ -48,7 +48,7 @@ RtspMediaCodecReader::Seek(int64_t aTime, int64_t aStartTime,
|
|||
// RtspMediaResource.
|
||||
mRtspResource->SeekTime(aTime);
|
||||
|
||||
MediaCodecReader::Seek(aTime, aStartTime, aEndTime, aCurrentTime);
|
||||
return MediaCodecReader::Seek(aTime, aStartTime, aEndTime, aCurrentTime);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -36,8 +36,9 @@ public:
|
|||
virtual ~RtspMediaCodecReader();
|
||||
|
||||
// Implement a time-based seek instead of byte-based.
|
||||
virtual void Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
// Override GetBuffered() to do nothing for below reasons:
|
||||
// 1. Because the Rtsp stream is a/v separated. The buffered data in a/v
|
||||
|
|
|
@ -32,8 +32,9 @@ nsresult RtspOmxReader::InitOmxDecoder()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void RtspOmxReader::Seek(int64_t aTime, int64_t aStartTime,
|
||||
int64_t aEndTime, int64_t aCurrentTime)
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
RtspOmxReader::Seek(int64_t aTime, int64_t aStartTime,
|
||||
int64_t aEndTime, int64_t aCurrentTime)
|
||||
{
|
||||
// The seek function of Rtsp is time-based, we call the SeekTime function in
|
||||
// RtspMediaResource. The SeekTime function finally send a seek command to
|
||||
|
@ -48,7 +49,7 @@ void RtspOmxReader::Seek(int64_t aTime, int64_t aStartTime,
|
|||
// seek operation. The function will clear the |mVideoQueue| and |mAudioQueue|
|
||||
// that store the decoded data and also call the |DecodeToTarget| to pass
|
||||
// the seek time to OMX a/v decoders.
|
||||
MediaOmxReader::Seek(aTime, aStartTime, aEndTime, aCurrentTime);
|
||||
return MediaOmxReader::Seek(aTime, aStartTime, aEndTime, aCurrentTime);
|
||||
}
|
||||
|
||||
void RtspOmxReader::SetIdle() {
|
||||
|
|
|
@ -46,8 +46,9 @@ public:
|
|||
}
|
||||
|
||||
// Implement a time-based seek instead of byte-based..
|
||||
virtual void Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_FINAL MOZ_OVERRIDE;
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_FINAL MOZ_OVERRIDE;
|
||||
|
||||
// Override GetBuffered() to do nothing for below reasons:
|
||||
// 1. Because the Rtsp stream is a/v separated. The buffered data in a/v
|
||||
|
|
|
@ -235,10 +235,15 @@ bool RawReader::DecodeVideoFrame(bool &aKeyframeSkip,
|
|||
return true;
|
||||
}
|
||||
|
||||
void RawReader::Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime)
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
RawReader::Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime)
|
||||
{
|
||||
nsresult res = SeekInternal(aTime);
|
||||
GetCallback()->OnSeekCompleted(res);
|
||||
if (NS_FAILED(res)) {
|
||||
return SeekPromise::CreateAndReject(res, __func__);
|
||||
} else {
|
||||
return SeekPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult RawReader::SeekInternal(int64_t aTime)
|
||||
|
|
|
@ -39,7 +39,9 @@ public:
|
|||
|
||||
virtual nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags);
|
||||
virtual void Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime);
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult GetBuffered(dom::TimeRanges* aBuffered);
|
||||
|
||||
virtual bool IsMediaSeekable() MOZ_OVERRIDE;
|
||||
|
|
|
@ -257,13 +257,14 @@ bool WaveReader::DecodeVideoFrame(bool &aKeyframeSkip,
|
|||
return false;
|
||||
}
|
||||
|
||||
void WaveReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime)
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
WaveReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime)
|
||||
{
|
||||
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
|
||||
LOG(PR_LOG_DEBUG, ("%p About to seek to %lld", mDecoder, aTarget));
|
||||
|
||||
if (NS_FAILED(ResetDecode())) {
|
||||
GetCallback()->OnSeekCompleted(NS_ERROR_FAILURE);
|
||||
return;
|
||||
return SeekPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
|
||||
}
|
||||
double d = BytesToTime(GetDataLength());
|
||||
NS_ASSERTION(d < INT64_MAX / USECS_PER_S, "Duration overflow");
|
||||
|
@ -273,7 +274,11 @@ void WaveReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime, int
|
|||
NS_ASSERTION(INT64_MAX - mWavePCMOffset > position, "Integer overflow during wave seek");
|
||||
position += mWavePCMOffset;
|
||||
nsresult res = mDecoder->GetResource()->Seek(nsISeekableStream::NS_SEEK_SET, position);
|
||||
GetCallback()->OnSeekCompleted(res);
|
||||
if (NS_FAILED(res)) {
|
||||
return SeekPromise::CreateAndReject(res, __func__);
|
||||
} else {
|
||||
return SeekPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
static double RoundToUsecs(double aSeconds) {
|
||||
|
|
|
@ -43,7 +43,9 @@ public:
|
|||
|
||||
virtual nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags);
|
||||
virtual void Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime);
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult GetBuffered(dom::TimeRanges* aBuffered);
|
||||
|
||||
// To seek in a buffered range, we just have to seek the stream.
|
||||
|
|
|
@ -951,11 +951,16 @@ void WebMReader::PushVideoPacket(NesteggPacketHolder* aItem)
|
|||
mVideoPackets.PushFront(aItem);
|
||||
}
|
||||
|
||||
void WebMReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime,
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
WebMReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime,
|
||||
int64_t aCurrentTime)
|
||||
{
|
||||
nsresult res = SeekInternal(aTarget, aStartTime);
|
||||
GetCallback()->OnSeekCompleted(res);
|
||||
if (NS_FAILED(res)) {
|
||||
return SeekPromise::CreateAndReject(res, __func__);
|
||||
} else {
|
||||
return SeekPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult WebMReader::SeekInternal(int64_t aTarget, int64_t aStartTime)
|
||||
|
|
|
@ -155,8 +155,9 @@ public:
|
|||
|
||||
virtual nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags);
|
||||
virtual void Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
|
||||
int64_t aCurrentTime);
|
||||
virtual nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult GetBuffered(dom::TimeRanges* aBuffered);
|
||||
virtual void NotifyDataArrived(const char* aBuffer, uint32_t aLength,
|
||||
int64_t aOffset);
|
||||
|
|
|
@ -888,14 +888,18 @@ WMFReader::DecodeVideoFrame(bool &aKeyframeSkip,
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
nsRefPtr<MediaDecoderReader::SeekPromise>
|
||||
WMFReader::Seek(int64_t aTargetUs,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime)
|
||||
{
|
||||
nsresult res = SeekInternal(aTargetUs);
|
||||
GetCallback()->OnSeekCompleted(res);
|
||||
if (NS_FAILED(res)) {
|
||||
return SeekPromise::CreateAndReject(res, __func__);
|
||||
} else {
|
||||
return SeekPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -43,10 +43,11 @@ public:
|
|||
nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags) MOZ_OVERRIDE;
|
||||
|
||||
void Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
nsRefPtr<SeekPromise>
|
||||
Seek(int64_t aTime,
|
||||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
bool IsMediaSeekable() MOZ_OVERRIDE;
|
||||
|
||||
|
|
|
@ -1246,7 +1246,7 @@ class PromiseWorkerProxyRunnable : public workers::WorkerRunnable
|
|||
{
|
||||
public:
|
||||
PromiseWorkerProxyRunnable(PromiseWorkerProxy* aPromiseWorkerProxy,
|
||||
JSStructuredCloneCallbacks* aCallbacks,
|
||||
const JSStructuredCloneCallbacks* aCallbacks,
|
||||
JSAutoStructuredCloneBuffer&& aBuffer,
|
||||
PromiseWorkerProxy::RunCallbackFunc aFunc)
|
||||
: WorkerRunnable(aPromiseWorkerProxy->GetWorkerPrivate(),
|
||||
|
@ -1292,7 +1292,7 @@ protected:
|
|||
|
||||
private:
|
||||
nsRefPtr<PromiseWorkerProxy> mPromiseWorkerProxy;
|
||||
JSStructuredCloneCallbacks* mCallbacks;
|
||||
const JSStructuredCloneCallbacks* mCallbacks;
|
||||
JSAutoStructuredCloneBuffer mBuffer;
|
||||
|
||||
// Function pointer for calling Promise::{ResolveInternal,RejectInternal}.
|
||||
|
@ -1301,7 +1301,7 @@ private:
|
|||
|
||||
PromiseWorkerProxy::PromiseWorkerProxy(WorkerPrivate* aWorkerPrivate,
|
||||
Promise* aWorkerPromise,
|
||||
JSStructuredCloneCallbacks* aCallbacks)
|
||||
const JSStructuredCloneCallbacks* aCallbacks)
|
||||
: mWorkerPrivate(aWorkerPrivate)
|
||||
, mWorkerPromise(aWorkerPromise)
|
||||
, mCleanedUp(false)
|
||||
|
|
|
@ -67,7 +67,7 @@ class PromiseWorkerProxy : public PromiseNativeHandler,
|
|||
public:
|
||||
PromiseWorkerProxy(workers::WorkerPrivate* aWorkerPrivate,
|
||||
Promise* aWorkerPromise,
|
||||
JSStructuredCloneCallbacks* aCallbacks = nullptr);
|
||||
const JSStructuredCloneCallbacks* aCallbacks = nullptr);
|
||||
|
||||
workers::WorkerPrivate* GetWorkerPrivate() const;
|
||||
|
||||
|
@ -104,7 +104,7 @@ private:
|
|||
|
||||
bool mCleanedUp; // To specify if the cleanUp() has been done.
|
||||
|
||||
JSStructuredCloneCallbacks* mCallbacks;
|
||||
const JSStructuredCloneCallbacks* mCallbacks;
|
||||
|
||||
// Aimed to keep objects alive when doing the structured-clone read/write,
|
||||
// which can be added by calling StoreISupports() on the main thread.
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "nsContentUtils.h"
|
||||
#include "nsCRTGlue.h"
|
||||
#include "nsDirectoryServiceUtils.h"
|
||||
#include "nsEscape.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsScriptSecurityManager.h"
|
||||
|
@ -1617,12 +1618,19 @@ QuotaManager::GetQuotaObject(PersistenceType aPersistenceType,
|
|||
fileSize = 0;
|
||||
}
|
||||
|
||||
// Re-escape our parameters above to make sure we get the right quota group.
|
||||
nsAutoCString tempStorage1;
|
||||
const nsCSubstring& group = NS_EscapeURL(aGroup, esc_Query, tempStorage1);
|
||||
|
||||
nsAutoCString tempStorage2;
|
||||
const nsCSubstring& origin = NS_EscapeURL(aOrigin, esc_Query, tempStorage2);
|
||||
|
||||
nsRefPtr<QuotaObject> result;
|
||||
{
|
||||
MutexAutoLock lock(mQuotaMutex);
|
||||
|
||||
GroupInfoTriple* triple;
|
||||
if (!mGroupInfoTriples.Get(aGroup, &triple)) {
|
||||
if (!mGroupInfoTriples.Get(group, &triple)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -1633,7 +1641,7 @@ QuotaManager::GetQuotaObject(PersistenceType aPersistenceType,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<OriginInfo> originInfo = groupInfo->LockedGetOriginInfo(aOrigin);
|
||||
nsRefPtr<OriginInfo> originInfo = groupInfo->LockedGetOriginInfo(origin);
|
||||
|
||||
if (!originInfo) {
|
||||
return nullptr;
|
||||
|
|
|
@ -123,7 +123,7 @@ static nsTArray<nsCString> gReason;
|
|||
static NetworkParams *gWifiTetheringParms = 0;
|
||||
|
||||
|
||||
CommandFunc NetworkUtils::sWifiEnableChain[] = {
|
||||
const CommandFunc NetworkUtils::sWifiEnableChain[] = {
|
||||
NetworkUtils::clearWifiTetherParms,
|
||||
NetworkUtils::wifiFirmwareReload,
|
||||
NetworkUtils::startAccessPointDriver,
|
||||
|
@ -139,7 +139,7 @@ CommandFunc NetworkUtils::sWifiEnableChain[] = {
|
|||
NetworkUtils::wifiTetheringSuccess
|
||||
};
|
||||
|
||||
CommandFunc NetworkUtils::sWifiDisableChain[] = {
|
||||
const CommandFunc NetworkUtils::sWifiDisableChain[] = {
|
||||
NetworkUtils::clearWifiTetherParms,
|
||||
NetworkUtils::stopSoftAP,
|
||||
NetworkUtils::stopAccessPointDriver,
|
||||
|
@ -153,14 +153,14 @@ CommandFunc NetworkUtils::sWifiDisableChain[] = {
|
|||
NetworkUtils::wifiTetheringSuccess
|
||||
};
|
||||
|
||||
CommandFunc NetworkUtils::sWifiFailChain[] = {
|
||||
const CommandFunc NetworkUtils::sWifiFailChain[] = {
|
||||
NetworkUtils::clearWifiTetherParms,
|
||||
NetworkUtils::stopSoftAP,
|
||||
NetworkUtils::setIpForwardingEnabled,
|
||||
NetworkUtils::stopTethering
|
||||
};
|
||||
|
||||
CommandFunc NetworkUtils::sWifiRetryChain[] = {
|
||||
const CommandFunc NetworkUtils::sWifiRetryChain[] = {
|
||||
NetworkUtils::clearWifiTetherParms,
|
||||
NetworkUtils::stopSoftAP,
|
||||
NetworkUtils::stopTethering,
|
||||
|
@ -180,12 +180,12 @@ CommandFunc NetworkUtils::sWifiRetryChain[] = {
|
|||
NetworkUtils::wifiTetheringSuccess
|
||||
};
|
||||
|
||||
CommandFunc NetworkUtils::sWifiOperationModeChain[] = {
|
||||
const CommandFunc NetworkUtils::sWifiOperationModeChain[] = {
|
||||
NetworkUtils::wifiFirmwareReload,
|
||||
NetworkUtils::wifiOperationModeSuccess
|
||||
};
|
||||
|
||||
CommandFunc NetworkUtils::sUSBEnableChain[] = {
|
||||
const CommandFunc NetworkUtils::sUSBEnableChain[] = {
|
||||
NetworkUtils::setInterfaceUp,
|
||||
NetworkUtils::enableNat,
|
||||
NetworkUtils::setIpForwardingEnabled,
|
||||
|
@ -196,7 +196,7 @@ CommandFunc NetworkUtils::sUSBEnableChain[] = {
|
|||
NetworkUtils::usbTetheringSuccess
|
||||
};
|
||||
|
||||
CommandFunc NetworkUtils::sUSBDisableChain[] = {
|
||||
const CommandFunc NetworkUtils::sUSBDisableChain[] = {
|
||||
NetworkUtils::untetherInterface,
|
||||
NetworkUtils::preTetherInterfaceList,
|
||||
NetworkUtils::postTetherInterfaceList,
|
||||
|
@ -206,48 +206,48 @@ CommandFunc NetworkUtils::sUSBDisableChain[] = {
|
|||
NetworkUtils::usbTetheringSuccess
|
||||
};
|
||||
|
||||
CommandFunc NetworkUtils::sUSBFailChain[] = {
|
||||
const CommandFunc NetworkUtils::sUSBFailChain[] = {
|
||||
NetworkUtils::stopSoftAP,
|
||||
NetworkUtils::setIpForwardingEnabled,
|
||||
NetworkUtils::stopTethering
|
||||
};
|
||||
|
||||
CommandFunc NetworkUtils::sUpdateUpStreamChain[] = {
|
||||
const CommandFunc NetworkUtils::sUpdateUpStreamChain[] = {
|
||||
NetworkUtils::cleanUpStream,
|
||||
NetworkUtils::createUpStream,
|
||||
NetworkUtils::updateUpStreamSuccess
|
||||
};
|
||||
|
||||
CommandFunc NetworkUtils::sStartDhcpServerChain[] = {
|
||||
const CommandFunc NetworkUtils::sStartDhcpServerChain[] = {
|
||||
NetworkUtils::setInterfaceUp,
|
||||
NetworkUtils::startTethering,
|
||||
NetworkUtils::setDhcpServerSuccess
|
||||
};
|
||||
|
||||
CommandFunc NetworkUtils::sStopDhcpServerChain[] = {
|
||||
const CommandFunc NetworkUtils::sStopDhcpServerChain[] = {
|
||||
NetworkUtils::stopTethering,
|
||||
NetworkUtils::setDhcpServerSuccess
|
||||
};
|
||||
|
||||
CommandFunc NetworkUtils::sNetworkInterfaceEnableAlarmChain[] = {
|
||||
const CommandFunc NetworkUtils::sNetworkInterfaceEnableAlarmChain[] = {
|
||||
NetworkUtils::enableAlarm,
|
||||
NetworkUtils::setQuota,
|
||||
NetworkUtils::setAlarm,
|
||||
NetworkUtils::networkInterfaceAlarmSuccess
|
||||
};
|
||||
|
||||
CommandFunc NetworkUtils::sNetworkInterfaceDisableAlarmChain[] = {
|
||||
const CommandFunc NetworkUtils::sNetworkInterfaceDisableAlarmChain[] = {
|
||||
NetworkUtils::removeQuota,
|
||||
NetworkUtils::disableAlarm,
|
||||
NetworkUtils::networkInterfaceAlarmSuccess
|
||||
};
|
||||
|
||||
CommandFunc NetworkUtils::sNetworkInterfaceSetAlarmChain[] = {
|
||||
const CommandFunc NetworkUtils::sNetworkInterfaceSetAlarmChain[] = {
|
||||
NetworkUtils::setAlarm,
|
||||
NetworkUtils::networkInterfaceAlarmSuccess
|
||||
};
|
||||
|
||||
CommandFunc NetworkUtils::sSetDnsChain[] = {
|
||||
const CommandFunc NetworkUtils::sSetDnsChain[] = {
|
||||
NetworkUtils::setDefaultInterface,
|
||||
NetworkUtils::setInterfaceDns
|
||||
};
|
||||
|
|
|
@ -164,7 +164,7 @@ class CommandChain MOZ_FINAL
|
|||
{
|
||||
public:
|
||||
CommandChain(const NetworkParams& aParams,
|
||||
CommandFunc aCmds[],
|
||||
const CommandFunc aCmds[],
|
||||
uint32_t aLength,
|
||||
ErrorCallback aError)
|
||||
: mIndex(-1)
|
||||
|
@ -196,7 +196,7 @@ public:
|
|||
private:
|
||||
uint32_t mIndex;
|
||||
NetworkParams mParams;
|
||||
CommandFunc* mCommands;
|
||||
const CommandFunc* mCommands;
|
||||
uint32_t mLength;
|
||||
ErrorCallback mError;
|
||||
};
|
||||
|
@ -263,21 +263,21 @@ private:
|
|||
* function pointer array holds all netd commands should be executed
|
||||
* in sequence to accomplish a given command by other module.
|
||||
*/
|
||||
static CommandFunc sWifiEnableChain[];
|
||||
static CommandFunc sWifiDisableChain[];
|
||||
static CommandFunc sWifiFailChain[];
|
||||
static CommandFunc sWifiRetryChain[];
|
||||
static CommandFunc sWifiOperationModeChain[];
|
||||
static CommandFunc sUSBEnableChain[];
|
||||
static CommandFunc sUSBDisableChain[];
|
||||
static CommandFunc sUSBFailChain[];
|
||||
static CommandFunc sUpdateUpStreamChain[];
|
||||
static CommandFunc sStartDhcpServerChain[];
|
||||
static CommandFunc sStopDhcpServerChain[];
|
||||
static CommandFunc sNetworkInterfaceEnableAlarmChain[];
|
||||
static CommandFunc sNetworkInterfaceDisableAlarmChain[];
|
||||
static CommandFunc sNetworkInterfaceSetAlarmChain[];
|
||||
static CommandFunc sSetDnsChain[];
|
||||
static const CommandFunc sWifiEnableChain[];
|
||||
static const CommandFunc sWifiDisableChain[];
|
||||
static const CommandFunc sWifiFailChain[];
|
||||
static const CommandFunc sWifiRetryChain[];
|
||||
static const CommandFunc sWifiOperationModeChain[];
|
||||
static const CommandFunc sUSBEnableChain[];
|
||||
static const CommandFunc sUSBDisableChain[];
|
||||
static const CommandFunc sUSBFailChain[];
|
||||
static const CommandFunc sUpdateUpStreamChain[];
|
||||
static const CommandFunc sStartDhcpServerChain[];
|
||||
static const CommandFunc sStopDhcpServerChain[];
|
||||
static const CommandFunc sNetworkInterfaceEnableAlarmChain[];
|
||||
static const CommandFunc sNetworkInterfaceDisableAlarmChain[];
|
||||
static const CommandFunc sNetworkInterfaceSetAlarmChain[];
|
||||
static const CommandFunc sSetDnsChain[];
|
||||
|
||||
/**
|
||||
* Individual netd command stored in command chain.
|
||||
|
|
|
@ -494,19 +494,13 @@ XPCOMUtils.defineLazyGetter(this, "gRadioEnabledController", function() {
|
|||
_getNumCards: function() {
|
||||
let numCards = 0;
|
||||
for (let i = 0, N = _ril.numRadioInterfaces; i < N; ++i) {
|
||||
if (this._isCardPresentAtClient(i)) {
|
||||
if (_ril.getRadioInterface(i).isCardPresent()) {
|
||||
numCards++;
|
||||
}
|
||||
}
|
||||
return numCards;
|
||||
},
|
||||
|
||||
_isCardPresentAtClient: function(clientId) {
|
||||
let cardState = _ril.getRadioInterface(clientId).rilContext.cardState;
|
||||
return cardState !== Ci.nsIIccProvider.CARD_STATE_UNDETECTED &&
|
||||
cardState !== Ci.nsIIccProvider.CARD_STATE_UNKNOWN;
|
||||
},
|
||||
|
||||
_isRadioAbleToEnableAtClient: function(clientId, numCards) {
|
||||
if (!RILQUIRKS_RADIO_OFF_WO_CARD) {
|
||||
return true;
|
||||
|
@ -516,7 +510,7 @@ XPCOMUtils.defineLazyGetter(this, "gRadioEnabledController", function() {
|
|||
// 1. a SIM card is presented or
|
||||
// 2. it is the default clientId and there is no any SIM card at any client.
|
||||
|
||||
if (this._isCardPresentAtClient(clientId)) {
|
||||
if (_ril.getRadioInterface(clientId).isCardPresent()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1511,12 +1505,15 @@ RadioInterfaceLayer.prototype = {
|
|||
},
|
||||
|
||||
getClientIdForEmergencyCall: function() {
|
||||
// Select the client with sim card first.
|
||||
for (let cid = 0; cid < this.numRadioInterfaces; ++cid) {
|
||||
if (gRadioEnabledController._isRadioAbleToEnableAtClient(cid)) {
|
||||
if (this.getRadioInterface(cid).isCardPresent()) {
|
||||
return cid;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
|
||||
// Use the defualt client if no card presents.
|
||||
return HW_DEFAULT_CLIENT_ID;
|
||||
},
|
||||
|
||||
setMicrophoneMuted: function(muted) {
|
||||
|
@ -1824,6 +1821,12 @@ RadioInterface.prototype = {
|
|||
return false;
|
||||
},
|
||||
|
||||
isCardPresent: function() {
|
||||
let cardState = this.rilContext.cardState;
|
||||
return cardState !== Ci.nsIIccProvider.CARD_STATE_UNDETECTED &&
|
||||
cardState !== Ci.nsIIccProvider.CARD_STATE_UNKNOWN;
|
||||
},
|
||||
|
||||
/**
|
||||
* Process a message from the content process.
|
||||
*/
|
||||
|
|
|
@ -62,27 +62,17 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class Telephony::EnumerationAck : public nsRunnable
|
||||
{
|
||||
nsRefPtr<Telephony> mTelephony;
|
||||
|
||||
public:
|
||||
explicit EnumerationAck(Telephony* aTelephony)
|
||||
: mTelephony(aTelephony)
|
||||
{
|
||||
MOZ_ASSERT(mTelephony);
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
mTelephony->NotifyEvent(NS_LITERAL_STRING("ready"));
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
Telephony::Telephony(nsPIDOMWindow* aOwner)
|
||||
: DOMEventTargetHelper(aOwner), mEnumerated(false)
|
||||
: DOMEventTargetHelper(aOwner)
|
||||
{
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aOwner);
|
||||
MOZ_ASSERT(global);
|
||||
|
||||
ErrorResult rv;
|
||||
nsRefPtr<Promise> promise = Promise::Create(global, rv);
|
||||
MOZ_ASSERT(!rv.Failed());
|
||||
|
||||
mReadyPromise = promise;
|
||||
}
|
||||
|
||||
Telephony::~Telephony()
|
||||
|
@ -327,6 +317,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(Telephony,
|
|||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCalls)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCallsList)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGroup)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mReadyPromise)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(Telephony,
|
||||
|
@ -335,6 +326,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(Telephony,
|
|||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCalls)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCallsList)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mGroup)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mReadyPromise)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(Telephony)
|
||||
|
@ -462,14 +454,16 @@ Telephony::ConferenceGroup() const
|
|||
return group.forget();
|
||||
}
|
||||
|
||||
// EventTarget
|
||||
|
||||
void
|
||||
Telephony::EventListenerAdded(nsIAtom* aType)
|
||||
already_AddRefed<Promise>
|
||||
Telephony::GetReady(ErrorResult& aRv) const
|
||||
{
|
||||
if (aType == nsGkAtoms::onready) {
|
||||
EnqueueEnumerationAck();
|
||||
if (!mReadyPromise) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = mReadyPromise;
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
// nsITelephonyListener
|
||||
|
@ -548,8 +542,6 @@ Telephony::ConferenceCallStateChanged(uint16_t aCallState)
|
|||
NS_IMETHODIMP
|
||||
Telephony::EnumerateCallStateComplete()
|
||||
{
|
||||
MOZ_ASSERT(!mEnumerated);
|
||||
|
||||
// Set conference state.
|
||||
if (mGroup->CallsArray().Length() >= 2) {
|
||||
const nsTArray<nsRefPtr<TelephonyCall> > &calls = mGroup->CallsArray();
|
||||
|
@ -565,10 +557,8 @@ Telephony::EnumerateCallStateComplete()
|
|||
mGroup->ChangeState(callState);
|
||||
}
|
||||
|
||||
mEnumerated = true;
|
||||
|
||||
if (NS_FAILED(NotifyEvent(NS_LITERAL_STRING("ready")))) {
|
||||
NS_WARNING("Failed to notify ready!");
|
||||
if (mReadyPromise) {
|
||||
mReadyPromise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
}
|
||||
|
||||
if (NS_FAILED(mService->RegisterListener(mListener))) {
|
||||
|
@ -693,19 +683,6 @@ Telephony::DispatchCallEvent(const nsAString& aType,
|
|||
return DispatchTrustedEvent(event);
|
||||
}
|
||||
|
||||
void
|
||||
Telephony::EnqueueEnumerationAck()
|
||||
{
|
||||
if (!mEnumerated) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> task = new EnumerationAck(this);
|
||||
if (NS_FAILED(NS_DispatchToCurrentThread(task))) {
|
||||
NS_WARNING("Failed to dispatch to current thread!");
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<nsITelephonyService>
|
||||
NS_CreateTelephonyService()
|
||||
{
|
||||
|
|
|
@ -40,9 +40,7 @@ class Telephony MOZ_FINAL : public DOMEventTargetHelper,
|
|||
* also bug 775997 comment #51.
|
||||
*/
|
||||
class Listener;
|
||||
class EnumerationAck;
|
||||
|
||||
friend class EnumerationAck;
|
||||
friend class telephony::TelephonyDialCallback;
|
||||
|
||||
nsCOMPtr<nsITelephonyService> mService;
|
||||
|
@ -53,7 +51,7 @@ class Telephony MOZ_FINAL : public DOMEventTargetHelper,
|
|||
|
||||
nsRefPtr<TelephonyCallGroup> mGroup;
|
||||
|
||||
bool mEnumerated;
|
||||
nsRefPtr<Promise> mReadyPromise;
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
@ -109,7 +107,9 @@ public:
|
|||
already_AddRefed<TelephonyCallGroup>
|
||||
ConferenceGroup() const;
|
||||
|
||||
IMPL_EVENT_HANDLER(ready)
|
||||
already_AddRefed<Promise>
|
||||
GetReady(ErrorResult& aRv) const;
|
||||
|
||||
IMPL_EVENT_HANDLER(incoming)
|
||||
IMPL_EVENT_HANDLER(callschanged)
|
||||
IMPL_EVENT_HANDLER(remoteheld)
|
||||
|
@ -146,8 +146,6 @@ public:
|
|||
return mCalls;
|
||||
}
|
||||
|
||||
virtual void EventListenerAdded(nsIAtom* aType) MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
explicit Telephony(nsPIDOMWindow* aOwner);
|
||||
~Telephony();
|
||||
|
@ -198,9 +196,6 @@ private:
|
|||
nsresult
|
||||
DispatchCallEvent(const nsAString& aType, TelephonyCall* aCall);
|
||||
|
||||
void
|
||||
EnqueueEnumerationAck();
|
||||
|
||||
already_AddRefed<TelephonyCall>
|
||||
GetCall(uint32_t aServiceId, uint32_t aCallIndex);
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче