Merge mozilla-central to fx-team

This commit is contained in:
Carsten "Tomcat" Book 2014-11-11 13:27:49 +01:00
commit 24a16f0935
141 changed files with 1711 additions and 1265 deletions

View File

@ -234,9 +234,6 @@ this.AccessFu = { // jshint ignore:line
case 'AccessFu:Input':
this.Input.setEditState(aMessage.json);
break;
case 'AccessFu:ActivateContextMenu':
this.Input.activateContextMenu(aMessage.json);
break;
case 'AccessFu:DoScroll':
this.Input.doScroll(aMessage.json);
break;
@ -283,7 +280,6 @@ this.AccessFu = { // jshint ignore:line
aMessageManager.addMessageListener('AccessFu:Present', this);
aMessageManager.addMessageListener('AccessFu:Input', this);
aMessageManager.addMessageListener('AccessFu:Ready', this);
aMessageManager.addMessageListener('AccessFu:ActivateContextMenu', this);
aMessageManager.addMessageListener('AccessFu:DoScroll', this);
},
@ -291,7 +287,6 @@ this.AccessFu = { // jshint ignore:line
aMessageManager.removeMessageListener('AccessFu:Present', this);
aMessageManager.removeMessageListener('AccessFu:Input', this);
aMessageManager.removeMessageListener('AccessFu:Ready', this);
aMessageManager.removeMessageListener('AccessFu:ActivateContextMenu', this);
aMessageManager.removeMessageListener('AccessFu:DoScroll', this);
},
@ -673,9 +668,6 @@ var Input = {
case 'doubletap1':
this.activateCurrent();
break;
case 'taphold1':
this.sendContextMenuMessage();
break;
case 'doubletaphold1':
Utils.dispatchChromeEvent('accessibility-control', 'quicknav-menu');
break;
@ -883,15 +875,6 @@ var Input = {
mm.sendAsyncMessage('AccessFu:ContextMenu', {});
},
activateContextMenu: function activateContextMenu(aDetails) {
if (Utils.MozBuildApp === 'mobile/android') {
let p = AccessFu.adjustContentBounds(aDetails.bounds,
Utils.CurrentBrowser, true).center();
Services.obs.notifyObservers(null, 'Gesture:LongPress',
JSON.stringify({x: p.x, y: p.y}));
}
},
setEditState: function setEditState(aEditState) {
Logger.debug(() => { return ['setEditState', JSON.stringify(aEditState)] });
this.editState = aEditState;

View File

@ -69,8 +69,13 @@ function forwardToChild(aMessage, aListener, aVCPosition) {
function activateContextMenu(aMessage) {
let position = Utils.getVirtualCursor(content.document).position;
if (!forwardToChild(aMessage, activateContextMenu, position)) {
sendAsyncMessage('AccessFu:ActivateContextMenu',
{ bounds: Utils.getBounds(position, true) });
let center = Utils.getBounds(position, true).center();
let evt = content.document.createEvent('HTMLEvents');
evt.initEvent('contextmenu', true, true);
evt.clientX = center.x;
evt.clientY = center.y;
position.DOMNode.dispatchEvent(evt);
}
}

View File

@ -100,11 +100,11 @@ let AdbController = {
return;
}
let storage = this.storages[storageIndex];
DEBUG && debug("Checking availability of storage: '" + storage.storageName);
DEBUG && debug("Checking availability of storage: '" + storage.storageName + "'");
let req = storage.available();
req.onsuccess = function(e) {
DEBUG && debug("Storage: '" + storage.storageName + "' is '" + e.target.result);
DEBUG && debug("Storage: '" + storage.storageName + "' is '" + e.target.result + "'");
if (e.target.result == 'shared') {
// We've found a storage area that's being shared with the PC.
// We can stop looking now.
@ -216,6 +216,11 @@ let AdbController = {
// Configure adb.
let currentConfig = libcutils.property_get("persist.sys.usb.config");
let configFuncs = currentConfig.split(",");
if (currentConfig == "" || currentConfig == "none") {
// We want to treat none like the empty string.
// "".split(",") yields [""] and not []
configFuncs = [];
}
let adbIndex = configFuncs.indexOf("adb");
if (enableAdb) {
@ -230,6 +235,11 @@ let AdbController = {
}
}
let newConfig = configFuncs.join(",");
if (newConfig == "") {
// Convert the empty string back into none, since that's what init.rc
// needs.
newConfig = "none";
}
if (newConfig != currentConfig) {
DEBUG && debug("updateState: currentConfig = " + currentConfig);
DEBUG && debug("updateState: newConfig = " + newConfig);

View File

@ -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="a98528f9a69dae06cbeba9b602c3d9839724250d"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="6af3a8a833eb8bb651e8b188cb3f3c3a43bb4184"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="e9cf0dc485a2af12353b41e9f1e41b23f3f07b41"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ed238f7f8824973ea16e69aef08c6a1d58c7165f"/>
<!-- 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"/>

View File

@ -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="a98528f9a69dae06cbeba9b602c3d9839724250d"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6af3a8a833eb8bb651e8b188cb3f3c3a43bb4184"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="67f2907bc340bad250b4ea6ce2902b52896c9ef0"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="e9cf0dc485a2af12353b41e9f1e41b23f3f07b41"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ed238f7f8824973ea16e69aef08c6a1d58c7165f"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>

View File

@ -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="a98528f9a69dae06cbeba9b602c3d9839724250d"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="6af3a8a833eb8bb651e8b188cb3f3c3a43bb4184"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="e9cf0dc485a2af12353b41e9f1e41b23f3f07b41"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ed238f7f8824973ea16e69aef08c6a1d58c7165f"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->

View File

@ -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="a98528f9a69dae06cbeba9b602c3d9839724250d"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="6af3a8a833eb8bb651e8b188cb3f3c3a43bb4184"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="e9cf0dc485a2af12353b41e9f1e41b23f3f07b41"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ed238f7f8824973ea16e69aef08c6a1d58c7165f"/>
<!-- 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"/>

View File

@ -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="a98528f9a69dae06cbeba9b602c3d9839724250d"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6af3a8a833eb8bb651e8b188cb3f3c3a43bb4184"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="67f2907bc340bad250b4ea6ce2902b52896c9ef0"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="e9cf0dc485a2af12353b41e9f1e41b23f3f07b41"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ed238f7f8824973ea16e69aef08c6a1d58c7165f"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>

View File

@ -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="a98528f9a69dae06cbeba9b602c3d9839724250d"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="6af3a8a833eb8bb651e8b188cb3f3c3a43bb4184"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="e9cf0dc485a2af12353b41e9f1e41b23f3f07b41"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ed238f7f8824973ea16e69aef08c6a1d58c7165f"/>
<!-- 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"/>

View File

@ -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="a98528f9a69dae06cbeba9b602c3d9839724250d"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="6af3a8a833eb8bb651e8b188cb3f3c3a43bb4184"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="e9cf0dc485a2af12353b41e9f1e41b23f3f07b41"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ed238f7f8824973ea16e69aef08c6a1d58c7165f"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->

View File

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "65b7d35ad078b90133481983950c64ad8fd27dd4",
"repo_path": "/integration/gaia-central"
"revision": "a7c053f5e582c15255c49645b07a19d72e4e5cb2",
"repo_path": "integration/gaia-central"
}

View File

@ -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="a98528f9a69dae06cbeba9b602c3d9839724250d"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6af3a8a833eb8bb651e8b188cb3f3c3a43bb4184"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="e9cf0dc485a2af12353b41e9f1e41b23f3f07b41"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ed238f7f8824973ea16e69aef08c6a1d58c7165f"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
<project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>

View File

@ -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="a98528f9a69dae06cbeba9b602c3d9839724250d"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6af3a8a833eb8bb651e8b188cb3f3c3a43bb4184"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -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="a98528f9a69dae06cbeba9b602c3d9839724250d"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="6af3a8a833eb8bb651e8b188cb3f3c3a43bb4184"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="e9cf0dc485a2af12353b41e9f1e41b23f3f07b41"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ed238f7f8824973ea16e69aef08c6a1d58c7165f"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->

View File

@ -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="a98528f9a69dae06cbeba9b602c3d9839724250d"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6af3a8a833eb8bb651e8b188cb3f3c3a43bb4184"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="45c54a55e31758f7e54e5eafe0d01d387f35897a"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="e9cf0dc485a2af12353b41e9f1e41b23f3f07b41"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ed238f7f8824973ea16e69aef08c6a1d58c7165f"/>
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>

View File

@ -6682,11 +6682,11 @@ var gIdentityHandler = {
this._encryptionLabel[this.IDENTITY_MODE_UNKNOWN] =
gNavigatorBundle.getString("identity.unencrypted");
this._encryptionLabel[this.IDENTITY_MODE_MIXED_DISPLAY_LOADED] =
gNavigatorBundle.getString("identity.mixed_display_loaded");
gNavigatorBundle.getString("identity.broken_loaded");
this._encryptionLabel[this.IDENTITY_MODE_MIXED_ACTIVE_LOADED] =
gNavigatorBundle.getString("identity.mixed_active_loaded2");
this._encryptionLabel[this.IDENTITY_MODE_MIXED_DISPLAY_LOADED_ACTIVE_BLOCKED] =
gNavigatorBundle.getString("identity.mixed_display_loaded");
gNavigatorBundle.getString("identity.broken_loaded");
return this._encryptionLabel;
},
get _identityPopup () {

View File

@ -254,7 +254,7 @@ function securityOnLoad() {
if (info.isBroken) {
hdr = pkiBundle.getString("pageInfo_MixedContent");
msg1 = pkiBundle.getString("pageInfo_Privacy_Mixed1");
msg1 = pkiBundle.getString("pageInfo_Privacy_Broken1");
msg2 = pkiBundle.getString("pageInfo_Privacy_None2");
}
else if (info.encryptionStrength > 0) {

View File

@ -430,33 +430,33 @@ skip-if = e10s
[browser_dbg_terminate-on-tab-close.js]
skip-if = e10s
[browser_dbg_tracing-01.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_tracing-02.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_tracing-03.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_tracing-04.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_tracing-05.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_tracing-06.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_tracing-07.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_tracing-08.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_variables-view-01.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_variables-view-02.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_variables-view-03.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_variables-view-04.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_variables-view-05.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_variables-view-06.js]
skip-if = e10s
skip-if = e10s && debug
[browser_dbg_variables-view-accessibility.js]
skip-if = e10s
[browser_dbg_variables-view-data.js]

View File

@ -7,13 +7,12 @@
const TAB_URL = EXAMPLE_URL + "doc_tracing-01.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
function test() {
SpecialPowers.pushPrefEnv({'set': [["devtools.debugger.tracer", true]]}, () => {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
@ -37,9 +36,7 @@ function test() {
}
function clickButton() {
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
sendMouseClickToTab(gTab, content.document.querySelector("button"));
}
function testTraceLogs() {
@ -103,7 +100,6 @@ function testTraceLogs() {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
});

View File

@ -7,13 +7,12 @@
const TAB_URL = EXAMPLE_URL + "doc_tracing-01.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
function test() {
SpecialPowers.pushPrefEnv({'set': [["devtools.debugger.tracer", true]]}, () => {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
@ -40,9 +39,7 @@ function test() {
}
function clickButton() {
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
sendMouseClickToTab(gTab, content.document.querySelector("button"));
}
function highlightCall() {
@ -72,7 +69,6 @@ function testNoneHighlighted() {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
});

View File

@ -7,13 +7,12 @@
const TAB_URL = EXAMPLE_URL + "doc_tracing-01.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
function test() {
SpecialPowers.pushPrefEnv({'set': [["devtools.debugger.tracer", true]]}, () => {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
@ -48,9 +47,7 @@ function test() {
}
function clickButton() {
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
sendMouseClickToTab(gTab, content.document.querySelector("button"));
}
function clickTraceLog() {
@ -64,7 +61,6 @@ function testCorrectLine() {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
});

View File

@ -7,13 +7,12 @@
const TAB_URL = EXAMPLE_URL + "doc_tracing-01.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
function test() {
SpecialPowers.pushPrefEnv({'set': [["devtools.debugger.tracer", true]]}, () => {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
@ -41,9 +40,7 @@ function test() {
}
function clickButton() {
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
sendMouseClickToTab(gTab, content.document.querySelector("button"));
}
function clickTraceCall() {
@ -78,7 +75,6 @@ function testReturn() {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
});

View File

@ -7,14 +7,13 @@
const TAB_URL = EXAMPLE_URL + "doc_tracing-01.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gTracer, gL10N;
function test() {
SpecialPowers.pushPrefEnv({'set': [["devtools.debugger.tracer", true]]}, () => {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gTracer = gDebugger.DebuggerView.Tracer;
@ -70,14 +69,11 @@ function testNoEmptyText() {
}
function clickButton() {
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
sendMouseClickToTab(gTab, content.document.querySelector("button"));
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gTracer = null;

View File

@ -8,14 +8,13 @@
const TAB_URL = EXAMPLE_URL + "doc_tracing-01.html";
const TRACER_PREF = "devtools.debugger.tracer";
let gTab, gDebuggee, gPanel, gDebugger;
let gTab, gPanel, gDebugger;
let gOriginalPref = Services.prefs.getBoolPref(TRACER_PREF);
Services.prefs.setBoolPref(TRACER_PREF, false);
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
@ -32,7 +31,6 @@ function test() {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
Services.prefs.setBoolPref(TRACER_PREF, gOriginalPref);

View File

@ -8,13 +8,13 @@
const TAB_URL = EXAMPLE_URL + "doc_tracing-01.html";
let gTab, gDebuggee, gPanel;
let gTab, gPanel;
function test() {
Task.async(function*() {
yield pushPref();
[gTab, gDebuggee, gPanel] = yield initDebugger(TAB_URL);
[gTab,, gPanel] = yield initDebugger(TAB_URL);
yield startTracing(gPanel);
yield clickButton();
@ -60,9 +60,7 @@ function test() {
}
function clickButton() {
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
sendMouseClickToTab(gTab, content.document.querySelector("button"));
}
function pushPref() {
@ -80,7 +78,6 @@ function popPref() {
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
});

View File

@ -9,7 +9,7 @@
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
let variables = aPanel.panelWin.DebuggerView.Variables;
let testScope = variables.addScope("test");

View File

@ -9,7 +9,7 @@
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
let variables = aPanel.panelWin.DebuggerView.Variables;
let testScope = variables.addScope("test");
let testVar = testScope.addItem("something");

View File

@ -9,7 +9,7 @@
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
let variables = aPanel.panelWin.DebuggerView.Variables;
let testScope = variables.addScope("test");

View File

@ -8,7 +8,7 @@
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
let variables = aPanel.panelWin.DebuggerView.Variables;
let testScope = variables.addScope("test");
let testVar = testScope.addItem("something");

View File

@ -8,7 +8,7 @@
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
let variables = aPanel.panelWin.DebuggerView.Variables;
let globalScope = variables.addScope("Test-Global");

View File

@ -8,11 +8,11 @@
const TAB_URL = EXAMPLE_URL + "doc_promise.html";
const test = Task.async(function* () {
const [tab, debuggee, panel] = yield initDebugger(TAB_URL);
const [tab,, panel] = yield initDebugger(TAB_URL);
yield ensureSourceIs(panel, "doc_promise.html", true);
const scopes = waitForCaretAndScopes(panel, 21);
executeSoon(debuggee.doPause);
callInTab(tab, "doPause");
yield scopes;
const variables = panel.panelWin.DebuggerView.Variables;

View File

@ -295,7 +295,7 @@ identity.identified.verified_by_you=You have added a security exception for this
identity.identified.state_and_country=%S, %S
identity.encrypted2=The connection to this website is secure.
identity.mixed_display_loaded=The connection to this website is not fully secure because it contains unencrypted elements (such as images).
identity.broken_loaded=The connection to this website is not fully secure because it contains unencrypted elements (such as images) or the encryption is not strong enough.
identity.mixed_active_loaded2=This website contains interactive content that isn't encrypted (such as scripts). Other people can view your information or modify the website's behavior.
identity.unencrypted=Your connection to this website is not encrypted.

View File

@ -3297,24 +3297,6 @@ if test "$ac_cv_cpp_unused_required" = yes ; then
fi
dnl Some compilers have trouble comparing a constant reference to a templatized
dnl class to zero, and require an explicit operator==() to be defined that takes
dnl an int. This test separates the strong from the weak.
AC_CACHE_CHECK(for trouble comparing to zero near std::operator!=(),
ac_cv_trouble_comparing_to_zero,
[AC_TRY_COMPILE([#include <algorithm>
template <class T> class Foo {};
class T2;
template <class T> int operator==(const T2*, const T&) { return 0; }
template <class T> int operator!=(const T2*, const T&) { return 0; }],
[Foo<int> f; return (0 != f);],
ac_cv_trouble_comparing_to_zero=no,
ac_cv_trouble_comparing_to_zero=yes)])
if test "$ac_cv_trouble_comparing_to_zero" = yes ; then
AC_DEFINE(HAVE_CPP_TROUBLE_COMPARING_TO_ZERO)
fi
# try harder, when checking for __thread support, see bug 521750 comment #33 and below
# We pass MOZ_OPTIMIZE_LDFLAGS to the linker because if dead_strip is
# enabled, the linker in xcode 4.1 will crash. Without this it would crash when
@ -9039,7 +9021,6 @@ CPP_THROW_NEW
HAVE_CPP_AMBIGUITY_RESOLVING_USING
HAVE_CPP_DYNAMIC_CAST_TO_VOID_PTR
HAVE_CPP_PARTIAL_SPECIALIZATION
HAVE_CPP_TROUBLE_COMPARING_TO_ZERO
NEED_CPP_UNUSED_IMPLEMENTATIONS
HAVE_GETPAGESIZE
HAVE_ICONV

View File

@ -26,6 +26,7 @@ support-files =
[test_app_enabled.html]
[test_app_update.html]
skip-if = os == "android" || toolkit == "gonk" # embed-apps doesn't work in mochitest app
[test_bug_795164.html]
[test_import_export.html]
[test_install_multiple_apps_origin.html]
@ -42,3 +43,4 @@ skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
[test_theme_role.html]
[test_web_app_install.html]
[test_widget.html]
skip-if = os == "android" || toolkit == "gonk" # embed-apps doesn't work in mochitest app

View File

@ -515,14 +515,6 @@ DragDataProducer::Produce(DataTransfer* aDataTransfer,
// grab the href as the url, use alt text as the title of the
// area if it's there. the drag data is the image tag and src
// attribute.
nsCOMPtr<nsIURI> imageURI;
image->GetCurrentURI(getter_AddRefs(imageURI));
if (imageURI) {
nsAutoCString spec;
imageURI->GetSpec(spec);
CopyUTF8toUTF16(spec, mUrlString);
}
nsCOMPtr<nsIDOMElement> imageElement(do_QueryInterface(image));
// XXXbz Shouldn't we use the "title" attr for title? Using
// "alt" seems very wrong....
@ -530,13 +522,10 @@ DragDataProducer::Produce(DataTransfer* aDataTransfer,
imageElement->GetAttribute(NS_LITERAL_STRING("alt"), mTitleString);
}
if (mTitleString.IsEmpty()) {
mTitleString = mUrlString;
}
nsCOMPtr<imgIRequest> imgRequest;
mUrlString.Truncate();
// grab the image data, and its request.
nsCOMPtr<imgIRequest> imgRequest;
nsCOMPtr<imgIContainer> img =
nsContentUtils::GetImageFromContent(image,
getter_AddRefs(imgRequest));
@ -547,7 +536,7 @@ DragDataProducer::Produce(DataTransfer* aDataTransfer,
// Fix the file extension in the URL if necessary
if (imgRequest && mimeService) {
nsCOMPtr<nsIURI> imgUri;
imgRequest->GetURI(getter_AddRefs(imgUri));
imgRequest->GetCurrentURI(getter_AddRefs(imgUri));
nsCOMPtr<nsIURL> imgUrl(do_QueryInterface(imgUri));
@ -568,6 +557,7 @@ DragDataProducer::Produce(DataTransfer* aDataTransfer,
// pass out the image source string
CopyUTF8toUTF16(spec, mImageSourceString);
mUrlString = mImageSourceString;
bool validExtension;
if (extension.IsEmpty() ||
@ -602,6 +592,18 @@ DragDataProducer::Produce(DataTransfer* aDataTransfer,
}
}
}
if (mUrlString.IsEmpty()) {
nsCOMPtr<nsIURI> imageURI;
image->GetCurrentURI(getter_AddRefs(imageURI));
if (imageURI) {
nsAutoCString spec;
imageURI->GetSpec(spec);
CopyUTF8toUTF16(spec, mUrlString);
}
}
if (mTitleString.IsEmpty()) {
mTitleString = mUrlString;
}
if (parentLink) {
// If we are dragging around an image in an anchor, then we

View File

@ -531,6 +531,7 @@ BluetoothOppManager::AfterOppDisconnected()
mLastCommand = 0;
mPutPacketReceivedLength = 0;
mDsFile = nullptr;
mDummyDsFile = nullptr;
// We can't reset mSuccessFlag here since this function may be called
// before we send system message of transfer complete
@ -557,6 +558,34 @@ BluetoothOppManager::AfterOppDisconnected()
}
}
void
BluetoothOppManager::RecoverFileName()
{
// Remove the trailing ".part" file name from mDsFile by two steps
// 1. mDsFile->SetPath() so that the notification sent to Gaia will carry
// correct information of the file.
// 2. mDsFile->mFile->RenameTo() so that the file name would actually be
// changed in file system.
if (mDsFile && mDsFile->mFile) {
nsString path;
path.AssignLiteral(TARGET_SUBDIR);
path.Append(mFileName);
mDsFile->SetPath(path);
mDsFile->mFile->RenameTo(nullptr, mFileName);
}
}
void
BluetoothOppManager::DeleteDummyFile()
{
// Remove the empty temp file
if (mDummyDsFile && mDummyDsFile->mFile) {
mDummyDsFile->mFile->Remove(false);
mDummyDsFile = nullptr;
}
}
void
BluetoothOppManager::DeleteReceivedFile()
{
@ -569,6 +598,8 @@ BluetoothOppManager::DeleteReceivedFile()
mDsFile->mFile->Remove(false);
mDsFile = nullptr;
}
DeleteDummyFile();
}
bool
@ -576,25 +607,39 @@ BluetoothOppManager::CreateFile()
{
MOZ_ASSERT(mPutPacketReceivedLength == mPacketLength);
// Create one dummy file to be a placeholder for the target file name, and
// create another file with a meaningless file extension to write the received
// data. By doing this, we can prevent applications from parsing incomplete
// data in the middle of the receiving process.
nsString path;
path.AssignLiteral(TARGET_SUBDIR);
path.Append(mFileName);
mDsFile = DeviceStorageFile::CreateUnique(
path, nsIFile::NORMAL_FILE_TYPE, 0644);
// Use an empty dummy file object to occupy the file name, so that after the
// whole file has been received successfully by using mDsFile, we could just
// remove mDummyDsFile and rename mDsFile to the file name of mDummyDsFile.
mDummyDsFile =
DeviceStorageFile::CreateUnique(path, nsIFile::NORMAL_FILE_TYPE, 0644);
NS_ENSURE_TRUE(mDummyDsFile, false);
// The function CreateUnique() may create a file with a different file
// name from the original mFileName. Therefore we have to retrieve
// the file name again.
mDummyDsFile->mFile->GetLeafName(mFileName);
BT_LOGR("mFileName: %s", NS_ConvertUTF16toUTF8(mFileName).get());
// Prepare the entire file path for the .part file
path.Truncate();
path.AssignLiteral(TARGET_SUBDIR);
path.Append(mFileName);
path.AppendLiteral(".part");
mDsFile =
DeviceStorageFile::CreateUnique(path, nsIFile::NORMAL_FILE_TYPE, 0644);
NS_ENSURE_TRUE(mDsFile, false);
nsCOMPtr<nsIFile> f;
mDsFile->mFile->Clone(getter_AddRefs(f));
/*
* The function CreateUnique() may create a file with a different file
* name from the original mFileName. Therefore we have to retrieve
* the file name again.
*/
f->GetLeafName(mFileName);
NS_NewLocalFileOutputStream(getter_AddRefs(mOutputStream), f);
NS_NewLocalFileOutputStream(getter_AddRefs(mOutputStream), mDsFile->mFile);
NS_ENSURE_TRUE(mOutputStream, false);
return true;
@ -911,6 +956,10 @@ BluetoothOppManager::ServerDataHandler(UnixSocketRawData* aMessage)
// Success to receive a file and notify completion
if (mPutFinalFlag) {
mSuccessFlag = true;
DeleteDummyFile();
RecoverFileName();
FileTransferComplete();
NotifyAboutFileChange();
}

View File

@ -85,6 +85,8 @@ private:
void ReceivingFileConfirmation();
bool CreateFile();
bool WriteToFile(const uint8_t* aData, int aDataLength);
void RecoverFileName();
void DeleteDummyFile();
void DeleteReceivedFile();
void ReplyToConnect();
void ReplyToDisconnectOrAbort();
@ -209,6 +211,7 @@ private:
nsCOMPtr<nsIInputStream> mInputStream;
nsCOMPtr<nsIVolumeMountLock> mMountLock;
nsRefPtr<DeviceStorageFile> mDsFile;
nsRefPtr<DeviceStorageFile> mDummyDsFile;
// If a connection has been established, mSocket will be the socket
// communicating with the remote socket. We maintain the invariant that if

View File

@ -553,6 +553,7 @@ BluetoothOppManager::AfterOppDisconnected()
mLastCommand = 0;
mPutPacketReceivedLength = 0;
mDsFile = nullptr;
mDummyDsFile = nullptr;
// We can't reset mSuccessFlag here since this function may be called
// before we send system message of transfer complete
@ -579,6 +580,34 @@ BluetoothOppManager::AfterOppDisconnected()
}
}
void
BluetoothOppManager::RecoverFileName()
{
// Remove the trailing ".part" file name from mDsFile by two steps
// 1. mDsFile->SetPath() so that the notification sent to Gaia will carry
// correct information of the file.
// 2. mDsFile->mFile->RenameTo() so that the file name would actually be
// changed in file system.
if (mDsFile && mDsFile->mFile) {
nsString path;
path.AssignLiteral(TARGET_SUBDIR);
path.Append(mFileName);
mDsFile->SetPath(path);
mDsFile->mFile->RenameTo(nullptr, mFileName);
}
}
void
BluetoothOppManager::DeleteDummyFile()
{
// Remove the empty temp file
if (mDummyDsFile && mDummyDsFile->mFile) {
mDummyDsFile->mFile->Remove(false);
mDummyDsFile = nullptr;
}
}
void
BluetoothOppManager::DeleteReceivedFile()
{
@ -591,6 +620,8 @@ BluetoothOppManager::DeleteReceivedFile()
mDsFile->mFile->Remove(false);
mDsFile = nullptr;
}
DeleteDummyFile();
}
bool
@ -598,25 +629,39 @@ BluetoothOppManager::CreateFile()
{
MOZ_ASSERT(mPutPacketReceivedLength == mPacketLength);
// Create one dummy file to be a placeholder for the target file name, and
// create another file with a meaningless file extension to write the received
// data. By doing this, we can prevent applications from parsing incomplete
// data in the middle of the receiving process.
nsString path;
path.AssignLiteral(TARGET_SUBDIR);
path.Append(mFileName);
mDsFile = DeviceStorageFile::CreateUnique(
path, nsIFile::NORMAL_FILE_TYPE, 0644);
// Use an empty dummy file object to occupy the file name, so that after the
// whole file has been received successfully by using mDsFile, we could just
// remove mDummyDsFile and rename mDsFile to the file name of mDummyDsFile.
mDummyDsFile =
DeviceStorageFile::CreateUnique(path, nsIFile::NORMAL_FILE_TYPE, 0644);
NS_ENSURE_TRUE(mDummyDsFile, false);
// The function CreateUnique() may create a file with a different file
// name from the original mFileName. Therefore we have to retrieve
// the file name again.
mDummyDsFile->mFile->GetLeafName(mFileName);
BT_LOGR("mFileName: %s", NS_ConvertUTF16toUTF8(mFileName).get());
// Prepare the entire file path for the .part file
path.Truncate();
path.AssignLiteral(TARGET_SUBDIR);
path.Append(mFileName);
path.AppendLiteral(".part");
mDsFile =
DeviceStorageFile::CreateUnique(path, nsIFile::NORMAL_FILE_TYPE, 0644);
NS_ENSURE_TRUE(mDsFile, false);
nsCOMPtr<nsIFile> f;
mDsFile->mFile->Clone(getter_AddRefs(f));
/*
* The function CreateUnique() may create a file with a different file
* name from the original mFileName. Therefore we have to retrieve
* the file name again.
*/
f->GetLeafName(mFileName);
NS_NewLocalFileOutputStream(getter_AddRefs(mOutputStream), f);
NS_NewLocalFileOutputStream(getter_AddRefs(mOutputStream), mDsFile->mFile);
NS_ENSURE_TRUE(mOutputStream, false);
return true;
@ -932,6 +977,10 @@ BluetoothOppManager::ServerDataHandler(UnixSocketRawData* aMessage)
// Success to receive a file and notify completion
if (mPutFinalFlag) {
mSuccessFlag = true;
DeleteDummyFile();
RecoverFileName();
FileTransferComplete();
NotifyAboutFileChange();
}

View File

@ -85,6 +85,8 @@ private:
void ReceivingFileConfirmation();
bool CreateFile();
bool WriteToFile(const uint8_t* aData, int aDataLength);
void RecoverFileName();
void DeleteDummyFile();
void DeleteReceivedFile();
void ReplyToConnect();
void ReplyToDisconnectOrAbort();
@ -209,6 +211,7 @@ private:
nsCOMPtr<nsIInputStream> mInputStream;
nsCOMPtr<nsIVolumeMountLock> mMountLock;
nsRefPtr<DeviceStorageFile> mDsFile;
nsRefPtr<DeviceStorageFile> mDummyDsFile;
// If a connection has been established, mSocket will be the socket
// communicating with the remote socket. We maintain the invariant that if

View File

@ -531,6 +531,7 @@ BluetoothOppManager::AfterOppDisconnected()
mLastCommand = 0;
mPutPacketReceivedLength = 0;
mDsFile = nullptr;
mDummyDsFile = nullptr;
// We can't reset mSuccessFlag here since this function may be called
// before we send system message of transfer complete
@ -557,6 +558,34 @@ BluetoothOppManager::AfterOppDisconnected()
}
}
void
BluetoothOppManager::RecoverFileName()
{
// Remove the trailing ".part" file name from mDsFile by two steps
// 1. mDsFile->SetPath() so that the notification sent to Gaia will carry
// correct information of the file.
// 2. mDsFile->mFile->RenameTo() so that the file name would actually be
// changed in file system.
if (mDsFile && mDsFile->mFile) {
nsString path;
path.AssignLiteral(TARGET_SUBDIR);
path.Append(mFileName);
mDsFile->SetPath(path);
mDsFile->mFile->RenameTo(nullptr, mFileName);
}
}
void
BluetoothOppManager::DeleteDummyFile()
{
// Remove the empty temp file
if (mDummyDsFile && mDummyDsFile->mFile) {
mDummyDsFile->mFile->Remove(false);
mDummyDsFile = nullptr;
}
}
void
BluetoothOppManager::DeleteReceivedFile()
{
@ -569,6 +598,8 @@ BluetoothOppManager::DeleteReceivedFile()
mDsFile->mFile->Remove(false);
mDsFile = nullptr;
}
DeleteDummyFile();
}
bool
@ -576,25 +607,39 @@ BluetoothOppManager::CreateFile()
{
MOZ_ASSERT(mPutPacketReceivedLength == mPacketLength);
// Create one dummy file to be a placeholder for the target file name, and
// create another file with a meaningless file extension to write the received
// data. By doing this, we can prevent applications from parsing incomplete
// data in the middle of the receiving process.
nsString path;
path.AssignLiteral(TARGET_SUBDIR);
path.Append(mFileName);
mDsFile = DeviceStorageFile::CreateUnique(
path, nsIFile::NORMAL_FILE_TYPE, 0644);
// Use an empty dummy file object to occupy the file name, so that after the
// whole file has been received successfully by using mDsFile, we could just
// remove mDummyDsFile and rename mDsFile to the file name of mDummyDsFile.
mDummyDsFile =
DeviceStorageFile::CreateUnique(path, nsIFile::NORMAL_FILE_TYPE, 0644);
NS_ENSURE_TRUE(mDummyDsFile, false);
// The function CreateUnique() may create a file with a different file
// name from the original mFileName. Therefore we have to retrieve
// the file name again.
mDummyDsFile->mFile->GetLeafName(mFileName);
BT_LOGR("mFileName: %s", NS_ConvertUTF16toUTF8(mFileName).get());
// Prepare the entire file path for the .part file
path.Truncate();
path.AssignLiteral(TARGET_SUBDIR);
path.Append(mFileName);
path.AppendLiteral(".part");
mDsFile =
DeviceStorageFile::CreateUnique(path, nsIFile::NORMAL_FILE_TYPE, 0644);
NS_ENSURE_TRUE(mDsFile, false);
nsCOMPtr<nsIFile> f;
mDsFile->mFile->Clone(getter_AddRefs(f));
/*
* The function CreateUnique() may create a file with a different file
* name from the original mFileName. Therefore we have to retrieve
* the file name again.
*/
f->GetLeafName(mFileName);
NS_NewLocalFileOutputStream(getter_AddRefs(mOutputStream), f);
NS_NewLocalFileOutputStream(getter_AddRefs(mOutputStream), mDsFile->mFile);
NS_ENSURE_TRUE(mOutputStream, false);
return true;
@ -911,6 +956,10 @@ BluetoothOppManager::ServerDataHandler(UnixSocketRawData* aMessage)
// Success to receive a file and notify completion
if (mPutFinalFlag) {
mSuccessFlag = true;
DeleteDummyFile();
RecoverFileName();
FileTransferComplete();
NotifyAboutFileChange();
}

View File

@ -85,6 +85,8 @@ private:
void ReceivingFileConfirmation();
bool CreateFile();
bool WriteToFile(const uint8_t* aData, int aDataLength);
void RecoverFileName();
void DeleteDummyFile();
void DeleteReceivedFile();
void ReplyToConnect();
void ReplyToDisconnectOrAbort();
@ -209,6 +211,7 @@ private:
nsCOMPtr<nsIInputStream> mInputStream;
nsCOMPtr<nsIVolumeMountLock> mMountLock;
nsRefPtr<DeviceStorageFile> mDsFile;
nsRefPtr<DeviceStorageFile> mDummyDsFile;
// If a connection has been established, mSocket will be the socket
// communicating with the remote socket. We maintain the invariant that if

View File

@ -553,6 +553,7 @@ BluetoothOppManager::AfterOppDisconnected()
mLastCommand = 0;
mPutPacketReceivedLength = 0;
mDsFile = nullptr;
mDummyDsFile = nullptr;
// We can't reset mSuccessFlag here since this function may be called
// before we send system message of transfer complete
@ -579,6 +580,34 @@ BluetoothOppManager::AfterOppDisconnected()
}
}
void
BluetoothOppManager::RecoverFileName()
{
// Remove the trailing ".part" file name from mDsFile by two steps
// 1. mDsFile->SetPath() so that the notification sent to Gaia will carry
// correct information of the file.
// 2. mDsFile->mFile->RenameTo() so that the file name would actually be
// changed in file system.
if (mDsFile && mDsFile->mFile) {
nsString path;
path.AssignLiteral(TARGET_SUBDIR);
path.Append(mFileName);
mDsFile->SetPath(path);
mDsFile->mFile->RenameTo(nullptr, mFileName);
}
}
void
BluetoothOppManager::DeleteDummyFile()
{
// Remove the empty temp file
if (mDummyDsFile && mDummyDsFile->mFile) {
mDummyDsFile->mFile->Remove(false);
mDummyDsFile = nullptr;
}
}
void
BluetoothOppManager::DeleteReceivedFile()
{
@ -591,6 +620,8 @@ BluetoothOppManager::DeleteReceivedFile()
mDsFile->mFile->Remove(false);
mDsFile = nullptr;
}
DeleteDummyFile();
}
bool
@ -598,25 +629,39 @@ BluetoothOppManager::CreateFile()
{
MOZ_ASSERT(mPutPacketReceivedLength == mPacketLength);
// Create one dummy file to be a placeholder for the target file name, and
// create another file with a meaningless file extension to write the received
// data. By doing this, we can prevent applications from parsing incomplete
// data in the middle of the receiving process.
nsString path;
path.AssignLiteral(TARGET_SUBDIR);
path.Append(mFileName);
mDsFile = DeviceStorageFile::CreateUnique(
path, nsIFile::NORMAL_FILE_TYPE, 0644);
// Use an empty dummy file object to occupy the file name, so that after the
// whole file has been received successfully by using mDsFile, we could just
// remove mDummyDsFile and rename mDsFile to the file name of mDummyDsFile.
mDummyDsFile =
DeviceStorageFile::CreateUnique(path, nsIFile::NORMAL_FILE_TYPE, 0644);
NS_ENSURE_TRUE(mDummyDsFile, false);
// The function CreateUnique() may create a file with a different file
// name from the original mFileName. Therefore we have to retrieve
// the file name again.
mDummyDsFile->mFile->GetLeafName(mFileName);
BT_LOGR("mFileName: %s", NS_ConvertUTF16toUTF8(mFileName).get());
// Prepare the entire file path for the .part file
path.Truncate();
path.AssignLiteral(TARGET_SUBDIR);
path.Append(mFileName);
path.AppendLiteral(".part");
mDsFile =
DeviceStorageFile::CreateUnique(path, nsIFile::NORMAL_FILE_TYPE, 0644);
NS_ENSURE_TRUE(mDsFile, false);
nsCOMPtr<nsIFile> f;
mDsFile->mFile->Clone(getter_AddRefs(f));
/*
* The function CreateUnique() may create a file with a different file
* name from the original mFileName. Therefore we have to retrieve
* the file name again.
*/
f->GetLeafName(mFileName);
NS_NewLocalFileOutputStream(getter_AddRefs(mOutputStream), f);
NS_NewLocalFileOutputStream(getter_AddRefs(mOutputStream), mDsFile->mFile);
NS_ENSURE_TRUE(mOutputStream, false);
return true;
@ -932,6 +977,10 @@ BluetoothOppManager::ServerDataHandler(UnixSocketRawData* aMessage)
// Success to receive a file and notify completion
if (mPutFinalFlag) {
mSuccessFlag = true;
DeleteDummyFile();
RecoverFileName();
FileTransferComplete();
NotifyAboutFileChange();
}

View File

@ -85,6 +85,8 @@ private:
void ReceivingFileConfirmation();
bool CreateFile();
bool WriteToFile(const uint8_t* aData, int aDataLength);
void RecoverFileName();
void DeleteDummyFile();
void DeleteReceivedFile();
void ReplyToConnect();
void ReplyToDisconnectOrAbort();
@ -209,6 +211,7 @@ private:
nsCOMPtr<nsIInputStream> mInputStream;
nsCOMPtr<nsIVolumeMountLock> mMountLock;
nsRefPtr<DeviceStorageFile> mDsFile;
nsRefPtr<DeviceStorageFile> mDummyDsFile;
// If a connection has been established, mSocket will be the socket
// communicating with the remote socket. We maintain the invariant that if

View File

@ -0,0 +1,42 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Bug 1059662 - Only allow a app to embed others apps when it runs
// in-process.
//
// The "inproc" version of this test should successfully embed the
// app, and the "oop" version of this test should fail to embed the
// app.
"use strict";
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
SpecialPowers.setAllAppsLaunchable(true);
function runTest() {
var canEmbedApp = !browserElementTestHelpers.getOOPByDefaultPref();
var iframe = document.createElement('iframe');
iframe.setAttribute('mozbrowser', 'true');
iframe.addEventListener('mozbrowsershowmodalprompt', function(e) {
is(e.detail.message == 'app', canEmbedApp, e.detail.message);
SimpleTest.finish();
});
document.body.appendChild(iframe);
var context = { 'url': 'http://example.org',
'appId': SpecialPowers.Ci.nsIScriptSecurityManager.NO_APP_ID,
'isInBrowserElement': true };
SpecialPowers.pushPermissions([
{'type': 'browser', 'allow': 1, 'context': context},
{'type': 'embed-apps', 'allow': 1, 'context': context}
], function() {
iframe.src = 'http://example.org/tests/dom/browser-element/mochitest/file_browserElement_DisallowEmbedAppsInOOP.html';
});
}
addEventListener('testready', runTest);

View File

@ -0,0 +1,19 @@
<html>
<head>
<script type="text/javascript">
addEventListener('load', function(e) {
var iframe = document.createElement('iframe');
iframe.setAttribute('mozbrowser', 'true');
iframe.setAttribute('remote', 'false');
iframe.setAttribute('mozapp', 'http://example.org/manifest.webapp');
iframe.addEventListener('mozbrowsershowmodalprompt', function(e) {
alert(e.detail.message);
});
document.body.appendChild(iframe);
iframe.src = 'http://example.org/tests/dom/browser-element/mochitest/file_browserElement_AppFramePermission.html';
});
</script>
</head>
<body>
</body>
</html>

View File

@ -31,6 +31,7 @@ skip-if = (toolkit == 'gonk' && !debug)
[test_browserElement_oop_CopyPaste.html]
[test_browserElement_oop_DOMRequestError.html]
[test_browserElement_oop_DataURI.html]
[test_browserElement_oop_DisallowEmbedAppsInOOP.html]
[test_browserElement_oop_DocumentFirstPaint.html]
[test_browserElement_oop_Download.html]
disabled = bug 1022281

View File

@ -22,6 +22,7 @@ support-files =
browserElement_CopyPaste.js
browserElement_DOMRequestError.js
browserElement_DataURI.js
browserElement_DisallowEmbedAppsInOOP.js
browserElement_DocumentFirstPaint.js
browserElement_Download.js
browserElement_ErrorSecurity.js
@ -77,6 +78,7 @@ support-files =
file_browserElement_CloseApp.html
file_browserElement_CloseFromOpener.html
file_browserElement_CookiesNotThirdParty.html
file_browserElement_DisallowEmbedAppsInOOP.html
file_browserElement_ForwardName.html
file_browserElement_FrameWrongURI.html
file_browserElement_LoadEvents.html
@ -143,6 +145,8 @@ skip-if = buildapp == 'b2g'
[test_browserElement_inproc_CopyPaste.html]
[test_browserElement_inproc_DOMRequestError.html]
[test_browserElement_inproc_DataURI.html]
[test_browserElement_inproc_DisallowEmbedAppsInOOP.html]
skip-if = os == "android" || toolkit == 'gonk' # embed-apps doesn't work in the mochitest app
[test_browserElement_inproc_DocumentFirstPaint.html]
[test_browserElement_inproc_Download.html]
disabled = bug 1022281

View File

@ -0,0 +1,13 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for Bug 1059662</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript;version=1.7" src="browserElement_DisallowEmbedAppsInOOP.js">
</script>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for Bug 1059662</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript;version=1.7" src="browserElement_DisallowEmbedAppsInOOP.js">
</script>
</body>
</html>

View File

@ -34,6 +34,7 @@ support-files =
file_notify_system_message.html
[test_app_install.html]
skip-if = toolkit == 'gonk' # embed-apps doesn't work in the mochitest app
[test_readonly.html]
skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 936226
[test_basic.html]

View File

@ -7,6 +7,7 @@
#include "nsGenericHTMLFrameElement.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/Preferences.h"
#include "mozilla/ErrorResult.h"
#include "GeckoProfiler.h"
@ -437,6 +438,11 @@ nsGenericHTMLFrameElement::GetAppManifestURL(nsAString& aOut)
return NS_OK;
}
if (XRE_GetProcessType() != GeckoProcessType_Default) {
NS_WARNING("Can't embed-apps. Embed-apps is restricted to in-proc apps, see bug 1059662");
return NS_OK;
}
nsAutoString appManifestURL;
nsAutoString widgetManifestURL;

View File

@ -6,7 +6,7 @@
dupe-manifest =
head = xpcshell-head-parent-process.js
tail =
skip-if = toolkit == 'android' || toolkit == 'gonk'
skip-if = toolkit == 'gonk'
support-files =
bug1056939.zip
GlobalObjectsChild.js
@ -21,6 +21,7 @@ support-files =
[test_blob_file_backed.js]
[test_bug1056939.js]
[test_globalObjects_ipc.js]
skip-if = toolkit == 'android'
[test_invalidate.js]
# disabled for the moment.
skip-if = true

View File

@ -1,8 +1,6 @@
# 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/.
[DEFAULT]
skip-if = toolkit == 'gonk'
[test_add_put.js]
[test_add_twice_failure.js]

View File

@ -1173,6 +1173,7 @@ MediaCache::Update()
// Figure out where we should be reading from. It's the first
// uncached byte after the current mStreamOffset.
int64_t dataOffset = stream->GetCachedDataEndInternal(stream->mStreamOffset);
MOZ_ASSERT(dataOffset >= 0);
// Compute where we'd actually seek to to read at readOffset
int64_t desiredOffset = dataOffset;
@ -1705,6 +1706,7 @@ MediaCacheStream::NotifyDataStarted(int64_t aOffset)
ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
NS_WARN_IF_FALSE(aOffset == mChannelOffset,
"Server is giving us unexpected offset");
MOZ_ASSERT(aOffset >= 0);
mChannelOffset = aOffset;
if (mStreamLength >= 0) {
// If we started reading at a certain offset, then for sure
@ -2134,23 +2136,28 @@ MediaCacheStream::Seek(int32_t aWhence, int64_t aOffset)
return NS_ERROR_FAILURE;
int64_t oldOffset = mStreamOffset;
int64_t newOffset = mStreamOffset;
switch (aWhence) {
case PR_SEEK_END:
if (mStreamLength < 0)
return NS_ERROR_FAILURE;
mStreamOffset = mStreamLength + aOffset;
newOffset = mStreamLength + aOffset;
break;
case PR_SEEK_CUR:
mStreamOffset += aOffset;
newOffset += aOffset;
break;
case PR_SEEK_SET:
mStreamOffset = aOffset;
newOffset = aOffset;
break;
default:
NS_ERROR("Unknown whence");
return NS_ERROR_FAILURE;
}
if (newOffset < 0)
return NS_ERROR_FAILURE;
mStreamOffset = newOffset;
CACHE_LOG(PR_LOG_DEBUG, ("Stream %p Seek to %lld", this, (long long)mStreamOffset));
gMediaCache->NoteSeek(this, oldOffset);
@ -2192,11 +2199,10 @@ MediaCacheStream::Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes)
break;
}
size = std::min(size, bytesRemaining);
// Clamp size until 64-bit file size issues (bug 500784) are fixed.
// Clamp size until 64-bit file size issues are fixed.
size = std::min(size, int64_t(INT32_MAX));
}
int32_t bytes;
int32_t cacheBlock = streamBlock < mBlocks.Length() ? mBlocks[streamBlock] : -1;
if (cacheBlock < 0) {
// We don't have a complete cached block here.
@ -2224,7 +2230,10 @@ MediaCacheStream::Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes)
// We can just use the data in mPartialBlockBuffer. In fact we should
// use it rather than waiting for the block to fill and land in
// the cache.
bytes = std::min<int64_t>(size, streamWithPartialBlock->mChannelOffset - mStreamOffset);
int64_t bytes = std::min<int64_t>(size, streamWithPartialBlock->mChannelOffset - mStreamOffset);
// Clamp bytes until 64-bit file size issues are fixed.
bytes = std::min(bytes, int64_t(INT32_MAX));
NS_ABORT_IF_FALSE(bytes >= 0 && bytes <= aCount, "Bytes out of range.");
memcpy(aBuffer,
reinterpret_cast<char*>(streamWithPartialBlock->mPartialBlockBuffer.get()) + offsetInStreamBlock, bytes);
if (mCurrentMode == MODE_METADATA) {
@ -2248,6 +2257,7 @@ MediaCacheStream::Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes)
gMediaCache->NoteBlockUsage(this, cacheBlock, mCurrentMode, TimeStamp::Now());
int64_t offset = cacheBlock*BLOCK_SIZE + offsetInStreamBlock;
int32_t bytes;
NS_ABORT_IF_FALSE(size >= 0 && size <= INT32_MAX, "Size out of range.");
nsresult rv = gMediaCache->ReadCacheFile(offset, aBuffer + count, int32_t(size), &bytes);
if (NS_FAILED(rv)) {
@ -2284,9 +2294,7 @@ MediaCacheStream::ReadAt(int64_t aOffset, char* aBuffer,
}
nsresult
MediaCacheStream::ReadFromCache(char* aBuffer,
int64_t aOffset,
int64_t aCount)
MediaCacheStream::ReadFromCache(char* aBuffer, int64_t aOffset, int64_t aCount)
{
ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
if (mClosed)
@ -2308,7 +2316,7 @@ MediaCacheStream::ReadFromCache(char* aBuffer,
return NS_ERROR_FAILURE;
}
size = std::min(size, bytesRemaining);
// Clamp size until 64-bit file size issues (bug 500784) are fixed.
// Clamp size until 64-bit file size issues are fixed.
size = std::min(size, int64_t(INT32_MAX));
}
@ -2319,7 +2327,10 @@ MediaCacheStream::ReadFromCache(char* aBuffer,
// We can just use the data in mPartialBlockBuffer. In fact we should
// use it rather than waiting for the block to fill and land in
// the cache.
bytes = std::min<int64_t>(size, mChannelOffset - streamOffset);
// Clamp bytes until 64-bit file size issues are fixed.
int64_t toCopy = std::min<int64_t>(size, mChannelOffset - streamOffset);
bytes = std::min(toCopy, int64_t(INT32_MAX));
NS_ABORT_IF_FALSE(bytes >= 0 && bytes <= toCopy, "Bytes out of range.");
memcpy(aBuffer + count,
reinterpret_cast<char*>(mPartialBlockBuffer.get()) + offsetInStreamBlock, bytes);
} else {

View File

@ -221,9 +221,6 @@ WMFAudioMFTManager::Output(int64_t aStreamOffset,
hr = buffer->Lock(&data, &maxLength, &currentLength);
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
int32_t numSamples = currentLength / mAudioBytesPerSample;
int32_t numFrames = numSamples / mAudioChannels;
// Sometimes when starting decoding, the AAC decoder gives us samples
// with a negative timestamp. AAC does usually have preroll (or encoder
// delay) encoded into its bitstream, but the amount encoded to the stream
@ -245,6 +242,13 @@ WMFAudioMFTManager::Output(int64_t aStreamOffset,
int32_t numFramesToStrip = 0;
sample->GetUINT32(MFSampleExtension_Discontinuity, &discontinuity);
if (mMustRecaptureAudioPosition || discontinuity) {
// Update the output type, in case this segment has a different
// rate. This also triggers on the first sample, which can have a
// different rate than is advertised in the container, and sometimes we
// don't get a MF_E_TRANSFORM_STREAM_CHANGE when the rate changes.
hr = UpdateOutputType();
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
mAudioFrameSum = 0;
LONGLONG timestampHns = 0;
hr = sample->GetSampleTime(&timestampHns);
@ -258,15 +262,10 @@ WMFAudioMFTManager::Output(int64_t aStreamOffset,
mAudioFrameOffset = 0;
}
mMustRecaptureAudioPosition = false;
// Also update the output type, in case this segment has a different
// rate. This also triggers on the first sample, which can have a
// different rate than is advertised in the container, and sometimes
// we don't get a MF_E_TRANSFORM_STREAM_CHANGE when the rate changes.
hr = UpdateOutputType();
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
}
MOZ_ASSERT(numFramesToStrip >= 0);
int32_t numSamples = currentLength / mAudioBytesPerSample;
int32_t numFrames = numSamples / mAudioChannels;
int32_t offset = std::min<int32_t>(numFramesToStrip, numFrames);
numFrames -= offset;
numSamples -= offset * mAudioChannels;

View File

@ -341,8 +341,6 @@ GMPChild::PreLoadLibraries(const std::string& aPluginPath)
// This must be in sorted order and lowercase!
static const char* whitelist[] =
{
"bcrypt.dll", // Used for OutputProtectionManager handshake
"crypt32.dll", // Used for OutputProtectionManager handshake
"d3d9.dll", // Create an `IDirect3D9` to get adapter information
"dxva2.dll", // Get monitor information
"msauddecmft.dll", // AAC decoder (on Windows 8)

View File

@ -33,6 +33,10 @@
#include "OMXCodecProxy.h"
#include "OmxDecoder.h"
#define LOG_TAG "OmxDecoder"
#include <android/log.h>
#define ALOG(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#ifdef PR_LOGGING
PRLogModuleInfo *gOmxDecoderLog;
#define LOG(type, msg...) PR_LOG(gOmxDecoderLog, type, (msg))
@ -66,7 +70,8 @@ OmxDecoder::OmxDecoder(MediaResource *aResource,
mIsVideoSeeking(false),
mAudioMetadataRead(false),
mAudioPaused(false),
mVideoPaused(false)
mVideoPaused(false),
mVideoLastFrameTime(-1)
{
mLooper = new ALooper;
mLooper->setName("OmxDecoder");
@ -556,14 +561,43 @@ bool OmxDecoder::ReadVideo(VideoFrame *aFrame, int64_t aTimeUs,
mIsVideoSeeking = true;
}
MediaSource::ReadOptions options;
options.setSeekTo(aTimeUs, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
err = mVideoSource->read(&mVideoBuffer, &options);
{
Mutex::Autolock autoLock(mSeekLock);
mIsVideoSeeking = false;
PostReleaseVideoBuffer(nullptr, FenceHandle());
MediaSource::ReadOptions::SeekMode seekMode;
// If the last timestamp of decoded frame is smaller than seekTime,
// seek to next key frame. Otherwise seek to the previos one.
if (mVideoLastFrameTime > aTimeUs || mVideoLastFrameTime == -1) {
seekMode = MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC;
} else {
seekMode = MediaSource::ReadOptions::SEEK_NEXT_SYNC;
}
bool findNextBuffer = true;
while (findNextBuffer) {
options.setSeekTo(aTimeUs, seekMode);
findNextBuffer = false;
err = mVideoSource->read(&mVideoBuffer, &options);
{
Mutex::Autolock autoLock(mSeekLock);
mIsVideoSeeking = false;
PostReleaseVideoBuffer(nullptr, FenceHandle());
}
// If there is no next Keyframe, jump to the previous key frame.
if (err == ERROR_END_OF_STREAM && seekMode == MediaSource::ReadOptions::SEEK_NEXT_SYNC) {
seekMode = MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC;
findNextBuffer = true;
{
Mutex::Autolock autoLock(mSeekLock);
mIsVideoSeeking = true;
}
continue;
} else if (err != OK) {
ALOG("Unexpected error when seeking to %lld", aTimeUs);
break;
}
if (mVideoBuffer->range_length() == 0) {
ReleaseVideoBuffer();
findNextBuffer = true;
}
}
aDoSeek = false;
} else {
err = mVideoSource->read(&mVideoBuffer);
@ -635,6 +669,7 @@ bool OmxDecoder::ReadVideo(VideoFrame *aFrame, int64_t aTimeUs,
if ((aKeyframeSkip && timeUs < aTimeUs) || length == 0) {
aFrame->mShouldSkip = true;
}
mVideoLastFrameTime = timeUs;
}
else if (err == INFO_FORMAT_CHANGED) {
// If the format changed, update our cached info.

View File

@ -60,6 +60,8 @@ class OmxDecoder : public OMXCodecProxy::EventListener {
int32_t mAudioChannels;
int32_t mAudioSampleRate;
int64_t mDurationUs;
int64_t mVideoLastFrameTime;
VideoFrame mVideoFrame;
AudioFrame mAudioFrame;
MP3FrameParser mMP3FrameParser;

View File

@ -123,9 +123,6 @@ this.SystemMessagePermissionsTable = {
"nfc-manager-send-file": {
"nfc-manager": []
},
"nfc-powerlevel-change": {
"settings": ["read", "write"]
},
"wifip2p-pairing-request": { },
"first-run-with-sim": {
"settings": ["read", "write"]

View File

@ -102,6 +102,7 @@ namespace system {
#define USB_FUNC_ADB "adb"
#define USB_FUNC_MTP "mtp"
#define USB_FUNC_NONE "none"
#define USB_FUNC_RNDIS "rndis"
#define USB_FUNC_UMS "mass_storage"
@ -528,6 +529,13 @@ SetUsbFunction(const char* aUsbFunc)
char oldSysUsbConfig[PROPERTY_VALUE_MAX];
property_get(SYS_USB_CONFIG, oldSysUsbConfig, "");
if (strcmp(oldSysUsbConfig, USB_FUNC_NONE) == 0) {
// It's quite possible that sys.usb.config may have the value "none". We
// convert that to an empty string here, and at the end we convert the
// empty string back to "none".
oldSysUsbConfig[0] = '\0';
}
if (IsUsbFunctionEnabled(oldSysUsbConfig, aUsbFunc)) {
// The function is already configured. Nothing else to do.
DBG("SetUsbFunction('%s') - already set - nothing to do", aUsbFunc);
@ -583,6 +591,10 @@ SetUsbFunction(const char* aUsbFunc)
return;
}
if (newSysUsbConfig[0] == '\0') {
// Convert the empty string back to the string "none"
strlcpy(newSysUsbConfig, USB_FUNC_NONE, sizeof(newSysUsbConfig));
}
LOG("SetUsbFunction(%s) %s from '%s' to '%s'", aUsbFunc, SYS_USB_CONFIG,
oldSysUsbConfig, newSysUsbConfig);
property_set(SYS_USB_CONFIG, newSysUsbConfig);

View File

@ -17,7 +17,7 @@ support-files =
localStorageCommon.js
[test_appIsolation.html]
skip-if = buildapp == 'b2g' || toolkit == 'android' #bug 793211 # b2g(needs https to work) b2g-debug(needs https to work) b2g-desktop(needs https to work)
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s #bug 793211 # b2g(needs https to work) b2g-debug(needs https to work) b2g-desktop(needs https to work)
[test_brokenUTF-16.html]
[test_bug600307-DBOps.html]
[test_bug746272-1.html]

View File

@ -1,5 +1,6 @@
[DEFAULT]
skip-if = os == "linux" && e10s && debug # bug 1091322 - wallpaper over an e10s crash
skip-if = os == "android" || toolkit == "gonk" || e10s
support-files =
file_app.sjs
file_app.template.webapp

View File

@ -1279,6 +1279,10 @@ EventRunnable::WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
mProxy->mSeenUploadLoadStart = false;
}
else {
if (!mProxy->mSeenLoadStart) {
// We've already dispatched premature abort events.
return true;
}
mProxy->mSeenLoadStart = false;
}
}
@ -2404,7 +2408,9 @@ XMLHttpRequest::UpdateState(const StateData& aStateData,
bool aUseCachedArrayBufferResponse)
{
if (aUseCachedArrayBufferResponse) {
MOZ_ASSERT(JS_IsArrayBufferObject(mStateData.mResponse.toObjectOrNull()));
MOZ_ASSERT(mStateData.mResponse.isObject() &&
JS_IsArrayBufferObject(&mStateData.mResponse.toObject()));
JS::Rooted<JS::Value> response(mWorkerPrivate->GetJSContext(),
mStateData.mResponse);
mStateData = aStateData;

View File

@ -447,7 +447,8 @@ nsHTMLEditRules::AfterEditInner(EditAction action,
res = PromoteRange(mDocChangeRange, action);
NS_ENSURE_SUCCESS(res, res);
// if we did a ranged deletion, make sure we have a place to put caret.
// if we did a ranged deletion or handling backspace key, make sure we have
// a place to put caret.
// Note we only want to do this if the overall operation was deletion,
// not if deletion was done along the way for EditAction::loadHTML, EditAction::insertText, etc.
// That's why this is here rather than DidDeleteSelection().
@ -2045,6 +2046,10 @@ nsHTMLEditRules::WillDeleteSelection(Selection* aSelection,
res = InsertBRIfNeeded(aSelection);
NS_ENSURE_SUCCESS(res, res);
// Remember that we did a ranged delete for the benefit of
// AfterEditInner().
mDidRangedDelete = true;
return NS_OK;
}

View File

@ -140,6 +140,7 @@ skip-if = os != "win"
[test_bug998188.html]
[test_bug1026397.html]
[test_bug1067255.html]
[test_bug1094000.html]
skip-if = e10s
[test_CF_HTML_clipboard.html]
[test_contenteditable_focus.html]

View File

@ -0,0 +1,104 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1094000
-->
<head>
<title>Test for Bug 1094000</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1094000">Mozilla Bug 1094000</a>
<p id="display"></p>
<div id="content">
<div id="editor0" contenteditable></div>
<div id="editor1" contenteditable><br></div>
<div id="editor2" contenteditable>a</div>
<div id="editor3" contenteditable>b</div>
<div id="editor4" contenteditable>c</div>
<div id="editor5" contenteditable>d</div>
<div id="editor6" contenteditable>e</div>
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 1094000 **/
SimpleTest.waitForExplicitFinish();
const kIsLinux = navigator.platform.indexOf("Linux") == 0;
function runTests()
{
var editor0 = document.getElementById("editor0");
var editor1 = document.getElementById("editor1");
var editor2 = document.getElementById("editor2");
var editor3 = document.getElementById("editor3");
var editor4 = document.getElementById("editor4");
var editor5 = document.getElementById("editor5");
var editor6 = document.getElementById("editor6");
ok(editor1.getBoundingClientRect().height - editor0.getBoundingClientRect().height > 1,
"an editor having a <br> element and an empty editor shouldn't be same height");
ok(Math.abs(editor1.getBoundingClientRect().height - editor2.getBoundingClientRect().height) <= 1,
"an editor having only a <br> element and an editor having \"a\" should be same height");
editor2.focus();
synthesizeKey("VK_RIGHT", {});
synthesizeKey("VK_BACK_SPACE", {});
is(editor2.innerHTML, "<br>",
"an editor which had \"a\" should have only <br> element after Backspace keypress");
ok(Math.abs(editor2.getBoundingClientRect().height - editor1.getBoundingClientRect().height) <= 1,
"an editor whose content was removed by Backspace key should have a place to put a caret");
editor3.focus();
synthesizeKey("VK_LEFT", {});
synthesizeKey("VK_DELETE", {});
is(editor3.innerHTML, "<br>",
"an editor which had \"b\" should have only <br> element after Delete keypress");
ok(Math.abs(editor3.getBoundingClientRect().height - editor1.getBoundingClientRect().height) <= 1,
"an editor whose content was removed by Delete key should have a place to put a caret");
editor4.focus();
window.getSelection().selectAllChildren(editor4);
synthesizeKey("VK_BACK_SPACE", {});
is(editor4.innerHTML, "<br>",
"an editor which had \"c\" should have only <br> element after removing selected text with Backspace key");
ok(Math.abs(editor4.getBoundingClientRect().height - editor1.getBoundingClientRect().height) <= 1,
"an editor whose content was selected and removed by Backspace key should have a place to put a caret");
editor5.focus();
window.getSelection().selectAllChildren(editor5);
synthesizeKey("VK_DELETE", {});
is(editor5.innerHTML, "<br>",
"an editor which had \"d\" should have only <br> element after removing selected text with Delete key");
ok(Math.abs(editor5.getBoundingClientRect().height - editor1.getBoundingClientRect().height) <= 1,
"an editor whose content was selected and removed by Delete key should have a place to put a caret");
editor6.focus();
window.getSelection().selectAllChildren(editor6);
synthesizeKey("x", { accelKey: true });
is(editor6.innerHTML, "<br>",
"an editor which had \"e\" should have only <br> element after removing selected text by \"Cut\"");
ok(Math.abs(editor6.getBoundingClientRect().height - editor1.getBoundingClientRect().height) <= 1,
"an editor whose content was selected and removed by \"Cut\" should have a place to put a caret");
editor0.focus();
synthesizeKey("VK_BACK_SPACE", {});
is(editor0.innerHTML, "",
"an empty editor should keep being empty even if Backspace key is pressed");
synthesizeKey("VK_DELETE", {});
is(editor0.innerHTML, "",
"an empty editor should keep being empty even if Delete key is pressed");
SimpleTest.finish();
}
SimpleTest.waitForFocus(runTests);
</script>
</pre>
</body>
</html>

View File

@ -148,7 +148,9 @@ However, on the main thread, web content might be running Javascript code that p
Scroll changes driven from the main thread are just as legitimate and need to be propagated to the compositor thread, so that the visual display updates in response.
Because the cross-thread messaging is asynchronous, reconciling the two types of scroll changes is a tricky problem.
Our design solves this using various flags and generation counters that ensures compositor-driven scroll changes never overwrite content-driven scroll changes - this behaviour is usually the desired outcome.
Our design solves this using various flags and generation counters.
The general heuristic we have is that content-driven scroll position changes (e.g. scrollTo from JS) are never lost.
For instance, if the user is doing an async scroll with their finger and content does a scrollTo in the middle, then some of the async scroll would occur before the "jump" and the rest after the "jump".
### Content preventing default behaviour of input events
@ -165,3 +167,116 @@ The way the APZ implementation deals with this is that upon receiving a touch ev
It also schedules a 300ms timeout during which content is allowed to prevent scrolling.
There is an API that allows the main-thread event dispatching code to notify the APZ as to whether or not the default action should be prevented.
If the APZ content response timeout expires, or if the main-thread event dispatching code notifies the APZ of the preventDefault status, then the APZ continues with the processing of the events (which may involve discarding the events).
## Technical details
This section describes various pieces of the APZ code, and goes into more specific detail on APIs and code than the previous sections.
The primary purpose of this section is to help people who plan on making changes to the code, while also not going into so much detail that it needs to be updated with every patch.
### Overall flow of input events
This section describes how input events flow through the APZ code.
<ol>
<li value="1">
Input events arrive from the hardware/widget code into the APZ via APZCTreeManager::ReceiveInputEvent.
The thread that invokes this is called the input thread, and may or may not be the same as the Gecko main thread.
</li>
<li value="2">
Conceptually the first thing that the APZCTreeManager does is to group these events into "input blocks".
An input block is a contiguous set of events that get handled together.
For example with touch events, all events following a touchstart up to but not including the next touchstart are in the same block.
All of the events in a given block will go to the same APZC instance and will either all be processed or all be dropped.
</li>
<li value="3">
Using the first event in the input block, the APZCTreeManager does a hit-test to see which APZC it hits.
If no APZC is hit, the events are discarded and we jump to step 6.
Otherwise, the input block is tagged with the APZC and put into a global APZ input queue.
</li>
<li value="4">
<ol>
<li value="i">
If the input events are not touch events, or if the APZC is for content without touch listeners, any available events in the input block are processed.
These may trigger behaviours like scrolling or tap gestures.
</li>
<li value="ii">
If the input events are touch events and the APZC is for content with touch listeners, the events are left in the queue and a 300ms timeout is initiated.
If the timeout expires before step 9 is completed, the APZ assumes the input block was not cancelled and processes them as part of step 10.
</li>
</ol>
</li>
<li value="5">
The call stack unwinds back to APZCTreeManager::ReceiveInputEvent, which does an in-place modification of the input event so that any async transforms are removed.
</li>
<li value="6">
The call stack unwinds back to the widget code that called ReceiveInputEvent.
This code now has the event in the coordinate space Gecko is expecting, and so can dispatch it to the Gecko main thread.
</li>
<li value="7">
Gecko performs its own usual hit-testing and event dispatching for the event.
As part of this, it records whether any touch listeners cancelled the input block by calling preventDefault().
</li>
<li value="8">
The call stack unwinds back to the widget code, which sends a notification to the APZ code by calling APZCTreeManager::ContentReceivedTouch on the input thread.
This happens only once per input block.
</li>
<li value="9">
<ol>
<li value="i">
If the events were processed as part of step 4(i), the call to ContentReceivedTouch is ignored and step 10 is skipped.
</li>
<li value="ii">
If events were queued as part of step 4(ii), and steps 5-8 take less than 300ms, the ContentReceivedTouch call marks the input block ready for processing.
</li>
<li value="iii">
If events were queued as part of step 4(ii), but steps 5-8 take longer than 300ms, the ContentReceivedTouch will be ignored and step 10 will already have happened.
</li>
</ol>
</li>
<li value="10">
If events were queued as part of step 4(ii) they are now either processed (if the input block was not cancelled, or if the timeout expired) or dropped (if it was cancelled).
Processing the events may trigger behaviours like scrolling or tap gestures.
</li>
</ol>
If the CSS touch-action property is enabled, the above steps are modified as follows:
<ul>
<li>
In step 4, the APZC also requires the allowed touch-action behaviours for the input event. This is not available yet, so the events are always queued.
</li>
<li>
In step 6, the widget code determines the content element at the point under the input element, and notifies the APZ code of the allowed touch-action behaviours.
This is done via a call to APZCTreeManager::SetAllowedTouchBehavior on the input thread.
</li>
</ul>
#### Threading considerations
The bulk of the input processing in the APZ code happens on what we call "the input thread".
In practice the input thread could be the Gecko main thread, the compositor thread, or some other thread.
There are obvious downsides to using the Gecko main thread - that is, "asynchronous" panning and zooming is not really asynchronous as input events can only be processed while Gecko is idle.
However, this is the current state of things on B2G and Metro.
Using the compositor thread as the input thread could work on some platforms, but may be inefficient on others.
For example, on Android (Fennec) we receive input events from the system on a dedicated UI thread.
We would have to redispatch the input events to the compositor thread if we wanted to the input thread to be the same as the compositor thread.
This introduces a potential for higher latency, particularly if the compositor does any blocking operations - blocking SwapBuffers operations, for example.
As a result, the APZ code itself does not assume that the input thread will be the same as the Gecko main thread or the compositor thread.
#### Active vs. inactive scrollframes
The number of scrollframes on a page is potentially unbounded.
However, we do not want to create a separate layer for each scrollframe right away, as this would require large amounts of memory.
Therefore, scrollframes as designated as either "active" or "inactive".
Active scrollframes are the ones that do have their contents put on a separate layer (or set of layers), and inactive ones do not.
Consider a page with a scrollframe that is initially inactive.
When layout generates the layers for this page, it inserts a "scrollinfo" layer into the layer tree to let the APZ know that there is potentially scrollable content there.
The scrollinfo layer is an empty ContainerLayer, which does not require much extra memory.
The composition bounds of this scrollinfo layer are used on the compositor for hit-testing, and a "placeholder" APZC is created for this scrollframe.
When the user starts interacting with that content, the hit-test in the APZ code finds the placeholder APZC and starts routing it the events as usual.
The APZC eventually sends a repaint request to the main thread, and that repaint request sets a displayport on the scrollframe.
Setting the displayport activates the scrollframe and causes it to get pushed onto a separate layer (or set of layers).
This model imples that when the user initially attempts to scroll an inactive scrollframe, it will not initially scroll visually.
(This is because although the APZC is tracking the events and updating scroll position, there is no layer to which it can apply the async scroll offset.)
Only after the round-trip to the gecko thread is complete is there a layer for async scrolling to actually occur.
At that point the scrollframe will visually "jump" to the correct scroll offset.

View File

@ -485,6 +485,12 @@ BasicLayerManager::EndTransactionInternal(DrawPaintedLayerCallback aCallback,
mTransactionIncomplete = false;
if (mRoot) {
if (aFlags & END_NO_COMPOSITE) {
// Apply pending tree updates before recomputing effective
// properties.
mRoot->ApplyPendingUpdatesToSubtree();
}
// Need to do this before we call ApplyDoubleBuffering,
// which depends on correct effective transforms
if (mTarget) {
@ -499,12 +505,6 @@ BasicLayerManager::EndTransactionInternal(DrawPaintedLayerCallback aCallback,
if (mRoot->GetMaskLayer()) {
ToData(mRoot->GetMaskLayer())->Validate(aCallback, aCallbackData, nullptr);
}
if (aFlags & END_NO_COMPOSITE) {
// Apply pending tree updates before recomputing effective
// properties.
mRoot->ApplyPendingUpdatesToSubtree();
}
}
if (mTarget && mRoot &&

View File

@ -584,7 +584,7 @@ gfxDWriteFont::ProvidesGlyphWidths() const
}
int32_t
gfxDWriteFont::GetGlyphWidth(gfxContext *aCtx, uint16_t aGID)
gfxDWriteFont::GetGlyphWidth(DrawTarget& aDrawTarget, uint16_t aGID)
{
if (!mGlyphWidths) {
mGlyphWidths = new nsDataHashtable<nsUint32HashKey,int32_t>(128);

View File

@ -54,7 +54,7 @@ public:
virtual bool ProvidesGlyphWidths() const;
virtual int32_t GetGlyphWidth(gfxContext *aCtx, uint16_t aGID);
virtual int32_t GetGlyphWidth(DrawTarget& aDrawTarget, uint16_t aGID);
virtual mozilla::TemporaryRef<mozilla::gfx::GlyphRenderingOptions>
GetGlyphRenderingOptions(const TextRunDrawParams* aRunParams = nullptr) MOZ_OVERRIDE;

View File

@ -168,7 +168,7 @@ gfxFT2FontBase::GetGlyph(uint32_t unicode, uint32_t variation_selector)
}
int32_t
gfxFT2FontBase::GetGlyphWidth(gfxContext *aCtx, uint16_t aGID)
gfxFT2FontBase::GetGlyphWidth(DrawTarget& aDrawTarget, uint16_t aGID)
{
cairo_text_extents_t extents;
GetGlyphExtents(aGID, &extents);

View File

@ -25,7 +25,7 @@ public:
virtual bool ProvidesGetGlyph() const { return true; }
virtual uint32_t GetGlyph(uint32_t unicode, uint32_t variation_selector);
virtual bool ProvidesGlyphWidths() const { return true; }
virtual int32_t GetGlyphWidth(gfxContext *aCtx, uint16_t aGID);
virtual int32_t GetGlyphWidth(DrawTarget& aDrawTarget, uint16_t aGID);
cairo_scaled_font_t *CairoScaledFont() { return mScaledFont; };
virtual bool SetupCairoFont(gfxContext *aContext);

View File

@ -791,7 +791,7 @@ gfxFont::GetGlyphHAdvance(gfxContext *aCtx, uint16_t aGID)
return 0;
}
if (ProvidesGlyphWidths()) {
return GetGlyphWidth(aCtx, aGID) / 65536.0;
return GetGlyphWidth(*aCtx->GetDrawTarget(), aGID) / 65536.0;
}
if (mFUnitsConvFactor == 0.0f) {
GetMetrics(eHorizontal);
@ -806,7 +806,7 @@ gfxFont::GetGlyphHAdvance(gfxContext *aCtx, uint16_t aGID)
if (!shaper->Initialize()) {
return 0;
}
return shaper->GetGlyphHAdvance(aCtx, aGID) / 65536.0;
return shaper->GetGlyphHAdvance(aGID) / 65536.0;
}
/*static*/

View File

@ -1267,6 +1267,9 @@ class gfxFont {
friend class gfxHarfBuzzShaper;
friend class gfxGraphiteShaper;
protected:
typedef mozilla::gfx::DrawTarget DrawTarget;
public:
nsrefcnt AddRef(void) {
NS_PRECONDITION(int32_t(mRefCnt) >= 0, "illegal refcnt");
@ -1709,7 +1712,7 @@ public:
virtual FontType GetType() const = 0;
virtual mozilla::TemporaryRef<mozilla::gfx::ScaledFont> GetScaledFont(mozilla::gfx::DrawTarget *aTarget)
virtual mozilla::TemporaryRef<mozilla::gfx::ScaledFont> GetScaledFont(DrawTarget* aTarget)
{ return gfxPlatform::GetPlatform()->GetScaledFontForFont(aTarget, this); }
bool KerningDisabled() {
@ -1820,7 +1823,7 @@ protected:
// The return value is interpreted as a horizontal advance in 16.16 fixed
// point format.
virtual int32_t GetGlyphWidth(gfxContext *aCtx, uint16_t aGID) {
virtual int32_t GetGlyphWidth(DrawTarget& aDrawTarget, uint16_t aGID) {
return -1;
}

View File

@ -460,7 +460,7 @@ gfxGDIFont::GetGlyph(uint32_t aUnicode, uint32_t aVarSelector)
}
int32_t
gfxGDIFont::GetGlyphWidth(gfxContext *aCtx, uint16_t aGID)
gfxGDIFont::GetGlyphWidth(DrawTarget& aDrawTarget, uint16_t aGID)
{
if (!mGlyphWidths) {
mGlyphWidths = new nsDataHashtable<nsUint32HashKey,int32_t>(128);
@ -471,7 +471,7 @@ gfxGDIFont::GetGlyphWidth(gfxContext *aCtx, uint16_t aGID)
return width;
}
DCFromContext dc(aCtx);
DCFromDrawTarget dc(aDrawTarget);
AutoSelectFont fs(dc, GetHFONT());
int devWidth;

View File

@ -60,7 +60,7 @@ public:
virtual bool ProvidesGlyphWidths() const { return true; }
// get hinted glyph width in pixels as 16.16 fixed-point value
virtual int32_t GetGlyphWidth(gfxContext *aCtx, uint16_t aGID);
virtual int32_t GetGlyphWidth(DrawTarget& aDrawTarget, uint16_t aGID);
virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
FontCacheSizes* aSizes) const;

View File

@ -50,7 +50,8 @@ gfxGraphiteShaper::GrGetAdvance(const void* appFontHandle, uint16_t glyphid)
{
const CallbackData *cb =
static_cast<const CallbackData*>(appFontHandle);
return FixedToFloat(cb->mFont->GetGlyphWidth(cb->mContext, glyphid));
return FixedToFloat(cb->mFont->GetGlyphWidth(*cb->mContext->GetDrawTarget(),
glyphid));
}
static inline uint32_t

View File

@ -184,8 +184,7 @@ struct GlyphMetrics {
};
hb_position_t
gfxHarfBuzzShaper::GetGlyphHAdvance(gfxContext *aContext,
hb_codepoint_t glyph) const
gfxHarfBuzzShaper::GetGlyphHAdvance(hb_codepoint_t glyph) const
{
// font did not implement GetGlyphWidth, so get an unhinted value
// directly from the font tables
@ -208,8 +207,7 @@ gfxHarfBuzzShaper::GetGlyphHAdvance(gfxContext *aContext,
}
hb_position_t
gfxHarfBuzzShaper::GetGlyphVAdvance(gfxContext *aContext,
hb_codepoint_t glyph) const
gfxHarfBuzzShaper::GetGlyphVAdvance(hb_codepoint_t glyph) const
{
if (!mVmtxTable) {
// Must be a "vertical" font that doesn't actually have vertical metrics;
@ -243,10 +241,9 @@ gfxHarfBuzzShaper::HBGetGlyphHAdvance(hb_font_t *font, void *font_data,
static_cast<const gfxHarfBuzzShaper::FontCallbackData*>(font_data);
gfxFont *gfxfont = fcd->mShaper->GetFont();
if (gfxfont->ProvidesGlyphWidths()) {
return gfxfont->GetGlyphWidth(fcd->mContext, glyph);
} else {
return fcd->mShaper->GetGlyphHAdvance(fcd->mContext, glyph);
return gfxfont->GetGlyphWidth(*fcd->mContext->GetDrawTarget(), glyph);
}
return fcd->mShaper->GetGlyphHAdvance(glyph);
}
/* static */
@ -258,10 +255,9 @@ gfxHarfBuzzShaper::HBGetGlyphVAdvance(hb_font_t *font, void *font_data,
static_cast<const gfxHarfBuzzShaper::FontCallbackData*>(font_data);
gfxFont *gfxfont = fcd->mShaper->GetFont();
if (gfxfont->ProvidesGlyphWidths()) {
return gfxfont->GetGlyphWidth(fcd->mContext, glyph);
} else {
return fcd->mShaper->GetGlyphVAdvance(fcd->mContext, glyph);
return gfxfont->GetGlyphWidth(*fcd->mContext->GetDrawTarget(), glyph);
}
return fcd->mShaper->GetGlyphVAdvance(glyph);
}
/* static */
@ -296,15 +292,15 @@ gfxHarfBuzzShaper::HBGetGlyphVOrigin(hb_font_t *font, void *font_data,
{
const gfxHarfBuzzShaper::FontCallbackData *fcd =
static_cast<const gfxHarfBuzzShaper::FontCallbackData*>(font_data);
fcd->mShaper->GetGlyphVOrigin(fcd->mContext, glyph, x, y);
fcd->mShaper->GetGlyphVOrigin(glyph, x, y);
return true;
}
void
gfxHarfBuzzShaper::GetGlyphVOrigin(gfxContext *aContext, hb_codepoint_t aGlyph,
gfxHarfBuzzShaper::GetGlyphVOrigin(hb_codepoint_t aGlyph,
hb_position_t *aX, hb_position_t *aY) const
{
*aX = -0.5 * GetGlyphHAdvance(aContext, aGlyph);
*aX = -0.5 * GetGlyphHAdvance(aGlyph);
if (mVORGTable) {
// We checked in Initialize() that the VORG table is safely readable,

View File

@ -42,13 +42,11 @@ public:
hb_codepoint_t variation_selector) const;
// get harfbuzz glyph advance, in font design units
hb_position_t GetGlyphHAdvance(gfxContext *aContext,
hb_codepoint_t glyph) const;
hb_position_t GetGlyphHAdvance(hb_codepoint_t glyph) const;
hb_position_t GetGlyphVAdvance(gfxContext *aContext,
hb_codepoint_t glyph) const;
hb_position_t GetGlyphVAdvance(hb_codepoint_t glyph) const;
void GetGlyphVOrigin(gfxContext *aContext, hb_codepoint_t aGlyph,
void GetGlyphVOrigin(hb_codepoint_t aGlyph,
hb_position_t *aX, hb_position_t *aY) const;
// get harfbuzz horizontal advance in 16.16 fixed point format.

View File

@ -4,10 +4,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ArrayUtils.h"
#include "gfxWindowsPlatform.h"
#include "cairo.h"
#include "mozilla/ArrayUtils.h"
#include "gfxImageSurface.h"
#include "gfxWindowsSurface.h"
@ -80,6 +81,31 @@ using namespace mozilla::layers;
using namespace mozilla::widget;
using namespace mozilla::image;
DCFromDrawTarget::DCFromDrawTarget(DrawTarget& aDrawTarget)
{
mDC = nullptr;
if (aDrawTarget.GetBackendType() == BackendType::CAIRO) {
cairo_surface_t *surf = (cairo_surface_t*)
aDrawTarget.GetNativeSurface(NativeSurfaceType::CAIRO_SURFACE);
cairo_surface_type_t surfaceType = cairo_surface_get_type(surf);
if (surfaceType == CAIRO_SURFACE_TYPE_WIN32 ||
surfaceType == CAIRO_SURFACE_TYPE_WIN32_PRINTING) {
mDC = cairo_win32_surface_get_dc(surf);
mNeedsRelease = false;
SaveDC(mDC);
cairo_t* ctx = (cairo_t*)
aDrawTarget.GetNativeSurface(NativeSurfaceType::CAIRO_CONTEXT);
cairo_scaled_font_t* scaled = cairo_get_scaled_font(ctx);
cairo_win32_scaled_font_select_font(scaled, mDC);
}
if (!mDC) {
mDC = GetDC(nullptr);
SetGraphicsMode(mDC, GM_ADVANCED);
mNeedsRelease = true;
}
}
}
#ifdef CAIRO_HAS_D2D_SURFACE
static const char *kFeatureLevelPref =
@ -1531,7 +1557,7 @@ bool DoesD3D11DeviceWork(ID3D11Device *device)
#endif
return false;
}
if (displayLinkModuleVersion <= GFX_DRIVER_VERSION(8,6,1,36484)) {
if (displayLinkModuleVersion <= V(8,6,1,36484)) {
#if defined(MOZ_CRASHREPORTER)
CrashReporter::AppendAppNotesToCrashReport(NS_LITERAL_CSTRING("DisplayLink: too old version\n"));
#endif

View File

@ -20,8 +20,8 @@
#include "gfxDWriteFonts.h"
#endif
#include "gfxPlatform.h"
#include "gfxContext.h"
#include "gfxTypes.h"
#include "mozilla/Attributes.h"
#include "nsTArray.h"
#include "nsDataHashtable.h"
@ -44,6 +44,9 @@
#endif
namespace mozilla {
namespace gfx {
class DrawTarget;
}
namespace layers {
class DeviceManagerD3D9;
class ReadbackManagerD3D11;
@ -55,44 +58,31 @@ struct IDXGIAdapter1;
class nsIMemoryReporter;
// Utility to get a Windows HDC from a thebes context,
// used by both GDI and Uniscribe font shapers
struct DCFromContext {
DCFromContext(gfxContext *aContext) {
dc = nullptr;
nsRefPtr<gfxASurface> aSurface = aContext->CurrentSurface();
if (aSurface &&
(aSurface->GetType() == gfxSurfaceType::Win32 ||
aSurface->GetType() == gfxSurfaceType::Win32Printing))
{
dc = static_cast<gfxWindowsSurface*>(aSurface.get())->GetDC();
needsRelease = false;
SaveDC(dc);
cairo_scaled_font_t* scaled =
cairo_get_scaled_font(aContext->GetCairo());
cairo_win32_scaled_font_select_font(scaled, dc);
}
if (!dc) {
dc = GetDC(nullptr);
SetGraphicsMode(dc, GM_ADVANCED);
needsRelease = true;
}
}
/**
* Utility to get a Windows HDC from a Moz2D DrawTarget. If the DrawTarget is
* not backed by a HDC this will get the HDC for the screen device context
* instead.
*/
class MOZ_STACK_CLASS DCFromDrawTarget MOZ_FINAL
{
public:
DCFromDrawTarget(mozilla::gfx::DrawTarget& aDrawTarget);
~DCFromContext() {
if (needsRelease) {
ReleaseDC(nullptr, dc);
~DCFromDrawTarget() {
if (mNeedsRelease) {
ReleaseDC(nullptr, mDC);
} else {
RestoreDC(dc, -1);
RestoreDC(mDC, -1);
}
}
operator HDC () {
return dc;
return mDC;
}
HDC dc;
bool needsRelease;
private:
HDC mDC;
bool mNeedsRelease;
};
// ClearType parameters set by running ClearType tuner

View File

@ -19,7 +19,7 @@ interface nsIPrincipal;
* @version 0.1
* @see imagelib2
*/
[scriptable, builtinclass, uuid(710f22f0-558b-11e4-8ed6-0800200c9a66)]
[scriptable, builtinclass, uuid(dc61f0ea-4139-4c2a-ae69-cec82d33e089)]
interface imgIRequest : nsIRequest
{
/**
@ -83,6 +83,11 @@ interface imgIRequest : nsIRequest
*/
readonly attribute nsIURI URI;
/**
* The URI of the resource we ended up loading after all redirects, etc.
*/
readonly attribute nsIURI currentURI;
readonly attribute imgINotificationObserver notificationObserver;
readonly attribute string mimeType;

View File

@ -245,35 +245,6 @@ Decoder::AllocateFrame()
return rv;
}
void
Decoder::FlushInvalidations()
{
NS_ABORT_IF_FALSE(!HasDecoderError(),
"Not allowed to make more decoder calls after error!");
// If we've got an empty invalidation rect, we have nothing to do
if (mInvalidRect.IsEmpty())
return;
if (mObserver) {
#ifdef XP_MACOSX
// Bug 703231
// Because of high quality down sampling on mac we show scan lines while decoding.
// Bypass this problem by redrawing the border.
if (mImageMetadata.HasSize()) {
nsIntRect mImageBound(0, 0, mImageMetadata.GetWidth(), mImageMetadata.GetHeight());
mInvalidRect.Inflate(1);
mInvalidRect = mInvalidRect.Intersect(mImageBound);
}
#endif
mObserver->FrameChanged(&mInvalidRect);
}
// Clear the invalidation rectangle
mInvalidRect.SetEmpty();
}
void
Decoder::SetSizeOnImage()
{
@ -320,11 +291,6 @@ Decoder::PostFrameStart()
// We shouldn't already be mid-frame
NS_ABORT_IF_FALSE(!mInFrame, "Starting new frame but not done with old one!");
// We should take care of any invalidation region when wrapping up the
// previous frame
NS_ABORT_IF_FALSE(mInvalidRect.IsEmpty(),
"Start image frame with non-empty invalidation region!");
// Update our state to reflect the new frame
mFrameCount++;
mInFrame = true;
@ -334,11 +300,6 @@ Decoder::PostFrameStart()
// reported by the Image.
NS_ABORT_IF_FALSE(mFrameCount == mImage.GetNumFrames(),
"Decoder frame count doesn't match image's!");
// Fire notifications
if (mObserver) {
mObserver->OnStartFrame();
}
}
void
@ -363,9 +324,6 @@ Decoder::PostFrameStop(FrameBlender::FrameAlpha aFrameAlpha /* = FrameBlender::k
mCurrentFrame->SetBlendMethod(aBlendMethod);
mCurrentFrame->ImageUpdated(mCurrentFrame->GetRect());
// Flush any invalidations before we finish the frame
FlushInvalidations();
// Fire notifications
if (mObserver) {
mObserver->OnStopFrame();

View File

@ -69,14 +69,17 @@ public:
void FinishSharedDecoder();
/**
* Tells the decoder to flush any pending invalidations. This informs the image
* frame of its decoded region, and sends the appropriate OnDataAvailable call
* to consumers.
*
* This can be called any time when we're midway through decoding a frame,
* and must be called after finishing a frame (before starting a new one).
* Gets the invalidation region accumulated by the decoder so far, and clears
* the decoder's invalidation region. This means that each call to
* TakeInvalidRect() returns only the invalidation region accumulated since
* the last call to TakeInvalidRect().
*/
void FlushInvalidations();
nsIntRect TakeInvalidRect()
{
nsIntRect invalidRect = mInvalidRect;
mInvalidRect.SetEmpty();
return invalidRect;
}
// We're not COM-y, so we don't get refcounts by default
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Decoder)

View File

@ -484,10 +484,10 @@ RasterImage::RequestRefresh(const TimeStamp& aTime)
UpdateImageContainer();
// Explicitly call this on mStatusTracker so we're sure to not interfere
// with the decoding process
if (mStatusTracker)
mStatusTracker->FrameChanged(&res.dirtyRect);
if (mStatusTracker) {
mStatusTracker->SyncNotifyDifference(ImageStatusDiff::NoChange(),
res.dirtyRect);
}
}
if (res.animationFinished) {
@ -655,6 +655,17 @@ RasterImage::GetRequestedFrameIndex(uint32_t aWhichFrame) const
return aWhichFrame == FRAME_FIRST ? 0 : GetCurrentFrameIndex();
}
nsIntRect
RasterImage::GetFirstFrameRect()
{
if (mAnim) {
return mAnim->GetFirstFrameRefreshArea();
}
// Fall back to our size. This is implicitly zero-size if !mHasSize.
return nsIntRect(nsIntPoint(0,0), mSize);
}
//******************************************************************************
/* [notxpcom] boolean frameIsOpaque(in uint32_t aWhichFrame); */
NS_IMETHODIMP_(bool)
@ -1457,7 +1468,7 @@ RasterImage::ResetAnimation()
// Update display
if (mStatusTracker) {
nsIntRect rect = mAnim->GetFirstFrameRefreshArea();
mStatusTracker->FrameChanged(&rect);
mStatusTracker->SyncNotifyDifference(ImageStatusDiff::NoChange(), rect);
}
// Start the animation again. It may not have been running before, if
@ -1558,14 +1569,6 @@ RasterImage::AddSourceData(const char *aBuffer, uint32_t aCount)
rv = WriteToDecoder(aBuffer, aCount, DECODE_SYNC);
CONTAINER_ENSURE_SUCCESS(rv);
// We're not storing source data, so this data is probably coming straight
// from the network. In this case, we want to display data as soon as we
// get it, so we want to flush invalidations after every write.
nsRefPtr<Decoder> kungFuDeathGrip = mDecoder;
mInDecoder = true;
mDecoder->FlushInvalidations();
mInDecoder = false;
rv = FinishedSomeDecoding();
CONTAINER_ENSURE_SUCCESS(rv);
}
@ -2416,15 +2419,6 @@ RasterImage::SyncDecode()
DECODE_SYNC);
CONTAINER_ENSURE_SUCCESS(rv);
// When we're doing a sync decode, we want to get as much information from the
// image as possible. We've send the decoder all of our data, so now's a good
// time to flush any invalidations (in case we don't have all the data and what
// we got left us mid-frame).
nsRefPtr<Decoder> kungFuDeathGrip = mDecoder;
mInDecoder = true;
mDecoder->FlushInvalidations();
mInDecoder = false;
rv = FinishedSomeDecoding();
CONTAINER_ENSURE_SUCCESS(rv);
@ -2498,9 +2492,8 @@ RasterImage::NotifyNewScaledFrame()
if (mStatusTracker) {
// Send an invalidation so observers will repaint and can take advantage of
// the new scaled frame if possible.
// XXX(seth): Why does FrameChanged take a pointer and not a reference?
nsIntRect invalidationRect(0, 0, mSize.width, mSize.height);
mStatusTracker->FrameChanged(&invalidationRect);
nsIntRect rect(0, 0, mSize.width, mSize.height);
mStatusTracker->SyncNotifyDifference(ImageStatusDiff::NoChange(), rect);
}
}
@ -3001,9 +2994,12 @@ RasterImage::FinishedSomeDecoding(eShutdownIntent aIntent /* = eShutdownIntent_D
bool done = false;
bool wasSize = false;
nsIntRect invalidRect;
nsresult rv = NS_OK;
if (image->mDecoder) {
invalidRect = image->mDecoder->TakeInvalidRect();
if (request && request->mChunkCount && !image->mDecoder->IsSizeDecode()) {
Telemetry::Accumulate(Telemetry::IMAGE_DECODE_CHUNKS, request->mChunkCount);
}
@ -3046,6 +3042,17 @@ RasterImage::FinishedSomeDecoding(eShutdownIntent aIntent /* = eShutdownIntent_D
}
}
if (GetCurrentFrameIndex() > 0) {
// Don't send invalidations for animated frames after the first; let
// RequestRefresh take care of that.
invalidRect = nsIntRect();
}
if (mHasBeenDecoded && !invalidRect.IsEmpty()) {
// Don't send partial invalidations if we've been decoded before.
invalidRect = mDecoded ? GetFirstFrameRect()
: nsIntRect();
}
ImageStatusDiff diff =
request ? image->mStatusTracker->Difference(request->mStatusTracker)
: image->mStatusTracker->DecodeStateAsDifference();
@ -3058,13 +3065,15 @@ RasterImage::FinishedSomeDecoding(eShutdownIntent aIntent /* = eShutdownIntent_D
// FinishedSomeDecoding on the stack.
NS_WARNING("Recursively notifying in RasterImage::FinishedSomeDecoding!");
mStatusDiff.Combine(diff);
mInvalidRect.Union(invalidRect);
} else {
MOZ_ASSERT(mStatusDiff.IsNoChange(), "Shouldn't have an accumulated change at this point");
MOZ_ASSERT(mInvalidRect.IsEmpty(), "Shouldn't have an accumulated invalidation rect here");
while (!diff.IsNoChange()) {
while (!diff.IsNoChange() || !invalidRect.IsEmpty()) {
// Tell the observers what happened.
mNotifying = true;
image->mStatusTracker->SyncNotifyDifference(diff);
image->mStatusTracker->SyncNotifyDifference(diff, invalidRect);
mNotifying = false;
// Gather any status changes that may have occurred as a result of sending
@ -3072,6 +3081,8 @@ RasterImage::FinishedSomeDecoding(eShutdownIntent aIntent /* = eShutdownIntent_D
// notifications for them next.
diff = mStatusDiff;
mStatusDiff = ImageStatusDiff::NoChange();
invalidRect = mInvalidRect;
mInvalidRect = nsIntRect();
}
}
@ -3484,31 +3495,6 @@ RasterImage::DecodePool::DecodeSomeOfImage(RasterImage* aImg,
aImg->mDecodeRequest->mChunkCount += chunkCount;
}
// Flush invalidations (and therefore paint) now that we've decoded all the
// chunks we're going to.
//
// However, don't paint if:
//
// * This was an until-size decode. Until-size decodes are always followed
// by normal decodes, so don't bother painting.
//
// * The decoder flagged an error. The decoder may have written garbage
// into the output buffer; don't paint it to the screen.
//
// * We have all the source data. This disables progressive display of
// previously-decoded images, thus letting us finish decoding faster,
// since we don't waste time painting while we decode.
// Decoder::PostFrameStop() will flush invalidations once the decode is
// done.
if (aDecodeType != DECODE_TYPE_UNTIL_SIZE &&
!aImg->mDecoder->HasError() &&
!aImg->mHasSourceData) {
aImg->mInDecoder = true;
aImg->mDecoder->FlushInvalidations();
aImg->mInDecoder = false;
}
return NS_OK;
}

View File

@ -552,6 +552,8 @@ private:
uint32_t GetCurrentFrameIndex() const;
uint32_t GetRequestedFrameIndex(uint32_t aWhichFrame) const;
nsIntRect GetFirstFrameRect();
size_t SizeOfDecodedWithComputedFallbackIfHeap(gfxMemoryLocation aLocation,
MallocSizeOf aMallocSizeOf) const;
@ -662,6 +664,7 @@ private: // data
// Notification state. Used to avoid recursive notifications.
ImageStatusDiff mStatusDiff;
nsIntRect mInvalidRect;
bool mNotifying:1;
// Boolean flags (clustered together to conserve space):

View File

@ -571,8 +571,10 @@ VectorImage::SendInvalidationNotifications()
if (mStatusTracker) {
SurfaceCache::Discard(this);
mStatusTracker->FrameChanged(&nsIntRect::GetMaxSizedIntRect());
mStatusTracker->OnStopFrame();
ImageStatusDiff diff;
diff.diffState = FLAG_FRAME_STOPPED;
mStatusTracker->ApplyDifference(diff);
mStatusTracker->SyncNotifyDifference(diff, nsIntRect::GetMaxSizedIntRect());
}
}
@ -1119,17 +1121,11 @@ VectorImage::OnSVGDocumentLoaded()
// Tell *our* observers that we're done loading.
if (mStatusTracker) {
nsRefPtr<imgStatusTracker> clone = mStatusTracker->CloneForRecording();
imgDecoderObserver* observer = clone->GetDecoderObserver();
observer->OnStartContainer(); // Signal that width/height are available.
observer->FrameChanged(&nsIntRect::GetMaxSizedIntRect());
observer->OnStopFrame();
observer->OnStopDecode(NS_OK); // Unblock page load.
ImageStatusDiff diff = mStatusTracker->Difference(clone);
ImageStatusDiff diff;
diff.diffState = FLAG_HAS_SIZE | FLAG_FRAME_STOPPED | FLAG_DECODE_STOPPED |
FLAG_ONLOAD_UNBLOCKED;
mStatusTracker->ApplyDifference(diff);
mStatusTracker->SyncNotifyDifference(diff);
mStatusTracker->SyncNotifyDifference(diff, nsIntRect::GetMaxSizedIntRect());
}
EvaluateAnimation();

View File

@ -66,20 +66,6 @@ public:
*/
virtual void OnStartContainer() = 0;
/**
* Decode notification.
*
* Called when we know a frame has begun decoding.
*/
virtual void OnStartFrame() = 0;
/**
* Decode notification.
*
* called when there is more to paint.
*/
virtual void FrameChanged(const nsIntRect * aDirtyRect) = 0;
/**
* Decode notification.
*

View File

@ -40,14 +40,17 @@ using namespace mozilla;
using namespace mozilla::image;
#if defined(PR_LOGGING)
PRLogModuleInfo *
PRLogModuleInfo*
GetImgLog()
{
static PRLogModuleInfo *sImgLog;
static PRLogModuleInfo* sImgLog;
if (!sImgLog)
sImgLog = PR_NewLogModule("imgRequest");
return sImgLog;
}
#define LOG_TEST(level) (GetImgLog() && PR_LOG_TEST(GetImgLog(), (level)))
#else
#define LOG_TEST(level) false
#endif
NS_IMPL_ISUPPORTS(imgRequest,
@ -367,6 +370,21 @@ nsresult imgRequest::GetURI(ImageURL **aURI)
return NS_ERROR_FAILURE;
}
nsresult imgRequest::GetCurrentURI(nsIURI **aURI)
{
MOZ_ASSERT(aURI);
LOG_FUNC(GetImgLog(), "imgRequest::GetCurrentURI");
if (mCurrentURI) {
*aURI = mCurrentURI;
NS_ADDREF(*aURI);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
nsresult imgRequest::GetImageErrorCode()
{
return mImageErrorCode;
@ -1064,16 +1082,24 @@ imgRequest::OnRedirectVerifyCallback(nsresult result)
mTimedChannel = do_QueryInterface(mChannel);
mNewRedirectChannel = nullptr;
#if defined(PR_LOGGING)
nsAutoCString oldspec;
if (mCurrentURI)
mCurrentURI->GetSpec(oldspec);
LOG_MSG_WITH_PARAM(GetImgLog(), "imgRequest::OnChannelRedirect", "old", oldspec.get());
#endif
if (LOG_TEST(PR_LOG_DEBUG)) {
nsAutoCString spec;
if (mCurrentURI)
mCurrentURI->GetSpec(spec);
LOG_MSG_WITH_PARAM(GetImgLog(), "imgRequest::OnChannelRedirect", "old", spec.get());
}
// make sure we have a protocol that returns data rather than opens
// an external application, e.g. mailto:
mChannel->GetURI(getter_AddRefs(mCurrentURI));
if (LOG_TEST(PR_LOG_DEBUG)) {
nsAutoCString spec;
if (mCurrentURI)
mCurrentURI->GetSpec(spec);
LOG_MSG_WITH_PARAM(GetImgLog(), "imgRequest::OnChannelRedirect", "new", spec.get());
}
bool doesNotReturnData = false;
nsresult rv =
NS_URIChainHasFlags(mCurrentURI, nsIProtocolHandler::URI_DOES_NOT_RETURN_DATA,

View File

@ -137,6 +137,7 @@ public:
// OK to use on any thread.
nsresult GetURI(ImageURL **aURI);
nsresult GetCurrentURI(nsIURI **aURI);
nsresult GetImageErrorCode(void);

View File

@ -537,6 +537,14 @@ NS_IMETHODIMP imgRequestProxy::GetURI(nsIURI **aURI)
return NS_OK;
}
nsresult imgRequestProxy::GetCurrentURI(nsIURI **aURI)
{
if (!GetOwner())
return NS_ERROR_FAILURE;
return GetOwner()->GetCurrentURI(aURI);
}
nsresult imgRequestProxy::GetURI(ImageURL **aURI)
{
if (!mURI)

View File

@ -62,22 +62,6 @@ public:
tracker->RecordStartContainer(image);
}
virtual void OnStartFrame() MOZ_OVERRIDE
{
LOG_SCOPE(GetImgLog(), "imgStatusTrackerObserver::OnStartFrame");
nsRefPtr<imgStatusTracker> tracker = mTracker.get();
if (!tracker) { return; }
tracker->RecordStartFrame();
}
virtual void FrameChanged(const nsIntRect* dirtyRect) MOZ_OVERRIDE
{
LOG_SCOPE(GetImgLog(), "imgStatusTrackerObserver::FrameChanged");
nsRefPtr<imgStatusTracker> tracker = mTracker.get();
if (!tracker) { return; }
tracker->RecordFrameChanged(dirtyRect);
}
virtual void OnStopFrame() MOZ_OVERRIDE
{
LOG_SCOPE(GetImgLog(), "imgStatusTrackerObserver::OnStopFrame");
@ -159,7 +143,6 @@ imgStatusTracker::imgStatusTracker(const imgStatusTracker& aOther)
// - mProperties, because we don't need it and it'd just point at the same
// object
// - mConsumers, because we don't need to talk to consumers
// - mInvalidRect, because the point of it is to be fired off and reset
{
mTrackerObserver = new imgStatusTrackerObserver(this);
}
@ -370,7 +353,7 @@ imgStatusTracker::NotifyCurrentState(imgRequestProxy* proxy)
#define NOTIFY_IMAGE_OBSERVERS(func) \
do { \
ProxyArray::ForwardIterator iter(proxies); \
ProxyArray::ForwardIterator iter(aProxies); \
while (iter.HasMore()) { \
nsRefPtr<imgRequestProxy> proxy = iter.GetNext().get(); \
if (proxy && !proxy->NotificationsDeferred()) { \
@ -380,57 +363,57 @@ imgStatusTracker::NotifyCurrentState(imgRequestProxy* proxy)
} while (false);
/* static */ void
imgStatusTracker::SyncNotifyState(ProxyArray& proxies,
bool hasImage, uint32_t state,
nsIntRect& dirtyRect)
imgStatusTracker::SyncNotifyState(ProxyArray& aProxies,
bool aHasImage, uint32_t aState,
const nsIntRect& aDirtyRect)
{
MOZ_ASSERT(NS_IsMainThread());
// OnStartRequest
if (state & FLAG_REQUEST_STARTED)
if (aState & FLAG_REQUEST_STARTED)
NOTIFY_IMAGE_OBSERVERS(OnStartRequest());
// OnStartContainer
if (state & FLAG_HAS_SIZE)
if (aState & FLAG_HAS_SIZE)
NOTIFY_IMAGE_OBSERVERS(OnStartContainer());
// OnStartDecode
if (state & FLAG_DECODE_STARTED)
if (aState & FLAG_DECODE_STARTED)
NOTIFY_IMAGE_OBSERVERS(OnStartDecode());
// BlockOnload
if (state & FLAG_ONLOAD_BLOCKED)
if (aState & FLAG_ONLOAD_BLOCKED)
NOTIFY_IMAGE_OBSERVERS(BlockOnload());
if (hasImage) {
if (aHasImage) {
// OnFrameUpdate
// If there's any content in this frame at all (always true for
// vector images, true for raster images that have decoded at
// least one frame) then send OnFrameUpdate.
if (!dirtyRect.IsEmpty())
NOTIFY_IMAGE_OBSERVERS(OnFrameUpdate(&dirtyRect));
if (!aDirtyRect.IsEmpty())
NOTIFY_IMAGE_OBSERVERS(OnFrameUpdate(&aDirtyRect));
if (state & FLAG_FRAME_STOPPED)
if (aState & FLAG_FRAME_STOPPED)
NOTIFY_IMAGE_OBSERVERS(OnStopFrame());
// OnImageIsAnimated
if (state & FLAG_IS_ANIMATED)
if (aState & FLAG_IS_ANIMATED)
NOTIFY_IMAGE_OBSERVERS(OnImageIsAnimated());
}
// Send UnblockOnload before OnStopDecode and OnStopRequest. This allows
// observers that can fire events when they receive those notifications to do
// so then, instead of being forced to wait for UnblockOnload.
if (state & FLAG_ONLOAD_UNBLOCKED) {
if (aState & FLAG_ONLOAD_UNBLOCKED) {
NOTIFY_IMAGE_OBSERVERS(UnblockOnload());
}
if (state & FLAG_DECODE_STOPPED) {
NS_ABORT_IF_FALSE(hasImage, "stopped decoding without ever having an image?");
if (aState & FLAG_DECODE_STOPPED) {
MOZ_ASSERT(aHasImage, "Stopped decoding without ever having an image?");
NOTIFY_IMAGE_OBSERVERS(OnStopDecode());
}
if (state & FLAG_REQUEST_STOPPED) {
NOTIFY_IMAGE_OBSERVERS(OnStopRequest(state & FLAG_MULTIPART_STOPPED));
if (aState & FLAG_REQUEST_STOPPED) {
NOTIFY_IMAGE_OBSERVERS(OnStopRequest(aState & FLAG_MULTIPART_STOPPED));
}
}
@ -440,22 +423,6 @@ imgStatusTracker::Difference(imgStatusTracker* aOther) const
MOZ_ASSERT(aOther, "aOther cannot be null");
ImageStatusDiff diff;
diff.diffState = ~mState & aOther->mState;
// Only record partial invalidations if we haven't been decoded before.
// When images are re-decoded after discarding, we don't want to display
// partially decoded versions to the user.
const uint32_t combinedState = mState | aOther->mState;
const bool doInvalidations = !(mState & FLAG_DECODE_STOPPED) ||
aOther->mState & FLAG_DECODE_STOPPED ||
combinedState & FLAG_HAS_ERROR;
// Record and reset the invalid rectangle.
// XXX(seth): We shouldn't be resetting anything here; see bug 910441.
if (doInvalidations) {
diff.invalidRect = aOther->mInvalidRect;
aOther->mInvalidRect.SetEmpty();
}
return diff;
}
@ -476,18 +443,15 @@ imgStatusTracker::ApplyDifference(const ImageStatusDiff& aDiff)
}
void
imgStatusTracker::SyncNotifyDifference(const ImageStatusDiff& diff)
imgStatusTracker::SyncNotifyDifference(const ImageStatusDiff& aDiff,
const nsIntRect& aInvalidRect /* = nsIntRect() */)
{
MOZ_ASSERT(NS_IsMainThread(), "Use mConsumers on main thread only");
LOG_SCOPE(GetImgLog(), "imgStatusTracker::SyncNotifyDifference");
nsIntRect invalidRect = mInvalidRect.Union(diff.invalidRect);
SyncNotifyState(mConsumers, !!mImage, aDiff.diffState, aInvalidRect);
SyncNotifyState(mConsumers, !!mImage, diff.diffState, invalidRect);
mInvalidRect.SetEmpty();
if (diff.diffState & FLAG_HAS_ERROR) {
if (aDiff.diffState & FLAG_HAS_ERROR) {
FireFailureNotification();
}
}
@ -648,14 +612,6 @@ imgStatusTracker::SendStartContainer(imgRequestProxy* aProxy)
aProxy->OnStartContainer();
}
void
imgStatusTracker::RecordStartFrame()
{
mInvalidRect.SetEmpty();
}
// No SendStartFrame since it's not observed below us.
void
imgStatusTracker::RecordStopFrame()
{
@ -746,23 +702,6 @@ imgStatusTracker::OnUnlockedDraw()
}
}
void
imgStatusTracker::RecordFrameChanged(const nsIntRect* aDirtyRect)
{
NS_ABORT_IF_FALSE(mImage,
"RecordFrameChanged called before we have an Image");
mInvalidRect = mInvalidRect.Union(*aDirtyRect);
}
void
imgStatusTracker::SendFrameChanged(imgRequestProxy* aProxy,
const nsIntRect* aDirtyRect)
{
MOZ_ASSERT(NS_IsMainThread());
if (!aProxy->NotificationsDeferred())
aProxy->OnFrameUpdate(aDirtyRect);
}
/* non-virtual sort-of-nsIRequestObserver methods */
void
imgStatusTracker::RecordStartRequest()
@ -895,22 +834,6 @@ imgStatusTracker::OnDiscard()
}
}
void
imgStatusTracker::FrameChanged(const nsIntRect* aDirtyRect)
{
MOZ_ASSERT(NS_IsMainThread());
RecordFrameChanged(aDirtyRect);
/* notify the kids */
ProxyArray::ForwardIterator iter(mConsumers);
while (iter.HasMore()) {
nsRefPtr<imgRequestProxy> proxy = iter.GetNext().get();
if (proxy) {
SendFrameChanged(proxy, aDirtyRect);
}
}
}
void
imgStatusTracker::OnStopFrame()
{

View File

@ -46,8 +46,7 @@ enum {
struct ImageStatusDiff
{
ImageStatusDiff()
: invalidRect()
, diffState(0)
: diffState(0)
{ }
static ImageStatusDiff NoChange() { return ImageStatusDiff(); }
@ -55,17 +54,14 @@ struct ImageStatusDiff
bool operator!=(const ImageStatusDiff& aOther) const { return !(*this == aOther); }
bool operator==(const ImageStatusDiff& aOther) const {
return aOther.invalidRect == invalidRect
&& aOther.diffState == diffState;
return aOther.diffState == diffState;
}
void Combine(const ImageStatusDiff& aOther) {
invalidRect = invalidRect.Union(aOther.invalidRect);
diffState |= aOther.diffState;
}
nsIntRect invalidRect;
uint32_t diffState;
uint32_t diffState;
};
} // namespace image
@ -179,7 +175,7 @@ public:
void RecordLoaded();
// Shorthand for recording all the decode notifications: StartDecode,
// StartFrame, DataAvailable, StopFrame, StopDecode.
// DataAvailable, StopFrame, StopDecode.
void RecordDecoded();
/* non-virtual imgDecoderObserver methods */
@ -189,10 +185,6 @@ public:
void SendStartDecode(imgRequestProxy* aProxy);
void RecordStartContainer(imgIContainer* aContainer);
void SendStartContainer(imgRequestProxy* aProxy);
void RecordStartFrame();
// No SendStartFrame since it's not observed below us.
void RecordFrameChanged(const nsIntRect* aDirtyRect);
void SendFrameChanged(imgRequestProxy* aProxy, const nsIntRect* aDirtyRect);
void RecordStopFrame();
void SendStopFrame(imgRequestProxy* aProxy);
void RecordStopDecode(nsresult statusg);
@ -219,7 +211,6 @@ public:
void OnDataAvailable();
void OnStopRequest(bool aLastPart, nsresult aStatus);
void OnDiscard();
void FrameChanged(const nsIntRect* aDirtyRect);
void OnUnlockedDraw();
// This is called only by VectorImage, and only to ensure tests work
// properly. Do not use it.
@ -265,9 +256,8 @@ public:
// Notify for the changes captured in an ImageStatusDiff. Because this may
// result in recursive notifications, no decoding locks may be held.
// Called on the main thread only.
void SyncNotifyDifference(const mozilla::image::ImageStatusDiff& aDiff);
nsIntRect GetInvalidRect() const { return mInvalidRect; }
void SyncNotifyDifference(const mozilla::image::ImageStatusDiff& aDiff,
const nsIntRect& aInvalidRect = nsIntRect());
private:
typedef nsTObserverArray<mozilla::WeakPtr<imgRequestProxy>> ProxyArray;
@ -282,16 +272,12 @@ private:
// Main thread only, since imgRequestProxy calls are expected on the main
// thread, and mConsumers is not threadsafe.
static void SyncNotifyState(ProxyArray& proxies,
bool hasImage, uint32_t state,
nsIntRect& dirtyRect);
static void SyncNotifyState(ProxyArray& aProxies,
bool aHasImage, uint32_t aState,
const nsIntRect& aInvalidRect);
nsCOMPtr<nsIRunnable> mRequestRunnable;
// The invalid area of the most recent frame we know about. (All previous
// frames are assumed to be fully valid.)
nsIntRect mInvalidRect;
// This weak ref should be set null when the image goes out of scope.
mozilla::image::Image* mImage;

View File

@ -33,6 +33,7 @@ var gRanEvent = false;
var gObserver;
var gImg1;
var gImg2;
var gFirstImageLoaded = false;
var gOuter;
var gFinished = false;
var gFirstRequest = null;
@ -71,20 +72,37 @@ function failTest() {
cleanUpAndFinish();
}
function waitForLoadAndTest(image) {
return () => {
// Draw the image into a canvas to ensure it's decoded.
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
context.drawImage(image, 0, 0);
// Attach the observer.
var imgLoadingContent = image.QueryInterface(Ci.nsIImageLoadingContent);
imgLoadingContent.addObserver(gOuter);
// If the other image already loaded, add both images to the document, which
// begins the real test.
if (gFirstImageLoaded) {
gContent.appendChild(gImg1);
gContent.appendChild(gImg2);
} else {
gFirstImageLoaded = true;
}
};
}
function main() {
gImg1 = new Image();
gImg2 = new Image();
// Create, customize & attach decoder observer
// Create and customize decoder observer
var obs = new ImageDecoderObserverStub();
obs.frameUpdate = frameUpdate;
gOuter = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools).createScriptedObserver(obs);
var imgLoadingContent = gImg1.QueryInterface(Ci.nsIImageLoadingContent);
imgLoadingContent.addObserver(gOuter);
imgLoadingContent = gImg2.QueryInterface(Ci.nsIImageLoadingContent);
imgLoadingContent.addObserver(gOuter);
// We want to test the cold loading behavior, so clear cache in case an
// earlier test got our image in there already.
@ -94,8 +112,9 @@ function main() {
gImg1.src = "animated1.gif";
gImg2.src = "animated2.gif";
gContent.appendChild(gImg1);
gContent.appendChild(gImg2);
// Wait for each image to load.
gImg1.addEventListener('load', waitForLoadAndTest(gImg1));
gImg2.addEventListener('load', waitForLoadAndTest(gImg2));
// In case something goes wrong, fail earlier than mochitest timeout,
// and with more information.

View File

@ -500,7 +500,7 @@ AsmJSHandleExecutionInterrupt()
{
AsmJSActivation *act = PerThreadData::innermostAsmJSActivation();
act->module().setInterrupted(true);
bool ret = HandleExecutionInterrupt(act->cx());
bool ret = CheckForInterrupt(act->cx());
act->module().setInterrupted(false);
return ret;
}
@ -673,8 +673,8 @@ AddressOf(AsmJSImmKind kind, ExclusiveContext *cx)
switch (kind) {
case AsmJSImm_Runtime:
return cx->runtimeAddressForJit();
case AsmJSImm_RuntimeInterrupt:
return cx->runtimeAddressOfInterrupt();
case AsmJSImm_RuntimeInterruptUint32:
return cx->runtimeAddressOfInterruptUint32();
case AsmJSImm_StackLimit:
return cx->stackLimitAddressForJitCode(StackForUntrustedScript);
case AsmJSImm_ReportOverRecursed:

View File

@ -2664,24 +2664,6 @@ if test "$ac_cv_cpp_unused_required" = yes ; then
fi
dnl Some compilers have trouble comparing a constant reference to a templatized
dnl class to zero, and require an explicit operator==() to be defined that takes
dnl an int. This test separates the strong from the weak.
AC_CACHE_CHECK(for trouble comparing to zero near std::operator!=(),
ac_cv_trouble_comparing_to_zero,
[AC_TRY_COMPILE([#include <algorithm>
template <class T> class Foo {};
class T2;
template <class T> int operator==(const T2*, const T&) { return 0; }
template <class T> int operator!=(const T2*, const T&) { return 0; }],
[Foo<int> f; return (0 != f);],
ac_cv_trouble_comparing_to_zero=no,
ac_cv_trouble_comparing_to_zero=yes)])
if test "$ac_cv_trouble_comparing_to_zero" = yes ; then
AC_DEFINE(HAVE_CPP_TROUBLE_COMPARING_TO_ZERO)
fi
# try harder, when checking for __thread support, see bug 521750 comment #33 and below
# We pass MOZ_OPTIMIZE_LDFLAGS to the linker because if dead_strip is
# enabled, the linker in xcode 4.1 will crash. Without this it would crash when

View File

@ -271,6 +271,7 @@ class GCRuntime
void decFJMinorCollecting() { fjCollectionCounter--; }
bool triggerGC(JS::gcreason::Reason reason);
void maybeAllocTriggerZoneGC(Zone *zone, const AutoLockGC &lock);
bool triggerZoneGC(Zone *zone, JS::gcreason::Reason reason);
bool maybeGC(Zone *zone);
void maybePeriodicFullGC();
@ -481,11 +482,15 @@ class GCRuntime
void freeUnusedLifoBlocksAfterSweeping(LifoAlloc *lifo);
void freeAllLifoBlocksAfterSweeping(LifoAlloc *lifo);
// Public here for ReleaseArenaLists and FinalizeTypedArenas.
void releaseArena(ArenaHeader *aheader, const AutoLockGC &lock);
private:
// For ArenaLists::allocateFromArena()
friend class ArenaLists;
Chunk *pickChunk(const AutoLockGC &lock,
AutoMaybeStartBackgroundAllocation &maybeStartBGAlloc);
ArenaHeader *allocateArena(Chunk *chunk, Zone *zone, AllocKind kind, const AutoLockGC &lock);
inline void arenaAllocatedDuringGC(JS::Zone *zone, ArenaHeader *arena);
template <AllowGC allowGC>
@ -543,8 +548,7 @@ class GCRuntime
bool sweepPhase(SliceBudget &sliceBudget);
void endSweepPhase(bool lastGC);
void sweepZones(FreeOp *fop, bool lastGC);
void decommitArenasFromAvailableList(Chunk **availableListHeadp);
void decommitArenas();
void decommitArenas(const AutoLockGC &lock);
void expireChunksAndArenas(bool shouldShrink, const AutoLockGC &lock);
void sweepBackgroundThings();
void assertBackgroundSweepingFinished();

View File

@ -37,6 +37,7 @@ struct Runtime;
namespace js {
class AutoLockGC;
class FreeOp;
#ifdef DEBUG
@ -945,9 +946,10 @@ struct Chunk
inline void insertToAvailableList(Chunk **insertPoint);
inline void removeFromAvailableList();
ArenaHeader *allocateArena(JS::Zone *zone, AllocKind kind);
ArenaHeader *allocateArena(JSRuntime *rt, JS::Zone *zone, AllocKind kind,
const AutoLockGC &lock);
void releaseArena(ArenaHeader *aheader);
void releaseArena(JSRuntime *rt, ArenaHeader *aheader, const AutoLockGC &lock);
void recycleArena(ArenaHeader *aheader, SortedArenaList &dest, AllocKind thingKind,
size_t thingsPerArena);
@ -1147,17 +1149,6 @@ ArenaHeader::unsetAllocDuringSweep()
auxNextLink = 0;
}
inline void
ReleaseArenaList(ArenaHeader *aheader)
{
ArenaHeader *next;
for (; aheader; aheader = next) {
// Copy aheader->next before releasing.
next = aheader->next;
aheader->chunk()->releaseArena(aheader);
}
}
static void
AssertValidColor(const TenuredCell *thing, uint32_t color)
{

View File

@ -152,7 +152,7 @@ NativeRegExpMacroAssembler::GenerateCode(JSContext *cx, bool match_only)
// Check if we have space on the stack.
Label stack_ok;
void *stack_limit = &runtime->mainThread.jitStackLimit;
void *stack_limit = runtime->mainThread.addressOfJitStackLimit();
masm.branchPtr(Assembler::Below, AbsoluteAddress(stack_limit), StackPointer, &stack_ok);
// Exit with an exception. There is not enough space on the stack
@ -502,7 +502,7 @@ NativeRegExpMacroAssembler::Backtrack()
// Check for an interrupt.
Label noInterrupt;
masm.branch32(Assembler::Equal,
AbsoluteAddress(&runtime->interrupt), Imm32(0),
AbsoluteAddress(runtime->addressOfInterruptUint32()), Imm32(0),
&noInterrupt);
masm.movePtr(ImmWord(RegExpRunStatus_Error), temp0);
masm.jump(&exit_label_);

View File

@ -496,7 +496,7 @@ bool
BaselineCompiler::emitStackCheck(bool earlyCheck)
{
Label skipCall;
uintptr_t *limitAddr = &cx->runtime()->mainThread.jitStackLimit;
void *limitAddr = cx->runtime()->mainThread.addressOfJitStackLimit();
uint32_t slotsSize = script->nslots() * sizeof(Value);
uint32_t tolerance = earlyCheck ? slotsSize : 0;
@ -646,7 +646,7 @@ BaselineCompiler::emitInterruptCheck()
frame.syncStack(0);
Label done;
void *interrupt = (void *)&cx->runtime()->interrupt;
void *interrupt = cx->runtimeAddressOfInterruptUint32();
masm.branch32(Assembler::Equal, AbsoluteAddress(interrupt), Imm32(0), &done);
prepareVMCall();

Some files were not shown because too many files have changed in this diff Show More