/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ /* 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/. */ "use strict"; const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/DOMRequestHelper.jsm"); const DEBUG = false; // interface MozWifiP2pGroupOwner implementation. function MozWifiP2pGroupOwner(aGo) { this.groupName = aGo.groupName; this.macAddress = aGo.macAddress; this.ipAddress = aGo.ipAddress; this.passphrase = aGo.passphrase; this.ssid = aGo.ssid; this.wpsCapabilities = aGo.wpsCapabilities; this.freq = aGo.freq; this.isLocal = aGo.isLocal; } MozWifiP2pGroupOwner.prototype = { classID: Components.ID("{a9b81450-349d-11e3-aa6e-0800200c9a66}"), contractID: "@mozilla.org/wifip2pgroupowner;1", QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]) }; // interface MozWifiP2pManager implementation. const MOZ_WIFIP2PMANAGER_CONTRACTID = "@mozilla.org/wifip2pmanager;1"; const MOZ_WIFIP2PMANAGER_CID = Components.ID("{8d9125a0-3498-11e3-aa6e-0800200c9a66}"); function MozWifiP2pManager() { this.defineEventHandlerGetterSetter("onstatuschange"); this.defineEventHandlerGetterSetter("onpeerinfoupdate"); this.defineEventHandlerGetterSetter("onenabled"); this.defineEventHandlerGetterSetter("ondisabled"); this.currentPeer = null; this.enabled = false; this.groupOwner = null; } // For smaller, read-only APIs, we expose any property that doesn't begin with // an underscore. function exposeReadOnly(obj) { let exposedProps = {}; for (let i in obj) { if (i[0] === "_") { continue; } exposedProps[i] = "r"; } obj.__exposedProps__ = exposedProps; return obj; } function debug(msg) { if (DEBUG) { dump('-------------- MozWifiP2pManager: ' + msg); } } MozWifiP2pManager.prototype = { __proto__: DOMRequestIpcHelper.prototype, classID: MOZ_WIFIP2PMANAGER_CID, contractID: MOZ_WIFIP2PMANAGER_CONTRACTID, QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer, Ci.nsISupportsWeakReference, Ci.nsIObserver, Ci.nsISupports]), // // nsIDOMGlobalPropertyInitializer implementation. // init: function(aWindow) { const messages = ["WifiP2pManager:setScanEnabled:Return:OK", "WifiP2pManager:setScanEnabled:Return:NO", "WifiP2pManager:getPeerList:Return:OK", "WifiP2pManager:getPeerList:Return:NO", "WifiP2pManager:connect:Return:OK", "WifiP2pManager:connect:Return:NO", "WifiP2pManager:disconnect:Return:OK", "WifiP2pManager:disconnect:Return:NO", "WifiP2pManager:setPairingConfirmation:Return", "WifiP2pManager:setDeviceName:Return:OK", "WifiP2pManager:setDeviceName:Return:NO", "WifiP2pManager:p2pDown", "WifiP2pManager:p2pUp", "WifiP2pManager:onconnecting", "WifiP2pManager:onconnected", "WifiP2pManager:ondisconnected", "WifiP2pManager:ongroupnstop", "WifiP2pManager:onconnectingfailed", "WifiP2pManager:onwpstimeout", "WifiP2pManager:onwpsfail", "WifiP2pManager:onpeerinfoupdate", ]; this.initDOMRequestHelper(aWindow, messages); this._mm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsISyncMessageSender); // Notify the internal a new DOM mananger is created. let state = this._mm.sendSyncMessage("WifiP2pManager:getState")[0]; if (state) { debug('State: ' + JSON.stringify(state)); this.enabled = state.enabled; this.currentPeer = state.currentPeer; if (state.groupOwner) { this.groupOwner = new MozWifiP2pGroupOwner(state.groupOwner); } } else { debug('Failed to get state'); } }, uninit: function() { }, _sendMessageForRequest: function(name, data, request) { let id = this.getRequestId(request); this._mm.sendAsyncMessage(name, { data: data, rid: id, mid: this._id }); }, receiveMessage: function(aMessage) { let msg = aMessage.json; if (msg.mid && msg.mid !== this._id) { return; } let request; switch (aMessage.name) { case "WifiP2pManager:setScanEnabled:Return:OK": request = this.takeRequest(msg.rid); Services.DOMRequest.fireSuccess(request, exposeReadOnly(msg.data)); break; case "WifiP2pManager:setScanEnabled:Return:NO": request = this.takeRequest(msg.rid); Services.DOMRequest.fireError(request, "Unable to enable/disable Wifi P2P peer discovery."); break; case "WifiP2pManager:getPeerList:Return:OK": request = this.takeRequest(msg.rid); Services.DOMRequest.fireSuccess(request, Cu.cloneInto(msg.data, this._window)); break; case "WifiP2pManager:getPeerList:Return:NO": request = this.takeRequest(msg.rid); Services.DOMRequest.fireError(request, "Unable to disable Wifi P2P peer discovery."); break; case "WifiP2pManager:connect:Return:OK": request = this.takeRequest(msg.rid); Services.DOMRequest.fireSuccess(request, exposeReadOnly(msg.data)); break; case "WifiP2pManager:connect:Return:NO": request = this.takeRequest(msg.rid); Services.DOMRequest.fireError(request, "Unable to connect to Wifi P2P peer."); break; case "WifiP2pManager:disconnect:Return:OK": request = this.takeRequest(msg.rid); Services.DOMRequest.fireSuccess(request, exposeReadOnly(msg.data)); break; case "WifiP2pManager:disconnect:Return:NO": request = this.takeRequest(msg.rid); Services.DOMRequest.fireError(request, "Unable to disconnect to Wifi P2P peer."); break; case "WifiP2pManager:setDeviceName:Return:OK": request = this.takeRequest(msg.rid); Services.DOMRequest.fireSuccess(request, exposeReadOnly(msg.data)); break; case "WifiP2pManager:setDeviceName:Return:NO": request = this.takeRequest(msg.rid); Services.DOMRequest.fireError(request, "Unable to set device name."); break; case "WifiP2pManager:p2pDown": this.enabled = false; this.currentPeer = null; this._fireEnabledOrDisabled(false); break; case "WifiP2pManager:p2pUp": this.enabled = true; this._fireEnabledOrDisabled(true); break; case "WifiP2pManager:onconnecting": debug('onconnecting with peer: ' + JSON.stringify(msg.peer)); this.currentPeer = msg.peer; this._fireStatusChangeEvent(msg.peer.address); break; case "WifiP2pManager:onconnected": debug('onconnected with peer: ' + JSON.stringify(msg.peer)); this.currentPeer = msg.peer; this.groupOwner = new MozWifiP2pGroupOwner(msg.groupOwner); this._fireStatusChangeEvent(msg.peer.address); break; case "WifiP2pManager:ondisconnected": debug('ondisconnected with peer: ' + JSON.stringify(msg.peer)); this.currentPeer = null; this.groupOwner = null; this._fireStatusChangeEvent(msg.peer.address); break; case "WifiP2pManager:onconnectingfailed": this._fireStatusChangeEvent(null); break; case "WifiP2pManager:onwpstimeout": this._fireStatusChangeEvent(null); break; case "WifiP2pManager:onwpsfail": this._fireStatusChangeEvent(null); break; case "WifiP2pManager:onpeerinfoupdate": this._firePeerInfoUpdateEvent(); break; } }, _firePeerInfoUpdateEvent: function PeerInfoUpdate() { let evt = new this._window.Event("peerinfoupdate"); this.__DOM_IMPL__.dispatchEvent(evt); }, _fireStatusChangeEvent: function WifiP2pStatusChange(peerAddress) { let evt = new this._window.MozWifiP2pStatusChangeEvent("statuschange", { peerAddress: peerAddress }); this.__DOM_IMPL__.dispatchEvent(evt); }, _fireEnabledOrDisabled: function enabledDisabled(enabled) { let evt = new this._window.Event(enabled ? "enabled" : "disabled"); this.__DOM_IMPL__.dispatchEvent(evt); }, // // WifiP2pManager.webidl implementation. // enableScan: function () { let request = this.createRequest(); this._sendMessageForRequest("WifiP2pManager:enableScan", null, request); return request; }, disableScan: function () { let request = this.createRequest(); this._sendMessageForRequest("WifiP2pManager:disableScan", null, request); return request; }, setScanEnabled: function(enabled) { let request = this.createRequest(); this._sendMessageForRequest("WifiP2pManager:setScanEnabled", enabled, request); return request; }, connect: function (address, wpsMethod, goIntent) { let request = this.createRequest(); let connectionInfo = { address: address, wpsMethod: wpsMethod, goIntent: goIntent }; this._sendMessageForRequest("WifiP2pManager:connect", connectionInfo, request); return request; }, disconnect: function (address) { let request = this.createRequest(); this._sendMessageForRequest("WifiP2pManager:disconnect", address, request); return request; }, getPeerList: function () { let request = this.createRequest(); this._sendMessageForRequest("WifiP2pManager:getPeerList", null, request); return request; }, setPairingConfirmation: function (accepted, pin) { let request = this.createRequest(); let result = { accepted: accepted, pin: pin }; this._sendMessageForRequest("WifiP2pManager:setPairingConfirmation", result, request); return request; }, setDeviceName: function(newDeviceName) { let request = this.createRequest(); this._sendMessageForRequest("WifiP2pManager:setDeviceName", newDeviceName, request); return request; }, // Helpers. defineEventHandlerGetterSetter: function(event) { Object.defineProperty(this, event, { get: function() { return this.__DOM_IMPL__.getEventHandler(event); }, set: function(handler) { this.__DOM_IMPL__.setEventHandler(event, handler); } }); }, }; this.NSGetFactory = XPCOMUtils.generateNSGetFactory([MozWifiP2pManager, MozWifiP2pGroupOwner]);