Bug 936367 - Support wifi hotspot enable API. r=vchang, r=ptheriault, sr=mrbkap

This commit is contained in:
Dimi Lee 2014-08-11 17:13:25 +08:00
parent b120b200da
commit 21d9d46259
8 changed files with 279 additions and 0 deletions

View File

@ -415,6 +415,12 @@
@BINPATH@/components/WifiWorker.manifest
#endif // MOZ_WIDGET_GONK
; Tethering
#ifdef MOZ_WIDGET_GONK
@BINPATH@/components/TetheringManager.js
@BINPATH@/components/TetheringManager.manifest
#endif
; ResourceStats
#ifdef MOZ_WIDGET_GONK
@BINPATH@/components/ResourceStats.js

View File

@ -96,6 +96,7 @@ if CONFIG['OS_ARCH'] == 'WINNT':
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
DIRS += [
'speakermanager',
'tethering',
'wifi',
]

View File

@ -0,0 +1,105 @@
/* 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");
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1",
"nsIMessageSender");
const DEBUG = false;
const TETHERING_TYPE_WIFI = "wifi";
const TETHERING_TYPE_BLUETOOTH = "bt";
const TETHERING_TYPE_USB = "usb";
function TetheringManager() {
}
TetheringManager.prototype = {
__proto__: DOMRequestIpcHelper.prototype,
classDescription: "TetheringManager",
classID: Components.ID("{bd8a831c-d8ec-4f00-8803-606e50781097}"),
contractID: "@mozilla.org/dom/tetheringmanager;1",
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer,
Ci.nsISupportsWeakReference,
Ci.nsIObserver]),
init: function(aWindow) {
const messages = ["WifiManager:setWifiTethering:Return:OK",
"WifiManager:setWifiTethering:Return:NO"];
this.initDOMRequestHelper(aWindow, messages);
},
_getPromise: function(aCallback) {
let self = this;
return this.createPromise(function(aResolve, aReject) {
let resolverId = self.getPromiseResolverId({
resolve: aResolve,
reject: aReject
});
aCallback(resolverId);
});
},
// TODO : aMessage format may be different after supporting bt/usb.
// for now, use wifi format first.
receiveMessage: function(aMessage) {
let data = aMessage.data.data;
let resolver = this.takePromiseResolver(data.resolverId);
if (!resolver) {
return;
}
switch (aMessage.name) {
case "WifiManager:setWifiTethering:Return:OK":
resolver.resolve(data);
break;
case "WifiManager:setWifiTethering:Return:NO":
resolver.reject(data.reason);
break;
}
},
setTetheringEnabled: function setTetheringEnabled(aEnabled, aType, aConfig) {
let self = this;
switch (aType) {
case TETHERING_TYPE_WIFI:
return this._getPromise(function(aResolverId) {
let data = { resolverId: aResolverId, enabled: aEnabled, config: aConfig };
cpmm.sendAsyncMessage("WifiManager:setWifiTethering", { data: data});
});
case TETHERING_TYPE_BLUETOOTH:
case TETHERING_TYPE_USB:
default:
debug("tethering type(" + aType + ") doesn't support");
return this._getPromise(function(aResolverId) {
self.takePromiseResolver(aResolverId).reject();
});
}
},
};
this.NSGetFactory =
XPCOMUtils.generateNSGetFactory([TetheringManager]);
let debug;
if (DEBUG) {
debug = function (s) {
dump("-*- TetheringManager component: " + s + "\n");
};
} else {
debug = function (s) {};
}

View File

@ -0,0 +1,4 @@
#TetheringManager.js
component {bd8a831c-d8ec-4f00-8803-606e50781097} TetheringManager.js
contract @mozilla.org/tetheringmanager;1 {bd8a831c-d8ec-4f00-8803-606e50781097}

12
dom/tethering/moz.build Normal file
View File

@ -0,0 +1,12 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
EXTRA_COMPONENTS += [
'TetheringManager.js',
'TetheringManager.manifest',
]
FINAL_LIBRARY = 'xul'

View File

@ -0,0 +1,57 @@
/* 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/. */
enum TetheringType {
"bluetooth",
"usb",
"wifi"
};
enum SecurityType {
"open",
"wpa-psk",
"wpa2-psk"
};
dictionary WifiTetheringConfig {
DOMString ssid;
SecurityType security;
DOMString key;
};
dictionary TetheringConfiguration {
DOMString ip;
DOMString prefix;
DOMString startIp;
DOMString endIp;
DOMString dns1;
DOMString dns2;
WifiTetheringConfig wifiConfig;
};
[JSImplementation="@mozilla.org/tetheringmanager;1",
NavigatorProperty="mozTetheringManager",
AvailableIn="CertifiedApps"]
interface MozTetheringManager {
/**
* Enable/Disable tethering.
* @param enabled True to enable tethering, False to disable tethering.
* @param type Tethering type to enable/disable.
* @param config Configuration should have following fields when enable is True:
* - ip ip address.
* - prefix mask length.
* - startIp start ip address allocated by DHCP server for tethering.
* - endIp end ip address allocated by DHCP server for tethering.
* - dns1 first DNS server address.
* - dns2 second DNS server address.
* - wifiConfig wifi tethering configuration
* - ssid SSID network name.
* - security open, wpa-psk or wpa2-psk.
* - key password for wpa-psk or wpa2-psk.
* config should not be set when enabled is False.
*/
Promise<any> setTetheringEnabled(boolean enabled,
TetheringType type,
optional TetheringConfiguration config);
};

