Merge m-c to fx-team. a=merge
Merge m-c to fx-team. a=merge
CLOSED TREE
--- a/addon-sdk/source/lib/sdk/content/sandbox.js
+++ b/addon-sdk/source/lib/sdk/content/sandbox.js
@@ -171,22 +171,18 @@ const WorkerSandbox = Class({
let options = 'contentScriptOptions' in worker ?
JSON.stringify(worker.contentScriptOptions) :
undefined;
// Then call `inject` method and communicate with this script
// by trading two methods that allow to send events to the other side:
// - `onEvent` called by content script
// - `result.emitToContent` called by addon script
- // Bug 758203: We have to explicitely define `__exposedProps__` in order
- // to allow access to these chrome object attributes from this sandbox with
- // content priviledges
- // https://developer.mozilla.org/en/XPConnect_wrappers#Other_security_wrappers
let onEvent = onContentEvent.bind(null, this);
- let chromeAPI = createChromeAPI();
+ let chromeAPI = createChromeAPI(ContentWorker);
let result = Cu.waiveXrays(ContentWorker).inject(content, chromeAPI, onEvent, options);
// Merge `emitToContent` into our private model of the
// WorkerSandbox so we can communicate with content script
model.emitToContent = result;
let console = new PlainTextConsole(null, getInnerId(window));
@@ -374,34 +370,21 @@ function modelFor (workerSandbox) {
function getUnsafeWindow (win) {
return win.wrappedJSObject || win;
}
function emitToContent (workerSandbox, args) {
return modelFor(workerSandbox).emitToContent(args);
}
-function createChromeAPI () {
- return {
+function createChromeAPI (scope) {
+ return Cu.cloneInto({
timers: {
- setTimeout: timer.setTimeout,
- setInterval: timer.setInterval,
- clearTimeout: timer.clearTimeout,
- clearInterval: timer.clearInterval,
- __exposedProps__: {
- setTimeout: 'r',
- setInterval: 'r',
- clearTimeout: 'r',
- clearInterval: 'r'
- },
+ setTimeout: timer.setTimeout.bind(timer),
+ setInterval: timer.setInterval.bind(timer),
+ clearTimeout: timer.clearTimeout.bind(timer),
+ clearInterval: timer.clearInterval.bind(timer),
},
sandbox: {
evaluate: evaluate,
- __exposedProps__: {
- evaluate: 'r'
- }
},
- __exposedProps__: {
- timers: 'r',
- sandbox: 'r'
- }
- };
+ }, scope, {cloneFunctions: true});
}
--- a/addon-sdk/source/lib/sdk/deprecated/traits-worker.js
+++ b/addon-sdk/source/lib/sdk/deprecated/traits-worker.js
@@ -179,44 +179,27 @@ const WorkerSandbox = EventEmitter.compo
let options = 'contentScriptOptions' in worker ?
JSON.stringify( worker.contentScriptOptions ) :
undefined;
// Then call `inject` method and communicate with this script
// by trading two methods that allow to send events to the other side:
// - `onEvent` called by content script
// - `result.emitToContent` called by addon script
- // Bug 758203: We have to explicitely define `__exposedProps__` in order
- // to allow access to these chrome object attributes from this sandbox with
- // content priviledges
- // https://developer.mozilla.org/en/XPConnect_wrappers#Other_security_wrappers
- let chromeAPI = {
+ let chromeAPI = Cu.cloneInto({
timers: {
- setTimeout: timer.setTimeout,
- setInterval: timer.setInterval,
- clearTimeout: timer.clearTimeout,
- clearInterval: timer.clearInterval,
- __exposedProps__: {
- setTimeout: 'r',
- setInterval: 'r',
- clearTimeout: 'r',
- clearInterval: 'r'
- }
+ setTimeout: timer.setTimeout.bind(timer),
+ setInterval: timer.setInterval.bind(timer),
+ clearTimeout: timer.clearTimeout.bind(timer),
+ clearInterval: timer.clearInterval.bind(timer),
},
sandbox: {
evaluate: evaluate,
- __exposedProps__: {
- evaluate: 'r',
- }
},
- __exposedProps__: {
- timers: 'r',
- sandbox: 'r',
- }
- };
+ }, ContentWorker, {cloneFunctions: true});
let onEvent = this._onContentEvent.bind(this);
let result = Cu.waiveXrays(ContentWorker).inject(content, chromeAPI, onEvent, options);
this._emitToContent = result;
// Handle messages send by this script:
let self = this;
// console.xxx calls
this.on("console", function consoleListener(kind) {
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -783,19 +783,16 @@ pref("dom.ipc.reuse_parent_app", false);
// When a process receives a system message, we hold a CPU wake lock on its
// behalf for this many seconds, or until it handles the system message,
// whichever comes first.
pref("dom.ipc.systemMessageCPULockTimeoutSec", 30);
// Ignore the "dialog=1" feature in window.open.
pref("dom.disable_window_open_dialog_feature", true);
-// Enable before keyboard events and after keyboard events.
-pref("dom.beforeAfterKeyboardEvent.enabled", true);
-
// Screen reader support
pref("accessibility.accessfu.activate", 2);
pref("accessibility.accessfu.quicknav_modes", "Link,Heading,FormElement,Landmark,ListItem");
// Active quicknav mode, index value of list from quicknav_modes
pref("accessibility.accessfu.quicknav_index", 0);
// Setting for an utterance order (0 - description first, 1 - description last).
pref("accessibility.accessfu.utterance", 1);
// Whether to skip images with empty alt text
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -319,18 +319,16 @@ var shell = {
// Capture all key events so we can filter out hardware buttons
// And send them to Gaia via mozChromeEvents.
// Ideally, hardware buttons wouldn't generate key events at all, or
// if they did, they would use keycodes that conform to DOM 3 Events.
// See discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=762362
chromeEventHandler.addEventListener('keydown', this, true);
chromeEventHandler.addEventListener('keypress', this, true);
chromeEventHandler.addEventListener('keyup', this, true);
- chromeEventHandler.addEventListener('mozbrowserbeforekeydown', this, true);
- chromeEventHandler.addEventListener('mozbrowserbeforekeyup', this, true);
window.addEventListener('MozApplicationManifest', this);
window.addEventListener('mozfullscreenchange', this);
window.addEventListener('MozAfterPaint', this);
window.addEventListener('sizemodechange', this);
window.addEventListener('unload', this);
this.contentBrowser.addEventListener('mozbrowserloadstart', this, true);
this.contentBrowser.addEventListener('mozbrowserselectionchange', this, true);
@@ -353,18 +351,16 @@ var shell = {
ppmm.addMessageListener("file-picker", this);
},
stop: function shell_stop() {
window.removeEventListener('unload', this);
window.removeEventListener('keydown', this, true);
window.removeEventListener('keypress', this, true);
window.removeEventListener('keyup', this, true);
- window.removeEventListener('mozbrowserbeforekeydown', this, true);
- window.removeEventListener('mozbrowserbeforekeyup', this, true);
window.removeEventListener('MozApplicationManifest', this);
window.removeEventListener('mozfullscreenchange', this);
window.removeEventListener('sizemodechange', this);
this.contentBrowser.removeEventListener('mozbrowserloadstart', this, true);
this.contentBrowser.removeEventListener('mozbrowserselectionchange', this, true);
this.contentBrowser.removeEventListener('mozbrowserscrollviewchange', this, true);
this.contentBrowser.removeEventListener('mozbrowsertouchcarettap', this, true);
ppmm.removeMessageListener("content-handler", this);
@@ -419,24 +415,27 @@ var shell = {
isMediaKey = true;
type = mediaKeys[evt.key];
}
if (!type) {
return;
}
+ // If we didn't return, then the key event represents a hardware key
+ // and we need to prevent it from propagating to Gaia
+ evt.stopImmediatePropagation();
+ evt.preventDefault(); // Prevent keypress events (when #501496 is fixed).
+
// If it is a key down or key up event, we send a chrome event to Gaia.
// If it is a keypress event we just ignore it.
switch (evt.type) {
- case 'mozbrowserbeforekeydown':
case 'keydown':
type = type + '-press';
break;
- case 'mozbrowserbeforekeyup':
case 'keyup':
type = type + '-release';
break;
case 'keypress':
return;
}
// Let applications receive the headset button key press/release event.
@@ -469,18 +468,16 @@ var shell = {
visibleNormalAudioActive: false,
handleEvent: function shell_handleEvent(evt) {
let content = this.contentBrowser.contentWindow;
switch (evt.type) {
case 'keydown':
case 'keyup':
case 'keypress':
- case 'mozbrowserbeforekeydown':
- case 'mozbrowserbeforekeyup':
this.filterHardwareKeys(evt);
break;
case 'mozfullscreenchange':
// When the screen goes fullscreen make sure to set the focus to the
// main window so noboby can prevent the ESC key to get out fullscreen
// mode
if (document.mozFullScreen)
Services.fm.focusedWindow = window;
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -10,17 +10,17 @@
<!--original fetch url was git://codeaurora.org/-->
<remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
- <project name="gaia" path="gaia" remote="mozillaorg" revision="5c636a7a54b2c86d8ff6bc1aa1e5f9594c7bc586"/>
+ <project name="gaia" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9f6b7471c881ee689183d681658cf2ba3dfc5610"/>
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,17 +14,17 @@
<!--original fetch url was git://github.com/apitrace/-->
<remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
<default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
<!-- Gonk specific things and forks -->
<project name="platform_build" path="build" remote="b2g" revision="84923f1940625c47ff4c1fdf01b10fde3b7d909e">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
- <project name="gaia.git" path="gaia" remote="mozillaorg" revision="5c636a7a54b2c86d8ff6bc1aa1e5f9594c7bc586"/>
+ <project name="gaia.git" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c058843242068d0df7c107e09da31b53d2e08fa6"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9f6b7471c881ee689183d681658cf2ba3dfc5610"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,17 +12,17 @@
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="8986df0f82e15ac2798df0b6c2ee3435400677ac">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
- <project name="gaia" path="gaia" remote="mozillaorg" revision="5c636a7a54b2c86d8ff6bc1aa1e5f9594c7bc586"/>
+ <project name="gaia" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9f6b7471c881ee689183d681658cf2ba3dfc5610"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
<project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
@@ -129,12 +129,12 @@
<project name="android-development" path="development" remote="b2g" revision="dab55669da8f48b6e57df95d5af9f16b4a87b0b1"/>
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="3a9a17613cc685aa232432566ad6cc607eab4ec1"/>
<project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="197cd9492b9fadaa915c5daf36ff557f8f4a8d1c"/>
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/>
<project name="libnfcemu" path="external/libnfcemu" remote="b2g" revision="125ccf9bd5986c7728ea44508b3e1d1185ac028b"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="d259117b4976decbe2f76eeed85218bf0109190f"/>
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9f28c4faea3b2f01db227b2467b08aeba96d9bec"/>
- <project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="85e864c4abc80e08bc82f0ac53c042e0d27839b0"/>
+ <project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="7047fcaa8bb55888ec7b84997e1bab41185ba3a3"/>
<project name="android-sdk" path="sdk" remote="b2g" revision="8b1365af38c9a653df97349ee53a3f5d64fd590a"/>
<project name="darwinstreamingserver" path="system/darwinstreamingserver" remote="b2g" revision="cf85968c7f85e0ec36e72c87ceb4837a943b8af6"/>
</manifest>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,17 +10,17 @@
<!--original fetch url was git://codeaurora.org/-->
<remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
- <project name="gaia" path="gaia" remote="mozillaorg" revision="5c636a7a54b2c86d8ff6bc1aa1e5f9594c7bc586"/>
+ <project name="gaia" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9f6b7471c881ee689183d681658cf2ba3dfc5610"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,17 +14,17 @@
<!--original fetch url was git://github.com/apitrace/-->
<remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
<default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
<!-- Gonk specific things and forks -->
<project name="platform_build" path="build" remote="b2g" revision="84923f1940625c47ff4c1fdf01b10fde3b7d909e">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
- <project name="gaia.git" path="gaia" remote="mozillaorg" revision="5c636a7a54b2c86d8ff6bc1aa1e5f9594c7bc586"/>
+ <project name="gaia.git" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c058843242068d0df7c107e09da31b53d2e08fa6"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9f6b7471c881ee689183d681658cf2ba3dfc5610"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -10,17 +10,17 @@
<!--original fetch url was git://codeaurora.org/-->
<remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
- <project name="gaia" path="gaia" remote="mozillaorg" revision="5c636a7a54b2c86d8ff6bc1aa1e5f9594c7bc586"/>
+ <project name="gaia" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9f6b7471c881ee689183d681658cf2ba3dfc5610"/>
@@ -127,17 +127,17 @@
<remove-project name="platform/hardware/libhardware"/>
<remove-project name="platform/external/bluetooth/bluedroid"/>
<!--original fetch url was git://github.com/t2m-foxfone/-->
<remote fetch="https://git.mozilla.org/external/t2m-foxfone" name="t2m"/>
<default remote="caf" revision="LNX.LA.3.5.2.1.1" sync-j="4"/>
<!-- Flame specific things -->
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="1bb28abbc215f45220620af5cd60a8ac1be93722"/>
<project name="device/qcom/common" path="device/qcom/common" revision="54c32c2ddef066fbdf611d29e4b7c47e0363599e"/>
- <project name="device-flame" path="device/t2m/flame" remote="b2g" revision="52c909e821d107d414f851e267dedcd7aae2cebf"/>
+ <project name="device-flame" path="device/t2m/flame" remote="b2g" revision="05aa7b98d3f891b334031dc710d48d0d6b82ec1d"/>
<project name="codeaurora_kernel_msm" path="kernel" remote="b2g" revision="7731d63c809dbca4da408e1de0c1a044f0765e52"/>
<project name="kernel_lk" path="bootable/bootloader/lk" remote="b2g" revision="fda40423ffa573dc6cafd3780515010cb2a086be"/>
<project name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="30b96dfca99cb384bf520a16b81f3aba56f09907"/>
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="5b71e40213f650459e95d35b6f14af7e88d8ab62"/>
<project name="platform_external_libnfc-nci" path="external/libnfc-nci" remote="t2m" revision="4186bdecb4dae911b39a8202252cc2310d91b0be"/>
<project name="platform/frameworks/av" path="frameworks/av" revision="ea2f399b3ca0a23524d2828f85f69902caefc22e"/>
<project name="platform/frameworks/base" path="frameworks/base" revision="6b58ab45e3e56c1fc20708cc39fa2264c52558df"/>
<project name="platform/frameworks/native" path="frameworks/native" revision="a46a9f1ac0ed5662d614c277cbb14eb3f332f365"/>
@@ -146,13 +146,13 @@
<project name="platform/hardware/qcom/camera" path="hardware/qcom/camera" revision="2a1ded216a91bf62a72b1640cf01ab4998f37028"/>
<project name="platform/hardware/qcom/display" path="hardware/qcom/display" revision="e5a971282719907f73fb1da964ca40aad67a3be0"/>
<project name="platform/hardware/qcom/gps" path="hardware/qcom/gps" revision="9883ea57b0668d8f60dba025d4522dfa69a1fbfa"/>
<project name="platform/hardware/qcom/media" path="hardware/qcom/media" revision="a558dc844bf5144fc38603fd8f4df8d9557052a5"/>
<project name="platform/hardware/qcom/wlan" path="hardware/qcom/wlan" revision="57ee1320ed7b4a1a1274d8f3f6c177cd6b9becb2"/>
<project name="platform/hardware/ril" path="hardware/ril" revision="12b1977cc704b35f2e9db2bb423fa405348bc2f3"/>
<project name="platform/system/bluetooth" path="system/bluetooth" revision="985bf15264d865fe7b9c5b45f61c451cbaafa43d"/>
<project name="platform/system/core" path="system/core" revision="350eac5403124dacb2a5fd9e28ac290a59fc3b8e"/>
- <project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="85e864c4abc80e08bc82f0ac53c042e0d27839b0"/>
+ <project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="7047fcaa8bb55888ec7b84997e1bab41185ba3a3"/>
<project name="platform/system/qcom" path="system/qcom" revision="63e3f6f176caad587d42bba4c16b66d953fb23c2"/>
<project name="platform/vendor/qcom-opensource/wlan/prima" path="vendor/qcom/opensource/wlan/prima" revision="d8952a42771045fca73ec600e2b42a4c7129d723"/>
<project name="platform/vendor/qcom/msm8610" path="device/qcom/msm8610" revision="7704e16da545f4207812e593743d6743e1afb9c5"/>
</manifest>
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -12,17 +12,17 @@
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="8986df0f82e15ac2798df0b6c2ee3435400677ac">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
- <project name="gaia" path="gaia" remote="mozillaorg" revision="5c636a7a54b2c86d8ff6bc1aa1e5f9594c7bc586"/>
+ <project name="gaia" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9f6b7471c881ee689183d681658cf2ba3dfc5610"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="e95b4ce22c825da44d14299e1190ea39a5260bde"/>
<project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="471afab478649078ad7c75ec6b252481a59e19b8"/>
@@ -140,13 +140,13 @@
<project name="platform/hardware/qcom/camera" path="hardware/qcom/camera" revision="5e110615212302c5d798a3c223dcee458817651c"/>
<project name="platform/hardware/qcom/display" path="hardware/qcom/display" revision="fa9ffd47948eb24466de227e48fe9c4a7c5e7711"/>
<project name="platform/hardware/qcom/gps" path="hardware/qcom/gps" revision="cd76b19aafd4229ccf83853d02faef8c51ca8b34"/>
<project name="platform/hardware/qcom/media" path="hardware/qcom/media" revision="8a0d0b0d9889ef99c4c6317c810db4c09295f15a"/>
<project name="platform/hardware/qcom/wlan" path="hardware/qcom/wlan" revision="2208fa3537ace873b8f9ec2355055761c79dfd5f"/>
<project name="platform/hardware/ril" path="hardware/ril" revision="c4e2ac95907a5519a0e09f01a0d8e27fec101af0"/>
<project name="platform/system/bluetooth" path="system/bluetooth" revision="e1eb226fa3ad3874ea7b63c56a9dc7012d7ff3c2"/>
<project name="platform/system/core" path="system/core" revision="adc485d8755af6a61641d197de7cfef667722580"/>
- <project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="85e864c4abc80e08bc82f0ac53c042e0d27839b0"/>
+ <project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="7047fcaa8bb55888ec7b84997e1bab41185ba3a3"/>
<project name="platform/system/qcom" path="system/qcom" revision="1cdab258b15258b7f9657da70e6f06ebd5a2fc25"/>
<project name="platform/vendor/qcom/msm8610" path="device/qcom/msm8610" revision="4ae5df252123591d5b941191790e7abed1bce5a4"/>
<project name="platform/vendor/qcom-opensource/wlan/prima" path="vendor/qcom/opensource/wlan/prima" revision="ce18b47b4a4f93a581d672bbd5cb6d12fe796ca9"/>
</manifest>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
{
"git": {
"git_revision": "",
"remote": "",
"branch": ""
},
- "revision": "8017299c3eb7b82bdaee1334994f546c11eb16ab",
+ "revision": "63436aa17e7fa3ad521fdeffdc22b81c36e5d69b",
"repo_path": "/integration/gaia-central"
}
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -12,17 +12,17 @@
<!--original fetch url was git://github.com/apitrace/-->
<remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
<default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
<!-- Gonk specific things and forks -->
<project name="platform_build" path="build" remote="b2g" revision="84923f1940625c47ff4c1fdf01b10fde3b7d909e">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
- <project name="gaia.git" path="gaia" remote="mozillaorg" revision="5c636a7a54b2c86d8ff6bc1aa1e5f9594c7bc586"/>
+ <project name="gaia.git" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<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="9f6b7471c881ee689183d681658cf2ba3dfc5610"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
<project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -10,17 +10,17 @@
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
<!-- Gonk specific things and forks -->
<project name="platform_build" path="build" remote="b2g" revision="84923f1940625c47ff4c1fdf01b10fde3b7d909e">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
- <project name="gaia.git" path="gaia" remote="mozillaorg" revision="5c636a7a54b2c86d8ff6bc1aa1e5f9594c7bc586"/>
+ <project name="gaia.git" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
<project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -12,17 +12,17 @@
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="8986df0f82e15ac2798df0b6c2ee3435400677ac">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
- <project name="gaia" path="gaia" remote="mozillaorg" revision="5c636a7a54b2c86d8ff6bc1aa1e5f9594c7bc586"/>
+ <project name="gaia" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9f6b7471c881ee689183d681658cf2ba3dfc5610"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
<project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
@@ -124,17 +124,17 @@
<project name="platform/system/netd" path="system/netd" revision="56112dd7b811301b718d0643a82fd5cac9522073"/>
<project name="platform/system/security" path="system/security" revision="f48ff68fedbcdc12b570b7699745abb6e7574907"/>
<project name="platform/system/vold" path="system/vold" revision="8de05d4a52b5a91e7336e6baa4592f945a6ddbea"/>
<default remote="caf" revision="refs/tags/android-4.3_r2.1" sync-j="4"/>
<!-- Nexus 4 specific things -->
<project name="device-mako" path="device/lge/mako" remote="b2g" revision="78d17f0c117f0c66dd55ee8d5c5dde8ccc93ecba"/>
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="3a9a17613cc685aa232432566ad6cc607eab4ec1"/>
<project name="device/lge/mako-kernel" path="device/lge/mako-kernel" revision="d1729e53d71d711c8fde25eab8728ff2b9b4df0e"/>
- <project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="85e864c4abc80e08bc82f0ac53c042e0d27839b0"/>
+ <project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="7047fcaa8bb55888ec7b84997e1bab41185ba3a3"/>
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/>
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
<project name="platform/hardware/broadcom/wlan" path="hardware/broadcom/wlan" revision="0e1929fa3aa38bf9d40e9e953d619fab8164c82e"/>
<project name="platform/hardware/qcom/audio" path="hardware/qcom/audio" revision="b0a528d839cfd9d170d092fe3743b5252b4243a6"/>
<project name="platform/hardware/qcom/bt" path="hardware/qcom/bt" revision="380945eaa249a2dbdde0daa4c8adb8ca325edba6"/>
<project name="platform/hardware/qcom/display" path="hardware/qcom/display" revision="6f3b0272cefaffeaed2a7d2bb8f633059f163ddc"/>
<project name="platform/hardware/qcom/keymaster" path="hardware/qcom/keymaster" revision="16da8262c997a5a0d797885788a64a0771b26910"/>
<project name="platform/hardware/qcom/media" path="hardware/qcom/media" revision="689b476ba3eb46c34b81343295fe144a0e81a18e"/>
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -12,17 +12,17 @@
<!--original fetch url was git://github.com/apitrace/-->
<remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
<default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
<!-- Gonk specific things and forks -->
<project name="platform_build" path="build" remote="b2g" revision="84923f1940625c47ff4c1fdf01b10fde3b7d909e">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
- <project name="gaia.git" path="gaia" remote="mozillaorg" revision="5c636a7a54b2c86d8ff6bc1aa1e5f9594c7bc586"/>
+ <project name="gaia.git" path="gaia" remote="mozillaorg" revision="abef62c0623e5504a97b4fd411e879a67b285b52"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
<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="9f6b7471c881ee689183d681658cf2ba3dfc5610"/>
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -20,17 +20,17 @@ DEFINES += \
ifdef LIBXUL_SDK #{
PREF_JS_EXPORTS += $(srcdir)/profile/channel-prefs.js
endif #} LIBXUL_SDK
# Build a binary bootstrapping with XRE_main
ifndef MOZ_WINCONSOLE
-ifdef MOZ_DEBUG
+ifneq (,$(MOZ_DEBUG)$(MOZ_ASAN))
MOZ_WINCONSOLE = 1
else
MOZ_WINCONSOLE = 0
endif
endif
# This switches $(INSTALL) to copy mode, like $(SYSINSTALL), so things that
# shouldn't get 755 perms need $(IFLAGS1) for either way of calling nsinstall.
--- a/browser/base/content/test/general/browser_bug767836_perwindowpb.js
+++ b/browser/base/content/test/general/browser_bug767836_perwindowpb.js
@@ -24,18 +24,23 @@ function test() {
is(aWindow.gBrowser.selectedBrowser.currentURI.spec, newTabURL,
"URL of NewTab should be " + newTabURL + " in " + mode + " mode");
// Set the custom newtab url
Services.prefs.setCharPref(newTabPrefName, testURL);
ok(Services.prefs.prefHasUserValue(newTabPrefName), "Custom newtab url is set");
// Open a newtab after setting the custom newtab url
openNewTab(aWindow, function () {
- is(aWindow.gBrowser.selectedBrowser.currentURI.spec, testURL,
- "URL of NewTab should be the custom url");
+ if (aIsPrivateMode) {
+ is(aWindow.gBrowser.selectedBrowser.currentURI.spec, newTabURL,
+ "URL of NewTab should always be " + newTabURL + " in " + mode + " mode");
+ } else {
+ is(aWindow.gBrowser.selectedBrowser.currentURI.spec, testURL,
+ "URL of NewTab should be the custom url");
+ }
// clear the custom url preference
Services.prefs.clearUserPref(newTabPrefName);
ok(!Services.prefs.prefHasUserValue(newTabPrefName), "No custom newtab url is set");
aWindow.gBrowser.removeTab(aWindow.gBrowser.selectedTab);
aWindow.gBrowser.removeTab(aWindow.gBrowser.selectedTab);
aWindow.close();
@@ -75,9 +80,9 @@ function openNewTab(aWindow, aCallback)
executeSoon(aCallback);
return;
}
browser.addEventListener("load", function onLoad() {
browser.removeEventListener("load", onLoad, true);
executeSoon(aCallback);
}, true);
-}
\ No newline at end of file
+}
--- a/browser/base/content/utilityOverlay.js
+++ b/browser/base/content/utilityOverlay.js
@@ -8,21 +8,21 @@ Components.utils.import("resource://gre/
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
Components.utils.import("resource:///modules/RecentWindow.jsm");
XPCOMUtils.defineLazyGetter(this, "BROWSER_NEW_TAB_URL", function () {
const PREF = "browser.newtab.url";
function getNewTabPageURL() {
- if (!Services.prefs.prefHasUserValue(PREF)) {
- if (PrivateBrowsingUtils.isWindowPrivate(window) &&
- !PrivateBrowsingUtils.permanentPrivateBrowsing)
- return "about:privatebrowsing";
+ if (PrivateBrowsingUtils.isWindowPrivate(window) &&
+ !PrivateBrowsingUtils.permanentPrivateBrowsing) {
+ return "about:privatebrowsing";
}
+
let url = Services.prefs.getComplexValue(PREF, Ci.nsISupportsString).data;
return url || "about:blank";
}
function update() {
BROWSER_NEW_TAB_URL = getNewTabPageURL();
}
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_urlbarfocus.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_urlbarfocus.js
@@ -1,70 +1,40 @@
/* 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/. */
// This test makes sure that the URL bar is focused when entering the private window.
-function test() {
- waitForExplicitFinish();
+"use strict";
- const TEST_URL = "data:text/plain,test";
+function checkUrlbarFocus(win) {
+ let urlbar = win.gURLBar;
+ is(win.document.activeElement, urlbar.inputField, "URL Bar should be focused");
+ is(urlbar.value, "", "URL Bar should be empty");
+}
- function checkUrlbarFocus(aWin, aIsPrivate, aCallback) {
- let urlbar = aWin.gURLBar;
- if (aIsPrivate) {
- is(aWin.document.commandDispatcher.focusedElement, urlbar.inputField,
- "URL Bar should be focused inside the private window");
- is(urlbar.value, "",
- "URL Bar should be empty inside the private window");
- } else {
- isnot(aWin.document.commandDispatcher.focusedElement, urlbar.inputField,
- "URL Bar should not be focused after opening window");
- isnot(urlbar.value, "",
- "URL Bar should not be empty after opening window");
- }
- aCallback();
- }
-
- let windowsToClose = [];
- function testOnWindow(aPrivate, aCallback) {
- whenNewWindowLoaded({private: aPrivate}, function(win) {
- windowsToClose.push(win);
- executeSoon(function() aCallback(win));
- });
- }
+function openNewPrivateWindow() {
+ let deferred = Promise.defer();
+ whenNewWindowLoaded({private: true}, win => {
+ executeSoon(() => deferred.resolve(win));
+ });
+ return deferred.promise;
+}
- function doneWithTests() {
- windowsToClose.forEach(function(win) {
- win.close();
- });
- finish();
- }
+add_task(function* () {
+ let win = yield openNewPrivateWindow();
+ checkUrlbarFocus(win);
+ win.close();
+});
- function whenLoadTab(aPrivate, aCallback) {
- testOnWindow(aPrivate, function(win) {
- if (!aPrivate) {
- let browser = win.gBrowser.selectedBrowser;
- browser.addEventListener("load", function() {
- browser.removeEventListener("load", arguments.callee, true);
- aCallback(win);
- }, true);
- browser.focus();
- browser.loadURI(TEST_URL);
- } else {
- aCallback(win);
- }
- });
- }
+add_task(function* () {
+ Services.prefs.setCharPref("browser.newtab.url", "about:blank");
+ registerCleanupFunction(() => {
+ Services.prefs.clearUserPref("browser.newtab.url");
+ });
- whenLoadTab(false, function(win) {
- checkUrlbarFocus(win, false, function() {
- whenLoadTab(true, function(win) {
- checkUrlbarFocus(win, true, function() {
- whenLoadTab(false, function(win) {
- checkUrlbarFocus(win, false, doneWithTests);
- });
- });
- });
- });
- });
-}
+ let win = yield openNewPrivateWindow();
+ checkUrlbarFocus(win);
+ win.close();
+
+ Services.prefs.clearUserPref("browser.newtab.url");
+});
--- a/build/autoconf/compiler-opts.m4
+++ b/build/autoconf/compiler-opts.m4
@@ -117,17 +117,17 @@ MOZ_ARG_ENABLE_STRING(debug,
MOZ_DEBUG_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'`
_MOZ_DEBUG_FLAGS_SET=1
fi
else
MOZ_DEBUG=
fi ],
MOZ_DEBUG=)
-if test -z "$MOZ_DEBUG"; then
+if test -z "$MOZ_DEBUG" -o -n "$MOZ_ASAN"; then
MOZ_NO_DEBUG_RTL=1
fi
AC_SUBST(MOZ_NO_DEBUG_RTL)
MOZ_DEBUG_ENABLE_DEFS="-DDEBUG -DTRACING"
MOZ_ARG_WITH_STRING(debug-label,
[ --with-debug-label=LABELS
--- a/build/autoconf/icu.m4
+++ b/build/autoconf/icu.m4
@@ -46,24 +46,30 @@ yes)
ENABLE_INTL_API=1
EXPOSE_INTL_API=1
;;
*)
AC_MSG_ERROR([Invalid value passed to --with-intl-api: $_INTL_API])
;;
esac
+if test -n "$ENABLE_INTL_API"; then
+ USE_ICU=1
+fi
+
if test -n "$EXPOSE_INTL_API"; then
AC_DEFINE(EXPOSE_INTL_API)
fi
-dnl Settings for the implementation of the ECMAScript Internationalization API
if test -n "$ENABLE_INTL_API"; then
AC_DEFINE(ENABLE_INTL_API)
+fi
+dnl Settings for the implementation of the ECMAScript Internationalization API
+if test -n "$USE_ICU"; then
icudir="$_topsrcdir/intl/icu/source"
if test ! -d "$icudir"; then
icudir="$_topsrcdir/../../intl/icu/source"
if test ! -d "$icudir"; then
AC_MSG_ERROR([Cannot find the ICU directory])
fi
fi
@@ -95,36 +101,37 @@ if test -n "$ENABLE_INTL_API"; then
*)
AC_MSG_ERROR([ECMAScript Internationalization API is not yet supported on this platform])
esac
fi
fi
AC_SUBST(MOZ_ICU_DBG_SUFFIX)
AC_SUBST(ENABLE_INTL_API)
+AC_SUBST(USE_ICU)
AC_SUBST_LIST(ICU_LIB_NAMES)
-if test -n "$ENABLE_INTL_API" -a -z "$MOZ_NATIVE_ICU"; then
+if test -n "$USE_ICU" -a -z "$MOZ_NATIVE_ICU"; then
dnl We build ICU as a static library for non-shared js builds and as a shared library for shared js builds.
if test -z "$MOZ_SHARED_ICU"; then
AC_DEFINE(U_STATIC_IMPLEMENTATION)
fi
dnl Source files that use ICU should have control over which parts of the ICU
dnl namespace they want to use.
AC_DEFINE(U_USING_ICU_NAMESPACE,0)
fi
])
AC_DEFUN([MOZ_SUBCONFIGURE_ICU], [
if test -z "$BUILDING_JS" -o -n "$JS_STANDALONE"; then
- if test -n "$ENABLE_INTL_API" -a -z "$MOZ_NATIVE_ICU"; then
+ if test -n "$USE_ICU" -a -z "$MOZ_NATIVE_ICU"; then
# Set ICU compile options
ICU_CPPFLAGS=""
# don't use icu namespace automatically in client code
ICU_CPPFLAGS="$ICU_CPPFLAGS -DU_USING_ICU_NAMESPACE=0"
# don't include obsolete header files
ICU_CPPFLAGS="$ICU_CPPFLAGS -DU_NO_DEFAULT_INCLUDE_UTF_HEADERS=1"
# remove chunks of the library that we don't need (yet)
ICU_CPPFLAGS="$ICU_CPPFLAGS -DUCONFIG_NO_LEGACY_CONVERSION"
--- a/config/external/icu/Makefile.in
+++ b/config/external/icu/Makefile.in
@@ -1,14 +1,14 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# Ensure that this happens before including rules.mk
-ifdef ENABLE_INTL_API
+ifdef USE_ICU
ifndef MOZ_NATIVE_ICU
# Library names: On Windows, ICU uses modified library names for static
# and debug libraries.
ifdef MOZ_SHARED_ICU
ifeq ($(OS_ARCH),WINNT)
ifdef JS_SHARED_LIBRARY
ICU_FILES := $(foreach libname,$(ICU_LIB_NAMES),$(DEPTH)/intl/icu/target/lib/$(libname)$(MOZ_ICU_DBG_SUFFIX)$(MOZ_ICU_VERSION).dll)
endif
@@ -31,21 +31,21 @@ ifdef ENABLE_INTL_API
endif
else # !MOZ_SHARED_ICU
ifeq ($(OS_ARCH),WINNT)
ICU_LIB_RENAME = $(foreach libname,$(ICU_LIB_NAMES),\
cp -p $(DEPTH)/intl/icu/target/lib/s$(libname)$(MOZ_ICU_DBG_SUFFIX).lib $(DEPTH)/intl/icu/target/lib/$(libname)$(MOZ_ICU_DBG_SUFFIX).lib;)
endif
endif # MOZ_SHARED_ICU
endif # !MOZ_NATIVE_ICU
-endif # ENABLE_INTL_API
+endif # USE_ICU
include $(topsrcdir)/config/rules.mk
-ifdef ENABLE_INTL_API
+ifdef USE_ICU
ifndef MOZ_NATIVE_ICU
target:: buildicu
$(STATIC_LIBS): buildicu
# - Force ICU to use the standard suffix for object files because expandlibs
# will discard all files with a non-standard suffix (bug 857450).
# - Options for genrb: -k strict parsing; -R omit collation tailoring rules.
buildicu::
--- a/configure.in
+++ b/configure.in
@@ -2201,16 +2201,20 @@ ia64*-hpux*)
# MSVC warning C4800 warns when a value is implicitly cast to bool,
# because this also forces narrowing to a single byte, which can be a
# perf hit. But this matters so little in practice (and often we want
# that behavior) that it's better to turn it off.
# MSVC warning C4819 warns some UTF-8 characters (e.g. copyright sign)
# on non-Western system locales even if it is in a comment.
CFLAGS="$CFLAGS -wd4244 -wd4267 -wd4819"
CXXFLAGS="$CXXFLAGS -wd4251 -wd4244 -wd4267 -wd4345 -wd4351 -wd4482 -wd4800 -wd4819"
+ if test -n "$CLANG_CL"; then
+ # Suppress the clang-cl warning for the inline 'new' and 'delete' in mozalloc
+ CXXFLAGS="$CXXFLAGS -Wno-inline-new-delete"
+ fi
# make 'foo == bar;' error out
CFLAGS="$CFLAGS -we4553"
CXXFLAGS="$CXXFLAGS -we4553"
LIBS="$LIBS kernel32.lib user32.lib gdi32.lib winmm.lib wsock32.lib advapi32.lib secur32.lib netapi32.lib"
MOZ_DEBUG_LDFLAGS='-DEBUG -DEBUGTYPE:CV'
WARNINGS_AS_ERRORS='-WX'
MOZ_OPTIMIZE_FLAGS='-O1 -Oi'
MOZ_FIX_LINK_PATHS=
@@ -8020,16 +8024,21 @@ else
MOZ_ENABLE_SKIA=
fi
MOZ_ARG_ENABLE_BOOL(skia,
[ --enable-skia Enable use of Skia],
MOZ_ENABLE_SKIA=1,
MOZ_ENABLE_SKIA=)
+MOZ_ARG_DISABLE_BOOL(skia-gpu,
+[ --disable-skia-gpu Disable use of Skia-GPU],
+MOZ_DISABLE_SKIA_GPU=1,
+MOZ_DISABLE_SKIA_GPU=)
+
if test "$USE_FC_FREETYPE"; then
if test "$COMPILE_ENVIRONMENT"; then
dnl ========================================================
dnl = Check for freetype2 and its functionality
dnl ========================================================
PKG_CHECK_MODULES(FT2, freetype2 >= 6.1.0, _HAVE_FREETYPE2=1, _HAVE_FREETYPE2=)
if test "$_HAVE_FREETYPE2"; then
@@ -8254,17 +8263,17 @@ dnl Skia
dnl ========================================================
if test "$MOZ_ENABLE_SKIA"; then
AC_DEFINE(MOZ_ENABLE_SKIA)
AC_DEFINE(USE_SKIA)
if test "${MOZ_WIDGET_TOOLKIT}" = "android" -o x"$MOZ_WIDGET_TOOLKIT" = x"gonk"; then
AC_DEFINE(SK_BUILD_FOR_ANDROID_NDK)
fi
- if test "${CPU_ARCH}" != "ppc" -a "${CPU_ARCH}" != "ppc64" -a "${CPU_ARCH}" != "sparc" ; then
+ if test "${CPU_ARCH}" != "ppc" -a "${CPU_ARCH}" != "ppc64" -a "${CPU_ARCH}" != "sparc" -a -z "$MOZ_DISABLE_SKIA_GPU" ; then
MOZ_ENABLE_SKIA_GPU=1
AC_DEFINE(USE_SKIA_GPU)
AC_SUBST(MOZ_ENABLE_SKIA_GPU)
fi
fi
AC_SUBST(MOZ_ENABLE_SKIA)
dnl ========================================================
@@ -9022,29 +9031,27 @@ dnl ICU Support
dnl ========================================================
# Internationalization isn't built or exposed by default in non-desktop
# builds. Bugs to enable:
#
# Android: bug 864843
# B2G: bug 866301
-if test "$MOZ_WIDGET_TOOLKIT" = "android"; then
+if test "$MOZ_WIDGET_TOOLKIT" = "android" ||
+ test "$MOZ_BUILD_APP" = "b2g"; then
_INTL_API=no
-elif test "$MOZ_BUILD_APP" = "b2g"; then
- if test "$MOZ_WIDGET_TOOLKIT" = "cocoa"; then
- # nsCollationMacUC needs ICU
- _INTL_API=yes
- else
- _INTL_API=no
- fi
else
_INTL_API=yes
fi
+if test "$MOZ_WIDGET_TOOLKIT" = "cocoa"; then
+ USE_ICU=1
+fi
+
MOZ_CONFIG_ICU()
if test -z "$JS_SHARED_LIBRARY"; then
AC_DEFINE(MOZ_STATIC_JS)
fi
AC_SUBST(JS_SHARED_LIBRARY)
MOZ_CREATE_CONFIG_STATUS()
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -789,20 +789,16 @@ GK_ATOM(onmousedown, "onmousedown")
GK_ATOM(onmouseenter, "onmouseenter")
GK_ATOM(onmouseleave, "onmouseleave")
GK_ATOM(onmousemove, "onmousemove")
GK_ATOM(onmouseout, "onmouseout")
GK_ATOM(onmouseover, "onmouseover")
GK_ATOM(onMozMouseHittest, "onMozMouseHittest")
GK_ATOM(onmouseup, "onmouseup")
GK_ATOM(onMozAfterPaint, "onMozAfterPaint")
-GK_ATOM(onmozbrowserafterkeydown, "onmozbrowserafterkeydown")
-GK_ATOM(onmozbrowserafterkeyup, "onmozbrowserafterkeyup")
-GK_ATOM(onmozbrowserbeforekeydown, "onmozbrowserbeforekeydown")
-GK_ATOM(onmozbrowserbeforekeyup, "onmozbrowserbeforekeyup")
GK_ATOM(onmozfullscreenchange, "onmozfullscreenchange")
GK_ATOM(onmozfullscreenerror, "onmozfullscreenerror")
GK_ATOM(onmozpointerlockchange, "onmozpointerlockchange")
GK_ATOM(onmozpointerlockerror, "onmozpointerlockerror")
GK_ATOM(onmoztimechange, "onmoztimechange")
GK_ATOM(onMozMousePixelScroll, "onMozMousePixelScroll")
GK_ATOM(onMozScrolledAreaChanged, "onMozScrolledAreaChanged")
GK_ATOM(onmoznetworkupload, "onmoznetworkupload")
@@ -1338,19 +1334,16 @@ GK_ATOM(fePointLight, "fePointLight")
GK_ATOM(feSpecularLighting, "feSpecularLighting")
GK_ATOM(feSpotLight, "feSpotLight")
GK_ATOM(feTile, "feTile")
GK_ATOM(feTurbulence, "feTurbulence")
GK_ATOM(fill, "fill")
GK_ATOM(fill_opacity, "fill-opacity")
GK_ATOM(fill_rule, "fill-rule")
GK_ATOM(filter, "filter")
-// Parsing for filterRes may be removed in the future.
-// https://bugzilla.mozilla.org/show_bug.cgi?id=979472
-GK_ATOM(filterRes, "filterRes")
GK_ATOM(filterUnits, "filterUnits")
GK_ATOM(_float, "float")
GK_ATOM(flood_color, "flood-color")
GK_ATOM(flood_opacity, "flood-opacity")
GK_ATOM(font_face, "font-face")
GK_ATOM(font_face_format, "font-face-format")
GK_ATOM(font_face_name, "font-face-name")
GK_ATOM(font_face_src, "font-face-src")
--- a/content/base/src/nsTreeSanitizer.cpp
+++ b/content/base/src/nsTreeSanitizer.cpp
@@ -388,18 +388,16 @@ nsIAtom** const kAttributesSVG[] = {
// cap-height
&nsGkAtoms::_class, // class
&nsGkAtoms::clip_path, // clip-path
&nsGkAtoms::clip_rule, // clip-rule
&nsGkAtoms::clipPathUnits, // clipPathUnits
&nsGkAtoms::color, // color
&nsGkAtoms::colorInterpolation, // color-interpolation
&nsGkAtoms::colorInterpolationFilters, // color-interpolation-filters
- // contentScriptType
- // contentStyleType
&nsGkAtoms::cursor, // cursor
&nsGkAtoms::cx, // cx
&nsGkAtoms::cy, // cy
&nsGkAtoms::d, // d
// descent
&nsGkAtoms::diffuseConstant, // diffuseConstant
&nsGkAtoms::direction, // direction
&nsGkAtoms::display, // display
@@ -411,17 +409,16 @@ nsIAtom** const kAttributesSVG[] = {
&nsGkAtoms::edgeMode, // edgeMode
&nsGkAtoms::elevation, // elevation
// enable-background
&nsGkAtoms::end, // end
&nsGkAtoms::fill, // fill
&nsGkAtoms::fill_opacity, // fill-opacity
&nsGkAtoms::fill_rule, // fill-rule
&nsGkAtoms::filter, // filter
- &nsGkAtoms::filterRes, // filterRes
&nsGkAtoms::filterUnits, // filterUnits
&nsGkAtoms::flood_color, // flood-color
&nsGkAtoms::flood_opacity, // flood-opacity
// XXX focusable
&nsGkAtoms::font, // font
&nsGkAtoms::font_family, // font-family
&nsGkAtoms::font_size, // font-size
&nsGkAtoms::font_size_adjust, // font-size-adjust
--- a/content/media/test/mochitest.ini
+++ b/content/media/test/mochitest.ini
@@ -297,17 +297,17 @@ support-files =
wave_metadata_utf8.wav
wave_metadata_utf8.wav^headers^
wavedata_s16.wav
wavedata_s16.wav^headers^
wavedata_u8.wav
wavedata_u8.wav^headers^
[test_access_control.html]
-skip-if = buildapp == 'b2g' && toolkit != 'gonk' # crash on b2g-desktop
+skip-if = buildapp == 'b2g' && toolkit != 'gonk' # bug 1082984
[test_aspectratio_mp4.html]
[test_audio1.html]
[test_audio2.html]
[test_audioDocumentTitle.html]
skip-if = true # bug 475110 - disabled since we don't play Wave files standalone
[test_autoplay.html]
[test_autoplay_contentEditable.html]
[test_buffered.html]
@@ -346,17 +346,17 @@ skip-if = toolkit == 'gonk' && debug
[test_contentDuration6.html]
[test_contentDuration7.html]
[test_controls.html]
[test_currentTime.html]
[test_decode_error.html]
[test_decoder_disable.html]
[test_defaultMuted.html]
[test_delay_load.html]
-skip-if = buildapp == 'b2g' # bug 1021676
+skip-if = buildapp == 'b2g' && toolkit != 'gonk' # bug 1082984
[test_encryptedMediaExtensions.html]
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # bug 1043403, bug 1057908
[test_error_in_video_document.html]
skip-if = toolkit == 'android' # bug 608634
[test_error_on_404.html]
[test_fastSeek.html]
[test_fastSeek-forwards.html]
[test_imagecapture.html]
--- a/content/media/test/test_delay_load.html
+++ b/content/media/test/test_delay_load.html
@@ -4,71 +4,58 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=479711
-->
<head>
<title>Test for Bug 479711</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript" src="manifest.js"></script>
<script>
-
+
var gRegisteredElements = [];
- var gLog = false;
var testWindows = [];
- function log(msg) {
- if (gLog) {
- document.getElementById('log').innerHTML += "<p>"+msg+"</p>";
- dump(msg + "\n");
- }
- }
-
function register(v) {
gRegisteredElements.push(v);
}
function loaded() {
- log("onload fired!");
+ info("onload fired!");
for (var i = 0; i < gRegisteredElements.length; ++i) {
var v = gRegisteredElements[i];
ok(v.readyState >= v.HAVE_CURRENT_DATA,
v._name + ":" + v.id + " is not ready before onload fired (" + v.readyState + ")");
}
for (i=0; i<testWindows.length; ++i) {
testWindows[i].close();
}
- mediaTestCleanup();
+ mediaTestCleanup();
SimpleTest.finish();
}
-
+
addLoadEvent(loaded);
-
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=479711">Mozilla Bug 479711</a>
<p id="display"></p>
-<div id="content" style="display: none">
-
-</div>
-
-
-<div id="log" style="font-size: small;"></div>
+<div id="content" style="display: none"></div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 479711 **/
function createVideo(name, type, id) {
var v = document.createElement("video");
+ v.preload = "metadata";
// Make sure each video is a unique resource
v.src = name + "?" + id;
v._name = name;
v.id = id;
register(v);
return v;
}
@@ -77,17 +64,17 @@ var test = getPlayableVideo(gSmallTests)
// Straightforward add, causing a load.
var v = createVideo(test.name, test.type, "1");
document.body.appendChild(v);
// Load, add, then remove.
v = createVideo(test.name, test.type, "1");
v.load();
document.body.appendChild(v);
-v.parentNode.removeChild(v);
+v.remove();
// Load and add.
v = createVideo(test.name, test.type, "2");
v.load();
document.body.appendChild(v);
// Load outside of doc.
v = createVideo(test.name, test.type, "3");
--- a/dom/apps/PermissionsTable.jsm
+++ b/dom/apps/PermissionsTable.jsm
@@ -488,22 +488,16 @@ this.PermissionsTable = { geolocation:
access: ["read", "write"],
additional: ["settings-api"]
},
"engineering-mode": {
app: DENY_ACTION,
trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
- },
- "before-after-keyboard-event": {
- app: DENY_ACTION,
- trusted: DENY_ACTION,
- privileged: DENY_ACTION,
- certified: ALLOW_ACTION
}
};
/**
* Append access modes to the permission name as suffixes.
* e.g. permission name 'contacts' with ['read', 'write'] =
* ['contacts-read', contacts-write']
* @param string aPermName
--- a/dom/base/test/test_window_enumeration.html
+++ b/dom/base/test/test_window_enumeration.html
@@ -8,27 +8,24 @@ https://bugzilla.mozilla.org/show_bug.cg
<title>Test for Bug 807222</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.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=807222">Mozilla Bug 807222</a>
<p id="display"></p>
<div id="content" style="display: none">
-
+
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 807222 **/
var expectedProps = [ "Image", "Audio", "Option",
"PerformanceTiming", "CSS2Properties", "SVGElement" ];
-if (navigator.mozTelephony) {
- expectedProps.push("USSDReceivedEvent");
-}
var actualProps = Object.getOwnPropertyNames(window);
for (var i = 0; i < expectedProps.length; ++i) {
isnot(actualProps.indexOf(expectedProps[i]), -1,
"getOwnPropertyNames should include " + expectedProps[i]);
}
</script>
</pre>
--- a/dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp
@@ -188,31 +188,71 @@ public:
BluetoothA2dpManager* a2dpManager = BluetoothA2dpManager::Get();
sBtAvrcpInterface->Init(a2dpManager, new InitAvrcpResultHandler(mRes));
}
private:
nsRefPtr<BluetoothProfileResultHandler> mRes;
};
+class OnErrorProfileResultHandlerRunnable MOZ_FINAL : public nsRunnable
+{
+public:
+ OnErrorProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes,
+ nsresult aRv)
+ : mRes(aRes)
+ , mRv(aRv)
+ {
+ MOZ_ASSERT(mRes);
+ }
+
+ NS_IMETHOD Run() MOZ_OVERRIDE
+ {
+ mRes->OnError(mRv);
+ return NS_OK;
+ }
+
+private:
+ nsRefPtr<BluetoothProfileResultHandler> mRes;
+ nsresult mRv;
+};
+
/*
* This function will be only called when Bluetooth is turning on.
* It is important to register a2dp callbacks before enable() gets called.
* It is required to register a2dp callbacks before a2dp media task
* starts up.
*/
// static
void
BluetoothA2dpManager::InitA2dpInterface(BluetoothProfileResultHandler* aRes)
{
BluetoothInterface* btInf = BluetoothInterface::GetInstance();
- NS_ENSURE_TRUE_VOID(btInf);
+ if (NS_WARN_IF(!btInf)) {
+ // If there's no HFP interface, we dispatch a runnable
+ // that calls the profile result handler.
+ nsRefPtr<nsRunnable> r =
+ new OnErrorProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
+ if (NS_FAILED(NS_DispatchToMainThread(r))) {
+ BT_LOGR("Failed to dispatch HFP OnError runnable");
+ }
+ return;
+ }
sBtA2dpInterface = btInf->GetBluetoothA2dpInterface();
- NS_ENSURE_TRUE_VOID(sBtA2dpInterface);
+ if (NS_WARN_IF(!sBtA2dpInterface)) {
+ // If there's no HFP interface, we dispatch a runnable
+ // that calls the profile result handler.
+ nsRefPtr<nsRunnable> r =
+ new OnErrorProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
+ if (NS_FAILED(NS_DispatchToMainThread(r))) {
+ BT_LOGR("Failed to dispatch HFP OnError runnable");
+ }
+ return;
+ }
BluetoothA2dpManager* a2dpManager = BluetoothA2dpManager::Get();
sBtA2dpInterface->Init(a2dpManager, new InitA2dpResultHandler(aRes));
}
BluetoothA2dpManager::~BluetoothA2dpManager()
{
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
@@ -336,16 +376,21 @@ public:
}
}
void Cleanup() MOZ_OVERRIDE
{
sBtA2dpInterface = nullptr;
if (sBtAvrcpInterface) {
sBtAvrcpInterface->Cleanup(new CleanupAvrcpResultHandler(mRes));
+ } else if (mRes) {
+ /* Not all backends support AVRCP. If it's not available
+ * we signal success from here.
+ */
+ mRes->Deinit();
}
}
private:
nsRefPtr<BluetoothProfileResultHandler> mRes;
};
class CleanupA2dpResultHandlerRunnable MOZ_FINAL : public nsRunnable
@@ -355,16 +400,21 @@ public:
: mRes(aRes)
{ }
NS_IMETHOD Run() MOZ_OVERRIDE
{
sBtA2dpInterface = nullptr;
if (sBtAvrcpInterface) {
sBtAvrcpInterface->Cleanup(new CleanupAvrcpResultHandler(mRes));
+ } else if (mRes) {
+ /* Not all backends support AVRCP. If it's not available
+ * we signal success from here.
+ */
+ mRes->Deinit();
}
return NS_OK;
}
private:
nsRefPtr<BluetoothProfileResultHandler> mRes;
};
--- a/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp
@@ -324,26 +324,66 @@ public:
mRes->RunInit();
return NS_OK;
}
private:
nsRefPtr<CleanupInitResultHandler> mRes;
};
+class OnErrorProfileResultHandlerRunnable MOZ_FINAL : public nsRunnable
+{
+public:
+ OnErrorProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes,
+ nsresult aRv)
+ : mRes(aRes)
+ , mRv(aRv)
+ {
+ MOZ_ASSERT(mRes);
+ }
+
+ NS_IMETHOD Run() MOZ_OVERRIDE
+ {
+ mRes->OnError(mRv);
+ return NS_OK;
+ }
+
+private:
+ nsRefPtr<BluetoothProfileResultHandler> mRes;
+ nsresult mRv;
+};
+
// static
void
BluetoothHfpManager::InitHfpInterface(BluetoothProfileResultHandler* aRes)
{
BluetoothInterface* btInf = BluetoothInterface::GetInstance();
- NS_ENSURE_TRUE_VOID(btInf);
+ if (NS_WARN_IF(!btInf)) {
+ // If there's no backend interface, we dispatch a runnable
+ // that calls the profile result handler.
+ nsRefPtr<nsRunnable> r =
+ new OnErrorProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
+ if (NS_FAILED(NS_DispatchToMainThread(r))) {
+ BT_LOGR("Failed to dispatch HFP OnError runnable");
+ }
+ return;
+ }
BluetoothHandsfreeInterface *interface =
btInf->GetBluetoothHandsfreeInterface();
- NS_ENSURE_TRUE_VOID(interface);
+ if (NS_WARN_IF(!interface)) {
+ // If there's no HFP interface, we dispatch a runnable
+ // that calls the profile result handler.
+ nsRefPtr<nsRunnable> r =
+ new OnErrorProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
+ if (NS_FAILED(NS_DispatchToMainThread(r))) {
+ BT_LOGR("Failed to dispatch HFP OnError runnable");
+ }
+ return;
+ }
nsRefPtr<CleanupInitResultHandler> res =
new CleanupInitResultHandler(interface, aRes);
if (sBluetoothHfpInterface) {
// Cleanup an initialized HFP before initializing again.
sBluetoothHfpInterface->Cleanup(res);
} else {
--- a/dom/bluetooth2/bluedroid/BluetoothA2dpManager.cpp
+++ b/dom/bluetooth2/bluedroid/BluetoothA2dpManager.cpp
@@ -192,40 +192,68 @@ public:
BluetoothA2dpManager* a2dpManager = BluetoothA2dpManager::Get();
sBtAvrcpInterface->Init(a2dpManager, new InitAvrcpResultHandler(mRes));
}
private:
nsRefPtr<BluetoothProfileResultHandler> mRes;
};
+class OnErrorProfileResultHandlerRunnable MOZ_FINAL : public nsRunnable
+{
+public:
+ OnErrorProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes,
+ nsresult aRv)
+ : mRes(aRes)
+ , mRv(aRv)
+ {
+ MOZ_ASSERT(mRes);
+ }
+
+ NS_IMETHOD Run() MOZ_OVERRIDE
+ {
+ mRes->OnError(mRv);
+ return NS_OK;
+ }
+
+private:
+ nsRefPtr<BluetoothProfileResultHandler> mRes;
+ nsresult mRv;
+};
+
/*
* This function will be only called when Bluetooth is turning on.
* It is important to register a2dp callbacks before enable() gets called.
* It is required to register a2dp callbacks before a2dp media task
* starts up.
*/
// static
void
BluetoothA2dpManager::InitA2dpInterface(BluetoothProfileResultHandler* aRes)
{
BluetoothInterface* btInf = BluetoothInterface::GetInstance();
- if (!btInf) {
- BT_LOGR("Error: Bluetooth interface not available");
- if (aRes) {
- aRes->OnError(NS_ERROR_FAILURE);
+ if (NS_WARN_IF(!btInf)) {
+ // If there's no backend interface, we dispatch a runnable
+ // that calls the profile result handler.
+ nsRefPtr<nsRunnable> r =
+ new OnErrorProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
+ if (NS_FAILED(NS_DispatchToMainThread(r))) {
+ BT_LOGR("Failed to dispatch HFP OnError runnable");
}
return;
}
sBtA2dpInterface = btInf->GetBluetoothA2dpInterface();
- if (!sBtA2dpInterface) {
- BT_LOGR("Error: Bluetooth A2DP interface not available");
- if (aRes) {
- aRes->OnError(NS_ERROR_FAILURE);
+ if (NS_WARN_IF(!sBtA2dpInterface)) {
+ // If there's no A2DP interface, we dispatch a runnable
+ // that calls the profile result handler.
+ nsRefPtr<nsRunnable> r =
+ new OnErrorProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
+ if (NS_FAILED(NS_DispatchToMainThread(r))) {
+ BT_LOGR("Failed to dispatch HFP OnError runnable");
}
return;
}
BluetoothA2dpManager* a2dpManager = BluetoothA2dpManager::Get();
sBtA2dpInterface->Init(a2dpManager, new InitA2dpResultHandler(aRes));
}
@@ -352,16 +380,21 @@ public:
}
}
void Cleanup() MOZ_OVERRIDE
{
sBtA2dpInterface = nullptr;
if (sBtAvrcpInterface) {
sBtAvrcpInterface->Cleanup(new CleanupAvrcpResultHandler(mRes));
+ } else if (mRes) {
+ /* Not all backends support AVRCP. If it's not available
+ * we signal success from here.
+ */
+ mRes->Deinit();
}
}
private:
nsRefPtr<BluetoothProfileResultHandler> mRes;
};
class CleanupA2dpResultHandlerRunnable MOZ_FINAL : public nsRunnable
@@ -371,16 +404,21 @@ public:
: mRes(aRes)
{ }
NS_IMETHOD Run() MOZ_OVERRIDE
{
sBtA2dpInterface = nullptr;
if (sBtAvrcpInterface) {
sBtAvrcpInterface->Cleanup(new CleanupAvrcpResultHandler(mRes));
+ } else if (mRes) {
+ /* Not all backends support AVRCP. If it's not available
+ * we signal success from here.
+ */
+ mRes->Deinit();
}
return NS_OK;
}
private:
nsRefPtr<BluetoothProfileResultHandler> mRes;
};
--- a/dom/bluetooth2/bluedroid/hfp/BluetoothHfpManager.cpp
+++ b/dom/bluetooth2/bluedroid/hfp/BluetoothHfpManager.cpp
@@ -315,35 +315,63 @@ public:
mRes->RunInit();
return NS_OK;
}
private:
nsRefPtr<CleanupInitResultHandler> mRes;
};
+class OnErrorProfileResultHandlerRunnable MOZ_FINAL : public nsRunnable
+{
+public:
+ OnErrorProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes,
+ nsresult aRv)
+ : mRes(aRes)
+ , mRv(aRv)
+ {
+ MOZ_ASSERT(mRes);
+ }
+
+ NS_IMETHOD Run() MOZ_OVERRIDE
+ {
+ mRes->OnError(mRv);
+ return NS_OK;
+ }
+
+private:
+ nsRefPtr<BluetoothProfileResultHandler> mRes;
+ nsresult mRv;
+};
+
// static
void
BluetoothHfpManager::InitHfpInterface(BluetoothProfileResultHandler* aRes)
{
BluetoothInterface* btInf = BluetoothInterface::GetInstance();
- if (!btInf) {
- BT_LOGR("Error: Bluetooth interface not available");
- if (aRes) {
- aRes->OnError(NS_ERROR_FAILURE);
+ if (NS_WARN_IF(!btInf)) {
+ // If there's no backend interface, we dispatch a runnable
+ // that calls the profile result handler.
+ nsRefPtr<nsRunnable> r =
+ new OnErrorProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
+ if (NS_FAILED(NS_DispatchToMainThread(r))) {
+ BT_LOGR("Failed to dispatch HFP OnError runnable");
}
return;
}
BluetoothHandsfreeInterface *interface =
btInf->GetBluetoothHandsfreeInterface();
- if (!interface) {
- BT_LOGR("Error: Bluetooth Handsfree interface not available");
- if (aRes) {
- aRes->OnError(NS_ERROR_FAILURE);
+ if (NS_WARN_IF(!interface)) {
+ // If there's no HFP interface, we dispatch a runnable
+ // that calls the profile result handler.
+ nsRefPtr<nsRunnable> r =
+ new OnErrorProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
+ if (NS_FAILED(NS_DispatchToMainThread(r))) {
+ BT_LOGR("Failed to dispatch HFP OnError runnable");
}
return;
}
nsRefPtr<CleanupInitResultHandler> res =
new CleanupInitResultHandler(interface, aRes);
if (sBluetoothHfpInterface) {
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -1214,17 +1214,17 @@ CanvasRenderingContext2D::EnsureTarget(R
}
if (layerManager) {
if (mode == RenderingMode::OpenGLBackendMode && CheckSizeForSkiaGL(size)) {
DemoteOldestContextIfNecessary();
SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
-#if USE_SKIA
+#if USE_SKIA_GPU
if (glue && glue->GetGrContext() && glue->GetGLContext()) {
mTarget = Factory::CreateDrawTargetSkiaWithGrContext(glue->GetGrContext(), size, format);
if (mTarget) {
AddDemotableContext(this);
} else {
printf_stderr("Failed to create a SkiaGL DrawTarget, falling back to software\n");
mode = RenderingMode::SoftwareBackendMode;
}
deleted file mode 100644
--- a/dom/events/BeforeAfterKeyboardEvent.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/dom/BeforeAfterKeyboardEvent.h"
-#include "mozilla/TextEvents.h"
-#include "prtime.h"
-
-namespace mozilla {
-namespace dom {
-
-BeforeAfterKeyboardEvent::BeforeAfterKeyboardEvent(
- EventTarget* aOwner,
- nsPresContext* aPresContext,
- InternalBeforeAfterKeyboardEvent* aEvent)
- : KeyboardEvent(aOwner, aPresContext,
- aEvent ? aEvent :
- new InternalBeforeAfterKeyboardEvent(false, 0,
- nullptr))
-{
- MOZ_ASSERT(mEvent->mClass == eBeforeAfterKeyboardEventClass,
- "event type mismatch eBeforeAfterKeyboardEventClass");
-
- if (!aEvent) {
- mEventIsInternal = true;
- mEvent->time = PR_Now();
- }
-}
-
-// static
-already_AddRefed<BeforeAfterKeyboardEvent>
-BeforeAfterKeyboardEvent::Constructor(
- EventTarget* aOwner,
- const nsAString& aType,
- const BeforeAfterKeyboardEventInit& aParam)
-{
- nsRefPtr<BeforeAfterKeyboardEvent> event =
- new BeforeAfterKeyboardEvent(aOwner, nullptr, nullptr);
- ErrorResult rv;
- event->InitWithKeyboardEventInit(aOwner, aType, aParam, rv);
- NS_WARN_IF(rv.Failed());
-
- event->mEvent->AsBeforeAfterKeyboardEvent()->mEmbeddedCancelled =
- aParam.mEmbeddedCancelled;
-
- return event.forget();
-}
-
-// static
-already_AddRefed<BeforeAfterKeyboardEvent>
-BeforeAfterKeyboardEvent::Constructor(
- const GlobalObject& aGlobal,
- const nsAString& aType,
- const BeforeAfterKeyboardEventInit& aParam,
- ErrorResult& aRv)
-{
- nsCOMPtr<EventTarget> owner = do_QueryInterface(aGlobal.GetAsSupports());
- return Constructor(owner, aType, aParam);
-}
-
-Nullable<bool>
-BeforeAfterKeyboardEvent::GetEmbeddedCancelled()
-{
- nsAutoString type;
- GetType(type);
- if (type.EqualsLiteral("mozbrowserafterkeydown") ||
- type.EqualsLiteral("mozbrowserafterkeyup")) {
- return mEvent->AsBeforeAfterKeyboardEvent()->mEmbeddedCancelled;
- }
- return Nullable<bool>();
-}
-
-} // namespace dom
-} // namespace mozilla
-
-using namespace mozilla;
-using namespace mozilla::dom;
-
-nsresult
-NS_NewDOMBeforeAfterKeyboardEvent(nsIDOMEvent** aInstancePtrResult,
- EventTarget* aOwner,
- nsPresContext* aPresContext,
- InternalBeforeAfterKeyboardEvent* aEvent)
-{
- BeforeAfterKeyboardEvent* it =
- new BeforeAfterKeyboardEvent(aOwner, aPresContext, aEvent);
-
- NS_ADDREF(it);
- *aInstancePtrResult = static_cast<Event*>(it);
- return NS_OK;
-}
deleted file mode 100644
--- a/dom/events/BeforeAfterKeyboardEvent.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_BeforeAfterKeyboardEvent_h_
-#define mozilla_dom_BeforeAfterKeyboardEvent_h_
-
-#include "mozilla/dom/KeyboardEvent.h"
-#include "mozilla/dom/BeforeAfterKeyboardEventBinding.h"
-
-namespace mozilla {
-namespace dom {
-
-class BeforeAfterKeyboardEvent : public KeyboardEvent
-{
-public:
- BeforeAfterKeyboardEvent(EventTarget* aOwner,
- nsPresContext* aPresContext,
- InternalBeforeAfterKeyboardEvent* aEvent);
-
- virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE
- {
- return BeforeAfterKeyboardEventBinding::Wrap(aCx, this);
- }
-
- static already_AddRefed<BeforeAfterKeyboardEvent>
- Constructor(const GlobalObject& aGlobal,
- const nsAString& aType,
- const BeforeAfterKeyboardEventInit& aParam,
- ErrorResult& aRv);
-
- static already_AddRefed<BeforeAfterKeyboardEvent>
- Constructor(EventTarget* aOwner, const nsAString& aType,
- const BeforeAfterKeyboardEventInit& aEventInitDict);
-
- // This function returns a boolean value when event typs is either
- // "mozbrowserafterkeydown" or "mozbrowserafterkeyup".
- Nullable<bool> GetEmbeddedCancelled();
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_BeforeAfterKeyboardEvent_h_
--- a/dom/events/EventDispatcher.cpp
+++ b/dom/events/EventDispatcher.cpp
@@ -696,19 +696,16 @@ EventDispatcher::CreateEvent(EventTarget
return NS_NewDOMUIEvent(aDOMEvent, aOwner, aPresContext,
aEvent->AsGUIEvent());
case eScrollAreaEventClass:
return NS_NewDOMScrollAreaEvent(aDOMEvent, aOwner, aPresContext,
aEvent->AsScrollAreaEvent());
case eKeyboardEventClass:
return NS_NewDOMKeyboardEvent(aDOMEvent, aOwner, aPresContext,
aEvent->AsKeyboardEvent());
- case eBeforeAfterKeyboardEventClass:
- return NS_NewDOMBeforeAfterKeyboardEvent(aDOMEvent, aOwner, aPresContext,
- aEvent->AsBeforeAfterKeyboardEvent());
case eCompositionEventClass:
return NS_NewDOMCompositionEvent(aDOMEvent, aOwner, aPresContext,
aEvent->AsCompositionEvent());
case eMouseEventClass:
return NS_NewDOMMouseEvent(aDOMEvent, aOwner, aPresContext,
aEvent->AsMouseEvent());
case eFocusEventClass:
return NS_NewDOMFocusEvent(aDOMEvent, aOwner, aPresContext,
--- a/dom/events/EventNameList.h
+++ b/dom/events/EventNameList.h
@@ -232,32 +232,16 @@ EVENT(keydown,
EVENT(keypress,
NS_KEY_PRESS,
EventNameType_HTMLXUL,
eKeyboardEventClass)
EVENT(keyup,
NS_KEY_UP,
EventNameType_HTMLXUL,
eKeyboardEventClass)
-NON_IDL_EVENT(mozbrowserbeforekeydown,
- NS_KEY_BEFORE_DOWN,
- EventNameType_None,
- eBeforeAfterKeyboardEventClass)
-NON_IDL_EVENT(mozbrowserafterkeydown,
- NS_KEY_AFTER_DOWN,
- EventNameType_None,
- eBeforeAfterKeyboardEventClass)
-NON_IDL_EVENT(mozbrowserbeforekeyup,
- NS_KEY_BEFORE_UP,
- EventNameType_None,
- eBeforeAfterKeyboardEventClass)
-NON_IDL_EVENT(mozbrowserafterkeyup,
- NS_KEY_AFTER_UP,
- EventNameType_None,
- eBeforeAfterKeyboardEventClass)
EVENT(loadeddata,
NS_LOADEDDATA,
EventNameType_HTML,
eBasicEventClass)
EVENT(loadedmetadata,
NS_LOADEDMETADATA,
EventNameType_HTML,
eBasicEventClass)
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -646,22 +646,18 @@ EventStateManager::PreHandleEvent(nsPres
if (modifierMask &&
(modifierMask == Prefs::ChromeAccessModifierMask() ||
modifierMask == Prefs::ContentAccessModifierMask())) {
HandleAccessKey(aPresContext, keyEvent, aStatus, nullptr,
eAccessKeyProcessingNormal, modifierMask);
}
}
// then fall through...
- case NS_KEY_BEFORE_DOWN:
case NS_KEY_DOWN:
- case NS_KEY_AFTER_DOWN:
- case NS_KEY_BEFORE_UP:
case NS_KEY_UP:
- case NS_KEY_AFTER_UP:
{
nsIContent* content = GetFocusedContent();
if (content)
mCurrentTargetContent = content;
// NOTE: Don't refer TextComposition::IsComposing() since DOM Level 3
// Events defines that KeyboardEvent.isComposing is true when it's
// dispatched after compositionstart and compositionend.
@@ -3162,19 +3158,17 @@ EventStateManager::PostHandleEvent(nsPre
break;
}
case NS_DRAGDROP_EXIT:
// make sure to fire the enter and exit_synth events after the
// NS_DRAGDROP_EXIT event, otherwise we'll clean up too early
GenerateDragDropEnterExit(presContext, aEvent->AsDragEvent());
break;
- case NS_KEY_BEFORE_UP:
case NS_KEY_UP:
- case NS_KEY_AFTER_UP:
break;
case NS_KEY_PRESS:
if (nsEventStatus_eConsumeNoDefault != *aStatus) {
WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent();
//This is to prevent keyboard scrolling while alt modifier in use.
if (!keyEvent->IsAlt()) {
switch(keyEvent->keyCode) {
--- a/dom/events/KeyboardEvent.cpp
+++ b/dom/events/KeyboardEvent.cpp
@@ -12,18 +12,20 @@ namespace mozilla {
namespace dom {
KeyboardEvent::KeyboardEvent(EventTarget* aOwner,
nsPresContext* aPresContext,
WidgetKeyboardEvent* aEvent)
: UIEvent(aOwner, aPresContext,
aEvent ? aEvent : new WidgetKeyboardEvent(false, 0, nullptr))
, mInitializedByCtor(false)
- , mInitializedWhichValue(0)
+ , mInitialzedWhichValue(0)
{
+ NS_ASSERTION(mEvent->mClass == eKeyboardEventClass, "event type mismatch");
+
if (aEvent) {
mEventIsInternal = false;
}
else {
mEventIsInternal = true;
mEvent->time = PR_Now();
mEvent->AsKeyboardEvent()->mKeyNameIndex = KEY_NAME_INDEX_USE_STRING;
}
@@ -250,22 +252,18 @@ uint32_t
KeyboardEvent::CharCode()
{
// If this event is initialized with ctor, we shouldn't check event type.
if (mInitializedByCtor) {
return mEvent->AsKeyboardEvent()->charCode;
}
switch (mEvent->message) {
- case NS_KEY_BEFORE_DOWN:
+ case NS_KEY_UP:
case NS_KEY_DOWN:
- case NS_KEY_AFTER_DOWN:
- case NS_KEY_BEFORE_UP:
- case NS_KEY_UP:
- case NS_KEY_AFTER_UP:
return 0;
case NS_KEY_PRESS:
return mEvent->AsKeyboardEvent()->charCode;
}
return 0;
}
NS_IMETHODIMP
@@ -279,37 +277,36 @@ KeyboardEvent::GetKeyCode(uint32_t* aKey
uint32_t
KeyboardEvent::KeyCode()
{
// If this event is initialized with ctor, we shouldn't check event type.
if (mInitializedByCtor) {
return mEvent->AsKeyboardEvent()->keyCode;
}
- if (mEvent->HasKeyEventMessage()) {
+ switch (mEvent->message) {
+ case NS_KEY_UP:
+ case NS_KEY_PRESS:
+ case NS_KEY_DOWN:
return mEvent->AsKeyboardEvent()->keyCode;
}
return 0;
}
uint32_t
KeyboardEvent::Which()
{
// If this event is initialized with ctor, which can have independent value.
if (mInitializedByCtor) {
- return mInitializedWhichValue;
+ return mInitialzedWhichValue;
}
switch (mEvent->message) {
- case NS_KEY_BEFORE_DOWN:
+ case NS_KEY_UP:
case NS_KEY_DOWN:
- case NS_KEY_AFTER_DOWN:
- case NS_KEY_BEFORE_UP:
- case NS_KEY_UP:
- case NS_KEY_AFTER_UP:
return KeyCode();
case NS_KEY_PRESS:
//Special case for 4xp bug 62878. Try to make value of which
//more closely mirror the values that 4.x gave for RETURN and BACKSPACE
{
uint32_t keyCode = mEvent->AsKeyboardEvent()->keyCode;
if (keyCode == NS_VK_RETURN || keyCode == NS_VK_BACK) {
return keyCode;
@@ -341,45 +338,36 @@ already_AddRefed<KeyboardEvent>
KeyboardEvent::Constructor(const GlobalObject& aGlobal,
const nsAString& aType,
const KeyboardEventInit& aParam,
ErrorResult& aRv)
{
nsCOMPtr<EventTarget> target = do_QueryInterface(aGlobal.GetAsSupports());
nsRefPtr<KeyboardEvent> newEvent =
new KeyboardEvent(target, nullptr, nullptr);
- newEvent->InitWithKeyboardEventInit(target, aType, aParam, aRv);
-
- return newEvent.forget();
-}
+ bool trusted = newEvent->Init(target);
+ aRv = newEvent->InitKeyEvent(aType, aParam.mBubbles, aParam.mCancelable,
+ aParam.mView, aParam.mCtrlKey, aParam.mAltKey,
+ aParam.mShiftKey, aParam.mMetaKey,
+ aParam.mKeyCode, aParam.mCharCode);
+ newEvent->SetTrusted(trusted);
+ newEvent->mDetail = aParam.mDetail;
+ newEvent->mInitializedByCtor = true;
+ newEvent->mInitialzedWhichValue = aParam.mWhich;
-void
-KeyboardEvent::InitWithKeyboardEventInit(EventTarget* aOwner,
- const nsAString& aType,
- const KeyboardEventInit& aParam,
- ErrorResult& aRv)
-{
- bool trusted = Init(aOwner);
- aRv = InitKeyEvent(aType, aParam.mBubbles, aParam.mCancelable,
- aParam.mView, aParam.mCtrlKey, aParam.mAltKey,
- aParam.mShiftKey, aParam.mMetaKey,
- aParam.mKeyCode, aParam.mCharCode);
- SetTrusted(trusted);
- mDetail = aParam.mDetail;
- mInitializedByCtor = true;
- mInitializedWhichValue = aParam.mWhich;
-
- WidgetKeyboardEvent* internalEvent = mEvent->AsKeyboardEvent();
+ WidgetKeyboardEvent* internalEvent = newEvent->mEvent->AsKeyboardEvent();
internalEvent->location = aParam.mLocation;
internalEvent->mIsRepeat = aParam.mRepeat;
internalEvent->mIsComposing = aParam.mIsComposing;
internalEvent->mKeyNameIndex = KEY_NAME_INDEX_USE_STRING;
+ internalEvent->mKeyValue = aParam.mKey;
internalEvent->mCodeNameIndex = CODE_NAME_INDEX_USE_STRING;
- internalEvent->mKeyValue = aParam.mKey;
internalEvent->mCodeValue = aParam.mCode;
+
+ return newEvent.forget();
}
NS_IMETHODIMP
KeyboardEvent::InitKeyEvent(const nsAString& aType,
bool aCanBubble,
bool aCancelable,
nsIDOMWindow* aView,
bool aCtrlKey,
--- a/dom/events/KeyboardEvent.h
+++ b/dom/events/KeyboardEvent.h
@@ -69,27 +69,21 @@ public:
aRv = InitKeyEvent(aType, aCanBubble, aCancelable, aView,
aCtrlKey, aAltKey, aShiftKey,aMetaKey,
aKeyCode, aCharCode);
}
protected:
~KeyboardEvent() {}
- void InitWithKeyboardEventInit(EventTarget* aOwner,
- const nsAString& aType,
- const KeyboardEventInit& aParam,
- ErrorResult& aRv);
-
private:
// True, if the instance is created with Constructor().
bool mInitializedByCtor;
-
// If the instance is created with Constructor(), which may have independent
// value. mInitializedWhichValue stores it. I.e., this is invalid when
// mInitializedByCtor is false.
- uint32_t mInitializedWhichValue;
+ uint32_t mInitialzedWhichValue;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_KeyboardEvent_h_
--- a/dom/events/moz.build
+++ b/dom/events/moz.build
@@ -27,17 +27,16 @@ EXPORTS.mozilla += [
'KeyNameList.h',
'PhysicalKeyCodeNameList.h',
'TextComposition.h',
'VirtualKeyCodeList.h',
]
EXPORTS.mozilla.dom += [
'AnimationEvent.h',
- 'BeforeAfterKeyboardEvent.h',
'BeforeUnloadEvent.h',
'ClipboardEvent.h',
'CommandEvent.h',
'CompositionEvent.h',
'CustomEvent.h',
'DataContainerEvent.h',
'DataTransfer.h',
'DeviceMotionEvent.h',
@@ -67,17 +66,16 @@ EXPORTS.mozilla.dom += [
]
if CONFIG['MOZ_WEBSPEECH']:
EXPORTS.mozilla.dom += ['SpeechRecognitionError.h']
UNIFIED_SOURCES += [
'AnimationEvent.cpp',
'AsyncEventDispatcher.cpp',
- 'BeforeAfterKeyboardEvent.cpp',
'BeforeUnloadEvent.cpp',
'ClipboardEvent.cpp',
'CommandEvent.cpp',
'CompositionEvent.cpp',
'ContentEventHandler.cpp',
'DataContainerEvent.cpp',
'DataTransfer.cpp',
'DeviceMotionEvent.cpp',
deleted file mode 100644
--- a/dom/events/test/bug989198_embedded.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Embedded iframe</title>
- <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body onload="getFocus();">
- <p id="display"></p>
- <div id="content" style="display: none"></div>
- <input id="input" style="display: block;">
- <pre id="test">
- <script type="application/javascript">
- function getFocus() {
- input = document.getElementById("input");
- input.focus();
- }
- </script>
-</body>
-</html>
deleted file mode 100644
--- a/dom/events/test/bug989198_helper.js
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Constants and helper functions for testing BeforeAfterKeyboardEvent.
- */
-
-const kUnknownEvent = 0x000;
-const kKeyDownEvent = 0x001;
-const kKeyUpEvent = 0x002;
-const kBeforeEvent = 0x010;
-const kAfterEvent = 0x020;
-const kParent = 0x100;
-const kChild = 0x200;
-
-var gCurrentTest;
-
-function frameScript()
-{
- function handler(e) {
- var results = sendSyncMessage("forwardevent", { type: e.type });
- if (results[0]) {
- e.preventDefault();
- }
- }
- addEventListener('keydown', handler);
- addEventListener('keyup', handler);
- addEventListener('mozbrowserbeforekeydown', handler);
- addEventListener('mozbrowserbeforekeyup', handler);
- addEventListener('mozbrowserafterkeydown', handler);
- addEventListener('mozbrowserafterkeyup', handler);
-}
-
-function prepareTest(useRemote)
-{
- setupHandlers(window, embedderHandler);
-
- var iframe = document.createElement("iframe");
- iframe.id = "embedded";
- iframe.src = "bug989198_embedded.html";
- iframe.setAttribute("remote", useRemote ? "true" : "false");
- SpecialPowers.wrap(iframe).mozbrowser = true;
-
- iframe.addEventListener("mozbrowserloadend", function onloadend() {
- iframe.removeEventListener("mozbrowserloadend", onloadend);
- iframe.focus();
- var mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
- mm.addMessageListener("forwardevent", function(msg) {
- return embeddedHandler(msg.json);
- });
- mm.loadFrameScript("data:,(" + frameScript.toString() + ")();", false);
- runTests();
- return;
- });
-
- document.body.appendChild(iframe);
-}
-
-function cleanupTest()
-{
- teardownHandlers(window, embedderHandler);
- runTests();
-}
-
-function setupHandlers(element, handler)
-{
- element.addEventListener('keydown', handler);
- element.addEventListener('keyup', handler);
- element.addEventListener('mozbrowserbeforekeydown', handler);
- element.addEventListener('mozbrowserbeforekeyup', handler);
- element.addEventListener('mozbrowserafterkeydown', handler);
- element.addEventListener('mozbrowserafterkeyup', handler);
-}
-
-function teardownHandlers(element, handler)
-{
- element.removeEventListener('keydown', handler);
- element.removeEventListener('keyup', handler);
- element.removeEventListener('mozbrowserbeforekeydown', handler);
- element.removeEventListener('mozbrowserbeforekeyup', handler);
- element.removeEventListener('mozbrowserafterkeydown', handler);
- element.removeEventListener('mozbrowserafterkeyup', handler);
-}
-
-function convertNameToCode(name)
-{
- switch (name) {
- case "mozbrowserbeforekeydown":
- return kBeforeEvent | kKeyDownEvent;
- case "mozbrowserafterkeydown":
- return kAfterEvent | kKeyDownEvent;
- case "mozbrowserbeforekeyup":
- return kBeforeEvent | kKeyUpEvent;
- case "mozbrowserafterkeyup":
- return kAfterEvent | kKeyUpEvent;
- case "keydown":
- return kKeyDownEvent;
- case "keyup":
- return kKeyUpEvent;
- default:
- return kUnknownEvent;
- }
-}
-
-function classifyEvents(test)
-{
- // Categorize resultEvents into KEYDOWN group and KEYUP group.
- for (var i = 0; i < gCurrentTest.resultEvents.length ; i++) {
- var code = test.resultEvents[i];
- if ((code & 0xF) == 0x1) { // KEYDOWN
- test.classifiedEvents[0].push(code);
- } else if ((code & 0xF) == 0x2) { // KEYUP
- test.classifiedEvents[1].push(code);
- } else {
- ok(false, "Invalid code for events");
- }
- }
-}
-
-function verifyResults(test)
-{
- for (var i = 0; i < gCurrentTest.expectedEvents.length; i++) {
- is(test.classifiedEvents[i].length,
- test.expectedEvents[i].length,
- test.description + ": Wrong number of events");
-
- for (var j = 0; j < gCurrentTest.classifiedEvents[i].length; j++) {
- var item = test.classifiedEvents[i][j];
- is(item, test.expectedEvents[i][j],
- test.description + ": Wrong order of events");
- }
- }
-}
-
-function embeddedHandler(e)
-{
- return handler(e, kChild);
-}
-
-function embedderHandler(e)
-{
- // Verify value of attribute embeddedCancelled
- handler(e, kParent, function checkEmbeddedCancelled(code){
- switch (code) {
- case kBeforeEvent | kKeyDownEvent:
- case kBeforeEvent | kKeyUpEvent:
- is(e.embeddedCancelled, null,
- gCurrentTest.description + ': embeddedCancelled should be null');
- break;
- case kAfterEvent | kKeyDownEvent:
- if ((gCurrentTest.doPreventDefaultAt & 0xFF) == kKeyDownEvent) {
- is(e.embeddedCancelled, true,
- gCurrentTest.description + ': embeddedCancelled should be true');
- } else {
- is(e.embeddedCancelled, false,
- gCurrentTest.description + ': embeddedCancelled should be false');
- }
- break;
- case kAfterEvent | kKeyUpEvent:
- if ((gCurrentTest.doPreventDefaultAt & 0xFF) == kKeyUpEvent) {
- is(e.embeddedCancelled, true,
- gCurrentTest.description + ': embeddedCancelled should be true');
- } else {
- is(e.embeddedCancelled, false,
- gCurrentTest.description + ': embeddedCancelled should be false');
- }
- break;
- default:
- break;
- }
- });
-}
-
-function handler(e, highBit, callback)
-{
- var code = convertNameToCode(e.type);
- var newCode = highBit | code;
- gCurrentTest.resultEvents.push(newCode);
-
- if (callback) {
- callback(code);
- }
-
- // Return and let frameScript to handle
- if (highBit == kChild) {
- return newCode == gCurrentTest.doPreventDefaultAt;
- }
-
- if (newCode == gCurrentTest.doPreventDefaultAt) {
- e.preventDefault();
- }
-}
-
-function runTests()
-{
- if (!tests.length) {
- SimpleTest.finish();
- return;
- }
-
- var test = tests.shift();
- test();
-}
--- a/dom/events/test/mochitest.ini
+++ b/dom/events/test/mochitest.ini
@@ -162,17 +162,8 @@ skip-if = toolkit == 'android' #CRASH_DU
[test_focus_disabled.html]
skip-if = buildapp == 'mulet'
[test_messageEvent.html]
[test_moz_mouse_pixel_scroll_event.html]
skip-if = buildapp == 'mulet'
[test_onerror_handler_args.html]
[test_wheel_default_action.html]
skip-if = buildapp == 'mulet' || buildapp == 'b2g' || e10s
-[test_dom_before_after_keyboard_event.html]
-support-files =
- bug989198_embedded.html
- bug989198_helper.js
-[test_dom_before_after_keyboard_event_remote.html]
-support-files =
- bug989198_embedded.html
- bug989198_helper.js
-skip-if = buildapp == 'b2g' || e10s
--- a/dom/events/test/test_all_synthetic_events.html
+++ b/dom/events/test/test_all_synthetic_events.html
@@ -29,20 +29,16 @@ const kEventConstructors = {
},
},
AnimationEvent: { create: function (aName, aProps) {
return new AnimationEvent(aName, aProps);
},
},
AudioProcessingEvent: { create: null, // Cannot create untrusted event from JS.
},
- BeforeAfterKeyboardEvent: { create: function (aName, aProps) {
- return new BeforeAfterKeyboardEvent(aName, aProps);
- },
- },
BeforeUnloadEvent: { create: function (aName, aProps) {
var e = document.createEvent("beforeunloadevent");
e.initEvent(aName, aProps.bubbles, aProps.cancelable);
return e;
},
},
BlobEvent: { create: function (aName, aProps) {
return new BlobEvent(aName, aProps);
deleted file mode 100644
--- a/dom/events/test/test_dom_before_after_keyboard_event.html
+++ /dev/null
@@ -1,117 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Test for Bug 989198</title>
- <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
- <script type="text/javascript" src="/tests/SimpleTest/NativeKeyCodes.js"></script>
- <script type="text/javascript" src="bug989198_helper.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body onload="runTests();">
-<a target="_blank"
- href="https://bugzilla.mozilla.org/show_bug.cgi?id=989198">Mozilla Bug 989198</a>
-<p id="display"></p>
-<pre id="test">
-<script type="application/javascript">
-
-SimpleTest.waitForExplicitFinish();
-
-function testEventOrderAndAttr()
-{
- const mainDesc = 'Testing the order of the events';
- const kTests = [
- {
- description: mainDesc,
- expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
- kChild | kKeyDownEvent,
- kParent | kAfterEvent | kKeyDownEvent ],
- [ kParent | kBeforeEvent | kKeyUpEvent,
- kChild | kKeyUpEvent,
- kParent | kAfterEvent | kKeyUpEvent ] ],
- resultEvents: [],
- classifiedEvents: [ [], [] ],
- doPreventDefaultAt: kUnknownEvent
- },
- {
- description: mainDesc + ', calling preventDefault() at "mozbrowserbeforekeydown" event',
- expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
- kParent | kAfterEvent | kKeyDownEvent ],
- [ kParent | kBeforeEvent | kKeyUpEvent,
- kChild | kKeyUpEvent,
- kParent | kAfterEvent | kKeyUpEvent ] ],
- resultEvents: [],
- classifiedEvents: [ [], [] ],
- doPreventDefaultAt: kParent | kBeforeEvent | kKeyDownEvent
- },
- {
- description: mainDesc + ', calling preventDefault() at "mozbrowserbeforekeyup" event',
- expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
- kChild | kKeyDownEvent,
- kParent | kAfterEvent | kKeyDownEvent ],
- [ kParent | kBeforeEvent | kKeyUpEvent,
- kParent | kAfterEvent | kKeyUpEvent ] ],
- resultEvents: [],
- classifiedEvents: [ [], [] ],
- doPreventDefaultAt: kParent | kBeforeEvent | kKeyUpEvent
- },
- {
- description: mainDesc + ', calling preventDefault() at "keydown" event',
- expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
- kChild | kKeyDownEvent,
- kParent | kAfterEvent | kKeyDownEvent ],
- [ kParent | kBeforeEvent | kKeyUpEvent,
- kChild | kKeyUpEvent,
- kParent | kAfterEvent | kKeyUpEvent ] ],
- resultEvents: [],
- classifiedEvents: [ [], [] ],
- doPreventDefaultAt: kChild | kKeyDownEvent
- },
- {
- description: mainDesc + ', calling preventDefault() at "keyup" event',
- expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
- kChild | kKeyDownEvent,
- kParent | kAfterEvent | kKeyDownEvent ],
- [ kParent | kBeforeEvent | kKeyUpEvent,
- kChild | kKeyUpEvent,
- kParent | kAfterEvent | kKeyUpEvent ] ],
- resultEvents: [],
- classifiedEvents: [ [], [] ],
- doPreventDefaultAt: kChild | kKeyUpEvent
- }
- ];
-
- for (var k = 0; k < kTests.length; k++ ) {
- gCurrentTest = kTests[k];
- synthesizeKey('a', {}, document.getElementById("embedded").contentWindow);
- classifyEvents(kTests[k]);
- verifyResults(kTests[k]);
- }
-
- runTests();
-}
-
-var tests = [
- function addPermissions() {
- SpecialPowers.pushPermissions(
- [{ type: "before-after-keyboard-event", allow: true, context: document },
- { type: "browser", allow: true, context: document }],
- runTests);
- },
- function addPreferences() {
- SpecialPowers.pushPrefEnv(
- { "set": [["dom.beforeAfterKeyboardEvent.enabled", true],
- ["dom.mozBrowserFramesEnabled", true],
- ["dom.ipc.tabs.disabled", false]] },
- runTests);
- },
-
- // Tests for in-process iframe, i.e. <iframe mozbrowser>.
- ()=>prepareTest(false),
- testEventOrderAndAttr,
- cleanupTest,
-];
-
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/dom/events/test/test_dom_before_after_keyboard_event_remote.html
+++ /dev/null
@@ -1,142 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Test for Bug 989198</title>
- <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
- <script type="text/javascript" src="/tests/SimpleTest/NativeKeyCodes.js"></script>
- <script type="text/javascript" src="bug989198_helper.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body onload="runTests();">
-<a target="_blank"
- href="https://bugzilla.mozilla.org/show_bug.cgi?id=989198">Mozilla Bug 989198</a>
-<p id="display"></p>
-<div id="content">
-</div>
-<pre id="test">
-<script type="application/javascript">
-
-SimpleTest.waitForExplicitFinish();
-
-const mainDesc = 'Testing the order of the events (OOP)';
-var testsForEventOrder = [
- {
- description: mainDesc,
- expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
- kParent | kKeyDownEvent,
- kChild | kKeyDownEvent,
- kParent | kAfterEvent | kKeyDownEvent ],
- [ kParent | kBeforeEvent | kKeyUpEvent,
- kParent | kKeyUpEvent,
- kChild | kKeyUpEvent,
- kParent | kAfterEvent | kKeyUpEvent ] ],
- resultEvents: [],
- classifiedEvents: [ [], [] ],
- doPreventDefaultAt: kUnknownEvent
- },
- {
- description: mainDesc + ', calling preventDefault() at "mozbrowserbeforekeydown" event',
- expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
- kParent | kAfterEvent | kKeyDownEvent ],
- [ kParent | kBeforeEvent | kKeyUpEvent,
- kParent | kKeyUpEvent,
- kChild | kKeyUpEvent,
- kParent | kAfterEvent | kKeyUpEvent ] ],
- resultEvents: [],
- classifiedEvents: [ [], [] ],
- doPreventDefaultAt: kParent | kBeforeEvent | kKeyDownEvent
- },
- {
- description: mainDesc + ', calling preventDefault() at "mozbrowserbeforekeyup" event',
- expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
- kParent | kKeyDownEvent,
- kChild | kKeyDownEvent,
- kParent | kAfterEvent | kKeyDownEvent ],
- [ kParent | kBeforeEvent | kKeyUpEvent,
- kParent | kAfterEvent | kKeyUpEvent ] ],
- resultEvents: [],
- classifiedEvents: [ [], [] ],
- doPreventDefaultAt: kParent | kBeforeEvent | kKeyUpEvent
- },
- {
- description: mainDesc + ', calling preventDefault() at "keydown" event',
- expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
- kParent | kKeyDownEvent,
- kChild | kKeyDownEvent,
- kParent | kAfterEvent | kKeyDownEvent ],
- [ kParent | kBeforeEvent | kKeyUpEvent,
- kParent | kKeyUpEvent,
- kChild | kKeyUpEvent,
- kParent | kAfterEvent | kKeyUpEvent ] ],
- resultEvents: [],
- classifiedEvents: [ [], [] ],
- doPreventDefaultAt: kChild | kKeyDownEvent
- },
- {
- description: mainDesc + ', calling preventDefault() at "keyup" event',
- expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
- kParent | kKeyDownEvent,
- kChild | kKeyDownEvent,
- kParent | kAfterEvent | kKeyDownEvent ],
- [ kParent | kBeforeEvent | kKeyUpEvent,
- kParent | kKeyUpEvent,
- kChild | kKeyUpEvent,
- kParent | kAfterEvent | kKeyUpEvent ] ],
- resultEvents: [],
- classifiedEvents: [ [], [] ],
- doPreventDefaultAt: kChild | kKeyUpEvent
- }
-];
-
-function testEventOrder()
-{
- if (!testsForEventOrder.length) {
- runTests();
- return;
- }
- gCurrentTest = testsForEventOrder.shift();
-
- synthesizeKey('a', {}, document.getElementById("embedded").contentWindow);
- // It take some time to propagate events to a remote iframe.
-
- waitAndVerifyResult(0);
-}
-
-function waitAndVerifyResult(count) {
- expectedEventLength = gCurrentTest.expectedEvents[0].length +
- gCurrentTest.expectedEvents[1].length;
- if (gCurrentTest.resultEvents.length >= expectedEventLength || count > 10) {
- classifyEvents(gCurrentTest);
- verifyResults(gCurrentTest);
- testEventOrder();
- }
- else {
- setTimeout(()=>waitAndVerifyResult(count + 1), 100);
- }
-}
-
-var tests = [
- function addPermissions() {
- SpecialPowers.pushPermissions(
- [{ type: "before-after-keyboard-event", allow: true, context: document },
- { type: "browser", allow: true, context: document }],
- runTests);
- },
- function addPreferences() {
- SpecialPowers.pushPrefEnv(
- { "set": [["dom.beforeAfterKeyboardEvent.enabled", true],
- ["dom.mozBrowserFramesEnabled", true],
- ["dom.ipc.tabs.disabled", false]] },
- runTests);
- },
-
- // Tests for out-of-process iframe, i.el. <iframe mozbrowser remote>
- ()=>prepareTest(true),
- testEventOrder,
- cleanupTest
-];
-
-</script>
-</body>
-</html>
--- a/dom/interfaces/events/nsIDOMEvent.idl
+++ b/dom/interfaces/events/nsIDOMEvent.idl
@@ -267,23 +267,16 @@ NS_NewDOMInputEvent(nsIDOMEvent** aInsta
mozilla::dom::EventTarget* aOwner,
nsPresContext* aPresContext,
mozilla::InternalEditorInputEvent* aEvent);
nsresult
NS_NewDOMKeyboardEvent(nsIDOMEvent** aInstancePtrResult,
mozilla::dom::EventTarget* aOwner,
nsPresContext* aPresContext,
mozilla::WidgetKeyboardEvent* aEvent);
-
-nsresult
-NS_NewDOMBeforeAfterKeyboardEvent(nsIDOMEvent** aInstancePtrResult,
- mozilla::dom::EventTarget* aOwner,
- nsPresContext* aPresContext,
- mozilla::InternalBeforeAfterKeyboardEvent* aEvent);
-
nsresult
NS_NewDOMCompositionEvent(nsIDOMEvent** aInstancePtrResult,
mozilla::dom::EventTarget* aOwner,
nsPresContext* aPresContext,
mozilla::WidgetCompositionEvent* aEvent);
nsresult
NS_NewDOMMutationEvent(nsIDOMEvent** aResult,
mozilla::dom::EventTarget* aOwner,
--- a/dom/ipc/Blob.cpp
+++ b/dom/ipc/Blob.cpp
@@ -21,27 +21,29 @@
#include "mozilla/dom/nsIContentChild.h"
#include "mozilla/dom/PBlobStreamChild.h"
#include "mozilla/dom/PBlobStreamParent.h"
#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
#include "mozilla/ipc/InputStreamUtils.h"
#include "mozilla/ipc/PBackgroundChild.h"
#include "mozilla/ipc/PBackgroundParent.h"
#include "mozilla/ipc/PFileDescriptorSetParent.h"
+#include "MultipartFileImpl.h"
#include "nsDataHashtable.h"
#include "nsHashKeys.h"
#include "nsID.h"
#include "nsIInputStream.h"
#include "nsIIPCSerializableInputStream.h"
#include "nsIMultiplexInputStream.h"
#include "nsIRemoteBlob.h"
#include "nsISeekableStream.h"
#include "nsIUUIDGenerator.h"
#include "nsNetCID.h"
#include "nsServiceManagerUtils.h"
+#include "nsStringStream.h"
#include "nsThreadUtils.h"
#include "nsXULAppAPI.h"
#ifdef DEBUG
#include "BackgroundChild.h" // BackgroundChild::GetForCurrentThread().
#endif
#define DISABLE_ASSERTS_FOR_FUZZING 0
@@ -54,16 +56,17 @@
#define PRIVATE_REMOTE_INPUT_STREAM_IID \
{0x30c7699f, 0x51d2, 0x48c8, {0xad, 0x56, 0xc0, 0x16, 0xd7, 0x6f, 0x71, 0x27}}
namespace mozilla {
namespace dom {
using namespace mozilla::ipc;
+using namespace mozilla::dom::indexedDB;
namespace {
const char kUUIDGeneratorContractId[] = "@mozilla.org/uuid-generator;1";
StaticRefPtr<nsIUUIDGenerator> gUUIDGenerator;
GeckoProcessType gProcessType = GeckoProcessType_Invalid;
@@ -156,16 +159,34 @@ ActorManagerProcessID(PBackgroundParent*
{
AssertCorrectThreadForManager(aManager);
MOZ_ASSERT(aManager);
return BackgroundParent::GetRawContentParentForComparison(aManager);
}
bool
+ActorManagerIsSameProcess(nsIContentParent* aManager)
+{
+ AssertCorrectThreadForManager(aManager);
+ MOZ_ASSERT(aManager);
+
+ return false;
+}
+
+bool
+ActorManagerIsSameProcess(PBackgroundParent* aManager)
+{
+ AssertCorrectThreadForManager(aManager);
+ MOZ_ASSERT(aManager);
+
+ return !BackgroundParent::IsOtherProcessActor(aManager);
+}
+
+bool
EventTargetIsOnCurrentThread(nsIEventTarget* aEventTarget)
{
if (!aEventTarget) {
return NS_IsMainThread();
}
bool current;
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(aEventTarget->IsOnCurrentThread(¤t)));
@@ -323,17 +344,18 @@ class RemoteInputStream MOZ_FINAL
nsCOMPtr<nsIInputStream> mStream;
nsRefPtr<FileImpl> mBlobImpl;
nsCOMPtr<nsIEventTarget> mEventTarget;
nsISeekableStream* mWeakSeekableStream;
public:
NS_DECL_THREADSAFE_ISUPPORTS
- explicit RemoteInputStream(FileImpl* aBlobImpl)
+ explicit
+ RemoteInputStream(FileImpl* aBlobImpl)
: mMonitor("RemoteInputStream.mMonitor")
, mBlobImpl(aBlobImpl)
, mWeakSeekableStream(nullptr)
{
MOZ_ASSERT(IsOnOwningThread());
MOZ_ASSERT(aBlobImpl);
if (!NS_IsMainThread()) {
@@ -697,21 +719,482 @@ private:
// This method is only called by the IPDL message machinery.
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE
{
// Nothing needs to be done here.
}
};
+class EmptyBlobImpl MOZ_FINAL
+ : public FileImplBase
+{
+public:
+ EmptyBlobImpl(const nsAString& aContentType)
+ : FileImplBase(aContentType, 0)
+ {
+ mImmutable = true;
+ }
+
+ EmptyBlobImpl(const nsAString& aName,
+ const nsAString& aContentType,
+ uint64_t aLastModifiedDate)
+ : FileImplBase(aName, aContentType, 0, aLastModifiedDate)
+ {
+ mImmutable = true;
+ }
+
+private:
+ virtual already_AddRefed<FileImpl>
+ CreateSlice(uint64_t /* aStart */,
+ uint64_t aLength,
+ const nsAString& aContentType,
+ ErrorResult& /* aRv */) MOZ_OVERRIDE
+ {
+ MOZ_ASSERT(!aLength);
+
+ nsRefPtr<FileImpl> sliceImpl = new EmptyBlobImpl(aContentType);
+
+ DebugOnly<bool> isMutable;
+ MOZ_ASSERT(NS_SUCCEEDED(sliceImpl->GetMutable(&isMutable)));
+ MOZ_ASSERT(!isMutable);
+
+ return sliceImpl.forget();
+ }
+
+ virtual nsresult
+ GetInternalStream(nsIInputStream** aStream) MOZ_OVERRIDE
+ {
+ NS_ENSURE_ARG_POINTER(aStream);
+
+ nsString emptyString;
+ nsresult rv = NS_NewStringInputStream(aStream, emptyString);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ return NS_OK;
+ }
+};
+
+// This is only needed for IndexedDB FileImplSnapshot.
+class SameProcessInputStreamBlobImpl MOZ_FINAL
+ : public FileImplBase
+{
+ nsCOMPtr<nsIInputStream> mInputStream;
+
+public:
+ SameProcessInputStreamBlobImpl(const nsAString& aContentType,
+ uint64_t aLength,
+ nsIInputStream* aInputStream)
+ : FileImplBase(aContentType, aLength)
+ , mInputStream(aInputStream)
+ {
+ MOZ_ASSERT(aLength != UINT64_MAX);
+ MOZ_ASSERT(aInputStream);
+
+ mImmutable = true;
+ }
+
+ SameProcessInputStreamBlobImpl(const nsAString& aName,
+ const nsAString& aContentType,
+ uint64_t aLength,
+ uint64_t aLastModifiedDate,
+ nsIInputStream* aInputStream)
+ : FileImplBase(aName, aContentType, aLength, aLastModifiedDate)
+ , mInputStream(aInputStream)
+ {
+ MOZ_ASSERT(aLength != UINT64_MAX);
+ MOZ_ASSERT(aLastModifiedDate != UINT64_MAX);
+ MOZ_ASSERT(aInputStream);
+
+ mImmutable = true;
+ }
+
+private:
+ virtual already_AddRefed<FileImpl>
+ CreateSlice(uint64_t /* aStart */,
+ uint64_t /* aLength */,
+ const nsAString& /* aContentType */,
+ ErrorResult& /* aRv */) MOZ_OVERRIDE
+ {
+ MOZ_CRASH("Not implemented");
+ }
+
+ virtual nsresult
+ GetInternalStream(nsIInputStream** aStream) MOZ_OVERRIDE
+ {
+ NS_ENSURE_ARG_POINTER(aStream);
+
+ nsCOMPtr<nsIInputStream> inputStream = mInputStream;
+ inputStream.forget(aStream);
+ return NS_OK;
+ }
+};
+
+struct MOZ_STACK_CLASS CreateBlobImplMetadata MOZ_FINAL
+{
+ nsString mContentType;
+ nsString mName;
+ uint64_t mLength;
+ uint64_t mLastModifiedDate;
+ bool mHasRecursed;
+ bool mIsSameProcessActor;
+
+ CreateBlobImplMetadata()
+ : mLength(0)
+ , mLastModifiedDate(0)
+ , mHasRecursed(false)
+ , mIsSameProcessActor(false)
+ {
+ MOZ_COUNT_CTOR(CreateBlobImplMetadata);
+
+ mName.SetIsVoid(true);
+ }
+
+ ~CreateBlobImplMetadata()
+ {
+ MOZ_COUNT_DTOR(CreateBlobImplMetadata);
+ }
+
+ bool
+ IsFile() const
+ {
+ return !mName.IsVoid();
+ }
+};
+
+already_AddRefed<FileImpl>
+CreateBlobImplFromParams(const StringInputStreamParams& aParams,
+ const CreateBlobImplMetadata& aMetadata)
+{
+ static_assert(sizeof(aParams.data().Length()) <= sizeof(size_t),
+ "String length won't fit in size_t!");
+ static_assert(sizeof(size_t) <= sizeof(uint64_t),
+ "size_t won't fit in uint64_t!");
+
+ MOZ_ASSERT(gProcessType == GeckoProcessType_Default);
+
+ nsRefPtr<FileImpl> blobImpl;
+
+ if (auto length = static_cast<size_t>(aParams.data().Length())) {
+ if (!aMetadata.mHasRecursed &&
+ NS_WARN_IF(aMetadata.mLength != uint64_t(length))) {
+ ASSERT_UNLESS_FUZZING();
+ return nullptr;
+ }
+
+ void* buffer = moz_malloc(aParams.data().Length());
+ if (NS_WARN_IF(!buffer)) {
+ return nullptr;
+ }
+
+ memcpy(buffer, aParams.data().get(), length);
+
+ if (!aMetadata.mHasRecursed && aMetadata.IsFile()) {
+ blobImpl =
+ new FileImplMemory(buffer,
+ uint64_t(length),
+ aMetadata.mName,
+ aMetadata.mContentType,
+ aMetadata.mLastModifiedDate);
+ } else {
+ blobImpl =
+ new FileImplMemory(buffer, uint64_t(length), aMetadata.mContentType);
+ }
+ } else if (!aMetadata.mHasRecursed && aMetadata.IsFile()) {
+ blobImpl =
+ new EmptyBlobImpl(aMetadata.mName,
+ aMetadata.mContentType,
+ aMetadata.mLastModifiedDate);
+ } else {
+ blobImpl = new EmptyBlobImpl(aMetadata.mContentType);
+ }
+
+ MOZ_ALWAYS_TRUE(NS_SUCCEEDED(blobImpl->SetMutable(false)));
+
+ return blobImpl.forget();
+}
+
+already_AddRefed<FileImpl>
+CreateBlobImplFromParams(const RemoteInputStreamParams& aParams,
+ const CreateBlobImplMetadata& aMetadata)
+{
+ MOZ_ASSERT(gProcessType == GeckoProcessType_Default);
+ MOZ_ASSERT(aMetadata.mHasRecursed);
+
+ nsRefPtr<FileImpl> blobImpl = BlobParent::GetBlobImplForID(aParams.id());
+ if (NS_WARN_IF(!blobImpl)) {
+ ASSERT_UNLESS_FUZZING();
+ return nullptr;
+ }
+
+ DebugOnly<bool> isMutable;
+ MOZ_ASSERT(NS_SUCCEEDED(blobImpl->GetMutable(&isMutable)));
+ MOZ_ASSERT(!isMutable);
+
+ return blobImpl.forget();
+}
+
+already_AddRefed<FileImpl>
+CreateBlobImplFromParams(const SameProcessInputStreamParams& aParams,
+ const CreateBlobImplMetadata& aMetadata)
+{
+ MOZ_ASSERT(gProcessType == GeckoProcessType_Default);
+ MOZ_ASSERT(aMetadata.mIsSameProcessActor);
+ MOZ_ASSERT(aParams.addRefedInputStream());
+
+ nsCOMPtr<nsIInputStream> inputStream =
+ dont_AddRef(
+ reinterpret_cast<nsIInputStream*>(aParams.addRefedInputStream()));
+
+ nsRefPtr<FileImpl> blobImpl;
+ if (!aMetadata.mHasRecursed && aMetadata.IsFile()) {
+ blobImpl =
+ new SameProcessInputStreamBlobImpl(aMetadata.mName,
+ aMetadata.mContentType,
+ aMetadata.mLength,
+ aMetadata.mLastModifiedDate,
+ inputStream);
+ } else {
+ blobImpl =
+ new SameProcessInputStreamBlobImpl(aMetadata.mContentType,
+ aMetadata.mLength,
+ inputStream);
+ }
+
+ DebugOnly<bool> isMutable;
+ MOZ_ASSERT(NS_SUCCEEDED(blobImpl->GetMutable(&isMutable)));
+ MOZ_ASSERT(!isMutable);
+
+ return blobImpl.forget();
+}
+
+already_AddRefed<FileImpl>
+CreateBlobImplFromParams(const MultiplexInputStreamParams& aParams,
+ CreateBlobImplMetadata& aMetadata);
+
+already_AddRefed<FileImpl>
+CreateBlobImplFromInputStreamParams(const InputStreamParams& aParams,
+ CreateBlobImplMetadata& aMetadata)
+{
+ MOZ_ASSERT(gProcessType == GeckoProcessType_Default);
+
+ nsRefPtr<FileImpl> blobImpl;
+
+ switch (aParams.type()) {
+ case InputStreamParams::TStringInputStreamParams: {
+ const StringInputStreamParams& params =
+ aParams.get_StringInputStreamParams();
+ blobImpl = CreateBlobImplFromParams(params, aMetadata);
+ break;
+ }
+
+ case InputStreamParams::TFileInputStreamParams: {
+ ASSERT_UNLESS_FUZZING();
+ return nullptr;
+ }
+
+ case InputStreamParams::TPartialFileInputStreamParams: {
+ ASSERT_UNLESS_FUZZING();
+ return nullptr;
+ }
+
+ case InputStreamParams::TBufferedInputStreamParams: {
+ ASSERT_UNLESS_FUZZING();
+ return nullptr;
+ }
+
+ case InputStreamParams::TMIMEInputStreamParams: {
+ ASSERT_UNLESS_FUZZING();
+ return nullptr;
+ }
+
+ case InputStreamParams::TMultiplexInputStreamParams: {
+ const MultiplexInputStreamParams& params =
+ aParams.get_MultiplexInputStreamParams();
+ blobImpl = CreateBlobImplFromParams(params, aMetadata);
+ break;
+ }
+
+ case InputStreamParams::TRemoteInputStreamParams: {
+ if (NS_WARN_IF(!aMetadata.mHasRecursed)) {
+ ASSERT_UNLESS_FUZZING();
+ return nullptr;
+ }
+
+ const RemoteInputStreamParams& params =
+ aParams.get_RemoteInputStreamParams();
+ blobImpl = CreateBlobImplFromParams(params, aMetadata);
+ break;
+ }
+
+ case InputStreamParams::TSameProcessInputStreamParams: {
+ if (NS_WARN_IF(!aMetadata.mIsSameProcessActor)) {
+ ASSERT_UNLESS_FUZZING();
+ return nullptr;
+ }
+
+ const SameProcessInputStreamParams& params =
+ aParams.get_SameProcessInputStreamParams();
+ blobImpl = CreateBlobImplFromParams(params, aMetadata);
+ break;
+ }
+
+ default:
+ MOZ_CRASH("Unknown params!");
+ }
+
+ return blobImpl.forget();
+}
+
+already_AddRefed<FileImpl>
+CreateBlobImplFromParams(const MultiplexInputStreamParams& aParams,
+ CreateBlobImplMetadata& aMetadata)
+{
+ MOZ_ASSERT(gProcessType == GeckoProcessType_Default);
+
+ if (NS_WARN_IF(aParams.currentStream())) {
+ ASSERT_UNLESS_FUZZING();
+ return nullptr;
+ }
+
+ if (NS_WARN_IF(NS_FAILED(aParams.status()))) {
+ ASSERT_UNLESS_FUZZING();
+ return nullptr;
+ }
+
+ if (NS_WARN_IF(aParams.startedReadingCurrent())) {
+ ASSERT_UNLESS_FUZZING();
+ return nullptr;
+ }
+
+ const nsTArray<InputStreamParams>& streams = aParams.streams();
+
+ // Special case for a multipart blob with only one part.
+ if (streams.Length() == 1) {
+ const InputStreamParams& params = streams[0];
+
+ nsRefPtr<FileImpl> blobImpl =
+ CreateBlobImplFromInputStreamParams(params, aMetadata);
+ if (NS_WARN_IF(!blobImpl)) {
+ return nullptr;
+ }
+
+ DebugOnly<bool> isMutable;
+ MOZ_ASSERT(NS_SUCCEEDED(blobImpl->GetMutable(&isMutable)));
+ MOZ_ASSERT(!isMutable);
+
+ return blobImpl.forget();
+ }
+
+ FallibleTArray<nsRefPtr<FileImpl>> fallibleBlobImpls;
+ if (NS_WARN_IF(!fallibleBlobImpls.SetLength(streams.Length()))) {
+ return nullptr;
+ }
+
+ nsTArray<nsRefPtr<FileImpl>> blobImpls;
+ fallibleBlobImpls.SwapElements(blobImpls);
+
+ const bool hasRecursed = aMetadata.mHasRecursed;
+ aMetadata.mHasRecursed = true;
+
+ for (uint32_t count = streams.Length(), index = 0; index < count; index++) {
+ const InputStreamParams& params = streams[index];
+ nsRefPtr<FileImpl>& blobImpl = blobImpls[index];
+
+ blobImpl = CreateBlobImplFromParams(params, aMetadata);
+ if (NS_WARN_IF(!blobImpl)) {
+ return nullptr;
+ }
+
+ DebugOnly<bool> isMutable;
+ MOZ_ASSERT(NS_SUCCEEDED(blobImpl->GetMutable(&isMutable)));
+ MOZ_ASSERT(!isMutable);
+ }
+
+ nsRefPtr<FileImpl> blobImpl;
+ if (!hasRecursed && aMetadata.IsFile()) {
+ blobImpl =
+ new MultipartFileImpl(blobImpls, aMetadata.mName, aMetadata.mContentType);
+ } else {
+ blobImpl =
+ new MultipartFileImpl(blobImpls, aMetadata.mContentType);
+ }
+
+ MOZ_ALWAYS_TRUE(NS_SUCCEEDED(blobImpl->SetMutable(false)));
+
+ return blobImpl.forget();
+}
+
+already_AddRefed<FileImpl>
+CreateBlobImplFromParams(const ParentBlobConstructorParams& aParams,
+ bool aIsSameProcessActor)
+{
+ MOZ_ASSERT(gProcessType == GeckoProcessType_Default);
+ MOZ_ASSERT(aParams.blobParams().type() ==
+ AnyBlobConstructorParams::TNormalBlobConstructorParams ||
+ aParams.blobParams().type() ==
+ AnyBlobConstructorParams::TFileBlobConstructorParams);
+ MOZ_ASSERT(aParams.optionalInputStreamParams().type() ==
+ OptionalInputStreamParams::TInputStreamParams);
+
+ CreateBlobImplMetadata metadata;
+
+ if (aParams.blobParams().type() ==
+ AnyBlobConstructorParams::TNormalBlobConstructorParams) {
+ const NormalBlobConstructorParams& params =
+ aParams.blobParams().get_NormalBlobConstructorParams();
+
+ if (NS_WARN_IF(params.length() == UINT64_MAX)) {
+ ASSERT_UNLESS_FUZZING();
+ return nullptr;
+ }
+
+ metadata.mContentType = params.contentType();
+ metadata.mLength = params.length();
+ } else {
+ const FileBlobConstructorParams& params =
+ aParams.blobParams().get_FileBlobConstructorParams();
+
+ if (NS_WARN_IF(params.length() == UINT64_MAX)) {
+ ASSERT_UNLESS_FUZZING();
+ return nullptr;
+ }
+
+ if (NS_WARN_IF(params.modDate() == UINT64_MAX)) {
+ ASSERT_UNLESS_FUZZING();
+ return nullptr;
+ }
+
+ metadata.mContentType = params.contentType();
+ metadata.mName = params.name();
+ metadata.mLength = params.length();
+ metadata.mLastModifiedDate = params.modDate();
+ }
+
+ metadata.mIsSameProcessActor = aIsSameProcessActor;
+
+ const InputStreamParams& inputStreamParams =
+ aParams.optionalInputStreamParams().get_InputStreamParams();
+
+ nsRefPtr<FileImpl> blobImpl =
+ CreateBlobImplFromInputStreamParams(inputStreamParams, metadata);
+ return blobImpl.forget();
+}
+
} // anonymous namespace
StaticAutoPtr<BlobParent::IDTable> BlobParent::sIDTable;
StaticAutoPtr<Mutex> BlobParent::sIDTableMutex;
+/*******************************************************************************
+ * BlobParent::IDTableEntry Declaration
+ ******************************************************************************/
+
class BlobParent::IDTableEntry MOZ_FINAL
{
const nsID mID;
const intptr_t mProcessID;
const nsRefPtr<FileImpl> mBlobImpl;
public:
static already_AddRefed<IDTableEntry>
@@ -798,16 +1281,20 @@ private:
GetOrCreateInternal(const nsID& aID,
intptr_t aProcessID,
FileImpl* aBlobImpl,
bool aMayCreate,
bool aMayGet,
bool aIgnoreProcessID);
};
+/*******************************************************************************
+ * BlobParent::OpenStreamRunnable Declaration
+ ******************************************************************************/
+
// Each instance of this class will be dispatched to the network stream thread
// pool to run the first time where it will open the file input stream. It will
// then dispatch itself back to the owning thread to send the child process its
// response (assuming that the child has not crashed). The runnable will then
// dispatch itself to the thread pool again in order to close the file input
// stream.
class BlobParent::OpenStreamRunnable MOZ_FINAL
: public nsRunnable
@@ -1047,60 +1534,46 @@ private:
};
NS_IMPL_ISUPPORTS_INHERITED0(BlobParent::OpenStreamRunnable, nsRunnable)
/*******************************************************************************
* BlobChild::RemoteBlobImpl Declaration
******************************************************************************/
-class BlobChild::RemoteBlobImpl MOZ_FINAL
+class BlobChild::RemoteBlobImpl
: public FileImplBase
, public nsIRemoteBlob
{
- class StreamHelper;
- class SliceHelper;
+protected:
+ class CreateStreamHelper;
BlobChild* mActor;
nsCOMPtr<nsIEventTarget> mActorTarget;
+ const bool mIsSlice;
public:
+ // For File.
RemoteBlobImpl(BlobChild* aActor,
const nsAString& aName,
const nsAString& aContentType,
uint64_t aLength,
- uint64_t aModDate)
- : FileImplBase(aName, aContentType, aLength, aModDate)
- {
- CommonInit(aActor);
- }
-
+ uint64_t aModDate);
+
+ // For Blob.
RemoteBlobImpl(BlobChild* aActor,
const nsAString& aContentType,
- uint64_t aLength)
- : FileImplBase(aContentType, aLength)
- {
- CommonInit(aActor);
- }
-
+ uint64_t aLength);
+
+ // For mystery blobs.
explicit
- RemoteBlobImpl(BlobChild* aActor)
- : FileImplBase(EmptyString(), EmptyString(), UINT64_MAX, UINT64_MAX)
- {
- CommonInit(aActor);
- }
+ RemoteBlobImpl(BlobChild* aActor);
void
- NoteDyingActor()
- {
- MOZ_ASSERT(mActor);
- mActor->AssertIsOnOwningThread();
-
- mActor = nullptr;
- }
+ NoteDyingActor();
BlobChild*
GetActor() const
{
AssertActorEventTargetIsOnCurrentThread();
return mActor;
}
@@ -1109,328 +1582,368 @@ public:
GetActorEventTarget() const
{
return mActorTarget;
}
void
AssertActorEventTargetIsOnCurrentThread() const
{
- MOZ_ASSERT(EventTargetIsOnCurrentThread(mActorTarget));
+ MOZ_ASSERT(
+ EventTargetIsOnCurrentThread(BaseRemoteBlobImpl()->mActorTarget));
}
+ bool
+ IsSlice() const
+ {
+ return mIsSlice;
+ }
+
+ RemoteBlobSliceImpl*
+ AsSlice() const;
+
+ RemoteBlobImpl*
+ BaseRemoteBlobImpl() const;
+
NS_DECL_ISUPPORTS_INHERITED
virtual void
GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) MOZ_OVERRIDE;
virtual already_AddRefed<FileImpl>
- CreateSlice(uint64_t aStart, uint64_t aLength,
- const nsAString& aContentType, ErrorResult& aRv) MOZ_OVERRIDE;
+ CreateSlice(uint64_t aStart,
+ uint64_t aLength,
+ const nsAString& aContentType,
+ ErrorResult& aRv) MOZ_OVERRIDE;
virtual nsresult
GetInternalStream(nsIInputStream** aStream) MOZ_OVERRIDE;
virtual int64_t
GetFileId() MOZ_OVERRIDE;
virtual int64_t GetLastModified(ErrorResult& aRv) MOZ_OVERRIDE;
virtual BlobChild*
GetBlobChild() MOZ_OVERRIDE;
virtual BlobParent*
GetBlobParent() MOZ_OVERRIDE;
+protected:
+ // For SliceImpl.
+ RemoteBlobImpl(const nsAString& aContentType, uint64_t aLength);
+
+ ~RemoteBlobImpl()
+ {
+ MOZ_ASSERT_IF(mActorTarget,
+ EventTargetIsOnCurrentThread(mActorTarget));
+ }
+
+ void
+ CommonInit(BlobChild* aActor);
+
+ void
+ Destroy();
+};
+
+class BlobChild::RemoteBlobImpl::CreateStreamHelper MOZ_FINAL
+ : public nsRunnable
+{
+ Monitor mMonitor;
+ nsRefPtr<RemoteBlobImpl> mRemoteBlobImpl;
+ nsRefPtr<RemoteInputStream> mInputStream;
+ const uint64_t mStart;
+ const uint64_t mLength;
+ bool mDone;
+
+public:
+ CreateStreamHelper(RemoteBlobImpl* aRemoteBlobImpl);
+
+ nsresult
+ GetStream(nsIInputStream** aInputStream);
+
+ NS_DECL_ISUPPORTS_INHERITED
+ NS_DECL_NSIRUNNABLE
+
+private:
+ ~CreateStreamHelper()
+ {
+ MOZ_ASSERT(!mRemoteBlobImpl);
+ MOZ_ASSERT(!mInputStream);
+ MOZ_ASSERT(mDone);
+ }
+
+ void
+ RunInternal(RemoteBlobImpl* aBaseRemoteBlobImpl, bool aNotify);
+};
+
+class BlobChild::RemoteBlobSliceImpl MOZ_FINAL
+ : public RemoteBlobImpl
+{
+ nsRefPtr<RemoteBlobImpl> mParent;
+ bool mActorWasCreated;
+
+public:
+ RemoteBlobSliceImpl(RemoteBlobImpl* aParent,
+ uint64_t aStart,
+ uint64_t aLength,
+ const nsAString& aContentType);
+
+ RemoteBlobImpl*
+ Parent() const
+ {
+ MOZ_ASSERT(mParent);
+
+ return const_cast<RemoteBlobImpl*>(mParent.get());
+ }
+
+ uint64_t
+ Start() const
+ {
+ return mStart;
+ }
+
+ NS_DECL_ISUPPORTS_INHERITED
+
+ virtual BlobChild*
+ GetBlobChild() MOZ_OVERRIDE;
+
+private:
+ ~RemoteBlobSliceImpl()
+ { }
+};
+
+/*******************************************************************************
+ * BlobParent::RemoteBlobImpl Declaration
+ ******************************************************************************/
+
+class BlobParent::RemoteBlobImpl MOZ_FINAL
+ : public FileImpl
+ , public nsIRemoteBlob
+{
+ BlobParent* mActor;
+ nsCOMPtr<nsIEventTarget> mActorTarget;
+ nsRefPtr<FileImpl> mBlobImpl;
+
+public:
+ RemoteBlobImpl(BlobParent* aActor, FileImpl* aBlobImpl);
+
+ void
+ NoteDyingActor();
+
+ NS_DECL_ISUPPORTS_INHERITED
+
+ virtual void
+ GetName(nsAString& aName) MOZ_OVERRIDE;
+
+ virtual nsresult
+ GetPath(nsAString& aPath) MOZ_OVERRIDE;
+
+ virtual int64_t
+ GetLastModified(ErrorResult& aRv) MOZ_OVERRIDE;
+
+ virtual void
+ GetMozFullPath(nsAString& aName, ErrorResult& aRv) MOZ_OVERRIDE;
+
+ virtual void
+ GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) MOZ_OVERRIDE;
+
+ virtual uint64_t
+ GetSize(ErrorResult& aRv) MOZ_OVERRIDE;
+
+ virtual void
+ GetType(nsAString& aType) MOZ_OVERRIDE;
+
+ virtual already_AddRefed<FileImpl>
+ CreateSlice(uint64_t aStart,
+ uint64_t aLength,
+ const nsAString& aContentType,
+ ErrorResult& aRv) MOZ_OVERRIDE;
+
+ virtual const nsTArray<nsRefPtr<FileImpl>>*
+ GetSubBlobImpls() const MOZ_OVERRIDE;
+
+ virtual nsresult
+ GetInternalStream(nsIInputStream** aStream) MOZ_OVERRIDE;
+
+ virtual int64_t
+ GetFileId() MOZ_OVERRIDE;
+
+ virtual void
+ AddFileInfo(FileInfo* aFileInfo) MOZ_OVERRIDE;
+
+ virtual FileInfo*
+ GetFileInfo(FileManager* aFileManager) MOZ_OVERRIDE;
+
+ virtual nsresult
+ GetSendInfo(nsIInputStream** aBody,
+ uint64_t* aContentLength,
+ nsACString& aContentType,
+ nsACString& aCharset) MOZ_OVERRIDE;
+
+ virtual nsresult
+ GetMutable(bool* aMutable) const MOZ_OVERRIDE;
+
+ virtual nsresult
+ SetMutable(bool aMutable) MOZ_OVERRIDE;
+
+ virtual void
+ SetLazyData(const nsAString& aName,
+ const nsAString& aContentType,
+ uint64_t aLength,
+ uint64_t aLastModifiedDate) MOZ_OVERRIDE;
+
+ virtual bool
+ IsMemoryFile() const MOZ_OVERRIDE;
+
+ virtual bool
+ IsSizeUnknown() const MOZ_OVERRIDE;
+
+ virtual bool
+ IsDateUnknown() const MOZ_OVERRIDE;
+
+ virtual bool
+ IsFile() const MOZ_OVERRIDE;
+
+ virtual void
+ Unlink() MOZ_OVERRIDE;
+
+ virtual void
+ Traverse(nsCycleCollectionTraversalCallback& aCallback) MOZ_OVERRIDE;
+
+ virtual BlobChild*
+ GetBlobChild() MOZ_OVERRIDE;
+
+ virtual BlobParent*
+ GetBlobParent() MOZ_OVERRIDE;
+
private:
~RemoteBlobImpl()
{
MOZ_ASSERT_IF(mActorTarget,
EventTargetIsOnCurrentThread(mActorTarget));
}
void
- CommonInit(BlobChild* aActor)
- {
- MOZ_ASSERT(aActor);
- aActor->AssertIsOnOwningThread();
-
- mActor = aActor;
- mActorTarget = aActor->EventTarget();
-
- mImmutable = true;
- }
-
- void
- Destroy()
- {
- if (EventTargetIsOnCurrentThread(mActorTarget)) {
- if (mActor) {
- mActor->AssertIsOnOwningThread();
- mActor->NoteDyingRemoteBlobImpl();
- }
-
- delete this;
- return;
- }
-
- nsCOMPtr<nsIRunnable> destroyRunnable =
- NS_NewNonOwningRunnableMethod(this, &RemoteBlobImpl::Destroy);
-
- if (mActorTarget) {
- MOZ_ALWAYS_TRUE(NS_SUCCEEDED(mActorTarget->Dispatch(destroyRunnable,
- NS_DISPATCH_NORMAL)));
- } else {
- MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(destroyRunnable)));
- }
- }
-};
-
-class BlobChild::RemoteBlobImpl::StreamHelper MOZ_FINAL
- : public nsRunnable
-{
- Monitor mMonitor;
- nsRefPtr<RemoteBlobImpl> mRemoteBlobImpl;
- nsRefPtr<RemoteInputStream> mInputStream;
- bool mDone;
-
-public:
- StreamHelper(RemoteBlobImpl* aRemoteBlobImpl)
- : mMonitor("BlobChild::RemoteBlobImpl::StreamHelper::mMonitor")
- , mRemoteBlobImpl(aRemoteBlobImpl)
- , mDone(false)
- {
- // This may be created on any thread.
- MOZ_ASSERT(aRemoteBlobImpl);
- }
-
- nsresult
- GetStream(nsIInputStream** aInputStream)
- {
- // This may be called on any thread.
- MOZ_ASSERT(aInputStream);
- MOZ_ASSERT(mRemoteBlobImpl);
- MOZ_ASSERT(!mInputStream);
- MOZ_ASSERT(!mDone);
-
- if (EventTargetIsOnCurrentThread(mRemoteBlobImpl->GetActorEventTarget())) {
- RunInternal(false);
- } else {
- nsCOMPtr<nsIEventTarget> target = mRemoteBlobImpl->GetActorEventTarget();
- if (!target) {
- target = do_GetMainThread();
- }
-
- MOZ_ASSERT(target);
-
- nsresult rv = target->Dispatch(this, NS_DISPATCH_NORMAL);
- NS_ENSURE_SUCCESS(rv, rv);
-
- {
- MonitorAutoLock lock(mMonitor);
- while (!mDone) {
- lock.Wait();
- }
- }
- }
-
- MOZ_ASSERT(!mRemoteBlobImpl);
- MOZ_ASSERT(mDone);
-
- if (!mInputStream) {
- return NS_ERROR_UNEXPECTED;
- }
-
- mInputStream.forget(aInputStream);
- return NS_OK;
- }
-
- NS_IMETHOD
- Run() MOZ_OVERRIDE
- {
- MOZ_ASSERT(mRemoteBlobImpl);
- mRemoteBlobImpl->AssertActorEventTargetIsOnCurrentThread();
-
- RunInternal(true);
- return NS_OK;
- }
-
-private:
- void
- RunInternal(bool aNotify)
- {
- MOZ_ASSERT(mRemoteBlobImpl);
- mRemoteBlobImpl->AssertActorEventTargetIsOnCurrentThread();
- MOZ_ASSERT(!mInputStream);
- MOZ_ASSERT(!mDone);
-
- if (BlobChild* actor = mRemoteBlobImpl->GetActor()) {
- nsRefPtr<RemoteInputStream> stream =
- new RemoteInputStream(mRemoteBlobImpl);
-
- InputStreamChild* streamActor = new InputStreamChild(stream);
- if (actor->SendPBlobStreamConstructor(streamActor)) {
- stream.swap(mInputStream);
- }
- }
-
- mRemoteBlobImpl = nullptr;
-
- if (aNotify) {
- MonitorAutoLock lock(mMonitor);
- mDone = true;
- lock.Notify();
- }
- else {
- mDone = true;
- }
- }
-};
-
-class BlobChild::RemoteBlobImpl::SliceHelper MOZ_FINAL
- : public nsRunnable
-{
- Monitor mMonitor;
- nsRefPtr<RemoteBlobImpl> mRemoteBlobImpl;
- nsRefPtr<FileImpl> mSlice;
- uint64_t mStart;
- uint64_t mLength;
- nsString mContentType;
- bool mDone;
-
-public:
- explicit
- SliceHelper(RemoteBlobImpl* aRemoteBlobImpl)
- : mMonitor("BlobChild::RemoteBlobImpl::SliceHelper::mMonitor")
- , mRemoteBlobImpl(aRemoteBlobImpl)
- , mStart(0)
- , mLength(0)
- , mDone(false)
- {
- // This may be created on any thread.
- MOZ_ASSERT(aRemoteBlobImpl);
- }
-
- already_AddRefed<FileImpl>
- GetSlice(uint64_t aStart, uint64_t aLength, const nsAString& aContentType)
- {
- // This may be called on any thread.
- MOZ_ASSERT(mRemoteBlobImpl);
- MOZ_ASSERT(!mSlice);
- MOZ_ASSERT(!mDone);
-
- mStart = aStart;
- mLength = aLength;
- mContentType = aContentType;
-
- if (EventTargetIsOnCurrentThread(mRemoteBlobImpl->GetActorEventTarget())) {
- RunInternal(false);
- } else {
- nsCOMPtr<nsIEventTarget> target = mRemoteBlobImpl->GetActorEventTarget();
- if (!target) {
- target = do_GetMainThread();
- }
-
- MOZ_ASSERT(target);
-
- nsresult rv = target->Dispatch(this, NS_DISPATCH_NORMAL);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return nullptr;
- }
-
- {
- MonitorAutoLock lock(mMonitor);
- while (!mDone) {
- lock.Wait();
- }
- }
- }
-
- MOZ_ASSERT(!mRemoteBlobImpl);
- MOZ_ASSERT(mDone);
-
- if (NS_WARN_IF(!mSlice)) {
- return nullptr;
- }
-
- return mSlice.forget();
- }
-
- NS_IMETHOD
- Run() MOZ_OVERRIDE
- {
- MOZ_ASSERT(mRemoteBlobImpl);
- mRemoteBlobImpl->AssertActorEventTargetIsOnCurrentThread();
-
- RunInternal(true);
- return NS_OK;
- }
-
-private:
- void
- RunInternal(bool aNotify)
- {
- MOZ_ASSERT(mRemoteBlobImpl);
- mRemoteBlobImpl->AssertActorEventTargetIsOnCurrentThread();
- MOZ_ASSERT(!mSlice);
- MOZ_ASSERT(!mDone);
-
- if (BlobChild* actor = mRemoteBlobImpl->GetActor()) {
- MOZ_ASSERT(actor->HasManager());
-
- nsID id;
- MOZ_ALWAYS_TRUE(NS_SUCCEEDED(gUUIDGenerator->GenerateUUIDInPlace(&id)));
-
- ChildBlobConstructorParams params(
- id,
- NormalBlobConstructorParams(mContentType /* contentType */,
- mLength /* length */));
-
- ParentBlobConstructorParams otherSideParams(
- SlicedBlobConstructorParams(nullptr /* sourceParent */,
- actor /* sourceChild */,
- id /* optionalID */,
- mStart /* begin */,
- mStart + mLength /* end */,
- mContentType /* contentType */),
- void_t() /* optionalInputStream */);
-
- BlobChild* newActor;
- if (nsIContentChild* contentManager = actor->GetContentManager()) {
- newActor = SendSliceConstructor(contentManager,
- params,
- otherSideParams);
- } else {
- newActor = SendSliceConstructor(actor->GetBackgroundManager(),
- params,
- otherSideParams);
- }
-
- if (newActor) {
- mSlice = newActor->GetBlobImpl();
- }
- }
-
- mRemoteBlobImpl = nullptr;
-
- if (aNotify) {
- MonitorAutoLock lock(mMonitor);
- mDone = true;
- lock.Notify();
- }
- else {
- mDone = true;
- }
- }
+ Destroy();
};
/*******************************************************************************
- * BlobChild::RemoteBlobImpl Implementation
+ * BlobChild::RemoteBlobImpl
******************************************************************************/
+BlobChild::
+RemoteBlobImpl::RemoteBlobImpl(BlobChild* aActor,
+ const nsAString& aName,
+ const nsAString& aContentType,
+ uint64_t aLength,
+ uint64_t aModDate)
+ : FileImplBase(aName, aContentType, aLength, aModDate)
+ , mIsSlice(false)
+{
+ CommonInit(aActor);
+}
+
+BlobChild::
+RemoteBlobImpl::RemoteBlobImpl(BlobChild* aActor,
+ const nsAString& aContentType,
+ uint64_t aLength)
+ : FileImplBase(aContentType, aLength)
+ , mIsSlice(false)
+{
+ CommonInit(aActor);
+}
+
+BlobChild::
+RemoteBlobImpl::RemoteBlobImpl(BlobChild* aActor)
+ : FileImplBase(EmptyString(), EmptyString(), UINT64_MAX, UINT64_MAX)
+ , mIsSlice(false)
+{
+ CommonInit(aActor);
+}
+
+BlobChild::
+RemoteBlobImpl::RemoteBlobImpl(const nsAString& aContentType, uint64_t aLength)
+ : FileImplBase(aContentType, aLength)
+ , mActor(nullptr)
+ , mIsSlice(true)
+{
+ mImmutable = true;
+}
+
+void
+BlobChild::
+RemoteBlobImpl::CommonInit(BlobChild* aActor)
+{
+ MOZ_ASSERT(aActor);
+ aActor->AssertIsOnOwningThread();
+ MOZ_ASSERT(!mIsSlice);
+
+ mActor = aActor;
+ mActorTarget = aActor->EventTarget();
+
+ mImmutable = true;
+}
+
+void
+BlobChild::
+RemoteBlobImpl::NoteDyingActor()
+{
+ MOZ_ASSERT(mActor);
+ mActor->AssertIsOnOwningThread();
+
+ mActor = nullptr;
+}
+
+BlobChild::RemoteBlobSliceImpl*
+BlobChild::
+RemoteBlobImpl::AsSlice() const
+{
+ MOZ_ASSERT(IsSlice());
+
+ return static_cast<RemoteBlobSliceImpl*>(const_cast<RemoteBlobImpl*>(this));
+}
+
+BlobChild::RemoteBlobImpl*
+BlobChild::
+RemoteBlobImpl::BaseRemoteBlobImpl() const
+{
+ if (IsSlice()) {
+ return AsSlice()->Parent()->BaseRemoteBlobImpl();
+ }
+
+ return const_cast<RemoteBlobImpl*>(this);
+}
+
+void
+BlobChild::
+RemoteBlobImpl::Destroy()
+{
+ if (EventTargetIsOnCurrentThread(mActorTarget)) {
+ if (mActor) {
+ mActor->AssertIsOnOwningThread();
+ mActor->NoteDyingRemoteBlobImpl();
+ }
+
+ delete this;
+ return;
+ }
+
+ nsCOMPtr<nsIRunnable> destroyRunnable =
+ NS_NewNonOwningRunnableMethod(this, &RemoteBlobImpl::Destroy);
+
+ if (mActorTarget) {
+ MOZ_ALWAYS_TRUE(NS_SUCCEEDED(mActorTarget->Dispatch(destroyRunnable,
+ NS_DISPATCH_NORMAL)));
+ } else {
+ MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(destroyRunnable)));
+ }
+}
+
NS_IMPL_ADDREF(BlobChild::RemoteBlobImpl)
NS_IMPL_RELEASE_WITH_DESTROY(BlobChild::RemoteBlobImpl, Destroy())
NS_IMPL_QUERY_INTERFACE_INHERITED(BlobChild::RemoteBlobImpl,
FileImpl,
nsIRemoteBlob)
void
BlobChild::
@@ -1452,35 +1965,33 @@ RemoteBlobImpl::GetMozFullPathInternal(n
return;
}
aFilePath = filePath;
}
already_AddRefed<FileImpl>
BlobChild::
-RemoteBlobImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
- const nsAString& aContentType, ErrorResult& aRv)
+RemoteBlobImpl::CreateSlice(uint64_t aStart,
+ uint64_t aLength,
+ const nsAString& aContentType,
+ ErrorResult& aRv)
{
- nsRefPtr<SliceHelper> helper = new SliceHelper(this);
-
- nsRefPtr<FileImpl> impl = helper->GetSlice(aStart, aLength, aContentType);
- if (NS_WARN_IF(!impl)) {
- aRv.Throw(NS_ERROR_FAILURE);
- return nullptr;
- }
-
- return impl.forget();
+ // May be called on any thread.
+ nsRefPtr<RemoteBlobSliceImpl> slice =
+ new RemoteBlobSliceImpl(this, aStart, aLength, aContentType);
+ return slice.forget();
}
nsresult
BlobChild::
RemoteBlobImpl::GetInternalStream(nsIInputStream** aStream)
{
- nsRefPtr<StreamHelper> helper = new StreamHelper(this);
+ // May be called on any thread.
+ nsRefPtr<CreateStreamHelper> helper = new CreateStreamHelper(this);
return helper->GetStream(aStream);
}
int64_t
BlobChild::
RemoteBlobImpl::GetFileId()
{
if (!EventTargetIsOnCurrentThread(mActorTarget)) {
@@ -1516,16 +2027,454 @@ RemoteBlobImpl::GetBlobChild()
BlobParent*
BlobChild::
RemoteBlobImpl::GetBlobParent()
{
return nullptr;
}
/*******************************************************************************
+ * BlobChild::RemoteBlobImpl::CreateStreamHelper
+ ******************************************************************************/
+
+BlobChild::RemoteBlobImpl::
+CreateStreamHelper::CreateStreamHelper(RemoteBlobImpl* aRemoteBlobImpl)
+ : mMonitor("BlobChild::RemoteBlobImpl::CreateStreamHelper::mMonitor")
+ , mRemoteBlobImpl(aRemoteBlobImpl)
+ , mStart(aRemoteBlobImpl->IsSlice() ? aRemoteBlobImpl->AsSlice()->Start() : 0)
+ , mLength(0)
+ , mDone(false)
+{
+ // This may be created on any thread.
+ MOZ_ASSERT(aRemoteBlobImpl);
+
+ ErrorResult rv;
+ const_cast<uint64_t&>(mLength) = aRemoteBlobImpl->GetSize(rv);
+ MOZ_ASSERT(!rv.Failed());
+}
+
+nsresult
+BlobChild::RemoteBlobImpl::
+CreateStreamHelper::GetStream(nsIInputStream** aInputStream)
+{
+ // This may be called on any thread.
+ MOZ_ASSERT(aInputStream);
+ MOZ_ASSERT(mRemoteBlobImpl);
+ MOZ_ASSERT(!mInputStream);
+ MOZ_ASSERT(!mDone);
+
+ nsRefPtr<RemoteBlobImpl> baseRemoteBlobImpl =
+ mRemoteBlobImpl->BaseRemoteBlobImpl();
+ MOZ_ASSERT(baseRemoteBlobImpl);
+
+ if (EventTargetIsOnCurrentThread(baseRemoteBlobImpl->GetActorEventTarget())) {
+ RunInternal(baseRemoteBlobImpl, false);
+ } else {
+ nsCOMPtr<nsIEventTarget> target = baseRemoteBlobImpl->GetActorEventTarget();
+ if (!target) {
+ target = do_GetMainThread();
+ }
+
+ MOZ_ASSERT(target);
+
+ nsresult rv = target->Dispatch(this, NS_DISPATCH_NORMAL);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ {
+ MonitorAutoLock lock(mMonitor);
+ while (!mDone) {
+ lock.Wait();
+ }
+ }
+ }
+
+ MOZ_ASSERT(!mRemoteBlobImpl);
+ MOZ_ASSERT(mDone);
+
+ if (!mInputStream) {
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ mInputStream.forget(aInputStream);
+ return NS_OK;
+}
+
+void
+BlobChild::RemoteBlobImpl::
+CreateStreamHelper::RunInternal(RemoteBlobImpl* aBaseRemoteBlobImpl,
+ bool aNotify)
+{
+ MOZ_ASSERT(aBaseRemoteBlobImpl);
+ aBaseRemoteBlobImpl->AssertActorEventTargetIsOnCurrentThread();
+ MOZ_ASSERT(!mInputStream);
+ MOZ_ASSERT(!mDone);
+
+ if (BlobChild* actor = aBaseRemoteBlobImpl->GetActor()) {
+ nsRefPtr<RemoteInputStream> stream =
+ new RemoteInputStream(aBaseRemoteBlobImpl);
+
+ InputStreamChild* streamActor = new InputStreamChild(stream);
+ if (actor->SendPBlobStreamConstructor(streamActor, mStart, mLength)) {
+ stream.swap(mInputStream);
+ }
+ }
+
+ mRemoteBlobImpl = nullptr;
+
+ if (aNotify) {
+ MonitorAutoLock lock(mMonitor);
+ mDone = true;
+ lock.Notify();
+ } else {
+ mDone = true;
+ }
+}
+
+NS_IMPL_ISUPPORTS_INHERITED0(BlobChild::RemoteBlobImpl::CreateStreamHelper,
+ nsRunnable)
+
+NS_IMETHODIMP
+BlobChild::RemoteBlobImpl::
+CreateStreamHelper::Run()
+{
+ MOZ_ASSERT(mRemoteBlobImpl);
+ mRemoteBlobImpl->AssertActorEventTargetIsOnCurrentThread();
+
+ nsRefPtr<RemoteBlobImpl> baseRemoteBlobImpl =
+ mRemoteBlobImpl->BaseRemoteBlobImpl();
+ MOZ_ASSERT(baseRemoteBlobImpl);
+
+ RunInternal(baseRemoteBlobImpl, true);
+ return NS_OK;
+}
+
+/*******************************************************************************
+ * BlobChild::RemoteBlobSliceImpl
+ ******************************************************************************/
+
+BlobChild::
+RemoteBlobSliceImpl::RemoteBlobSliceImpl(RemoteBlobImpl* aParent,
+ uint64_t aStart,
+ uint64_t aLength,
+ const nsAString& aContentType)
+ : RemoteBlobImpl(aContentType, aLength)
+ , mParent(aParent->BaseRemoteBlobImpl())
+ , mActorWasCreated(false)
+{
+ MOZ_ASSERT(mParent);
+ MOZ_ASSERT(mParent->BaseRemoteBlobImpl() == mParent);
+
+ DebugOnly<bool> isMutable;
+ MOZ_ASSERT(NS_SUCCEEDED(aParent->GetMutable(&isMutable)));
+ MOZ_ASSERT(!isMutable);
+
+#ifdef DEBUG
+ {
+ ErrorResult rv;
+ uint64_t parentSize = aParent->GetSize(rv);
+ MOZ_ASSERT(!rv.Failed());
+ MOZ_ASSERT(parentSize >= aStart + aLength);
+ }
+#endif
+
+ // Account for the offset of the parent slice, if any.
+ mStart = aParent->IsSlice() ? aParent->AsSlice()->mStart + aStart : aStart;
+}
+
+NS_IMPL_ISUPPORTS_INHERITED0(BlobChild::RemoteBlobSliceImpl,
+ BlobChild::RemoteBlobImpl)
+
+BlobChild*
+BlobChild::
+RemoteBlobSliceImpl::GetBlobChild()
+{
+ AssertActorEventTargetIsOnCurrentThread();
+
+ if (mActorWasCreated) {
+ return RemoteBlobImpl::GetBlobChild();
+ }
+
+ mActorWasCreated = true;
+
+ BlobChild* baseActor = mParent->GetActor();
+ MOZ_ASSERT(baseActor);
+ MOZ_ASSERT(baseActor->HasManager());
+
+ nsID id;
+ MOZ_ALWAYS_TRUE(NS_SUCCEEDED(gUUIDGenerator->GenerateUUIDInPlace(&id)));
+
+ ParentBlobConstructorParams params(
+ SlicedBlobConstructorParams(nullptr /* sourceParent */,
+ baseActor /* sourceChild */,
+ id /* id */,
+ mStart /* begin */,
+ mStart + mLength /* end */,
+ mContentType /* contentType */),
+ void_t() /* optionalInputStream */);
+
+ if (nsIContentChild* contentManager = baseActor->GetContentManager()) {
+ mActor = SendSliceConstructor(contentManager, this, params);
+ } else {
+ mActor =
+ SendSliceConstructor(baseActor->GetBackgroundManager(), this, params);
+ }
+
+ return mActor;
+}
+
+/*******************************************************************************
+ * BlobParent::RemoteBlobImpl
+ ******************************************************************************/
+
+BlobParent::
+RemoteBlobImpl::RemoteBlobImpl(BlobParent* aActor, FileImpl* aBlobImpl)
+ : mActor(aActor)
+ , mActorTarget(aActor->EventTarget())
+ , mBlobImpl(aBlobImpl)
+{
+ MOZ_ASSERT(aActor);
+ aActor->AssertIsOnOwningThread();
+ MOZ_ASSERT(aBlobImpl);
+
+ DebugOnly<bool> isMutable;
+ MOZ_ASSERT(NS_SUCCEEDED(aBlobImpl->GetMutable(&isMutable)));
+ MOZ_ASSERT(!isMutable);
+}
+
+void
+BlobParent::
+RemoteBlobImpl::NoteDyingActor()
+{
+ MOZ_ASSERT(mActor);
+ mActor->AssertIsOnOwningThread();
+
+ mActor = nullptr;
+}
+
+void
+BlobParent::
+RemoteBlobImpl::Destroy()
+{
+ if (EventTargetIsOnCurrentThread(mActorTarget)) {
+ if (mActor) {
+ mActor->AssertIsOnOwningThread();
+ mActor->NoteDyingRemoteBlobImpl();
+ }
+
+ delete this;
+ return;
+ }
+
+ nsCOMPtr<nsIRunnable> destroyRunnable =
+ NS_NewNonOwningRunnableMethod(this, &RemoteBlobImpl::Destroy);
+
+ if (mActorTarget) {
+ MOZ_ALWAYS_TRUE(NS_SUCCEEDED(mActorTarget->Dispatch(destroyRunnable,
+ NS_DISPATCH_NORMAL)));
+ } else {
+ MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(destroyRunnable)));
+ }
+}
+
+NS_IMPL_ADDREF(BlobParent::RemoteBlobImpl)
+NS_IMPL_RELEASE_WITH_DESTROY(BlobParent::RemoteBlobImpl, Destroy())
+NS_IMPL_QUERY_INTERFACE_INHERITED(BlobParent::RemoteBlobImpl,
+ FileImpl,
+ nsIRemoteBlob)
+
+void
+BlobParent::
+RemoteBlobImpl::GetName(nsAString& aName)
+{
+ mBlobImpl->GetName(aName);
+}
+
+nsresult
+BlobParent::
+RemoteBlobImpl::GetPath(nsAString& aPath)
+{
+ return mBlobImpl->GetPath(aPath);
+}
+
+int64_t
+BlobParent::
+RemoteBlobImpl::GetLastModified(ErrorResult& aRv)
+{
+ return mBlobImpl->GetLastModified(aRv);
+}
+
+void
+BlobParent::
+RemoteBlobImpl::GetMozFullPath(nsAString& aName, ErrorResult& aRv)
+{
+ mBlobImpl->GetMozFullPath(aName, aRv);
+}
+
+void
+BlobParent::
+RemoteBlobImpl::GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv)
+{
+ mBlobImpl->GetMozFullPathInternal(aFileName, aRv);
+}
+
+uint64_t
+BlobParent::
+RemoteBlobImpl::GetSize(ErrorResult& aRv)
+{
+ return mBlobImpl->GetSize(aRv);
+}
+
+void
+BlobParent::
+RemoteBlobImpl::GetType(nsAString& aType)
+{
+ mBlobImpl->GetType(aType);
+}
+
+already_AddRefed<FileImpl>
+BlobParent::
+RemoteBlobImpl::CreateSlice(uint64_t aStart,
+ uint64_t aLength,
+ const nsAString& aContentType,
+ ErrorResult& aRv)
+{
+ return mBlobImpl->CreateSlice(aStart, aLength, aContentType, aRv);
+}
+
+const nsTArray<nsRefPtr<FileImpl>>*
+BlobParent::
+RemoteBlobImpl::GetSubBlobImpls() const
+{
+ return mBlobImpl->GetSubBlobImpls();
+}
+
+nsresult
+BlobParent::
+RemoteBlobImpl::GetInternalStream(nsIInputStream** aStream)
+{
+ return mBlobImpl->GetInternalStream(aStream);
+}
+
+int64_t
+BlobParent::
+RemoteBlobImpl::GetFileId()
+{
+ return mBlobImpl->GetFileId();
+}
+
+void
+BlobParent::
+RemoteBlobImpl::AddFileInfo(FileInfo* aFileInfo)
+{
+ return mBlobImpl->AddFileInfo(aFileInfo);
+}
+
+FileInfo*
+BlobParent::
+RemoteBlobImpl::GetFileInfo(FileManager* aFileManager)
+{
+ return mBlobImpl->GetFileInfo(aFileManager);
+}
+
+nsresult
+BlobParent::
+RemoteBlobImpl::GetSendInfo(nsIInputStream** aBody,
+ uint64_t* aContentLength,
+ nsACString& aContentType,
+ nsACString& aCharset)
+{
+ return mBlobImpl->GetSendInfo(aBody,
+ aContentLength,
+ aContentType,
+ aCharset);
+}
+
+nsresult
+BlobParent::
+RemoteBlobImpl::GetMutable(bool* aMutable) const
+{
+ return mBlobImpl->GetMutable(aMutable);
+}
+
+nsresult
+BlobParent::
+RemoteBlobImpl::SetMutable(bool aMutable)
+{
+ return mBlobImpl->SetMutable(aMutable);
+}
+
+void
+BlobParent::
+RemoteBlobImpl::SetLazyData(const nsAString& aName,
+ const nsAString& aContentType,
+ uint64_t aLength,
+ uint64_t aLastModifiedDate)
+{
+ MOZ_CRASH("This should never be called!");
+}
+
+bool
+BlobParent::
+RemoteBlobImpl::IsMemoryFile() const
+{
+ return mBlobImpl->IsMemoryFile();
+}
+
+bool
+BlobParent::
+RemoteBlobImpl::IsSizeUnknown() const
+{
+ return mBlobImpl->IsSizeUnknown();
+}
+
+bool
+BlobParent::
+RemoteBlobImpl::IsDateUnknown() const
+{
+ return mBlobImpl->IsDateUnknown();
+}
+
+bool
+BlobParent::
+RemoteBlobImpl::IsFile() const
+{
+ return mBlobImpl->IsFile();
+}
+
+void
+BlobParent::
+RemoteBlobImpl::Unlink()
+{
+ return mBlobImpl->Unlink();
+}
+
+void
+BlobParent::
+RemoteBlobImpl::Traverse(nsCycleCollectionTraversalCallback& aCallback)
+{
+ return mBlobImpl->Traverse(aCallback);
+}
+
+BlobChild*
+BlobParent::
+RemoteBlobImpl::GetBlobChild()
+{
+ return nullptr;
+}
+
+BlobParent*
+BlobParent::
+RemoteBlobImpl::GetBlobParent()
+{
+ return mActor;
+}
+
+/*******************************************************************************
* BlobChild
******************************************************************************/
BlobChild::BlobChild(nsIContentChild* aManager, FileImpl* aBlobImpl)
: mBackgroundManager(nullptr)
, mContentManager(aManager)
{
AssertCorrectThreadForManager(aManager);
@@ -1596,16 +2545,45 @@ BlobChild::BlobChild(PBackgroundChild* a
CommonInit(aParams);
if (!NS_IsMainThread()) {
mEventTarget = do_GetCurrentThread();
MOZ_ASSERT(mEventTarget);
}
}
+BlobChild::BlobChild(nsIContentChild* aManager,
+ const nsID& aParentID,
+ RemoteBlobSliceImpl* aRemoteBlobSliceImpl)
+ : mBackgroundManager(nullptr)
+ , mContentManager(aManager)
+{
+ AssertCorrectThreadForManager(aManager);
+ MOZ_ASSERT(aManager);
+
+ CommonInit(aParentID, aRemoteBlobSliceImpl);
+}
+
+BlobChild::BlobChild(PBackgroundChild* aManager,
+ const nsID& aParentID,
+ RemoteBlobSliceImpl* aRemoteBlobSliceImpl)
+ : mBackgroundManager(aManager)
+ , mContentManager(nullptr)
+{
+ AssertCorrectThreadForManager(aManager);
+ MOZ_ASSERT(aManager);
+
+ CommonInit(aParentID, aRemoteBlobSliceImpl);
+
+ if (!NS_IsMainThread()) {
+ mEventTarget = do_GetCurrentThread();
+ MOZ_ASSERT(mEventTarget);
+ }
+}
+
BlobChild::~BlobChild()
{
AssertIsOnOwningThread();
MOZ_COUNT_DTOR(BlobChild);
}
void
@@ -1628,18 +2606,16 @@ BlobChild::CommonInit(FileImpl* aBlobImp
void
BlobChild::CommonInit(BlobChild* aOther)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aOther);
MOZ_ASSERT_IF(mContentManager, aOther->GetBackgroundManager());
MOZ_ASSERT_IF(mBackgroundManager, aOther->GetContentManager());
- MOZ_COUNT_CTOR(BlobChild);
-
nsRefPtr<FileImpl> otherImpl = aOther->GetBlobImpl();
MOZ_ASSERT(otherImpl);
nsString contentType;
otherImpl->GetType(contentType);
ErrorResult rv;
uint64_t length = otherImpl->GetSize(rv);
@@ -1653,28 +2629,17 @@ BlobChild::CommonInit(BlobChild* aOther)
uint64_t modDate = otherImpl->GetLastModified(rv);
MOZ_ASSERT(!rv.Failed());
remoteBlob = new RemoteBlobImpl(this, name, contentType, length, modDate);
} else {
remoteBlob = new RemoteBlobImpl(this, contentType, length);
}
- MOZ_ASSERT(remoteBlob);
-
- DebugOnly<bool> isMutable;
- MOZ_ASSERT(NS_SUCCEEDED(remoteBlob->GetMutable(&isMutable)));
- MOZ_ASSERT(!isMutable);
-
- mRemoteBlobImpl = remoteBlob;
-
- remoteBlob.forget(&mBlobImpl);
- mOwnsBlobImpl = true;
-
- mParentID = aOther->ParentID();
+ CommonInit(aOther->ParentID(), remoteBlob);
}
void
BlobChild::CommonInit(const ChildBlobConstructorParams& aParams)
{
AssertIsOnOwningThread();
MOZ_COUNT_CTOR(BlobChild);
@@ -1726,16 +2691,38 @@ BlobChild::CommonInit(const ChildBlobCon
mRemoteBlobImpl = remoteBlob;
remoteBlob.forget(&mBlobImpl);
mOwnsBlobImpl = true;
mParentID = aParams.id();
}
+void
+BlobChild::CommonInit(const nsID& aParentID, RemoteBlobImpl* aRemoteBlobImpl)
+{
+ AssertIsOnOwningThread();
+ MOZ_ASSERT(aRemoteBlobImpl);
+
+ DebugOnly<bool> isMutable;
+ MOZ_ASSERT(NS_SUCCEEDED(aRemoteBlobImpl->GetMutable(&isMutable)));
+ MOZ_ASSERT(!isMutable);
+
+ MOZ_COUNT_CTOR(BlobChild);
+
+ nsRefPtr<RemoteBlobImpl> remoteBlob = aRemoteBlobImpl;
+
+ mRemoteBlobImpl = remoteBlob;
+
+ remoteBlob.forget(&mBlobImpl);
+ mOwnsBlobImpl = true;
+
+ mParentID = aParentID;
+}
+
#ifdef DEBUG
void
BlobChild::AssertIsOnOwningThread() const
{
MOZ_ASSERT(IsOnOwningThread());
}
@@ -1878,76 +2865,50 @@ BlobChild::CreateFromParams(ChildManager
switch (blobParams.type()) {
case AnyBlobConstructorParams::TNormalBlobConstructorParams:
case AnyBlobConstructorParams::TFileBlobConstructorParams:
case AnyBlobConstructorParams::TMysteryBlobConstructorParams: {
return new BlobChild(aManager, aParams);
}
case AnyBlobConstructorParams::TSlicedBlobConstructorParams: {
- const SlicedBlobConstructorParams& params =
- blobParams.get_SlicedBlobConstructorParams();
- MOZ_ASSERT(params.optionalID().type() == OptionalID::Tvoid_t);
-
- auto* actor =
- const_cast<BlobChild*>(
- static_cast<const BlobChild*>(params.sourceChild()));
- MOZ_ASSERT(actor);
-
- nsRefPtr<FileImpl> source = actor->GetBlobImpl();
- MOZ_ASSERT(source);
-
- Optional<int64_t> start;
- start.Construct(params.begin());
-
- Optional<int64_t> end;
- start.Construct(params.end());
-
- ErrorResult rv;
- nsRefPtr<FileImpl> slice =
- source->Slice(start, end, params.contentType(), rv);
- if (NS_WARN_IF(rv.Failed())) {
- return nullptr;
- }
-
- MOZ_ALWAYS_TRUE(NS_SUCCEEDED(slice->SetMutable(false)));
-
- actor = new BlobChild(aManager, slice);
-
- actor->mParentID = aParams.id();
-
- return actor;
+ MOZ_CRASH("Parent should never send SlicedBlobConstructorParams!");
}
case AnyBlobConstructorParams::TKnownBlobConstructorParams: {
- MOZ_CRASH("Parent should never send this type!");
+ MOZ_CRASH("Parent should never send KnownBlobConstructorParams!");
}
default:
MOZ_CRASH("Unknown params!");
}
MOZ_CRASH("Should never get here!");
}
// static
template <class ChildManagerType>
BlobChild*
-BlobChild::SendSliceConstructor(
- ChildManagerType* aManager,
- const ChildBlobConstructorParams& aParams,
- const ParentBlobConstructorParams& aOtherSideParams)
+BlobChild::SendSliceConstructor(ChildManagerType* aManager,
+ RemoteBlobSliceImpl* aRemoteBlobSliceImpl,
+ const ParentBlobConstructorParams& aParams)
{
AssertCorrectThreadForManager(aManager);
MOZ_ASSERT(aManager);
-
- BlobChild* newActor = BlobChild::Create(aManager, aParams);
- MOZ_ASSERT(newActor);
-
- if (aManager->SendPBlobConstructor(newActor, aOtherSideParams)) {
+ MOZ_ASSERT(aRemoteBlobSliceImpl);
+ MOZ_ASSERT(aParams.blobParams().type() ==
+ AnyBlobConstructorParams::TSlicedBlobConstructorParams);
+ MOZ_ASSERT(aParams.optionalInputStreamParams().type() ==
+ OptionalInputStreamParams::Tvoid_t);
+
+ const nsID& id = aParams.blobParams().get_SlicedBlobConstructorParams().id();
+
+ BlobChild* newActor = new BlobChild(aManager, id, aRemoteBlobSliceImpl);
+
+ if (aManager->SendPBlobConstructor(newActor, aParams)) {
if (gProcessType != GeckoProcessType_Default || !NS_IsMainThread()) {
newActor->SendWaitForSliceCreation();
}
return newActor;
}
BlobChild::Destroy(newActor);
return nullptr;
@@ -2135,588 +3096,34 @@ BlobChild::ActorDestroy(ActorDestroyReas
mRemoteBlobImpl = nullptr;
mBackgroundManager = nullptr;
mContentManager = nullptr;
mOwnsBlobImpl = false;
#endif
}
PBlobStreamChild*
-BlobChild::AllocPBlobStreamChild()
+BlobChild::AllocPBlobStreamChild(const uint64_t& aStart,
+ const uint64_t& aLength)
{
AssertIsOnOwningThread();
return new InputStreamChild();
}
bool
BlobChild::DeallocPBlobStreamChild(PBlobStreamChild* aActor)
{
AssertIsOnOwningThread();
delete static_cast<InputStreamChild*>(aActor);
return true;
}
/*******************************************************************************
- * BlobParent::RemoteBlob Declaration
- ******************************************************************************/
-
-class BlobParent::RemoteBlobImplBase
- : public nsISupports
-{
- friend class BlobParent;
-
- BlobParent* mActor;
- nsCOMPtr<nsIEventTarget> mActorTarget;
- bool mForwards;
-
-protected:
- RemoteBlobImplBase(BlobParent* aActor, bool aForwards)
- : mActor(aActor)
- , mActorTarget(aActor->EventTarget())
- , mForwards(aForwards)
- {
- MOZ_ASSERT(aActor);
- aActor->AssertIsOnOwningThread();
-
- MOZ_COUNT_CTOR(BlobParent::RemoteBlobImplBase);
- }
-
- virtual
- ~RemoteBlobImplBase()
- {
- MOZ_ASSERT_IF(mActorTarget,
- EventTargetIsOnCurrentThread(mActorTarget));
-
- MOZ_COUNT_DTOR(BlobParent::RemoteBlobImplBase);
- }
-
- void
- Destroy()
- {
- if (EventTargetIsOnCurrentThread(mActorTarget)) {
- if (mActor) {
- mActor->AssertIsOnOwningThread();
- mActor->NoteDyingRemoteBlobImpl();
- }
-
- delete this;
- return;
- }
-
- nsCOMPtr<nsIRunnable> destroyRunnable =
- NS_NewNonOwningRunnableMethod(this, &RemoteBlobImplBase::Destroy);
-
- if (mActorTarget) {
- MOZ_ALWAYS_TRUE(NS_SUCCEEDED(mActorTarget->Dispatch(destroyRunnable,
- NS_DISPATCH_NORMAL)));
- } else {
- MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(destroyRunnable)));
- }
- }
-
-private:
- void
- NoteDyingActor()
- {
- MOZ_ASSERT(mActor);
- mActor->AssertIsOnOwningThread();
-
- mActor = nullptr;
- }
-};
-
-class BlobParent::RemoteBlobImpl MOZ_FINAL
- : public RemoteBlobImplBase
- , public FileImplBase
- , public nsIRemoteBlob
-{
- friend class mozilla::dom::BlobParent;
-
- class SliceHelper;
-
- InputStreamParams mInputStreamParams;
-
-public:
- NS_DECL_ISUPPORTS_INHERITED
-
- virtual already_AddRefed<FileImpl>
- CreateSlice(uint64_t aStart, uint64_t aLength, const nsAString& aContentType,
- ErrorResult& aRv) MOZ_OVERRIDE;
-
- virtual nsresult
- GetInternalStream(nsIInputStream** aStream) MOZ_OVERRIDE;
-
- virtual int64_t
- GetLastModified(ErrorResult& aRv) MOZ_OVERRIDE;
-
- virtual BlobChild*
- GetBlobChild() MOZ_OVERRIDE;
-
- virtual BlobParent*
- GetBlobParent() MOZ_OVERRIDE;
-
-private:
- RemoteBlobImpl(BlobParent* aActor,
- const InputStreamParams& aInputStreamParams,
- const nsAString& aName,
- const nsAString& aContentType,
- uint64_t aLength,
- uint64_t aModDate)
- : RemoteBlobImplBase(aActor, /* aForwards */ false)
- , FileImplBase(aName, aContentType, aLength, aModDate)
- {
- CommonInit(aInputStreamParams);
- }
-
- RemoteBlobImpl(BlobParent* aActor,
- const InputStreamParams& aInputStreamParams,
- const nsAString& aContentType,
- uint64_t aLength)
- : RemoteBlobImplBase(aActor, /* aForwards */ false)
- , FileImplBase(aContentType, aLength)
- {
- CommonInit(aInputStreamParams);
- }
-
- ~RemoteBlobImpl()
- { }
-
- void
- CommonInit(const InputStreamParams& aInputStreamParams)
- {
- MOZ_ASSERT(aInputStreamParams.type() != InputStreamParams::T__None);
-
- mInputStreamParams = aInputStreamParams;
-
- mImmutable = true;
- }
-};
-
-class BlobParent::RemoteBlobImpl::SliceHelper MOZ_FINAL
- : public nsRunnable
-{
- Monitor mMonitor;
- BlobParent* mActor;
- nsRefPtr<FileImpl> mSlice;
- uint64_t mStart;
- uint64_t mLength;
- nsString mContentType;
- bool mDone;
-
-public:
- explicit
- SliceHelper(BlobParent* aActor)
- : mMonitor("BlobParent::RemoteBlobImpl::SliceHelper::mMonitor")
- , mActor(aActor)
- , mStart(0)
- , mLength(0)
- , mDone(false)
- {
- // This may be created on any thread.
- MOZ_ASSERT(aActor);
- }
-
- FileImpl*
- GetSlice(uint64_t aStart,
- uint64_t aLength,
- const nsAString& aContentType)
- {
- // This may be called on any thread.
- MOZ_ASSERT(mActor);
- MOZ_ASSERT(!mSlice);
- MOZ_ASSERT(!mDone);
-
- mStart = aStart;
- mLength = aLength;
- mContentType = aContentType;
-
- if (mActor->IsOnOwningThread()) {
- RunInternal(false);
- } else {
- nsCOMPtr<nsIEventTarget> target = mActor->EventTarget();
- if (!target) {
- target = do_GetMainThread();
- }
-
- MOZ_ASSERT(target);
-
- nsresult rv = target->Dispatch(this, NS_DISPATCH_NORMAL);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return nullptr;
- }
-
- {
- MonitorAutoLock lock(mMonitor);
- while (!mDone) {
- lock.Wait();
- }
- }
- }
-
- MOZ_ASSERT(!mActor);
- MOZ_ASSERT(mDone);
-
- if (NS_WARN_IF(!mSlice)) {
- return nullptr;
- }
-
- return mSlice;
- }
-
- NS_IMETHOD
- Run() MOZ_OVERRIDE
- {
- MOZ_ASSERT(mActor);
- mActor->AssertIsOnOwningThread();
-
- RunInternal(true);
- return NS_OK;
- }
-
-private:
- void
- RunInternal(bool aNotify)
- {
- MOZ_ASSERT(mActor);
- mActor->AssertIsOnOwningThread();
- MOZ_ASSERT(!mSlice);
- MOZ_ASSERT(!mDone);
-
- NS_ENSURE_TRUE_VOID(mActor->HasManager());
-
- nsID id;
- MOZ_ALWAYS_TRUE(NS_SUCCEEDED(gUUIDGenerator->GenerateUUIDInPlace(&id)));
-
- ParentBlobConstructorParams params(
- NormalBlobConstructorParams(mContentType /* contentType */,
- mLength /* length */),
- void_t() /* optionalInputStreamParams */);
-
- ChildBlobConstructorParams otherSideParams(
- id,
- SlicedBlobConstructorParams(mActor /* sourceParent*/,
- nullptr /* sourceChild */,
- void_t() /* optionalID */,
- mStart /* begin */,
- mStart + mLength /* end */,
- mContentType /* contentType */));
-
- BlobParent* newActor;
- if (nsIContentParent* contentManager = mActor->GetContentManager()) {
- newActor = SendSliceConstructor(contentManager, params, otherSideParams);
- } else {
- newActor = SendSliceConstructor(mActor->GetBackgroundManager(),
- params,
- otherSideParams);
- }
-
- if (newActor) {
- mSlice = newActor->GetBlobImpl();
- }
-
- mActor = nullptr;
-
- if (aNotify) {
- MonitorAutoLock lock(mMonitor);
- mDone = true;
- lock.Notify();
- }
- else {
- mDone = true;
- }
- }
-};
-
-class BlobParent::ForwardingRemoteBlobImpl MOZ_FINAL
- : public RemoteBlobImplBase
- , public FileImpl
- , public nsIRemoteBlob
-{
- friend class mozilla::dom::BlobParent;
-
- typedef mozilla::dom::indexedDB::FileInfo FileInfo;
- typedef mozilla::dom::indexedDB::FileManager FileManager;
-
- nsRefPtr<FileImpl> mBlobImpl;
- nsCOMPtr<nsIRemoteBlob> mRemoteBlob;
-
-public:
- NS_DECL_ISUPPORTS_INHERITED
-
- virtual void
- GetName(nsAString& aName) MOZ_OVERRIDE
- {
- mBlobImpl->GetName(aName);
- }
-
- virtual nsresult
- GetPath(nsAString& aPath) MOZ_OVERRIDE
- {
- return mBlobImpl->GetPath(aPath);
- }
-
- virtual int64_t
- GetLastModified(ErrorResult& aRv) MOZ_OVERRIDE
- {
- return mBlobImpl->GetLastModified(aRv);
- }
-
- virtual void
- GetMozFullPath(nsAString& aName, ErrorResult& aRv) MOZ_OVERRIDE
- {
- mBlobImpl->GetMozFullPath(aName, aRv);
- }
-
- virtual void
- GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) MOZ_OVERRIDE
- {
- mBlobImpl->GetMozFullPathInternal(aFileName, aRv);
- }
-
- virtual uint64_t
- GetSize(ErrorResult& aRv) MOZ_OVERRIDE
- {
- return mBlobImpl->GetSize(aRv);
- }
-
- virtual void
- GetType(nsAString& aType) MOZ_OVERRIDE
- {
- mBlobImpl->GetType(aType);
- }
-
- virtual already_AddRefed<FileImpl>
- CreateSlice(uint64_t aStart,
- uint64_t aLength,
- const nsAString& aContentType,
- ErrorResult& aRv) MOZ_OVERRIDE
- {
- return mBlobImpl->CreateSlice(aStart, aLength, aContentType, aRv);
- }
-
- virtual const nsTArray<nsRefPtr<FileImpl>>*
- GetSubBlobImpls() const MOZ_OVERRIDE
- {
- return mBlobImpl->GetSubBlobImpls();
- }
-
- virtual nsresult
- GetInternalStream(nsIInputStream** aStream) MOZ_OVERRIDE
- {
- return mBlobImpl->GetInternalStream(aStream);
- }
-
- virtual int64_t
- GetFileId() MOZ_OVERRIDE
- {
- return mBlobImpl->GetFileId();
- }
-
- virtual void
- AddFileInfo(FileInfo* aFileInfo) MOZ_OVERRIDE
- {
- return mBlobImpl->AddFileInfo(aFileInfo);
- }
-
- virtual FileInfo*
- GetFileInfo(FileManager* aFileManager) MOZ_OVERRIDE
- {
- return mBlobImpl->GetFileInfo(aFileManager);
- }
-
- virtual nsresult
- GetSendInfo(nsIInputStream** aBody,
- uint64_t* aContentLength,
- nsACString& aContentType,
- nsACString& aCharset) MOZ_OVERRIDE
- {
- return mBlobImpl->GetSendInfo(aBody,
- aContentLength,
- aContentType,
- aCharset);
- }
-
- virtual nsresult
- GetMutable(bool* aMutable) const MOZ_OVERRIDE
- {
- return mBlobImpl->GetMutable(aMutable);
- }
-
- virtual nsresult
- SetMutable(bool aMutable) MOZ_OVERRIDE
- {
- return mBlobImpl->SetMutable(aMutable);
- }
-
- virtual void
- SetLazyData(const nsAString& aName,
- const nsAString& aContentType,
- uint64_t aLength,
- uint64_t aLastModifiedDate) MOZ_OVERRIDE
- {
- MOZ_CRASH("This should never be called!");
- }
-
- virtual bool
- IsMemoryFile() const MOZ_OVERRIDE
- {
- return mBlobImpl->IsMemoryFile();
- }
-
- virtual bool
- IsSizeUnknown() const MOZ_OVERRIDE
- {
- return mBlobImpl->IsSizeUnknown();
- }
-
- virtual bool
- IsDateUnknown() const MOZ_OVERRIDE
- {
- return mBlobImpl->IsDateUnknown();
- }
-
- virtual bool
- IsFile() const MOZ_OVERRIDE
- {
- return mBlobImpl->IsFile();
- }
-
- virtual void
- Unlink() MOZ_OVERRIDE
- {
- return mBlobImpl->Unlink();
- }
-
- virtual void
- Traverse(nsCycleCollectionTraversalCallback& aCallback) MOZ_OVERRIDE
- {
- return mBlobImpl->Traverse(aCallback);
- }
-
- virtual BlobChild*
- GetBlobChild() MOZ_OVERRIDE
- {
- MOZ_ASSERT(mRemoteBlob);
-
- return mRemoteBlob->GetBlobChild();
- }
-
- virtual BlobParent*
- GetBlobParent() MOZ_OVERRIDE
- {
- MOZ_ASSERT(mRemoteBlob);
-
- return mRemoteBlob->GetBlobParent();
- }
-
-private:
- ForwardingRemoteBlobImpl(BlobParent* aActor,
- FileImpl* aBlobImpl)
- : RemoteBlobImplBase(aActor, /* aForwards */ true)
- , mBlobImpl(aBlobImpl)
- , mRemoteBlob(do_QueryObject(aBlobImpl))
- {
- MOZ_ASSERT(aBlobImpl);
-
- DebugOnly<bool> isMutable;
- MOZ_ASSERT(NS_SUCCEEDED(aBlobImpl->GetMutable(&isMutable)));
- MOZ_ASSERT(!isMutable);
- }
-
- ~ForwardingRemoteBlobImpl()
- { }
-};
-
-/*******************************************************************************
- * BlobParent::RemoteBlobImpl Implementation
- ******************************************************************************/
-
-NS_IMPL_ADDREF(BlobParent::RemoteBlobImpl)
-NS_IMPL_RELEASE_WITH_DESTROY(BlobParent::RemoteBlobImpl, Destroy())
-NS_IMPL_QUERY_INTERFACE_INHERITED(BlobParent::RemoteBlobImpl,
- FileImplBase,
- nsIRemoteBlob)
-
-already_AddRefed<FileImpl>
-BlobParent::
-RemoteBlobImpl::CreateSlice(uint64_t aStart,
- uint64_t aLength,
- const nsAString& aContentType,
- ErrorResult& aRv)
-{
- if (!mActor) {
- aRv.Throw(NS_ERROR_FAILURE);
- return nullptr;
- }
-
- nsRefPtr<SliceHelper> helper = new SliceHelper(mActor);
-
- nsRefPtr<FileImpl> impl = helper->GetSlice(aStart, aLength, aContentType);
- if (NS_WARN_IF(!impl)) {
- aRv.Throw(NS_ERROR_FAILURE);
- return nullptr;
- }
-
- return impl.forget();
-}
-
-nsresult
-BlobParent::
-RemoteBlobImpl::GetInternalStream(nsIInputStream** aStream)
-{
- MOZ_ASSERT(mInputStreamParams.type() != InputStreamParams::T__None);
-
- nsTArray<FileDescriptor> fds;
- nsCOMPtr<nsIInputStream> realStream =
- DeserializeInputStream(mInputStreamParams, fds);
- if (!realStream) {
- NS_WARNING("Failed to deserialize stream!");
- return NS_ERROR_UNEXPECTED;
- }
-
- nsCOMPtr<nsIInputStream> stream =
- new BlobInputStreamTether(realStream, this);
- stream.forget(aStream);
- return NS_OK;
-}
-
-int64_t
-BlobParent::
-RemoteBlobImpl::GetLastModified(ErrorResult& aRv)
-{
- if (IsDateUnknown()) {
- return 0;
- }
-
- return mLastModificationDate;
-}
-
-BlobChild*
-BlobParent::
-RemoteBlobImpl::GetBlobChild()
-{
- return nullptr;
-}
-
-BlobParent*
-BlobParent::
-RemoteBlobImpl::GetBlobParent()
-{
- return mActor;
-}
-
-NS_IMPL_ADDREF(BlobParent::ForwardingRemoteBlobImpl)
-NS_IMPL_RELEASE_WITH_DESTROY(BlobParent::ForwardingRemoteBlobImpl, Destroy())
-NS_INTERFACE_MAP_BEGIN(BlobParent::ForwardingRemoteBlobImpl)
- NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIRemoteBlob, mRemoteBlob)
-NS_INTERFACE_MAP_END_INHERITING(FileImpl)
-
-/*******************************************************************************
* BlobParent
******************************************************************************/
BlobParent::BlobParent(nsIContentParent* aManager, IDTableEntry* aIDTableEntry)
: mBackgroundManager(nullptr)
, mContentManager(aManager)
{
AssertCorrectThreadForManager(aManager);
@@ -2733,39 +3140,39 @@ BlobParent::BlobParent(PBackgroundParent
AssertCorrectThreadForManager(aManager);
MOZ_ASSERT(aManager);
MOZ_ASSERT(mEventTarget);
CommonInit(aIDTableEntry);
}
BlobParent::BlobParent(nsIContentParent* aManager,
- const ParentBlobConstructorParams& aParams,
+ FileImpl* aBlobImpl,
IDTableEntry* aIDTableEntry)
: mBackgroundManager(nullptr)
, mContentManager(aManager)
{
AssertCorrectThreadForManager(aManager);
MOZ_ASSERT(aManager);
- CommonInit(aParams, aIDTableEntry);
+ CommonInit(aBlobImpl, aIDTableEntry);
}
BlobParent::BlobParent(PBackgroundParent* aManager,
- const ParentBlobConstructorParams& aParams,
+ FileImpl* aBlobImpl,
IDTableEntry* aIDTableEntry)
: mBackgroundManager(aManager)
, mContentManager(nullptr)
, mEventTarget(do_GetCurrentThread())
{
AssertCorrectThreadForManager(aManager);
MOZ_ASSERT(aManager);
MOZ_ASSERT(mEventTarget);
- CommonInit(aParams, aIDTableEntry);
+ CommonInit(aBlobImpl, aIDTableEntry);
}
BlobParent::~BlobParent()
{
AssertIsOnOwningThread();
MOZ_COUNT_DTOR(BlobParent);
}
@@ -2784,110 +3191,34 @@ BlobParent::CommonInit(IDTableEntry* aID
mBlobImpl->AddRef();
mOwnsBlobImpl = true;
mIDTableEntry = aIDTableEntry;
}
void
-BlobParent::CommonInit(const ParentBlobConstructorParams& aParams,
- IDTableEntry* aIDTableEntry)
+BlobParent::CommonInit(FileImpl* aBlobImpl, IDTableEntry* aIDTableEntry)
{
AssertIsOnOwningThread();
+ MOZ_ASSERT(aBlobImpl);
+ MOZ_ASSERT(aIDTableEntry);
MOZ_COUNT_CTOR(BlobParent);
- const AnyBlobConstructorParams& blobParams = aParams.blobParams();
-
- const AnyBlobConstructorParams::Type paramsType = blobParams.type();
- MOZ_ASSERT(paramsType ==
- AnyBlobConstructorParams::TNormalBlobConstructorParams ||
- paramsType ==
- AnyBlobConstructorParams::TFileBlobConstructorParams ||
- paramsType ==
- AnyBlobConstructorParams::TKnownBlobConstructorParams);
- MOZ_ASSERT_IF(paramsType ==
- AnyBlobConstructorParams::TKnownBlobConstructorParams,
- aIDTableEntry);
- MOZ_ASSERT_IF(paramsType !=
- AnyBlobConstructorParams::TKnownBlobConstructorParams,
- !aIDTableEntry);
- MOZ_ASSERT_IF(paramsType ==
- AnyBlobConstructorParams::TKnownBlobConstructorParams,
- aParams.optionalInputStreamParams().type() ==
- OptionalInputStreamParams::Tvoid_t);
- MOZ_ASSERT_IF(paramsType !=
- AnyBlobConstructorParams::TKnownBlobConstructorParams,
- aParams.optionalInputStreamParams().type() ==
- OptionalInputStreamParams::TInputStreamParams);
-
- nsRefPtr<FileImpl> remoteBlobImpl;
- RemoteBlobImplBase* remoteBlobBase = nullptr;
-
- switch (paramsType) {
- case AnyBlobConstructorParams::TNormalBlobConstructorParams: {
- const InputStreamParams& inputStreamParams =
- aParams.optionalInputStreamParams().get_InputStreamParams();
-
- const NormalBlobConstructorParams& params =
- blobParams.get_NormalBlobConstructorParams();
-
- nsRefPtr<RemoteBlobImpl> impl =
- new RemoteBlobImpl(this,
- inputStreamParams,
- params.contentType(),
- params.length());
-
- remoteBlobBase = impl;
- remoteBlobImpl = impl.forget();
- break;
- }
-
- case AnyBlobConstructorParams::TFileBlobConstructorParams: {
- const InputStreamParams& inputStreamParams =
- aParams.optionalInputStreamParams().get_InputStreamParams();
-
- const FileBlobConstructorParams& params =
- blobParams.get_FileBlobConstructorParams();
-
- nsRefPtr<RemoteBlobImpl> impl =
- new RemoteBlobImpl(this,
- inputStreamParams,
- params.name(),
- params.contentType(),
- params.length(),
- params.modDate());
-
- remoteBlobBase = impl;
- remoteBlobImpl = impl.forget();
- break;
- }
-
- case AnyBlobConstructorParams::TKnownBlobConstructorParams: {
- nsRefPtr<ForwardingRemoteBlobImpl> impl =
- new ForwardingRemoteBlobImpl(this, aIDTableEntry->BlobImpl());
-
- remoteBlobBase = impl;
- remoteBlobImpl = impl.forget();
- break;
- }
-
- default:
- MOZ_CRASH("Unknown params!");
- }
-
- MOZ_ASSERT(remoteBlobImpl);
- MOZ_ASSERT(remoteBlobBase);
-
DebugOnly<bool> isMutable;
+ MOZ_ASSERT(NS_SUCCEEDED(aBlobImpl->GetMutable(&isMutable)));
+ MOZ_ASSERT(!isMutable);
+
+ nsRefPtr<RemoteBlobImpl> remoteBlobImpl = new RemoteBlobImpl(this, aBlobImpl);
+
MOZ_ASSERT(NS_SUCCEEDED(remoteBlobImpl->GetMutable(&isMutable)));
MOZ_ASSERT(!isMutable);
- mRemoteBlobImpl = remoteBlobBase;
+ mRemoteBlobImpl = remoteBlobImpl;
remoteBlobImpl.forget(&mBlobImpl);
mOwnsBlobImpl = true;
mIDTableEntry = aIDTableEntry;
}
#ifdef DEBUG
@@ -3067,66 +3398,82 @@ BlobParent::CreateFromParams(ParentManag
case AnyBlobConstructorParams::TNormalBlobConstructorParams:
case AnyBlobConstructorParams::TFileBlobConstructorParams: {
if (aParams.optionalInputStreamParams().type() !=
OptionalInputStreamParams::TInputStreamParams) {
ASSERT_UNLESS_FUZZING();
return nullptr;
}
- return new BlobParent(aManager, aParams, /* aIDTableEntry */ nullptr);
+ nsRefPtr<FileImpl> blobImpl =
+ CreateBlobImplFromParams(aParams, ActorManagerIsSameProcess(aManager));
+ if (NS_WARN_IF(!blobImpl)) {
+ ASSERT_UNLESS_FUZZING();
+ return nullptr;
+ }
+
+ nsID id;
+ MOZ_ALWAYS_TRUE(NS_SUCCEEDED(gUUIDGenerator->GenerateUUIDInPlace(&id)));
+
+ nsRefPtr<IDTableEntry> idTableEntry =
+ IDTableEntry::Create(id, ActorManagerProcessID(aManager), blobImpl);
+ if (NS_WARN_IF(!idTableEntry)) {
+ ASSERT_UNLESS_FUZZING();
+ return nullptr;
+ }
+
+ return new BlobParent(aManager, blobImpl, idTableEntry);
}
case AnyBlobConstructorParams::TSlicedBlobConstructorParams: {
if (aParams.optionalInputStreamParams().type() !=
OptionalInputStreamParams::Tvoid_t) {
ASSERT_UNLESS_FUZZING();
return nullptr;
}
const SlicedBlobConstructorParams& params =
blobParams.get_SlicedBlobConstructorParams();
- if (NS_WARN_IF(params.optionalID().type() != OptionalID::TnsID)) {
+
+ if (NS_WARN_IF(params.end() < params.begin())) {
ASSERT_UNLESS_FUZZING();
return nullptr;
}
auto* actor =
const_cast<BlobParent*>(
static_cast<const BlobParent*>(params.sourceParent()));
MOZ_ASSERT(actor);
nsRefPtr<FileImpl> source = actor->GetBlobImpl();
MOZ_ASSERT(source);
- Optional<int64_t> start;
- start.Construct(params.begin());
-
- Optional<int64_t> end;
- end.Construct(params.end());
-
ErrorResult rv;
nsRefPtr<FileImpl> slice =
- source->Slice(start, end, params.contentType(), rv);
+ source->CreateSlice(params.begin(),
+ params.end() - params.begin(),
+ params.contentType(),
+ rv);
if (NS_WARN_IF(rv.Failed())) {
+ ASSERT_UNLESS_FUZZING();
return nullptr;
}
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(slice->SetMutable(false)));
nsRefPtr<IDTableEntry> idTableEntry =
- IDTableEntry::Create(params.optionalID(),
+ IDTableEntry::Create(params.id(),
ActorManagerProcessID(aManager),
slice);
if (NS_WARN_IF(!idTableEntry)) {
ASSERT_UNLESS_FUZZING();
return nullptr;
}
- return new BlobParent(aManager, idTableEntry);
+ return new BlobParent(aManager, slice, idTableEntry);
}
case AnyBlobConstructorParams::TKnownBlobConstructorParams: {
if (aParams.optionalInputStreamParams().type() !=
OptionalInputStreamParams::Tvoid_t) {
ASSERT_UNLESS_FUZZING();
return nullptr;
}
@@ -3136,17 +3483,20 @@ BlobParent::CreateFromParams(ParentManag
nsRefPtr<IDTableEntry> idTableEntry =
IDTableEntry::Get(params.id(), ActorManagerProcessID(aManager));
if (NS_WARN_IF(!idTableEntry)) {
ASSERT_UNLESS_FUZZING();
return nullptr;
}
- return new BlobParent(aManager, aParams, idTableEntry);
+ nsRefPtr<FileImpl> blobImpl = idTableEntry->BlobImpl();
+ MOZ_ASSERT(blobImpl);
+
+ return new BlobParent(aManager, blobImpl, idTableEntry);
}
default:
MOZ_CRASH("Unknown params!");
}
MOZ_CRASH("Should never get here!");
}
@@ -3307,40 +3657,74 @@ BlobParent::ActorDestroy(ActorDestroyRea
mRemoteBlobImpl = nullptr;
mBackgroundManager = nullptr;
mContentManager = nullptr;
mOwnsBlobImpl = false;
#endif
}
PBlobStreamParent*
-BlobParent::AllocPBlobStreamParent()
+BlobParent::AllocPBlobStreamParent(const uint64_t& aStart,
+ const uint64_t& aLength)
{
AssertIsOnOwningThread();
- if (NS_WARN_IF(mRemoteBlobImpl && !mRemoteBlobImpl->mForwards)) {
+ if (NS_WARN_IF(mRemoteBlobImpl)) {
ASSERT_UNLESS_FUZZING();
return nullptr;
}
return new InputStreamParent();
}
bool
-BlobParent::RecvPBlobStreamConstructor(PBlobStreamParent* aActor)
+BlobParent::RecvPBlobStreamConstructor(PBlobStreamParent* aActor,
+ const uint64_t& aStart,
+ const uint64_t& aLength)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aActor);
MOZ_ASSERT(mBlobImpl);
- MOZ_ASSERT_IF(mRemoteBlobImpl, mRemoteBlobImpl->mForwards);
+ MOZ_ASSERT(!mRemoteBlobImpl);
MOZ_ASSERT(mOwnsBlobImpl);
+ // Make sure we can't overflow.
+ if (NS_WARN_IF(UINT64_MAX - aLength < aStart)) {
+ ASSERT_UNLESS_FUZZING();
+ return nullptr;
+ }
+
+ ErrorResult errorResult;
+ uint64_t blobLength = mBlobImpl->GetSize(errorResult);
+ MOZ_ASSERT(!errorResult.Failed());
+
+ if (NS_WARN_IF(aStart + aLength > blobLength)) {
+ ASSERT_UNLESS_FUZZING();
+ return nullptr;
+ }
+
+ nsRefPtr<FileImpl> blobImpl;
+
+ if (!aStart && aLength == blobLength) {
+ blobImpl = mBlobImpl;
+ } else {
+ nsString type;
+ mBlobImpl->GetType(type);
+
+ blobImpl = mBlobImpl->CreateSlice(aStart, aLength, type, errorResult);
+ if (NS_WARN_IF(errorResult.Failed())) {
+ return false;
+ }
+ }
+
nsCOMPtr<nsIInputStream> stream;
- nsresult rv = mBlobImpl->GetInternalStream(getter_AddRefs(stream));
- NS_ENSURE_SUCCESS(rv, false);
+ errorResult = blobImpl->GetInternalStream(getter_AddRefs(stream));
+ if (NS_WARN_IF(errorResult.Failed())) {
+ return false;
+ }
// If the stream is entirely backed by memory then we can serialize and send
// it immediately.
if (mBlobImpl->IsMemoryFile()) {
InputStreamParams params;
nsTArray<FileDescriptor> fds;
SerializeInputStream(stream, params, fds);
@@ -3373,26 +3757,28 @@ BlobParent::RecvPBlobStreamConstructor(P
serializableStream = do_QueryInterface(stream);
if (!serializableStream) {
MOZ_ASSERT(false, "Must be serializable!");
return false;
}
}
nsCOMPtr<nsIThread> target;
- rv = NS_NewNamedThread("Blob Opener", getter_AddRefs(target));
- if (NS_WARN_IF(NS_FAILED(rv))) {
+ errorResult = NS_NewNamedThread("Blob Opener", getter_AddRefs(target));
+ if (NS_WARN_IF(errorResult.Failed())) {
return false;
}
nsRefPtr<OpenStreamRunnable> runnable =
new OpenStreamRunnable(this, aActor, stream, serializableStream, target);
- rv = runnable->Dispatch();
- NS_ENSURE_SUCCESS(rv, false);
+ errorResult = runnable->Dispatch();
+ if (NS_WARN_IF(errorResult.Failed())) {
+ return false;
+ }
// nsRevocableEventPtr lacks some of the operators needed for anything nicer.
*mOpenStreamRunnables.AppendElement() = runnable;
return true;
}
bool
BlobParent::DeallocPBlobStreamParent(PBlobStreamParent* aActor)
@@ -3464,17 +3850,16 @@ BlobParent::RecvResolveMystery(const Res
MOZ_CRASH("Should never get here!");
}
bool
BlobParent::RecvWaitForSliceCreation()
{
AssertIsOnOwningThread();
MOZ_ASSERT(mBlobImpl);
- MOZ_ASSERT(!mRemoteBlobImpl);
MOZ_ASSERT(mOwnsBlobImpl);
// The whole point of this message is to ensure that the sliced blob created
// by the child has been inserted into our IDTable.
MOZ_ASSERT(mIDTableEntry);
#ifdef DEBUG
{
@@ -3487,18 +3872,16 @@ BlobParent::RecvWaitForSliceCreation()
#endif
return true;
}
bool
BlobParent::RecvGetFileId(int64_t* aFileId)
{
- using namespace mozilla::dom::indexedDB;
-
AssertIsOnOwningThread();
MOZ_ASSERT(mBlobImpl);
MOZ_ASSERT(!mRemoteBlobImpl);
MOZ_ASSERT(mOwnsBlobImpl);
if (NS_WARN_IF(!IndexedDatabaseManager::InTestingMode())) {
ASSERT_UNLESS_FUZZING();
return false;
@@ -3506,18 +3889,16 @@ BlobParent::RecvGetFileId(int64_t* aFile
*aFileId = mBlobImpl->GetFileId();
return true;
}
bool
BlobParent::RecvGetFilePath(nsString* aFilePath)
{
- using namespace mozilla::dom::indexedDB;
-
AssertIsOnOwningThread();
MOZ_ASSERT(mBlobImpl);
MOZ_ASSERT(!mRemoteBlobImpl);
MOZ_ASSERT(mOwnsBlobImpl);
// In desktop e10s the file picker code sends this message.
#ifdef MOZ_CHILD_PERMISSIONS
if (NS_WARN_IF(!IndexedDatabaseManager::InTestingMode())) {
@@ -3532,41 +3913,19 @@ BlobParent::RecvGetFilePath(nsString* aF
if (NS_WARN_IF(rv.Failed())) {
return false;
}
*aFilePath = filePath;
return true;
}
-bool
-InputStreamChild::Recv__delete__(const InputStreamParams& aParams,
- const OptionalFileDescriptorSet& aFDs)
-{
- MOZ_ASSERT(mRemoteStream);
- mRemoteStream->AssertIsOnOwningThread();
-
- nsTArray<FileDescriptor> fds;
- if (aFDs.type() == OptionalFileDescriptorSet::TPFileDescriptorSetChild) {
- FileDescriptorSetChild* fdSetActor =
- static_cast<FileDescriptorSetChild*>(aFDs.get_PFileDescriptorSetChild());
- MOZ_ASSERT(fdSetActor);
-
- fdSetActor->ForgetFileDescriptors(fds);
- MOZ_ASSERT(!fds.IsEmpty());
-
- fdSetActor->Send__delete__(fdSetActor);
- }
-
- nsCOMPtr<nsIInputStream> stream = DeserializeInputStream(aParams, fds);
- MOZ_ASSERT(stream);
-
- mRemoteStream->SetStream(stream);
- return true;
-}
+/*******************************************************************************
+ * BlobParent::IDTableEntry
+ ******************************************************************************/
BlobParent::
IDTableEntry::IDTableEntry(const nsID& aID,
intptr_t aProcessID,
FileImpl* aBlobImpl)
: mID(aID)
, mProcessID(aProcessID)
, mBlobImpl(aBlobImpl)
@@ -3645,10 +4004,40 @@ IDTableEntry::GetOrCreateInternal(const
}
}
MOZ_ASSERT(entry);
return entry.forget();
}
+/*******************************************************************************
+ * Other stuff
+ ******************************************************************************/
+
+bool
+InputStreamChild::Recv__delete__(const InputStreamParams& aParams,
+ const OptionalFileDescriptorSet& aFDs)
+{
+ MOZ_ASSERT(mRemoteStream);
+ mRemoteStream->AssertIsOnOwningThread();
+
+ nsTArray<FileDescriptor> fds;
+ if (aFDs.type() == OptionalFileDescriptorSet::TPFileDescriptorSetChild) {
+ FileDescriptorSetChild* fdSetActor =
+ static_cast<FileDescriptorSetChild*>(aFDs.get_PFileDescriptorSetChild());
+ MOZ_ASSERT(fdSetActor);
+
+ fdSetActor->ForgetFileDescriptors(fds);
+ MOZ_ASSERT(!fds.IsEmpty());
+
+ fdSetActor->Send__delete__(fdSetActor);
+ }
+
+ nsCOMPtr<nsIInputStream> stream = DeserializeInputStream(aParams, fds);
+ MOZ_ASSERT(stream);
+
+ mRemoteStream->SetStream(stream);
+ return true;
+}
+
} // namespace dom
} // namespace mozilla
--- a/dom/ipc/BlobChild.h
+++ b/dom/ipc/BlobChild.h
@@ -32,16 +32,19 @@ class PBlobStreamChild;
class BlobChild MOZ_FINAL
: public PBlobChild
{
typedef mozilla::ipc::PBackgroundChild PBackgroundChild;
class RemoteBlobImpl;
friend class RemoteBlobImpl;
+ class RemoteBlobSliceImpl;
+ friend class RemoteBlobSliceImpl;
+
FileImpl* mBlobImpl;
RemoteBlobImpl* mRemoteBlobImpl;
// One of these will be null and the other non-null.
PBackgroundChild* mBackgroundManager;
nsCOMPtr<nsIContentChild> mContentManager;
nsCOMPtr<nsIEventTarget> mEventTarget;
@@ -136,42 +139,54 @@ private:
// These constructors are called on the receiving side.
BlobChild(nsIContentChild* aManager,
const ChildBlobConstructorParams& aParams);
BlobChild(PBackgroundChild* aManager,
const ChildBlobConstructorParams& aParams);
+ // These constructors are called for slices.
+ BlobChild(nsIContentChild* aManager,
+ const nsID& aParentID,
+ RemoteBlobSliceImpl* aRemoteBlobSliceImpl);
+
+ BlobChild(PBackgroundChild* aManager,
+ const nsID& aParentID,
+ RemoteBlobSliceImpl* aRemoteBlobSliceImpl);
+
// Only called by Destroy().
~BlobChild();
void
CommonInit(FileImpl* aBlobImpl);
void
CommonInit(BlobChild* aOther);
void
CommonInit(const ChildBlobConstructorParams& aParams);
+ void
+ CommonInit(const nsID& aParentID, RemoteBlobImpl* aRemoteBlobImpl);
+
template <class ChildManagerType>
static BlobChild*
GetOrCreateFromImpl(ChildManagerType* aManager, FileImpl* aBlobImpl);
template <class ChildManagerType>
static BlobChild*
CreateFromParams(ChildManagerType* aManager,
const ChildBlobConstructorParams& aParams);
template <class ChildManagerType>
static BlobChild*
SendSliceConstructor(ChildManagerType* aManager,
- const ChildBlobConstructorParams& aParams,
- const ParentBlobConstructorParams& aOtherSideParams);
+ RemoteBlobSliceImpl* aRemoteBlobSliceImpl,
+ const ParentBlobConstructorParams& aParams);
static BlobChild*
MaybeGetActorFromRemoteBlob(nsIRemoteBlob* aRemoteBlob,
nsIContentChild* aManager);
static BlobChild*
MaybeGetActorFromRemoteBlob(nsIRemoteBlob* aRemoteBlob,
PBackgroundChild* aManager);
@@ -188,17 +203,18 @@ private:
bool
IsOnOwningThread() const;
// These methods are only called by the IPDL message machinery.
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
virtual PBlobStreamChild*
- AllocPBlobStreamChild() MOZ_OVERRIDE;
+ AllocPBlobStreamChild(const uint64_t& aStart,
+ const uint64_t& aLength) MOZ_OVERRIDE;
virtual bool
DeallocPBlobStreamChild(PBlobStreamChild* aActor) MOZ_OVERRIDE;
};
// Only let ContentChild call BlobChild::Startup() and ensure that
// ContentChild can't access any other BlobChild internals.
class BlobChild::FriendKey MOZ_FINAL
--- a/dom/ipc/BlobParent.h
+++ b/dom/ipc/BlobParent.h
@@ -43,27 +43,25 @@ class BlobParent MOZ_FINAL
typedef mozilla::ipc::PBackgroundParent PBackgroundParent;
class IDTableEntry;
typedef nsDataHashtable<nsIDHashKey, IDTableEntry*> IDTable;
class OpenStreamRunnable;
friend class OpenStreamRunnable;
- class RemoteBlobImplBase;
- friend class RemoteBlobImplBase;
+ class RemoteBlobImpl;
- class RemoteBlobImpl;
- class ForwardingRemoteBlobImpl;
+ struct CreateBlobImplMetadata;
static StaticAutoPtr<IDTable> sIDTable;
static StaticAutoPtr<Mutex> sIDTableMutex;
FileImpl* mBlobImpl;
- RemoteBlobImplBase* mRemoteBlobImpl;
+ RemoteBlobImpl* mRemoteBlobImpl;
// One of these will be null and the other non-null.
PBackgroundParent* mBackgroundManager;
nsCOMPtr<nsIContentParent> mContentManager;
nsCOMPtr<nsIEventTarget> mEventTarget;
// nsIInputStreams backed by files must ensure that the files are actually
@@ -143,32 +141,31 @@ public:
private:
// These constructors are called on the sending side.
BlobParent(nsIContentParent* aManager, IDTableEntry* aIDTableEntry);
BlobParent(PBackgroundParent* aManager, IDTableEntry* aIDTableEntry);
// These constructors are called on the receiving side.
BlobParent(nsIContentParent* aManager,
- const ParentBlobConstructorParams& aParams,
+ FileImpl* aBlobImpl,
IDTableEntry* aIDTableEntry);
BlobParent(PBackgroundParent* aManager,
- const ParentBlobConstructorParams& aParams,
+ FileImpl* aBlobImpl,
IDTableEntry* aIDTableEntry);
// Only destroyed by BackgroundParentImpl and ContentParent.
~BlobParent();
void
CommonInit(IDTableEntry* aIDTableEntry);
void
- CommonInit(const ParentBlobConstructorParams& aParams,
- IDTableEntry* aIDTableEntry);
+ CommonInit(FileImpl* aBlobImpl, IDTableEntry* aIDTableEntry);
template <class ParentManagerType>
static BlobParent*
GetOrCreateFromImpl(ParentManagerType* aManager,
FileImpl* aBlobImpl);
template <class ParentManagerType>
static BlobParent*
@@ -204,20 +201,23 @@ private:
bool
IsOnOwningThread() const;
// These methods are only called by the IPDL message machinery.
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
virtual PBlobStreamParent*
- AllocPBlobStreamParent() MOZ_OVERRIDE;
+ AllocPBlobStreamParent(const uint64_t& aStart,
+ const uint64_t& aLength) MOZ_OVERRIDE;
virtual bool
- RecvPBlobStreamConstructor(PBlobStreamParent* aActor) MOZ_OVERRIDE;
+ RecvPBlobStreamConstructor(PBlobStreamParent* aActor,
+ const uint64_t& aStart,
+ const uint64_t& aLength) MOZ_OVERRIDE;
virtual bool
DeallocPBlobStreamParent(PBlobStreamParent* aActor) MOZ_OVERRIDE;
virtual bool
RecvResolveMystery(const ResolveMysteryParams& aParams) MOZ_OVERRIDE;
virtual bool
--- a/dom/ipc/DOMTypes.ipdlh
+++ b/dom/ipc/DOMTypes.ipdlh
@@ -40,18 +40,17 @@ struct FileBlobConstructorParams
nsString contentType;
uint64_t length;
uint64_t modDate;
};
struct SlicedBlobConstructorParams
{
PBlob source;
- // Must be void_t for parent -> child and nsID for child -> parent.
- OptionalID optionalID;
+ nsID id;
uint64_t begin;
uint64_t end;
nsString contentType;
};
struct MysteryBlobConstructorParams
{
// Nothing is known about this type of blob.
@@ -59,28 +58,33 @@ struct MysteryBlobConstructorParams
struct KnownBlobConstructorParams
{
nsID id;
};
union AnyBlobConstructorParams
{
+ // These types may be sent to/from parent and child.
NormalBlobConstructorParams;
FileBlobConstructorParams;
+
+ // This type may only be sent from parent to child.
+ MysteryBlobConstructorParams;
+
+ // These types may only be sent from child to parent.
SlicedBlobConstructorParams;
- MysteryBlobConstructorParams;
KnownBlobConstructorParams;
};
struct ChildBlobConstructorParams
{
nsID id;
- // May never be KnownBlobConstructorParams.
+ // May not be SlicedBlobConstructorParams or KnownBlobConstructorParams.
AnyBlobConstructorParams blobParams;
};
struct ParentBlobConstructorParams
{
// May not be MysteryBlobConstructorParams.
AnyBlobConstructorParams blobParams;
--- a/dom/ipc/PBlob.ipdl
+++ b/dom/ipc/PBlob.ipdl
@@ -22,17 +22,17 @@ sync protocol PBlob
{
manager PBackground or PContent or PContentBridge;
manages PBlobStream;
both:
__delete__();
parent:
- PBlobStream();
+ PBlobStream(uint64_t begin, uint64_t length);
ResolveMystery(ResolveMysteryParams params);
sync WaitForSliceCreation();
// Use only for testing!
sync GetFileId()
returns (int64_t fileId);
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -393,18 +393,16 @@ parent:
* OnAuthAvailable or OnAuthCancelled message.
*/
AsyncAuthPrompt(nsCString uri, nsString realm, uint64_t aCallbackId);
__delete__();
ReplyKeyEvent(WidgetKeyboardEvent event);
- DispatchAfterKeyboardEvent(WidgetKeyboardEvent event);
-
sync RequestNativeKeyBindings(WidgetKeyboardEvent event)
returns (MaybeNativeKeyBinding bindings);
/**
* Child informs the parent that the graphics objects are ready for
* compositing. This is sent when all pending changes have been
* sent to the compositor and are ready to be shown on the next composite.
* @see PCompositor
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -16,17 +16,17 @@
#include "mozilla/EventListenerManager.h"
#include "mozilla/IntentionalCrash.h"
#include "mozilla/docshell/OfflineCacheUpdateChild.h"
#include "mozilla/dom/indexedDB/PIndexedDBPermissionRequestChild.h"
#include "mozilla/ipc/DocumentRendererChild.h"
#include "mozilla/ipc/FileDescriptorUtils.h"
#include "mozilla/layers/ActiveElementManager.h"
#include "mozilla/layers/APZCCallbackHelper.h"
-#include "mozilla/layers/AsyncPanZoomController.h"
+#include "mozilla/layers/APZCTreeManager.h"
#include "mozilla/layers/CompositorChild.h"
#include "mozilla/layers/ImageBridgeChild.h"
#include "mozilla/layers/ShadowLayers.h"
#include "mozilla/layout/RenderFrameChild.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/Services.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/TextEvents.h"
@@ -76,18 +76,18 @@
#include "JavaScriptChild.h"
#include "nsILoadContext.h"
#include "ipc/nsGUIEventIPC.h"
#include "mozilla/gfx/Matrix.h"
#include "UnitTransforms.h"
#include "ClientLayerManager.h"
#include "LayersLogging.h"
#include "nsIOService.h"
+
#include "nsColorPickerProxy.h"
-#include "nsPresShell.h"
#define BROWSER_ELEMENT_CHILD_SCRIPT \
NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js")
#define TABC_LOG(...)
// #define TABC_LOG(...) printf_stderr("TABC: " __VA_ARGS__)
using namespace mozilla;
@@ -426,17 +426,17 @@ TabChildBase::HandlePossibleViewportChan
if (!pageSize.width) {
// Return early rather than divide by 0.
return false;
}
metrics.mScrollableRect = CSSRect(CSSPoint(), pageSize);
// Calculate a display port _after_ having a scrollable rect because the
// display port is clamped to the scrollable rect.
- metrics.SetDisplayPortMargins(AsyncPanZoomController::CalculatePendingDisplayPort(
+ metrics.SetDisplayPortMargins(APZCTreeManager::CalculatePendingDisplayPort(
// The page must have been refreshed in some way such as a new document or
// new CSS viewport, so we know that there's no velocity, acceleration, and
// we have no idea how long painting will take.
metrics, ScreenPoint(0.0f, 0.0f), 0.0));
metrics.SetUseDisplayPortMargins();
// Force a repaint with these metrics. This, among other things, sets the
// displayport, so we start with async painting.
@@ -2357,20 +2357,16 @@ TabChild::RecvRealKeyEvent(const WidgetK
if (event.message == NS_KEY_DOWN) {
mIgnoreKeyPressEvent = status == nsEventStatus_eConsumeNoDefault;
}
if (localEvent.mFlags.mWantReplyFromContentProcess) {
SendReplyKeyEvent(localEvent);
}
- if (PresShell::BeforeAfterKeyboardEventEnabled()) {
- SendDispatchAfterKeyboardEvent(localEvent);
- }
-
return true;
}
bool
TabChild::RecvKeyEvent(const nsString& aType,
const int32_t& aKeyCode,
const int32_t& aCharCode,
const int32_t& aModifiers,
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -47,17 +47,16 @@
#include "nsIWindowCreator2.h"
#include "nsIXULBrowserWindow.h"
#include "nsIXULWindow.h"
#include "nsViewManager.h"
#include "nsIWidget.h"
#include "nsIWindowWatcher.h"
#include "nsPIDOMWindow.h"
#include "nsPIWindowWatcher.h"
-#include "nsPresShell.h"
#include "nsPrintfCString.h"
#include "nsServiceManagerUtils.h"
#include "nsThreadUtils.h"
#include "nsWindowWatcher.h"
#include "private/pprio.h"
#include "PermissionMessageUtils.h"
#include "StructuredCloneUtils.h"
#include "ColorPickerParent.h"
@@ -1459,39 +1458,16 @@ TabParent::RecvReplyKeyEvent(const Widge
NS_ENSURE_TRUE(presShell, true);
nsPresContext* presContext = presShell->GetPresContext();
NS_ENSURE_TRUE(presContext, true);
EventDispatcher::Dispatch(mFrameElement, presContext, &localEvent);
return true;
}
-bool
-TabParent::RecvDispatchAfterKeyboardEvent(const WidgetKeyboardEvent& aEvent)
-{
- NS_ENSURE_TRUE(mFrameElement, true);
-
- WidgetKeyboardEvent localEvent(aEvent);
- localEvent.widget = GetWidget();
-
- nsIDocument* doc = mFrameElement->OwnerDoc();
- nsCOMPtr<nsIPresShell> presShell = doc->GetShell();
- NS_ENSURE_TRUE(presShell, true);
-
- if (mFrameElement &&
- PresShell::BeforeAfterKeyboardEventEnabled() &&
- localEvent.message != NS_KEY_PRESS) {
- nsCOMPtr<nsINode> node(do_QueryInterface(mFrameElement));
- presShell->DispatchAfterKeyboardEvent(mFrameElement, localEvent,
- aEvent.mFlags.mDefaultPrevented);
- }
-
- return true;
-}
-
/**
* Try to answer query event using cached text.
*
* For NS_QUERY_SELECTED_TEXT, fail if the cache doesn't contain the whole
* selected range. (This shouldn't happen because PuppetWidget should have
* already sent the whole selection.)
*
* For NS_QUERY_TEXT_CONTENT, fail only if the cache doesn't overlap with
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -117,17 +117,16 @@ public:
*/
bool TryCapture(const WidgetGUIEvent& aEvent);
void Destroy();
virtual bool RecvMoveFocus(const bool& aForward) MOZ_OVERRIDE;
virtual bool RecvEvent(const RemoteDOMEvent& aEvent) MOZ_OVERRIDE;
virtual bool RecvReplyKeyEvent(const WidgetKeyboardEvent& event);
- virtual bool RecvDispatchAfterKeyboardEvent(const WidgetKeyboardEvent& event);
virtual bool RecvPRenderFrameConstructor(PRenderFrameParent* aActor,
ScrollingBehavior* aScrolling,
TextureFactoryIdentifier* aFactoryIdentifier,
uint64_t* aLayersId,
bool* aSuccess) MOZ_OVERRIDE;
virtual bool RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
const nsString& aURL,
const nsString& aName,
--- a/dom/ipc/tests/mochitest.ini
+++ b/dom/ipc/tests/mochitest.ini
@@ -1,8 +1,14 @@
+[test_blob_sliced_from_child_process.html]
+# This test is only supposed to run in the main process.
+skip-if = buildapp == 'b2g' || buildapp == 'mulet' || e10s
+[test_blob_sliced_from_parent_process.html]
+# This test is only supposed to run in the main process.
+skip-if = buildapp == 'b2g' || buildapp == 'mulet' || e10s
[test_NuwaProcessCreation.html]
run-if = toolkit == 'gonk'
[test_NuwaProcessDeadlock.html]
run-if = toolkit == 'gonk'
[test_child_docshell.html]
run-if = toolkit != 'cocoa' # disabled due to hangs, see changeset 6852e7c47edf
[test_CrashService_crash.html]
run-if = crashreporter && !e10s && (toolkit == 'gtk2' || toolkit == 'gtk3' || toolkit == 'cocoa' || toolkit == 'windows') && (buildapp != 'b2g' || toolkit == 'gonk')
new file mode 100644
--- /dev/null
+++ b/dom/ipc/tests/test_blob_sliced_from_child_process.html
@@ -0,0 +1,184 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Test for slicing blobs that originated in a child process</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ </head>
+ <body onload="setup();">
+ <script type="application/javascript;version=1.7">
+"use strict";
+
+function childFrameScript() {
+ "use strict";
+
+ Components.utils.importGlobalProperties(["Blob"]);
+
+ const messageName = "test:blob-slice-test";
+ const blobData = ["So", " ", "many", " ", "blobs!"];
+ const blobText = blobData.join("");
+ const blobType = "text/plain";
+
+ let blob = new Blob(blobData, { type: blobType });
+
+ let sliceText = blobData[2][1] + blobData[2][2];
+ let sliceIndex = blobText.indexOf(sliceText);
+
+ let firstSliceStart = blobData[0].length + blobData[1].length;
+ let firstSliceEnd = firstSliceStart + blobData[2].length;
+
+ let slice = blob.slice(firstSliceStart, firstSliceEnd, blobType);
+
+ let secondSliceStart = blobData[2].indexOf("a");
+ let secondSliceEnd = secondSliceStart + 2;
+
+ slice = slice.slice(secondSliceStart, secondSliceEnd, blobType);
+
+ sendAsyncMessage(messageName, { blob: blob });
+ sendAsyncMessage(messageName, { slice: slice });
+}
+
+function parentFrameScript(mm) {
+ const messageName = "test:blob-slice-test";
+ const blobData = ["So", " ", "many", " ", "blobs!"];
+ const blobText = blobData.join("");
+ const blobType = "text/plain";
+
+ const sliceText = "an";
+
+ let receivedBlob = false;
+ let receivedSlice = false;
+
+ let finishedTestingBlob = false;
+ let finishedTestingSlice = false;
+
+ mm.addMessageListener(messageName, function(message) {
+ if ("blob" in message.data) {
+ is(receivedBlob, false, "Have not yet received Blob");
+ is(receivedSlice, false, "Have not yet received Slice");
+ is(finishedTestingBlob, false, "Have not yet finished testing Blob");
+ is(finishedTestingSlice, false, "Have not yet finished testing Slice");
+
+ receivedBlob = true;
+
+ let blob = message.data.blob;
+
+ ok(blob instanceof Blob, "Received a Blob");
+ is(blob.size, blobText.length, "Blob has correct size");
+ is(blob.type, blobType, "Blob has correct type");
+
+ let slice = blob.slice(blobText.length -
+ blobData[blobData.length - 1].length,
+ blob.size,
+ blobType);
+
+ ok(slice instanceof Blob, "Slice returned a Blob");
+ is(slice.size,
+ blobData[blobData.length - 1].length,
+ "Slice has correct size");
+ is(slice.type, blobType, "Slice has correct type");
+
+ let reader = new FileReader();
+ reader.onload = function() {
+ is(reader.result,
+ blobData[blobData.length - 1],
+ "Slice has correct data");
+
+ finishedTestingBlob = true;
+
+ if (finishedTestingSlice) {
+ SimpleTest.finish();
+ }
+ };
+ reader.readAsText(slice);
+
+ return;
+ }
+
+ if ("slice" in message.data) {
+ is(receivedBlob, true, "Already received Blob");
+ is(receivedSlice, false, "Have not yet received Slice");
+ is(finishedTestingSlice, false, "Have not yet finished testing Slice");
+
+ receivedSlice = true;
+
+ let slice = message.data.slice;
+
+ ok(slice instanceof Blob, "Received a Blob for slice");
+ is(slice.size, sliceText.length, "Slice has correct size");
+ is(slice.type, blobType, "Slice has correct type");
+
+ let reader = new FileReader();
+ reader.onload = function() {
+ is(reader.result, sliceText, "Slice has correct data");
+
+ let slice2 = slice.slice(1, 2, blobType);
+
+ ok(slice2 instanceof Blob, "Slice returned a Blob");
+ is(slice2.size, 1, "Slice has correct size");
+ is(slice2.type, blobType, "Slice has correct type");
+
+ let reader2 = new FileReader();
+ reader2.onload = function() {
+ is(reader2.result, sliceText[1], "Slice has correct data");
+
+ finishedTestingSlice = true;
+
+ if (finishedTestingBlob) {
+ SimpleTest.finish();
+ }
+ };
+ reader2.readAsText(slice2);
+ };
+ reader.readAsText(slice);
+
+ return;
+ }
+
+ ok(false, "Received a bad message: " + JSON.stringify(message.data));
+ });
+
+ mm.loadFrameScript("data:,(" + childFrameScript.toString() + ")();",
+ false);
+}
+
+function setup() {
+ info("Got load event");
+
+ SpecialPowers.pushPrefEnv(
+ { set: [ ["dom.ipc.browser_frames.oop_by_default", true],
+ ["dom.mozBrowserFramesEnabled", true],
+ ["browser.pagethumbnails.capturing_disabled", true] ] },
+ function() {
+ info("Prefs set");
+
+ SpecialPowers.pushPermissions(
+ [ { type: "browser", allow: true, context: document } ],
+ function() {
+ info("Permissions set");
+
+ let iframe = document.createElement("iframe");
+ SpecialPowers.wrap(iframe).mozbrowser = true;
+ iframe.id = "iframe";
+ iframe.src =
+ "data:text/html,<!DOCTYPE HTML><html><body></body></html>";
+
+ iframe.addEventListener("mozbrowserloadend", function() {
+ info("Starting tests");
+
+ let mm = SpecialPowers.getBrowserFrameMessageManager(iframe)
+ parentFrameScript(mm);
+ });
+
+ document.body.appendChild(iframe);
+ }
+ );
+ }
+ );
+}
+
+SimpleTest.waitForExplicitFinish();
+ </script>
+ </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/ipc/tests/test_blob_sliced_from_parent_process.html
@@ -0,0 +1,217 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Test for slicing blobs that originated in a parent process</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js">
+ </script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ </head>
+ <body onload="setup();">
+ <script type="application/javascript;version=1.7">
+"use strict";
+
+function childFrameScript() {
+ "use strict";
+
+ const { classes: Cc, interfaces: Ci } = Components;
+
+ const messageName = "test:blob-slice-test";
+ const blobData = ["So", " ", "many", " ", "blobs!"];
+ const blobText = blobData.join("");
+ const blobType = "text/plain";
+
+ const sliceText = "an";
+
+ function info(msg) {
+ sendAsyncMessage(messageName, { op: "info", msg: msg });
+ }
+
+ function ok(condition, name, diag) {
+ sendAsyncMessage(messageName,
+ { op: "ok",
+ condition: condition,
+ name: name,
+ diag: diag });
+ }
+
+ function is(a, b, name) {
+ let pass = a == b;
+ let diag = pass ? "" : "got " + a + ", expected " + b;
+ ok(pass, name, diag);
+ }
+
+ function finish(result) {
+ sendAsyncMessage(messageName, { op: "done", result: result });
+ }
+
+ function createFileReader() {
+ return Cc["@mozilla.org/files/filereader;1"]
+ .createInstance(Ci.nsIDOMFileReader);
+ }
+
+ function grabAndContinue(arg) {
+ testGenerator.send(arg);
+ }
+
+ function testSteps() {
+ addMessageListener(messageName, grabAndContinue);
+ let message = yield undefined;
+
+ let blob = message.data;
+
+ ok(blob instanceof Ci.nsIDOMBlob, "Received a Blob");
+ is(blob.size, blobText.length, "Blob has correct length");
+ is(blob.type, blobType, "Blob has correct type");
+
+ info("Reading blob");
+
+ let reader = createFileReader();
+ reader.addEventListener("load", grabAndContinue);
+ reader.readAsText(blob);
+
+ yield undefined;
+
+ is(reader.result, blobText, "Blob has correct data");
+
+ let firstSliceStart = blobData[0].length + blobData[1].length;
+ let firstSliceEnd = firstSliceStart + blobData[2].length;
+
+ let slice = blob.slice(firstSliceStart, firstSliceEnd, blobType);
+
+ ok(slice instanceof Ci.nsIDOMBlob, "Slice returned a Blob");
+ is(slice.size, blobData[2].length, "Slice has correct length");
+ is(slice.type, blobType, "Slice has correct type");
+
+ info("Reading slice");
+
+ reader = createFileReader();
+ reader.addEventListener("load", grabAndContinue);
+ reader.readAsText(slice);
+
+ yield undefined;
+
+ is(reader.result, blobData[2], "Slice has correct data");
+
+ let secondSliceStart = blobData[2].indexOf("a");
+ let secondSliceEnd = secondSliceStart + sliceText.length;
+
+ slice = slice.slice(secondSliceStart, secondSliceEnd, blobType);
+
+ ok(slice instanceof Ci.nsIDOMBlob, "Second slice returned a Blob");
+ is(slice.size, sliceText.length, "Second slice has correct length");
+ is(slice.type, blobType, "Second slice has correct type");
+
+ info("Sending second slice");
+ finish(slice);
+
+ yield undefined;
+ }
+
+ let testGenerator = testSteps();
+ testGenerator.next();
+}
+
+function parentFrameScript(mm) {
+ const messageName = "test:blob-slice-test";
+ const blobData = ["So", " ", "many", " ", "blobs!"];
+ const blobText = blobData.join("");
+ const blobType = "text/plain";
+
+ const sliceText = "an";
+
+ function grabAndContinue(arg) {
+ testGenerator.send(arg);
+ }
+
+ function testSteps() {
+ let slice = yield undefined;
+
+ ok(slice instanceof Blob, "Received a Blob");
+ is(slice.size, sliceText.length, "Slice has correct size");
+ is(slice.type, blobType, "Slice has correct type");
+
+ let reader = new FileReader();
+ reader.onload = grabAndContinue;
+ reader.readAsText(slice);
+ yield undefined;
+
+ is(reader.result, sliceText, "Slice has correct data");
+ SimpleTest.finish();
+
+ yield undefined;
+ }
+
+ let testGenerator = testSteps();
+ testGenerator.next();
+
+ mm.addMessageListener(messageName, function(message) {
+ let data = message.data;
+ switch (data.op) {
+ case "info": {
+ info(data.msg);
+ break;
+ }
+
+ case "ok": {
+ ok(data.condition, data.name, data.diag);
+ break;
+ }
+
+ case "done": {
+ testGenerator.send(data.result);
+ break;
+ }
+
+ default: {
+ ok(false, "Unknown op: " + data.op);
+ SimpleTest.finish();
+ }
+ }
+ });
+
+ mm.loadFrameScript("data:,(" + childFrameScript.toString() + ")();",
+ false);
+
+ let blob = new Blob(blobData, { type: blobType });
+ mm.sendAsyncMessage(messageName, blob);
+}
+
+function setup() {
+ info("Got load event");
+
+ SpecialPowers.pushPrefEnv(
+ { set: [ ["dom.ipc.browser_frames.oop_by_default", true],
+ ["dom.mozBrowserFramesEnabled", true],
+ ["browser.pagethumbnails.capturing_disabled", true] ] },
+ function() {
+ info("Prefs set");
+
+ SpecialPowers.pushPermissions(
+ [ { type: "browser", allow: true, context: document } ],
+ function() {
+ info("Permissions set");
+
+ let iframe = document.createElement("iframe");
+ SpecialPowers.wrap(iframe).mozbrowser = true;
+ iframe.id = "iframe";
+ iframe.src =
+ "data:text/html,<!DOCTYPE HTML><html><body></body></html>";
+
+ iframe.addEventListener("mozbrowserloadend", function() {
+ info("Starting tests");
+
+ let mm = SpecialPowers.getBrowserFrameMessageManager(iframe)
+ parentFrameScript(mm);
+ });
+
+ document.body.appendChild(iframe);
+ }
+ );
+ }
+ );
+}
+
+SimpleTest.waitForExplicitFinish();
+ </script>
+ </body>
+</html>
--- a/dom/mobileconnection/gonk/MobileConnectionService.js
+++ b/dom/mobileconnection/gonk/MobileConnectionService.js
@@ -22,18 +22,18 @@ const GONK_MOBILECONNECTIONSERVICE_CID =
const MOBILECONNECTIONINFO_CID =
Components.ID("{8162b3c0-664b-45f6-96cd-f07b4e193b0e}");
const MOBILENETWORKINFO_CID =
Components.ID("{a6c8416c-09b4-46d1-bf29-6520d677d085}");
const MOBILECELLINFO_CID =
Components.ID("{0635d9ab-997e-4cdf-84e7-c1883752dff3}");
const MOBILECALLFORWARDINGOPTIONS_CID =
Components.ID("{e0cf4463-ee63-4b05-ab2e-d94bf764836c}");
-const TELEPHONYCALLBACK_CID =
- Components.ID("{6e1af17e-37f3-11e4-aed3-60a44c237d2b}");
+const TELEPHONYDIALCALLBACK_CID =
+ Components.ID("{c2af1a5d-3649-44ef-a1ff-18e9ac1dec51}");
const NS_XPCOM_SHUTDOWN_OBSERVER_ID = "xpcom-shutdown";
const NS_PREFBRANCH_PREFCHANGE_TOPIC_ID = "nsPref:changed";
const NS_NETWORK_ACTIVE_CHANGED_TOPIC_ID = "network-active-changed";
const kPrefRilDebuggingEnabled = "ril.debugging.enabled";
XPCOMUtils.defineLazyServiceGetter(this, "gSystemMessenger",
@@ -134,24 +134,24 @@ MobileCallForwardingOptions.prototype =
action: Ci.nsIMobileConnection.CALL_FORWARD_ACTION_UNKNOWN,
reason: Ci.nsIMobileConnection.CALL_FORWARD_REASON_UNKNOWN,
number: null,
timeSeconds: -1,
serviceClass: Ci.nsIMobileConnection.ICC_SERVICE_CLASS_NONE
}
/**
- * Wrap a MobileConnectionCallback to a TelephonyCallback.
+ * Wrap a MobileConnectionCallback to a TelephonyDialCallback.
*/
-function TelephonyCallback(aCallback) {
+function TelephonyDialCallback(aCallback) {
this.callback = aCallback;
}
-TelephonyCallback.prototype = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsITelephonyCallback]),
- classID: TELEPHONYCALLBACK_CID,
+TelephonyDialCallback.prototype = {
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsITelephonyDialCallback]),
+ classID: TELEPHONYDIALCALLBACK_CID,
_notifySendCancelMmiSuccess: function(aResult) {
// No additional information.
if (aResult.additionalInformation === undefined) {
this.callback.notifySendCancelMmiSuccess(aResult.serviceCode,
aResult.statusMessage);
return;
}
@@ -687,18 +687,18 @@ MobileConnectionProvider.prototype = {
}
aCallback.notifySuccessWithBoolean(aResponse.enabled);
return false;
}).bind(this));
},
sendMMI: function(aMmi, aCallback) {
- let telephonyCallback = new TelephonyCallback(aCallback);
- gGonkTelephonyService.dialMMI(this._clientId, aMmi, telephonyCallback);
+ let callback = new TelephonyDialCallback(aCallback);
+ gGonkTelephonyService.dialMMI(this._clientId, aMmi, callback);
},
cancelMMI: function(aCallback) {
this._radioInterface.sendWorkerMessage("cancelUSSD", null,
(function(aResponse) {
if (aResponse.errorMsg) {
aCallback.notifyError(aResponse.errorMsg);
return false;
@@ -995,24 +995,16 @@ MobileConnectionService.prototype = {
notifyUssdReceived: function(aClientId, aMessage, aSessionEnded) {
if (DEBUG) {
debug("notifyUssdReceived for " + aClientId + ": " +
aMessage + " (sessionEnded : " + aSessionEnded + ")");
}
this.getItemByServiceId(aClientId)
.deliverListenerEvent("notifyUssdReceived", [aMessage, aSessionEnded]);
-
- let info = {
- message: aMessage,
- sessionEnded: aSessionEnded,
- serviceId: aClientId
- };
-
- gSystemMessenger.broadcastMessage("ussd-received", info);
},
notifyDataError: function(aClientId, aMessage) {
if (DEBUG) {
debug("notifyDataError for " + aClientId + ": " + aMessage);
}
this.getItemByServiceId(aClientId)
--- a/dom/nfc/gonk/Nfc.js
+++ b/dom/nfc/gonk/Nfc.js
@@ -625,16 +625,17 @@ Nfc.prototype = {
case "NFC:PowerOff":
this.setConfig({powerLevel: NFC.NFC_POWER_LEVEL_DISABLED,
requestId: message.data.requestId});
break;
case "NFC:ReadNDEF":
this.sendToNfcService("readNDEF", message.data);
break;
case "NFC:WriteNDEF":
+ message.data.isP2P = SessionHelper.isP2PSession(message.data.sessionId);
this.sendToNfcService("writeNDEF", message.data);
break;
case "NFC:MakeReadOnlyNDEF":
this.sendToNfcService("makeReadOnlyNDEF", message.data);
break;
case "NFC:Connect":
this.sendToNfcService("connect", message.data);
break;
--- a/dom/nfc/gonk/NfcGonkMessage.h
+++ b/dom/nfc/gonk/NfcGonkMessage.h
@@ -3,17 +3,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef NfcGonkMessage_h
#define NfcGonkMessage_h
namespace mozilla {
#define NFCD_MAJOR_VERSION 1
-#define NFCD_MINOR_VERSION 10
+#define NFCD_MINOR_VERSION 12
enum NfcRequest {
ConfigReq = 0,
ConnectReq,
CloseReq,
ReadNDEFReq,
WriteNDEFReq,
MakeReadOnlyNDEFReq,
--- a/dom/nfc/gonk/NfcMessageHandler.cpp
+++ b/dom/nfc/gonk/NfcMessageHandler.cpp
@@ -191,16 +191,17 @@ NfcMessageHandler::ReadNDEFResponse(cons
return true;
}
bool
NfcMessageHandler::WriteNDEFRequest(Parcel& aParcel, const CommandOptions& aOptions)
{
aParcel.writeInt32(NfcRequest::WriteNDEFReq);
aParcel.writeInt32(aOptions.mSessionId);
+ aParcel.writeInt32(aOptions.mIsP2P);
WriteNDEFMessage(aParcel, aOptions);
mRequestIdQueue.AppendElement(aOptions.mRequestId);
return true;
}
bool
NfcMessageHandler::MakeReadOnlyNDEFRequest(Parcel& aParcel, const CommandOptions& aOptions)
{
--- a/dom/nfc/gonk/NfcOptions.h
+++ b/dom/nfc/gonk/NfcOptions.h
@@ -31,16 +31,17 @@ struct CommandOptions
prop = defaultValue; \
}
COPY_FIELD(mType)
COPY_FIELD(mRequestId)
COPY_OPT_FIELD(mSessionId, 0)
COPY_OPT_FIELD(mPowerLevel, 0)
COPY_OPT_FIELD(mTechType, 0)
+ COPY_OPT_FIELD(mIsP2P, false)
if (!aOther.mRecords.WasPassed()) {
return;
}
mozilla::dom::Sequence<mozilla::dom::MozNDEFRecordOptions> const & currentValue = aOther.mRecords.InternalValue();
int count = currentValue.Length();
for (int32_t i = 0; i < count; i++) {
@@ -72,16 +73,17 @@ struct CommandOptions
#undef COPY_OPT_FIELD
}
nsString mType;
int32_t mSessionId;
nsString mRequestId;
int32_t mPowerLevel;
int32_t mTechType;
+ bool mIsP2P;
nsTArray<NDEFRecordStruct> mRecords;
};
struct EventOptions
{
EventOptions()
: mType(EmptyString()), mStatus(-1), mSessionId(-1), mRequestId(EmptyString()), mMajorVersion(-1), mMinorVersion(-1),
mIsReadOnly(-1), mCanBeMadeReadOnly(-1), mMaxSupportedLength(-1), mPowerLevel(-1),
--- a/dom/nfc/nsNfc.js
+++ b/dom/nfc/nsNfc.js
@@ -26,42 +26,26 @@ XPCOMUtils.defineLazyServiceGetter(this,
/**
* NFCTag
*/
function MozNFCTag() {
debug("In MozNFCTag Constructor");
this._nfcContentHelper = Cc["@mozilla.org/nfc/content-helper;1"]
.getService(Ci.nsINfcContentHelper);
this.session = null;
-
- // Map WebIDL declared enum map names to integer
- this._techTypesMap = [];
- this._techTypesMap['NFC_A'] = 0;
- this._techTypesMap['NFC_B'] = 1;
- this._techTypesMap['NFC_ISO_DEP'] = 2;
- this._techTypesMap['NFC_F'] = 3;
- this._techTypesMap['NFC_V'] = 4;
- this._techTypesMap['NDEF'] = 5;
- this._techTypesMap['NDEF_FORMATABLE'] = 6;
- this._techTypesMap['MIFARE_CLASSIC'] = 7;
- this._techTypesMap['MIFARE_ULTRALIGHT'] = 8;
- this._techTypesMap['NFC_BARCODE'] = 9;
- this._techTypesMap['P2P'] = 10;
}
MozNFCTag.prototype = {
_nfcContentHelper: null,
_window: null,
initialize: function(aWindow, aSessionToken) {
this._window = aWindow;
this.session = aSessionToken;
},
- _techTypesMap: null,
-
// NFCTag interface:
readNDEF: function readNDEF() {
return this._nfcContentHelper.readNDEF(this._window, this.session);
},
writeNDEF: function writeNDEF(records) {
return this._nfcContentHelper.writeNDEF(this._window, records, this.session);
},
makeReadOnlyNDEF: function makeReadOnlyNDEF() {
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -1980,23 +1980,28 @@ RadioInterface.prototype = {
break;
case "callDisconnected":
gTelephonyService.notifyCallDisconnected(this.clientId, message.call);
break;
case "conferenceCallStateChanged":
gTelephonyService.notifyConferenceCallStateChanged(message.state);
break;
case "cdmaCallWaiting":
- gTelephonyService.notifyCdmaCallWaiting(this.clientId, message.waitingCall);
+ gTelephonyService.notifyCdmaCallWaiting(this.clientId,
+ message.waitingCall);
break;
case "suppSvcNotification":
gTelephonyService.notifySupplementaryService(this.clientId,
message.callIndex,
message.notification);
break;
+ case "ussdreceived":
+ gTelephonyService.notifyUssdReceived(this.clientId, message.message,
+ message.sessionEnded);
+ break;
case "datacallerror":
connHandler.handleDataCallError(message);
break;
case "datacallstatechange":
let addresses = [];
for (let i = 0; i < message.addresses.length; i++) {
let [address, prefixLength] = message.addresses[i].split("/");
// From AOSP hardware/ril/include/telephony/ril.h, that address prefix
@@ -2040,21 +2045,16 @@ RadioInterface.prototype = {
gMobileConnectionService.notifyOtaStatusChanged(this.clientId, message.status);
break;
case "radiostatechange":
// gRadioEnabledController should know the radio state for each client,
// so notify gRadioEnabledController here.
gRadioEnabledController.notifyRadioStateChanged(this.clientId,
message.radioState);
break;
- case "ussdreceived":
- gMobileConnectionService.notifyUssdReceived(this.clientId,
- message.message,
- message.sessionEnded);
- break;
case "cardstatechange":
this.rilContext.cardState = message.cardState;
gRadioEnabledController.receiveCardState(this.clientId);
gMessageManager.sendIccMessage("RIL:CardStateChanged",
this.clientId, message);
break;
case "sms-received":
this.handleSmsMultipart(message);
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -2636,32 +2636,58 @@ RilObject.prototype = {
}
// If the MMI code is not a known code, it is treated as an ussd.
if (!_isRadioAvailable()) {
return;
}
options.ussd = mmi.fullMMI;
+
+ if (options.startNewSession && this._ussdSession) {
+ if (DEBUG) this.context.debug("Cancel existing ussd session.");
+ this.cachedUSSDRequest = options;
+ this.cancelUSSD({});
+ return;
+ }
+
this.sendUSSD(options);
},
/**
+ * Cache the request for send out a new ussd when there is an existing
+ * session. We should do cancelUSSD first.
+ */
+ cachedUSSDRequest : null,
+
+ /**
* Send USSD.
*
* @param ussd
* String containing the USSD code.
- *
- */
- sendUSSD: function(options) {
- let Buf = this.context.Buf;
- Buf.newParcel(REQUEST_SEND_USSD, options);
- Buf.writeString(options.ussd);
- Buf.sendParcel();
- },
+ * @param checkSession
+ * True if an existing session should be there.
+ */
+ sendUSSD: function(options) {
+ if (options.checkSession && !this._ussdSession) {
+ options.success = false;
+ options.errorMsg = GECKO_ERROR_GENERIC_FAILURE;
+ this.sendChromeMessage(options);
+ return;
+ }
+
+ this.sendRilRequestSendUSSD(options);
+ },
+
+ sendRilRequestSendUSSD: function(options) {
+ let Buf = this.context.Buf;
+ Buf.newParcel(REQUEST_SEND_USSD, options);
+ Buf.writeString(options.ussd);
+ Buf.sendParcel();
+ },
/**
* Cancel pending USSD.
*/
cancelUSSD: function(options) {
this.context.Buf.simpleRequest(REQUEST_CANCEL_USSD, options);
},
@@ -5674,19 +5700,29 @@ RilObject.prototype[REQUEST_SEND_USSD] =
options.success = (this._ussdSession = options.rilRequestError === 0);
options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
this.sendChromeMessage(options);
};
RilObject.prototype[REQUEST_CANCEL_USSD] = function REQUEST_CANCEL_USSD(length, options) {
if (DEBUG) {
this.context.debug("REQUEST_CANCEL_USSD" + JSON.stringify(options));
}
+
options.success = (options.rilRequestError === 0);
this._ussdSession = !options.success;
options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
+
+ // The cancelUSSD is triggered by ril_worker itself.
+ if (this.cachedUSSDRequest) {
+ if (DEBUG) this.context.debug("Send out the cached ussd request");
+ this.sendUSSD(this.cachedUSSDRequest);
+ this.cachedUSSDRequest = null;
+ return;
+ }
+
this.sendChromeMessage(options);
};
RilObject.prototype[REQUEST_GET_CLIR] = function REQUEST_GET_CLIR(length, options) {
options.success = (options.rilRequestError === 0);
if (!options.success) {
options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
this.sendChromeMessage(options);
return;
--- a/dom/telephony/Telephony.cpp
+++ b/dom/telephony/Telephony.cpp
@@ -21,17 +21,17 @@
#include "nsPIDOMWindow.h"
#include "nsServiceManagerUtils.h"
#include "nsThreadUtils.h"
#include "CallsList.h"
#include "TelephonyCall.h"
#include "TelephonyCallGroup.h"
#include "TelephonyCallId.h"
-#include "TelephonyCallback.h"
+#include "TelephonyDialCallback.h"
// Service instantiation
#include "ipc/TelephonyIPCService.h"
#if defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
#include "nsIGonkTelephonyService.h"
#endif
#include "nsXULAppAPI.h" // For XRE_GetProcessType()
@@ -230,18 +230,18 @@ Telephony::DialInternal(uint32_t aServic
}
// We only support one outgoing call at a time.
if (HasDialingCall()) {
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
return promise.forget();
}
- nsCOMPtr<nsITelephonyCallback> callback =
- new TelephonyCallback(GetOwner(), this, promise, aServiceId);
+ nsCOMPtr<nsITelephonyDialCallback> callback =
+ new TelephonyDialCallback(GetOwner(), this, promise, aServiceId);
nsresult rv = mService->Dial(aServiceId, aNumber, aEmergency, callback);
if (NS_FAILED(rv)) {
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
return promise.forget();
}
return promise.forget();
--- a/dom/telephony/Telephony.h
+++ b/dom/telephony/Telephony.h
@@ -18,17 +18,17 @@
#include "TelephonyCall.h"
class nsPIDOMWindow;
namespace mozilla {
namespace dom {
namespace telephony {
-class TelephonyCallback;
+class TelephonyDialCallback;
} // namespace telephony
class OwningTelephonyCallOrTelephonyCallGroup;
class Telephony MOZ_FINAL : public DOMEventTargetHelper,
private nsITelephonyListener
{
@@ -38,17 +38,17 @@ class Telephony MOZ_FINAL : public DOMEv
* and passes it to nsITelephonyService. The onreceived events are first
* delivered to mListener and then forwarded to its owner, Telephony. See
* also bug 775997 comment #51.
*/
class Listener;
class EnumerationAck;
friend class EnumerationAck;
- friend class telephony::TelephonyCallback;
+ friend class telephony::TelephonyDialCallback;
nsCOMPtr<nsITelephonyService> mService;
nsRefPtr<Listener> mListener;
nsTArray<nsRefPtr<TelephonyCall> > mCalls;
nsRefPtr<CallsList> mCallsList;
nsRefPtr<TelephonyCallGroup> mGroup;
--- a/dom/telephony/TelephonyCallback.cpp
+++ b/dom/telephony/TelephonyCallback.cpp
@@ -1,139 +1,34 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "TelephonyCallback.h"
-#include "mozilla/dom/DOMMMIError.h"
-#include "nsServiceManagerUtils.h"
+#include "mozilla/dom/Promise.h"
+#include "nsJSUtils.h"
using namespace mozilla::dom;
using namespace mozilla::dom::telephony;
NS_IMPL_ISUPPORTS(TelephonyCallback, nsITelephonyCallback)
-TelephonyCallback::TelephonyCallback(nsPIDOMWindow* aWindow,
- Telephony* aTelephony,
- Promise* aPromise,
- uint32_t aServiceId)
- : mWindow(aWindow), mTelephony(aTelephony), mPromise(aPromise),
- mServiceId(aServiceId)
-{
- MOZ_ASSERT(mTelephony);
-}
-
-nsresult
-TelephonyCallback::NotifyDialMMISuccess(const nsAString& aStatusMessage)
+TelephonyCallback::TelephonyCallback(Promise* aPromise)
+ : mPromise(aPromise)
{
- AutoJSAPI jsapi;
- if (!NS_WARN_IF(jsapi.Init(mWindow))) {
- return NS_ERROR_FAILURE;
- }
-
- JSContext* cx = jsapi.cx();
-
- MozMMIResult result;
-
- result.mServiceCode.Assign(mServiceCode);
- result.mStatusMessage.Assign(aStatusMessage);
-
- return NotifyDialMMISuccess(cx, result);
-}
-
-nsresult
-TelephonyCallback::NotifyDialMMISuccess(JSContext* aCx,
- const nsAString& aStatusMessage,
- JS::Handle<JS::Value> aInfo)
-{
- RootedDictionary<MozMMIResult> result(aCx);
-
- result.mServiceCode.Assign(mServiceCode);
- result.mStatusMessage.Assign(aStatusMessage);
- result.mAdditionalInformation.Construct().SetAsObject() = &aInfo.toObject();
-
- return NotifyDialMMISuccess(aCx, result);
-}
-
-nsresult
-TelephonyCallback::NotifyDialMMISuccess(JSContext* aCx,
- const MozMMIResult& aResult)
-{
- JS::Rooted<JS::Value> jsResult(aCx);
-
- if (!ToJSValue(aCx, aResult, &jsResult)) {
- JS_ClearPendingException(aCx);
- return NS_ERROR_TYPE_ERR;
- }
-
- return NotifyDialMMISuccess(jsResult);
}
// nsITelephonyCallback
NS_IMETHODIMP
-TelephonyCallback::NotifyDialMMI(const nsAString& aServiceCode)
-{
- mMMIRequest = new DOMRequest(mWindow);
- mServiceCode.Assign(aServiceCode);
-
- mPromise->MaybeResolve(mMMIRequest);
- return NS_OK;
-}
-
-NS_IMETHODIMP
-TelephonyCallback::NotifyDialError(const nsAString& aError)
+TelephonyCallback::NotifySuccess()
{
- mPromise->MaybeRejectBrokenly(aError);
- return NS_OK;
-}
-
-NS_IMETHODIMP
-TelephonyCallback::NotifyDialCallSuccess(uint32_t aCallIndex,
- const nsAString& aNumber)
-{
- nsRefPtr<TelephonyCallId> id = mTelephony->CreateCallId(aNumber);
- nsRefPtr<TelephonyCall> call =
- mTelephony->CreateCall(id, mServiceId, aCallIndex,
- nsITelephonyService::CALL_STATE_DIALING);
-
- mPromise->MaybeResolve(call);
+ mPromise->MaybeResolve(JS::UndefinedHandleValue);
return NS_OK;
}
NS_IMETHODIMP
-TelephonyCallback::NotifyDialMMISuccess(JS::Handle<JS::Value> aResult)
-{
- nsCOMPtr<nsIDOMRequestService> rs = do_GetService(DOMREQUEST_SERVICE_CONTRACTID);
- NS_ENSURE_TRUE(rs, NS_ERROR_FAILURE);
-
- return rs->FireSuccessAsync(mMMIRequest, aResult);
-}
-
-NS_IMETHODIMP
-TelephonyCallback::NotifyDialMMIError(const nsAString& aError)
+TelephonyCallback::NotifyError(const nsAString& aError)
{
- Nullable<int16_t> info;
-
- nsRefPtr<DOMError> error =
- new DOMMMIError(mWindow, aError, EmptyString(), mServiceCode, info);
-
- nsCOMPtr<nsIDOMRequestService> rs = do_GetService(DOMREQUEST_SERVICE_CONTRACTID);
- NS_ENSURE_TRUE(rs, NS_ERROR_FAILURE);
-
- return rs->FireDetailedError(mMMIRequest, error);
+ mPromise->MaybeRejectBrokenly(aError);
+ return NS_OK;
}
-
-NS_IMETHODIMP
-TelephonyCallback::NotifyDialMMIErrorWithInfo(const nsAString& aError,
- uint16_t aInfo)
-{
- Nullable<int16_t> info(aInfo);
-
- nsRefPtr<DOMError> error =
- new DOMMMIError(mWindow, aError, EmptyString(), mServiceCode, info);
-
- nsCOMPtr<nsIDOMRequestService> rs = do_GetService(DOMREQUEST_SERVICE_CONTRACTID);
- NS_ENSURE_TRUE(rs, NS_ERROR_FAILURE);
-
- return rs->FireDetailedError(mMMIRequest, error);
-}
--- a/dom/telephony/TelephonyCallback.h
+++ b/dom/telephony/TelephonyCallback.h
@@ -1,81 +1,38 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_TelephonyCallback_h
#define mozilla_dom_TelephonyCallback_h
-#include "Telephony.h"
-#include "mozilla/dom/DOMRequest.h"
-#include "mozilla/dom/MozMobileConnectionBinding.h"
-#include "mozilla/dom/Promise.h"
-#include "mozilla/dom/ToJSValue.h"
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#include "nsITelephonyService.h"
-#include "nsJSUtils.h"
-#include "nsString.h"
-
-class nsPIDOMWindow;
namespace mozilla {
namespace dom {
+
+class Promise;
+
namespace telephony {
-class TelephonyCallback MOZ_FINAL : public nsITelephonyCallback
+class TelephonyCallback : public nsITelephonyCallback
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSITELEPHONYCALLBACK
- TelephonyCallback(nsPIDOMWindow* aWindow, Telephony* aTelephony,
- Promise* aPromise, uint32_t aServiceId);
-
- nsresult
- NotifyDialMMISuccess(const nsAString& aStatusMessage);
-
- template<typename T>
- nsresult
- NotifyDialMMISuccess(const nsAString& aStatusMessage, const T& aInfo)
- {
- AutoJSAPI jsapi;
- if (!NS_WARN_IF(jsapi.Init(mWindow))) {
- return NS_ERROR_FAILURE;
- }
-
- JSContext* cx = jsapi.cx();
- JS::Rooted<JS::Value> info(cx);
+ TelephonyCallback(Promise* aPromise);
- if (!ToJSValue(cx, aInfo, &info)) {
- JS_ClearPendingException(cx);
- return NS_ERROR_TYPE_ERR;
- }
-
- return NotifyDialMMISuccess(cx, aStatusMessage, info);
- }
-
-private:
- ~TelephonyCallback() {}
+protected:
+ virtual ~TelephonyCallback() {}
- nsresult
- NotifyDialMMISuccess(JSContext* aCx, const nsAString& aStatusMessage,
- JS::Handle<JS::Value> aInfo);
-
- nsresult
- NotifyDialMMISuccess(JSContext* aCx, const MozMMIResult& aResult);
-
-
- nsCOMPtr<nsPIDOMWindow> mWindow;
- nsRefPtr<Telephony> mTelephony;
+protected:
nsRefPtr<Promise> mPromise;
- uint32_t mServiceId;
-
- nsRefPtr<DOMRequest> mMMIRequest;
- nsString mServiceCode;
};
} // namespace telephony
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_TelephonyCallback_h
new file mode 100644
--- /dev/null
+++ b/dom/telephony/TelephonyDialCallback.cpp
@@ -0,0 +1,133 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "TelephonyDialCallback.h"
+
+#include "mozilla/dom/DOMMMIError.h"
+#include "nsServiceManagerUtils.h"
+
+using namespace mozilla::dom;
+using namespace mozilla::dom::telephony;
+
+NS_IMPL_ISUPPORTS_INHERITED(TelephonyDialCallback, TelephonyCallback,
+ nsITelephonyDialCallback)
+
+TelephonyDialCallback::TelephonyDialCallback(nsPIDOMWindow* aWindow,
+ Telephony* aTelephony,
+ Promise* aPromise,
+ uint32_t aServiceId)
+ : TelephonyCallback(aPromise), mWindow(aWindow), mTelephony(aTelephony),
+ mServiceId(aServiceId)
+{
+ MOZ_ASSERT(mTelephony);
+}
+
+nsresult
+TelephonyDialCallback::NotifyDialMMISuccess(const nsAString& aStatusMessage)
+{
+ AutoJSAPI jsapi;
+ if (!NS_WARN_IF(jsapi.Init(mWindow))) {
+ return NS_ERROR_FAILURE;
+ }
+
+ JSContext* cx = jsapi.cx();
+
+ MozMMIResult result;
+
+ result.mServiceCode.Assign(mServiceCode);
+ result.mStatusMessage.Assign(aStatusMessage);
+
+ return NotifyDialMMISuccess(cx, result);
+}
+
+nsresult
+TelephonyDialCallback::NotifyDialMMISuccess(JSContext* aCx,
+ const nsAString& aStatusMessage,
+ JS::Handle<JS::Value> aInfo)
+{
+ RootedDictionary<MozMMIResult> result(aCx);
+
+ result.mServiceCode.Assign(mServiceCode);
+ result.mStatusMessage.Assign(aStatusMessage);
+ result.mAdditionalInformation.Construct().SetAsObject() = &aInfo.toObject();
+
+ return NotifyDialMMISuccess(aCx, result);
+}
+
+nsresult
+TelephonyDialCallback::NotifyDialMMISuccess(JSContext* aCx,
+ const MozMMIResult& aResult)
+{
+ JS::Rooted<JS::Value> jsResult(aCx);
+
+ if (!ToJSValue(aCx, aResult, &jsResult)) {
+ JS_ClearPendingException(aCx);
+ return NS_ERROR_TYPE_ERR;
+ }
+
+ return NotifyDialMMISuccess(jsResult);
+}
+
+// nsITelephonyDialCallback
+
+NS_IMETHODIMP
+TelephonyDialCallback::NotifyDialMMI(const nsAString& aServiceCode)
+{
+ mMMIRequest = new DOMRequest(mWindow);
+ mServiceCode.Assign(aServiceCode);
+
+ mPromise->MaybeResolve(mMMIRequest);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+TelephonyDialCallback::NotifyDialCallSuccess(uint32_t aCallIndex,
+ const nsAString& aNumber)
+{
+ nsRefPtr<TelephonyCallId> id = mTelephony->CreateCallId(aNumber);
+ nsRefPtr<TelephonyCall> call =
+ mTelephony->CreateCall(id, mServiceId, aCallIndex,
+ nsITelephonyService::CALL_STATE_DIALING);
+
+ mPromise->MaybeResolve(call);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+TelephonyDialCallback::NotifyDialMMISuccess(JS::Handle<JS::Value> aResult)
+{
+ nsCOMPtr<nsIDOMRequestService> rs = do_GetService(DOMREQUEST_SERVICE_CONTRACTID);
+ NS_ENSURE_TRUE(rs, NS_ERROR_FAILURE);
+
+ return rs->FireSuccessAsync(mMMIRequest, aResult);
+}
+
+NS_IMETHODIMP
+TelephonyDialCallback::NotifyDialMMIError(const nsAString& aError)
+{
+ Nullable<int16_t> info;
+
+ nsRefPtr<DOMError> error =
+ new DOMMMIError(mWindow, aError, EmptyString(), mServiceCode, info);
+
+ nsCOMPtr<nsIDOMRequestService> rs = do_GetService(DOMREQUEST_SERVICE_CONTRACTID);
+ NS_ENSURE_TRUE(rs, NS_ERROR_FAILURE);
+
+ return rs->FireDetailedError(mMMIRequest, error);
+}
+
+NS_IMETHODIMP
+TelephonyDialCallback::NotifyDialMMIErrorWithInfo(const nsAString& aError,
+ uint16_t aInfo)
+{
+ Nullable<int16_t> info(aInfo);
+
+ nsRefPtr<DOMError> error =
+ new DOMMMIError(mWindow, aError, EmptyString(), mServiceCode, info);
+
+ nsCOMPtr<nsIDOMRequestService> rs = do_GetService(DOMREQUEST_SERVICE_CONTRACTID);
+ NS_ENSURE_TRUE(rs, NS_ERROR_FAILURE);
+
+ return rs->FireDetailedError(mMMIRequest, error);
+}
new file mode 100644
--- /dev/null
+++ b/dom/telephony/TelephonyDialCallback.h
@@ -0,0 +1,84 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_TelephonyDialCallback_h
+#define mozilla_dom_TelephonyDialCallback_h
+
+#include "Telephony.h"
+#include "mozilla/dom/DOMRequest.h"
+#include "mozilla/dom/MozMobileConnectionBinding.h"
+#include "mozilla/dom/Promise.h"
+#include "mozilla/dom/ToJSValue.h"
+#include "mozilla/dom/telephony/TelephonyCallback.h"
+#include "nsAutoPtr.h"
+#include "nsCOMPtr.h"
+#include "nsITelephonyService.h"
+#include "nsJSUtils.h"
+#include "nsString.h"
+
+class nsPIDOMWindow;
+
+namespace mozilla {
+namespace dom {
+namespace telephony {
+
+class TelephonyDialCallback MOZ_FINAL : public TelephonyCallback,
+ public nsITelephonyDialCallback
+{
+public:
+ NS_DECL_ISUPPORTS_INHERITED
+ NS_DECL_NSITELEPHONYDIALCALLBACK
+
+ TelephonyDialCallback(nsPIDOMWindow* aWindow, Telephony* aTelephony,
+ Promise* aPromise, uint32_t aServiceId);
+
+ NS_FORWARD_NSITELEPHONYCALLBACK(TelephonyCallback::)
+
+ nsresult
+ NotifyDialMMISuccess(const nsAString& aStatusMessage);
+
+ template<typename T>
+ nsresult
+ NotifyDialMMISuccess(const nsAString& aStatusMessage, const T& aInfo)
+ {
+ AutoJSAPI jsapi;
+ if (!NS_WARN_IF(jsapi.Init(mWindow))) {
+ return NS_ERROR_FAILURE;
+ }
+
+ JSContext* cx = jsapi.cx();
+ JS::Rooted<JS::Value> info(cx);
+
+ if (!ToJSValue(cx, aInfo, &info)) {
+ JS_ClearPendingException(cx);
+ return NS_ERROR_TYPE_ERR;
+ }
+
+ return NotifyDialMMISuccess(cx, aStatusMessage, info);
+ }
+
+private:
+ ~TelephonyDialCallback() {}
+
+ nsresult
+ NotifyDialMMISuccess(JSContext* aCx, const nsAString& aStatusMessage,
+ JS::Handle<JS::Value> aInfo);
+
+ nsresult
+ NotifyDialMMISuccess(JSContext* aCx, const MozMMIResult& aResult);
+
+
+ nsCOMPtr<nsPIDOMWindow> mWindow;
+ nsRefPtr<Telephony> mTelephony;
+ uint32_t mServiceId;
+
+ nsRefPtr<DOMRequest> mMMIRequest;
+ nsString mServiceCode;
+};
+
+} // namespace telephony
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_TelephonyDialCallback_h
new file mode 100644
--- /dev/null
+++ b/dom/telephony/USSDSession.cpp
@@ -0,0 +1,97 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/dom/USSDSession.h"
+
+#include "mozilla/dom/USSDSessionBinding.h"
+#include "mozilla/dom/telephony/TelephonyCallback.h"
+#include "nsIGlobalObject.h"
+#include "nsServiceManagerUtils.h"
+
+using namespace mozilla::dom;
+using namespace mozilla::dom::telephony;
+using mozilla::ErrorResult;
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(USSDSession, mWindow)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(USSDSession)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(USSDSession)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(USSDSession)
+ NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+ NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+USSDSession::USSDSession(nsPIDOMWindow* aWindow, nsITelephonyService* aService,
+ uint32_t aServiceId)
+ : mWindow(aWindow), mService(aService), mServiceId(aServiceId)
+{
+}
+
+USSDSession::~USSDSession()
+{
+}
+
+nsPIDOMWindow*
+USSDSession::GetParentObject() const
+{
+ return mWindow;
+}
+
+JSObject*
+USSDSession::WrapObject(JSContext* aCx)
+{
+ return USSDSessionBinding::Wrap(aCx, this);
+}
+
+// WebIDL
+
+already_AddRefed<USSDSession>
+USSDSession::Constructor(const GlobalObject& aGlobal, uint32_t aServiceId,
+ ErrorResult& aRv)
+{
+ nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports());
+ if (!window) {
+ aRv.Throw(NS_ERROR_UNEXPECTED);
+ return nullptr;
+ }
+
+ nsCOMPtr<nsITelephonyService> ril =
+ do_GetService(TELEPHONY_SERVICE_CONTRACTID);
+ if (!ril) {
+ aRv.Throw(NS_ERROR_UNEXPECTED);
+ return nullptr;
+ }
+
+ nsRefPtr<USSDSession> session = new USSDSession(window, ril, aServiceId);
+ return session.forget();
+}
+
+already_AddRefed<Promise>
+USSDSession::Send(const nsAString& aUssd, ErrorResult& aRv)
+{
+ if (!mService) {
+ aRv.Throw(NS_ERROR_FAILURE);
+ return nullptr;
+ }
+
+ nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mWindow);
+ if (!global) {
+ return nullptr;
+ }
+
+ nsRefPtr<Promise> promise = Promise::Create(global, aRv);
+ if (aRv.Failed()) {
+ return nullptr;
+ }
+
+ nsCOMPtr<nsITelephonyCallback> callback = new TelephonyCallback(promise);
+
+ nsresult rv = mService->SendUSSD(mServiceId, aUssd, callback);
+ if (NS_FAILED(rv)) {
+ promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
+ }
+
+ return promise.forget();
+}
new file mode 100644
--- /dev/null
+++ b/dom/telephony/USSDSession.h
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_USSDSession_h
+#define mozilla_dom_USSDSession_h
+
+#include "mozilla/Attributes.h"
+#include "mozilla/ErrorResult.h"
+#include "mozilla/dom/BindingDeclarations.h"
+#include "mozilla/dom/Promise.h"
+#include "nsAutoPtr.h"
+#include "nsCOMPtr.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsITelephonyService.h"
+#include "nsPIDOMWindow.h"
+#include "nsWrapperCache.h"
+
+struct JSContext;
+
+namespace mozilla {
+namespace dom {
+
+class USSDSession MOZ_FINAL : public nsISupports,
+ public nsWrapperCache
+{
+public:
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(USSDSession)
+
+ USSDSession(nsPIDOMWindow* aWindow, nsITelephonyService* aService,
+ uint32_t aServiceId);
+
+ nsPIDOMWindow*
+ GetParentObject() const;
+
+ virtual JSObject*
+ WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+
+ // WebIDL
+ static already_AddRefed<USSDSession>
+ Constructor(const GlobalObject& aGlobal, uint32_t aServiceId,
+ ErrorResult& aRv);
+
+ already_AddRefed<Promise>
+ Send(const nsAString& aUssd, ErrorResult& aRv);
+
+private:
+ ~USSDSession();
+
+ nsCOMPtr<nsPIDOMWindow> mWindow;
+ nsCOMPtr<nsITelephonyService> mService;
+ uint32_t mServiceId;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_USSDSession_h
--- a/dom/telephony/gonk/TelephonyService.js
+++ b/dom/telephony/gonk/TelephonyService.js
@@ -559,75 +559,75 @@ TelephonyService.prototype = {
if (!aIsDialEmergency) {
aNumber = gPhoneNumberUtils.normalize(aNumber);
}
// Validate the number.
// Note: isPlainPhoneNumber also accepts USSD and SS numbers
if (!gPhoneNumberUtils.isPlainPhoneNumber(aNumber)) {
if (DEBUG) debug("Error: Number '" + aNumber + "' is not viable. Drop.");
- aCallback.notifyDialError(DIAL_ERROR_BAD_NUMBER);
+ aCallback.notifyError(DIAL_ERROR_BAD_NUMBER);
return;
}
let mmi = this._parseMMI(aNumber, this._hasCalls(aClientId));
if (!mmi) {
this._dialCall(aClientId,
{ number: aNumber,
isDialEmergency: aIsDialEmergency }, aCallback);
} else if (this._isTemporaryCLIR(mmi)) {
this._dialCall(aClientId,
{ number: mmi.dialNumber,
clirMode: this._getTemporaryCLIRMode(mmi.procedure),
isDialEmergency: aIsDialEmergency }, aCallback);
} else {
// Reject MMI code from dialEmergency api.
if (aIsDialEmergency) {
- aCallback.notifyDialError(DIAL_ERROR_BAD_NUMBER);
+ aCallback.notifyError(DIAL_ERROR_BAD_NUMBER);
return;
}
- this._dialMMI(aClientId, mmi, aCallback);
+ this._dialMMI(aClientId, mmi, aCallback, true);
}
},
/**
* @param aOptions.number
* @param aOptions.clirMode (optional)
* @param aOptions.isDialEmergency
*/
_dialCall: function(aClientId, aOptions, aCallback) {
if (this._isDialing) {
if (DEBUG) debug("Error: Already has a dialing call.");
- aCallback.notifyDialError(DIAL_ERROR_INVALID_STATE_ERROR);
+ aCallback.notifyError(DIAL_ERROR_INVALID_STATE_ERROR);
return;
}
// We can only have at most two calls on the same line (client).
if (this._numCallsOnLine(aClientId) >= 2) {
if (DEBUG) debug("Error: Already has more than 2 calls on line.");
- aCallback.notifyDialError(DIAL_ERROR_INVALID_STATE_ERROR);
+ aCallback.notifyError(DIAL_ERROR_INVALID_STATE_ERROR);
return;
}
// For DSDS, if there is aleady a call on SIM 'aClientId', we cannot place
// any new call on other SIM.
if (this._hasCallsOnOtherClient(aClientId)) {
if (DEBUG) debug("Error: Already has a call on other sim.");
- aCallback.notifyDialError(DIAL_ERROR_OTHER_CONNECTION_IN_USE);
+ aCallback.notifyError(DIAL_ERROR_OTHER_CONNECTION_IN_USE);
return;
}
aOptions.isEmergency = this._isEmergencyNumber(aOptions.number);
if (aOptions.isEmergency) {
// Automatically select a proper clientId for emergency call.
aClientId = gRadioInterfaceLayer.getClientIdForEmergencyCall() ;
if (aClientId === -1) {
if (DEBUG) debug("Error: No client is avaialble for emergency call.");
- aCallback.notifyDialError(DIAL_ERROR_INVALID_STATE_ERROR);
+ aCallback.notifyError(DIAL_ERROR_INVALID_STATE_ERROR);
return;
}
}
// Before we dial, we have to hold the active call first.
let activeCall = this._getOneActiveCall(aClientId);
if (!activeCall) {
this._sendDialCallRequest(aClientId, aOptions, aCallback);
@@ -650,17 +650,17 @@ TelephonyService.prototype = {
_sendDialCallRequest: function(aClientId, aOptions, aCallback) {
this._isDialing = true;
this._sendToRilWorker(aClientId, "dial", aOptions, response => {
this._isDialing = false;
if (!response.success) {
- aCallback.notifyDialError(response.errorMsg);
+ aCallback.notifyError(response.errorMsg);
return;
}
let currentCdmaCallIndex = !response.isCdma ? null :
Object.keys(this._currentCalls[aClientId])[0];
if (currentCdmaCallIndex == null) {
aCallback.notifyDialCallSuccess(response.callIndex, response.number);
@@ -668,26 +668,34 @@ TelephonyService.prototype = {
// RIL doesn't hold the 2nd call. We create one by ourselves.
aCallback.notifyDialCallSuccess(CDMA_SECOND_CALL_INDEX, response.number);
this._addCdmaChildCall(aClientId, response.number, currentCdmaCallIndex);
}
});
},
/**
+ * @param aClientId
+ * Client id.
* @param aMmi
* Parsed MMI structure.
+ * @param aCallback
+ * A nsITelephonyDialCallback object.
+ * @param aStartNewSession
+ * True to start a new session for ussd request.
*/
- _dialMMI: function(aClientId, aMmi, aCallback) {
+ _dialMMI: function(aClientId, aMmi, aCallback, aStartNewSession) {
let mmiServiceCode = aMmi ?
this._serviceCodeToKeyString(aMmi.serviceCode) : RIL.MMI_KS_SC_USSD;
aCallback.notifyDialMMI(mmiServiceCode);
- this._sendToRilWorker(aClientId, "sendMMI", { mmi: aMmi }, response => {
+ this._sendToRilWorker(aClientId, "sendMMI",
+ { mmi: aMmi,
+ startNewSession: aStartNewSession }, response => {
if (DEBUG) debug("MMI response: " + JSON.stringify(response));
if (!response.success) {
if (response.additionalInformation != null) {
aCallback.notifyDialMMIErrorWithInfo(response.errorMsg,
response.additionalInformation);
} else {
aCallback.notifyDialMMIError(response.errorMsg);
@@ -1043,16 +1051,28 @@ TelephonyService.prototype = {
holdConference: function(aClientId) {
this._sendToRilWorker(aClientId, "holdConference");
},
resumeConference: function(aClientId) {
this._sendToRilWorker(aClientId, "resumeConference");
},
+ sendUSSD: function(aClientId, aUssd, aCallback) {
+ this._sendToRilWorker(aClientId, "sendUSSD",
+ { ussd: aUssd, checkSession: true },
+ response => {
+ if (!response.success) {
+ aCallback.notifyError(response.errorMsg);
+ } else {
+ aCallback.notifySuccess();
+ }
+ });
+ },
+
get microphoneMuted() {
return gAudioManager.microphoneMuted;
},
set microphoneMuted(aMuted) {
if (aMuted == this.microphoneMuted) {
return;
}
@@ -1261,19 +1281,37 @@ TelephonyService.prototype = {
},
notifyConferenceCallStateChanged: function(aState) {
if (DEBUG) debug("handleConferenceCallStateChanged: " + aState);
aState = this._convertRILCallState(aState);
this._notifyAllListeners("conferenceCallStateChanged", [aState]);
},
+ notifyUssdReceived: function(aClientId, aMessage, aSessionEnded) {
+ if (DEBUG) {
+ debug("notifyUssdReceived for " + aClientId + ": " +
+ aMessage + " (sessionEnded : " + aSessionEnded + ")");
+ }
+
+ let info = {
+ serviceId: aClientId,
+ message: aMessage,
+ sessionEnded: aSessionEnded
+ };
+
+ gSystemMessenger.broadcastMessage("ussd-received", info);
+
+ gGonkMobileConnectionService.notifyUssdReceived(aClientId, aMessage,
+ aSessionEnded);
+ },
+
dialMMI: function(aClientId, aMmiString, aCallback) {
let mmi = this._parseMMI(aMmiString, this._hasCalls(aClientId));
- this._dialMMI(aClientId, mmi, aCallback);
+ this._dialMMI(aClientId, mmi, aCallback, false);
},
/**
* nsIObserver interface.
*/
observe: function(aSubject, aTopic, aData) {
switch (aTopic) {
@@ -1290,9 +1328,43 @@ TelephonyService.prototype = {
this._releaseCallRingWakeLock();
Services.obs.removeObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
break;
}
}
};
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([TelephonyService]);
+/**
+ * This implements nsISystemMessagesWrapper.wrapMessage(), which provides a
+ * plugable way to wrap a "ussd-received" type system message.
+ *
+ * Please see SystemMessageManager.js to know how it customizes the wrapper.
+ */
+function USSDReceivedWrapper() {
+ if (DEBUG) debug("USSDReceivedWrapper()");
+}
+USSDReceivedWrapper.prototype = {
+ // nsISystemMessagesWrapper implementation.
+ wrapMessage: function(aMessage, aWindow) {
+ if (DEBUG) debug("wrapMessage: " + JSON.stringify(aMessage));
+
+ let session = aMessage.sessionEnded ? null :
+ new aWindow.USSDSession(aMessage.serviceId);
+
+ let event = new aWindow.USSDReceivedEvent("ussdreceived", {
+ serviceId: aMessage.serviceId,
+ message: aMessage.message,
+ sessionEnded: aMessage.sessionEnded,
+ session: session
+ });
+
+ return event;
+ },
+
+ classDescription: "USSDReceivedWrapper",
+ classID: Components.ID("{d03684ed-ede4-4210-8206-f4f32772d9f5}"),
+ contractID: "@mozilla.org/dom/system-messages/wrapper/ussd-received;1",
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsISystemMessagesWrapper])
+};
+
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([TelephonyService,
+ USSDReceivedWrapper]);
--- a/dom/telephony/gonk/TelephonyService.manifest
+++ b/dom/telephony/gonk/TelephonyService.manifest
@@ -1,2 +1,5 @@
component {67d26434-d063-4d28-9f48-5b3189788155} TelephonyService.js
contract @mozilla.org/telephony/gonktelephonyservice;1 {67d26434-d063-4d28-9f48-5b3189788155}
+
+component {d03684ed-ede4-4210-8206-f4f32772d9f5} TelephonyService.js
+contract @mozilla.org/dom/system-messages/wrapper/ussd-received;1 {d03684ed-ede4-4210-8206-f4f32772d9f5}
--- a/dom/telephony/ipc/PTelephony.ipdl
+++ b/dom/telephony/ipc/PTelephony.ipdl
@@ -19,20 +19,27 @@ struct EnumerateCallsRequest
struct DialRequest
{
uint32_t clientId;
nsString number;
bool isEmergency;
};
+struct USSDRequest
+{
+ uint32_t clientId;
+ nsString ussd;
+};
+
union IPCTelephonyRequest
{
EnumerateCallsRequest;
DialRequest;
+ USSDRequest;
};
sync protocol PTelephony {
manager PContent;
manages PTelephonyRequest;
child:
NotifyCallError(uint32_t aClientId, int32_t aCallIndex, nsString aError);
--- a/dom/telephony/ipc/PTelephonyRequest.ipdl
+++ b/dom/telephony/ipc/PTelephonyRequest.ipdl
@@ -11,17 +11,22 @@ namespace mozilla {
namespace dom {
namespace telephony {
struct EnumerateCallsResponse
{
// empty.
};
-struct DialResponseError
+struct SuccessResponse
+{
+ // empty.
+};
+
+struct ErrorResponse
{
nsString name;
};
struct DialResponseCallSuccess
{
uint32_t callIndex;
nsString number;
@@ -37,18 +42,22 @@ struct DialResponseMMIError
{
nsString name;
AdditionalInformation additionalInformation;
};
union IPCTelephonyResponse
{
EnumerateCallsResponse;
+
+ // General.
+ SuccessResponse;
+ ErrorResponse;
+
// dial
- DialResponseError;
DialResponseCallSuccess;
DialResponseMMISuccess;
DialResponseMMIError;
};
protocol PTelephonyRequest
{
manager PTelephony;
--- a/dom/telephony/ipc/TelephonyChild.cpp
+++ b/dom/telephony/ipc/TelephonyChild.cpp
@@ -1,16 +1,16 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "TelephonyChild.h"
-#include "mozilla/dom/telephony/TelephonyCallback.h"
+#include "mozilla/dom/telephony/TelephonyDialCallback.h"
#include "TelephonyIPCService.h"
USING_TELEPHONY_NAMESPACE
/*******************************************************************************
* TelephonyChild
******************************************************************************/
@@ -142,18 +142,20 @@ TelephonyRequestChild::ActorDestroy(Acto
bool
TelephonyRequestChild::Recv__delete__(const IPCTelephonyResponse& aResponse)
{
switch (aResponse.type()) {
case IPCTelephonyResponse::TEnumerateCallsResponse:
mListener->EnumerateCallStateComplete();
break;
- case IPCTelephonyResponse::TDialResponseError:
- return DoResponse(aResponse.get_DialResponseError());
+ case IPCTelephonyResponse::TSuccessResponse:
+ return DoResponse(aResponse.get_SuccessResponse());
+ case IPCTelephonyResponse::TErrorResponse:
+ return DoResponse(aResponse.get_ErrorResponse());
case IPCTelephonyResponse::TDialResponseCallSuccess:
return DoResponse(aResponse.get_DialResponseCallSuccess());
case IPCTelephonyResponse::TDialResponseMMISuccess:
return DoResponse(aResponse.get_DialResponseMMISuccess());
case IPCTelephonyResponse::TDialResponseMMIError:
return DoResponse(aResponse.get_DialResponseMMIError());
default:
MOZ_CRASH("Unknown type!");
@@ -182,45 +184,55 @@ TelephonyRequestChild::RecvNotifyEnumera
aData.isMergeable());
return true;
}
bool
TelephonyRequestChild::RecvNotifyDialMMI(const nsString& aServiceCode)
{
MOZ_ASSERT(mCallback);
-
- mCallback->NotifyDialMMI(aServiceCode);
+ nsCOMPtr<nsITelephonyDialCallback> callback = do_QueryInterface(mCallback);
+ callback->NotifyDialMMI(aServiceCode);
return true;
}
bool
-TelephonyRequestChild::DoResponse(const DialResponseError& aResponse)
+TelephonyRequestChild::DoResponse(const SuccessResponse& aResponse)
{
MOZ_ASSERT(mCallback);
- mCallback->NotifyDialError(aResponse.name());
+ mCallback->NotifySuccess();
+ return true;
+}
+
+bool
+TelephonyRequestChild::DoResponse(const ErrorResponse& aResponse)
+{
+ MOZ_ASSERT(mCallback);
+ mCallback->NotifyError(aResponse.name());
return true;
}
bool
TelephonyRequestChild::DoResponse(const DialResponseCallSuccess& aResponse)
{
MOZ_ASSERT(mCallback);
- mCallback->NotifyDialCallSuccess(aResponse.callIndex(), aResponse.number());
+ nsCOMPtr<nsITelephonyDialCallback> callback = do_QueryInterface(mCallback);
+ callback->NotifyDialCallSuccess(aResponse.callIndex(), aResponse.number());
return true;
}
bool
TelephonyRequestChild::DoResponse(const DialResponseMMISuccess& aResponse)
{
MOZ_ASSERT(mCallback);
// FIXME: Need to overload NotifyDialMMISuccess in the IDL. mCallback is not
// necessarily an instance of TelephonyCallback.
- nsRefPtr<TelephonyCallback> callback = static_cast<TelephonyCallback*>(mCallback.get());
+ nsCOMPtr<nsITelephonyDialCallback> dialCallback = do_QueryInterface(mCallback);
+ nsRefPtr<TelephonyDialCallback> callback = static_cast<TelephonyDialCallback*>(dialCallback.get());
nsAutoString statusMessage(aResponse.statusMessage());
AdditionalInformation info(aResponse.additionalInformation());
switch (info.type()) {
case AdditionalInformation::Tvoid_t:
callback->NotifyDialMMISuccess(statusMessage);
break;
@@ -237,26 +249,27 @@ TelephonyRequestChild::DoResponse(const
return true;
}
bool
TelephonyRequestChild::DoResponse(const DialResponseMMIError& aResponse)
{
MOZ_ASSERT(mCallback);
+ nsCOMPtr<nsITelephonyDialCallback> callback = do_QueryInterface(mCallback);
nsAutoString name(aResponse.name());
AdditionalInformation info(aResponse.additionalInformation());
switch (info.type()) {
case AdditionalInformation::Tvoid_t:
- mCallback->NotifyDialMMIError(name);
+ callback->NotifyDialMMIError(name);
break;
case AdditionalInformation::Tuint16_t:
- mCallback->NotifyDialMMIErrorWithInfo(name, info.get_uint16_t());
+ callback->NotifyDialMMIErrorWithInfo(name, info.get_uint16_t());
break;
default:
MOZ_CRASH("Received invalid type!");
break;
}
return true;
}
--- a/dom/telephony/ipc/TelephonyChild.h
+++ b/dom/telephony/ipc/TelephonyChild.h
@@ -79,17 +79,20 @@ protected:
RecvNotifyEnumerateCallState(const uint32_t& aClientId,
const IPCCallStateData& aData) MOZ_OVERRIDE;
virtual bool
RecvNotifyDialMMI(const nsString& aServiceCode) MOZ_OVERRIDE;
private:
bool
- DoResponse(const DialResponseError& aResponse);
+ DoResponse(const SuccessResponse& aResponse);
+
+ bool
+ DoResponse(const ErrorResponse& aResponse);
bool
DoResponse(const DialResponseCallSuccess& aResponse);
bool
DoResponse(const DialResponseMMISuccess& aResponse);
bool
--- a/dom/telephony/ipc/TelephonyIPCService.cpp
+++ b/dom/telephony/ipc/TelephonyIPCService.cpp
@@ -157,17 +157,18 @@ TelephonyIPCService::SendRequest(nsITele
NS_IMETHODIMP
TelephonyIPCService::EnumerateCalls(nsITelephonyListener *aListener)
{
return SendRequest(aListener, nullptr, EnumerateCallsRequest());
}
NS_IMETHODIMP
TelephonyIPCService::Dial(uint32_t aClientId, const nsAString& aNumber,
- bool aIsEmergency, nsITelephonyCallback *aCallback)
+ bool aIsEmergency,
+ nsITelephonyDialCallback *aCallback)
{
return SendRequest(nullptr, aCallback,
DialRequest(aClientId, nsString(aNumber), aIsEmergency));
}
NS_IMETHODIMP
TelephonyIPCService::HangUp(uint32_t aClientId, uint32_t aCallIndex)
{
@@ -296,16 +297,24 @@ TelephonyIPCService::StopTone(uint32_t a
return NS_ERROR_FAILURE;
}
mPTelephonyChild->SendStopTone(aClientId);
return NS_OK;
}
NS_IMETHODIMP
+TelephonyIPCService::SendUSSD(uint32_t aClientId, const nsAString& aUssd,
+ nsITelephonyCallback *aCallback)
+{
+ return SendRequest(nullptr, aCallback,
+ USSDRequest(aClientId, nsString(aUssd)));
+}
+
+NS_IMETHODIMP
TelephonyIPCService::GetMicrophoneMuted(bool* aMuted)
{
if (!mPTelephonyChild) {
NS_WARNING("TelephonyService used after shutdown has begun!");
return NS_ERROR_FAILURE;
}
mPTelephonyChild->SendGetMicrophoneMuted(aMuted);
--- a/dom/telephony/ipc/TelephonyParent.cpp
+++ b/dom/telephony/ipc/TelephonyParent.cpp
@@ -38,16 +38,18 @@ TelephonyParent::RecvPTelephonyRequestCo
{
TelephonyRequestParent* actor = static_cast<TelephonyRequestParent*>(aActor);
switch (aRequest.type()) {
case IPCTelephonyRequest::TEnumerateCallsRequest:
return actor->DoRequest(aRequest.get_EnumerateCallsRequest());
case IPCTelephonyRequest::TDialRequest:
return actor->DoRequest(aRequest.get_DialRequest());
+ case IPCTelephonyRequest::TUSSDRequest:
+ return actor->DoRequest(aRequest.get_USSDRequest());
default:
MOZ_CRASH("Unknown type!");
}
return false;
}
PTelephonyRequestParent*
@@ -380,17 +382,18 @@ TelephonyParent::SupplementaryServiceNot
}
/*******************************************************************************
* TelephonyRequestParent
******************************************************************************/
NS_IMPL_ISUPPORTS(TelephonyRequestParent,
nsITelephonyListener,
- nsITelephonyCallback)
+ nsITelephonyCallback,
+ nsITelephonyDialCallback)
TelephonyRequestParent::TelephonyRequestParent()
: mActorDestroyed(false)
{
}
void
TelephonyRequestParent::ActorDestroy(ActorDestroyReason why)
@@ -421,19 +424,33 @@ TelephonyRequestParent::DoRequest(const
bool
TelephonyRequestParent::DoRequest(const DialRequest& aRequest)
{
nsCOMPtr<nsITelephonyService> service =
do_GetService(TELEPHONY_SERVICE_CONTRACTID);
if (service) {
service->Dial(aRequest.clientId(), aRequest.number(),
- aRequest.isEmergency(), this);
+ aRequest.isEmergency(), this);
} else {
- return NS_SUCCEEDED(NotifyDialError(NS_LITERAL_STRING("InvalidStateError")));
+ return NS_SUCCEEDED(NotifyError(NS_LITERAL_STRING("InvalidStateError")));
+ }
+
+ return true;
+}
+
+bool
+TelephonyRequestParent::DoRequest(const USSDRequest& aRequest)
+{
+ nsCOMPtr<nsITelephonyService> service =
+ do_GetService(TELEPHONY_SERVICE_CONTRACTID);
+ if (service) {
+ service->SendUSSD(aRequest.clientId(), aRequest.ussd(), this);
+ } else {
+ return NS_SUCCEEDED(NotifyError(NS_LITERAL_STRING("InvalidStateError")));
}
return true;
}
nsresult
TelephonyRequestParent::SendResponse(const IPCTelephonyResponse& aResponse)
{
@@ -527,30 +544,36 @@ TelephonyRequestParent::NotifyError(uint
NS_IMETHODIMP
TelephonyRequestParent::SupplementaryServiceNotification(uint32_t aClientId,
int32_t aCallIndex,
uint16_t aNotification)
{
MOZ_CRASH("Not a TelephonyParent!");
}
-// nsITelephonyCallback
+// nsITelephonyDialCallback
NS_IMETHODIMP
TelephonyRequestParent::NotifyDialMMI(const nsAString& aServiceCode)
{
NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE);
return SendNotifyDialMMI(nsAutoString(aServiceCode)) ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
-TelephonyRequestParent::NotifyDialError(const nsAString& aError)
+TelephonyRequestParent::NotifySuccess()
{
- return SendResponse(DialResponseError(nsAutoString(aError)));
+ return SendResponse(SuccessResponse());
+}
+
+NS_IMETHODIMP
+TelephonyRequestParent::NotifyError(const nsAString& aError)
+{
+ return SendResponse(ErrorResponse(nsAutoString(aError)));
}
NS_IMETHODIMP
TelephonyRequestParent::NotifyDialCallSuccess(uint32_t aCallIndex,
const nsAString& aNumber)
{
return SendResponse(DialResponseCallSuccess(aCallIndex, nsAutoString(aNumber)));
}
--- a/dom/telephony/ipc/TelephonyParent.h
+++ b/dom/telephony/ipc/TelephonyParent.h
@@ -93,24 +93,25 @@ protected:
private:
bool mActorDestroyed;
bool mRegistered;
};
class TelephonyRequestParent : public PTelephonyRequestParent
, public nsITelephonyListener
- , public nsITelephonyCallback
+ , public nsITelephonyDialCallback
{
friend class TelephonyParent;
public:
NS_DECL_ISUPPORTS
NS_DECL_NSITELEPHONYLISTENER
NS_DECL_NSITELEPHONYCALLBACK
+ NS_DECL_NSITELEPHONYDIALCALLBACK
protected:
TelephonyRequestParent();
virtual ~TelephonyRequestParent() {}
virtual void
ActorDestroy(ActorDestroyReason why);
@@ -120,13 +121,16 @@ protected:
private:
bool mActorDestroyed;
bool
DoRequest(const EnumerateCallsRequest& aRequest);
bool
DoRequest(const DialRequest& aRequest);
+
+ bool
+ DoRequest(const USSDRequest& aRequest);
};
END_TELEPHONY_NAMESPACE
#endif /* mozilla_dom_telephony_TelephonyParent_h */
--- a/dom/telephony/moz.build
+++ b/dom/telephony/moz.build
@@ -11,35 +11,39 @@ XPIDL_SOURCES += [
XPIDL_MODULE = 'dom_telephony'
EXPORTS.mozilla.dom += [
'CallsList.h',
'Telephony.h',
'TelephonyCall.h',
'TelephonyCallGroup.h',
'TelephonyCallId.h',
+ 'USSDSession.h'
]
EXPORTS.mozilla.dom.telephony += [
'ipc/TelephonyChild.h',
'ipc/TelephonyParent.h',
'TelephonyCallback.h',
'TelephonyCommon.h',
+ 'TelephonyDialCallback.h',
]
UNIFIED_SOURCES += [
'CallsList.cpp',
'ipc/TelephonyChild.cpp',
'ipc/TelephonyIPCService.cpp',
'ipc/TelephonyParent.cpp',
'Telephony.cpp',
'TelephonyCall.cpp',
'TelephonyCallback.cpp',
'TelephonyCallGroup.cpp',
'TelephonyCallId.cpp',
+ 'TelephonyDialCallback.cpp',
+ 'USSDSession.cpp',
]
IPDL_SOURCES += [
'ipc/PTelephony.ipdl',
'ipc/PTelephonyRequest.ipdl',
'ipc/TelephonyTypes.ipdlh'
]
--- a/dom/telephony/nsIGonkTelephonyService.idl
+++ b/dom/telephony/nsIGonkTelephonyService.idl
@@ -5,28 +5,31 @@
#include "nsITelephonyService.idl"
%{C++
#define GONK_TELEPHONY_SERVICE_CONTRACTID \
"@mozilla.org/telephony/gonktelephonyservice;1"
%}
-[scriptable, uuid(8790e2cc-2c68-4ce9-90dc-f68e1b6e4886)]
+[scriptable, uuid(79eec3c3-2dfc-4bbf-b106-af5457651ae0)]
interface nsIGonkTelephonyService : nsITelephonyService
{
void notifyCallDisconnected(in unsigned long clientId, in jsval call);
void notifyCallRing();
void notifyCallStateChanged(in unsigned long clientId, in jsval call,
[optional] in boolean skipStateConversion);
void notifyCdmaCallWaiting(in unsigned long clientId, in jsval waitingCall);
void notifySupplementaryService(in unsigned long clientId, in long callIndex,
in AString notification);
void notifyConferenceCallStateChanged(in short state);
+ void notifyUssdReceived(in unsigned long clientId, in DOMString message,
+ in boolean sessionEnded);
+
void dialMMI(in unsigned long clientId, in AString mmiString,
- in nsITelephonyCallback callback);
+ in nsITelephonyDialCallback callback);
};
--- a/dom/telephony/nsITelephonyService.idl
+++ b/dom/telephony/nsITelephonyService.idl
@@ -172,39 +172,41 @@ interface nsITelephonyListener : nsISupp
* @param message
* Detailed error message from RIL.
*/
void notifyConferenceError(in AString name,
in AString message);
};
/**
- * A callback interface for handling asynchronous response of Telephony.dial().
+ * A callback interface for handling asynchronous response.
*/
-[scriptable, uuid(67533db3-cd38-475c-a774-8d0bbf9169fb)]
+[scriptable, uuid(cffc3f9d-2c88-4a14-8ebc-f216caf0cc1d)]
interface nsITelephonyCallback : nsISupports
{
+ void notifySuccess();
+ void notifyError(in AString error);
+};
+
+/**
+ * A callback interface for handling asynchronous response for telephony.dial.
+ */
+[scriptable, uuid(4481212f-72e9-4aef-97e1-5397af782113)]
+interface nsITelephonyDialCallback : nsITelephonyCallback
+{
/**
* Called when a dial request is treated as an MMI code and it is about to
* process the request.
*
* @param serviceCode
* MMI service code key string that defined in MMI_KS_SC_*
*/
void notifyDialMMI(in AString serviceCode);
/**
- * Called when a dial request fails.
- *
- * @param error
- * Error from RIL.
- */
- void notifyDialError(in AString error);
-
- /**
* Called when a dial request is treated as a call setup and the result
* succeeds.
*
* @param callIndex
* Call index from RIL.
* @param number
* Dialed out phone number (ex: Temporary CLIR prefix will be removed)
*/
@@ -233,17 +235,17 @@ interface nsITelephonyCallback : nsISupp
#define TELEPHONY_SERVICE_CONTRACTID \
"@mozilla.org/telephony/telephonyservice;1"
%}
/**
* XPCOM component (in the content process) that provides the telephony
* information.
*/
-[scriptable, uuid(4ff3ecb7-b024-4752-9dd6-c3623c6e6b8a)]
+[scriptable, uuid(79188caa-046a-48e1-b9c5-2e891504dc7a)]
interface nsITelephonyService : nsISupports
{
const unsigned short CALL_STATE_UNKNOWN = 0;
const unsigned short CALL_STATE_DIALING = 1;
const unsigned short CALL_STATE_ALERTING = 2;
const unsigned short CALL_STATE_CONNECTING = 3;
const unsigned short CALL_STATE_CONNECTED = 4;
const unsigned short CALL_STATE_HOLDING = 5;
@@ -276,32 +278,42 @@ interface nsITelephonyService : nsISuppo
* returns false.
*/
void enumerateCalls(in nsITelephonyListener listener);
/**
* Functionality for making and managing phone calls.
*/
void dial(in unsigned long clientId, in DOMString number,
- in boolean isEmergency, in nsITelephonyCallback callback);
+ in boolean isEmergency, in nsITelephonyDialCallback callback);
void hangUp(in unsigned long clientId, in unsigned long callIndex);
void startTone(in unsigned long clientId, in DOMString dtmfChar);
void stopTone(in unsigned long clientId);
void answerCall(in unsigned long clientId, in unsigned long callIndex);
void rejectCall(in unsigned long clientId, in unsigned long callIndex);
void holdCall(in unsigned long clientId, in unsigned long callIndex);
void resumeCall(in unsigned long clientId, in unsigned long callIndex);
void conferenceCall(in unsigned long clientId);
void separateCall(in unsigned long clientId, in unsigned long callIndex);
void holdConference(in unsigned long clientId);
void resumeConference(in unsigned long clientId);
+ /**
+ * Send an USSD on existing session. It results in error if the session is
+ * not existed.
+ *
+ * If successful, callback.notifySuccess() will be called.
+ * Otherwise, callback.notifyError() will be called.
+ */
+ void sendUSSD(in unsigned long clientId, in DOMString ussd,
+ in nsITelephonyCallback callback);
+
attribute bool microphoneMuted;
attribute bool speakerEnabled;
};
%{C++
template<typename T> struct already_AddRefed;
already_AddRefed<nsITelephonyService>
--- a/dom/tests/mochitest/general/test_interfaces.html
+++ b/dom/tests/mochitest/general/test_interfaces.html
@@ -167,40 +167,36 @@ var interfaceNamesInGlobalScope =
"AudioProcessingEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!
"AudioStreamTrack",
// IMPORTANT: Do not change this list without review from a DOM peer!
"BarProp",
// IMPORTANT: Do not change this list without review from a DOM peer!
"BatteryManager",
// IMPORTANT: Do not change this list without review from a DOM peer!
- {name: "BeforeAfterKeyboardEvent", b2g: true,
- pref: "dom.beforeAfterKeyboardEvent.enabled",
- permission: ["embed-apps", "before-after-keyboard-event"]},
-// IMPORTANT: Do not change this list without review from a DOM peer!
"BeforeUnloadEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!
"BiquadFilterNode",
// IMPORTANT: Do not change this list without review from a DOM peer!
"Blob",
// IMPORTANT: Do not change this list without review from a DOM peer!
"BlobEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!
- {name: "BluetoothAdapter", b2g: true, permission: ["bluetooth"]},
+ {name: "BluetoothAdapter", b2g: true, permission: "bluetooth"},
// IMPORTANT: Do not change this list without review from a DOM peer!
- {name: "BluetoothDevice", b2g: true, permission: ["bluetooth"]},
+ {name: "BluetoothDevice", b2g: true, permission: "bluetooth"},
// IMPORTANT: Do not change this list without review from a DOM peer!
- {name: "BluetoothDeviceEvent", b2g: true, permission: ["bluetooth"]},
+ {name: "BluetoothDeviceEvent", b2g: true, permission: "bluetooth"},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "BluetoothDiscoveryStateChangedEvent", b2g: true,
- permission: ["bluetooth"]},
+ permission: "bluetooth"},
// IMPORTANT: Do not change this list without review from a DOM peer!
- {name: "BluetoothManager", b2g: true, permission: ["bluetooth"]},
+ {name: "BluetoothManager", b2g: true, permission: "bluetooth"},
// IMPORTANT: Do not change this list without review from a DOM peer!
- {name: "BluetoothStatusChangedEvent", b2g: true, permission: ["bluetooth"]},
+ {name: "BluetoothStatusChangedEvent", b2g: true, permission: "bluetooth"},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "BoxObject", xbl: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "CallEvent", b2g: true, pref: "dom.telephony.enabled"},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "CallGroupErrorEvent", b2g: true, pref: "dom.telephony.enabled"},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "CameraCapabilities", b2g: true},
@@ -752,17 +748,17 @@ var interfaceNamesInGlobalScope =
{name: "mozRTCIceCandidate", pref: "media.peerconnection.enabled"},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "mozRTCPeerConnection", pref: "media.peerconnection.enabled"},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "mozRTCSessionDescription", pref: "media.peerconnection.enabled"},
// IMPORTANT: Do not change this list without review from a DOM peer!
"MozSettingsEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!
- {name: "MozSettingsTransactionEvent", permission: ["settings-api-read"]},
+ {name: "MozSettingsTransactionEvent", permission: "settings-api-read"},
// IMPORTANT: Do not change this list without review from a DOM peer!
"MozSmsEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!
"MozSmsMessage",
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "MozSpeakerManager", b2g: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "MozStkCommandEvent", b2g: true, pref: "dom.icc.enabled"},
@@ -772,33 +768,33 @@ var interfaceNamesInGlobalScope =
{name: "MozVoicemail", b2g: true, pref: "dom.voicemail.enabled"},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "MozVoicemailEvent", b2g: true, pref: "dom.voicemail.enabled"},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "MozVoicemailStatus", b2g: true, pref: "dom.voicemail.enabled"},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "MozWakeLock", b2g: true, pref: "dom.wakelock.enabled"},
// IMPORTANT: Do not change this list without review from a DOM peer!
- {name: "MozWifiCapabilities", b2g: true, permission: ["wifi-manage"]},
+ {name: "MozWifiCapabilities", b2g: true, permission: "wifi-manage"},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "MozWifiConnectionInfoEvent", b2g: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "MozWifiStationInfoEvent", b2g: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
- {name: "MozWifiManager", b2g: true, permission: ["wifi-manage"]},
+ {name: "MozWifiManager", b2g: true, permission: "wifi-manage"},
// IMPORTANT: Do not change this list without review from a DOM peer!
- {name: "MozWifiNetwork", b2g: true, permission: ["wifi-manage"]},
+ {name: "MozWifiNetwork", b2g: true, permission: "wifi-manage"},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "MozWifiStatusChangeEvent", b2g: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
- {name: "MozWifiP2pGroupOwner", b2g: true, permission: ["wifi-manage"]},
+ {name: "MozWifiP2pGroupOwner", b2g: true, permission: "wifi-manage"},
// IMPORTANT: Do not change this list without review from a DOM peer!
- {name: "MozWifiP2pManager", b2g: true, permission: ["wifi-manage"]},
+ {name: "MozWifiP2pManager", b2g: true, permission: "wifi-manage"},
// IMPORTANT: Do not change this list without review from a DOM peer!
- {name: "MozWifiP2pStatusChangeEvent", b2g: true, permission: ["wifi-manage"]},
+ {name: "MozWifiP2pStatusChangeEvent", b2g: true, permission: "wifi-manage"},
// IMPORTANT: Do not change this list without review from a DOM peer!
"MutationEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!
"MutationObserver",
// IMPORTANT: Do not change this list without review from a DOM peer!
"MutationRecord",
// IMPORTANT: Do not change this list without review from a DOM peer!
"NamedNodeMap",
@@ -846,19 +842,19 @@ var interfaceNamesInGlobalScope =
"PerformanceNavigation",
// IMPORTANT: Do not change this list without review from a DOM peer!
"PerformanceResourceTiming",
// IMPORTANT: Do not change this list without review from a DOM peer!
"PerformanceTiming",
// IMPORTANT: Do not change this list without review from a DOM peer!
"PeriodicWave",
// IMPORTANT: Do not change this list without review from a DOM peer!
- {name: "PermissionSettings", b2g: true, permission: ["permissions"]},
+ {name: "PermissionSettings", b2g: true, permission: "permissions"},
// IMPORTANT: Do not change this list without review from a DOM peer!
- {name: "PhoneNumberService", permission: ["phonenumberservice"]},
+ {name: "PhoneNumberService", permission: "phonenumberservice"},
// IMPORTANT: Do not change this list without review from a DOM peer!
"Plugin",
// IMPORTANT: Do not change this list without review from a DOM peer!
"PluginArray",
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "PointerEvent", pref: "dom.w3c_pointer_events.enabled"},
// IMPORTANT: Do not change this list without review from a DOM peer!
"PopStateEvent",
@@ -1230,34 +1226,30 @@ var interfaceNamesInGlobalScope =
{name: "TreeColumns", xbl: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "TreeContentView", xbl: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "TreeSelection", xbl: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
"TreeWalker",
// IMPORTANT: Do not change this list without review from a DOM peer!
- {name: "UDPMessageEvent", pref: "dom.udpsocket.enabled",
- permission: ["udp-socket"]},
+ {name: "UDPMessageEvent", pref: "dom.udpsocket.enabled", permission: "udp-socket"},
// IMPORTANT: Do not change this list without review from a DOM peer!
- {name: "UDPSocket", pref: "dom.udpsocket.enabled",
- permission: ["udp-socket"]},
+ {name: "UDPSocket", pref: "dom.udpsocket.enabled", permission: "udp-socket"},
// IMPORTANT: Do not change this list without review from a DOM peer!
"UIEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!
"UndoManager",
// IMPORTANT: Do not change this list without review from a DOM peer!
"URL",
// IMPORTANT: Do not change this list without review from a DOM peer!
"URLSearchParams",
// IMPORTANT: Do not change this list without review from a DOM peer!
"UserProximityEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!
- {name: "USSDReceivedEvent", b2g: true, pref: "dom.mobileconnection.enabled"},
-// IMPORTANT: Do not change this list without review from a DOM peer!
"ValidityState",
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "VideoPlaybackQuality", pref: "media.mediasource.enabled"},
// IMPORTANT: Do not change this list without review from a DOM peer!
"VideoStreamTrack",
// IMPORTANT: Do not change this list without review from a DOM peer!
"VTTCue",
// IMPORTANT: Do not change this list without review from a DOM peer!
@@ -1344,22 +1336,18 @@ var interfaceNamesInGlobalScope =
function createInterfaceMap(isXBLScope) {
var prefs = SpecialPowers.Services.prefs;
var version = SpecialPowers.Cc["@mozilla.org/xre/app-info;1"].getService(SpecialPowers.Ci.nsIXULAppInfo).version;
var isNightly = version.endsWith("a1");
var isRelease = !version.contains("a");
var isDesktop = !/Mobile|Tablet/.test(navigator.userAgent);
var isB2G = !isDesktop && !navigator.userAgent.contains("Android");
- var hasPermission = function (aPermissions) {
- var result = false;
- for (var p of aPermissions) {
- result = result || SpecialPowers.hasPermission(p, window.document);
- }
- return result;
+ var hasPermission = function (aPermission) {
+ return SpecialPowers.hasPermission(aPermission, window.document);
};
var interfaceMap = {};
function addInterfaces(interfaces)
{
for (var entry of interfaces) {
if (typeof(entry) === "string") {
deleted file mode 100644
--- a/dom/webidl/BeforeAfterKeyboardEvent.webidl
+++ /dev/null
@@ -1,24 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-[Constructor(DOMString typeArg,
- optional BeforeAfterKeyboardEventInit eventInitDict),
- CheckPermissions="embed-apps before-after-keyboard-event",
- Pref="dom.beforeAfterKeyboardEvent.enabled"]
-interface BeforeAfterKeyboardEvent : KeyboardEvent
-{
- // The valid value of embeddedCancelled is:
- // - "mozbrowserbeforekeydown": null
- // - "mozbrowserbeforekeyup": null
- // - "mozbrowserafterkeydown": true/false
- // - "mozbrowserafterkeyup": true/false
- readonly attribute boolean? embeddedCancelled;
-};
-
-dictionary BeforeAfterKeyboardEventInit : KeyboardEventInit
-{
- boolean? embeddedCancelled = null;
-};
--- a/dom/webidl/MozNFCTag.webidl
+++ b/dom/webidl/MozNFCTag.webidl
@@ -5,18 +5,16 @@
* Part of this idl is from:
* http://w3c.github.io/nfc/proposals/common/nfc.html#nfctag-interface
*
* Copyright © 2013 Deutsche Telekom, Inc.
*/
enum NFCTechType {
"NDEF",
- "NDEF_WRITABLE",
- "NDEF_FORMATABLE",
"P2P",
"NFC_A",
"NFC_B",
"NFC_F",
"NFC_V",
"NFC_ISO_DEP",
"MIFARE_CLASSIC",
"MIFARE_ULTRALIGHT",
--- a/dom/webidl/NfcOptions.webidl
+++ b/dom/webidl/NfcOptions.webidl
@@ -8,16 +8,17 @@ dictionary NfcCommandOptions
long sessionId;
DOMString requestId = "";
long powerLevel;
long techType;
+ boolean isP2P;
sequence<MozNDEFRecordOptions> records;
};
dictionary NfcEventOptions
{
DOMString type = "";
long status;
--- a/dom/webidl/USSDReceivedEvent.webidl
+++ b/dom/webidl/USSDReceivedEvent.webidl
@@ -1,19 +1,25 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-[Pref="dom.mobileconnection.enabled",
+[Pref="dom.telephony.enabled",
+ CheckPermissions="telephony mobileconnection",
+ AvailableIn="CertifiedApps",
Constructor(DOMString type, optional USSDReceivedEventInit eventInitDict)]
interface USSDReceivedEvent : Event
{
+ readonly attribute unsigned long serviceId;
readonly attribute DOMString? message;
- readonly attribute boolean sessionEnded;
+ readonly attribute USSDSession? session; // null if session is ended.
+ readonly attribute boolean sessionEnded; // deprecated. Bug 1070831
};
dictionary USSDReceivedEventInit : EventInit
{
+ unsigned long serviceId = 0;
DOMString? message = null;
+ USSDSession? session = null;
boolean sessionEnded = false;
};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/USSDSession.webidl
@@ -0,0 +1,14 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+[Pref="dom.telephony.enabled",
+ CheckPermissions="telephony",
+ AvailableIn="CertifiedApps",
+ Constructor(unsigned long serviceId)]
+interface USSDSession {
+ [Throws]
+ Promise<void> send(DOMString ussd);
+};
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -44,17 +44,16 @@ WEBIDL_FILES = [
'AudioParam.webidl',
'AudioProcessingEvent.webidl',
'AudioStreamTrack.webidl',
'AudioTrack.webidl',
'AudioTrackList.webidl',
'AutocompleteInfo.webidl',
'BarProp.webidl',
'BatteryManager.webidl',
- 'BeforeAfterKeyboardEvent.webidl',
'BeforeUnloadEvent.webidl',
'BiquadFilterNode.webidl',
'Blob.webidl',
'BoxObject.webidl',
'BrowserElementDictionaries.webidl',
'CallsList.webidl',
'CameraCapabilities.webidl',
'CameraControl.webidl',
@@ -504,16 +503,17 @@ WEBIDL_FILES = [
'UDPMessageEvent.webidl',
'UDPSocket.webidl',
'UIEvent.webidl',
'UndoManager.webidl',
'URL.webidl',
'URLSearchParams.webidl',
'URLUtils.webidl',
'URLUtilsReadOnly.webidl',
+ 'USSDSession.webidl',
'ValidityState.webidl',
'VideoPlaybackQuality.webidl',
'VideoStreamTrack.webidl',
'VideoTrack.webidl',
'VideoTrackList.webidl',
'VTTCue.webidl',
'VTTRegion.webidl',
'WaveShaperNode.webidl',
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -117,17 +117,21 @@ GetBitmapForSurface(SourceSurface* aSurf
result.mBitmap.setInfo(info, surf->Stride());
result.mBitmap.setPixels(surf->GetData());
result.mTmpSurface = surf.forget();
return result;
}
DrawTargetSkia::DrawTargetSkia()
- : mTexture(0), mSnapshot(nullptr)
+ :
+#ifdef USE_SKIA_GPU
+ mTexture(0),
+#endif
+ mSnapshot(nullptr)
{
}
DrawTargetSkia::~DrawTargetSkia()
{
}
TemporaryRef<SourceSurface>
@@ -843,20 +847,21 @@ DrawTargetSkia::SetTransform(const Matri
GfxMatrixToSkiaMatrix(aTransform, mat);
mCanvas->setMatrix(mat);
mTransform = aTransform;
}
void*
DrawTargetSkia::GetNativeSurface(NativeSurfaceType aType)
{
+#ifdef USE_SKIA_GPU
if (aType == NativeSurfaceType::OPENGL_TEXTURE) {
return (void*)((uintptr_t)mTexture);
}
-
+#endif
return nullptr;
}
TemporaryRef<PathBuilder>
DrawTargetSkia::CreatePathBuilder(FillRule aFillRule) const
{
return new PathBuilderSkia(aFillRule);
--- a/gfx/2d/FilterNodeSoftware.cpp
+++ b/gfx/2d/FilterNodeSoftware.cpp
@@ -1151,41 +1151,55 @@ FilterNodeTransformSoftware::SourceRectF
}
TemporaryRef<DataSourceSurface>
FilterNodeTransformSoftware::Render(const IntRect& aRect)
{
IntRect srcRect = SourceRectForOutputRect(aRect);
RefPtr<DataSourceSurface> input =
- GetInputDataSourceSurface(IN_TRANSFORM_IN, srcRect, NEED_COLOR_CHANNELS);
+ GetInputDataSourceSurface(IN_TRANSFORM_IN, srcRect);
if (!input) {
return nullptr;
}
Matrix transform = Matrix::Translation(srcRect.x, srcRect.y) * mMatrix *
Matrix::Translation(-aRect.x, -aRect.y);
if (transform.IsIdentity() && srcRect.Size() == aRect.Size()) {
return input.forget();
}
+ RefPtr<DataSourceSurface> surf =
+ Factory::CreateDataSourceSurface(aRect.Size(), input->GetFormat(), true);
+
+ if (!surf) {
+ return nullptr;
+ }
+
+ DataSourceSurface::MappedSurface mapping;
+ surf->Map(DataSourceSurface::MapType::WRITE, &mapping);
+
RefPtr<DrawTarget> dt =
- Factory::CreateDrawTarget(BackendType::CAIRO, aRect.Size(), input->GetFormat());
+ Factory::CreateDrawTargetForData(BackendType::CAIRO,
+ mapping.mData,
+ surf->GetSize(),
+ mapping.mStride,
+ surf->GetFormat());
if (!dt) {
return nullptr;
}
Rect r(0, 0, srcRect.width, srcRect.height);
dt->SetTransform(transform);
dt->DrawSurface(input, r, r, DrawSurfaceOptions(mFilter));
- RefPtr<SourceSurface> result = dt->Snapshot();
- RefPtr<DataSourceSurface> resultData = result->GetDataSurface();
- return resultData.forget();
+ dt->Flush();
+ surf->Unmap();
+ return surf.forget();
}
void
FilterNodeTransformSoftware::RequestFromInputsForRect(const IntRect &aRect)
{
RequestInputRect(IN_TRANSFORM_IN, SourceRectForOutputRect(aRect));
}
--- a/gfx/2d/Matrix.h
+++ b/gfx/2d/Matrix.h
@@ -796,29 +796,29 @@ public:
Float __33 = _12*_24*_41 - _14*_22*_41 +
_14*_21*_42 - _11*_24*_42 -
_12*_21*_44 + _11*_22*_44;
return (__33 * det) < 0;
}
Matrix4x4 &NudgeToIntegersFixedEpsilon()
{
+ NudgeToInteger(&_11);
+ NudgeToInteger(&_12);
+ NudgeToInteger(&_13);
+ NudgeToInteger(&_14);
+ NudgeToInteger(&_21);
+ NudgeToInteger(&_22);
+ NudgeToInteger(&_23);
+ NudgeToInteger(&_24);
+ NudgeToInteger(&_31);
+ NudgeToInteger(&_32);
+ NudgeToInteger(&_33);
+ NudgeToInteger(&_34);
static const float error = 1e-5f;
- NudgeToInteger(&_11, error);
- NudgeToInteger(&_12, error);
- NudgeToInteger(&_13, error);
- NudgeToInteger(&_14, error);
- NudgeToInteger(&_21, error);
- NudgeToInteger(&_22, error);
- NudgeToInteger(&_23, error);
- NudgeToInteger(&_24, error);
- NudgeToInteger(&_31, error);
- NudgeToInteger(&_32, error);
- NudgeToInteger(&_33, error);
- NudgeToInteger(&_34, error);
NudgeToInteger(&_41, error);
NudgeToInteger(&_42, error);
NudgeToInteger(&_43, error);
NudgeToInteger(&_44, error);
return *this;
}
Point4D TransposedVector(int aIndex) const
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -44,17 +44,17 @@
#endif
namespace mozilla {
namespace gl {
using namespace mozilla::gfx;
using namespace mozilla::layers;
-#ifdef DEBUG
+#ifdef MOZ_GL_DEBUG
unsigned GLContext::sCurrentGLContextTLS = -1;
#endif
uint32_t GLContext::sDebugMode = 0;
#define MAX_SYMBOL_LENGTH 128
#define MAX_SYMBOL_NAMES 5
@@ -287,17 +287,17 @@ GLContext::GLContext(const SurfaceCaps&
: mInitialized(false),
mIsOffscreen(isOffscreen),
mContextLost(false),
mVersion(0),
mProfile(ContextProfile::Unknown),
mVendor(GLVendor::Other),
mRenderer(GLRenderer::Other),
mHasRobustness(false),
-#ifdef DEBUG
+#ifdef MOZ_GL_DEBUG
mIsInLocalErrorCheck(false),
#endif
mSharedContext(sharedContext),
mCaps(caps),
mScreen(nullptr),
mLockedSurface(nullptr),
mMaxTextureSize(0),
mMaxCubeMapTextureSize(0),
@@ -307,17 +307,17 @@ GLContext::GLContext(const SurfaceCaps&
mWorkAroundDriverBugs(true),
mHeavyGLCallsSinceLastFlush(false)
{
mOwningThreadId = PlatformThread::CurrentId();
}
GLContext::~GLContext() {
NS_ASSERTION(IsDestroyed(), "GLContext implementation must call MarkDestroyed in destructor!");
-#ifdef DEBUG
+#ifdef MOZ_GL_DEBUG
if (mSharedContext) {
GLContext *tip = mSharedContext;
while (tip->mSharedContext)
tip = tip->mSharedContext;
tip->SharedContextDestroyed(this);
tip->ReportOutstandingNames();
} else {
ReportOutstandingNames();
@@ -506,17 +506,17 @@ GLContext::InitWithPrefix(const char *pr
mInitialized = LoadSymbols(&symbols[0], trygl, prefix);
MakeCurrent();
if (mInitialized) {
unsigned int version = 0;
ParseGLVersion(this, &version);
-#ifdef DEBUG
+#ifdef MOZ_GL_DEBUG
printf_stderr("OpenGL version detected: %u\n", version);
printf_stderr("OpenGL vendor: %s\n", fGetString(LOCAL_GL_VENDOR));
printf_stderr("OpenGL renderer: %s\n", fGetString(LOCAL_GL_RENDERER));
#endif
if (version >= mVersion) {
mVersion = version;
}
@@ -626,32 +626,32 @@ GLContext::InitWithPrefix(const char *pr
if (DoesStringMatch(glRendererString, rendererMatchStrings[i])) {
mRenderer = GLRenderer(i);
break;
}
}
}
-#ifdef DEBUG
+#ifdef MOZ_GL_DEBUG
if (PR_GetEnv("MOZ_GL_DEBUG"))
sDebugMode |= DebugEnabled;
// enables extra verbose output, informing of the start and finish of every GL call.
// useful e.g. to record information to investigate graphics system crashes/lockups
if (PR_GetEnv("MOZ_GL_DEBUG_VERBOSE"))
sDebugMode |= DebugTrace;
// aborts on GL error. Can be useful to debug quicker code that is known not to generate any GL error in principle.
if (PR_GetEnv("MOZ_GL_DEBUG_ABORT_ON_ERROR"))
sDebugMode |= DebugAbortOnError;
#endif
if (mInitialized) {
-#ifdef DEBUG
+#ifdef MOZ_GL_DEBUG
static bool firstRun = true;
if (firstRun && DebugMode()) {
const char *vendors[size_t(GLVendor::Other)] = {
"Intel",
"NVIDIA",
"ATI",
"Qualcomm"
};
@@ -1603,17 +1603,17 @@ GLContext::DebugCallback(GLenum source,
void
GLContext::InitExtensions()
{
MakeCurrent();
const char* extensions = (const char*)fGetString(LOCAL_GL_EXTENSIONS);
if (!extensions)
return;
-#ifdef DEBUG
+#ifdef MOZ_GL_DEBUG
static bool firstRun = true;
#else
// Non-DEBUG, so never spew.
const bool firstRun = false;
#endif
InitializeExtensionsBitSet(mAvailableExtensions, extensions, sExtensionNames, firstRun && DebugMode());
@@ -1654,17 +1654,17 @@ GLContext::InitExtensions()
nsCocoaFeatures::OSXVersionMajor() == 10 &&
nsCocoaFeatures::OSXVersionMinor() == 9 &&
Renderer() == GLRenderer::IntelHD3000)
{
MarkExtensionUnsupported(EXT_texture_compression_s3tc);
}
#endif
-#ifdef DEBUG
+#ifdef MOZ_GL_DEBUG
firstRun = false;
#endif
}
void
GLContext::PlatformStartup()
{
RegisterStrongMemoryReporter(new GfxTexturesReporter());
@@ -1744,17 +1744,17 @@ GLContext::QueryPixelFormat()
return format;
}
void
GLContext::UpdatePixelFormat()
{
PixelBufferFormat format = QueryPixelFormat();
-#ifdef DEBUG
+#ifdef MOZ_GL_DEBUG
const SurfaceCaps& caps = Caps();
MOZ_ASSERT(!caps.any, "Did you forget to DetermineCaps()?");
MOZ_ASSERT(caps.color == !!format.red);
MOZ_ASSERT(caps.color == !!format.green);
MOZ_ASSERT(caps.color == !!format.blue);
// These we either must have if they're requested, or
@@ -1968,27 +1968,27 @@ GLContext::AssembleOffscreenFBs(const GL
}
// We should be all resized. Check for framebuffer completeness.
GLenum status;
bool isComplete = true;
if (!IsFramebufferComplete(drawFB, &status)) {
NS_WARNING("DrawFBO: Incomplete");
- #ifdef DEBUG
+ #ifdef MOZ_GL_DEBUG
if (DebugMode()) {
printf_stderr("Framebuffer status: %X\n", status);
}
#endif
isComplete = false;
}
if (!IsFramebufferComplete(readFB, &status)) {
NS_WARNING("ReadFBO: Incomplete");
- #ifdef DEBUG
+ #ifdef MOZ_GL_DEBUG
if (DebugMode()) {
printf_stderr("Framebuffer status: %X\n", status);
}
#endif
isComplete = false;
}
if (drawFB_out) {
@@ -2102,17 +2102,17 @@ GLContext::MarkDestroyed()
mTexGarbageBin->GLContextTeardown();
} else {
NS_WARNING("MakeCurrent() failed during MarkDestroyed! Skipping GL object teardown.");
}
mSymbols.Zero();
}
-#ifdef DEBUG
+#ifdef MOZ_GL_DEBUG
/* static */ void
GLContext::AssertNotPassingStackBufferToTheGL(const void* ptr)
{
int somethingOnTheStack;
const void* someStackPtr = &somethingOnTheStack;
const int page_bits = 12;
intptr_t page = reinterpret_cast<uintptr_t>(ptr) >> page_bits;
intptr_t someStackPage = reinterpret_cast<uintptr_t>(someStackPtr) >> page_bits;
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -21,16 +21,22 @@
#ifdef WIN32
#include <windows.h>
#endif
#ifdef GetClassName
#undef GetClassName
#endif
+// Define MOZ_GL_DEBUG unconditionally to enable GL debugging in opt
+// builds.
+#ifdef DEBUG
+#define MOZ_GL_DEBUG 1
+#endif
+
#include "mozilla/UniquePtr.h"
#include "GLDefs.h"
#include "GLLibraryLoader.h"
#include "nsISupportsImpl.h"
#include "plstr.h"
#include "nsDataHashtable.h"
#include "nsHashKeys.h"
@@ -638,39 +644,39 @@ private:
PushError(err);
}
}
////////////////////////////////////
// Use this safer option.
private:
-#ifdef DEBUG
+#ifdef MOZ_GL_DEBUG
bool mIsInLocalErrorCheck;
#endif
public:
class ScopedLocalErrorCheck {
GLContext* const mGL;
bool mHasBeenChecked;
public:
explicit ScopedLocalErrorCheck(GLContext* gl)
: mGL(gl)
, mHasBeenChecked(false)
{
-#ifdef DEBUG
+#ifdef MOZ_GL_DEBUG
MOZ_ASSERT(!mGL->mIsInLocalErrorCheck);
mGL->mIsInLocalErrorCheck = true;
#endif
mGL->GetAndPushAllErrors();
}
GLenum GetLocalError() {
-#ifdef DEBUG
+#ifdef MOZ_GL_DEBUG
MOZ_ASSERT(mGL->mIsInLocalErrorCheck);
mGL->mIsInLocalErrorCheck = false;
#endif
MOZ_ASSERT(!mHasBeenChecked);
mHasBeenChecked = true;
return mGL->GetAndClearUnpushedErrors();
@@ -699,17 +705,17 @@ private:
// -----------------------------------------------------------------------------
// MOZ_GL_DEBUG implementation
private:
#undef BEFORE_GL_CALL
#undef AFTER_GL_CALL
-#ifdef DEBUG
+#ifdef MOZ_GL_DEBUG
#ifndef MOZ_FUNCTION_NAME
# ifdef __GNUC__
# define MOZ_FUNCTION_NAME __PRETTY_FUNCTION__
# elif defined(_MSC_VER)
# define MOZ_FUNCTION_NAME __FUNCTION__
# else
# define MOZ_FUNCTION_NAME __func__ // defined in C99, supported in various C++ compilers. Just raw function name.
@@ -787,29 +793,29 @@ private:
#define TRACKING_CONTEXT(a) \
do { \
TrackingContext()->a; \
} while (0)
#define ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(ptr) AssertNotPassingStackBufferToTheGL(ptr)
-#else // ifdef DEBUG
+#else // ifdef MOZ_GL_DEBUG
#ifdef MOZ_WIDGET_ANDROID
// Record the name of the GL call for better hang stacks on Android.
#define BEFORE_GL_CALL PROFILER_LABEL_FUNC(js::ProfileEntry::Category::GRAPHICS)
#else
#define BEFORE_GL_CALL do { } while (0)
#endif
#define AFTER_GL_CALL do { } while (0)
#define TRACKING_CONTEXT(a) do {} while (0)
#define ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(ptr) do {} while (0)
-#endif // ifdef DEBUG
+#endif // ifdef MOZ_GL_DEBUG
#define ASSERT_SYMBOL_PRESENT(func) \
do {\
MOZ_ASSERT(strstr(MOZ_FUNCTION_NAME, #func) != nullptr, "Mismatched symbol check.");\
if (MOZ_UNLIKELY(!mSymbols.func)) {\
printf_stderr("RUNTIME ASSERT: Uninitialized GL function: %s\n", #func);\
MOZ_CRASH();\
}\
@@ -3195,27 +3201,27 @@ public:
// -----------------------------------------------------------------------------
// Everything that isn't standard GL APIs
protected:
typedef gfx::SurfaceFormat SurfaceFormat;
virtual bool MakeCurrentImpl(bool aForce) = 0;
public:
-#ifdef DEBUG
+#ifdef MOZ_GL_DEBUG
static void StaticInit() {
PR_NewThreadPrivateIndex(&sCurrentGLContextTLS, nullptr);
}
#endif
bool MakeCurrent(bool aForce = false) {
if (IsDestroyed()) {
return false;
}
-#ifdef DEBUG
+#ifdef MOZ_GL_DEBUG
PR_SetThreadPrivate(sCurrentGLContextTLS, this);
// XXX this assertion is disabled because it's triggering on Mac;
// we need to figure out why and reenable it.
#if 0
// IsOwningThreadCurrent is a bit of a misnomer;
// the "owning thread" is the creation thread,
// and the only thread that can own this. We don't
@@ -3380,32 +3386,32 @@ public:
DebugEnabled = 1 << 0,
DebugTrace = 1 << 1,
DebugAbortOnError = 1 << 2
};
static uint32_t sDebugMode;
static uint32_t DebugMode() {
-#ifdef DEBUG
+#ifdef MOZ_GL_DEBUG
return sDebugMode;
#else
return 0;
#endif
}
protected:
nsRefPtr<GLContext> mSharedContext;
// The thread id which this context was created.
PlatformThreadId mOwningThreadId;
GLContextSymbols mSymbols;
-#ifdef DEBUG
+#ifdef MOZ_GL_DEBUG
// GLDebugMode will check that we don't send call
// to a GLContext that isn't current on the current
// thread.
// Store the current context when binding to thread local
// storage to support DebugMode on an arbitrary thread.
static unsigned sCurrentGLContextTLS;
#endif
@@ -3636,17 +3642,17 @@ public:
mViewportRect[3] = height;
BEFORE_GL_CALL;
mSymbols.fViewport(x, y, width, height);
AFTER_GL_CALL;
}
#undef ASSERT_SYMBOL_PRESENT
-#ifdef DEBUG
+#ifdef MOZ_GL_DEBUG
void CreatedProgram(GLContext *aOrigin, GLuint aName);
void CreatedShader(GLContext *aOrigin, GLuint aName);
void CreatedBuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
void CreatedQueries(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
void CreatedTextures(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
void CreatedFramebuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
void CreatedRenderbuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
void DeletedProgram(GLContext *aOrigin, GLuint aName);
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -2,33 +2,33 @@
* vim: sw=2 ts=8 et :
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "Layers.h"
#include <algorithm> // for max, min
+#include "apz/src/AsyncPanZoomController.h"
#include "CompositableHost.h" // for CompositableHost
#include "ImageContainer.h" // for ImageContainer, etc
#include "ImageLayers.h" // for ImageLayer
#include "LayerSorter.h" // for SortLayersBy3DZOrder
#include "LayersLogging.h" // for AppendToString
#include "ReadbackLayer.h" // for ReadbackLayer
#include "gfxPlatform.h" // for gfxPlatform
#include "gfxPrefs.h"
#include "gfxUtils.h" // for gfxUtils, etc
#include "gfx2DGlue.h"
#include "mozilla/DebugOnly.h" // for DebugOnly
#include "mozilla/Telemetry.h" // for Accumulate
#include "mozilla/dom/AnimationPlayer.h" // for ComputedTimingFunction
#include "mozilla/gfx/2D.h" // for DrawTarget
#include "mozilla/gfx/BaseSize.h" // for BaseSize
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
-#include "mozilla/layers/AsyncPanZoomController.h"
#include "mozilla/layers/Compositor.h" // for Compositor
#include "mozilla/layers/CompositorTypes.h"
#include "mozilla/layers/LayerManagerComposite.h" // for LayerComposite
#include "mozilla/layers/LayerMetricsWrapper.h" // for LayerMetricsWrapper
#include "mozilla/layers/LayersMessages.h" // for TransformFunction, etc
#include "nsAString.h"
#include "nsCSSValue.h" // for nsCSSValue::Array, etc
#include "nsPrintfCString.h" // for nsPrintfCString
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -1,22 +1,22 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "APZCTreeManager.h"
+#include "AsyncPanZoomController.h"
#include "Compositor.h" // for Compositor
#include "CompositorParent.h" // for CompositorParent, etc
#include "InputData.h" // for InputData, etc
#include "Layers.h" // for Layer, etc
#include "mozilla/dom/Touch.h" // for Touch
#include "mozilla/gfx/Point.h" // for Point
#include "mozilla/layers/AsyncCompositionManager.h" // for ViewTransform
-#include "mozilla/layers/AsyncPanZoomController.h"
#include "mozilla/layers/LayerMetricsWrapper.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/mozalloc.h" // for operator new
#include "mozilla/TouchEvents.h"
#include "mozilla/Preferences.h" // for Preferences
#include "nsDebug.h" // for NS_WARNING
#include "nsPoint.h" // for nsIntPoint
#include "nsThreadUtils.h" // for NS_IsMainThread
@@ -55,16 +55,26 @@ struct APZCTreeManager::TreeBuildingStat
const uint64_t mOriginatingLayersId;
const APZPaintLogHelper mPaintLogger;
// State that is updated as we perform the tree build
nsTArray< nsRefPtr<AsyncPanZoomController> > mApzcsToDestroy;
std::map<ScrollableLayerGuid, AsyncPanZoomController*> mApzcMap;
};
+/*static*/ const LayerMargin
+APZCTreeManager::CalculatePendingDisplayPort(
+ const FrameMetrics& aFrameMetrics,
+ const ScreenPoint& aVelocity,
+ double aEstimatedPaintDuration)
+{
+ return AsyncPanZoomController::CalculatePendingDisplayPort(
+ aFrameMetrics, aVelocity, aEstimatedPaintDuration);
+}
+
APZCTreeManager::APZCTreeManager()
: mTreeLock("APZCTreeLock"),
mInOverscrolledApzc(false),
mRetainedTouchIdentifier(-1),
mTouchCount(0),
mApzcTreeLog("apzctree")
{
MOZ_ASSERT(NS_IsMainThread());
--- a/gfx/layers/apz/src/APZCTreeManager.h
+++ b/gfx/layers/apz/src/APZCTreeManager.h
@@ -232,16 +232,26 @@ public:
void ClearTree();
/**
* Tests if a screen point intersect an apz in the tree.
*/
bool HitTestAPZC(const ScreenIntPoint& aPoint);
/**
+ * See AsyncPanZoomController::CalculatePendingDisplayPort. This
+ * function simply delegates to that one, so that non-layers code
+ * never needs to include AsyncPanZoomController.h
+ */
+ static const LayerMargin CalculatePendingDisplayPort(
+ const FrameMetrics& aFrameMetrics,
+ const ScreenPoint& aVelocity,
+ double aEstimatedPaintDuration);
+
+ /**
* Set the dpi value used by all AsyncPanZoomControllers.
* DPI defaults to 72 if not set using SetDPI() at any point.
*/
static void SetDPI(float aDpiValue) { sDPI = aDpiValue; }
/**
* Returns the current dpi value in use.
*/
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -4,23 +4,25 @@
* 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 <math.h> // for fabsf, fabs, atan2
#include <stdint.h> // for uint32_t, uint64_t
#include <sys/types.h> // for int32_t
#include <algorithm> // for max, min
#include "AsyncPanZoomController.h" // for AsyncPanZoomController, etc
+#include "Axis.h" // for AxisX, AxisY, Axis, etc
#include "Compositor.h" // for Compositor
#include "CompositorParent.h" // for CompositorParent
#include "FrameMetrics.h" // for FrameMetrics, etc
#include "GestureEventListener.h" // for GestureEventListener
#include "InputData.h" // for MultiTouchInput, etc
#include "InputBlockState.h" // for InputBlockState, TouchBlockState
#include "OverscrollHandoffState.h" // for OverscrollHandoffState
+#include "TaskThrottler.h" // for TaskThrottler
#include "Units.h" // for CSSRect, CSSPoint, etc
#include "UnitTransforms.h" // for TransformTo
#include "base/message_loop.h" // for MessageLoop
#include "base/task.h" // for NewRunnableMethod, etc
#include "base/tracked.h" // for FROM_HERE
#include "gfxPrefs.h" // for gfxPrefs
#include "gfxTypes.h" // for gfxFloat
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
@@ -36,22 +38,20 @@
#include "mozilla/dom/Touch.h" // for Touch
#include "mozilla/gfx/BasePoint.h" // for BasePoint
#include "mozilla/gfx/BaseRect.h" // for BaseRect
#include "mozilla/gfx/Point.h" // for Point, RoundedToInt, etc
#include "mozilla/gfx/Rect.h" // for RoundedIn
#include "mozilla/gfx/ScaleFactor.h" // for ScaleFactor
#include "mozilla/layers/APZCTreeManager.h" // for ScrollableLayerGuid
#include "mozilla/layers/AsyncCompositionManager.h" // for ViewTransform
-#include "mozilla/layers/Axis.h" // for AxisX, AxisY, Axis, etc
#include "mozilla/layers/AxisPhysicsModel.h" // for AxisPhysicsModel
#include "mozilla/layers/AxisPhysicsMSDModel.h" // for AxisPhysicsMSDModel
#include "mozilla/layers/LayerTransactionParent.h" // for LayerTransactionParent
#include "mozilla/layers/PCompositorParent.h" // for PCompositorParent
-#include "mozilla/layers/TaskThrottler.h" // for TaskThrottler
#include "mozilla/mozalloc.h" // for operator new, etc
#include "mozilla/unused.h" // for unused
#include "mozilla/FloatingPoint.h" // for FuzzyEquals*
#include "nsAlgorithm.h" // for clamped
#include "nsAutoPtr.h" // for nsRefPtr
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsDebug.h" // for NS_WARNING
#include "nsIDOMWindowUtils.h" // for nsIDOMWindowUtils
@@ -1023,17 +1023,17 @@ nsEventStatus AsyncPanZoomController::Re
// We want to cancel animations here as soon as possible (i.e. without waiting for
// content responses) because a finger has gone down and we don't want to keep moving
// the content under the finger. However, to prevent "future" touchstart events from
// interfering with "past" animations (i.e. from a previous touch block that is still
// being processed) we only do this animation-cancellation if there are no older
// touch blocks still in the queue.
if (block == CurrentTouchBlock()) {
- if (GetVelocityVector().Length() > gfxPrefs::APZFlingStopOnTapThreshold()) {
+ if (block->GetOverscrollHandoffChain()->HasFastMovingApzc()) {
// If we're already in a fast fling, then we want the touch event to stop the fling
// and to disallow the touch event from being used as part of a fling.
block->DisallowSingleTap();
}
block->GetOverscrollHandoffChain()->CancelAnimations();
}
if (mFrameMetrics.mMayHaveTouchListeners || mFrameMetrics.mMayHaveTouchCaret) {
@@ -1771,17 +1771,17 @@ float AsyncPanZoomController::PanDistanc
ToGlobalScreenCoordinates(&panVector, panStart);
return NS_hypot(panVector.x, panVector.y);
}
ScreenPoint AsyncPanZoomController::PanStart() const {
return ScreenPoint(mX.PanStart(), mY.PanStart());
}
-const ScreenPoint AsyncPanZoomController::GetVelocityVector() {
+const ScreenPoint AsyncPanZoomController::GetVelocityVector() const {
return ScreenPoint(mX.GetVelocity(), mY.GetVelocity());
}
void AsyncPanZoomController::HandlePanningWithTouchAction(double aAngle) {
// Handling of cross sliding will need to be added in this method after touch-action released
// enabled by default.
if (CurrentTouchBlock()->TouchActionAllowsPanningXY()) {
if (mX.CanScrollNow() && mY.CanScrollNow()) {
@@ -2325,16 +2325,21 @@ bool AsyncPanZoomController::SnapBackIfO
if (IsOverscrolled()) {
APZC_LOG("%p is overscrolled, starting snap-back\n", this);
StartSnapBack();
return true;
}
return false;
}
+bool AsyncPanZoomController::IsMovingFast() const {
+ ReentrantMonitorAutoEnter lock(mMonitor);
+ return (GetVelocityVector().Length() > gfxPrefs::APZFlingStopOnTapThreshold());
+}
+
bool AsyncPanZoomController::IsPannable() const {
ReentrantMonitorAutoEnter lock(mMonitor);
return mX.CanScroll() || mY.CanScroll();
}
int32_t AsyncPanZoomController::GetLastTouchIdentifier() const {
nsRefPtr<GestureEventListener> listener = GetGestureEventListener();
return listener ? listener->GetLastTouchIdentifier() : -1;
--- a/gfx/layers/apz/src/AsyncPanZoomController.h
+++ b/gfx/layers/apz/src/AsyncPanZoomController.h
@@ -324,16 +324,22 @@ public:
bool HasScrollgrab() const { return mFrameMetrics.GetHasScrollgrab(); }
/**
* Returns whether this APZC has room to be panned (in any direction).
*/
bool IsPannable() const;
/**
+ * Returns true if the APZC has a velocity greater than the stop-on-tap
+ * fling velocity threshold (which is pref-controlled).
+ */
+ bool IsMovingFast() const;
+
+ /**
* Returns the identifier of the touch in the last touch event processed by
* this APZC. This should only be called when the last touch event contained
* only one touch.
*/
int32_t GetLastTouchIdentifier() const;
/**
* Convert the vector |aVector|, rooted at the point |aAnchor|, from
@@ -486,17 +492,17 @@ protected:
* Unlikely PanDistance(), this function returns a point in local screen
* coordinates.
*/
ScreenPoint PanStart() const;
/**
* Gets a vector of the velocities of each axis.
*/
- const ScreenPoint GetVelocityVector();
+ const ScreenPoint GetVelocityVector() const;
/**
* Gets the first touch point from a MultiTouchInput. This gets only
* the first one and assumes the rest are either missing or not relevant.
*/
ScreenPoint GetFirstTouchScreenPoint(const MultiTouchInput& aEvent);
/**
--- a/gfx/layers/apz/src/Axis.cpp
+++ b/gfx/layers/apz/src/Axis.cpp
@@ -315,17 +315,17 @@ CSSCoord Axis::ScaleWillOverscrollAmount
return (originAfterScale - GetPageStart()) / zoom;
}
if (plus) {
return (originAfterScale + (GetCompositionLength() / aScale) - GetPageEnd()) / zoom;
}
return 0;
}
-float Axis::GetVelocity() {
+float Axis::GetVelocity() const {
return mAxisLocked ? 0 : mVelocity;
}
void Axis::SetVelocity(float aVelocity) {
mVelocity = aVelocity;
}
ScreenCoord Axis::GetCompositionEnd() const {
--- a/gfx/layers/apz/src/Axis.h
+++ b/gfx/layers/apz/src/Axis.h
@@ -146,17 +146,17 @@ public:
*/
bool CanScrollNow() const;
void SetAxisLocked(bool aAxisLocked) { mAxisLocked = aAxisLocked; }
/**
* Gets the raw velocity of this axis at this moment.
*/
- float GetVelocity();
+ float GetVelocity() const;
/**
* Sets the raw velocity of this axis at this moment.
* Intended to be called only when the axis "takes over" a velocity from
* another APZC, in which case there are no touch points available to call
* UpdateWithTouchAtDevicePoint. In other circumstances,
* UpdateWithTouchAtDevicePoint should be used and the velocity calculated
* there.
--- a/gfx/layers/apz/src/OverscrollHandoffState.cpp
+++ b/gfx/layers/apz/src/OverscrollHandoffState.cpp
@@ -142,11 +142,17 @@ OverscrollHandoffChain::CanBePanned(cons
}
bool
OverscrollHandoffChain::HasOverscrolledApzc() const
{
return AnyApzc(&AsyncPanZoomController::IsOverscrolled);
}
+bool
+OverscrollHandoffChain::HasFastMovingApzc() const
+{
+ return AnyApzc(&AsyncPanZoomController::IsMovingFast);
+}
+
} // namespace layers
} // namespace mozilla
--- a/gfx/layers/apz/src/OverscrollHandoffState.h
+++ b/gfx/layers/apz/src/OverscrollHandoffState.h
@@ -103,16 +103,20 @@ public:
void SnapBackOverscrolledApzc(const AsyncPanZoomController* aStart) const;
// Determine whether the given APZC, or any APZC further in the chain,
// has room to be panned.
bool CanBePanned(const AsyncPanZoomController* aApzc) const;
// Determine whether any APZC along this handoff chain is overscrolled.
bool HasOverscrolledApzc() const;
+
+ // Determine whether any APZC along this handoff chain is moving fast.
+ bool HasFastMovingApzc() const;
+
private:
std::vector<nsRefPtr<AsyncPanZoomController>> mChain;
typedef void (AsyncPanZoomController::*APZCMethod)();
typedef bool (AsyncPanZoomController::*APZCPredicate)() const;
void ForEachApzc(APZCMethod aMethod) const;
bool AnyApzc(APZCPredicate aPredicate) const;
};
--- a/gfx/layers/basic/MacIOSurfaceTextureHostBasic.cpp
+++ b/gfx/layers/basic/MacIOSurfaceTextureHostBasic.cpp
@@ -1,15 +1,14 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "MacIOSurfaceTextureHostBasic.h"
-#include "mozilla/layers/BasicCompositor.h"
#include "mozilla/gfx/MacIOSurface.h"
namespace mozilla {
namespace layers {
MacIOSurfaceTextureSourceBasic::MacIOSurfaceTextureSourceBasic(
BasicCompositor* aCompositor,
MacIOSurface* aSurface)
--- a/gfx/layers/basic/MacIOSurfaceTextureHostBasic.h
+++ b/gfx/layers/basic/MacIOSurfaceTextureHostBasic.h
@@ -1,16 +1,17 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_GFX_MACIOSURFACETEXTUREHOST_BASIC_H
#define MOZILLA_GFX_MACIOSURFACETEXTUREHOST_BASIC_H
+#include "mozilla/layers/BasicCompositor.h"
#include "mozilla/layers/TextureHostBasic.h"
class MacIOSurface;
namespace mozilla {
namespace layers {
class BasicCompositor;
@@ -36,17 +37,17 @@ public:
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE;
virtual gfx::SourceSurface* GetSurface(gfx::DrawTarget* aTarget) MOZ_OVERRIDE;
virtual void DeallocateDeviceData() MOZ_OVERRIDE { }
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
protected:
- BasicCompositor* mCompositor;
+ RefPtr<BasicCompositor> mCompositor;
RefPtr<MacIOSurface> mSurface;
RefPtr<gfx::SourceSurface> mSourceSurface;
};
/**
* A TextureHost for shared MacIOSurface
*
* Most of the logic actually happens in MacIOSurfaceTextureSourceBasic.
@@ -75,17 +76,17 @@ public:
virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
#ifdef MOZ_LAYERS_HAVE_LOG
virtual const char* Name() { return "MacIOSurfaceTextureHostBasic"; }
#endif
protected:
- BasicCompositor* mCompositor;
+ RefPtr<BasicCompositor> mCompositor;
RefPtr<MacIOSurfaceTextureSourceBasic> mTextureSource;
RefPtr<MacIOSurface> mSurface;
};
}
}
#endif // MOZILLA_GFX_MACIOSURFACETEXTUREHOSTOGL_BASIC_H
--- a/gfx/layers/basic/X11TextureSourceBasic.cpp
+++ b/gfx/layers/basic/X11TextureSourceBasic.cpp
@@ -1,15 +1,14 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "X11TextureSourceBasic.h"
-#include "mozilla/layers/BasicCompositor.h"
#include "gfxXlibSurface.h"
#include "gfx2DGlue.h"
namespace mozilla {
namespace layers {
using namespace mozilla::gfx;
--- a/gfx/layers/basic/X11TextureSourceBasic.h
+++ b/gfx/layers/basic/X11TextureSourceBasic.h
@@ -1,16 +1,17 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_GFX_X11TEXTURESOURCEBASIC__H
#define MOZILLA_GFX_X11TEXTURESOURCEBASIC__H
+#include "mozilla/layers/BasicCompositor.h"
#include "mozilla/layers/TextureHostBasic.h"
#include "mozilla/gfx/2D.h"
namespace mozilla {
namespace layers {
class BasicCompositor;
@@ -32,17 +33,17 @@ public:
virtual void DeallocateDeviceData() MOZ_OVERRIDE { }
virtual void SetCompositor(Compositor* aCompositor);
static gfx::SurfaceFormat ContentTypeToSurfaceFormat(gfxContentType aType);
protected:
- BasicCompositor* mCompositor;
+ RefPtr<BasicCompositor> mCompositor;
RefPtr<gfxXlibSurface> mSurface;
RefPtr<gfx::SourceSurface> mSourceSurface;
};
} // namespace layers
} // namespace mozilla
#endif // MOZILLA_GFX_X11TEXTURESOURCEBASIC__H
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -210,16 +210,19 @@ TextureClient::GetIPDLActor()
{
return mActor;
}
#ifdef MOZ_WIDGET_GONK
static bool
DisableGralloc(SurfaceFormat aFormat, const gfx::IntSize& aSizeHint)
{
+ if (gfxPrefs::DisableGralloc()) {
+ return true;
+ }
if (aFormat == gfx::SurfaceFormat::A8) {
return true;
}
#if ANDROID_VERSION <= 15
// Adreno 200 has a problem of drawing gralloc buffer width less than 64 and
// drawing gralloc buffer with a height 9px-16px.
// See Bug 983971.
--- a/gfx/layers/composite/AsyncCompositionManager.cpp
+++ b/gfx/layers/composite/AsyncCompositionManager.cpp
@@ -1,29 +1,29 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=2 et tw=80 : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/layers/AsyncCompositionManager.h"
#include <stdint.h> // for uint32_t
+#include "apz/src/AsyncPanZoomController.h"
#include "CompositorParent.h" // for CompositorParent, etc
#include "FrameMetrics.h" // for FrameMetrics
#include "LayerManagerComposite.h" // for LayerManagerComposite, etc
#include "Layers.h" // for Layer, ContainerLayer, etc
#include "gfxPoint.h" // for gfxPoint, gfxSize
#include "mozilla/StyleAnimationValue.h" // for StyleAnimationValue, etc
#include "mozilla/WidgetUtils.h" // for ComputeTransformForRotation
#include "mozilla/dom/AnimationPlayer.h" // for AnimationPlayer
#include "mozilla/gfx/BaseRect.h" // for BaseRect
#include "mozilla/gfx/Point.h" // for RoundedToInt, PointTyped
#include "mozilla/gfx/Rect.h" // for RoundedToInt, RectTyped
#include "mozilla/gfx/ScaleFactor.h" // for ScaleFactor
-#include "mozilla/layers/AsyncPanZoomController.h"
#include "mozilla/layers/Compositor.h" // for Compositor
#include "mozilla/layers/LayerMetricsWrapper.h" // for LayerMetricsWrapper
#include "nsCSSPropList.h"
#include "nsCoord.h" // for NSAppUnitsToFloatPixels, etc
#include "nsDebug.h" // for NS_ASSERTION, etc
#include "nsDeviceContext.h" // for nsDeviceContext
#include "nsDisplayList.h" // for nsDisplayTransform, etc
#include "nsMathUtils.h" // for NS_round
--- a/gfx/layers/composite/CompositableHost.h
+++ b/gfx/layers/composite/CompositableHost.h
@@ -11,16 +11,17 @@
#include "gfxRect.h" // for gfxRect
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/Attributes.h" // for MOZ_OVERRIDE
#include "mozilla/RefPtr.h" // for RefPtr, RefCounted, etc
#include "mozilla/gfx/Point.h" // for Point
#include "mozilla/gfx/Rect.h" // for Rect
#include "mozilla/gfx/Types.h" // for Filter
#include "mozilla/ipc/ProtocolUtils.h"
+#include "mozilla/layers/Compositor.h" // for Compositor
#include "mozilla/layers/CompositorTypes.h" // for TextureInfo, etc
#include "mozilla/layers/Effects.h" // for Texture Effect
#include "mozilla/layers/LayersTypes.h" // for LayerRenderState, etc
#include "mozilla/layers/LayersMessages.h"
#include "mozilla/layers/TextureHost.h" // for TextureHost
#include "mozilla/mozalloc.h" // for operator delete
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsRegion.h" // for nsIntRegion
@@ -306,17 +307,17 @@ public:
virtual TemporaryRef<TexturedEffect> GenEffect(const gfx::Filter& aFilter) {
return nullptr;
}
protected:
TextureInfo mTextureInfo;
uint64_t mAsyncID;
uint64_t mCompositorID;
- Compositor* mCompositor;
+ RefPtr<Compositor> mCompositor;
Layer* mLayer;
RefPtr<CompositableBackendSpecificData> mBackendData;
uint32_t mFlashCounter; // used when the pref "layers.flash-borders" is true.
bool mAttached;
bool mKeepAttached;
};
class AutoLockCompositableHost MOZ_FINAL
--- a/gfx/layers/composite/ContainerLayerComposite.cpp
+++ b/gfx/layers/composite/ContainerLayerComposite.cpp
@@ -1,32 +1,32 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ContainerLayerComposite.h"
#include <algorithm> // for min
+#include "apz/src/AsyncPanZoomController.h" // for AsyncPanZoomController
#include "FrameMetrics.h" // for FrameMetrics
#include "Units.h" // for LayerRect, LayerPixel, etc
#include "gfx2DGlue.h" // for ToMatrix4x4
#include "gfxPrefs.h" // for gfxPrefs
#include "gfxUtils.h" // for gfxUtils, etc
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/RefPtr.h" // for RefPtr
#include "mozilla/UniquePtr.h" // for UniquePtr
#include "mozilla/gfx/BaseRect.h" // for BaseRect
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
#include "mozilla/gfx/Point.h" // for Point, IntPoint
#include "mozilla/gfx/Rect.h" // for IntRect, Rect
#include "mozilla/layers/Compositor.h" // for Compositor, etc
#include "mozilla/layers/CompositorTypes.h" // for DiagnosticFlags::CONTAINER
#include "mozilla/layers/Effects.h" // for Effect, EffectChain, etc
#include "mozilla/layers/TextureHost.h" // for CompositingRenderTarget
-#include "mozilla/layers/AsyncPanZoomController.h" // for AsyncPanZoomController
#include "mozilla/layers/AsyncCompositionManager.h" // for ViewTransform
#include "mozilla/layers/LayerMetricsWrapper.h" // for LayerMetricsWrapper
#include "mozilla/mozalloc.h" // for operator delete, etc
#include "nsAutoPtr.h" // for nsRefPtr
#include "nsDebug.h" // for NS_ASSERTION
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
#include "nsISupportsUtils.h" // for NS_ADDREF, NS_RELEASE
#include "nsPoint.h" // for nsIntPoint
--- a/gfx/layers/composite/TextureHost.h
+++ b/gfx/layers/composite/TextureHost.h
@@ -10,16 +10,17 @@
#include <stdint.h> // for uint64_t, uint32_t, uint8_t
#include "gfxTypes.h"
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/Attributes.h" // for MOZ_OVERRIDE
#include "mozilla/RefPtr.h" // for RefPtr, TemporaryRef, etc
#include "mozilla/gfx/2D.h" // for DataSourceSurface
#include "mozilla/gfx/Point.h" // for IntSize, IntPoint
#include "mozilla/gfx/Types.h" // for SurfaceFormat, etc
+#include "mozilla/layers/Compositor.h" // for Compositor
#include "mozilla/layers/CompositorTypes.h" // for TextureFlags, etc
#include "mozilla/layers/FenceUtils.h" // for FenceHandle
#include "mozilla/layers/LayersTypes.h" // for LayerRenderState, etc
#include "mozilla/mozalloc.h" // for operator delete
#include "mozilla/UniquePtr.h" // for UniquePtr
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsDebug.h" // for NS_RUNTIMEABORT
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
@@ -490,17 +491,17 @@ public:
virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE;
virtual bool HasInternalBuffer() const MOZ_OVERRIDE { return true; }
protected:
bool Upload(nsIntRegion *aRegion = nullptr);
bool MaybeUpload(nsIntRegion *aRegion = nullptr);
- Compositor* mCompositor;
+ RefPtr<Compositor> mCompositor;
RefPtr<DataTextureSource> mFirstSource;
nsIntRegion mMaybeUpdatedRegion;
gfx::IntSize mSize;
// format of the data that is shared with the content process.
gfx::SurfaceFormat mFormat;
uint32_t mUpdateSerial;
bool mLocked;
bool mNeedsFullUpdate;
@@ -625,17 +626,17 @@ public:
virtual const char* Name() { return "SharedSurfaceTextureHost"; }
#endif
protected:
void EnsureTexSource();
bool mIsLocked;
gl::SharedSurface* const mSurf;
- Compositor* mCompositor;
+ RefPtr<Compositor> mCompositor;
RefPtr<TextureSource> mTexSource;
};
class MOZ_STACK_CLASS AutoLockTextureHost
{
public:
explicit AutoLockTextureHost(TextureHost* aTexture)
: mTexture(aTexture)
--- a/gfx/layers/composite/X11TextureHost.cpp
+++ b/gfx/layers/composite/X11TextureHost.cpp
@@ -36,23 +36,23 @@ X11TextureHost::Lock()
if (!mCompositor) {
return false;
}
if (!mTextureSource) {
switch (mCompositor->GetBackendType()) {
case LayersBackend::LAYERS_BASIC:
mTextureSource =
- new X11TextureSourceBasic(static_cast<BasicCompositor*>(mCompositor),
+ new X11TextureSourceBasic(static_cast<BasicCompositor*>(mCompositor.get()),
mSurface);
break;
#ifdef GL_PROVIDER_GLX
case LayersBackend::LAYERS_OPENGL:
mTextureSource =
- new X11TextureSourceOGL(static_cast<CompositorOGL*>(mCompositor),
+ new X11TextureSourceOGL(static_cast<CompositorOGL*>(mCompositor.get()),
mSurface);
break;
#endif
default:
return false;
}
}
--- a/gfx/layers/composite/X11TextureHost.h
+++ b/gfx/layers/composite/X11TextureHost.h
@@ -40,17 +40,17 @@ public:
return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
}
#ifdef MOZ_LAYERS_HAVE_LOG
virtual const char* Name() { return "X11TextureHost"; }
#endif
protected:
- Compositor* mCompositor;
+ RefPtr<Compositor> mCompositor;
RefPtr<TextureSource> mTextureSource;
RefPtr<gfxXlibSurface> mSurface;
};
} // namespace layers
} // namespace mozilla
#endif // MOZILLA_GFX_X11TEXTUREHOST__H
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -2,16 +2,17 @@
* vim: sw=2 ts=8 et :
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "LayerTransactionParent.h"
#include <vector> // for vector
+#include "apz/src/AsyncPanZoomController.h"
#include "CompositableHost.h" // for CompositableParent, Get, etc
#include "ImageLayers.h" // for ImageLayer
#include "Layers.h" // for Layer, ContainerLayer, etc
#include "ShadowLayerParent.h" // for ShadowLayerParent
#include "CompositableTransactionParent.h" // for EditReplyVector
#include "ShadowLayersManager.h" // for ShadowLayersManager
#include "mozilla/gfx/BasePoint3D.h" // for BasePoint3D
#include "mozilla/layers/CanvasLayerComposite.h"
@@ -36,17 +37,16 @@
#include "nsISupportsImpl.h" // for Layer::Release, etc
#include "nsLayoutUtils.h" // for nsLayoutUtils
#include "nsMathUtils.h" // for NS_round
#include "nsPoint.h" // for nsPoint
#include "nsTArray.h" // for nsTArray, nsTArray_Impl, etc
#include "GeckoProfiler.h"
#include "mozilla/layers/TextureHost.h"
#include "mozilla/layers/AsyncCompositionManager.h"
-#include "mozilla/layers/AsyncPanZoomController.h"
typedef std::vector<mozilla::layers::EditReply> EditReplyVector;
using mozilla::layout::RenderFrameParent;
namespace mozilla {
namespace layers {
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -108,20 +108,16 @@ EXPORTS.gfxipc += [
'ipc/ShadowLayerUtils.h',
]
EXPORTS.mozilla.layers += [
'apz/public/GeckoContentController.h',
# exporting things from apz/src is temporary until we extract a
# proper interface for the code there
'apz/src/APZCTreeManager.h',
- 'apz/src/AsyncPanZoomController.h',
- 'apz/src/Axis.h',
- 'apz/src/GestureEventListener.h',
- 'apz/src/TaskThrottler.h',
'apz/testutil/APZTestData.h',
'apz/util/ActiveElementManager.h',
'apz/util/APZCCallbackHelper.h',
'AtomicRefCountedWithFinalize.h',
'AxisPhysicsModel.h',
'AxisPhysicsMSDModel.h',
'basic/BasicCompositor.h',
'basic/MacIOSurfaceTextureHostBasic.h',
--- a/gfx/layers/opengl/CompositingRenderTargetOGL.h
+++ b/gfx/layers/opengl/CompositingRenderTargetOGL.h
@@ -152,17 +152,22 @@ public:
private:
/**
* Actually do the initialisation. Note that we leave our FBO bound, and so
* calling this method is only suitable when about to use this render target.
*/
void InitializeImpl();
InitParams mInitParams;
- CompositorOGL* mCompositor;
+ /**
+ * There is temporary a cycle between the compositor and the render target,
+ * each having a strong ref to the other. The compositor's reference to
+ * the target is always cleared at the end of a frame.
+ */
+ RefPtr<CompositorOGL> mCompositor;
GLContext* mGL;
GLuint mTextureHandle;
GLuint mFBO;
};
}
}
--- a/gfx/layers/opengl/GrallocTextureHost.cpp
+++ b/gfx/layers/opengl/GrallocTextureHost.cpp
@@ -4,17 +4,16 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "base/process.h"
#include "GLContext.h"
#include "gfx2DGlue.h"
#include <ui/GraphicBuffer.h>
#include "GrallocImages.h" // for GrallocImage
#include "mozilla/layers/GrallocTextureHost.h"
-#include "mozilla/layers/CompositorOGL.h"
#include "mozilla/layers/SharedBufferManagerParent.h"
#include "EGLImageHelpers.h"
#include "GLReadTexImageHelper.h"
namespace mozilla {
namespace layers {
using namespace android;
--- a/gfx/layers/opengl/GrallocTextureHost.h
+++ b/gfx/layers/opengl/GrallocTextureHost.h
@@ -2,16 +2,17 @@
// * This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_GFX_GRALLOCTEXTUREHOST_H
#define MOZILLA_GFX_GRALLOCTEXTUREHOST_H
#ifdef MOZ_WIDGET_GONK
+#include "mozilla/layers/CompositorOGL.h"
#include "mozilla/layers/TextureHostOGL.h"
#include "mozilla/layers/ShadowLayerUtilsGralloc.h"
#include <ui/GraphicBuffer.h>
namespace mozilla {
namespace layers {
class GrallocTextureHostOGL;
@@ -70,17 +71,17 @@ public:
{
return mEGLImage;
}
bool Lock();
protected:
RefPtr<TextureSharedDataGonkOGL> mTextureBackendSpecificData;
- CompositorOGL* mCompositor;
+ RefPtr<CompositorOGL> mCompositor;
GrallocTextureHostOGL* mTextureHost;
android::sp<android::GraphicBuffer> mGraphicBuffer;
EGLImage mEGLImage;
GLuint mTexture;
gfx::SurfaceFormat mFormat;
bool mNeedsReset;
};
--- a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
+++ b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
@@ -1,16 +1,15 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "MacIOSurfaceTextureHostOGL.h"
#include "mozilla/gfx/MacIOSurface.h"
-#include "mozilla/layers/CompositorOGL.h"
#include "GLContextCGL.h"
namespace mozilla {
namespace layers {
MacIOSurfaceTextureHostOGL::MacIOSurfaceTextureHostOGL(TextureFlags aFlags,
const SurfaceDescriptorMacIOSurface& aDescriptor)
: TextureHost(aFlags)
--- a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.h
+++ b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.h
@@ -1,16 +1,17 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_GFX_MACIOSURFACETEXTUREHOSTOGL_H
#define MOZILLA_GFX_MACIOSURFACETEXTUREHOSTOGL_H
+#include "mozilla/layers/CompositorOGL.h"
#include "mozilla/layers/TextureHostOGL.h"
class MacIOSurface;
namespace mozilla {
namespace layers {
/**
@@ -44,17 +45,17 @@ public:
// MacIOSurfaceTextureSourceOGL doesn't own any gl texture
virtual void DeallocateDeviceData() {}
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
gl::GLContext* gl() const;
protected:
- CompositorOGL* mCompositor;
+ RefPtr<CompositorOGL> mCompositor;
RefPtr<MacIOSurface> mSurface;
};
/**
* A TextureHost for shared MacIOSurface
*
* Most of the logic actually happens in MacIOSurfaceTextureSourceOGL.
*/
@@ -87,17 +88,17 @@ public:
virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
#ifdef MOZ_LAYERS_HAVE_LOG
virtual const char* Name() { return "MacIOSurfaceTextureHostOGL"; }
#endif
protected:
- CompositorOGL* mCompositor;
+ RefPtr<CompositorOGL> mCompositor;
RefPtr<MacIOSurfaceTextureSourceOGL> mTextureSource;
RefPtr<MacIOSurface> mSurface;
};
}
}
#endif // MOZILLA_GFX_MACIOSURFACETEXTUREHOSTOGL_H
--- a/gfx/layers/opengl/TextureHostOGL.cpp
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -9,17 +9,16 @@
#include "GLContext.h" // for GLContext, etc
#include "GLLibraryEGL.h" // for GLLibraryEGL
#include "GLUploadHelpers.h"
#include "GLReadTexImageHelper.h"
#include "gfx2DGlue.h" // for ContentForFormat, etc
#include "gfxReusableSurfaceWrapper.h" // for gfxReusableSurfaceWrapper
#include "mozilla/gfx/2D.h" // for DataSourceSurface
#include "mozilla/gfx/BaseSize.h" // for BaseSize
-#include "mozilla/layers/CompositorOGL.h" // for CompositorOGL
#ifdef MOZ_WIDGET_GONK
# include "GrallocImages.h" // for GrallocImage
# include "EGLImageHelpers.h"
#endif
#include "mozilla/layers/ISurfaceAllocator.h"
#include "mozilla/layers/YCbCrImageDataSerializer.h"
#include "mozilla/layers/GrallocTextureHost.h"
#include "nsPoint.h" // for nsIntPoint
--- a/gfx/layers/opengl/TextureHostOGL.h
+++ b/gfx/layers/opengl/TextureHostOGL.h
@@ -15,16 +15,17 @@
#include "gfxTypes.h"
#include "mozilla/GfxMessageUtils.h" // for gfxContentType
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/Attributes.h" // for MOZ_OVERRIDE
#include "mozilla/RefPtr.h" // for RefPtr
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
#include "mozilla/gfx/Point.h" // for IntSize, IntPoint
#include "mozilla/gfx/Types.h" // for SurfaceFormat, etc
+#include "mozilla/layers/CompositorOGL.h" // for CompositorOGL
#include "mozilla/layers/CompositorTypes.h" // for TextureFlags
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
#include "mozilla/layers/TextureHost.h" // for TextureHost, etc
#include "mozilla/mozalloc.h" // for operator delete, etc
#include "nsAutoPtr.h" // for nsRefPtr
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsDebug.h" // for NS_WARNING
#include "nsISupportsImpl.h" // for TextureImage::Release, etc
@@ -391,17 +392,17 @@ public:
virtual void DeallocateDeviceData() MOZ_OVERRIDE {}
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
gl::GLContext* gl() const;
protected:
const gfx::IntSize mSize;
- CompositorOGL* mCompositor;
+ RefPtr<CompositorOGL> mCompositor;
const GLuint mTex;
const gfx::SurfaceFormat mFormat;
const GLenum mTextureTarget;
};