☠☠ backed out by 9dfac0d146bc ☠ ☠ | |
author | Avi Halachmi <avihpit@yahoo.com> |
Tue, 27 Sep 2016 16:43:37 +0300 | |
changeset 315360 | 610b70634239c1dc46d4f5052666a09ce712601d |
parent 315359 | 866c0244a7c1a80bc82d1163217241ea079ca552 |
child 315361 | 926a610af8a723b75e0f4b5991f978f9e0d745ad |
push id | 82138 |
push user | ahalachmi@mozilla.com |
push date | Tue, 27 Sep 2016 13:43:58 +0000 |
treeherder | mozilla-inbound@14660f4f2b23 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mconley |
bugs | 1189901 |
milestone | 52.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/testing/talos/talos/talos-powers/chrome/talos-powers-content.js +++ b/testing/talos/talos/talos-powers/chrome/talos-powers-content.js @@ -1,12 +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/. */ +// This file is loaded as a framescript + var { interfaces: Ci, utils: Cu } = Components; /** * Content that wants to quit the whole session should * fire the TalosQuitApplication custom event. This will * attempt to force-quit the browser. */ addEventListener("TalosQuitApplication", event => { @@ -75,8 +77,47 @@ addEventListener("TalosPowersContentGetS detail: msg.data, }, content); content.dispatchEvent( new content.CustomEvent("TalosPowersContentGetStartupInfoResult", event)); }); }); + +/* * + * Mediator for the generic ParentExec mechanism. + * Listens for a query event from the content, forwards it as a query message + * to the parent, listens to a parent reply message, and forwards it as a reply + * event for the content to capture. + * The consumer API for this mechanism is at content/TalosPowersContent.js + * and the callees are at ParentExecServices at components/TalosPowersService.js + */ +addEventListener("TalosPowers:ParentExec:QueryEvent", function (e) { + if (content.location.protocol != "file:" && + content.location.hostname != "localhost" && + content.location.hostname != "127.0.0.1") { + throw new Error("TalosPowers:ParentExec may only be used with local content"); + } + let uniqueMessageId = "TalosPowers:ParentExec:" + + content.document.documentURI + Date.now() + Math.random(); + + // Listener for the reply from the parent process + addMessageListener("TalosPowers:ParentExec:ReplyMsg", function done(reply) { + if (reply.data.id != uniqueMessageId) + return; + + removeMessageListener("TalosPowers:ParentExec:ReplyMsg", done); + + // reply to content via an event + let contentEvent = Cu.cloneInto({ + bubbles: true, + detail: reply.data.result + }, content); + content.dispatchEvent(new content.CustomEvent(e.detail.listeningTo, contentEvent)); + }); + + // Send the query to the parent process + sendAsyncMessage("TalosPowers:ParentExec:QueryMsg", { + command: e.detail.command, + id: uniqueMessageId + }); +}, false, true); // wantsUntrusted since we're exposing to unprivileged
--- a/testing/talos/talos/talos-powers/components/TalosPowersService.js +++ b/testing/talos/talos/talos-powers/components/TalosPowersService.js @@ -36,16 +36,17 @@ TalosPowersService.prototype = { }, init() { Services.mm.loadFrameScript(FRAME_SCRIPT, true); Services.mm.addMessageListener("Talos:ForceQuit", this); Services.mm.addMessageListener("TalosContentProfiler:Command", this); Services.mm.addMessageListener("TalosPowersContent:ForceCCAndGC", this); Services.mm.addMessageListener("TalosPowersContent:GetStartupInfo", this); + Services.mm.addMessageListener("TalosPowers:ParentExec:QueryMsg", this); Services.obs.addObserver(this, "xpcom-shutdown", false); }, uninit() { Services.obs.removeObserver(this, "xpcom-shutdown", false); }, receiveMessage(message) { @@ -61,16 +62,21 @@ TalosPowersService.prototype = { case "TalosPowersContent:ForceCCAndGC": { Cu.forceGC(); Cu.forceCC(); Cu.forceShrinkingGC(); break; } case "TalosPowersContent:GetStartupInfo": { this.receiveGetStartupInfo(message); + break; + } + case "TalosPowers:ParentExec:QueryMsg": { + this.RecieveParentExecCommand(message); + break; } } }, /** * Enable the SPS profiler with some settings and then pause * immediately. * @@ -251,11 +257,48 @@ TalosPowersService.prototype = { startupInfo); }; Services.obs.addObserver(obs, "widget-first-paint", false); } else { mm.sendAsyncMessage("TalosPowersContent:GetStartupInfo:Result", startupInfo); } }, + + // These services are exposed to local unprivileged content. + // Each service is a function which accepts an argument, a callback for sending + // the reply (possibly async), and the parent window as a utility. + // arg/reply semantice are service-specific. + // To add a service: add a method at ParentExecServices here, then at the content: + // <script src="chrome://talos-powers-content/content/TalosPowersContent.js"></script> + // and then e.g. TalosPowersParent.exec("sampleParentService", myArg, myCallback) + // Sample service: + /* + // arg: anything. return: sample reply + sampleParentService: function(arg, callback, win) { + win.setTimeout(function() { + callback("sample reply for: " + arg); + }, 500); + }, + + */ + ParentExecServices: { + }, + + RecieveParentExecCommand(msg) { + function sendResult(result) { + let mm = msg.target.messageManager; + mm.sendAsyncMessage("TalosPowers:ParentExec:ReplyMsg", { + id: msg.data.id, + result: result + }); + } + + let command = msg.data.command; + if (!this.ParentExecServices.hasOwnProperty(command.name)) + throw new Error("TalosPowers:ParentExec: Invalid service '" + command.name + "'"); + + this.ParentExecServices[command.name](command.data, sendResult, msg.target.ownerGlobal); + }, + }; this.NSGetFactory = XPCOMUtils.generateNSGetFactory([TalosPowersService]);
--- a/testing/talos/talos/talos-powers/content/TalosPowersContent.js +++ b/testing/talos/talos/talos-powers/content/TalosPowersContent.js @@ -1,13 +1,20 @@ /* 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 file should be executed by the [possibly unprivileged] consumer, e.g.: +// <script src="chrome://talos-powers-content/content/TalosPowersContent.js"></script> +// and then e.g. TalosPowersParent.exec("sampleParentService", myArg, myCallback) +// It marely sends a query event and possibly listens to a reply event, and does not +// depend on any special privileges. + var TalosPowersContent; +var TalosPowersParent; (function() { TalosPowersContent = { /** * Synchronously force CC and GC in this process, as well as in the * parent process. */ forceCCAndGC() { @@ -40,9 +47,45 @@ var TalosPowersContent; function onResult(e) { removeEventListener("TalosPowersContentGetStartupInfoResult", onResult); resolve(e.detail); }); }); }, }; + + /** + * Generic interface to service functions which run at the parent process. + */ + // If including this script proves too much touble, you may embed the following + // code verbatim instead, and keep the copy up to date with its source here: + TalosPowersParent = { + replyId: 1, + + // dispatch an event to the framescript and register the result/callback event + exec: function(commandName, arg, callback, opt_custom_window) { + let win = opt_custom_window || window; + let replyEvent = "TalosPowers:ParentExec:ReplyEvent:" + this.replyId++; + if (callback) { + win.addEventListener(replyEvent, function rvhandler(e) { + win.removeEventListener(replyEvent, rvhandler); + callback(e.detail); + }); + } + win.dispatchEvent( + new win.CustomEvent("TalosPowers:ParentExec:QueryEvent", { + bubbles: true, + detail: { + command: { + name: commandName, + data: arg, + }, + listeningTo: replyEvent, + } + }) + ); + }, + + }; + // End of possibly embedded code + })();