Merge b2g-inbound to m-c. a=merge

This commit is contained in:
Ryan VanderMeulen 2014-06-09 17:11:08 -04:00
commit 1485564e4d
21 changed files with 394 additions and 156 deletions

View File

@ -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

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d283b742a12ac43ec087f45b02d3817cf7ddab69"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="3b2ae74d3a3aab77360559842467ba6f4ecb2b4a"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="dbb66e540194a187326cece28ae0b51cdd500184"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="8e4420c0c5c8e8c8e58a000278a7129403769f96"/>

View File

@ -12,12 +12,12 @@
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="6e2a3b589d1e8cc1d9df25f5e630ce30a0aa39f3">
<project name="platform_build" path="build" remote="b2g" revision="cc67f31dc638c0b7edba3cf7e3d87cadf0ed52bf">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d283b742a12ac43ec087f45b02d3817cf7ddab69"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="3b2ae74d3a3aab77360559842467ba6f4ecb2b4a"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="dbb66e540194a187326cece28ae0b51cdd500184"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="cabebb87fcd32f8596af08e6b5e80764ee0157dd"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="276ce45e78b09c4a4ee643646f691d22804754c1">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d283b742a12ac43ec087f45b02d3817cf7ddab69"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="3b2ae74d3a3aab77360559842467ba6f4ecb2b4a"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="dbb66e540194a187326cece28ae0b51cdd500184"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d283b742a12ac43ec087f45b02d3817cf7ddab69"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="3b2ae74d3a3aab77360559842467ba6f4ecb2b4a"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="dbb66e540194a187326cece28ae0b51cdd500184"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="8e4420c0c5c8e8c8e58a000278a7129403769f96"/>

View File

@ -12,12 +12,12 @@
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="6e2a3b589d1e8cc1d9df25f5e630ce30a0aa39f3">
<project name="platform_build" path="build" remote="b2g" revision="cc67f31dc638c0b7edba3cf7e3d87cadf0ed52bf">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d283b742a12ac43ec087f45b02d3817cf7ddab69"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="3b2ae74d3a3aab77360559842467ba6f4ecb2b4a"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="dbb66e540194a187326cece28ae0b51cdd500184"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="cabebb87fcd32f8596af08e6b5e80764ee0157dd"/>

