Bug 1423282 - Drop MarionetteFrame:getInterruptedState IPC message. r=automatedtester,maja_zf

MarionetteFrame:getInterruptedState was used in B2G to abortence
if the OOP frame got interrupted by a modal dialogue.  Like the
MarionetteFrame:handleModal IPC message, the frame script needed
chrome assistance for querying the presence of this dialogue.

Today modal dialogues (known as "user prompts") are handled entirely
in chrome space, and the presence of such a dialogue is indeed
meant to pause script execution in the web document.

This patch makes some rather questionable changes to the legacyaction
module, but this is alright because we don't expect any more tests to
be written using it.  This patch just about makes sure the remaining
body of tests keeps passing.

MozReview-Commit-ID: 72g0GlYy21T

--HG--
extra : rebase_source : f44ed5999554a42c67827d6935bd96cc79a8e5dd
This commit is contained in:
Andreas Tolfsen 2017-12-05 19:22:53 +00:00
Родитель 79058696cd
Коммит f42cdc3940
3 изменённых файлов: 74 добавлений и 145 удалений

Просмотреть файл

@ -4,7 +4,7 @@
"use strict"; "use strict";
const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components; const {interfaces: Ci, results: Cr, utils: Cu} = Components;
Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm");
@ -51,8 +51,6 @@ frame.Manager = class {
this.currentRemoteFrame = null; this.currentRemoteFrame = null;
// frame we'll need to restore once interrupt is gone // frame we'll need to restore once interrupt is gone
this.previousRemoteFrame = null; this.previousRemoteFrame = null;
// set to true when we have been interrupted by a modal
this.handledModal = false;
this.driver = driver; this.driver = driver;
} }
@ -62,32 +60,6 @@ frame.Manager = class {
/*eslint-disable*/ /*eslint-disable*/
receiveMessage(message) { receiveMessage(message) {
switch (message.name) { switch (message.name) {
case "MarionetteFrame:getInterruptedState":
// this will return true if the calling frame was interrupted by a modal dialog
if (this.previousRemoteFrame) {
// get the frame window of the interrupted frame
let interruptedFrame = Services.wm.getOuterWindowWithId(
this.previousRemoteFrame.windowId);
if (this.previousRemoteFrame.frameId !== null) {
// find OOP frame
let iframes = interruptedFrame.document.getElementsByTagName("iframe");
interruptedFrame = iframes[this.previousRemoteFrame.frameId];
}
// check if the interrupted frame is the same as the calling frame
if (interruptedFrame.src == message.target.src) {
return {value: this.handledModal};
}
// we get here if previousRemoteFrame and currentRemoteFrame are null,
// i.e. if we're in a non-OOP process, or we haven't switched into an OOP frame,
// in which case, handledModal can't be set to true
} else if (this.currentRemoteFrame === null) {
return {value: this.handledModal};
}
return {value: false};
case "MarionetteFrame:getCurrentFrameId": case "MarionetteFrame:getCurrentFrameId":
if (this.currentRemoteFrame !== null) { if (this.currentRemoteFrame !== null) {
return this.currentRemoteFrame.frameId; return this.currentRemoteFrame.frameId;
@ -156,9 +128,7 @@ frame.Manager = class {
/** /**
* Adds message listeners to the driver, listening for * Adds message listeners to the driver, listening for
* messages from content frame scripts. It also adds a * messages from content frame scripts.
* MarionetteFrame:getInterruptedState message listener to the
* FrameManager, so the frame manager's state can be checked by the frame.
* *
* @param {nsIMessageListenerManager} mm * @param {nsIMessageListenerManager} mm
* The message manager object, typically * The message manager object, typically
@ -175,14 +145,10 @@ frame.Manager = class {
mm.addWeakMessageListener("Marionette:listenersAttached", this.driver); mm.addWeakMessageListener("Marionette:listenersAttached", this.driver);
mm.addWeakMessageListener("Marionette:GetLogLevel", this.driver); mm.addWeakMessageListener("Marionette:GetLogLevel", this.driver);
mm.addWeakMessageListener("MarionetteFrame:getCurrentFrameId", this); mm.addWeakMessageListener("MarionetteFrame:getCurrentFrameId", this);
mm.addWeakMessageListener("MarionetteFrame:getInterruptedState", this);
} }
/** /**
* Removes listeners for messages from content frame scripts. * Removes listeners for messages from content frame scripts.
* We do not remove the MarionetteFrame:getInterruptedState
* message listener, because we want to allow all known frames to
* contact the frame manager so that it can check if it was interrupted.
* *
* @param {nsIMessageListenerManager} mm * @param {nsIMessageListenerManager} mm
* The message manager object, typically * The message manager object, typically

Просмотреть файл

@ -27,7 +27,7 @@ this.legacyaction = this.action = {};
/** /**
* Functionality for (single finger) action chains. * Functionality for (single finger) action chains.
*/ */
action.Chain = function (checkForInterrupted) { action.Chain = function() {
// for assigning unique ids to all touches // for assigning unique ids to all touches
this.nextTouchId = 1000; this.nextTouchId = 1000;
// keep track of active Touches // keep track of active Touches
@ -40,12 +40,6 @@ action.Chain = function (checkForInterrupted) {
this.mouseEventsOnly = false; this.mouseEventsOnly = false;
this.checkTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); this.checkTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
if (typeof checkForInterrupted == "function") {
this.checkForInterrupted = checkForInterrupted;
} else {
this.checkForInterrupted = () => {};
}
// determines if we create touch events // determines if we create touch events
this.inputSource = null; this.inputSource = null;
}; };
@ -111,35 +105,33 @@ action.Chain.prototype.emitMouseEvent = function (
button, button,
clickCount, clickCount,
modifiers) { modifiers) {
if (!this.checkForInterrupted()) { logger.debug(`Emitting ${type} mouse event ` +
logger.debug(`Emitting ${type} mouse event ` + `at coordinates (${elClientX}, ${elClientY}) ` +
`at coordinates (${elClientX}, ${elClientY}) ` + `relative to the viewport, ` +
`relative to the viewport, ` + `button: ${button}, ` +
`button: ${button}, ` + `clickCount: ${clickCount}`);
`clickCount: ${clickCount}`);
let win = doc.defaultView; let win = doc.defaultView;
let domUtils = win.QueryInterface(Ci.nsIInterfaceRequestor) let domUtils = win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils); .getInterface(Ci.nsIDOMWindowUtils);
let mods; let mods;
if (typeof modifiers != "undefined") { if (typeof modifiers != "undefined") {
mods = event.parseModifiers_(modifiers); mods = event.parseModifiers_(modifiers);
} else { } else {
mods = 0; mods = 0;
}
domUtils.sendMouseEvent(
type,
elClientX,
elClientY,
button || 0,
clickCount || 1,
mods,
false,
0,
this.inputSource);
} }
domUtils.sendMouseEvent(
type,
elClientX,
elClientY,
button || 0,
clickCount || 1,
mods,
false,
0,
this.inputSource);
}; };
/** /**
@ -476,7 +468,6 @@ action.Chain.prototype.generateEvents = function (
default: default:
throw new WebDriverError("Unknown event type: " + type); throw new WebDriverError("Unknown event type: " + type);
} }
this.checkForInterrupted();
}; };
action.Chain.prototype.mouseTap = function (doc, x, y, button, count, mod) { action.Chain.prototype.mouseTap = function (doc, x, y, button, count, mod) {

Просмотреть файл

@ -49,8 +49,6 @@ Cu.importGlobalProperties(["URL"]);
let listenerId = null; // unique ID of this listener let listenerId = null; // unique ID of this listener
let curContainer = {frame: content, shadowRoot: null}; let curContainer = {frame: content, shadowRoot: null};
let previousContainer = null;
// Listen for click event to indicate one click has happened, so actions // Listen for click event to indicate one click has happened, so actions
// code can send dblclick event, also resetClick and cancelTimer // code can send dblclick event, also resetClick and cancelTimer
@ -73,7 +71,7 @@ const SUPPORTED_STRATEGIES = new Set([
let capabilities; let capabilities;
let legacyactions = new legacyaction.Chain(checkForInterrupted); let legacyactions = new legacyaction.Chain();
// last touch for each fingerId // last touch for each fingerId
let multiLast = {}; let multiLast = {};
@ -719,30 +717,6 @@ function resetValues() {
action.inputsToCancel = []; action.inputsToCancel = [];
} }
function wasInterrupted() {
if (previousContainer) {
let element = content.document.elementFromPoint(
(content.innerWidth / 2), (content.innerHeight / 2));
if (element.id.indexOf("modal-dialog") == -1) {
return true;
}
return false;
}
return sendSyncMessage("MarionetteFrame:getInterruptedState", {})[0].value;
}
function checkForInterrupted() {
if (wasInterrupted()) {
// if previousContainer is set, then we're in a single process
// environment
if (previousContainer) {
curContainer = legacyactions.container = previousContainer;
previousContainer = null;
}
sendSyncMessage("Marionette:switchedToFrame", {restorePrevious: true});
}
}
async function execute(script, args, timeout, opts) { async function execute(script, args, timeout, opts) {
opts.timeout = timeout; opts.timeout = timeout;
let sb = sandbox.createMutable(curContainer.frame); let sb = sandbox.createMutable(curContainer.frame);
@ -756,58 +730,56 @@ async function executeInSandbox(script, args, timeout, opts) {
} }
function emitTouchEvent(type, touch) { function emitTouchEvent(type, touch) {
if (!wasInterrupted()) { logger.info(`Emitting Touch event of type ${type} ` +
logger.info(`Emitting Touch event of type ${type} ` + `to element with id: ${touch.target.id} ` +
`to element with id: ${touch.target.id} ` + `and tag name: ${touch.target.tagName} ` +
`and tag name: ${touch.target.tagName} ` + `at coordinates (${touch.clientX}), ` +
`at coordinates (${touch.clientX}), ` + `${touch.clientY}) relative to the viewport`);
`${touch.clientY}) relative to the viewport`);
const win = curContainer.frame; const win = curContainer.frame;
let docShell = win.QueryInterface(Ci.nsIInterfaceRequestor) let docShell = win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation) .getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell); .QueryInterface(Ci.nsIDocShell);
if (docShell.asyncPanZoomEnabled && legacyactions.scrolling) { if (docShell.asyncPanZoomEnabled && legacyactions.scrolling) {
// if we're in APZ and we're scrolling, we must use // if we're in APZ and we're scrolling, we must use
// sendNativeTouchPoint to dispatch our touchmove events // sendNativeTouchPoint to dispatch our touchmove events
let index = sendSyncMessage("MarionetteFrame:getCurrentFrameId"); let index = sendSyncMessage("MarionetteFrame:getCurrentFrameId");
// only call emitTouchEventForIFrame if we're inside an iframe. // only call emitTouchEventForIFrame if we're inside an iframe.
if (index != null) { if (index != null) {
let ev = { let ev = {
index, index,
type,
id: touch.identifier,
clientX: touch.clientX,
clientY: touch.clientY,
screenX: touch.screenX,
screenY: touch.screenY,
radiusX: touch.radiusX,
radiusY: touch.radiusY,
rotation: touch.rotationAngle,
force: touch.force,
};
sendSyncMessage("Marionette:emitTouchEvent", ev);
return;
}
}
// we get here if we're not in asyncPacZoomEnabled land, or if we're
// the main process
let domWindowUtils = win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
domWindowUtils.sendTouchEvent(
type, type,
[touch.identifier], id: touch.identifier,
[touch.clientX], clientX: touch.clientX,
[touch.clientY], clientY: touch.clientY,
[touch.radiusX], screenX: touch.screenX,
[touch.radiusY], screenY: touch.screenY,
[touch.rotationAngle], radiusX: touch.radiusX,
[touch.force], radiusY: touch.radiusY,
1, rotation: touch.rotationAngle,
0); force: touch.force,
};
sendSyncMessage("Marionette:emitTouchEvent", ev);
return;
}
} }
// we get here if we're not in asyncPacZoomEnabled land, or if we're
// the main process
let domWindowUtils = win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
domWindowUtils.sendTouchEvent(
type,
[touch.identifier],
[touch.clientX],
[touch.clientY],
[touch.radiusX],
[touch.radiusY],
[touch.rotationAngle],
[touch.force],
1,
0);
} }
/** /**