1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/testing/specialpowers/components/SpecialPowersObserver.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,178 @@ 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 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +// Based on: 1.9 +// https://bugzilla.mozilla.org/show_bug.cgi?id=549539 1.10 +// https://bug549539.bugzilla.mozilla.org/attachment.cgi?id=429661 1.11 +// https://developer.mozilla.org/en/XPCOM/XPCOM_changes_in_Gecko_1.9.3 1.12 +// http://mxr.mozilla.org/mozilla-central/source/toolkit/components/console/hudservice/HUDService.jsm#3240 1.13 +// https://developer.mozilla.org/en/how_to_build_an_xpcom_component_in_javascript 1.14 + 1.15 +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); 1.16 +Components.utils.import("resource://gre/modules/Services.jsm"); 1.17 + 1.18 +const Cc = Components.classes; 1.19 +const Ci = Components.interfaces; 1.20 + 1.21 +const CHILD_SCRIPT = "chrome://specialpowers/content/specialpowers.js" 1.22 +const CHILD_SCRIPT_API = "chrome://specialpowers/content/specialpowersAPI.js" 1.23 +const CHILD_LOGGER_SCRIPT = "chrome://specialpowers/content/MozillaLogger.js" 1.24 + 1.25 + 1.26 +// Glue to add in the observer API to this object. This allows us to share code with chrome tests 1.27 +var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] 1.28 + .getService(Components.interfaces.mozIJSSubScriptLoader); 1.29 +loader.loadSubScript("chrome://specialpowers/content/SpecialPowersObserverAPI.js"); 1.30 + 1.31 +/* XPCOM gunk */ 1.32 +this.SpecialPowersObserver = function SpecialPowersObserver() { 1.33 + this._isFrameScriptLoaded = false; 1.34 + this._mmIsGlobal = true; 1.35 + this._messageManager = Cc["@mozilla.org/globalmessagemanager;1"]. 1.36 + getService(Ci.nsIMessageBroadcaster); 1.37 +} 1.38 + 1.39 + 1.40 +SpecialPowersObserver.prototype = new SpecialPowersObserverAPI(); 1.41 + 1.42 + SpecialPowersObserver.prototype.classDescription = "Special powers Observer for use in testing."; 1.43 + SpecialPowersObserver.prototype.classID = Components.ID("{59a52458-13e0-4d93-9d85-a637344f29a1}"); 1.44 + SpecialPowersObserver.prototype.contractID = "@mozilla.org/special-powers-observer;1"; 1.45 + SpecialPowersObserver.prototype.QueryInterface = XPCOMUtils.generateQI([Components.interfaces.nsIObserver]); 1.46 + SpecialPowersObserver.prototype._xpcom_categories = [{category: "profile-after-change", service: true }]; 1.47 + 1.48 + SpecialPowersObserver.prototype.observe = function(aSubject, aTopic, aData) 1.49 + { 1.50 + switch (aTopic) { 1.51 + case "profile-after-change": 1.52 + this.init(); 1.53 + break; 1.54 + 1.55 + case "chrome-document-global-created": 1.56 + if (!this._isFrameScriptLoaded) { 1.57 + // Register for any messages our API needs us to handle 1.58 + this._messageManager.addMessageListener("SPPrefService", this); 1.59 + this._messageManager.addMessageListener("SPProcessCrashService", this); 1.60 + this._messageManager.addMessageListener("SPPingService", this); 1.61 + this._messageManager.addMessageListener("SpecialPowers.Quit", this); 1.62 + this._messageManager.addMessageListener("SpecialPowers.Focus", this); 1.63 + this._messageManager.addMessageListener("SPPermissionManager", this); 1.64 + this._messageManager.addMessageListener("SPWebAppService", this); 1.65 + this._messageManager.addMessageListener("SPObserverService", this); 1.66 + this._messageManager.addMessageListener("SPLoadChromeScript", this); 1.67 + this._messageManager.addMessageListener("SPChromeScriptMessage", this); 1.68 + 1.69 + this._messageManager.loadFrameScript(CHILD_LOGGER_SCRIPT, true); 1.70 + this._messageManager.loadFrameScript(CHILD_SCRIPT_API, true); 1.71 + this._messageManager.loadFrameScript(CHILD_SCRIPT, true); 1.72 + this._isFrameScriptLoaded = true; 1.73 + } 1.74 + break; 1.75 + 1.76 + case "http-on-modify-request": 1.77 + if (aSubject instanceof Ci.nsIChannel) { 1.78 + let uri = aSubject.URI.spec; 1.79 + this._sendAsyncMessage("specialpowers-http-notify-request", { uri: uri }); 1.80 + } 1.81 + break; 1.82 + 1.83 + case "xpcom-shutdown": 1.84 + this.uninit(); 1.85 + break; 1.86 + 1.87 + default: 1.88 + this._observe(aSubject, aTopic, aData); 1.89 + break; 1.90 + } 1.91 + }; 1.92 + 1.93 + SpecialPowersObserver.prototype._sendAsyncMessage = function(msgname, msg) 1.94 + { 1.95 + if (this._mmIsGlobal) { 1.96 + this._messageManager.broadcastAsyncMessage(msgname, msg); 1.97 + } 1.98 + else { 1.99 + this._messageManager.sendAsyncMessage(msgname, msg); 1.100 + } 1.101 + }; 1.102 + 1.103 + SpecialPowersObserver.prototype._receiveMessage = function(aMessage) { 1.104 + return this._receiveMessageAPI(aMessage); 1.105 + }; 1.106 + 1.107 + SpecialPowersObserver.prototype.init = function(messageManager) 1.108 + { 1.109 + var obs = Services.obs; 1.110 + obs.addObserver(this, "xpcom-shutdown", false); 1.111 + obs.addObserver(this, "chrome-document-global-created", false); 1.112 + obs.addObserver(this, "http-on-modify-request", false); 1.113 + 1.114 + if (messageManager) { 1.115 + this._messageManager = messageManager; 1.116 + this._mmIsGlobal = false; 1.117 + } 1.118 + }; 1.119 + 1.120 + SpecialPowersObserver.prototype.uninit = function() 1.121 + { 1.122 + var obs = Services.obs; 1.123 + obs.removeObserver(this, "chrome-document-global-created"); 1.124 + obs.removeObserver(this, "http-on-modify-request"); 1.125 + this._removeProcessCrashObservers(); 1.126 + }; 1.127 + 1.128 + SpecialPowersObserver.prototype._addProcessCrashObservers = function() { 1.129 + if (this._processCrashObserversRegistered) { 1.130 + return; 1.131 + } 1.132 + 1.133 + var obs = Components.classes["@mozilla.org/observer-service;1"] 1.134 + .getService(Components.interfaces.nsIObserverService); 1.135 + 1.136 + obs.addObserver(this, "plugin-crashed", false); 1.137 + obs.addObserver(this, "ipc:content-shutdown", false); 1.138 + this._processCrashObserversRegistered = true; 1.139 + }; 1.140 + 1.141 + SpecialPowersObserver.prototype._removeProcessCrashObservers = function() { 1.142 + if (!this._processCrashObserversRegistered) { 1.143 + return; 1.144 + } 1.145 + 1.146 + var obs = Components.classes["@mozilla.org/observer-service;1"] 1.147 + .getService(Components.interfaces.nsIObserverService); 1.148 + 1.149 + obs.removeObserver(this, "plugin-crashed"); 1.150 + obs.removeObserver(this, "ipc:content-shutdown"); 1.151 + this._processCrashObserversRegistered = false; 1.152 + }; 1.153 + 1.154 + /** 1.155 + * messageManager callback function 1.156 + * This will get requests from our API in the window and process them in chrome for it 1.157 + **/ 1.158 + SpecialPowersObserver.prototype.receiveMessage = function(aMessage) { 1.159 + switch(aMessage.name) { 1.160 + case "SPPingService": 1.161 + if (aMessage.json.op == "ping") { 1.162 + aMessage.target 1.163 + .QueryInterface(Ci.nsIFrameLoaderOwner) 1.164 + .frameLoader 1.165 + .messageManager 1.166 + .sendAsyncMessage("SPPingService", { op: "pong" }); 1.167 + } 1.168 + break; 1.169 + case "SpecialPowers.Quit": 1.170 + let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup); 1.171 + appStartup.quit(Ci.nsIAppStartup.eForceQuit); 1.172 + break; 1.173 + case "SpecialPowers.Focus": 1.174 + aMessage.target.focus(); 1.175 + break; 1.176 + default: 1.177 + return this._receiveMessage(aMessage); 1.178 + } 1.179 + }; 1.180 + 1.181 +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SpecialPowersObserver]);