View File

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "0d0d9de7b2534dbeb4809ad019294000eb719a80",
"revision": "70cb8b50e7ad2bb64a7ac43e9b9e0c965ae8cd2f",
"repo_path": "/integration/gaia-central"
}

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d283b742a12ac43ec087f45b02d3817cf7ddab69"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="3b2ae74d3a3aab77360559842467ba6f4ecb2b4a"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="dbb66e540194a187326cece28ae0b51cdd500184"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d283b742a12ac43ec087f45b02d3817cf7ddab69"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="3b2ae74d3a3aab77360559842467ba6f4ecb2b4a"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="dbb66e540194a187326cece28ae0b51cdd500184"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -12,12 +12,12 @@
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="6e2a3b589d1e8cc1d9df25f5e630ce30a0aa39f3">
<project name="platform_build" path="build" remote="b2g" revision="cc67f31dc638c0b7edba3cf7e3d87cadf0ed52bf">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="d283b742a12ac43ec087f45b02d3817cf7ddab69"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="3b2ae74d3a3aab77360559842467ba6f4ecb2b4a"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="dbb66e540194a187326cece28ae0b51cdd500184"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="cabebb87fcd32f8596af08e6b5e80764ee0157dd"/>

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="d283b742a12ac43ec087f45b02d3817cf7ddab69"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="3b2ae74d3a3aab77360559842467ba6f4ecb2b4a"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="dbb66e540194a187326cece28ae0b51cdd500184"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -135,6 +135,7 @@ function BrowserElementParent(frameLoader, hasRemoteFrame, isPendingFrame) {
defineNoReturnMethod('goForward', this._goForward);
defineNoReturnMethod('reload', this._reload);
defineNoReturnMethod('stop', this._stop);
defineMethod('download', this._download);
defineDOMRequestMethod('purgeHistory', 'purge-history');
defineMethod('getScreenshot', this._getScreenshot);
defineMethod('addNextPaintListener', this._addNextPaintListener);
@ -620,6 +621,106 @@ BrowserElementParent.prototype = {
this._sendAsyncMsg('stop');
},
_download: function(_url, _options) {
let ioService =
Cc['@mozilla.org/network/io-service;1'].getService(Ci.nsIIOService);
let uri = ioService.newURI(_url, null, null);
let url = uri.QueryInterface(Ci.nsIURL);
// Ensure we have _options, we always use it to send the filename.
_options = _options || {};
if (!_options.filename) {
_options.filename = url.fileName;
}
debug('_options = ' + uneval(_options));
// Ensure we have a filename.
if (!_options.filename) {
throw Components.Exception("Invalid argument", Cr.NS_ERROR_INVALID_ARG);
}
let interfaceRequestor =
this._frameLoader.loadContext.QueryInterface(Ci.nsIInterfaceRequestor);
let req = Services.DOMRequest.createRequest(this._window);
function DownloadListener() {
debug('DownloadListener Constructor');
}
DownloadListener.prototype = {
extListener: null,
onStartRequest: function(aRequest, aContext) {
debug('DownloadListener - onStartRequest');
let extHelperAppSvc =
Cc['@mozilla.org/uriloader/external-helper-app-service;1'].
getService(Ci.nsIExternalHelperAppService);
let channel = aRequest.QueryInterface(Ci.nsIChannel);
this.extListener =
extHelperAppSvc.doContent(
channel.contentType,
aRequest,
interfaceRequestor,
true);
this.extListener.onStartRequest(aRequest, aContext);
},
onStopRequest: function(aRequest, aContext, aStatusCode) {
debug('DownloadListener - onStopRequest (aStatusCode = ' +
aStatusCode + ')');
if (aStatusCode == Cr.NS_OK) {
// Everything looks great.
debug('DownloadListener - Download Successful.');
this.services.DOMRequest.fireSuccess(this.req, aStatusCode);
}
else {
// In case of failure, we'll simply return the failure status code.
debug('DownloadListener - Download Failed!');
this.services.DOMRequest.fireError(this.req, aStatusCode);
}
if (this.extListener) {
this.extListener.onStopRequest(aRequest, aContext, aStatusCode);
}
},
onDataAvailable: function(aRequest, aContext, aInputStream,
aOffset, aCount) {
this.extListener.onDataAvailable(aRequest, aContext, aInputStream,
aOffset, aCount);
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIStreamListener,
Ci.nsIRequestObserver])
};
let channel = ioService.newChannelFromURI(url);
// XXX We would set private browsing information prior to calling this.
channel.notificationCallbacks = interfaceRequestor;
// Since we're downloading our own local copy we'll want to bypass the
// cache and local cache if the channel let's us specify this.
let flags = Ci.nsIChannel.LOAD_CALL_CONTENT_SNIFFERS |
Ci.nsIChannel.LOAD_BYPASS_CACHE;
if (channel instanceof Ci.nsICachingChannel) {
debug('This is a caching channel. Forcing bypass.');
flags |= Ci.nsICachingChannel.LOAD_BYPASS_LOCAL_CACHE_IF_BUSY;
}
channel.loadFlags |= flags;
if (channel instanceof Ci.nsIHttpChannel) {
debug('Setting HTTP referrer = ' + this._window.document.documentURIObject);
channel.referrer = this._window.document.documentURIObject;
if (channel instanceof Ci.nsIHttpChannelInternal) {
channel.forceAllowThirdPartyCookie = true;
}
}
// Set-up complete, let's get things started.
channel.asyncOpen(new DownloadListener(), null);
return req;
},
_getScreenshot: function(_width, _height, _mimeType) {
let width = parseInt(_width);
let height = parseInt(_height);

View File

@ -0,0 +1,37 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Bug 983747 - Test 'download' method on iframe.
"use strict";
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
var iframe;
var downloadURL = 'http://test/tests/dom/browser-element/mochitest/file_download_bin.sjs';
function runTest() {
iframe = document.createElement('iframe');
SpecialPowers.wrap(iframe).mozbrowser = true;
iframe.addEventListener('mozbrowserloadend', loadend);
iframe.src = 'data:text/html,<html><body>hello</body></html>';
iframe.setAttribute('remote', 'true');
document.body.appendChild(iframe);
}
function loadend() {
var req = iframe.download(downloadURL, { filename: 'test.bin' });
req.onsuccess = function() {
ok(true, 'Download finished as expected.');
SimpleTest.finish();
}
req.onerror = function() {
ok(false, 'Expected no error, got ' + req.error);
}
}
addEventListener('testready', runTest);

View File

@ -0,0 +1,4 @@
function handleRequest(request, response) {
response.setHeader("Content-Type", "application/octet-stream", false);
response.write("BIN");
}

View File

@ -30,6 +30,8 @@ skip-if = (toolkit == 'gonk' && !debug)
[test_browserElement_oop_DOMRequestError.html]
[test_browserElement_oop_DataURI.html]
[test_browserElement_oop_DocumentFirstPaint.html]
[test_browserElement_oop_Download.html]
disabled = bug 1022281
[test_browserElement_oop_ErrorSecurity.html]
skip-if = (toolkit == 'gonk' && !debug)
[test_browserElement_oop_FirstPaint.html]

View File

@ -21,6 +21,7 @@ support-files =
browserElement_DOMRequestError.js
browserElement_DataURI.js
browserElement_DocumentFirstPaint.js
browserElement_Download.js
browserElement_ErrorSecurity.js
browserElement_ExposableURI.js
browserElement_FirstPaint.js
@ -96,6 +97,7 @@ support-files =
file_browserElement_XFrameOptionsSameOrigin.html
file_bug709759.sjs
file_bug741717.sjs
file_download_bin.sjs
file_empty.html
file_empty_script.js
file_focus.html
@ -134,6 +136,8 @@ skip-if = buildapp == 'b2g'
[test_browserElement_inproc_DOMRequestError.html]
[test_browserElement_inproc_DataURI.html]
[test_browserElement_inproc_DocumentFirstPaint.html]
[test_browserElement_inproc_Download.html]
disabled = bug 1022281
[test_browserElement_inproc_ExposableURI.html]
[test_browserElement_inproc_FirstPaint.html]
[test_browserElement_inproc_ForwardName.html]

View File

@ -0,0 +1,13 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for Bug 983747</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript;version=1.7" src="browserElement_Download.js">
</script>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for Bug 983747</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript;version=1.7" src="browserElement_Download.js">
</script>
</body>
</html>

View File

@ -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);
}
}
}

