michael@0: /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: "use strict"; michael@0: michael@0: const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; michael@0: michael@0: Cu.import("resource://gre/modules/XPCOMUtils.jsm"); michael@0: Cu.import("resource://gre/modules/Services.jsm"); michael@0: Cu.import("resource://gre/modules/DOMRequestHelper.jsm"); michael@0: michael@0: const DEBUG = false; // set to false to suppress debug messages michael@0: michael@0: const DOMWIFIMANAGER_CONTRACTID = "@mozilla.org/wifimanager;1"; michael@0: const DOMWIFIMANAGER_CID = Components.ID("{c9b5f09e-25d2-40ca-aef4-c4d13d93c706}"); michael@0: michael@0: function MozWifiNetwork() { michael@0: } michael@0: michael@0: MozWifiNetwork.prototype = { michael@0: michael@0: init: function(aWindow) { michael@0: this._window = aWindow; michael@0: }, michael@0: michael@0: __init: function(obj) { michael@0: for (let key in obj) { michael@0: this[key] = obj[key]; michael@0: } michael@0: }, michael@0: michael@0: classID: Components.ID("{c01fd751-43c0-460a-8b64-abf652ec7220}"), michael@0: contractID: "@mozilla.org/mozwifinetwork;1", michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, michael@0: Ci.nsIDOMGlobalPropertyInitializer]) michael@0: }; michael@0: michael@0: function MozWifiConnection(obj) { michael@0: this.status = obj.status; michael@0: this.network = obj.network; michael@0: } michael@0: michael@0: MozWifiConnection.prototype = { michael@0: classID: Components.ID("{23579da4-201b-4319-bd42-9b7f337343ac}"), michael@0: contractID: "@mozilla.org/mozwificonnection;1", michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]) michael@0: }; michael@0: michael@0: function MozWifiConnectionInfo(obj) { michael@0: this.signalStrength = obj.signalStrength; michael@0: this.relSignalStrength = obj.relSignalStrength; michael@0: this.linkSpeed = obj.linkSpeed; michael@0: this.ipAddress = obj.ipAddress; michael@0: } michael@0: michael@0: MozWifiConnectionInfo.prototype = { michael@0: classID: Components.ID("{83670352-6ed4-4c35-8de9-402296a1959c}"), michael@0: contractID: "@mozilla.org/mozwificonnectioninfo;1", michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]) michael@0: } michael@0: michael@0: function DOMWifiManager() { michael@0: this.defineEventHandlerGetterSetter("onstatuschange"); michael@0: this.defineEventHandlerGetterSetter("onconnectionInfoUpdate"); michael@0: this.defineEventHandlerGetterSetter("onenabled"); michael@0: this.defineEventHandlerGetterSetter("ondisabled"); michael@0: } michael@0: michael@0: DOMWifiManager.prototype = { michael@0: __proto__: DOMRequestIpcHelper.prototype, michael@0: classDescription: "DOMWifiManager", michael@0: classID: DOMWIFIMANAGER_CID, michael@0: contractID: DOMWIFIMANAGER_CONTRACTID, michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer, michael@0: Ci.nsISupportsWeakReference, michael@0: Ci.nsIObserver]), michael@0: michael@0: // nsIDOMGlobalPropertyInitializer implementation michael@0: init: function(aWindow) { michael@0: // Maintain this state for synchronous APIs. michael@0: this._currentNetwork = null; michael@0: this._connectionStatus = "disconnected"; michael@0: this._enabled = false; michael@0: this._lastConnectionInfo = null; michael@0: michael@0: const messages = ["WifiManager:getNetworks:Return:OK", "WifiManager:getNetworks:Return:NO", michael@0: "WifiManager:getKnownNetworks:Return:OK", "WifiManager:getKnownNetworks:Return:NO", michael@0: "WifiManager:associate:Return:OK", "WifiManager:associate:Return:NO", michael@0: "WifiManager:forget:Return:OK", "WifiManager:forget:Return:NO", michael@0: "WifiManager:wps:Return:OK", "WifiManager:wps:Return:NO", michael@0: "WifiManager:setPowerSavingMode:Return:OK", "WifiManager:setPowerSavingMode:Return:NO", michael@0: "WifiManager:setHttpProxy:Return:OK", "WifiManager:setHttpProxy:Return:NO", michael@0: "WifiManager:setStaticIpMode:Return:OK", "WifiManager:setStaticIpMode:Return:NO", michael@0: "WifiManager:wifiDown", "WifiManager:wifiUp", michael@0: "WifiManager:onconnecting", "WifiManager:onassociate", michael@0: "WifiManager:onconnect", "WifiManager:ondisconnect", michael@0: "WifiManager:onwpstimeout", "WifiManager:onwpsfail", michael@0: "WifiManager:onwpsoverlap", "WifiManager:connectionInfoUpdate", michael@0: "WifiManager:onconnectingfailed"]; michael@0: this.initDOMRequestHelper(aWindow, messages); michael@0: this._mm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsISyncMessageSender); michael@0: michael@0: var state = this._mm.sendSyncMessage("WifiManager:getState")[0]; michael@0: if (state) { michael@0: this._currentNetwork = this._convertWifiNetwork(state.network); michael@0: this._lastConnectionInfo = this._convertConnectionInfo(state.connectionInfo); michael@0: this._enabled = state.enabled; michael@0: this._connectionStatus = state.status; michael@0: this._macAddress = state.macAddress; michael@0: } else { michael@0: this._currentNetwork = null; michael@0: this._lastConnectionInfo = null; michael@0: this._enabled = false; michael@0: this._connectionStatus = "disconnected"; michael@0: this._macAddress = ""; michael@0: } michael@0: }, michael@0: michael@0: _convertWifiNetworkToJSON: function(aNetwork) { michael@0: let json = {}; michael@0: michael@0: for (let key in aNetwork) { michael@0: // In WifiWorker.js there are lots of check using "key in network". michael@0: // So if the value of any property of WifiNetwork is undefined, do not clone it. michael@0: if (aNetwork[key] != undefined) { michael@0: json[key] = aNetwork[key]; michael@0: } michael@0: } michael@0: return json; michael@0: }, michael@0: michael@0: _convertWifiNetwork: function(aNetwork) { michael@0: let network = aNetwork ? new this._window.MozWifiNetwork(aNetwork) : null; michael@0: return network; michael@0: }, michael@0: michael@0: _convertWifiNetworks: function(aNetworks) { michael@0: let networks = []; michael@0: for (let i in aNetworks) { michael@0: networks.push(this._convertWifiNetwork(aNetworks[i])); michael@0: } michael@0: return networks; michael@0: }, michael@0: michael@0: _convertConnection: function(aConn) { michael@0: let conn = aConn ? new MozWifiConnection(aConn) : null; michael@0: return conn; michael@0: }, michael@0: michael@0: _convertConnectionInfo: function(aInfo) { michael@0: let info = aInfo ? new MozWifiConnectionInfo(aInfo) : null; michael@0: return info; michael@0: }, michael@0: michael@0: _sendMessageForRequest: function(name, data, request) { michael@0: let id = this.getRequestId(request); michael@0: this._mm.sendAsyncMessage(name, { data: data, rid: id, mid: this._id }); michael@0: }, michael@0: michael@0: receiveMessage: function(aMessage) { michael@0: let msg = aMessage.json; michael@0: if (msg.mid && msg.mid != this._id) michael@0: return; michael@0: michael@0: let request; michael@0: if (msg.rid) { michael@0: request = this.takeRequest(msg.rid); michael@0: if (!request) { michael@0: return; michael@0: } michael@0: } michael@0: michael@0: switch (aMessage.name) { michael@0: case "WifiManager:getNetworks:Return:OK": michael@0: Services.DOMRequest.fireSuccess(request, this._convertWifiNetworks(msg.data)); michael@0: break; michael@0: michael@0: case "WifiManager:getNetworks:Return:NO": michael@0: Services.DOMRequest.fireError(request, "Unable to scan for networks"); michael@0: break; michael@0: michael@0: case "WifiManager:getKnownNetworks:Return:OK": michael@0: Services.DOMRequest.fireSuccess(request, this._convertWifiNetworks(msg.data)); michael@0: break; michael@0: michael@0: case "WifiManager:getKnownNetworks:Return:NO": michael@0: Services.DOMRequest.fireError(request, "Unable to get known networks"); michael@0: break; michael@0: michael@0: case "WifiManager:associate:Return:OK": michael@0: Services.DOMRequest.fireSuccess(request, true); michael@0: break; michael@0: michael@0: case "WifiManager:associate:Return:NO": michael@0: Services.DOMRequest.fireError(request, "Unable to add the network"); michael@0: break; michael@0: michael@0: case "WifiManager:forget:Return:OK": michael@0: Services.DOMRequest.fireSuccess(request, true); michael@0: break; michael@0: michael@0: case "WifiManager:forget:Return:NO": michael@0: Services.DOMRequest.fireError(request, msg.data); michael@0: break; michael@0: michael@0: case "WifiManager:wps:Return:OK": michael@0: Services.DOMRequest.fireSuccess(request, msg.data); michael@0: break; michael@0: michael@0: case "WifiManager:wps:Return:NO": michael@0: Services.DOMRequest.fireError(request, msg.data); michael@0: break; michael@0: michael@0: case "WifiManager:setPowerSavingMode:Return:OK": michael@0: Services.DOMRequest.fireSuccess(request, msg.data); michael@0: break; michael@0: michael@0: case "WifiManager:setPowerSavingMode:Return:NO": michael@0: Services.DOMRequest.fireError(request, msg.data); michael@0: break; michael@0: michael@0: case "WifiManager:setHttpProxy:Return:OK": michael@0: Services.DOMRequest.fireSuccess(request, msg.data); michael@0: break; michael@0: michael@0: case "WifiManager:setHttpProxy:Return:NO": michael@0: Services.DOMRequest.fireError(request, msg.data); michael@0: break; michael@0: michael@0: case "WifiManager:setStaticIpMode:Return:OK": michael@0: Services.DOMRequest.fireSuccess(request, msg.data); michael@0: break; michael@0: michael@0: case "WifiManager:setStaticIpMode:Return:NO": michael@0: Services.DOMRequest.fireError(request, msg.data); michael@0: break; michael@0: michael@0: case "WifiManager:wifiDown": michael@0: this._enabled = false; michael@0: this._currentNetwork = null; michael@0: this._fireEnabledOrDisabled(false); michael@0: break; michael@0: michael@0: case "WifiManager:wifiUp": michael@0: this._enabled = true; michael@0: this._macAddress = msg.macAddress; michael@0: this._fireEnabledOrDisabled(true); michael@0: break; michael@0: michael@0: case "WifiManager:onconnecting": michael@0: this._currentNetwork = this._convertWifiNetwork(msg.network); michael@0: this._connectionStatus = "connecting"; michael@0: this._fireStatusChangeEvent(); michael@0: break; michael@0: michael@0: case "WifiManager:onassociate": michael@0: this._currentNetwork = this._convertWifiNetwork(msg.network); michael@0: this._connectionStatus = "associated"; michael@0: this._fireStatusChangeEvent(); michael@0: break; michael@0: michael@0: case "WifiManager:onconnect": michael@0: this._currentNetwork = this._convertWifiNetwork(msg.network); michael@0: this._connectionStatus = "connected"; michael@0: this._fireStatusChangeEvent(); michael@0: break; michael@0: michael@0: case "WifiManager:ondisconnect": michael@0: this._currentNetwork = null; michael@0: this._connectionStatus = "disconnected"; michael@0: this._lastConnectionInfo = null; michael@0: this._fireStatusChangeEvent(); michael@0: break; michael@0: michael@0: case "WifiManager:onwpstimeout": michael@0: this._currentNetwork = null; michael@0: this._connectionStatus = "wps-timedout"; michael@0: this._lastConnectionInfo = null; michael@0: this._fireStatusChangeEvent(); michael@0: break; michael@0: michael@0: case "WifiManager:onwpsfail": michael@0: this._currentNetwork = null; michael@0: this._connectionStatus = "wps-failed"; michael@0: this._lastConnectionInfo = null; michael@0: this._fireStatusChangeEvent(); michael@0: break; michael@0: michael@0: case "WifiManager:onwpsoverlap": michael@0: this._currentNetwork = null; michael@0: this._connectionStatus = "wps-overlapped"; michael@0: this._lastConnectionInfo = null; michael@0: this._fireStatusChangeEvent(); michael@0: break; michael@0: michael@0: case "WifiManager:connectionInfoUpdate": michael@0: this._lastConnectionInfo = this._convertConnectionInfo(msg); michael@0: this._fireConnectionInfoUpdate(msg); michael@0: break; michael@0: case "WifiManager:onconnectingfailed": michael@0: this._currentNetwork = null; michael@0: this._connectionStatus = "connectingfailed"; michael@0: this._lastConnectionInfo = null; michael@0: this._fireStatusChangeEvent(); michael@0: break; michael@0: } michael@0: }, michael@0: michael@0: _fireStatusChangeEvent: function StatusChangeEvent() { michael@0: var event = new this._window.MozWifiStatusChangeEvent("statuschange", michael@0: { network: this._currentNetwork, michael@0: status: this._connectionStatus michael@0: }); michael@0: this.__DOM_IMPL__.dispatchEvent(event); michael@0: }, michael@0: michael@0: _fireConnectionInfoUpdate: function onConnectionInfoUpdate(info) { michael@0: var evt = new this._window.MozWifiConnectionInfoEvent("connectioninfoupdate", michael@0: { network: this._currentNetwork, michael@0: signalStrength: info.signalStrength, michael@0: relSignalStrength: info.relSignalStrength, michael@0: linkSpeed: info.linkSpeed, michael@0: ipAddress: info.ipAddress, michael@0: }); michael@0: this.__DOM_IMPL__.dispatchEvent(evt); michael@0: }, michael@0: michael@0: _fireEnabledOrDisabled: function enabledDisabled(enabled) { michael@0: var evt = new this._window.Event(enabled ? "enabled" : "disabled"); michael@0: this.__DOM_IMPL__.dispatchEvent(evt); michael@0: }, michael@0: michael@0: getNetworks: function getNetworks() { michael@0: var request = this.createRequest(); michael@0: this._sendMessageForRequest("WifiManager:getNetworks", null, request); michael@0: return request; michael@0: }, michael@0: michael@0: getKnownNetworks: function getKnownNetworks() { michael@0: var request = this.createRequest(); michael@0: this._sendMessageForRequest("WifiManager:getKnownNetworks", null, request); michael@0: return request; michael@0: }, michael@0: michael@0: associate: function associate(network) { michael@0: var request = this.createRequest(); michael@0: this._sendMessageForRequest("WifiManager:associate", michael@0: this._convertWifiNetworkToJSON(network), request); michael@0: return request; michael@0: }, michael@0: michael@0: forget: function forget(network) { michael@0: var request = this.createRequest(); michael@0: this._sendMessageForRequest("WifiManager:forget", michael@0: this._convertWifiNetworkToJSON(network), request); michael@0: return request; michael@0: }, michael@0: michael@0: wps: function wps(detail) { michael@0: var request = this.createRequest(); michael@0: this._sendMessageForRequest("WifiManager:wps", detail, request); michael@0: return request; michael@0: }, michael@0: michael@0: setPowerSavingMode: function setPowerSavingMode(enabled) { michael@0: var request = this.createRequest(); michael@0: this._sendMessageForRequest("WifiManager:setPowerSavingMode", enabled, request); michael@0: return request; michael@0: }, michael@0: michael@0: setHttpProxy: function setHttpProxy(network, info) { michael@0: var request = this.createRequest(); michael@0: this._sendMessageForRequest("WifiManager:setHttpProxy", michael@0: { network: this._convertWifiNetworkToJSON(network), info:info}, request); michael@0: return request; michael@0: }, michael@0: michael@0: setStaticIpMode: function setStaticIpMode(network, info) { michael@0: var request = this.createRequest(); michael@0: this._sendMessageForRequest("WifiManager:setStaticIpMode", michael@0: { network: this._convertWifiNetworkToJSON(network), info: info}, request); michael@0: return request; michael@0: }, michael@0: michael@0: get enabled() { michael@0: return this._enabled; michael@0: }, michael@0: michael@0: get macAddress() { michael@0: return this._macAddress; michael@0: }, michael@0: michael@0: get connection() { michael@0: let _connection = this._convertConnection({ status: this._connectionStatus, michael@0: network: this._currentNetwork, michael@0: }); michael@0: return _connection; michael@0: }, michael@0: michael@0: get connectionInformation() { michael@0: return this._lastConnectionInfo; michael@0: }, michael@0: michael@0: defineEventHandlerGetterSetter: function(name) { michael@0: Object.defineProperty(this, name, { michael@0: get: function() { michael@0: return this.__DOM_IMPL__.getEventHandler(name); michael@0: }, michael@0: set: function(handler) { michael@0: this.__DOM_IMPL__.setEventHandler(name, handler); michael@0: } michael@0: }); michael@0: }, michael@0: }; michael@0: michael@0: this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ michael@0: DOMWifiManager, MozWifiNetwork, MozWifiConnection, MozWifiConnectionInfo michael@0: ]); michael@0: michael@0: let debug; michael@0: if (DEBUG) { michael@0: debug = function (s) { michael@0: dump("-*- DOMWifiManager component: " + s + "\n"); michael@0: }; michael@0: } else { michael@0: debug = function (s) {}; michael@0: }