Bug 1167132 - Part 2: [NetworkManager] Move network information into a separate interface (NetworkManager). r=echen

This commit is contained in:
Jessica Jong 2015-07-29 02:02:00 -04:00
parent 83ec6bf570
commit 4814a82ec4
3 changed files with 195 additions and 182 deletions

View File

@ -16,7 +16,7 @@ const NETWORKMANAGER_CONTRACTID = "@mozilla.org/network/manager;1";
const NETWORKMANAGER_CID =
Components.ID("{33901e46-33b8-11e1-9869-f46d04d25bcc}");
const DEFAULT_PREFERRED_NETWORK_TYPE = Ci.nsINetworkInterface.NETWORK_TYPE_WIFI;
const DEFAULT_PREFERRED_NETWORK_TYPE = Ci.nsINetworkInfo.NETWORK_TYPE_WIFI;
XPCOMUtils.defineLazyGetter(this, "ppmm", function() {
return Cc["@mozilla.org/parentprocessmessagemanager;1"]
@ -85,24 +85,22 @@ function defineLazyRegExp(obj, name, pattern) {
});
}
function NetworkInterface(aNetwork) {
function ExtraNetworkInfo(aNetwork) {
let ips = {};
let prefixLengths = {};
aNetwork.getAddresses(ips, prefixLengths);
aNetwork.info.getAddresses(ips, prefixLengths);
this.state = aNetwork.state;
this.type = aNetwork.type;
this.name = aNetwork.name;
this.state = aNetwork.info.state;
this.type = aNetwork.info.type;
this.name = aNetwork.info.name;
this.ips = ips.value;
this.prefixLengths = prefixLengths.value;
this.gateways = aNetwork.getGateways();
this.dnses = aNetwork.getDnses();
this.gateways = aNetwork.info.getGateways();
this.dnses = aNetwork.info.getDnses();
this.httpProxyHost = aNetwork.httpProxyHost;
this.httpProxyPort = aNetwork.httpProxyPort;
}
NetworkInterface.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInterface]),
ExtraNetworkInfo.prototype = {
getAddresses: function(aIps, aPrefixLengths) {
aIps.value = this.ips.slice();
aPrefixLengths.value = this.prefixLengths.slice();
@ -114,6 +112,7 @@ NetworkInterface.prototype = {
if (aCount) {
aCount.value = this.gateways.length;
}
return this.gateways.slice();
},
@ -121,6 +120,7 @@ NetworkInterface.prototype = {
if (aCount) {
aCount.value = this.dnses.length;
}
return this.dnses.slice();
}
};
@ -232,11 +232,11 @@ NetworkManager.prototype = {
let interfaces = [];
for each (let i in this.networkInterfaces) {
if ((i.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_MMS && excludeMms) ||
(i.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_SUPL && excludeSupl) ||
(i.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_IMS && excludeIms) ||
(i.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN && excludeDun) ||
(i.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_FOTA && excludeFota)) {
if ((i.type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_MMS && excludeMms) ||
(i.type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_SUPL && excludeSupl) ||
(i.type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_IMS && excludeIms) ||
(i.type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_DUN && excludeDun) ||
(i.type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_FOTA && excludeFota)) {
continue;
}
@ -261,16 +261,16 @@ NetworkManager.prototype = {
}
},
getNetworkId: function(network) {
getNetworkId: function(aNetworkInfo) {
let id = "device";
try {
if (network instanceof Ci.nsIRilNetworkInterface) {
let rilNetwork = network.QueryInterface(Ci.nsIRilNetworkInterface);
id = "ril" + rilNetwork.serviceId;
if (aNetworkInfo instanceof Ci.nsIRilNetworkInfo) {
let rilInfo = aNetworkInfo.QueryInterface(Ci.nsIRilNetworkInfo);
id = "ril" + rilInfo.serviceId;
}
} catch (e) {}
return id + "-" + network.type;
return id + "-" + aNetworkInfo.type;
},
// nsINetworkManager
@ -280,7 +280,7 @@ NetworkManager.prototype = {
throw Components.Exception("Argument must be nsINetworkInterface.",
Cr.NS_ERROR_INVALID_ARG);
}
let networkId = this.getNetworkId(network);
let networkId = this.getNetworkId(network.info);
if (networkId in this.networkInterfaces) {
throw Components.Exception("Network with that type already registered!",
Cr.NS_ERROR_INVALID_ARG);
@ -288,7 +288,7 @@ NetworkManager.prototype = {
this.networkInterfaces[networkId] = network;
this.networkInterfaceLinks[networkId] = new NetworkInterfaceLinks();
Services.obs.notifyObservers(network, TOPIC_INTERFACE_REGISTERED, null);
Services.obs.notifyObservers(network.info, TOPIC_INTERFACE_REGISTERED, null);
debug("Network '" + networkId + "' registered.");
},
@ -316,65 +316,65 @@ NetworkManager.prototype = {
throw Components.Exception("Argument must be nsINetworkInterface.",
Cr.NS_ERROR_INVALID_ARG);
}
let networkId = this.getNetworkId(network);
let networkId = this.getNetworkId(network.info);
if (!(networkId in this.networkInterfaces)) {
throw Components.Exception("No network with that type registered.",
Cr.NS_ERROR_INVALID_ARG);
}
debug("Network " + network.type + "/" + network.name +
" changed state to " + network.state);
debug("Network " + network.info.type + "/" + network.info.name +
" changed state to " + network.info.state);
// Keep a copy of network in case it is modified while we are updating.
let networkInterface = new NetworkInterface(network);
let extNetworkInfo = new ExtraNetworkInfo(network);
// Note that since Lollipop we need to allocate and initialize
// something through netd, so we add createNetwork/destroyNetwork
// to deal with that explicitly.
switch (networkInterface.state) {
case Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED:
switch (extNetworkInfo.state) {
case Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED:
this._createNetwork(networkInterface.name)
this._createNetwork(extNetworkInfo.name)
// Remove pre-created default route and let setAndConfigureActive()
// to set default route only on preferred network
.then(() => this._removeDefaultRoute(networkInterface))
.then(() => this._removeDefaultRoute(extNetworkInfo))
// Set DNS server as early as possible to prevent from
// premature domain name lookup.
.then(() => this._setDNS(networkInterface))
.then(() => this._setDNS(extNetworkInfo))
.then(() => {
// Add host route for data calls
if (!this.isNetworkTypeMobile(networkInterface.type)) {
if (!this.isNetworkTypeMobile(extNetworkInfo.type)) {
return;
}
let currentInterfaceLinks = this.networkInterfaceLinks[networkId];
let newLinkRoutes = networkInterface.getDnses().concat(
networkInterface.httpProxyHost);
let newLinkRoutes = extNetworkInfo.getDnses().concat(
extNetworkInfo.httpProxyHost);
// If gateways have changed, remove all old routes first.
return this._handleGateways(networkId, networkInterface.getGateways())
return this._handleGateways(networkId, extNetworkInfo.getGateways())
.then(() => this._updateRoutes(currentInterfaceLinks.linkRoutes,
newLinkRoutes,
networkInterface.getGateways(),
networkInterface.name))
extNetworkInfo.getGateways(),
extNetworkInfo.name))
.then(() => currentInterfaceLinks.setLinks(newLinkRoutes,
networkInterface.getGateways(),
networkInterface.name));
extNetworkInfo.getGateways(),
extNetworkInfo.name));
})
.then(() => {
if (networkInterface.type !=
Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN) {
if (extNetworkInfo.type !=
Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_DUN) {
return;
}
// Dun type is a special case where we add the default route to a
// secondary table.
return this.setSecondaryDefaultRoute(networkInterface);
return this.setSecondaryDefaultRoute(extNetworkInfo);
})
.then(() => this._addSubnetRoutes(networkInterface))
.then(() => this._addSubnetRoutes(extNetworkInfo))
.then(() => this.setAndConfigureActive())
.then(() => {
// Update data connection when Wifi connected/disconnected
if (networkInterface.type ==
Ci.nsINetworkInterface.NETWORK_TYPE_WIFI && this.mRil) {
if (extNetworkInfo.type ==
Ci.nsINetworkInfo.NETWORK_TYPE_WIFI && this.mRil) {
for (let i = 0; i < this.mRil.numRadioInterfaces; i++) {
this.mRil.getRadioInterface(i).updateRILNetworkInterface();
}
@ -382,70 +382,74 @@ NetworkManager.prototype = {
// Probing the public network accessibility after routing table is ready
CaptivePortalDetectionHelper
.notify(CaptivePortalDetectionHelper.EVENT_CONNECT, this.active);
.notify(CaptivePortalDetectionHelper.EVENT_CONNECT,
this.activeNetworkInfo);
})
.then(() => {
// Notify outer modules like MmsService to start the transaction after
// the configuration of the network interface is done.
Services.obs.notifyObservers(network, TOPIC_CONNECTION_STATE_CHANGED,
this.convertConnectionType(network));
Services.obs.notifyObservers(network.info,
TOPIC_CONNECTION_STATE_CHANGED,
this.convertConnectionType(network.info));
})
.catch(aError => {
debug("updateNetworkInterface error: " + aError);
});
break;
case Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED:
case Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED:
Promise.resolve()
.then(() => {
if (!this.isNetworkTypeMobile(networkInterface.type)) {
if (!this.isNetworkTypeMobile(extNetworkInfo.type)) {
return;
}
// Remove host route for data calls
return this._cleanupAllHostRoutes(networkId);
})
.then(() => {
if (networkInterface.type !=
Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN) {
if (extNetworkInfo.type !=
Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_DUN) {
return;
}
// Remove secondary default route for dun.
return this.removeSecondaryDefaultRoute(networkInterface);
return this.removeSecondaryDefaultRoute(extNetworkInfo);
})
.then(() => {
if (networkInterface.type == Ci.nsINetworkInterface.NETWORK_TYPE_WIFI) {
if (extNetworkInfo.type == Ci.nsINetworkInfo.NETWORK_TYPE_WIFI) {
// Remove routing table in /proc/net/route
return this._resetRoutingTable(networkInterface.name);
return this._resetRoutingTable(extNetworkInfo.name);
}
if (networkInterface.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE) {
return this._removeDefaultRoute(networkInterface)
if (extNetworkInfo.type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE) {
return this._removeDefaultRoute(extNetworkInfo)
}
})
.then(() => {
// Clear http proxy on active network.
if (this.active && networkInterface.type == this.active.type) {
if (this.activeNetworkInfo &&
extNetworkInfo.type == this.activeNetworkInfo.type) {
this.clearNetworkProxy();
}
// Abort ongoing captive portal detection on the wifi interface
CaptivePortalDetectionHelper
.notify(CaptivePortalDetectionHelper.EVENT_DISCONNECT, networkInterface);
.notify(CaptivePortalDetectionHelper.EVENT_DISCONNECT, extNetworkInfo);
})
.then(() => this.setAndConfigureActive())
.then(() => {
// Update data connection when Wifi connected/disconnected
if (networkInterface.type ==
Ci.nsINetworkInterface.NETWORK_TYPE_WIFI && this.mRil) {
if (extNetworkInfo.type ==
Ci.nsINetworkInfo.NETWORK_TYPE_WIFI && this.mRil) {
for (let i = 0; i < this.mRil.numRadioInterfaces; i++) {
this.mRil.getRadioInterface(i).updateRILNetworkInterface();
}
}
})
.then(() => this._destroyNetwork(networkInterface.name))
.then(() => this._destroyNetwork(extNetworkInfo.name))
.then(() => {
// Notify outer modules like MmsService to start the transaction after
// the configuration of the network interface is done.
Services.obs.notifyObservers(network, TOPIC_CONNECTION_STATE_CHANGED,
this.convertConnectionType(network));
Services.obs.notifyObservers(network.info,
TOPIC_CONNECTION_STATE_CHANGED,
this.convertConnectionType(network.info));
})
.catch(aError => {
debug("updateNetworkInterface error: " + aError);
@ -459,7 +463,7 @@ NetworkManager.prototype = {
throw Components.Exception("Argument must be nsINetworkInterface.",
Cr.NS_ERROR_INVALID_ARG);
}
let networkId = this.getNetworkId(network);
let networkId = this.getNetworkId(network.info);
if (!(networkId in this.networkInterfaces)) {
throw Components.Exception("No network with that type registered.",
Cr.NS_ERROR_INVALID_ARG);
@ -467,13 +471,13 @@ NetworkManager.prototype = {
// This is for in case a network gets unregistered without being
// DISCONNECTED.
if (this.isNetworkTypeMobile(network.type)) {
if (this.isNetworkTypeMobile(network.info.type)) {
this._cleanupAllHostRoutes(networkId);
}
delete this.networkInterfaces[networkId];
Services.obs.notifyObservers(network, TOPIC_INTERFACE_UNREGISTERED, null);
Services.obs.notifyObservers(network.info, TOPIC_INTERFACE_UNREGISTERED, null);
debug("Network '" + networkId + "' unregistered.");
},
@ -488,19 +492,25 @@ NetworkManager.prototype = {
return this._preferredNetworkType;
},
set preferredNetworkType(val) {
if ([Ci.nsINetworkInterface.NETWORK_TYPE_WIFI,
Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE].indexOf(val) == -1) {
if ([Ci.nsINetworkInfo.NETWORK_TYPE_WIFI,
Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE].indexOf(val) == -1) {
throw "Invalid network type";
}
this._preferredNetworkType = val;
},
active: null,
_activeNetwork: null,
get activeNetworkInfo() {
return this._activeNetwork && this._activeNetwork.info;
},
_overriddenActive: null,
overrideActive: function(network) {
if ([Ci.nsINetworkInterface.NETWORK_TYPE_WIFI,
Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE].indexOf(val) == -1) {
let type = network.info.type;
if ([Ci.nsINetworkInfo.NETWORK_TYPE_WIFI,
Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE].indexOf(type) == -1) {
throw "Invalid network type";
}
@ -548,10 +558,10 @@ NetworkManager.prototype = {
return Promise.all(promises);
},
isValidatedNetwork: function(network) {
isValidatedNetwork: function(aNetworkInfo) {
let isValid = false;
try {
isValid = (this.getNetworkId(network) in this.networkInterfaces);
isValid = (this.getNetworkId(aNetworkInfo) in this.networkInterfaces);
} catch (e) {
debug("Invalid network interface: " + e);
}
@ -559,19 +569,19 @@ NetworkManager.prototype = {
return isValid;
},
addHostRoute: function(network, host) {
if (!this.isValidatedNetwork(network)) {
return Promise.reject("Invalid network interface.");
addHostRoute: function(aNetworkInfo, aHost) {
if (!this.isValidatedNetwork(aNetworkInfo)) {
return Promise.reject("Invalid network info.");
}
return this.resolveHostname(network, host)
return this.resolveHostname(aNetworkInfo, aHost)
.then((ipAddresses) => {
let promises = [];
let networkId = this.getNetworkId(network);
let networkId = this.getNetworkId(aNetworkInfo);
ipAddresses.forEach((aIpAddress) => {
let promise =
this._setHostRoutes(true, [aIpAddress], network.name, network.getGateways())
this._setHostRoutes(true, [aIpAddress], aNetworkInfo.name, aNetworkInfo.getGateways())
.then(() => this.networkInterfaceLinks[networkId].extraRoutes.push(aIpAddress));
promises.push(promise);
@ -581,15 +591,15 @@ NetworkManager.prototype = {
});
},
removeHostRoute: function(network, host) {
if (!this.isValidatedNetwork(network)) {
return Promise.reject("Invalid network interface.");
removeHostRoute: function(aNetworkInfo, aHost) {
if (!this.isValidatedNetwork(aNetworkInfo)) {
return Promise.reject("Invalid network info.");
}
return this.resolveHostname(network, host)
return this.resolveHostname(aNetworkInfo, aHost)
.then((ipAddresses) => {
let promises = [];
let networkId = this.getNetworkId(network);
let networkId = this.getNetworkId(aNetworkInfo);
ipAddresses.forEach((aIpAddress) => {
let found = this.networkInterfaceLinks[networkId].extraRoutes.indexOf(aIpAddress);
@ -598,7 +608,7 @@ NetworkManager.prototype = {
}
let promise =
this._setHostRoutes(false, [aIpAddress], network.name, network.getGateways())
this._setHostRoutes(false, [aIpAddress], aNetworkInfo.name, aNetworkInfo.getGateways())
.then(() => {
this.networkInterfaceLinks[networkId].extraRoutes.splice(found, 1);
}, () => {
@ -613,15 +623,15 @@ NetworkManager.prototype = {
},
isNetworkTypeSecondaryMobile: function(type) {
return (type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_MMS ||
type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_SUPL ||
type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_IMS ||
type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN ||
type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_FOTA);
return (type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_MMS ||
type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_SUPL ||
type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_IMS ||
type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_DUN ||
type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_FOTA);
},
isNetworkTypeMobile: function(type) {
return (type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE ||
return (type == Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE ||
this.isNetworkTypeSecondaryMobile(type));
},
@ -765,62 +775,64 @@ NetworkManager.prototype = {
*/
setAndConfigureActive: function() {
debug("Evaluating whether active network needs to be changed.");
let oldActive = this.active;
let oldActive = this._activeNetwork;
if (this._overriddenActive) {
debug("We have an override for the active network: " +
this._overriddenActive.name);
this._overriddenActive.info.name);
// The override was just set, so reconfigure the network.
if (this.active != this._overriddenActive) {
this.active = this._overriddenActive;
this._setDefaultRouteAndProxy(this.active, oldActive);
Services.obs.notifyObservers(this.active, TOPIC_ACTIVE_CHANGED, null);
if (this._activeNetwork != this._overriddenActive) {
this._activeNetwork = this._overriddenActive;
this._setDefaultRouteAndProxy(this._activeNetwork, oldActive);
Services.obs.notifyObservers(this.activeNetworkInfo,
TOPIC_ACTIVE_CHANGED, null);
}
return;
}
// The active network is already our preferred type.
if (this.active &&
this.active.state == Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED &&
this.active.type == this._preferredNetworkType) {
if (this.activeNetworkInfo &&
this.activeNetworkInfo.state == Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED &&
this.activeNetworkInfo.type == this._preferredNetworkType) {
debug("Active network is already our preferred type.");
return this._setDefaultRouteAndProxy(this.active, oldActive);
return this._setDefaultRouteAndProxy(this._activeNetwork, oldActive);
}
// Find a suitable network interface to activate.
this.active = null;
this._activeNetwork = null;
let anyConnected = false;
for each (let network in this.networkInterfaces) {
if (network.state != Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED) {
if (network.info.state != Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) {
continue;
}
anyConnected = true;
// Set active only for default connections.
if (network.type != Ci.nsINetworkInterface.NETWORK_TYPE_WIFI &&
network.type != Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE) {
if (network.info.type != Ci.nsINetworkInfo.NETWORK_TYPE_WIFI &&
network.info.type != Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE) {
continue;
}
this.active = network;
if (network.type == this.preferredNetworkType) {
debug("Found our preferred type of network: " + network.name);
this._activeNetwork = network;
if (network.info.type == this.preferredNetworkType) {
debug("Found our preferred type of network: " + network.info.name);
break;
}
}
return Promise.resolve()
.then(() => {
if (!this.active) {
if (!this._activeNetwork) {
return Promise.resolve();
}
return this._setDefaultRouteAndProxy(this.active, oldActive);
return this._setDefaultRouteAndProxy(this._activeNetwork, oldActive);
})
.then(() => {
if (this.active != oldActive) {
Services.obs.notifyObservers(this.active, TOPIC_ACTIVE_CHANGED, null);
if (this._activeNetwork != oldActive) {
Services.obs.notifyObservers(this.activeNetworkInfo,
TOPIC_ACTIVE_CHANGED, null);
}
if (this._manageOfflineStatus) {
@ -829,15 +841,15 @@ NetworkManager.prototype = {
});
},
resolveHostname: function(network, hostname) {
resolveHostname: function(aNetworkInfo, aHostname) {
// Sanity check for null, undefined and empty string... etc.
if (!hostname) {
return Promise.reject(new Error("hostname is empty: " + hostname));
if (!aHostname) {
return Promise.reject(new Error("hostname is empty: " + aHostname));
}
if (hostname.match(this.REGEXP_IPV4) ||
hostname.match(this.REGEXP_IPV6)) {
return Promise.resolve([hostname]);
if (aHostname.match(this.REGEXP_IPV4) ||
aHostname.match(this.REGEXP_IPV6)) {
return Promise.resolve([aHostname]);
}
// Wrap gDNSService.asyncResolveExtended to a promise, which
@ -848,7 +860,7 @@ NetworkManager.prototype = {
// Callback for gDNSService.asyncResolveExtended.
let onLookupComplete = (aRequest, aRecord, aStatus) => {
if (!Components.isSuccessCode(aStatus)) {
aReject(new Error("Failed to resolve '" + hostname +
aReject(new Error("Failed to resolve '" + aHostname +
"', with status: " + aStatus));
return;
}
@ -863,14 +875,14 @@ NetworkManager.prototype = {
return;
}
debug("hostname is resolved: " + hostname);
debug("hostname is resolved: " + aHostname);
debug("Addresses: " + JSON.stringify(retval));
aResolve(retval);
};
debug('Calling gDNSService.asyncResolveExtended: ' + aNetId + ', ' + hostname);
gDNSService.asyncResolveExtended(hostname,
debug('Calling gDNSService.asyncResolveExtended: ' + aNetId + ', ' + aHostname);
gDNSService.asyncResolveExtended(aHostname,
0,
aNetId,
onLookupComplete,
@ -880,36 +892,36 @@ NetworkManager.prototype = {
// TODO: |getNetId| will be implemented as a sync call in nsINetworkManager
// once Bug 1141903 is landed.
return gNetworkService.getNetId(network.name)
return gNetworkService.getNetId(aNetworkInfo.name)
.then(aNetId => hostResolveWrapper(aNetId));
},
convertConnectionType: function(network) {
convertConnectionType: function(aNetworkInfo) {
// If there is internal interface change (e.g., MOBILE_MMS, MOBILE_SUPL),
// the function will return null so that it won't trigger type change event
// in NetworkInformation API.
if (network.type != Ci.nsINetworkInterface.NETWORK_TYPE_WIFI &&
network.type != Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE) {
if (aNetworkInfo.type != Ci.nsINetworkInfo.NETWORK_TYPE_WIFI &&
aNetworkInfo.type != Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE) {
return null;
}
if (network.state == Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED) {
if (aNetworkInfo.state == Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED) {
return CONNECTION_TYPE_NONE;
}
switch (network.type) {
case Ci.nsINetworkInterface.NETWORK_TYPE_WIFI:
switch (aNetworkInfo.type) {
case Ci.nsINetworkInfo.NETWORK_TYPE_WIFI:
return CONNECTION_TYPE_WIFI;
case Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE:
case Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE:
return CONNECTION_TYPE_CELLULAR;
}
},
_setDNS: function(aNetwork) {
_setDNS: function(aNetworkInfo) {
return new Promise((aResolve, aReject) => {
let dnses = aNetwork.getDnses();
let gateways = aNetwork.getGateways();
gNetworkService.setDNS(aNetwork.name, dnses.length, dnses,
let dnses = aNetworkInfo.getDnses();
let gateways = aNetworkInfo.getGateways();
gNetworkService.setDNS(aNetworkInfo.name, dnses.length, dnses,
gateways.length, gateways, (aError) => {
if (aError) {
aReject("setDNS failed");
@ -956,10 +968,10 @@ NetworkManager.prototype = {
});
},
_removeDefaultRoute: function(aNetwork) {
_removeDefaultRoute: function(aNetworkInfo) {
return new Promise((aResolve, aReject) => {
let gateways = aNetwork.getGateways();
gNetworkService.removeDefaultRoute(aNetwork.name, gateways.length,
let gateways = aNetworkInfo.getGateways();
gNetworkService.removeDefaultRoute(aNetworkInfo.name, gateways.length,
gateways, (aSuccess) => {
if (!aSuccess) {
debug("removeDefaultRoute failed");
@ -972,12 +984,13 @@ NetworkManager.prototype = {
_setDefaultRouteAndProxy: function(aNetwork, aOldInterface) {
return new Promise((aResolve, aReject) => {
let gateways = aNetwork.getGateways();
let oldInterfaceName = (aOldInterface ? aOldInterface.name : "");
gNetworkService.setDefaultRoute(aNetwork.name, gateways.length, gateways,
let networkInfo = aNetwork.info;
let gateways = networkInfo.getGateways();
let oldInterfaceName = (aOldInterface ? aOldInterface.info.name : "");
gNetworkService.setDefaultRoute(networkInfo.name, gateways.length, gateways,
oldInterfaceName, (aSuccess) => {
if (!aSuccess) {
gNetworkService.destroyNetwork(aNetwork, function() {
gNetworkService.destroyNetwork(networkInfo.name, function() {
aReject("setDefaultRoute failed");
});
return;
@ -988,23 +1001,23 @@ NetworkManager.prototype = {
});
},
setNetworkProxy: function(network) {
setNetworkProxy: function(aNetwork) {
try {
if (!network.httpProxyHost || network.httpProxyHost === "") {
if (!aNetwork.httpProxyHost || aNetwork.httpProxyHost === "") {
// Sets direct connection to internet.
this.clearNetworkProxy();
debug("No proxy support for " + network.name + " network interface.");
debug("No proxy support for " + aNetwork.info.name + " network interface.");
return;
}
debug("Going to set proxy settings for " + network.name + " network interface.");
debug("Going to set proxy settings for " + aNetwork.info.name + " network interface.");
// Do not use this proxy server for all protocols.
Services.prefs.setBoolPref("network.proxy.share_proxy_settings", false);
Services.prefs.setCharPref("network.proxy.http", network.httpProxyHost);
Services.prefs.setCharPref("network.proxy.ssl", network.httpProxyHost);
let port = network.httpProxyPort === 0 ? 8080 : network.httpProxyPort;
Services.prefs.setCharPref("network.proxy.http", aNetwork.httpProxyHost);
Services.prefs.setCharPref("network.proxy.ssl", aNetwork.httpProxyHost);
let port = aNetwork.httpProxyPort === 0 ? 8080 : aNetwork.httpProxyPort;
Services.prefs.setIntPref("network.proxy.http_port", port);
Services.prefs.setIntPref("network.proxy.ssl_port", port);
@ -1022,7 +1035,7 @@ NetworkManager.prototype = {
}
} catch(ex) {
debug("Exception " + ex + ". Unable to set proxy setting for " +
network.name + " network interface.");
aNetwork.info.name + " network interface.");
}
},
@ -1105,7 +1118,7 @@ let CaptivePortalDetectionHelper = (function() {
case EVENT_CONNECT:
// perform captive portal detection on wifi interface
if (_available && network &&
network.type == Ci.nsINetworkInterface.NETWORK_TYPE_WIFI) {
network.type == Ci.nsINetworkInfo.NETWORK_TYPE_WIFI) {
_performDetection(network.name, function() {
// TODO: bug 837600
// We can disconnect wifi in here if user abort the login procedure.
@ -1115,7 +1128,7 @@ let CaptivePortalDetectionHelper = (function() {
break;
case EVENT_DISCONNECT:
if (_available &&
network.type == Ci.nsINetworkInterface.NETWORK_TYPE_WIFI) {
network.type == Ci.nsINetworkInfo.NETWORK_TYPE_WIFI) {
_abort(network.name);
}
break;

View File

@ -9,18 +9,18 @@ const SETTINGS_KEY_DATA_APN_SETTINGS = "ril.data.apnSettings";
const TOPIC_CONNECTION_STATE_CHANGED = "network-connection-state-changed";
const TOPIC_NETWORK_ACTIVE_CHANGED = "network-active-changed";
const NETWORK_STATE_UNKNOWN = Ci.nsINetworkInterface.NETWORK_STATE_UNKNOWN;
const NETWORK_STATE_CONNECTING = Ci.nsINetworkInterface.NETWORK_STATE_CONNECTING;
const NETWORK_STATE_CONNECTED = Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED;
const NETWORK_STATE_DISCONNECTING = Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTING;
const NETWORK_STATE_DISCONNECTED = Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED;
const NETWORK_STATE_UNKNOWN = Ci.nsINetworkInfo.NETWORK_STATE_UNKNOWN;
const NETWORK_STATE_CONNECTING = Ci.nsINetworkInfo.NETWORK_STATE_CONNECTING;
const NETWORK_STATE_CONNECTED = Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED;
const NETWORK_STATE_DISCONNECTING = Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTING;
const NETWORK_STATE_DISCONNECTED = Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED;
const NETWORK_TYPE_MOBILE = Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE;
const NETWORK_TYPE_MOBILE_MMS = Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_MMS;
const NETWORK_TYPE_MOBILE_SUPL = Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_SUPL;
const NETWORK_TYPE_MOBILE_IMS = Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_IMS;
const NETWORK_TYPE_MOBILE_DUN = Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN;
const NETWORK_TYPE_MOBILE_FOTA = Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_FOTA;
const NETWORK_TYPE_MOBILE = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE;
const NETWORK_TYPE_MOBILE_MMS = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_MMS;
const NETWORK_TYPE_MOBILE_SUPL = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_SUPL;
const NETWORK_TYPE_MOBILE_IMS = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_IMS;
const NETWORK_TYPE_MOBILE_DUN = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_DUN;
const NETWORK_TYPE_MOBILE_FOTA = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_FOTA;
const networkTypes = [
NETWORK_TYPE_MOBILE,
@ -144,13 +144,13 @@ function setDataEnabledAndWait(aEnabled) {
let promises = [];
promises.push(waitForObserverEvent(TOPIC_CONNECTION_STATE_CHANGED)
.then(function(aSubject) {
ok(aSubject instanceof Ci.nsIRilNetworkInterface,
"subject should be an instance of nsIRILNetworkInterface");
ok(aSubject instanceof Ci.nsIRilNetworkInfo,
"subject should be an instance of nsIRilNetworkInfo");
is(aSubject.type, NETWORK_TYPE_MOBILE,
"subject.type should be " + NETWORK_TYPE_MOBILE);
is(aSubject.state,
aEnabled ? Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED
: Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED,
aEnabled ? Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED
: Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED,
"subject.state should be " + aEnabled ? "CONNECTED" : "DISCONNECTED");
}));
promises.push(setSettings(SETTINGS_KEY_DATA_ENABLED, aEnabled));
@ -175,11 +175,11 @@ function setupDataCallAndWait(aNetworkType) {
let promises = [];
promises.push(waitForObserverEvent(TOPIC_CONNECTION_STATE_CHANGED)
.then(function(aSubject) {
ok(aSubject instanceof Ci.nsIRilNetworkInterface,
"subject should be an instance of nsIRILNetworkInterface");
ok(aSubject instanceof Ci.nsIRilNetworkInfo,
"subject should be an instance of nsIRilNetworkInfo");
is(aSubject.type, aNetworkType,
"subject.type should be " + aNetworkType);
is(aSubject.state, Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED,
is(aSubject.state, Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED,
"subject.state should be CONNECTED");
}));
promises.push(radioInterface.setupDataCallByType(aNetworkType));
@ -204,11 +204,11 @@ function deactivateDataCallAndWait(aNetworkType) {
let promises = [];
promises.push(waitForObserverEvent(TOPIC_CONNECTION_STATE_CHANGED)
.then(function(aSubject) {
ok(aSubject instanceof Ci.nsIRilNetworkInterface,
"subject should be an instance of nsIRILNetworkInterface");
ok(aSubject instanceof Ci.nsIRilNetworkInfo,
"subject should be an instance of nsIRilNetworkInfo");
is(aSubject.type, aNetworkType,
"subject.type should be " + aNetworkType);
is(aSubject.state, Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED,
is(aSubject.state, Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED,
"subject.state should be DISCONNECTED");
}));
promises.push(radioInterface.deactivateDataCallByType(aNetworkType));

View File

@ -13,8 +13,8 @@ function testInitialState() {
return getSettings(SETTINGS_KEY_DATA_ENABLED)
.then((enabled) => {
is(enabled, false, "data should be off by default");
is(networkManager.active, null,
"networkManager.active should be null by default");
is(networkManager.activeNetworkInfo, null,
"networkManager.activeNetworkInfo should be null by default");
});
}
@ -29,16 +29,16 @@ function testActiveNetworkChangedBySwitchingDataCall(aDataCallEnabled) {
let subject = results[0];
if (aDataCallEnabled) {
ok(subject instanceof Ci.nsINetworkInterface,
"subject should be an instance of nsINetworkInterface");
ok(subject instanceof Ci.nsIRilNetworkInterface,
"subject should be an instance of nsIRILNetworkInterface");
ok(subject instanceof Ci.nsINetworkInfo,
"subject should be an instance of nsINetworkInfo");
ok(subject instanceof Ci.nsIRilNetworkInfo,
"subject should be an instance of nsIRilNetworkInfo");
is(subject.type, NETWORK_TYPE_MOBILE,
"subject.type should be NETWORK_TYPE_MOBILE");
}
is(subject, networkManager.active,
"subject should be equal with networkManager.active");
is(subject, networkManager.activeNetworkInfo,
"subject should be equal with networkManager.activeNetworkInfo");
});
}