/* 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/. */ const Cm = Components.manager; const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); var OnRefTestLoad, OnRefTestUnload; XPCOMUtils.defineLazyServiceGetter(this, "resProto", "@mozilla.org/network/protocol;1?name=resource", "nsISubstitutingProtocolHandler"); XPCOMUtils.defineLazyServiceGetter(this, "aomStartup", "@mozilla.org/addons/addon-manager-startup;1", "amIAddonManagerStartup"); function processTerminated() { return new Promise(resolve => { Services.obs.addObserver(function observe(subject, topic) { if (topic == "ipc:content-shutdown") { Services.obs.removeObserver(observe, topic); resolve(); } }, "ipc:content-shutdown"); }); } function startAndroid(win) { // Add setTimeout here because windows.innerWidth/Height are not set yet. win.setTimeout(function() {OnRefTestLoad(win);}, 0); } var WindowListener = { onOpenWindow: function(xulWin) { Services.wm.removeListener(WindowListener); let win = xulWin.docShell.domWindow; win.addEventListener("load", function listener() { // Load into any existing windows. for (win of Services.wm.getEnumerator("navigator:browser")) { break; } win.addEventListener("pageshow", function() { startAndroid(win); }, {once: true}); }, {once: true}); } }; this.reftest = class extends ExtensionAPI { onStartup() { let uri = Services.io.newURI("chrome/reftest/res/", null, this.extension.rootURI); resProto.setSubstitutionWithFlags("reftest", uri, resProto.ALLOW_CONTENT_ACCESS); const manifestURI = Services.io.newURI("manifest.json", null, this.extension.rootURI); this.chromeHandle = aomStartup.registerChrome(manifestURI, [ ["content", "reftest", "chrome/reftest/content/", "contentaccessible=yes"], ]); // Starting tests is handled quite differently on android and desktop. // On Android, OnRefTestLoad() takes over the main browser window so // we just need to call it as soon as the browser window is available. // On desktop, a separate window (dummy) is created and explicitly given // focus (see bug 859339 for details), then tests are launched in a new // top-level window. let win = Services.wm.getMostRecentWindow("navigator:browser"); if (!win) { // There is no navigator:browser in the geckoview TestRunnerActivity; // try navigator.geckoview instead. win = Services.wm.getMostRecentWindow("navigator:geckoview"); } if (Services.appinfo.OS == "Android") { ({OnRefTestLoad, OnRefTestUnload} = ChromeUtils.import("resource://reftest/reftest.jsm")); if (win) { startAndroid(win); } else { Services.wm.addListener(WindowListener); } return; } Services.io.manageOfflineStatus = false; Services.io.offline = false; let dummy = Services.ww.openWindow(null, "about:blank", "dummy", "chrome,dialog=no,left=800,height=200,width=200,all",null); dummy.onload = async function() { // Close pre-existing window win.close(); const {PerTestCoverageUtils} = ChromeUtils.import("resource://reftest/PerTestCoverageUtils.jsm"); if (PerTestCoverageUtils.enabled) { // In PerTestCoverage mode, wait for the process belonging to the window we just closed // to be terminated, to avoid its shutdown interfering when we reset the counters. await processTerminated(); } dummy.focus(); Services.ww.openWindow(null, "chrome://reftest/content/reftest.xul", "_blank", "chrome,dialog=no,all", {}); }; } onShutdown() { resProto.setSubstitution("reftest", null); this.chromeHandle.destruct(); this.chromeHandle = null; if (Services.appinfo.OS == "Android") { Services.wm.removeListener(WindowListener); OnRefTestUnload(); Cu.unload("resource://reftest/reftest.jsm"); } } };