mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 855949 - Network Per-App Metering on WebSocket. r=mcmanus
This commit is contained in:
parent
97c78a1426
commit
a64ff312a6
@ -47,6 +47,11 @@
|
||||
#include "zlib.h"
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include "nsINetworkManager.h"
|
||||
#include "nsINetworkStatsServiceProxy.h"
|
||||
#endif
|
||||
|
||||
// rather than slurp up all of nsIWebSocket.idl, which lives outside necko, just
|
||||
// dupe one constant we need from it
|
||||
#define CLOSE_GOING_AWAY 1001
|
||||
@ -953,7 +958,12 @@ WebSocketChannel::WebSocketChannel() :
|
||||
mDynamicOutputSize(0),
|
||||
mDynamicOutput(nullptr),
|
||||
mPrivateBrowsing(false),
|
||||
mConnectionLogService(nullptr)
|
||||
mConnectionLogService(nullptr),
|
||||
mCountRecv(0),
|
||||
mCountSent(0),
|
||||
mAppId(0),
|
||||
mConnectionType(NETWORK_NO_TYPE),
|
||||
mIsInBrowser(false)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread");
|
||||
|
||||
@ -1062,6 +1072,16 @@ WebSocketChannel::BeginOpen()
|
||||
return;
|
||||
}
|
||||
|
||||
// obtain app info
|
||||
if (localChannel) {
|
||||
NS_GetAppInfo(localChannel, &mAppId, &mIsInBrowser);
|
||||
}
|
||||
|
||||
// obtain active connection type
|
||||
if (mAppId != NECKO_NO_APP_ID) {
|
||||
GetConnectionType(&mConnectionType);
|
||||
}
|
||||
|
||||
rv = localChannel->AsyncOpen(this, mHttpChannel);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("WebSocketChannel::BeginOpen: cannot async open\n"));
|
||||
@ -2709,6 +2729,9 @@ WebSocketChannel::Close(uint16_t code, const nsACString & reason)
|
||||
LOG(("WebSocketChannel::Close() %p\n", this));
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread");
|
||||
|
||||
// save the networkstats (bug 855949)
|
||||
SaveNetworkStats(true);
|
||||
|
||||
if (mRequestedClose) {
|
||||
return NS_OK;
|
||||
}
|
||||
@ -3035,6 +3058,9 @@ WebSocketChannel::OnInputStreamReady(nsIAsyncInputStream *aStream)
|
||||
rv = mSocketIn->Read((char *)buffer, 2048, &count);
|
||||
LOG(("WebSocketChannel::OnInputStreamReady: read %u rv %x\n", count, rv));
|
||||
|
||||
// accumulate received bytes
|
||||
CountRecvBytes(count);
|
||||
|
||||
if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
|
||||
mSocketIn->AsyncWait(this, 0, 0, mSocketThread);
|
||||
return NS_OK;
|
||||
@ -3114,6 +3140,9 @@ WebSocketChannel::OnOutputStreamReady(nsIAsyncOutputStream *aStream)
|
||||
LOG(("WebSocketChannel::OnOutputStreamReady: write %u rv %x\n",
|
||||
amtSent, rv));
|
||||
|
||||
// accumulate sent bytes
|
||||
CountSentBytes(amtSent);
|
||||
|
||||
if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
|
||||
mSocketOut->AsyncWait(this, 0, 0, nullptr);
|
||||
return NS_OK;
|
||||
@ -3239,5 +3268,74 @@ WebSocketChannel::OnDataAvailable(nsIRequest *aRequest,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
WebSocketChannel::GetConnectionType(int32_t *type)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsresult result;
|
||||
nsCOMPtr<nsINetworkManager> networkManager = do_GetService("@mozilla.org/network/manager;1", &result);
|
||||
|
||||
if (NS_FAILED(result) || !networkManager) {
|
||||
*type = NETWORK_NO_TYPE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsINetworkInterface> networkInterface;
|
||||
result = networkManager->GetActive(getter_AddRefs(networkInterface));
|
||||
|
||||
if (networkInterface) {
|
||||
result = networkInterface->GetType(type);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
#else
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
nsresult
|
||||
WebSocketChannel::SaveNetworkStats(bool enforce)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// Check if the connection type and app id are valid.
|
||||
if(mConnectionType == NETWORK_NO_TYPE ||
|
||||
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;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsINetworkStatsServiceProxy> mNetworkStatsServiceProxy =
|
||||
do_GetService("@mozilla.org/networkstatsServiceProxy;1", &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mNetworkStatsServiceProxy->SaveAppStats(mAppId, mConnectionType, PR_Now() / 1000,
|
||||
mCountRecv, mCountSent, nullptr);
|
||||
|
||||
// Reset the counters after saving.
|
||||
mCountSent = 0;
|
||||
mCountRecv = 0;
|
||||
|
||||
return NS_OK;
|
||||
#else
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace mozilla::net
|
||||
} // namespace mozilla
|
||||
|
@ -252,6 +252,31 @@ private:
|
||||
nsCOMPtr<nsIDashboardEventNotifier> mConnectionLogService;
|
||||
uint32_t mSerial;
|
||||
static uint32_t sSerialSeed;
|
||||
|
||||
// These members are used for network per-app metering (bug 855949)
|
||||
// Currently, they are only available on gonk.
|
||||
public:
|
||||
const static int32_t NETWORK_NO_TYPE = -1; // default conntection type
|
||||
const static uint64_t NETWORK_STATS_THRESHOLD = 65536;
|
||||
|
||||
private:
|
||||
uint64_t mCountRecv;
|
||||
uint64_t mCountSent;
|
||||
uint32_t mAppId;
|
||||
int32_t mConnectionType;
|
||||
bool mIsInBrowser;
|
||||
nsresult GetConnectionType(int32_t *);
|
||||
nsresult SaveNetworkStats(bool);
|
||||
void CountRecvBytes(uint64_t recvBytes)
|
||||
{
|
||||
mCountRecv += recvBytes;
|
||||
SaveNetworkStats(false);
|
||||
}
|
||||
void CountSentBytes(uint64_t sentBytes)
|
||||
{
|
||||
mCountSent += sentBytes;
|
||||
SaveNetworkStats(false);
|
||||
}
|
||||
};
|
||||
|
||||
class WebSocketSSLChannel : public WebSocketChannel
|
||||
|
Loading…
Reference in New Issue
Block a user