View File

@ -38,6 +38,15 @@ const CDMA_SECOND_CALL_INDEX = 2;
const DIAL_ERROR_INVALID_STATE_ERROR = "InvalidStateError";
const DIAL_ERROR_OTHER_CONNECTION_IN_USE = "OtherConnectionInUse";
const AUDIO_STATE_NO_CALL = 0;
const AUDIO_STATE_INCOMING = 1;
const AUDIO_STATE_IN_CALL = 2;
const AUDIO_STATE_NAME = [
"PHONE_STATE_NORMAL",
"PHONE_STATE_RINGTONE",
"PHONE_STATE_IN_CALL"
];
let DEBUG;
function debug(s) {
dump("TelephonyService: " + s + "\n");
@ -89,36 +98,15 @@ XPCOMUtils.defineLazyGetter(this, "gPhoneNumberUtils", function() {
return ns.PhoneNumberUtils;
});
function SingleCall(options){
this.clientId = options.clientId;
this.callIndex = options.callIndex;
this.state = options.state;
this.number = options.number;
this.isOutgoing = options.isOutgoing;
this.isEmergency = options.isEmergency;
this.isConference = options.isConference;
}
SingleCall.prototype = {
clientId: null,
callIndex: null,
state: null,
number: null,
isOutgoing: false,
isEmergency: false,
isConference: false
};
function ConferenceCall(state){
this.state = state;
}
ConferenceCall.prototype = {
state: null
};
function TelephonyService() {
this._numClients = gRadioInterfaceLayer.numRadioInterfaces;
this._listeners = [];
this._currentCalls = {};
// _isActiveCall[clientId][callIndex] shows the active status of the call.
this._isActiveCall = {};
this._numActiveCall = 0;
this._updateDebugFlag();
this.defaultServiceId = this._getDefaultServiceId();
@ -129,6 +117,7 @@ function TelephonyService() {
for (let i = 0; i < this._numClients; ++i) {
this._enumerateCallsForClient(i);
this._isActiveCall[i] = {};
}
}
TelephonyService.prototype = {
@ -199,96 +188,68 @@ TelephonyService.prototype = {
}
},
_matchActiveSingleCall: function(aCall) {
return this._activeCall &&
this._activeCall instanceof SingleCall &&
this._activeCall.clientId === aCall.clientId &&
this._activeCall.callIndex === aCall.callIndex;
},
/**
* Track the active call and update the audio system as its state changes.
*/
_activeCall: null,
_updateActiveCall: function(aCall, aConferenceState) {
if (aConferenceState === nsITelephonyService.CALL_STATE_CONNECTED) {
this._activeCall = new ConferenceCall(aConferenceState);
this._updateCallAudioState(aCall);
return;
}
if (aConferenceState === nsITelephonyService.CALL_STATE_UNKNOWN ||
aConferenceState === nsITelephonyService.CALL_STATE_HELD) {
if (this._activeCall instanceof ConferenceCall) {
this._activeCall = null;
this._updateCallAudioState(aCall);
}
return;
}
if (!aCall) {
return;
}
if (aCall.isConference) {
if (this._matchActiveSingleCall(aCall)) {
this._activeCall = null;
}
return;
}
_updateActiveCall: function(aCall) {
let active = false;
let incoming = false;
switch (aCall.state) {
case nsITelephonyService.CALL_STATE_DIALING: // Fall through...
case nsITelephonyService.CALL_STATE_ALERTING:
case nsITelephonyService.CALL_STATE_CONNECTED:
this._activeCall = new SingleCall(aCall);
this._updateCallAudioState(aCall);
active = true;
break;
case nsITelephonyService.CALL_STATE_INCOMING:
this._updateCallAudioState(aCall);
incoming = true;
break;
case nsITelephonyService.CALL_STATE_HELD: // Fall through...
case nsITelephonyService.CALL_STATE_DISCONNECTED:
if (this._matchActiveSingleCall(aCall)) {
// Previously active call is not active now.
this._activeCall = null;
this._updateCallAudioState(aCall);
}
break;
}
// Update active count and info.
let oldActive = this._isActiveCall[aCall.clientId][aCall.callIndex];
if (!oldActive && active) {
this._numActiveCall++;
} else if (oldActive && !active) {
this._numActiveCall--;
}
this._isActiveCall[aCall.clientId][aCall.callIndex] = active;
if (incoming && !this._numActiveCall) {
// Change the phone state into RINGTONE only when there's no active call.
this._updateCallAudioState(AUDIO_STATE_INCOMING);
} else if (this._numActiveCall) {
this._updateCallAudioState(AUDIO_STATE_IN_CALL);
} else {
this._updateCallAudioState(AUDIO_STATE_NO_CALL);
}
},
_updateCallAudioState: function(aCall) {
let active = (this._activeCall !== null);
let incoming = (aCall &&
aCall.state === nsITelephonyService.CALL_STATE_INCOMING);
_updateCallAudioState: function(aAudioState) {
switch (aAudioState) {
case AUDIO_STATE_NO_CALL:
gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL;
break;
if (active) {
gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_IN_CALL;
if (this.speakerEnabled) {
gAudioManager.setForceForUse(nsIAudioManager.USE_COMMUNICATION,
nsIAudioManager.FORCE_SPEAKER);
}
if (DEBUG) {
debug("Active call, put audio system into PHONE_STATE_IN_CALL: " +
gAudioManager.phoneState);
}
} else if (incoming) {
// We can change the phone state into RINGTONE only when there's
// no active call.
gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_RINGTONE;
if (DEBUG) {
debug("Incoming call, put audio system into PHONE_STATE_RINGTONE: " +
gAudioManager.phoneState);
}
} else {
gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL;
if (DEBUG) {
debug("No active call, put audio system into PHONE_STATE_NORMAL: " +
gAudioManager.phoneState);
}
case AUDIO_STATE_INCOMING:
gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_RINGTONE;
break;
case AUDIO_STATE_IN_CALL:
gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_IN_CALL;
if (this.speakerEnabled) {
gAudioManager.setForceForUse(nsIAudioManager.USE_COMMUNICATION,
nsIAudioManager.FORCE_SPEAKER);
}
break;
}
if (DEBUG) {
debug("Put audio system into " + AUDIO_STATE_NAME[aAudioState] + ": " +
gAudioManager.phoneState);
}
},
@ -689,7 +650,7 @@ TelephonyService.prototype = {
}
gAudioManager.microphoneMuted = aMuted;
if (!this._activeCall) {
if (!this._numActiveCall) {
gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL;
}
},
@ -707,7 +668,7 @@ TelephonyService.prototype = {
nsIAudioManager.FORCE_NONE;
gAudioManager.setForceForUse(nsIAudioManager.USE_COMMUNICATION, force);
if (!this._activeCall) {
if (!this._numActiveCall) {
gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL;
}
},
@ -722,6 +683,7 @@ TelephonyService.prototype = {
notifyCallDisconnected: function(aClientId, aCall) {
if (DEBUG) debug("handleCallDisconnected: " + JSON.stringify(aCall));
aCall.clientId = aClientId;
aCall.state = nsITelephonyService.CALL_STATE_DISCONNECTED;
let duration = ("started" in aCall && typeof aCall.started == "number") ?
new Date().getTime() - aCall.started : 0;
@ -734,8 +696,6 @@ TelephonyService.prototype = {
};
gSystemMessenger.broadcastMessage("telephony-call-ended", data);
aCall.clientId = aClientId;
let manualConfStateChange = false;
let childId = this._currentCalls[aClientId][aCall.callIndex].childId;
if (childId) {
@ -761,7 +721,7 @@ TelephonyService.prototype = {
}
}
this._updateActiveCall(aCall, null);
this._updateActiveCall(aCall);
if (!aCall.failCause ||
aCall.failCause === RIL.GECKO_CALL_ERROR_NORMAL_CALL_CLEARING) {
@ -815,7 +775,7 @@ TelephonyService.prototype = {
}
aCall.clientId = aClientId;
this._updateActiveCall(aCall, null);
this._updateActiveCall(aCall);
let call = this._currentCalls[aClientId][aCall.callIndex];
if (call) {
@ -870,8 +830,6 @@ TelephonyService.prototype = {
notifyConferenceCallStateChanged: function(aState) {
if (DEBUG) debug("handleConferenceCallStateChanged: " + aState);
aState = this._convertRILCallState(aState);
this._updateActiveCall(null, aState);
this._notifyAllListeners("conferenceCallStateChanged", [aState]);
},

View File

@ -1391,8 +1391,18 @@ this.DownloadSaver.prototype = {
// The start time is always available when we reach this point.
let startPRTime = this.download.startTime.getTime() * 1000;
gDownloadHistory.addDownload(sourceUri, referrerUri, startPRTime,
targetUri);
try {
gDownloadHistory.addDownload(sourceUri, referrerUri, startPRTime,
targetUri);
}
catch(ex if ex instanceof Components.Exception &&
ex.result == Cr.NS_ERROR_NOT_AVAILABLE) {
//
// Under normal operation the download history service may not
// be available. We don't want all downloads that are public to fail
// when this happens so we'll ignore this error and this error only!
//
}
},
/**