mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1126222 - Part 2: Use promise to ensure execution order in NetworkManager. r=echen
This commit is contained in:
parent
7bc34d3788
commit
2ed08371fa
@ -85,6 +85,46 @@ function defineLazyRegExp(obj, name, pattern) {
|
||||
});
|
||||
}
|
||||
|
||||
function NetworkInterface(aNetwork) {
|
||||
let ips = {};
|
||||
let prefixLengths = {};
|
||||
aNetwork.getAddresses(ips, prefixLengths);
|
||||
|
||||
this.state = aNetwork.state;
|
||||
this.type = aNetwork.type;
|
||||
this.name = aNetwork.name;
|
||||
this.ips = ips.value;
|
||||
this.prefixLengths = prefixLengths.value;
|
||||
this.gateways = aNetwork.getGateways();
|
||||
this.dnses = aNetwork.getDnses();
|
||||
this.httpProxyHost = aNetwork.httpProxyHost;
|
||||
this.httpProxyPort = aNetwork.httpProxyPort;
|
||||
}
|
||||
NetworkInterface.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsINetworkInterface]),
|
||||
|
||||
getAddresses: function(aIps, aPrefixLengths) {
|
||||
aIps.value = this.ips.slice();
|
||||
aPrefixLengths.value = this.prefixLengths.slice();
|
||||
|
||||
return this.ips.length;
|
||||
},
|
||||
|
||||
getGateways: function(aCount) {
|
||||
if (aCount) {
|
||||
aCount.value = this.gateways.length;
|
||||
}
|
||||
return this.gateways.slice();
|
||||
},
|
||||
|
||||
getDnses: function(aCount) {
|
||||
if (aCount) {
|
||||
aCount.value = this.dnses.length;
|
||||
}
|
||||
return this.dnses.slice();
|
||||
}
|
||||
};
|
||||
|
||||
function NetworkInterfaceLinks()
|
||||
{
|
||||
this.resetLinks();
|
||||
@ -254,14 +294,19 @@ NetworkManager.prototype = {
|
||||
let ips = {};
|
||||
let prefixLengths = {};
|
||||
let length = network.getAddresses(ips, prefixLengths);
|
||||
let promises = [];
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
debug('Adding subnet routes: ' + ips.value[i] + '/' + prefixLengths.value[i]);
|
||||
gNetworkService.modifyRoute(Ci.nsINetworkService.MODIFY_ROUTE_ADD,
|
||||
network.name, ips.value[i], prefixLengths.value[i])
|
||||
.catch((aError) => {
|
||||
promises.push(
|
||||
gNetworkService.modifyRoute(Ci.nsINetworkService.MODIFY_ROUTE_ADD,
|
||||
network.name, ips.value[i], prefixLengths.value[i])
|
||||
.catch(aError => {
|
||||
debug("_addSubnetRoutes error: " + aError);
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
return Promise.all(promises);
|
||||
},
|
||||
|
||||
updateNetworkInterface: function(network) {
|
||||
@ -277,46 +322,57 @@ NetworkManager.prototype = {
|
||||
debug("Network " + network.type + "/" + network.name +
|
||||
" changed state to " + network.state);
|
||||
|
||||
// Keep a copy of network in case it is modified while we are updating.
|
||||
let networkInterface = new NetworkInterface(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 (network.state) {
|
||||
switch (networkInterface.state) {
|
||||
case Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED:
|
||||
gNetworkService.createNetwork(network.name, () => {
|
||||
|
||||
this._createNetwork(networkInterface.name)
|
||||
// Remove pre-created default route and let setAndConfigureActive()
|
||||
// to set default route only on preferred network
|
||||
gNetworkService.removeDefaultRoute(network);
|
||||
|
||||
.then(() => this._removeDefaultRoute(networkInterface))
|
||||
// Set DNS server as early as possible to prevent from
|
||||
// premature domain name lookup.
|
||||
gNetworkService.setDNS(network, () => {
|
||||
.then(() => this._setDNS(networkInterface))
|
||||
.then(() => {
|
||||
// Add host route for data calls
|
||||
if (this.isNetworkTypeMobile(network.type)) {
|
||||
let currentInterfaceLinks = this.networkInterfaceLinks[networkId];
|
||||
let newLinkRoutes = network.getDnses().concat(network.httpProxyHost);
|
||||
// If gateways have changed, remove all old routes first.
|
||||
this._handleGateways(networkId, network.getGateways())
|
||||
.then(() => this._updateRoutes(currentInterfaceLinks.linkRoutes,
|
||||
newLinkRoutes,
|
||||
network.getGateways(), network.name))
|
||||
.then(() => currentInterfaceLinks.setLinks(newLinkRoutes,
|
||||
network.getGateways(),
|
||||
network.name));
|
||||
if (!this.isNetworkTypeMobile(networkInterface.type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let currentInterfaceLinks = this.networkInterfaceLinks[networkId];
|
||||
let newLinkRoutes = networkInterface.getDnses().concat(
|
||||
networkInterface.httpProxyHost);
|
||||
// If gateways have changed, remove all old routes first.
|
||||
return this._handleGateways(networkId, networkInterface.getGateways())
|
||||
.then(() => this._updateRoutes(currentInterfaceLinks.linkRoutes,
|
||||
newLinkRoutes,
|
||||
networkInterface.getGateways(),
|
||||
networkInterface.name))
|
||||
.then(() => currentInterfaceLinks.setLinks(newLinkRoutes,
|
||||
networkInterface.getGateways(),
|
||||
networkInterface.name));
|
||||
})
|
||||
.then(() => {
|
||||
if (networkInterface.type !=
|
||||
Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN) {
|
||||
return;
|
||||
}
|
||||
// Dun type is a special case where we add the default route to a
|
||||
// secondary table.
|
||||
if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN) {
|
||||
this.setSecondaryDefaultRoute(network);
|
||||
}
|
||||
|
||||
this._addSubnetRoutes(network);
|
||||
this.setAndConfigureActive();
|
||||
|
||||
return this.setSecondaryDefaultRoute(networkInterface);
|
||||
})
|
||||
.then(() => this._addSubnetRoutes(networkInterface))
|
||||
.then(() => this.setAndConfigureActive())
|
||||
.then(() => {
|
||||
// Update data connection when Wifi connected/disconnected
|
||||
if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_WIFI && this.mRil) {
|
||||
if (networkInterface.type ==
|
||||
Ci.nsINetworkInterface.NETWORK_TYPE_WIFI && this.mRil) {
|
||||
for (let i = 0; i < this.mRil.numRadioInterfaces; i++) {
|
||||
this.mRil.getRadioInterface(i).updateRILNetworkInterface();
|
||||
}
|
||||
@ -325,53 +381,73 @@ NetworkManager.prototype = {
|
||||
// Probing the public network accessibility after routing table is ready
|
||||
CaptivePortalDetectionHelper
|
||||
.notify(CaptivePortalDetectionHelper.EVENT_CONNECT, this.active);
|
||||
|
||||
})
|
||||
.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));
|
||||
})
|
||||
.catch(aError => {
|
||||
debug("updateNetworkInterface error: " + aError);
|
||||
});
|
||||
});
|
||||
|
||||
break;
|
||||
case Ci.nsINetworkInterface.NETWORK_STATE_DISCONNECTED:
|
||||
// Remove host route for data calls
|
||||
if (this.isNetworkTypeMobile(network.type)) {
|
||||
this._cleanupAllHostRoutes(networkId);
|
||||
}
|
||||
// Remove secondary default route for dun.
|
||||
if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN) {
|
||||
this.removeSecondaryDefaultRoute(network);
|
||||
}
|
||||
// Remove routing table in /proc/net/route
|
||||
if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_WIFI) {
|
||||
gNetworkService.resetRoutingTable(network);
|
||||
} else if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE) {
|
||||
gNetworkService.removeDefaultRoute(network);
|
||||
}
|
||||
// Clear http proxy on active network.
|
||||
if (this.active && network.type == this.active.type) {
|
||||
this.clearNetworkProxy();
|
||||
}
|
||||
Promise.resolve()
|
||||
.then(() => {
|
||||
if (!this.isNetworkTypeMobile(networkInterface.type)) {
|
||||
return;
|
||||
}
|
||||
// Remove host route for data calls
|
||||
return this._cleanupAllHostRoutes(networkId);
|
||||
})
|
||||
.then(() => {
|
||||
if (networkInterface.type !=
|
||||
Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN) {
|
||||
return;
|
||||
}
|
||||
// Remove secondary default route for dun.
|
||||
return this.removeSecondaryDefaultRoute(networkInterface);
|
||||
})
|
||||
.then(() => {
|
||||
if (networkInterface.type == Ci.nsINetworkInterface.NETWORK_TYPE_WIFI) {
|
||||
// Remove routing table in /proc/net/route
|
||||
return this._resetRoutingTable(networkInterface);
|
||||
}
|
||||
if (networkInterface.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE) {
|
||||
return this._removeDefaultRoute(networkInterface)
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
// Clear http proxy on active network.
|
||||
if (this.active && networkInterface.type == this.active.type) {
|
||||
this.clearNetworkProxy();
|
||||
}
|
||||
|
||||
// Abort ongoing captive portal detection on the wifi interface
|
||||
CaptivePortalDetectionHelper
|
||||
.notify(CaptivePortalDetectionHelper.EVENT_DISCONNECT, network);
|
||||
this.setAndConfigureActive();
|
||||
|
||||
// Update data connection when Wifi connected/disconnected
|
||||
if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_WIFI && this.mRil) {
|
||||
for (let i = 0; i < this.mRil.numRadioInterfaces; i++) {
|
||||
this.mRil.getRadioInterface(i).updateRILNetworkInterface();
|
||||
}
|
||||
}
|
||||
|
||||
gNetworkService.destroyNetwork(network.name, () => {
|
||||
// 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));
|
||||
});
|
||||
// Abort ongoing captive portal detection on the wifi interface
|
||||
CaptivePortalDetectionHelper
|
||||
.notify(CaptivePortalDetectionHelper.EVENT_DISCONNECT, networkInterface);
|
||||
})
|
||||
.then(() => this.setAndConfigureActive())
|
||||
.then(() => {
|
||||
// Update data connection when Wifi connected/disconnected
|
||||
if (networkInterface.type ==
|
||||
Ci.nsINetworkInterface.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(() => {
|
||||
// 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));
|
||||
})
|
||||
.catch(aError => {
|
||||
debug("updateNetworkInterface error: " + aError);
|
||||
});
|
||||
break;
|
||||
}
|
||||
},
|
||||
@ -599,45 +675,86 @@ NetworkManager.prototype = {
|
||||
return null;
|
||||
},
|
||||
|
||||
_setSecondaryRoute: function(aDoAdd, aInterfaceName, aRoute) {
|
||||
return new Promise((aResolve, aReject) => {
|
||||
if (aDoAdd) {
|
||||
gNetworkService.addSecondaryRoute(aInterfaceName, aRoute,
|
||||
(aSuccess) => {
|
||||
if (!aSuccess) {
|
||||
aReject("addSecondaryRoute failed");
|
||||
return;
|
||||
}
|
||||
aResolve();
|
||||
});
|
||||
} else {
|
||||
gNetworkService.removeSecondaryRoute(aInterfaceName, aRoute,
|
||||
(aSuccess) => {
|
||||
if (!aSuccess) {
|
||||
debug("removeSecondaryRoute failed")
|
||||
}
|
||||
// Always resolve.
|
||||
aResolve();
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
setSecondaryDefaultRoute: function(network) {
|
||||
let gateways = network.getGateways();
|
||||
let promises = [];
|
||||
|
||||
for (let i = 0; i < gateways.length; i++) {
|
||||
let isIPv6 = (gateways[i].indexOf(":") != -1) ? true : false;
|
||||
// First, we need to add a host route to the gateway in the secondary
|
||||
// routing table to make the gateway reachable. Host route takes the max
|
||||
// prefix and gateway address 'any'.
|
||||
let route = {
|
||||
let hostRoute = {
|
||||
ip: gateways[i],
|
||||
prefix: isIPv6 ? IPV6_MAX_PREFIX_LENGTH : IPV4_MAX_PREFIX_LENGTH,
|
||||
gateway: isIPv6 ? IPV6_ADDRESS_ANY : IPV4_ADDRESS_ANY
|
||||
};
|
||||
gNetworkService.addSecondaryRoute(network.name, route);
|
||||
// Now we can add the default route through gateway. Default route takes the
|
||||
// min prefix and destination ip 'any'.
|
||||
route.ip = isIPv6 ? IPV6_ADDRESS_ANY : IPV4_ADDRESS_ANY;
|
||||
route.prefix = 0;
|
||||
route.gateway = gateways[i];
|
||||
gNetworkService.addSecondaryRoute(network.name, route);
|
||||
}
|
||||
},
|
||||
|
||||
removeSecondaryDefaultRoute: function(network) {
|
||||
let gateways = network.getGateways();
|
||||
for (let i = 0; i < gateways.length; i++) {
|
||||
let isIPv6 = (gateways[i].indexOf(":") != -1) ? true : false;
|
||||
// Remove both default route and host route.
|
||||
let route = {
|
||||
let defaultRoute = {
|
||||
ip: isIPv6 ? IPV6_ADDRESS_ANY : IPV4_ADDRESS_ANY,
|
||||
prefix: 0,
|
||||
gateway: gateways[i]
|
||||
};
|
||||
gNetworkService.removeSecondaryRoute(network.name, route);
|
||||
|
||||
route.ip = gateways[i];
|
||||
route.prefix = isIPv6 ? IPV6_MAX_PREFIX_LENGTH : IPV4_MAX_PREFIX_LENGTH;
|
||||
route.gateway = isIPv6 ? IPV6_ADDRESS_ANY : IPV4_ADDRESS_ANY;
|
||||
gNetworkService.removeSecondaryRoute(network.name, route);
|
||||
let promise = this._setSecondaryRoute(true, network.name, hostRoute)
|
||||
.then(() => this._setSecondaryRoute(true, network.name, defaultRoute));
|
||||
|
||||
promises.push(promise);
|
||||
}
|
||||
|
||||
return Promise.all(promises);
|
||||
},
|
||||
|
||||
removeSecondaryDefaultRoute: function(network) {
|
||||
let gateways = network.getGateways();
|
||||
let promises = [];
|
||||
|
||||
for (let i = 0; i < gateways.length; i++) {
|
||||
let isIPv6 = (gateways[i].indexOf(":") != -1) ? true : false;
|
||||
// Remove both default route and host route.
|
||||
let defaultRoute = {
|
||||
ip: isIPv6 ? IPV6_ADDRESS_ANY : IPV4_ADDRESS_ANY,
|
||||
prefix: 0,
|
||||
gateway: gateways[i]
|
||||
};
|
||||
let hostRoute = {
|
||||
ip: gateways[i],
|
||||
prefix: isIPv6 ? IPV6_MAX_PREFIX_LENGTH : IPV4_MAX_PREFIX_LENGTH,
|
||||
gateway: isIPv6 ? IPV6_ADDRESS_ANY : IPV4_ADDRESS_ANY
|
||||
};
|
||||
|
||||
let promise = this._setSecondaryRoute(false, network.name, defaultRoute)
|
||||
.then(() => this._setSecondaryRoute(false, network.name, hostRoute));
|
||||
|
||||
promises.push(promise);
|
||||
}
|
||||
|
||||
return Promise.all(promises);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -664,8 +781,7 @@ NetworkManager.prototype = {
|
||||
this.active.state == Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED &&
|
||||
this.active.type == this._preferredNetworkType) {
|
||||
debug("Active network is already our preferred type.");
|
||||
this._setDefaultRouteAndProxy(this.active, oldActive);
|
||||
return;
|
||||
return this._setDefaultRouteAndProxy(this.active, oldActive);
|
||||
}
|
||||
|
||||
// Find a suitable network interface to activate.
|
||||
@ -688,28 +804,33 @@ NetworkManager.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.active) {
|
||||
// Give higher priority to default data APN than secondary APN.
|
||||
// If default data APN is not connected, we still set default route
|
||||
// and DNS on secondary APN.
|
||||
if (defaultDataNetwork &&
|
||||
this.isNetworkTypeSecondaryMobile(this.active.type) &&
|
||||
this.active.type != this.preferredNetworkType) {
|
||||
this.active = defaultDataNetwork;
|
||||
}
|
||||
// Don't set default route on secondary APN
|
||||
if (!this.isNetworkTypeSecondaryMobile(this.active.type)) {
|
||||
this._setDefaultRouteAndProxy(this.active, oldActive);
|
||||
}
|
||||
// Give higher priority to default data APN than secondary APN.
|
||||
// If default data APN is not connected, we still set default route
|
||||
// and DNS on secondary APN.
|
||||
if (this.active && defaultDataNetwork &&
|
||||
this.isNetworkTypeSecondaryMobile(this.active.type) &&
|
||||
this.active.type != this.preferredNetworkType) {
|
||||
this.active = defaultDataNetwork;
|
||||
}
|
||||
|
||||
if (this.active != oldActive) {
|
||||
Services.obs.notifyObservers(this.active, TOPIC_ACTIVE_CHANGED, null);
|
||||
}
|
||||
return Promise.resolve()
|
||||
.then(() => {
|
||||
// Don't set default route on secondary APN
|
||||
if (!this.active || this.isNetworkTypeSecondaryMobile(this.active.type)) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
if (this._manageOfflineStatus) {
|
||||
Services.io.offline = !this.active;
|
||||
}
|
||||
return this._setDefaultRouteAndProxy(this.active, oldActive);
|
||||
})
|
||||
.then(() => {
|
||||
if (this.active != oldActive) {
|
||||
Services.obs.notifyObservers(this.active, TOPIC_ACTIVE_CHANGED, null);
|
||||
}
|
||||
|
||||
if (this._manageOfflineStatus) {
|
||||
Services.io.offline = !this.active;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
resolveHostname: function(network, hostname) {
|
||||
@ -788,13 +909,78 @@ NetworkManager.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
_setDefaultRouteAndProxy: function(network, oldInterface) {
|
||||
gNetworkService.setDefaultRoute(network, oldInterface, (success) => {
|
||||
if (!success) {
|
||||
gNetworkService.destroyNetwork(network, function() {});
|
||||
return;
|
||||
}
|
||||
this.setNetworkProxy(network);
|
||||
_setDNS: function(aNetwork) {
|
||||
return new Promise((aResolve, aReject) => {
|
||||
gNetworkService.setDNS(aNetwork, (aError) => {
|
||||
if (aError) {
|
||||
aReject("setDNS failed");
|
||||
return;
|
||||
}
|
||||
aResolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
_createNetwork: function(aInterfaceName) {
|
||||
return new Promise((aResolve, aReject) => {
|
||||
gNetworkService.createNetwork(aInterfaceName, (aSuccess) => {
|
||||
if (!aSuccess) {
|
||||
aReject("createNetwork failed");
|
||||
return;
|
||||
}
|
||||
aResolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
_destroyNetwork: function(aInterfaceName) {
|
||||
return new Promise((aResolve, aReject) => {
|
||||
gNetworkService.destroyNetwork(aInterfaceName, (aSuccess) => {
|
||||
if (!aSuccess) {
|
||||
debug("destroyNetwork failed")
|
||||
}
|
||||
// Always resolve.
|
||||
aResolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
_resetRoutingTable: function(aNetwork) {
|
||||
return new Promise((aResolve, aReject) => {
|
||||
gNetworkService.resetRoutingTable(aNetwork, (aSuccess) => {
|
||||
if (!aSuccess) {
|
||||
debug("resetRoutingTable failed");
|
||||
}
|
||||
// Always resolve.
|
||||
aResolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
_removeDefaultRoute: function(aNetwork) {
|
||||
return new Promise((aResolve, aReject) => {
|
||||
gNetworkService.removeDefaultRoute(aNetwork, (aSuccess) => {
|
||||
if (!aSuccess) {
|
||||
debug("removeDefaultRoute failed");
|
||||
}
|
||||
// Always resolve.
|
||||
aResolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
_setDefaultRouteAndProxy: function(aNetwork, aOldInterface) {
|
||||
return new Promise((aResolve, aReject) => {
|
||||
gNetworkService.setDefaultRoute(aNetwork, aOldInterface, (aSuccess) => {
|
||||
if (!aSuccess) {
|
||||
gNetworkService.destroyNetwork(aNetwork, function() {
|
||||
aReject("setDefaultRoute failed");
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.setNetworkProxy(aNetwork);
|
||||
aResolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -2703,13 +2703,13 @@ DataCall.prototype = {
|
||||
if (this.state == RIL.GECKO_NETWORK_STATE_CONNECTED) {
|
||||
// This needs to run asynchronously, to behave the same way as the case of
|
||||
// non-shared apn, see bug 1059110.
|
||||
Services.tm.currentThread.dispatch(function(state) {
|
||||
Services.tm.currentThread.dispatch(() => {
|
||||
// Do not notify if state changed while this event was being dispatched,
|
||||
// the state probably was notified already or need not to be notified.
|
||||
if (networkInterface.state == state) {
|
||||
if (networkInterface.state == RIL.GECKO_NETWORK_STATE_CONNECTED) {
|
||||
networkInterface.notifyRILNetworkInterface();
|
||||
}
|
||||
}.bind(null, RIL.GECKO_NETWORK_STATE_CONNECTED), Ci.nsIEventTarget.DISPATCH_NORMAL);
|
||||
}, Ci.nsIEventTarget.DISPATCH_NORMAL);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2829,13 +2829,15 @@ DataCall.prototype = {
|
||||
// Notify the DISCONNECTED event immediately after network interface is
|
||||
// removed from requestedNetworkIfaces, to make the DataCall, shared or
|
||||
// not, to have the same behavior.
|
||||
Services.tm.currentThread.dispatch(function(state) {
|
||||
Services.tm.currentThread.dispatch(() => {
|
||||
// Do not notify if state changed while this event was being dispatched,
|
||||
// the state probably was notified already or need not to be notified.
|
||||
if (networkInterface.state == state) {
|
||||
if (networkInterface.state == RIL.GECKO_NETWORK_STATE_DISCONNECTED) {
|
||||
networkInterface.notifyRILNetworkInterface();
|
||||
// Clear link info after notifying NetworkManager.
|
||||
this.resetLinkInfo();
|
||||
}
|
||||
}.bind(null, RIL.GECKO_NETWORK_STATE_DISCONNECTED), Ci.nsIEventTarget.DISPATCH_NORMAL);
|
||||
}, Ci.nsIEventTarget.DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
// Only deactivate data call if no more network interface needs this
|
||||
@ -2861,7 +2863,6 @@ DataCall.prototype = {
|
||||
}, this.onDeactivateDataCallResult.bind(this));
|
||||
|
||||
this.state = RIL.GECKO_NETWORK_STATE_DISCONNECTING;
|
||||
this.resetLinkInfo();
|
||||
},
|
||||
|
||||
// Entry method for timer events. Used to reconnect to a failed APN
|
||||
|
Loading…
Reference in New Issue
Block a user