mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 20:05:49 +00:00
Bug 1018088 - PUSH wakeup compatible multiple mobile networks carriers. r=nsm
This commit is contained in:
parent
283734ec19
commit
53ed7beec6
@ -463,6 +463,17 @@ pref("services.push.pingInterval", 1800000); // 30 minutes
|
||||
pref("services.push.requestTimeout", 10000);
|
||||
// enable udp wakeup support
|
||||
pref("services.push.udp.wakeupEnabled", true);
|
||||
// This value should be the prefix to be added to the current PDP context[1]
|
||||
// domain or a full-qualified domain name.
|
||||
// If finished with a dot, it will be added as a prefix to the PDP context
|
||||
// domain. If not, will be used as the DNS query.
|
||||
// If the DNS query is unsuccessful, the push agent will send a null netid and
|
||||
// is a server decision what to do with the device. If the MCC-MNC identifies a
|
||||
// unique network the server will change to UDP mode. Otherwise, a websocket
|
||||
// connection will be maintained.
|
||||
// [1] Packet Data Protocol
|
||||
// http://en.wikipedia.org/wiki/GPRS_core_network#PDP_context
|
||||
pref("services.push.udp.well-known_netidAddress", "_wakeup_.");
|
||||
|
||||
// NetworkStats
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
|
@ -25,9 +25,19 @@ Cu.import("resource://gre/modules/Preferences.jsm");
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
Cu.importGlobalProperties(["indexedDB"]);
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "gDNSService",
|
||||
"@mozilla.org/network/dns-service;1",
|
||||
"nsIDNSService");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService",
|
||||
"@mozilla.org/settingsService;1",
|
||||
"nsISettingsService");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "AlarmService",
|
||||
"resource://gre/modules/AlarmService.jsm");
|
||||
|
||||
var threadManager = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager);
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["PushService"];
|
||||
|
||||
const prefs = new Preferences("services.push.");
|
||||
@ -643,6 +653,9 @@ this.PushService = {
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the APN data from the settings DB.
|
||||
let lock = gSettingsService.createLock();
|
||||
lock.get("ril.data.apnSettings", this);
|
||||
|
||||
debug("serverURL: " + uri.spec);
|
||||
this._wsListener = new PushWebSocketListener(this);
|
||||
@ -651,6 +664,25 @@ this.PushService = {
|
||||
this._currentState = STATE_WAITING_FOR_WS_START;
|
||||
},
|
||||
|
||||
/**
|
||||
* nsISettingsServiceCallback
|
||||
*/
|
||||
handle: function(name, result) {
|
||||
if (name !== "ril.data.apnSettings" || !result) {
|
||||
return;
|
||||
}
|
||||
let apn = result[0].filter(function(e) {
|
||||
return e.types[0] === "default";
|
||||
});
|
||||
if (apn.length === 0 || !apn[0].apn) {
|
||||
this._apnDomain = null;
|
||||
debug("No APN Domain found. No netid support");
|
||||
return;
|
||||
}
|
||||
this._apnDomain = apn[0].apn;
|
||||
debug("APN Domain: " + this._apnDomain);
|
||||
},
|
||||
|
||||
_startListeningIfChannelsPresent: function() {
|
||||
// Check to see if we need to do anything.
|
||||
this._db.getAllChannelIDs(function(channelIDs) {
|
||||
@ -1295,9 +1327,6 @@ this.PushService = {
|
||||
// Since we've had a successful connection reset the retry fail count.
|
||||
this._retryFailCount = 0;
|
||||
|
||||
// Openning an available UDP port.
|
||||
this._listenForUDPWakeup();
|
||||
|
||||
let data = {
|
||||
messageType: "hello",
|
||||
}
|
||||
@ -1305,20 +1334,6 @@ this.PushService = {
|
||||
if (this._UAID)
|
||||
data["uaid"] = this._UAID;
|
||||
|
||||
let networkState = this._getNetworkState();
|
||||
if (networkState.ip) {
|
||||
// Hostport is apparently a thing.
|
||||
data["wakeup_hostport"] = {
|
||||
ip: networkState.ip,
|
||||
port: this._udpServer && this._udpServer.port
|
||||
};
|
||||
|
||||
data["mobilenetwork"] = {
|
||||
mcc: networkState.mcc,
|
||||
mnc: networkState.mnc
|
||||
};
|
||||
}
|
||||
|
||||
function sendHelloMessage(ids) {
|
||||
// On success, ids is an array, on error its not.
|
||||
data["channelIDs"] = ids.map ?
|
||||
@ -1327,8 +1342,27 @@ this.PushService = {
|
||||
this._currentState = STATE_WAITING_FOR_HELLO;
|
||||
}
|
||||
|
||||
this._db.getAllChannelIDs(sendHelloMessage.bind(this),
|
||||
sendHelloMessage.bind(this));
|
||||
this._getNetworkState((networkState) => {
|
||||
if (networkState.ip) {
|
||||
// Opening an available UDP port.
|
||||
this._listenForUDPWakeup();
|
||||
|
||||
// Host-port is apparently a thing.
|
||||
data["wakeup_hostport"] = {
|
||||
ip: networkState.ip,
|
||||
port: this._udpServer && this._udpServer.port
|
||||
};
|
||||
|
||||
data["mobilenetwork"] = {
|
||||
mcc: networkState.mcc,
|
||||
mnc: networkState.mnc,
|
||||
netid: networkState.netid
|
||||
};
|
||||
}
|
||||
|
||||
this._db.getAllChannelIDs(sendHelloMessage.bind(this),
|
||||
sendHelloMessage.bind(this));
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1421,6 +1455,9 @@ this.PushService = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* This method should be called only if the device is on a mobile network!
|
||||
*/
|
||||
_listenForUDPWakeup: function() {
|
||||
debug("listenForUDPWakeup()");
|
||||
|
||||
@ -1429,11 +1466,6 @@ this.PushService = {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._getNetworkState().ip) {
|
||||
debug("No IP");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!prefs.get("udp.wakeupEnabled")) {
|
||||
debug("UDP support disabled");
|
||||
return;
|
||||
@ -1474,12 +1506,15 @@ this.PushService = {
|
||||
* woken up by UDP (which currently just means having an mcc and mnc along
|
||||
* with an IP).
|
||||
*/
|
||||
_getNetworkState: function() {
|
||||
_getNetworkState: function(callback) {
|
||||
if (typeof callback !== 'function') {
|
||||
throw new Error("No callback method. Aborting push agent !");
|
||||
}
|
||||
debug("getNetworkState()");
|
||||
try {
|
||||
if (!prefs.get("udp.wakeupEnabled")) {
|
||||
debug("UDP support disabled, we do not send any carrier info");
|
||||
throw "UDP disabled";
|
||||
throw new Error("UDP disabled");
|
||||
}
|
||||
|
||||
let nm = Cc["@mozilla.org/network/manager;1"].getService(Ci.nsINetworkManager);
|
||||
@ -1494,25 +1529,33 @@ this.PushService = {
|
||||
let iccInfo = icc.getIccInfo(clientId);
|
||||
if (iccInfo) {
|
||||
debug("Running on mobile data");
|
||||
|
||||
let ips = {};
|
||||
let prefixLengths = {};
|
||||
nm.active.getAddresses(ips, prefixLengths);
|
||||
return {
|
||||
mcc: iccInfo.mcc,
|
||||
mnc: iccInfo.mnc,
|
||||
ip: ips.value[0]
|
||||
}
|
||||
|
||||
this._getMobileNetworkId(function(netid) {
|
||||
debug("Recovered netID = " + netid);
|
||||
callback({
|
||||
mcc: iccInfo.mcc,
|
||||
mnc: iccInfo.mnc,
|
||||
ip: ips.value[0],
|
||||
netid: netid
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
debug("Error recovering mobile network information: " + e);
|
||||
}
|
||||
|
||||
debug("Running on wifi");
|
||||
|
||||
return {
|
||||
callback({
|
||||
mcc: 0,
|
||||
mnc: 0,
|
||||
ip: undefined
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
// utility function used to add/remove observers in init() and shutdown()
|
||||
@ -1523,5 +1566,47 @@ this.PushService = {
|
||||
} catch (e) {
|
||||
return "network:offline-status-changed";
|
||||
}
|
||||
},
|
||||
|
||||
// Get the mobile network ID (netid)
|
||||
_getMobileNetworkId: function(callback) {
|
||||
if (typeof callback !== 'function') {
|
||||
return;
|
||||
}
|
||||
|
||||
function queryDNSForDomain(domain) {
|
||||
debug("[_getMobileNetworkId:queryDNSForDomain] Querying DNS for " +
|
||||
domain);
|
||||
let netIDDNSListener = {
|
||||
onLookupComplete: function(aRequest, aRecord, aStatus) {
|
||||
if (aRecord) {
|
||||
let netid = aRecord.getNextAddrAsString();
|
||||
debug("[_getMobileNetworkId:queryDNSForDomain] NetID found: " +
|
||||
netid);
|
||||
callback(netid);
|
||||
} else {
|
||||
debug("[_getMobileNetworkId:queryDNSForDomain] NetID not found");
|
||||
callback(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
gDNSService.asyncResolve(domain, 0, netIDDNSListener,
|
||||
threadManager.currentThread);
|
||||
return [];
|
||||
}
|
||||
|
||||
debug("[_getMobileNetworkId:queryDNSForDomain] Getting mobile network ID (I'm " +
|
||||
gDNSService.myHostName + ")");
|
||||
|
||||
let netidAddress = prefs.get("udp.well-known_netidAddress");
|
||||
if (netidAddress.endsWith(".")) {
|
||||
if (this._apnDomain) {
|
||||
queryDNSForDomain(netidAddress + this._apnDomain, callback);
|
||||
} else {
|
||||
callback(null); // No netid could be recovered
|
||||
}
|
||||
} else if(netidAddress) {
|
||||
queryDNSForDomain(netidAddress, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user