1 /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
9 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
11 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
12 Cu.import("resource://gre/modules/Services.jsm");
13 Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
15 const DEBUG = false; // set to false to suppress debug messages
17 const DOMWIFIMANAGER_CONTRACTID = "@mozilla.org/wifimanager;1";
18 const DOMWIFIMANAGER_CID = Components.ID("{2cf775a7-1837-410c-9e26-323c42e076da}");
20 function DOMWifiManager() {
23 function exposeCurrentNetwork(currentNetwork) {
24 currentNetwork.__exposedProps__ = exposeCurrentNetwork.currentNetworkApi;
27 exposeCurrentNetwork.currentNetworkApi = {
33 // For smaller, read-only APIs, we expose any property that doesn't begin with
35 function exposeReadOnly(obj) {
36 var exposedProps = {};
40 exposedProps[i] = "r";
43 obj.__exposedProps__ = exposedProps;
47 DOMWifiManager.prototype = {
48 __proto__: DOMRequestIpcHelper.prototype,
50 classID: DOMWIFIMANAGER_CID,
51 classInfo: XPCOMUtils.generateCI({classID: DOMWIFIMANAGER_CID,
52 contractID: DOMWIFIMANAGER_CONTRACTID,
53 classDescription: "DOMWifiManager",
54 interfaces: [Ci.nsIDOMWifiManager],
55 flags: Ci.nsIClassInfo.DOM_OBJECT}),
57 QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMWifiManager,
58 Ci.nsIDOMGlobalPropertyInitializer]),
60 // nsIDOMGlobalPropertyInitializer implementation
61 init: function(aWindow) {
62 let principal = aWindow.document.nodePrincipal;
63 let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
65 let perm = principal == secMan.getSystemPrincipal()
66 ? Ci.nsIPermissionManager.ALLOW_ACTION
67 : Services.perms.testExactPermissionFromPrincipal(principal, "wifi-manage");
69 // Only pages with perm set can use the wifi manager.
70 this._hasPrivileges = perm == Ci.nsIPermissionManager.ALLOW_ACTION;
72 // Maintain this state for synchronous APIs.
73 this._currentNetwork = null;
74 this._connectionStatus = "disconnected";
75 this._enabled = false;
76 this._lastConnectionInfo = null;
78 const messages = ["WifiManager:getNetworks:Return:OK", "WifiManager:getNetworks:Return:NO",
79 "WifiManager:getKnownNetworks:Return:OK", "WifiManager:getKnownNetworks:Return:NO",
80 "WifiManager:associate:Return:OK", "WifiManager:associate:Return:NO",
81 "WifiManager:forget:Return:OK", "WifiManager:forget:Return:NO",
82 "WifiManager:wps:Return:OK", "WifiManager:wps:Return:NO",
83 "WifiManager:setPowerSavingMode:Return:OK", "WifiManager:setPowerSavingMode:Return:NO",
84 "WifiManager:wifiDown", "WifiManager:wifiUp",
85 "WifiManager:onconnecting", "WifiManager:onassociate",
86 "WifiManager:onconnect", "WifiManager:ondisconnect",
87 "WifiManager:onwpstimeout", "WifiManager:onwpsfail",
88 "WifiManager:onwpsoverlap", "WifiManager:connectionInfoUpdate",
89 "WifiManager:onconnectingfailed"];
90 this.initHelper(aWindow, messages);
91 this._mm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsISyncMessageSender);
93 var state = this._mm.sendSyncMessage("WifiManager:getState")[0];
95 this._currentNetwork = state.network;
96 if (this._currentNetwork)
97 exposeCurrentNetwork(this._currentNetwork);
98 this._lastConnectionInfo = state.connectionInfo;
99 this._enabled = state.enabled;
100 this._connectionStatus = state.status;
101 this._macAddress = state.macAddress;
103 this._currentNetwork = null;
104 this._lastConnectionInfo = null;
105 this._enabled = false;
106 this._connectionStatus = "disconnected";
107 this._macAddress = "";
112 this._onStatusChange = null;
113 this._onConnectionInfoUpdate = null;
114 this._onEnabled = null;
115 this._onDisabled = null;
118 _sendMessageForRequest: function(name, data, request) {
119 let id = this.getRequestId(request);
120 this._mm.sendAsyncMessage(name, { data: data, rid: id, mid: this._id });
123 receiveMessage: function(aMessage) {
124 let msg = aMessage.json;
125 if (msg.mid && msg.mid != this._id)
129 switch (aMessage.name) {
130 case "WifiManager:getNetworks:Return:OK":
131 request = this.takeRequest(msg.rid);
132 Services.DOMRequest.fireSuccess(request, exposeReadOnly(msg.data));
135 case "WifiManager:getNetworks:Return:NO":
136 request = this.takeRequest(msg.rid);
137 Services.DOMRequest.fireError(request, "Unable to scan for networks");
140 case "WifiManager:getKnownNetworks:Return:OK":
141 request = this.takeRequest(msg.rid);
142 Services.DOMRequest.fireSuccess(request, exposeReadOnly(msg.data));
145 case "WifiManager:getKnownNetworks:Return:NO":
146 request = this.takeRequest(msg.rid);
147 Services.DOMRequest.fireError(request, "Unable to get known networks");
150 case "WifiManager:associate:Return:OK":
151 request = this.takeRequest(msg.rid);
152 Services.DOMRequest.fireSuccess(request, true);
155 case "WifiManager:associate:Return:NO":
156 request = this.takeRequest(msg.rid);
157 Services.DOMRequest.fireError(request, "Unable to add the network");
160 case "WifiManager:forget:Return:OK":
161 request = this.takeRequest(msg.rid);
162 Services.DOMRequest.fireSuccess(request, true);
165 case "WifiManager:forget:Return:NO":
166 request = this.takeRequest(msg.rid);
167 Services.DOMRequest.fireError(request, msg.data);
170 case "WifiManager:wps:Return:OK":
171 request = this.takeRequest(msg.rid);
172 Services.DOMRequest.fireSuccess(request, exposeReadOnly(msg.data));
175 case "WifiManager:wps:Return:NO":
176 request = this.takeRequest(msg.rid);
177 Services.DOMRequest.fireError(request, msg.data);
180 case "WifiManager:setPowerSavingMode:Return:OK":
181 request = this.takeRequest(msg.rid);
182 Services.DOMRequest.fireSuccess(request, exposeReadOnly(msg.data));
185 case "WifiManager:setPowerSavingMode:Return:NO":
186 request = this.takeRequest(msg.rid);
187 Services.DOMRequest.fireError(request, msg.data);
190 case "WifiManager:wifiDown":
191 this._enabled = false;
192 this._currentNetwork = null;
193 this._fireEnabledOrDisabled(false);
196 case "WifiManager:wifiUp":
197 this._enabled = true;
198 this._fireEnabledOrDisabled(true);
201 case "WifiManager:onconnecting":
202 this._currentNetwork = msg.network;
203 exposeCurrentNetwork(this._currentNetwork);
204 this._connectionStatus = "connecting";
205 this._fireStatusChangeEvent();
208 case "WifiManager:onassociate":
209 this._currentNetwork = msg.network;
210 exposeCurrentNetwork(this._currentNetwork);
211 this._connectionStatus = "associated";
212 this._fireStatusChangeEvent();
215 case "WifiManager:onconnect":
216 this._currentNetwork = msg.network;
217 exposeCurrentNetwork(this._currentNetwork);
218 this._connectionStatus = "connected";
219 this._fireStatusChangeEvent();
222 case "WifiManager:ondisconnect":
223 this._currentNetwork = null;
224 this._connectionStatus = "disconnected";
225 this._lastConnectionInfo = null;
226 this._fireStatusChangeEvent();
229 case "WifiManager:onwpstimeout":
230 this._currentNetwork = null;
231 this._connectionStatus = "wps-timedout";
232 this._lastConnectionInfo = null;
233 this._fireStatusChangeEvent();
236 case "WifiManager:onwpsfail":
237 this._currentNetwork = null;
238 this._connectionStatus = "wps-failed";
239 this._lastConnectionInfo = null;
240 this._fireStatusChangeEvent();
243 case "WifiManager:onwpsoverlap":
244 this._currentNetwork = null;
245 this._connectionStatus = "wps-overlapped";
246 this._lastConnectionInfo = null;
247 this._fireStatusChangeEvent();
250 case "WifiManager:connectionInfoUpdate":
251 this._lastConnectionInfo = msg;
252 this._fireConnectionInfoUpdate(msg);
254 case "WifiManager:onconnectingfailed":
255 this._currentNetwork = null;
256 this._connectionStatus = "connectingfailed";
257 this._lastConnectionInfo = null;
258 this._fireStatusChangeEvent();
263 _fireStatusChangeEvent: function StatusChangeEvent() {
264 if (this._onStatusChange) {
265 debug("StatusChangeEvent");
266 var event = new this._window.MozWifiStatusChangeEvent("statusChangeEvent",
267 { network: this._currentNetwork,
268 status: this._connectionStatus
270 this._onStatusChange.handleEvent(event);
274 _fireConnectionInfoUpdate: function connectionInfoUpdate(info) {
275 if (this._onConnectionInfoUpdate) {
276 debug("ConnectionInfoEvent");
277 var evt = new this._window.MozWifiConnectionInfoEvent("connectionInfoEvent",
278 { network: this._currentNetwork,
279 signalStrength: info.signalStrength,
280 relSignalStrength: info.relSignalStrength,
281 linkSpeed: info.linkSpeed,
282 ipAddress: info.ipAddress,
284 this._onConnectionInfoUpdate.handleEvent(evt);
288 _fireEnabledOrDisabled: function enabledDisabled(enabled) {
289 var handler = enabled ? this._onEnabled : this._onDisabled;
291 var evt = new this._window.Event("WifiEnabled");
292 handler.handleEvent(evt);
297 getNetworks: function nsIDOMWifiManager_getNetworks() {
298 if (!this._hasPrivileges)
299 throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
300 var request = this.createRequest();
301 this._sendMessageForRequest("WifiManager:getNetworks", null, request);
305 getKnownNetworks: function nsIDOMWifiManager_getKnownNetworks() {
306 if (!this._hasPrivileges)
307 throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
308 var request = this.createRequest();
309 this._sendMessageForRequest("WifiManager:getKnownNetworks", null, request);
313 associate: function nsIDOMWifiManager_associate(network) {
314 if (!this._hasPrivileges)
315 throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
316 var request = this.createRequest();
317 this._sendMessageForRequest("WifiManager:associate", network, request);
321 forget: function nsIDOMWifiManager_forget(network) {
322 if (!this._hasPrivileges)
323 throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
324 var request = this.createRequest();
325 this._sendMessageForRequest("WifiManager:forget", network, request);
329 wps: function nsIDOMWifiManager_wps(detail) {
330 if (!this._hasPrivileges)
331 throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
332 var request = this.createRequest();
333 this._sendMessageForRequest("WifiManager:wps", detail, request);
337 setPowerSavingMode: function nsIDOMWifiManager_setPowerSavingMode(enabled) {
338 if (!this._hasPrivileges)
339 throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
340 var request = this.createRequest();
341 this._sendMessageForRequest("WifiManager:setPowerSavingMode", enabled, request);
346 if (!this._hasPrivileges)
347 throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
348 return this._enabled;
352 if (!this._hasPrivileges)
353 throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
354 return this._macAddress;
358 if (!this._hasPrivileges)
359 throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
360 return exposeReadOnly({ status: this._connectionStatus,
361 network: this._currentNetwork });
364 get connectionInformation() {
365 if (!this._hasPrivileges)
366 throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
367 return this._lastConnectionInfo
368 ? exposeReadOnly(this._lastConnectionInfo)
372 set onstatuschange(callback) {
373 if (!this._hasPrivileges)
374 throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
375 this._onStatusChange = callback;
378 set connectionInfoUpdate(callback) {
379 if (!this._hasPrivileges)
380 throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
381 this._onConnectionInfoUpdate = callback;
384 set onenabled(callback) {
385 if (!this._hasPrivileges)
386 throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
387 this._onEnabled = callback;
390 set ondisabled(callback) {
391 if (!this._hasPrivileges)
392 throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
393 this._onDisabled = callback;
397 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([DOMWifiManager]);
401 debug = function (s) {
402 dump("-*- DOMWifiManager component: " + s + "\n");
405 debug = function (s) {};