1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/testing/marionette/components/marionettecomponent.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,185 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +this.CC = Components.Constructor; 1.9 +this.Cc = Components.classes; 1.10 +this.Ci = Components.interfaces; 1.11 +this.Cu = Components.utils; 1.12 + 1.13 +const MARIONETTE_CONTRACTID = "@mozilla.org/marionette;1"; 1.14 +const MARIONETTE_CID = Components.ID("{786a1369-dca5-4adc-8486-33d23c88010a}"); 1.15 +const MARIONETTE_ENABLED_PREF = 'marionette.defaultPrefs.enabled'; 1.16 +const MARIONETTE_FORCELOCAL_PREF = 'marionette.force-local'; 1.17 +const MARIONETTE_LOG_PREF = 'marionette.logging'; 1.18 + 1.19 +this.ServerSocket = CC("@mozilla.org/network/server-socket;1", 1.20 + "nsIServerSocket", 1.21 + "initSpecialConnection"); 1.22 + 1.23 +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); 1.24 +Cu.import("resource://gre/modules/Services.jsm"); 1.25 +Cu.import("resource://gre/modules/FileUtils.jsm"); 1.26 +Cu.import("resource://gre/modules/Log.jsm"); 1.27 + 1.28 +let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"] 1.29 + .getService(Ci.mozIJSSubScriptLoader); 1.30 + 1.31 +function MarionetteComponent() { 1.32 + this._loaded = false; 1.33 + this.observerService = Services.obs; 1.34 + 1.35 + // set up the logger 1.36 + this.logger = Log.repository.getLogger("Marionette"); 1.37 + this.logger.level = Log.Level["Trace"]; 1.38 + let dumper = false; 1.39 +#ifdef DEBUG 1.40 + dumper = true; 1.41 +#endif 1.42 +#ifdef MOZ_B2G 1.43 + dumper = true; 1.44 +#endif 1.45 + try { 1.46 + if (dumper || Services.prefs.getBoolPref(MARIONETTE_LOG_PREF)) { 1.47 + let formatter = new Log.BasicFormatter(); 1.48 + this.logger.addAppender(new Log.DumpAppender(formatter)); 1.49 + } 1.50 + } 1.51 + catch(e) {} 1.52 +} 1.53 + 1.54 +MarionetteComponent.prototype = { 1.55 + classDescription: "Marionette component", 1.56 + classID: MARIONETTE_CID, 1.57 + contractID: MARIONETTE_CONTRACTID, 1.58 + QueryInterface: XPCOMUtils.generateQI([Ci.nsICommandLineHandler, Ci.nsIObserver]), 1.59 + _xpcom_categories: [{category: "command-line-handler", entry: "b-marionette"}, 1.60 + {category: "profile-after-change", service: true}], 1.61 + appName: Services.appinfo.name, 1.62 + enabled: false, 1.63 + finalUiStartup: false, 1.64 + _marionetteServer: null, 1.65 + 1.66 + onSocketAccepted: function mc_onSocketAccepted(aSocket, aTransport) { 1.67 + this.logger.info("onSocketAccepted for Marionette dummy socket"); 1.68 + }, 1.69 + 1.70 + onStopListening: function mc_onStopListening(aSocket, status) { 1.71 + this.logger.info("onStopListening for Marionette dummy socket, code " + status); 1.72 + aSocket.close(); 1.73 + }, 1.74 + 1.75 + // Check cmdLine argument for --marionette 1.76 + handle: function mc_handle(cmdLine) { 1.77 + // If the CLI is there then lets do work otherwise nothing to see 1.78 + if (cmdLine.handleFlag("marionette", false)) { 1.79 + this.enabled = true; 1.80 + this.logger.info("marionette enabled via command-line"); 1.81 + this.init(); 1.82 + } 1.83 + }, 1.84 + 1.85 + observe: function mc_observe(aSubject, aTopic, aData) { 1.86 + switch (aTopic) { 1.87 + case "profile-after-change": 1.88 + // Using final-ui-startup as the xpcom category doesn't seem to work, 1.89 + // so we wait for that by adding an observer here. 1.90 + this.observerService.addObserver(this, "final-ui-startup", false); 1.91 +#ifdef ENABLE_MARIONETTE 1.92 + let enabledPref = false; 1.93 + try { 1.94 + enabledPref = Services.prefs.getBoolPref(MARIONETTE_ENABLED_PREF); 1.95 + } catch(e) {} 1.96 + if (enabledPref) { 1.97 + this.enabled = true; 1.98 + this.logger.info("marionette enabled via build flag and pref"); 1.99 + 1.100 + // We want to suppress the modal dialog that's shown 1.101 + // when starting up in safe-mode to enable testing. 1.102 + if (Services.appinfo.inSafeMode) { 1.103 + this.observerService.addObserver(this, "domwindowopened", false); 1.104 + } 1.105 + } 1.106 +#endif 1.107 + break; 1.108 + case "final-ui-startup": 1.109 + this.finalUiStartup = true; 1.110 + this.observerService.removeObserver(this, aTopic); 1.111 + this.observerService.addObserver(this, "xpcom-shutdown", false); 1.112 + this.init(); 1.113 + break; 1.114 + case "domwindowopened": 1.115 + this.observerService.removeObserver(this, aTopic); 1.116 + this._suppressSafeModeDialog(aSubject); 1.117 + break; 1.118 + case "xpcom-shutdown": 1.119 + this.observerService.removeObserver(this, "xpcom-shutdown"); 1.120 + this.uninit(); 1.121 + break; 1.122 + } 1.123 + }, 1.124 + 1.125 + _suppressSafeModeDialog: function mc_suppressSafeModeDialog(aWindow) { 1.126 + // Wait for the modal dialog to finish loading. 1.127 + aWindow.addEventListener("load", function onLoad() { 1.128 + aWindow.removeEventListener("load", onLoad); 1.129 + 1.130 + if (aWindow.document.getElementById("safeModeDialog")) { 1.131 + aWindow.setTimeout(() => { 1.132 + // Accept the dialog to start in safe-mode. 1.133 + aWindow.document.documentElement.getButton("accept").click(); 1.134 + }); 1.135 + } 1.136 + }); 1.137 + }, 1.138 + 1.139 + init: function mc_init() { 1.140 + if (!this._loaded && this.enabled && this.finalUiStartup) { 1.141 + this._loaded = true; 1.142 + 1.143 + let marionette_forcelocal = this.appName == 'B2G' ? false : true; 1.144 + try { 1.145 + marionette_forcelocal = Services.prefs.getBoolPref(MARIONETTE_FORCELOCAL_PREF); 1.146 + } 1.147 + catch(e) {} 1.148 + Services.prefs.setBoolPref(MARIONETTE_FORCELOCAL_PREF, marionette_forcelocal); 1.149 + 1.150 + if (!marionette_forcelocal) { 1.151 + // See bug 800138. Because the first socket that opens with 1.152 + // force-local=false fails, we open a dummy socket that will fail. 1.153 + // keepWhenOffline=true so that it still work when offline (local). 1.154 + // This allows the following attempt by Marionette to open a socket 1.155 + // to succeed. 1.156 + let insaneSacrificialGoat = new ServerSocket(666, Ci.nsIServerSocket.KeepWhenOffline, 4); 1.157 + insaneSacrificialGoat.asyncListen(this); 1.158 + } 1.159 + 1.160 + let port; 1.161 + try { 1.162 + port = Services.prefs.getIntPref('marionette.defaultPrefs.port'); 1.163 + } 1.164 + catch(e) { 1.165 + port = 2828; 1.166 + } 1.167 + try { 1.168 + loader.loadSubScript("chrome://marionette/content/marionette-server.js"); 1.169 + let forceLocal = Services.prefs.getBoolPref(MARIONETTE_FORCELOCAL_PREF); 1.170 + this._marionetteServer = new MarionetteServer(port, forceLocal); 1.171 + this.logger.info("Marionette server ready"); 1.172 + } 1.173 + catch(e) { 1.174 + this.logger.error('exception: ' + e.name + ', ' + e.message); 1.175 + } 1.176 + } 1.177 + }, 1.178 + 1.179 + uninit: function mc_uninit() { 1.180 + if (this._marionetteServer) { 1.181 + this._marionetteServer.closeListener(); 1.182 + } 1.183 + this._loaded = false; 1.184 + }, 1.185 + 1.186 +}; 1.187 + 1.188 +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([MarionetteComponent]);