Bug 855948 - Network Per-App Metering on FTP Layer. r=mcmanus

This commit is contained in:
John Shih 2013-10-24 12:04:44 +08:00
parent a3aed82e31
commit 2b819cd884
2 changed files with 102 additions and 5 deletions

View File

@ -43,6 +43,10 @@
#include "nsIURI.h"
#include "nsICacheSession.h"
#ifdef MOZ_WIDGET_GONK
#include "nsINetworkStatsServiceProxy.h"
#endif
#if defined(PR_LOGGING)
extern PRLogModuleInfo* gFTPLog;
#endif
@ -1684,9 +1688,12 @@ nsFtpState::Init(nsFtpChannel *channel)
mChannel = channel; // a straight ref ptr to the channel
// initialize counter for network metering
mCountRecv = 0;
mKeepRunning = true;
mSuppliedEntityID = channel->EntityID();
if (channel->UploadStream())
mAction = PUT;
@ -2176,13 +2183,79 @@ nsFtpState::ReadSegments(nsWriteSegmentFun writer, void *closure,
if (mDataStream) {
nsWriteSegmentThunk thunk = { this, writer, closure };
return mDataStream->ReadSegments(NS_WriteSegmentThunk, &thunk, count,
result);
nsresult rv;
rv = mDataStream->ReadSegments(NS_WriteSegmentThunk, &thunk, count,
result);
if (NS_SUCCEEDED(rv)) {
CountRecvBytes(*result);
}
return rv;
}
return nsBaseContentStream::ReadSegments(writer, closure, count, result);
}
nsresult
nsFtpState::SaveNetworkStats(bool enforce)
{
#ifdef MOZ_WIDGET_GONK
MOZ_ASSERT(NS_IsMainThread());
// Obtain active network
nsresult rv;
if (!mActiveNetwork) {
nsCOMPtr<nsINetworkManager> networkManager =
do_GetService("@mozilla.org/network/manager;1", &rv);
if (NS_FAILED(rv) || !networkManager) {
mActiveNetwork = nullptr;
return rv;
}
networkManager->GetActive(getter_AddRefs(mActiveNetwork));
}
// Obtain app id
uint32_t appId;
bool isInBrowser;
NS_GetAppInfo(mChannel, &appId, &isInBrowser);
// Check if active network and appid are valid.
if (!mActiveNetwork || appId == NECKO_NO_APP_ID) {
return NS_OK;
}
if (mCountRecv <= 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.
if (!enforce && mCountRecv < NETWORK_STATS_THRESHOLD) {
return NS_OK;
}
nsCOMPtr<nsINetworkStatsServiceProxy> networkStatsServiceProxy =
do_GetService("@mozilla.org/networkstatsServiceProxy;1", &rv);
if (NS_FAILED(rv)) {
return rv;
}
networkStatsServiceProxy->SaveAppStats(appId, mActiveNetwork,
PR_Now() / 1000, mCountRecv,
0, nullptr);
// Reset the counters after saving.
mCountRecv = 0;
return NS_OK;
#else
return NS_ERROR_NOT_IMPLEMENTED;
#endif
}
NS_IMETHODIMP
nsFtpState::CloseWithStatus(nsresult status)
{
@ -2202,6 +2275,9 @@ nsFtpState::CloseWithStatus(nsresult status)
}
if (mDataTransport) {
// Save the network stats before data transport is closing.
SaveNetworkStats(true);
// Shutdown the data transport.
mDataTransport->Close(NS_ERROR_ABORT);
mDataTransport = nullptr;

View File

@ -18,6 +18,10 @@
#include "nsFtpControlConnection.h"
#include "nsIProtocolProxyCallback.h"
#ifdef MOZ_WIDGET_GONK
#include "nsINetworkManager.h"
#endif
// ftp server types
#define FTP_GENERIC_TYPE 0
#define FTP_UNIX_TYPE 1
@ -239,7 +243,7 @@ private:
nsCOMPtr<nsIRequest> mUploadRequest;
bool mAddressChecked;
bool mServerIsIPv6;
static uint32_t mSessionStartTime;
mozilla::net::NetAddr mServerAddress;
@ -250,11 +254,28 @@ private:
nsCOMPtr<nsICacheEntryDescriptor> mCacheEntry;
bool mDoomCache;
nsCString mSuppliedEntityID;
nsCOMPtr<nsICancelable> mProxyRequest;
bool mDeferredCallbackPending;
// These members are used for network per-app metering (bug 855948)
// Currently, they are only available on gonk.
public:
const static uint64_t NETWORK_STATS_THRESHOLD = 65536;
private:
uint64_t mCountRecv;
#ifdef MOZ_WIDGET_GONK
nsCOMPtr<nsINetworkInterface> mActiveNetwork;
#endif
nsresult SaveNetworkStats(bool);
void CountRecvBytes(uint64_t recvBytes)
{
mCountRecv += recvBytes;
SaveNetworkStats(false);
}
};
#endif //__nsFtpState__h_