mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 904170 - telemetry for daily http data consumption r=jduell
This commit is contained in:
parent
1da3704a92
commit
176a4657e1
@ -378,6 +378,8 @@
|
|||||||
@BINPATH@/components/PeerConnection.js
|
@BINPATH@/components/PeerConnection.js
|
||||||
@BINPATH@/components/PeerConnection.manifest
|
@BINPATH@/components/PeerConnection.manifest
|
||||||
#endif
|
#endif
|
||||||
|
@BINPATH@/components/HttpDataUsage.manifest
|
||||||
|
@BINPATH@/components/HttpDataUsage.js
|
||||||
@BINPATH@/components/SiteSpecificUserAgent.js
|
@BINPATH@/components/SiteSpecificUserAgent.js
|
||||||
@BINPATH@/components/SiteSpecificUserAgent.manifest
|
@BINPATH@/components/SiteSpecificUserAgent.manifest
|
||||||
@BINPATH@/components/storage-Legacy.js
|
@BINPATH@/components/storage-Legacy.js
|
||||||
|
@ -544,6 +544,9 @@
|
|||||||
@BINPATH@/components/PeerConnection.manifest
|
@BINPATH@/components/PeerConnection.manifest
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@BINPATH@/components/HttpDataUsage.manifest
|
||||||
|
@BINPATH@/components/HttpDataUsage.js
|
||||||
|
|
||||||
@BINPATH@/chrome/marionette@JAREXT@
|
@BINPATH@/chrome/marionette@JAREXT@
|
||||||
@BINPATH@/chrome/marionette.manifest
|
@BINPATH@/chrome/marionette.manifest
|
||||||
@BINPATH@/components/MarionetteComponents.manifest
|
@BINPATH@/components/MarionetteComponents.manifest
|
||||||
|
@ -406,6 +406,9 @@
|
|||||||
@BINPATH@/components/PeerConnection.manifest
|
@BINPATH@/components/PeerConnection.manifest
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@BINPATH@/components/HttpDataUsage.manifest
|
||||||
|
@BINPATH@/components/HttpDataUsage.js
|
||||||
|
|
||||||
#ifdef MOZ_SERVICES_HEALTHREPORT
|
#ifdef MOZ_SERVICES_HEALTHREPORT
|
||||||
@BINPATH@/components/HealthReportComponents.manifest
|
@BINPATH@/components/HealthReportComponents.manifest
|
||||||
@BINPATH@/components/HealthReportService.js
|
@BINPATH@/components/HealthReportService.js
|
||||||
|
222
netwerk/protocol/http/HttpDataUsage.js
Normal file
222
netwerk/protocol/http/HttpDataUsage.js
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
/* -*- indent-tabs-mode: nil -*- */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
/* HTTPDATA_* telemetry producer
|
||||||
|
every 3 minutes of idle time we update a data file and report it
|
||||||
|
once a day. this avoids adding io to the shutdown path
|
||||||
|
*/
|
||||||
|
|
||||||
|
const Cc = Components.classes;
|
||||||
|
const Ci = Components.interfaces;
|
||||||
|
const Cr = Components.results;
|
||||||
|
const Cu = Components.utils;
|
||||||
|
const CC = Components.Constructor;
|
||||||
|
|
||||||
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
|
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyServiceGetter(this, "idleService",
|
||||||
|
"@mozilla.org/widget/idleservice;1",
|
||||||
|
"nsIIdleService");
|
||||||
|
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
|
||||||
|
"resource://gre/modules/FileUtils.jsm");
|
||||||
|
|
||||||
|
const MB = 1000000;
|
||||||
|
|
||||||
|
var gDataUsage;
|
||||||
|
function HttpDataUsage() {}
|
||||||
|
HttpDataUsage.prototype = {
|
||||||
|
classID: Components.ID("{6d72bfca-2747-4859-887f-6f06d4ce6787}"),
|
||||||
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
|
||||||
|
contractID: "@mozilla.org/network/HttpDataUsage;1",
|
||||||
|
|
||||||
|
_isIdleObserver: false,
|
||||||
|
_locked : false,
|
||||||
|
_do_telemetry : false,
|
||||||
|
_idle_timeout : 60 * 3,
|
||||||
|
_quanta : 86400000, // per day
|
||||||
|
|
||||||
|
_logtime : new Date(),
|
||||||
|
_ethernetRead : 0,
|
||||||
|
_ethernetWritten : 0,
|
||||||
|
_cellRead : 0,
|
||||||
|
_cellWritten : 0,
|
||||||
|
|
||||||
|
_dataFile : FileUtils.getFile("ProfD", ["httpDataUsage.dat"], true),
|
||||||
|
_dataUsage : Cc["@mozilla.org/network/protocol;1?name=http"]
|
||||||
|
.getService(Ci.nsIHttpProtocolHandler)
|
||||||
|
.QueryInterface(Ci.nsIHttpDataUsage),
|
||||||
|
_pipe : CC("@mozilla.org/pipe;1", "nsIPipe", "init"),
|
||||||
|
_outputStream : CC("@mozilla.org/network/file-output-stream;1",
|
||||||
|
"nsIFileOutputStream", "init"),
|
||||||
|
|
||||||
|
setup: function setup() {
|
||||||
|
gDataUsage = this;
|
||||||
|
|
||||||
|
var enabled = false;
|
||||||
|
try {
|
||||||
|
if (Services.prefs.getBoolPref("toolkit.telemetry.enabled"))
|
||||||
|
enabled = true;
|
||||||
|
} catch (e) { }
|
||||||
|
try {
|
||||||
|
if (Services.prefs.getBoolPref("toolkit.telemetry.enabledPreRelease"))
|
||||||
|
enabled = true;
|
||||||
|
} catch (e) { }
|
||||||
|
|
||||||
|
// this isn't important enough to worry about getting a
|
||||||
|
// runtime telemetry config change for
|
||||||
|
if (!enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (this._dataUsage == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
idleService.addIdleObserver(this, this._idle_timeout);
|
||||||
|
this._isIdleObserver = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
shutdown: function shutdown() {
|
||||||
|
if (this._isIdleObserver)
|
||||||
|
idleService.removeIdleObserver(this, this._idle_timeout);
|
||||||
|
this._isIdleObserver = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
sUpdateStats2: function sUpdateStats2(stream, result) {
|
||||||
|
gDataUsage.updateStats2(stream, result);
|
||||||
|
},
|
||||||
|
|
||||||
|
sGatherTelemetry2: function sGatherTelemetry2(stream, result) {
|
||||||
|
gDataUsage.gatherTelemetry2(stream, result);
|
||||||
|
},
|
||||||
|
|
||||||
|
readCounters: function readCounters(stream, result) {
|
||||||
|
if (Components.isSuccessCode(result)) {
|
||||||
|
let count = stream.available();
|
||||||
|
let data = NetUtil.readInputStreamToString(stream, count);
|
||||||
|
var list = data.split(",");
|
||||||
|
if (list.length == 5) {
|
||||||
|
this._logtime = new Date(Number(list[0]));
|
||||||
|
this._ethernetRead = Number(list[1]);
|
||||||
|
this._ethernetWritten = Number(list[2]);
|
||||||
|
this._cellRead = Number(list[3]);
|
||||||
|
this._cellWritten = Number(list[4]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._ethernetRead += this._dataUsage.ethernetBytesRead;
|
||||||
|
this._ethernetWritten += this._dataUsage.ethernetBytesWritten;
|
||||||
|
this._cellRead += this._dataUsage.cellBytesRead;
|
||||||
|
this._cellWritten += this._dataUsage.cellBytesWritten;
|
||||||
|
this._dataUsage.resetHttpDataUsage();
|
||||||
|
},
|
||||||
|
|
||||||
|
// writeCounters also releases the lock
|
||||||
|
writeCounters: function writeCounters() {
|
||||||
|
var dataout = this._logtime.getTime().toString() + "," +
|
||||||
|
this._ethernetRead.toString() + "," +
|
||||||
|
this._ethernetWritten.toString() + "," +
|
||||||
|
this._cellRead.toString() + "," +
|
||||||
|
this._cellWritten.toString() + "\n";
|
||||||
|
|
||||||
|
var buffer = new this._pipe(true, false, 4096, 1, null);
|
||||||
|
buffer.outputStream.write(dataout, dataout.length);
|
||||||
|
buffer.outputStream.close();
|
||||||
|
var fileOut = new this._outputStream(this._dataFile, -1, -1, 0);
|
||||||
|
|
||||||
|
NetUtil.asyncCopy(buffer.inputStream, fileOut,
|
||||||
|
function (result) { gDataUsage.finishedWriting(); });
|
||||||
|
},
|
||||||
|
|
||||||
|
updateStats2: function updateStats2(stream, result) {
|
||||||
|
this.readCounters(stream, result);
|
||||||
|
this.writeCounters();
|
||||||
|
},
|
||||||
|
|
||||||
|
gatherTelemetry2: function gatherTelemetry2(stream, result) {
|
||||||
|
this.readCounters(stream, result);
|
||||||
|
|
||||||
|
var now = new Date();
|
||||||
|
var elapsed = now.getTime() - this._logtime.getTime();
|
||||||
|
// make sure we have at least 1 day of data
|
||||||
|
if (elapsed < this._quanta) {
|
||||||
|
this.finishedWriting();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var days = elapsed / this._quanta;
|
||||||
|
var eInPerQuanta = Math.floor(this._ethernetRead / days);
|
||||||
|
var eOutPerQuanta = Math.floor(this._ethernetWritten / days);
|
||||||
|
var cInPerQuanta = Math.floor(this._cellRead / days);
|
||||||
|
var cOutPerQuanta = Math.floor(this._cellWritten / days);
|
||||||
|
|
||||||
|
var histogram;
|
||||||
|
|
||||||
|
while (elapsed >= this._quanta) {
|
||||||
|
histogram = Services.telemetry.getHistogramById("HTTPDATA_DAILY_ETHERNET_IN");
|
||||||
|
histogram.add(Math.round(eInPerQuanta / MB));
|
||||||
|
histogram = Services.telemetry.getHistogramById("HTTPDATA_DAILY_ETHERNET_OUT");
|
||||||
|
histogram.add(Math.round(eOutPerQuanta / MB));
|
||||||
|
histogram = Services.telemetry.getHistogramById("HTTPDATA_DAILY_CELL_IN");
|
||||||
|
histogram.add(Math.round(cInPerQuanta / MB));
|
||||||
|
histogram = Services.telemetry.getHistogramById("HTTPDATA_DAILY_CELL_OUT");
|
||||||
|
histogram.add(Math.round(cOutPerQuanta / MB));
|
||||||
|
|
||||||
|
elapsed -= this._quanta;
|
||||||
|
this._ethernetRead -= eInPerQuanta;
|
||||||
|
this._ethernetWritten -= eOutPerQuanta;
|
||||||
|
this._cellRead -= cInPerQuanta;
|
||||||
|
this._cellWritten -= cOutPerQuanta;
|
||||||
|
}
|
||||||
|
this._logtime = new Date(now.getTime() - elapsed);
|
||||||
|
|
||||||
|
this.writeCounters();
|
||||||
|
},
|
||||||
|
|
||||||
|
finishedWriting : function finishedWriting() {
|
||||||
|
this._locked = false;
|
||||||
|
if (this._do_telemetry) {
|
||||||
|
this._do_telemetry = false;
|
||||||
|
this.gatherTelemetry();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
updateStats: function updateStats() {
|
||||||
|
if (this._locked)
|
||||||
|
return;
|
||||||
|
this._locked = true;
|
||||||
|
|
||||||
|
NetUtil.asyncFetch(this._dataFile, this.sUpdateStats2);
|
||||||
|
},
|
||||||
|
|
||||||
|
gatherTelemetry: function gatherTelemetry() {
|
||||||
|
if (this._locked)
|
||||||
|
return; // oh well, maybe next time
|
||||||
|
this._locked = true;
|
||||||
|
|
||||||
|
NetUtil.asyncFetch(this._dataFile, this.sGatherTelemetry2);
|
||||||
|
},
|
||||||
|
|
||||||
|
observe: function (aSubject, aTopic, aData) {
|
||||||
|
switch (aTopic) {
|
||||||
|
case "profile-after-change":
|
||||||
|
this.setup();
|
||||||
|
break;
|
||||||
|
case "gather-telemetry":
|
||||||
|
this._do_telemetry = true;
|
||||||
|
this.updateStats();
|
||||||
|
break;
|
||||||
|
case "idle":
|
||||||
|
this.updateStats();
|
||||||
|
break;
|
||||||
|
case "profile-change-net-teardown":
|
||||||
|
this.shutdown();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([HttpDataUsage]);
|
3
netwerk/protocol/http/HttpDataUsage.manifest
Normal file
3
netwerk/protocol/http/HttpDataUsage.manifest
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
component {6d72bfca-2747-4859-887f-6f06d4ce6787} HttpDataUsage.js
|
||||||
|
contract @mozilla.org/network/HttpDataUsage;1 {6d72bfca-2747-4859-887f-6f06d4ce6787}
|
||||||
|
category profile-after-change HttpDataUsage @mozilla.org/network/HttpDataUsage;1
|
@ -13,6 +13,7 @@ XPIDL_SOURCES += [
|
|||||||
'nsIHttpChannelAuthProvider.idl',
|
'nsIHttpChannelAuthProvider.idl',
|
||||||
'nsIHttpChannelChild.idl',
|
'nsIHttpChannelChild.idl',
|
||||||
'nsIHttpChannelInternal.idl',
|
'nsIHttpChannelInternal.idl',
|
||||||
|
'nsIHttpDataUsage.idl',
|
||||||
'nsIHttpEventSink.idl',
|
'nsIHttpEventSink.idl',
|
||||||
'nsIHttpHeaderVisitor.idl',
|
'nsIHttpHeaderVisitor.idl',
|
||||||
'nsIHttpProtocolHandler.idl',
|
'nsIHttpProtocolHandler.idl',
|
||||||
@ -81,6 +82,11 @@ EXTRA_JS_MODULES += [
|
|||||||
'UserAgentUpdates.jsm',
|
'UserAgentUpdates.jsm',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
EXTRA_COMPONENTS += [
|
||||||
|
'HttpDataUsage.js',
|
||||||
|
'HttpDataUsage.manifest',
|
||||||
|
]
|
||||||
|
|
||||||
FAIL_ON_WARNINGS = True
|
FAIL_ON_WARNINGS = True
|
||||||
|
|
||||||
LIBXUL_LIBRARY = True
|
LIBXUL_LIBRARY = True
|
||||||
|
@ -46,6 +46,8 @@ nsHttpConnection::nsHttpConnection()
|
|||||||
, mMaxBytesRead(0)
|
, mMaxBytesRead(0)
|
||||||
, mTotalBytesRead(0)
|
, mTotalBytesRead(0)
|
||||||
, mTotalBytesWritten(0)
|
, mTotalBytesWritten(0)
|
||||||
|
, mUnreportedBytesRead(0)
|
||||||
|
, mUnreportedBytesWritten(0)
|
||||||
, mKeepAlive(true) // assume to keep-alive by default
|
, mKeepAlive(true) // assume to keep-alive by default
|
||||||
, mKeepAliveMask(true)
|
, mKeepAliveMask(true)
|
||||||
, mDontReuse(false)
|
, mDontReuse(false)
|
||||||
@ -75,6 +77,7 @@ nsHttpConnection::~nsHttpConnection()
|
|||||||
{
|
{
|
||||||
LOG(("Destroying nsHttpConnection @%x\n", this));
|
LOG(("Destroying nsHttpConnection @%x\n", this));
|
||||||
|
|
||||||
|
ReportDataUsage(false);
|
||||||
if (!mEverUsedSpdy) {
|
if (!mEverUsedSpdy) {
|
||||||
LOG(("nsHttpConnection %p performed %d HTTP/1.x transactions\n",
|
LOG(("nsHttpConnection %p performed %d HTTP/1.x transactions\n",
|
||||||
this, mHttp1xTransactionCount));
|
this, mHttp1xTransactionCount));
|
||||||
@ -1182,6 +1185,8 @@ nsHttpConnection::CloseTransaction(nsAHttpTransaction *trans, nsresult reason)
|
|||||||
mCallbacks = nullptr;
|
mCallbacks = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReportDataUsage(false);
|
||||||
|
|
||||||
if (NS_FAILED(reason))
|
if (NS_FAILED(reason))
|
||||||
Close(reason);
|
Close(reason);
|
||||||
|
|
||||||
@ -1224,8 +1229,11 @@ nsHttpConnection::OnReadSegment(const char *buf,
|
|||||||
else {
|
else {
|
||||||
mLastWriteTime = PR_IntervalNow();
|
mLastWriteTime = PR_IntervalNow();
|
||||||
mSocketOutCondition = NS_OK; // reset condition
|
mSocketOutCondition = NS_OK; // reset condition
|
||||||
if (!mProxyConnectInProgress)
|
if (!mProxyConnectInProgress) {
|
||||||
mTotalBytesWritten += *countRead;
|
mTotalBytesWritten += *countRead;
|
||||||
|
mUnreportedBytesWritten += *countRead;
|
||||||
|
ReportDataUsage(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return mSocketOutCondition;
|
return mSocketOutCondition;
|
||||||
@ -1443,6 +1451,8 @@ nsHttpConnection::OnSocketReadable()
|
|||||||
else {
|
else {
|
||||||
mCurrentBytesRead += n;
|
mCurrentBytesRead += n;
|
||||||
mTotalBytesRead += n;
|
mTotalBytesRead += n;
|
||||||
|
mUnreportedBytesRead += n;
|
||||||
|
ReportDataUsage(true);
|
||||||
if (NS_FAILED(mSocketInCondition)) {
|
if (NS_FAILED(mSocketInCondition)) {
|
||||||
// continue waiting for the socket if necessary...
|
// continue waiting for the socket if necessary...
|
||||||
if (mSocketInCondition == NS_BASE_STREAM_WOULD_BLOCK)
|
if (mSocketInCondition == NS_BASE_STREAM_WOULD_BLOCK)
|
||||||
@ -1507,6 +1517,27 @@ nsHttpConnection::SetupProxyConnect()
|
|||||||
return NS_NewCStringInputStream(getter_AddRefs(mProxyConnectStream), buf);
|
return NS_NewCStringInputStream(getter_AddRefs(mProxyConnectStream), buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsHttpConnection::ReportDataUsage(bool allowDefer)
|
||||||
|
{
|
||||||
|
static const uint64_t kDeferThreshold = 128000;
|
||||||
|
|
||||||
|
if (!mUnreportedBytesRead && !mUnreportedBytesWritten)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!gHttpHandler->IsTelemetryEnabled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (allowDefer &&
|
||||||
|
(mUnreportedBytesRead + mUnreportedBytesWritten) < kDeferThreshold) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gHttpHandler->UpdateDataUsage(mCallbacks,
|
||||||
|
mUnreportedBytesRead, mUnreportedBytesWritten);
|
||||||
|
mUnreportedBytesRead = mUnreportedBytesWritten = 0;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// nsHttpConnection::nsISupports
|
// nsHttpConnection::nsISupports
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -193,6 +193,9 @@ private:
|
|||||||
// Directly Add a transaction to an active connection for SPDY
|
// Directly Add a transaction to an active connection for SPDY
|
||||||
nsresult AddTransaction(nsAHttpTransaction *, int32_t);
|
nsresult AddTransaction(nsAHttpTransaction *, int32_t);
|
||||||
|
|
||||||
|
// used to inform nsIHttpDataUsage of transfer
|
||||||
|
void ReportDataUsage(bool);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsCOMPtr<nsISocketTransport> mSocketTransport;
|
nsCOMPtr<nsISocketTransport> mSocketTransport;
|
||||||
nsCOMPtr<nsIAsyncInputStream> mSocketIn;
|
nsCOMPtr<nsIAsyncInputStream> mSocketIn;
|
||||||
@ -226,6 +229,10 @@ private:
|
|||||||
int64_t mTotalBytesRead; // total data read
|
int64_t mTotalBytesRead; // total data read
|
||||||
int64_t mTotalBytesWritten; // does not include CONNECT tunnel
|
int64_t mTotalBytesWritten; // does not include CONNECT tunnel
|
||||||
|
|
||||||
|
// for nsIHttpDataUsage
|
||||||
|
uint64_t mUnreportedBytesRead; // subset of totalBytesRead
|
||||||
|
uint64_t mUnreportedBytesWritten; // subset of totalBytesWritten
|
||||||
|
|
||||||
nsRefPtr<nsIAsyncInputStream> mInputOverflow;
|
nsRefPtr<nsIAsyncInputStream> mInputOverflow;
|
||||||
|
|
||||||
PRIntervalTime mRtt;
|
PRIntervalTime mRtt;
|
||||||
|
@ -69,6 +69,10 @@
|
|||||||
#include <os2.h>
|
#include <os2.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(MOZ_WIDGET_GONK)
|
||||||
|
#include "nsINetworkManager.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::net;
|
using namespace mozilla::net;
|
||||||
@ -198,6 +202,12 @@ nsHttpHandler::nsHttpHandler()
|
|||||||
, mRequestTokenBucketHz(100)
|
, mRequestTokenBucketHz(100)
|
||||||
, mRequestTokenBucketBurst(32)
|
, mRequestTokenBucketBurst(32)
|
||||||
, mCritialRequestPrioritization(true)
|
, mCritialRequestPrioritization(true)
|
||||||
|
, mEthernetBytesRead(0)
|
||||||
|
, mEthernetBytesWritten(0)
|
||||||
|
, mCellBytesRead(0)
|
||||||
|
, mCellBytesWritten(0)
|
||||||
|
, mNetworkTypeKnown(false)
|
||||||
|
, mNetworkTypeWasEthernet(true)
|
||||||
{
|
{
|
||||||
#if defined(PR_LOGGING)
|
#if defined(PR_LOGGING)
|
||||||
gHttpLog = PR_NewLogModule("nsHttp");
|
gHttpLog = PR_NewLogModule("nsHttp");
|
||||||
@ -1505,13 +1515,14 @@ nsHttpHandler::SetAcceptEncodings(const char *aAcceptEncodings)
|
|||||||
// nsHttpHandler::nsISupports
|
// nsHttpHandler::nsISupports
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS6(nsHttpHandler,
|
NS_IMPL_ISUPPORTS7(nsHttpHandler,
|
||||||
nsIHttpProtocolHandler,
|
nsIHttpProtocolHandler,
|
||||||
nsIProxiedProtocolHandler,
|
nsIProxiedProtocolHandler,
|
||||||
nsIProtocolHandler,
|
nsIProtocolHandler,
|
||||||
nsIObserver,
|
nsIObserver,
|
||||||
nsISupportsWeakReference,
|
nsISupportsWeakReference,
|
||||||
nsISpeculativeConnect)
|
nsISpeculativeConnect,
|
||||||
|
nsIHttpDataUsage)
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// nsHttpHandler::nsIProtocolHandler
|
// nsHttpHandler::nsIProtocolHandler
|
||||||
@ -1931,45 +1942,248 @@ nsHttpHandler::SpeculativeConnect(nsIURI *aURI,
|
|||||||
return SpeculativeConnect(ci, aCallbacks);
|
return SpeculativeConnect(ci, aCallbacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
// nsIHttpDataUsage
|
||||||
nsHttpHandler::TickleWifi(nsIInterfaceRequestor *cb)
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHttpHandler::GetEthernetBytesRead(uint64_t *aEthernetBytesRead)
|
||||||
{
|
{
|
||||||
if (!cb || !mWifiTickler)
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
*aEthernetBytesRead = mEthernetBytesRead;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHttpHandler::GetEthernetBytesWritten(uint64_t *aEthernetBytesWritten)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
*aEthernetBytesWritten = mEthernetBytesWritten;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHttpHandler::GetCellBytesRead(uint64_t *aCellBytesRead)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
*aCellBytesRead = mCellBytesRead;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHttpHandler::GetCellBytesWritten(uint64_t *aCellBytesWritten)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
*aCellBytesWritten = mCellBytesWritten;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHttpHandler::ResetHttpDataUsage()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
mEthernetBytesRead = mEthernetBytesWritten = 0;
|
||||||
|
mCellBytesRead = mCellBytesWritten = 0;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
class DataUsageEvent : public nsRunnable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit DataUsageEvent(nsIInterfaceRequestor *cb,
|
||||||
|
uint64_t bytesRead,
|
||||||
|
uint64_t bytesWritten)
|
||||||
|
: mCB(cb), mRead(bytesRead), mWritten(bytesWritten) { }
|
||||||
|
|
||||||
|
NS_IMETHOD Run() MOZ_OVERRIDE
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
if (gHttpHandler)
|
||||||
|
gHttpHandler->UpdateDataUsage(mCB, mRead, mWritten);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
~DataUsageEvent() { }
|
||||||
|
nsCOMPtr<nsIInterfaceRequestor> mCB;
|
||||||
|
uint64_t mRead;
|
||||||
|
uint64_t mWritten;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
nsHttpHandler::UpdateDataUsage(nsIInterfaceRequestor *cb,
|
||||||
|
uint64_t bytesRead, uint64_t bytesWritten)
|
||||||
|
{
|
||||||
|
if (!IsTelemetryEnabled())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// If B2G requires a similar mechanism nsINetworkManager, currently only avail
|
if (!NS_IsMainThread()) {
|
||||||
// on B2G, contains the necessary information on wifi and gateway
|
nsRefPtr<nsIRunnable> event = new DataUsageEvent(cb, bytesRead, bytesWritten);
|
||||||
|
NS_DispatchToMainThread(event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isEthernet = true;
|
||||||
|
|
||||||
|
if (NS_FAILED(GetNetworkEthernetInfo(cb, &isEthernet))) {
|
||||||
|
// without a window it is hard for android to determine the network type
|
||||||
|
// so on failures we will just use the last value
|
||||||
|
if (!mNetworkTypeKnown)
|
||||||
|
return;
|
||||||
|
isEthernet = mNetworkTypeWasEthernet;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isEthernet) {
|
||||||
|
mEthernetBytesRead += bytesRead;
|
||||||
|
mEthernetBytesWritten += bytesWritten;
|
||||||
|
} else {
|
||||||
|
mCellBytesRead += bytesRead;
|
||||||
|
mCellBytesWritten += bytesWritten;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsHttpHandler::GetNetworkEthernetInfo(nsIInterfaceRequestor *cb,
|
||||||
|
bool *aEthernet)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aEthernet);
|
||||||
|
|
||||||
|
nsresult rv = GetNetworkEthernetInfoInner(cb, aEthernet);
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
mNetworkTypeKnown = true;
|
||||||
|
mNetworkTypeWasEthernet = *aEthernet;
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// aEthernet and aGateway are required out parameters
|
||||||
|
// on b2g and desktop gateway cannot be determined yet and
|
||||||
|
// this function returns ERROR_NOT_IMPLEMENTED.
|
||||||
|
nsresult
|
||||||
|
nsHttpHandler::GetNetworkInfo(nsIInterfaceRequestor *cb,
|
||||||
|
bool *aEthernet,
|
||||||
|
uint32_t *aGateway)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aEthernet);
|
||||||
|
NS_ENSURE_ARG_POINTER(aGateway);
|
||||||
|
|
||||||
|
nsresult rv = GetNetworkInfoInner(cb, aEthernet, aGateway);
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
mNetworkTypeKnown = true;
|
||||||
|
mNetworkTypeWasEthernet = *aEthernet;
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsHttpHandler::GetNetworkInfoInner(nsIInterfaceRequestor *cb,
|
||||||
|
bool *aEthernet,
|
||||||
|
uint32_t *aGateway)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aEthernet);
|
||||||
|
NS_ENSURE_ARG_POINTER(aGateway);
|
||||||
|
|
||||||
|
*aGateway = 0;
|
||||||
|
*aEthernet = true;
|
||||||
|
|
||||||
|
#if defined(MOZ_WIDGET_GONK)
|
||||||
|
// b2g only allows you to ask for ethernet or not right now.
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ANDROID)
|
||||||
|
if (!cb)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMWindow> domWindow;
|
nsCOMPtr<nsIDOMWindow> domWindow;
|
||||||
cb->GetInterface(NS_GET_IID(nsIDOMWindow), getter_AddRefs(domWindow));
|
cb->GetInterface(NS_GET_IID(nsIDOMWindow), getter_AddRefs(domWindow));
|
||||||
if (!domWindow)
|
if (!domWindow)
|
||||||
return;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNavigator> domNavigator;
|
nsCOMPtr<nsIDOMNavigator> domNavigator;
|
||||||
domWindow->GetNavigator(getter_AddRefs(domNavigator));
|
domWindow->GetNavigator(getter_AddRefs(domNavigator));
|
||||||
nsCOMPtr<nsIMozNavigatorNetwork> networkNavigator =
|
nsCOMPtr<nsIMozNavigatorNetwork> networkNavigator =
|
||||||
do_QueryInterface(domNavigator);
|
do_QueryInterface(domNavigator);
|
||||||
if (!networkNavigator)
|
if (!networkNavigator)
|
||||||
return;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMMozConnection> mozConnection;
|
nsCOMPtr<nsIDOMMozConnection> mozConnection;
|
||||||
networkNavigator->GetMozConnection(getter_AddRefs(mozConnection));
|
networkNavigator->GetMozConnection(getter_AddRefs(mozConnection));
|
||||||
nsCOMPtr<nsINetworkProperties> networkProperties =
|
nsCOMPtr<nsINetworkProperties> networkProperties =
|
||||||
do_QueryInterface(mozConnection);
|
do_QueryInterface(mozConnection);
|
||||||
if (!networkProperties)
|
if (!networkProperties)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
rv = networkProperties->GetDhcpGateway(aGateway);
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
return networkProperties->GetIsWifi(aEthernet);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// desktop does not currently know about the gateway
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsHttpHandler::GetNetworkEthernetInfoInner(nsIInterfaceRequestor *cb,
|
||||||
|
bool *aEthernet)
|
||||||
|
{
|
||||||
|
*aEthernet = true;
|
||||||
|
|
||||||
|
#if defined(MOZ_WIDGET_GONK)
|
||||||
|
int32_t networkType;
|
||||||
|
nsCOMPtr<nsINetworkManager> networkManager =
|
||||||
|
do_GetService("@mozilla.org/network/manager;1");
|
||||||
|
if (!networkManager)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
if (NS_FAILED(networkManager->GetPreferredNetworkType(&networkType)))
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
*aEthernet = networkType == nsINetworkInterface::NETWORK_TYPE_WIFI;
|
||||||
|
return NS_OK;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ANDROID)
|
||||||
|
if (!cb)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMWindow> domWindow;
|
||||||
|
cb->GetInterface(NS_GET_IID(nsIDOMWindow), getter_AddRefs(domWindow));
|
||||||
|
if (!domWindow)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMNavigator> domNavigator;
|
||||||
|
domWindow->GetNavigator(getter_AddRefs(domNavigator));
|
||||||
|
nsCOMPtr<nsIMozNavigatorNetwork> networkNavigator =
|
||||||
|
do_QueryInterface(domNavigator);
|
||||||
|
if (!networkNavigator)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMMozConnection> mozConnection;
|
||||||
|
networkNavigator->GetMozConnection(getter_AddRefs(mozConnection));
|
||||||
|
nsCOMPtr<nsINetworkProperties> networkProperties =
|
||||||
|
do_QueryInterface(mozConnection);
|
||||||
|
if (!networkProperties)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
return networkProperties->GetIsWifi(aEthernet);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// desktop assumes never on cell data
|
||||||
|
*aEthernet = true;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsHttpHandler::TickleWifi(nsIInterfaceRequestor *cb)
|
||||||
|
{
|
||||||
|
if (!cb || !mWifiTickler)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint32_t gwAddress;
|
uint32_t gwAddress;
|
||||||
bool isWifi;
|
bool isWifi;
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
rv = networkProperties->GetDhcpGateway(&gwAddress);
|
nsresult rv = GetNetworkInfo(cb, &isWifi, &gwAddress);
|
||||||
if (NS_SUCCEEDED(rv))
|
if (NS_FAILED(rv) || !gwAddress || !isWifi)
|
||||||
rv = networkProperties->GetIsWifi(&isWifi);
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!gwAddress || !isWifi)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mWifiTickler->SetIPV4Address(gwAddress);
|
mWifiTickler->SetIPV4Address(gwAddress);
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsWeakReference.h"
|
#include "nsWeakReference.h"
|
||||||
|
|
||||||
|
#include "nsIHttpDataUsage.h"
|
||||||
#include "nsIHttpProtocolHandler.h"
|
#include "nsIHttpProtocolHandler.h"
|
||||||
#include "nsIObserver.h"
|
#include "nsIObserver.h"
|
||||||
#include "nsISpeculativeConnect.h"
|
#include "nsISpeculativeConnect.h"
|
||||||
@ -50,6 +51,7 @@ class nsHttpHandler : public nsIHttpProtocolHandler
|
|||||||
, public nsIObserver
|
, public nsIObserver
|
||||||
, public nsSupportsWeakReference
|
, public nsSupportsWeakReference
|
||||||
, public nsISpeculativeConnect
|
, public nsISpeculativeConnect
|
||||||
|
, public nsIHttpDataUsage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||||||
@ -58,6 +60,7 @@ public:
|
|||||||
NS_DECL_NSIHTTPPROTOCOLHANDLER
|
NS_DECL_NSIHTTPPROTOCOLHANDLER
|
||||||
NS_DECL_NSIOBSERVER
|
NS_DECL_NSIOBSERVER
|
||||||
NS_DECL_NSISPECULATIVECONNECT
|
NS_DECL_NSISPECULATIVECONNECT
|
||||||
|
NS_DECL_NSIHTTPDATAUSAGE
|
||||||
|
|
||||||
nsHttpHandler();
|
nsHttpHandler();
|
||||||
virtual ~nsHttpHandler();
|
virtual ~nsHttpHandler();
|
||||||
@ -473,8 +476,30 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// for nsIHttpDataUsage
|
||||||
|
uint64_t mEthernetBytesRead;
|
||||||
|
uint64_t mEthernetBytesWritten;
|
||||||
|
uint64_t mCellBytesRead;
|
||||||
|
uint64_t mCellBytesWritten;
|
||||||
|
bool mNetworkTypeKnown;
|
||||||
|
bool mNetworkTypeWasEthernet;
|
||||||
|
|
||||||
nsRefPtr<mozilla::net::Tickler> mWifiTickler;
|
nsRefPtr<mozilla::net::Tickler> mWifiTickler;
|
||||||
|
nsresult GetNetworkEthernetInfo(nsIInterfaceRequestor *cb,
|
||||||
|
bool *ethernet);
|
||||||
|
nsresult GetNetworkEthernetInfoInner(nsIInterfaceRequestor *cb,
|
||||||
|
bool *ethernet);
|
||||||
|
nsresult GetNetworkInfo(nsIInterfaceRequestor *cb,
|
||||||
|
bool *ethernet, uint32_t *gw);
|
||||||
|
nsresult GetNetworkInfoInner(nsIInterfaceRequestor *cb,
|
||||||
|
bool *ethernet, uint32_t *gw);
|
||||||
void TickleWifi(nsIInterfaceRequestor *cb);
|
void TickleWifi(nsIInterfaceRequestor *cb);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// this is called to update the member variables used for nsIHttpDataUsage
|
||||||
|
// it can be called from any thread
|
||||||
|
void UpdateDataUsage(nsIInterfaceRequestor *cb,
|
||||||
|
uint64_t bytesRead, uint64_t bytesWritten);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern nsHttpHandler *gHttpHandler;
|
extern nsHttpHandler *gHttpHandler;
|
||||||
|
27
netwerk/protocol/http/nsIHttpDataUsage.idl
Normal file
27
netwerk/protocol/http/nsIHttpDataUsage.idl
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "nsISupports.idl"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nsIHttpDataUsage contains counters for the amount of HTTP data transferred
|
||||||
|
* in and out of this session since the last time it was reset with the
|
||||||
|
* resetHttpDataUsage() method. These counters are normally reset on each
|
||||||
|
* telemetry ping.
|
||||||
|
*
|
||||||
|
* Data is split into ethernet and cell. ethernet includes wifi.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
[scriptable, uuid(79dee3eb-9323-4d5c-b0a8-1baa18934d9e)]
|
||||||
|
interface nsIHttpDataUsage : nsISupports
|
||||||
|
{
|
||||||
|
readonly attribute unsigned long long ethernetBytesRead;
|
||||||
|
readonly attribute unsigned long long ethernetBytesWritten;
|
||||||
|
readonly attribute unsigned long long cellBytesRead;
|
||||||
|
readonly attribute unsigned long long cellBytesWritten;
|
||||||
|
|
||||||
|
void resetHttpDataUsage();
|
||||||
|
};
|
@ -869,6 +869,34 @@
|
|||||||
"kind": "boolean",
|
"kind": "boolean",
|
||||||
"description": "Whether a HTTP base page load was over SSL or not."
|
"description": "Whether a HTTP base page load was over SSL or not."
|
||||||
},
|
},
|
||||||
|
"HTTPDATA_DAILY_ETHERNET_IN": {
|
||||||
|
"kind": "exponential",
|
||||||
|
"high": "10000",
|
||||||
|
"n_buckets": 200,
|
||||||
|
"extended_statistics_ok": true,
|
||||||
|
"description": "MB of http ethernet data recvd in one day"
|
||||||
|
},
|
||||||
|
"HTTPDATA_DAILY_ETHERNET_OUT": {
|
||||||
|
"kind": "exponential",
|
||||||
|
"high": "10000",
|
||||||
|
"n_buckets": 200,
|
||||||
|
"extended_statistics_ok": true,
|
||||||
|
"description": "MB of http ethernet data sent in one day"
|
||||||
|
},
|
||||||
|
"HTTPDATA_DAILY_CELL_IN": {
|
||||||
|
"kind": "exponential",
|
||||||
|
"high": "10000",
|
||||||
|
"n_buckets": 200,
|
||||||
|
"extended_statistics_ok": true,
|
||||||
|
"description": "MB of http cell data recvd in one day"
|
||||||
|
},
|
||||||
|
"HTTPDATA_DAILY_CELL_OUT": {
|
||||||
|
"kind": "exponential",
|
||||||
|
"high": "10000",
|
||||||
|
"n_buckets": 200,
|
||||||
|
"extended_statistics_ok": true,
|
||||||
|
"description": "MB of http cell data sent in one day"
|
||||||
|
},
|
||||||
"SSL_HANDSHAKE_VERSION": {
|
"SSL_HANDSHAKE_VERSION": {
|
||||||
"kind": "enumerated",
|
"kind": "enumerated",
|
||||||
"n_values": 16,
|
"n_values": 16,
|
||||||
|
Loading…
Reference in New Issue
Block a user