Merge mozilla-central and birch

This commit is contained in:
Ed Morley 2013-06-11 09:38:18 +01:00
commit a5fe50957e
7 changed files with 452 additions and 227 deletions

View File

@ -1566,8 +1566,13 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData)
}
BluetoothSignal signal(signalName, signalPath, v);
nsRefPtr<DistributeBluetoothSignalTask> task
= new DistributeBluetoothSignalTask(signal);
nsRefPtr<nsRunnable> task;
if (signalInterface.EqualsLiteral(DBUS_SINK_IFACE)) {
task = new SinkPropertyChangedHandler(signal);
} else {
task = new DistributeBluetoothSignalTask(signal);
}
NS_DispatchToMainThread(task);
return DBUS_HANDLER_RESULT_HANDLED;

View File

@ -73,17 +73,8 @@ const WIFI_CTRL_INTERFACE = "wl0.1";
const NETWORK_INTERFACE_UP = "up";
const NETWORK_INTERFACE_DOWN = "down";
// Settings DB path for Wifi tethering.
const SETTINGS_WIFI_ENABLED = "tethering.wifi.enabled";
const SETTINGS_WIFI_SSID = "tethering.wifi.ssid";
const SETTINGS_WIFI_SECURITY_TYPE = "tethering.wifi.security.type";
const SETTINGS_WIFI_SECURITY_PASSWORD = "tethering.wifi.security.password";
const SETTINGS_WIFI_IP = "tethering.wifi.ip";
const SETTINGS_WIFI_PREFIX = "tethering.wifi.prefix";
const SETTINGS_WIFI_DHCPSERVER_STARTIP = "tethering.wifi.dhcpserver.startip";
const SETTINGS_WIFI_DHCPSERVER_ENDIP = "tethering.wifi.dhcpserver.endip";
const SETTINGS_WIFI_DNS1 = "tethering.wifi.dns1";
const SETTINGS_WIFI_DNS2 = "tethering.wifi.dns2";
const TETHERING_STATE_ONGOING = "ongoing";
const TETHERING_STATE_IDLE = "idle";
// Settings DB path for USB tethering.
const SETTINGS_USB_ENABLED = "tethering.usb.enabled";
@ -94,15 +85,6 @@ const SETTINGS_USB_DHCPSERVER_ENDIP = "tethering.usb.dhcpserver.endip";
const SETTINGS_USB_DNS1 = "tethering.usb.dns1";
const SETTINGS_USB_DNS2 = "tethering.usb.dns2";
// Default value for WIFI tethering.
const DEFAULT_WIFI_IP = "192.168.1.1";
const DEFAULT_WIFI_PREFIX = "24";
const DEFAULT_WIFI_DHCPSERVER_STARTIP = "192.168.1.10";
const DEFAULT_WIFI_DHCPSERVER_ENDIP = "192.168.1.30";
const DEFAULT_WIFI_SSID = "FirefoxHotspot";
const DEFAULT_WIFI_SECURITY_TYPE = "open";
const DEFAULT_WIFI_SECURITY_PASSWORD = "1234567890";
// Default value for USB tethering.
const DEFAULT_USB_IP = "192.168.0.1";
const DEFAULT_USB_PREFIX = "24";
@ -183,16 +165,6 @@ function NetworkManager() {
this.initTetheringSettings();
let settingsLock = gSettingsService.createLock();
// Read wifi tethering data from settings DB.
settingsLock.get(SETTINGS_WIFI_SSID, this);
settingsLock.get(SETTINGS_WIFI_SECURITY_TYPE, this);
settingsLock.get(SETTINGS_WIFI_SECURITY_PASSWORD, this);
settingsLock.get(SETTINGS_WIFI_IP, this);
settingsLock.get(SETTINGS_WIFI_PREFIX, this);
settingsLock.get(SETTINGS_WIFI_DHCPSERVER_STARTIP, this);
settingsLock.get(SETTINGS_WIFI_DHCPSERVER_ENDIP, this);
settingsLock.get(SETTINGS_WIFI_DNS1, this);
settingsLock.get(SETTINGS_WIFI_DNS2, this);
// Read usb tethering data from settings DB.
settingsLock.get(SETTINGS_USB_IP, this);
settingsLock.get(SETTINGS_USB_PREFIX, this);
@ -200,28 +172,19 @@ function NetworkManager() {
settingsLock.get(SETTINGS_USB_DHCPSERVER_ENDIP, this);
settingsLock.get(SETTINGS_USB_DNS1, this);
settingsLock.get(SETTINGS_USB_DNS2, this);
settingsLock.get(SETTINGS_USB_ENABLED, this);
this._usbTetheringSettingsToRead = [SETTINGS_USB_IP,
SETTINGS_USB_PREFIX,
SETTINGS_USB_DHCPSERVER_STARTIP,
SETTINGS_USB_DHCPSERVER_ENDIP,
SETTINGS_USB_DNS1,
SETTINGS_USB_DNS2,
SETTINGS_USB_ENABLED];
this.wantConnectionEvent = null;
this.setAndConfigureActive();
let self = this;
this.waitForConnectionReadyCallback = null;
settingsLock.get(SETTINGS_WIFI_ENABLED, {
handle: function (aName, aResult) {
if (!aResult) {
return;
}
// Turn on wifi tethering when the mobile data connection is established.
self.waitForConnectionReadyCallback = (function callback() {
let settingsLock = gSettingsService.createLock();
settingsLock.set(SETTINGS_WIFI_ENABLED, aResult, null);
});
},
handleError: function (aErrorMessage) {
debug("Error reading the 'tethering.wifi.enabled' setting: " + aErrorMessage);
}
});
ppmm.addMessageListener('NetworkInterfaceList:ListInterface', this);
// Used in resolveHostname().
@ -267,11 +230,9 @@ NetworkManager.prototype = {
if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_WIFI) {
this.mRIL.updateRILNetworkInterface();
}
// Turn on wifi tethering when the callback is set.
if (this.waitForConnectionReadyCallback) {
this.waitForConnectionReadyCallback.call(this);
this.waitForConnectionReadyCallback = null;
}
this.onConnectionChanged(network);
// Probing the public network accessibility after routing table is ready
CaptivePortalDetectionHelper.notify(CaptivePortalDetectionHelper.EVENT_CONNECT, this.active);
break;
@ -704,17 +665,7 @@ NetworkManager.prototype = {
tetheringSettings: {},
initTetheringSettings: function initTetheringSettings() {
this.tetheringSettings[SETTINGS_WIFI_ENABLED] = false;
this.tetheringSettings[SETTINGS_USB_ENABLED] = false;
this.tetheringSettings[SETTINGS_WIFI_SSID] = DEFAULT_WIFI_SSID;
this.tetheringSettings[SETTINGS_WIFI_SECURITY_TYPE] = DEFAULT_WIFI_SECURITY_TYPE;
this.tetheringSettings[SETTINGS_WIFI_SECURITY_PASSWORD] = DEFAULT_WIFI_SECURITY_PASSWORD;
this.tetheringSettings[SETTINGS_WIFI_IP] = DEFAULT_WIFI_IP;
this.tetheringSettings[SETTINGS_WIFI_PREFIX] = DEFAULT_WIFI_PREFIX;
this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_STARTIP] = DEFAULT_WIFI_DHCPSERVER_STARTIP;
this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_ENDIP] = DEFAULT_WIFI_DHCPSERVER_ENDIP;
this.tetheringSettings[SETTINGS_WIFI_DNS1] = DEFAULT_DNS1;
this.tetheringSettings[SETTINGS_WIFI_DNS2] = DEFAULT_DNS2;
this.tetheringSettings[SETTINGS_USB_IP] = DEFAULT_USB_IP;
this.tetheringSettings[SETTINGS_USB_PREFIX] = DEFAULT_USB_PREFIX;
this.tetheringSettings[SETTINGS_USB_DHCPSERVER_STARTIP] = DEFAULT_USB_DHCPSERVER_STARTIP;
@ -723,34 +674,42 @@ NetworkManager.prototype = {
this.tetheringSettings[SETTINGS_USB_DNS2] = DEFAULT_DNS2;
},
_requestCount: 0,
handle: function handle(aName, aResult) {
switch(aName) {
case SETTINGS_USB_ENABLED:
this.handleUSBTetheringToggle(aResult);
break;
// SETTINGS_WIFI_ENABLED is handled in WifiManager.js to deal with
// the interaction between wifi and wifi tethering settings. Also, we
// update tetheringSettings[SETTINGS_WIFI_ENABLED] in setWifiTethering
// function.
case SETTINGS_WIFI_SSID:
case SETTINGS_WIFI_SECURITY_TYPE:
case SETTINGS_WIFI_SECURITY_PASSWORD:
case SETTINGS_WIFI_IP:
case SETTINGS_WIFI_PREFIX:
case SETTINGS_WIFI_DHCPSERVER_STARTIP:
case SETTINGS_WIFI_DHCPSERVER_ENDIP:
case SETTINGS_WIFI_DNS1:
case SETTINGS_WIFI_DNS2:
this._oldUsbTetheringEnabledState = this.tetheringSettings[SETTINGS_USB_ENABLED];
case SETTINGS_USB_IP:
case SETTINGS_USB_PREFIX:
case SETTINGS_USB_DHCPSERVER_STARTIP:
case SETTINGS_USB_DHCPSERVER_ENDIP:
case SETTINGS_USB_DNS1:
case SETTINGS_USB_DNS2:
if (aResult) {
if (aResult !== null) {
this.tetheringSettings[aName] = aResult;
}
debug("'" + aName + "'" + " is now " + this.tetheringSettings[aName]);
let index = this._usbTetheringSettingsToRead.indexOf(aName);
if (index != -1) {
this._usbTetheringSettingsToRead.splice(index, 1);
}
if (this._usbTetheringSettingsToRead.length) {
debug("We haven't read completely the usb Tethering data from settings db.");
break;
}
if (this._oldUsbTetheringEnabledState === this.tetheringSettings[SETTINGS_USB_ENABLED]) {
debug("No changes for SETTINGS_USB_ENABLED flag. Nothing to do.");
break;
}
this._requestCount++;
if (this._requestCount === 1) {
this.handleUSBTetheringToggle(aResult);
}
break;
};
},
@ -758,7 +717,6 @@ NetworkManager.prototype = {
handleError: function handleError(aErrorMessage) {
debug("There was an error while reading Tethering settings.");
this.tetheringSettings = {};
this.tetheringSettings[SETTINGS_WIFI_ENABLED] = false;
this.tetheringSettings[SETTINGS_USB_ENABLED] = false;
},
@ -771,14 +729,36 @@ NetworkManager.prototype = {
return null;
},
_usbTetheringAction: TETHERING_STATE_IDLE,
_usbTetheringSettingsToRead: [],
_oldUsbTetheringEnabledState: null,
// External and internal interface name.
_tetheringInterface: null,
handleUSBTetheringToggle: function handleUSBTetheringToggle(enable) {
if (this.tetheringSettings[SETTINGS_USB_ENABLED] == enable) {
handleLastRequest: function handleLastRequest() {
let count = this._requestCount;
this._requestCount = 0;
if (count === 1) {
if (this.wantConnectionEvent) {
if (this.tetheringSettings[SETTINGS_USB_ENABLED]) {
this.wantConnectionEvent.call(this);
}
this.wantConnectionEvent = null;
}
return;
}
if (count > 1) {
this.handleUSBTetheringToggle(this.tetheringSettings[SETTINGS_USB_ENABLED]);
this.wantConnectionEvent = null;
}
},
handleUSBTetheringToggle: function handleUSBTetheringToggle(enable) {
if (!enable) {
this.tetheringSettings[SETTINGS_USB_ENABLED] = false;
this.enableUsbRndis(false, this.enableUsbRndisResult);
@ -797,72 +777,6 @@ NetworkManager.prototype = {
this.enableUsbRndis(true, this.enableUsbRndisResult);
},
getWifiTetheringParameters: function getWifiTetheringParameters(enable, tetheringinterface) {
let ssid;
let securityType;
let securityId;
let interfaceIp;
let prefix;
let dhcpStartIp;
let dhcpEndIp;
let dns1;
let dns2;
let internalInterface = tetheringinterface.internalInterface;
let externalInterface = tetheringinterface.externalInterface;
ssid = this.tetheringSettings[SETTINGS_WIFI_SSID];
securityType = this.tetheringSettings[SETTINGS_WIFI_SECURITY_TYPE];
securityId = this.tetheringSettings[SETTINGS_WIFI_SECURITY_PASSWORD];
interfaceIp = this.tetheringSettings[SETTINGS_WIFI_IP];
prefix = this.tetheringSettings[SETTINGS_WIFI_PREFIX];
dhcpStartIp = this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_STARTIP];
dhcpEndIp = this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_ENDIP];
dns1 = this.tetheringSettings[SETTINGS_WIFI_DNS1];
dns2 = this.tetheringSettings[SETTINGS_WIFI_DNS2];
// Check the format to prevent netd from crash.
if (!ssid || ssid == "") {
debug("Invalid SSID value.");
return null;
}
if (securityType != WIFI_SECURITY_TYPE_NONE &&
securityType != WIFI_SECURITY_TYPE_WPA_PSK &&
securityType != WIFI_SECURITY_TYPE_WPA2_PSK) {
debug("Invalid security type.");
return null;
}
if (securityType != WIFI_SECURITY_TYPE_NONE && !securityId) {
debug("Invalid security password.");
return null;
}
// Using the default values here until application supports these settings.
if (interfaceIp == "" || prefix == "" ||
dhcpStartIp == "" || dhcpEndIp == "") {
debug("Invalid subnet information.");
return null;
}
return {
ifname: internalInterface,
wifictrlinterfacename: WIFI_CTRL_INTERFACE,
ssid: ssid,
security: securityType,
key: securityId,
ip: interfaceIp,
prefix: prefix,
startIp: dhcpStartIp,
endIp: dhcpEndIp,
dns1: dns1,
dns2: dns2,
internalIfname: internalInterface,
externalIfname: externalInterface,
enable: enable,
mode: enable ? WIFI_FIRMWARE_AP : WIFI_FIRMWARE_STATION,
link: enable ? NETWORK_INTERFACE_UP : NETWORK_INTERFACE_DOWN
};
},
getUSBTetheringParameters: function getUSBTetheringParameters(enable, tetheringinterface) {
let interfaceIp;
let prefix;
@ -902,14 +816,9 @@ NetworkManager.prototype = {
};
},
get wifiTetheringEnabled() {
return this.tetheringSettings[SETTINGS_WIFI_ENABLED];
},
notifyError: function notifyError(resetSettings, callback, msg) {
if (resetSettings) {
let settingsLock = gSettingsService.createLock();
this.tetheringSettings[SETTINGS_WIFI_ENABLED] = false;
// Disable wifi tethering with a useful error message for the user.
settingsLock.set("tethering.wifi.enabled", false, null, msg);
}
@ -922,16 +831,17 @@ NetworkManager.prototype = {
},
// Enable/disable WiFi tethering by sending commands to netd.
setWifiTethering: function setWifiTethering(enable, network, callback) {
if (this.tetheringSettings[SETTINGS_WIFI_ENABLED] == enable) {
this.notifyError(false, callback, "no change");
return;
}
setWifiTethering: function setWifiTethering(enable, network, config, callback) {
if (!network) {
this.notifyError(true, callback, "invalid network information");
return;
}
if (!config) {
this.notifyError(true, callback, "invalid configuration");
return;
}
this._tetheringInterface[TETHERING_TYPE_WIFI].internalInterface = network.name;
let mobile = this.getNetworkInterface(Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE);
@ -939,27 +849,22 @@ NetworkManager.prototype = {
if (mobile) {
this._tetheringInterface[TETHERING_TYPE_WIFI].externalInterface = mobile.name;
}
// Clear this flag to prevent unexpected action.
this.waitForConnectionReadyCallback = null;
let params = this.getWifiTetheringParameters(enable, this._tetheringInterface[TETHERING_TYPE_WIFI]);
if (!params) {
this.notifyError(true, callback, "invalid parameters");
return;
}
config.ifname = this._tetheringInterface[TETHERING_TYPE_WIFI].internalInterface;
config.internalIfname = this._tetheringInterface[TETHERING_TYPE_WIFI].internalInterface;
config.externalIfname = this._tetheringInterface[TETHERING_TYPE_WIFI].externalInterface;
config.wifictrlinterfacename = WIFI_CTRL_INTERFACE;
params.cmd = "setWifiTethering";
config.cmd = "setWifiTethering";
// The callback function in controlMessage may not be fired immediately.
params.isAsync = true;
this.controlMessage(params, function setWifiTetheringResult(data) {
config.isAsync = true;
this.controlMessage(config, function setWifiTetheringResult(data) {
let code = data.resultCode;
let reason = data.resultReason;
let enable = data.enable;
let enableString = enable ? "Enable" : "Disable";
debug(enableString + " Wifi tethering result: Code " + code + " reason " + reason);
// Update settings status.
this.tetheringSettings[SETTINGS_WIFI_ENABLED] = enable;
if (isError(code)) {
this.notifyError(true, callback, "netd command error");
@ -970,7 +875,9 @@ NetworkManager.prototype = {
},
// Enable/disable USB tethering by sending commands to netd.
setUSBTethering: function setUSBTethering(enable, tetheringInterface) {
setUSBTethering: function setUSBTethering(enable,
tetheringInterface,
callback) {
let params = this.getUSBTetheringParameters(enable, tetheringInterface);
if (params === null) {
@ -979,15 +886,15 @@ NetworkManager.prototype = {
resultCode: NETD_COMMAND_ERROR,
resultReason: "Invalid parameters"
};
this.usbTetheringResultReport(params);
this.enableUsbRndis(false, null);
this.usbTetheringResultReport(params);
return;
}
params.cmd = "setUSBTethering";
// The callback function in controlMessage may not be fired immediately.
params.isAsync = true;
this.controlMessage(params, this.usbTetheringResultReport);
this.controlMessage(params, callback);
},
getUsbInterface: function getUsbInterface() {
@ -1012,7 +919,9 @@ NetworkManager.prototype = {
let enable = data.enable;
if (result) {
this._tetheringInterface[TETHERING_TYPE_USB].internalInterface = this.getUsbInterface();
this.setUSBTethering(enable, this._tetheringInterface[TETHERING_TYPE_USB]);
this.setUSBTethering(enable,
this._tetheringInterface[TETHERING_TYPE_USB],
this.usbTetheringResultReport);
} else {
let params = {
enable: false,
@ -1040,6 +949,7 @@ NetworkManager.prototype = {
// The callback function in controlMessage may not be fired immediately.
params.isAsync = true;
this._usbTetheringAction = TETHERING_STATE_ONGOING;
this.controlMessage(params, callback);
},
@ -1051,11 +961,84 @@ NetworkManager.prototype = {
let settingsLock = gSettingsService.createLock();
debug(enableString + " USB tethering result: Code " + code + " reason " + reason);
this._usbTetheringAction = TETHERING_STATE_IDLE;
// Disable tethering settings when fail to enable it.
if (isError(code)) {
this.tetheringSettings[SETTINGS_USB_ENABLED] = false;
settingsLock.set("tethering.usb.enabled", false, null);
// Skip others request when we found an error.
this._requestCount = 0;
} else {
this.handleLastRequest();
}
},
updateUpStream: function updateUpStream(previous, current, callback) {
let params = {
cmd: "updateUpStream",
isAsync: true,
previous: previous,
current: current
};
this.controlMessage(params, callback);
},
onConnectionChangedReport: function onConnectionChangedReport(data) {
let code = data.resultCode;
let reason = data.resultReason;
debug("onConnectionChangedReport result: Code " + code + " reason " + reason);
if (!isError(code)) {
// Update the external interface.
this._tetheringInterface[TETHERING_TYPE_USB].externalInterface = data.current.externalIfname;
debug("Change the interface name to " + data.current.externalIfname);
}
},
onConnectionChanged: function onConnectionChanged(network) {
if (network.state != Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED) {
debug("We are only interested in CONNECTED event");
return;
}
if (!this.tetheringSettings[SETTINGS_USB_ENABLED]) {
debug("Usb tethering settings is not enabled");
return;
}
if (this._tetheringInterface[TETHERING_TYPE_USB].externalInterface ===
this.active.name) {
debug("The active interface is the same");
return;
}
let previous = {
internalIfname: this._tetheringInterface[TETHERING_TYPE_USB].internalInterface,
externalIfname: this._tetheringInterface[TETHERING_TYPE_USB].externalInterface
};
let current = {
internalIfname: this._tetheringInterface[TETHERING_TYPE_USB].internalInterface,
externalIfname: network.name
};
let callback = (function () {
// Update external network interface.
debug("Update upstream interface to " + network.name);
this.updateUpStream(previous, current, this.onConnectionChangedReport);
}).bind(this);
if (this._usbTetheringAction === TETHERING_STATE_ONGOING) {
debug("Postpone the event and handle it when state is idle.");
this.wantConnectionEvent = callback;
return;
}
this.wantConnectionEvent = null;
callback.call(this);
}
};

View File

@ -116,9 +116,6 @@ function usbTetheringFail(params) {
postMessage(params);
// Try to roll back to ensure
// we don't leave the network systems in limbo.
let functionChain = [setIpForwardingEnabled,
stopTethering];
// This parameter is used to disable ipforwarding.
params.enable = false;
chain(params, gUSBFailChain, null);
@ -147,6 +144,18 @@ function networkInterfaceStatsSuccess(params) {
return true;
}
function updateUpStreamSuccess(params) {
// Notify the main thread.
postMessage(params);
return true;
}
function updateUpStreamFail(params) {
// Notify the main thread.
postMessage(params);
return true;
}
/**
* Get network interface properties from the system property table.
*
@ -442,6 +451,18 @@ function setAccessPoint(params, callback) {
return doCommand(command, callback);
}
function cleanUpStream(params, callback) {
let command = "nat disable " + params.previous.internalIfname + " " +
params.previous.externalIfname + " " + "0";
return doCommand(command, callback);
}
function createUpStream(params, callback) {
let command = "nat enable " + params.current.internalIfname + " " +
params.current.externalIfname + " " + "0";
return doCommand(command, callback);
}
/**
* Modify usb function's property to turn on USB RNDIS function
*/
@ -616,6 +637,16 @@ function setWifiTethering(params) {
return true;
}
let gUpdateUpStreamChain = [cleanUpStream,
createUpStream,
updateUpStreamSuccess];
/**
* handling upstream interface change event.
*/
function updateUpStream(params) {
chain(params, gUpdateUpStreamChain, updateUpStreamFail);
}
let gUSBEnableChain = [setInterfaceUp,
enableNat,
setIpForwardingEnabled,

View File

@ -112,7 +112,7 @@ interface nsINetworkStatsCallback : nsISupports
/**
* Manage network interfaces.
*/
[scriptable, uuid(4bee9633-47ed-47ae-b92b-3e0679087561)]
[scriptable, uuid(24f8ede0-c862-11e2-8b8b-0800200c9a66)]
interface nsINetworkManager : nsISupports
{
/**
@ -180,11 +180,6 @@ interface nsINetworkManager : nsISupports
*/
long overrideActive(in nsINetworkInterface network);
/**
* Returns whether or not wifi tethering is currently enabled.
*/
readonly attribute boolean wifiTetheringEnabled;
/**
* Enable or disable Wifi Tethering
*
@ -192,11 +187,14 @@ interface nsINetworkManager : nsISupports
* Boolean that indicates whether tethering should be enabled (true) or disabled (false).
* @param network
* The Wifi network interface with at least name of network interface.
* @param config
* The Wifi Tethering configuration from settings db.
* @param callback
* Callback function used to report status to WifiManager.
*/
void setWifiTethering(in boolean enabled,
in nsINetworkInterface networkInterface,
in jsval config,
in nsIWifiTetheringCallback callback);
/**

View File

@ -24,6 +24,41 @@ const kMozSettingsChangedObserverTopic = "mozsettings-changed";
const MAX_RETRIES_ON_AUTHENTICATION_FAILURE = 2;
const MAX_SUPPLICANT_LOOP_ITERATIONS = 4;
// Settings DB path for wifi
const SETTINGS_WIFI_ENABLED = "wifi.enabled";
const SETTINGS_WIFI_DEBUG_ENABLED = "wifi.debugging.enabled";
// Settings DB path for Wifi tethering.
const SETTINGS_WIFI_TETHERING_ENABLED = "tethering.wifi.enabled";
const SETTINGS_WIFI_SSID = "tethering.wifi.ssid";
const SETTINGS_WIFI_SECURITY_TYPE = "tethering.wifi.security.type";
const SETTINGS_WIFI_SECURITY_PASSWORD = "tethering.wifi.security.password";
const SETTINGS_WIFI_IP = "tethering.wifi.ip";
const SETTINGS_WIFI_PREFIX = "tethering.wifi.prefix";
const SETTINGS_WIFI_DHCPSERVER_STARTIP = "tethering.wifi.dhcpserver.startip";
const SETTINGS_WIFI_DHCPSERVER_ENDIP = "tethering.wifi.dhcpserver.endip";
const SETTINGS_WIFI_DNS1 = "tethering.wifi.dns1";
const SETTINGS_WIFI_DNS2 = "tethering.wifi.dns2";
// Default value for WIFI tethering.
const DEFAULT_WIFI_IP = "192.168.1.1";
const DEFAULT_WIFI_PREFIX = "24";
const DEFAULT_WIFI_DHCPSERVER_STARTIP = "192.168.1.10";
const DEFAULT_WIFI_DHCPSERVER_ENDIP = "192.168.1.30";
const DEFAULT_WIFI_SSID = "FirefoxHotspot";
const DEFAULT_WIFI_SECURITY_TYPE = "open";
const DEFAULT_WIFI_SECURITY_PASSWORD = "1234567890";
const DEFAULT_DNS1 = "8.8.8.8";
const DEFAULT_DNS2 = "8.8.4.4";
const WIFI_FIRMWARE_AP = "AP";
const WIFI_FIRMWARE_STATION = "STA";
const WIFI_SECURITY_TYPE_NONE = "open";
const WIFI_SECURITY_TYPE_WPA_PSK = "wpa-psk";
const WIFI_SECURITY_TYPE_WPA2_PSK = "wpa2-psk";
const NETWORK_INTERFACE_UP = "up";
const NETWORK_INTERFACE_DOWN = "down";
XPCOMUtils.defineLazyServiceGetter(this, "gNetworkManager",
"@mozilla.org/network/manager;1",
"nsINetworkManager");
@ -1142,7 +1177,7 @@ var WifiManager = (function() {
}
// Get wifi interface and load wifi driver when enable Ap mode.
manager.setWifiApEnabled = function(enabled, callback) {
manager.setWifiApEnabled = function(enabled, configuration, callback) {
if (enabled) {
manager.tetheringState = "INITIALIZING";
getProperty("wifi.interface", "tiwlan0", function (ifname) {
@ -1162,7 +1197,8 @@ var WifiManager = (function() {
function doStartWifiTethering() {
cancelWaitForDriverReadyTimer();
WifiNetworkInterface.name = manager.ifname;
gNetworkManager.setWifiTethering(enabled, WifiNetworkInterface, function(result) {
gNetworkManager.setWifiTethering(enabled, WifiNetworkInterface,
configuration, function(result) {
if (result) {
manager.tetheringState = "UNINITIALIZED";
} else {
@ -1182,7 +1218,8 @@ var WifiManager = (function() {
});
});
} else {
gNetworkManager.setWifiTethering(enabled, WifiNetworkInterface, function(result) {
gNetworkManager.setWifiTethering(enabled, WifiNetworkInterface,
configuration, function(result) {
// Should we fire a dom event if we fail to set wifi tethering ?
debug("Disable Wifi tethering result: " + (result ? result : "successfully"));
// Unload wifi driver even if we fail to control wifi tethering.
@ -1661,6 +1698,10 @@ function WifiWorker() {
this._connectionInfoTimer = null;
this._reconnectOnDisconnect = false;
// Users of instances of nsITimer should keep a reference to the timer until
// it is no longer needed in order to assure the timer is fired.
this._callbackTimer = null;
// XXX On some phones (Otoro and Unagi) the wifi driver doesn't play nicely
// with the automatic scans that wpa_supplicant does (it appears that the
// driver forgets that it's returned scan results and then refuses to try to
@ -1912,7 +1953,7 @@ function WifiWorker() {
// We get the ASSOCIATED event when we've associated but not connected, so
// wait until the handshake is complete.
if (this.fromStatus) {
if (this.fromStatus || !self.currentNetwork) {
// In this case, we connected to an already-connected wpa_supplicant,
// because of that we need to gather information about the current
// network here.
@ -2114,21 +2155,21 @@ function WifiWorker() {
// nsISettingsServiceCallback implementation
var initWifiEnabledCb = {
handle: function handle(aName, aResult) {
if (aName !== "wifi.enabled")
if (aName !== SETTINGS_WIFI_ENABLED)
return;
if (aResult === null)
aResult = true;
self.setWifiEnabled({enabled: aResult});
self.handleWifiEnabled(aResult);
},
handleError: function handleError(aErrorMessage) {
debug("Error reading the 'wifi.enabled' setting. Default to wifi on.");
self.setWifiEnabled({enabled: true});
self.handleWifiEnabled(true);
}
};
var initWifiDebuggingEnabledCb = {
handle: function handle(aName, aResult) {
if (aName !== "wifi.debugging.enabled")
if (aName !== SETTINGS_WIFI_DEBUG_ENABLED)
return;
if (aResult === null)
aResult = false;
@ -2142,9 +2183,34 @@ function WifiWorker() {
}
};
this.initTetheringSettings();
let lock = gSettingsService.createLock();
lock.get("wifi.enabled", initWifiEnabledCb);
lock.get("wifi.debugging.enabled", initWifiDebuggingEnabledCb);
lock.get(SETTINGS_WIFI_ENABLED, initWifiEnabledCb);
lock.get(SETTINGS_WIFI_DEBUG_ENABLED, initWifiDebuggingEnabledCb);
lock.get(SETTINGS_WIFI_SSID, this);
lock.get(SETTINGS_WIFI_SECURITY_TYPE, this);
lock.get(SETTINGS_WIFI_SECURITY_PASSWORD, this);
lock.get(SETTINGS_WIFI_IP, this);
lock.get(SETTINGS_WIFI_PREFIX, this);
lock.get(SETTINGS_WIFI_DHCPSERVER_STARTIP, this);
lock.get(SETTINGS_WIFI_DHCPSERVER_ENDIP, this);
lock.get(SETTINGS_WIFI_DNS1, this);
lock.get(SETTINGS_WIFI_DNS2, this);
lock.get(SETTINGS_WIFI_TETHERING_ENABLED, this);
this._wifiTetheringSettingsToRead = [SETTINGS_WIFI_SSID,
SETTINGS_WIFI_SECURITY_TYPE,
SETTINGS_WIFI_SECURITY_PASSWORD,
SETTINGS_WIFI_IP,
SETTINGS_WIFI_PREFIX,
SETTINGS_WIFI_DHCPSERVER_STARTIP,
SETTINGS_WIFI_DHCPSERVER_ENDIP,
SETTINGS_WIFI_DNS1,
SETTINGS_WIFI_DNS2,
SETTINGS_WIFI_TETHERING_ENABLED];
}
function translateState(state) {
@ -2178,12 +2244,32 @@ WifiWorker.prototype = {
Ci.nsIObserver]}),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWorkerHolder,
Ci.nsIWifi]),
Ci.nsIWifi,
Ci.nsISettingsServiceCallback]),
disconnectedByWifi: false,
disconnectedByWifiTethering: false,
_wifiTetheringSettingsToRead: [],
_oldWifiTetheringEnabledState: null,
tetheringSettings: {},
initTetheringSettings: function initTetheringSettings() {
this.tetheringSettings[SETTINGS_WIFI_ENABLED] = false;
this.tetheringSettings[SETTINGS_WIFI_SSID] = DEFAULT_WIFI_SSID;
this.tetheringSettings[SETTINGS_WIFI_SECURITY_TYPE] = DEFAULT_WIFI_SECURITY_TYPE;
this.tetheringSettings[SETTINGS_WIFI_SECURITY_PASSWORD] = DEFAULT_WIFI_SECURITY_PASSWORD;
this.tetheringSettings[SETTINGS_WIFI_IP] = DEFAULT_WIFI_IP;
this.tetheringSettings[SETTINGS_WIFI_PREFIX] = DEFAULT_WIFI_PREFIX;
this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_STARTIP] = DEFAULT_WIFI_DHCPSERVER_STARTIP;
this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_ENDIP] = DEFAULT_WIFI_DHCPSERVER_ENDIP;
this.tetheringSettings[SETTINGS_WIFI_DNS1] = DEFAULT_DNS1;
this.tetheringSettings[SETTINGS_WIFI_DNS2] = DEFAULT_DNS2;
},
// Internal methods.
waitForScan: function(callback) {
this.wantScanResults.push(callback);
@ -2585,12 +2671,11 @@ WifiWorker.prototype = {
!("callback" in this._stateRequests[0]) &&
this._stateRequests[0].enabled === state);
}
// If there were requests queued after this one, run them.
if (this._stateRequests.length > 0) {
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
let self = this;
timer.initWithCallback(function(timer) {
this._callbackTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
this._callbackTimer.initWithCallback(function(timer) {
if ("callback" in self._stateRequests[0]) {
self._stateRequests[0].callback.call(self, self._stateRequests[0].enabled);
} else {
@ -2643,8 +2728,75 @@ WifiWorker.prototype = {
this.setWifiEnabled({enabled: enabled, callback: callback});
},
getWifiTetheringParameters: function getWifiTetheringParameters(enable) {
let ssid;
let securityType;
let securityId;
let interfaceIp;
let prefix;
let dhcpStartIp;
let dhcpEndIp;
let dns1;
let dns2;
ssid = this.tetheringSettings[SETTINGS_WIFI_SSID];
securityType = this.tetheringSettings[SETTINGS_WIFI_SECURITY_TYPE];
securityId = this.tetheringSettings[SETTINGS_WIFI_SECURITY_PASSWORD];
interfaceIp = this.tetheringSettings[SETTINGS_WIFI_IP];
prefix = this.tetheringSettings[SETTINGS_WIFI_PREFIX];
dhcpStartIp = this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_STARTIP];
dhcpEndIp = this.tetheringSettings[SETTINGS_WIFI_DHCPSERVER_ENDIP];
dns1 = this.tetheringSettings[SETTINGS_WIFI_DNS1];
dns2 = this.tetheringSettings[SETTINGS_WIFI_DNS2];
// Check the format to prevent netd from crash.
if (!ssid || ssid == "") {
debug("Invalid SSID value.");
return null;
}
if (securityType != WIFI_SECURITY_TYPE_NONE &&
securityType != WIFI_SECURITY_TYPE_WPA_PSK &&
securityType != WIFI_SECURITY_TYPE_WPA2_PSK) {
debug("Invalid security type.");
return null;
}
if (securityType != WIFI_SECURITY_TYPE_NONE && !securityId) {
debug("Invalid security password.");
return null;
}
// Using the default values here until application supports these settings.
if (interfaceIp == "" || prefix == "" ||
dhcpStartIp == "" || dhcpEndIp == "") {
debug("Invalid subnet information.");
return null;
}
return {
ssid: ssid,
security: securityType,
key: securityId,
ip: interfaceIp,
prefix: prefix,
startIp: dhcpStartIp,
endIp: dhcpEndIp,
dns1: dns1,
dns2: dns2,
enable: enable,
mode: enable ? WIFI_FIRMWARE_AP : WIFI_FIRMWARE_STATION,
link: enable ? NETWORK_INTERFACE_UP : NETWORK_INTERFACE_DOWN
};
},
setWifiApEnabled: function(enabled, callback) {
WifiManager.setWifiApEnabled(enabled, callback);
let configuration = this.getWifiTetheringParameters(enabled);
if (!configuration) {
debug("Invalid Wifi Tethering configuration.");
return;
}
WifiManager.setWifiApEnabled(enabled, configuration, callback);
},
associate: function(msg) {
@ -2849,8 +3001,9 @@ WifiWorker.prototype = {
// It's really sad that we don't have an API to notify the wifi
// hotspot status. Toggle settings to let gaia know that wifi hotspot
// is enabled.
this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED] = true;
gSettingsService.createLock().set(
"tethering.wifi.enabled", true, null, "fromInternalSetting");
SETTINGS_WIFI_TETHERING_ENABLED, true, null, "fromInternalSetting");
// Check for the next request.
this.nextRequest();
},
@ -2859,8 +3012,9 @@ WifiWorker.prototype = {
// It's really sad that we don't have an API to notify the wifi
// hotspot status. Toggle settings to let gaia know that wifi hotspot
// is disabled.
this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED] = false;
gSettingsService.createLock().set(
"tethering.wifi.enabled", false, null, "fromInternalSetting");
SETTINGS_WIFI_TETHERING_ENABLED, false, null, "fromInternalSetting");
// Check for the next request.
this.nextRequest();
},
@ -2870,7 +3024,7 @@ WifiWorker.prototype = {
return;
}
// Make sure Wifi hotspot is idle before switching to Wifi mode.
if (enabled && (gNetworkManager.wifiTetheringEnabled ||
if (enabled && (this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED] ||
WifiManager.tetheringState != "UNINITIALIZED")) {
this.queueRequest(false, function(data) {
this.disconnectedByWifi = true;
@ -2878,7 +3032,7 @@ WifiWorker.prototype = {
}.bind(this));
}
this.setWifiEnabled({enabled: enabled});
if (!enabled && this.disconnectedByWifi) {
this.queueRequest(true, function(data) {
this.disconnectedByWifi = false;
@ -2888,10 +3042,6 @@ WifiWorker.prototype = {
},
handleWifiTetheringEnabled: function(enabled) {
if (gNetworkManager.wifiTetheringEnabled === enabled) {
return;
}
// Make sure Wifi is idle before switching to Wifi hotspot mode.
if (enabled && (WifiManager.enabled ||
WifiManager.state != "UNINITIALIZED")) {
@ -2920,30 +3070,74 @@ WifiWorker.prototype = {
}
let setting = JSON.parse(data);
if (setting.key === "wifi.debugging.enabled") {
DEBUG = setting.value;
updateDebug();
return;
}
if (setting.key !== "wifi.enabled" &&
setting.key !== "tethering.wifi.enabled") {
return;
}
// To avoid WifiWorker setting the wifi again, don't need to deal with
// the "mozsettings-changed" event fired from internal setting.
if (setting.message && setting.message === "fromInternalSetting") {
return;
}
switch (setting.key) {
case "wifi.enabled":
this.handleWifiEnabled(setting.value)
this.handle(setting.key, setting.value);
},
handle: function handle(aName, aResult) {
switch(aName) {
case SETTINGS_WIFI_ENABLED:
this.handleWifiEnabled(aResult)
break;
case "tethering.wifi.enabled":
this.handleWifiTetheringEnabled(setting.value)
case SETTINGS_WIFI_DEBUG_ENABLED:
if (aResult === null)
aResult = false;
DEBUG = aResult;
updateDebug();
break;
}
}
case SETTINGS_WIFI_TETHERING_ENABLED:
this._oldWifiTetheringEnabledState = this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED];
// Fall through!
case SETTINGS_WIFI_SSID:
case SETTINGS_WIFI_SECURITY_TYPE:
case SETTINGS_WIFI_SECURITY_PASSWORD:
case SETTINGS_WIFI_IP:
case SETTINGS_WIFI_PREFIX:
case SETTINGS_WIFI_DHCPSERVER_STARTIP:
case SETTINGS_WIFI_DHCPSERVER_ENDIP:
case SETTINGS_WIFI_DNS1:
case SETTINGS_WIFI_DNS2:
if (aResult !== null) {
this.tetheringSettings[aName] = aResult;
}
debug("'" + aName + "'" + " is now " + this.tetheringSettings[aName]);
let index = this._wifiTetheringSettingsToRead.indexOf(aName);
if (index != -1) {
this._wifiTetheringSettingsToRead.splice(index, 1);
}
if (this._wifiTetheringSettingsToRead.length) {
debug("We haven't read completely the wifi Tethering data from settings db.");
break;
}
if (this._oldWifiTetheringEnabledState === this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED]) {
debug("No changes for SETTINGS_WIFI_TETHERING_ENABLED flag. Nothing to do.");
break;
}
if (this._oldWifiTetheringEnabledState === null &&
!this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED]) {
debug("Do nothing when initial settings for SETTINGS_WIFI_TETHERING_ENABLED flag is false.");
break;
}
this.handleWifiTetheringEnabled(aResult)
break;
};
},
handleError: function handleError(aErrorMessage) {
debug("There was an error while reading Tethering settings.");
this.tetheringSettings = {};
this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED] = false;
},
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([WifiWorker]);

View File

@ -25,6 +25,8 @@
#include "GeckoProfiler.h"
#include "cutils/properties.h"
using namespace android;
using namespace base;
using namespace mozilla::layers;
@ -343,6 +345,18 @@ ISurfaceAllocator::PlatformAllocSurfaceDescriptor(const gfxIntSize& aSize,
uint32_t aCaps,
SurfaceDescriptor* aBuffer)
{
// Check for Nexus S to disable gralloc. We only check for this on ICS or
// earlier, in hopes that JB will work.
#ifdef ANDROID_VERSION <= 15
char propValue[PROPERTY_VALUE_MAX];
property_get("ro.product.device", propValue, "None");
if (strcmp("crespo",propValue) == 0) {
NS_WARNING("Nexus S has issues with gralloc, falling back to shmem");
return false;
}
#endif
// Some GL implementations fail to render gralloc textures with
// width < 64. There's not much point in gralloc'ing buffers that
// small anyway, so fall back on shared memory plus a texture

View File

@ -79,7 +79,7 @@ MTRANSPORT_LCPPSRCS = \
transportlayerprsock.cpp \
$(NULL)
ifdef MOZ_B2G_RIL
ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
MTRANSPORT_LCPPSRCS += \
gonk_addrs.cpp \
$(NULL)