зеркало из https://github.com/mozilla/gecko-dev.git
Bug 746073 - Network Per-App Metering on HTTP layer. r=honzab
This commit is contained in:
Родитель
56c88d861c
Коммит
ab4aae2e25
|
@ -34,6 +34,9 @@
|
|||
#include "nsIOService.h"
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include "nsINetworkStatsServiceProxy.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
|
@ -121,6 +124,9 @@ nsHttpTransaction::nsHttpTransaction()
|
|||
, mSubmittedRatePacing(false)
|
||||
, mPassedRatePacing(false)
|
||||
, mSynchronousRatePaceRequest(false)
|
||||
, mCountRecv(0)
|
||||
, mCountSent(0)
|
||||
, mAppId(NECKO_NO_APP_ID)
|
||||
{
|
||||
LOG(("Creating nsHttpTransaction @%p\n", this));
|
||||
gHttpHandler->GetMaxPipelineObjectSize(&mMaxPipelineObjectSize);
|
||||
|
@ -224,6 +230,18 @@ nsHttpTransaction::Init(uint32_t caps,
|
|||
mActivityDistributor = nullptr;
|
||||
}
|
||||
|
||||
// obtain app info
|
||||
bool isInBrowser;
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(eventsink);
|
||||
if (channel) {
|
||||
NS_GetAppInfo(channel, &mAppId, &isInBrowser);
|
||||
}
|
||||
|
||||
// obtain active connection type
|
||||
if (mAppId != NECKO_NO_APP_ID) {
|
||||
GetActiveNetwork();
|
||||
}
|
||||
|
||||
// create transport event sink proxy. it coalesces all events if and only
|
||||
// if the activity observer is not active. when the observer is active
|
||||
// we need not to coalesce any events to get all expected notifications
|
||||
|
@ -565,6 +583,7 @@ nsHttpTransaction::ReadRequestSegment(nsIInputStream *stream,
|
|||
"net::http::first-write");
|
||||
}
|
||||
|
||||
trans->CountSentBytes(*countRead);
|
||||
trans->mSentData = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -641,6 +660,7 @@ nsHttpTransaction::WritePipeSegment(nsIOutputStream *stream,
|
|||
}
|
||||
|
||||
MOZ_ASSERT(*countWritten > 0, "bad writer");
|
||||
trans->CountRecvBytes(*countWritten);
|
||||
trans->mReceivedData = true;
|
||||
|
||||
// Let the transaction "play" with the buffer. It is free to modify
|
||||
|
@ -687,6 +707,118 @@ nsHttpTransaction::WriteSegments(nsAHttpSegmentWriter *writer,
|
|||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsHttpTransaction::GetActiveNetwork()
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsINetworkManager> networkManager =
|
||||
do_GetService("@mozilla.org/network/manager;1", &rv);
|
||||
|
||||
if (NS_FAILED(rv) || !networkManager) {
|
||||
mActiveNetwork = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsINetworkInterface> activeNetwork;
|
||||
networkManager->GetActive(getter_AddRefs(activeNetwork));
|
||||
mActiveNetwork =
|
||||
new nsMainThreadPtrHolder<nsINetworkInterface>(activeNetwork);
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsHttpTransaction save network statistics event
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
namespace {
|
||||
class SaveNetworkStatsEvent : public nsRunnable {
|
||||
public:
|
||||
SaveNetworkStatsEvent(uint32_t aAppId,
|
||||
nsMainThreadPtrHandle<nsINetworkInterface> &aActiveNetwork,
|
||||
uint64_t aCountRecv,
|
||||
uint64_t aCountSent)
|
||||
: mAppId(aAppId),
|
||||
mActiveNetwork(aActiveNetwork),
|
||||
mCountRecv(aCountRecv),
|
||||
mCountSent(aCountSent)
|
||||
{
|
||||
MOZ_ASSERT(mAppId != NECKO_NO_APP_ID);
|
||||
MOZ_ASSERT(mActiveNetwork);
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsINetworkStatsServiceProxy> mNetworkStatsServiceProxy =
|
||||
do_GetService("@mozilla.org/networkstatsServiceProxy;1", &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// save the network stats through NetworkStatsServiceProxy
|
||||
mNetworkStatsServiceProxy->SaveAppStats(mAppId,
|
||||
mActiveNetwork,
|
||||
PR_Now() / 1000,
|
||||
mCountRecv,
|
||||
mCountSent,
|
||||
nullptr);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
uint32_t mAppId;
|
||||
nsMainThreadPtrHandle<nsINetworkInterface> mActiveNetwork;
|
||||
uint64_t mCountRecv;
|
||||
uint64_t mCountSent;
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
nsresult
|
||||
nsHttpTransaction::SaveNetworkStats(bool enforce)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// Check if active network and appid are valid.
|
||||
if (!mActiveNetwork || mAppId == NECKO_NO_APP_ID) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mCountRecv <= 0 && mCountSent <= 0) {
|
||||
// There is no traffic, no need to save.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If |enforce| is false, the traffic amount is saved
|
||||
// only when the total amount exceeds the predefined
|
||||
// threshold.
|
||||
uint64_t totalBytes = mCountRecv + mCountSent;
|
||||
if (!enforce && totalBytes < NETWORK_STATS_THRESHOLD) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Create the event to save the network statistics.
|
||||
// the event is then dispathed to the main thread.
|
||||
nsRefPtr<nsRunnable> event =
|
||||
new SaveNetworkStatsEvent(mAppId, mActiveNetwork,
|
||||
mCountRecv, mCountSent);
|
||||
NS_DispatchToMainThread(event);
|
||||
|
||||
// Reset the counters after saving.
|
||||
mCountSent = 0;
|
||||
mCountRecv = 0;
|
||||
|
||||
return NS_OK;
|
||||
#else
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
nsHttpTransaction::Close(nsresult reason)
|
||||
{
|
||||
|
@ -828,6 +960,9 @@ nsHttpTransaction::Close(nsresult reason)
|
|||
if (relConn && mConnection)
|
||||
NS_RELEASE(mConnection);
|
||||
|
||||
// save network statistics in the end of transaction
|
||||
SaveNetworkStats(true);
|
||||
|
||||
mStatus = reason;
|
||||
mTransactionDone = true; // forcibly flag the transaction as complete
|
||||
mClosed = true;
|
||||
|
|
|
@ -15,6 +15,11 @@
|
|||
#include "nsILoadGroup.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "TimingStruct.h"
|
||||
#include "nsProxyRelease.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include "nsINetworkManager.h"
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -332,6 +337,31 @@ private:
|
|||
bool mPassedRatePacing;
|
||||
bool mSynchronousRatePaceRequest;
|
||||
nsCOMPtr<nsICancelable> mTokenBucketCancel;
|
||||
|
||||
// These members are used for network per-app metering (bug 746073)
|
||||
// Currently, they are only available on gonk.
|
||||
public:
|
||||
const static uint64_t NETWORK_STATS_THRESHOLD = 65536;
|
||||
|
||||
private:
|
||||
uint64_t mCountRecv;
|
||||
uint64_t mCountSent;
|
||||
uint32_t mAppId;
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
nsMainThreadPtrHandle<nsINetworkInterface> mActiveNetwork;
|
||||
#endif
|
||||
nsresult SaveNetworkStats(bool);
|
||||
void GetActiveNetwork();
|
||||
void CountRecvBytes(uint64_t recvBytes)
|
||||
{
|
||||
mCountRecv += recvBytes;
|
||||
SaveNetworkStats(false);
|
||||
}
|
||||
void CountSentBytes(uint64_t sentBytes)
|
||||
{
|
||||
mCountSent += sentBytes;
|
||||
SaveNetworkStats(false);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // nsHttpTransaction_h__
|
||||
|
|
Загрузка…
Ссылка в новой задаче