View File

@ -263,6 +263,7 @@ WEBIDL_FILES = [
'MozNamedAttrMap.webidl',
'MozPowerManager.webidl',
'MozSelfSupport.webidl',
'MozTetheringManager.webidl',
'MozTimeManager.webidl',
'MozWakeLock.webidl',
'MutationEvent.webidl',

View File

@ -1765,6 +1765,7 @@ function WifiWorker() {
"WifiManager:getImportedCerts",
"WifiManager:deleteCert",
"WifiManager:setWifiEnabled",
"WifiManager:setWifiTethering",
"child-process-shutdown"];
messages.forEach((function(msgName) {
@ -2751,6 +2752,9 @@ WifiWorker.prototype = {
case "WifiManager:deleteCert":
this.deleteCert(msg);
break;
case "WifiManager:setWifiTethering":
this.setWifiTethering(msg);
break;
case "WifiManager:getState": {
let i;
if ((i = this._domManagers.indexOf(msg.manager)) === -1) {
@ -2986,6 +2990,60 @@ WifiWorker.prototype = {
},
getWifiTetheringParameters: function getWifiTetheringParameters(enable) {
if (this.useTetheringAPI) {
return this.getWifiTetheringConfiguration(enable);
} else {
return this.getWifiTetheringParametersBySetting(enable);
}
},
getWifiTetheringConfiguration: function getWifiTetheringConfiguration(enable) {
let config = {};
let params = this.tetheringConfig;
let check = function(field, _default) {
config[field] = field in params ? params[field] : _default;
};
check("ssid", DEFAULT_WIFI_SSID);
check("security", DEFAULT_WIFI_SECURITY_TYPE);
check("key", DEFAULT_WIFI_SECURITY_PASSWORD);
check("ip", DEFAULT_WIFI_IP);
check("prefix", DEFAULT_WIFI_PREFIX);
check("wifiStartIp", DEFAULT_WIFI_DHCPSERVER_STARTIP);
check("wifiEndIp", DEFAULT_WIFI_DHCPSERVER_ENDIP);
check("usbStartIp", DEFAULT_USB_DHCPSERVER_STARTIP);
check("usbEndIp", DEFAULT_USB_DHCPSERVER_ENDIP);
check("dns1", DEFAULT_DNS1);
check("dns2", DEFAULT_DNS2);
config.enable = enable;
config.mode = enable ? WIFI_FIRMWARE_AP : WIFI_FIRMWARE_STATION;
config.link = enable ? NETWORK_INTERFACE_UP : NETWORK_INTERFACE_DOWN;
// Check the format to prevent netd from crash.
if (enable && (!config.ssid || config.ssid == "")) {
debug("Invalid SSID value.");
return null;
}
if (enable && (config.security != WIFI_SECURITY_TYPE_NONE && !config.key)) {
debug("Invalid security password.");
return null;
}
// Using the default values here until application supports these settings.
if (config.ip == "" || config.prefix == "" ||
config.wifiStartIp == "" || config.wifiEndIp == "" ||
config.usbStartIp == "" || config.usbEndIp == "") {
debug("Invalid subnet information.");
return null;
}
return config;
},
getWifiTetheringParametersBySetting: function getWifiTetheringParametersBySetting(enable) {
let ssid;
let securityType;
let securityId;
@ -3400,6 +3458,35 @@ WifiWorker.prototype = {
});
},
// TODO : These two variables should be removed once GAIA uses tethering API.
useTetheringAPI : false,
tetheringConfig : {},
setWifiTethering: function setWifiTethering(msg) {
const message = "WifiManager:setWifiTethering:Return";
let self = this;
let enabled = msg.data.enabled;
this.useTetheringAPI = true;
this.tetheringConfig = msg.data.config;
if (WifiManager.enabled) {
this._sendMessage(message, false, "Wifi is enabled", msg);
return;
}
this.setWifiApEnabled(enabled, function() {
if ((enabled && WifiManager.tetheringState == "COMPLETED") ||
(!enabled && WifiManager.tetheringState == "UNINITIALIZED")) {
self._sendMessage(message, true, msg.data, msg);
} else {
msg.data.reason = enabled ?
"Enable WIFI tethering faild" : "Disable WIFI tethering faild";
self._sendMessage(message, false, msg.data, msg);
}
});
},
// This is a bit ugly, but works. In particular, this depends on the fact
// that RadioManager never actually tries to get the worker from us.
get worker() { throw "Not implemented"; },
@ -3597,6 +3684,12 @@ WifiWorker.prototype = {
case SETTINGS_WIFI_DNS2:
case SETTINGS_USB_DHCPSERVER_STARTIP:
case SETTINGS_USB_DHCPSERVER_ENDIP:
// TODO: code related to wifi-tethering setting should be removed after GAIA
// use tethering API
if (this.useTetheringAPI) {
break;
}
if (aResult !== null) {
this.tetheringSettings[aName] = aResult;
}