mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 777445 - Network activity indicator for B2G, r=jduell
This commit is contained in:
parent
971f193cff
commit
874dc9c6a2
@ -553,3 +553,9 @@ pref("ui.mouse.radius.enabled", true);
|
||||
|
||||
// Disable native prompt
|
||||
pref("browser.prompt.allowNative", false);
|
||||
|
||||
// Minimum delay in milliseconds between network activity notifications (0 means
|
||||
// no notifications). The delay is the same for both download and upload, though
|
||||
// they are handled separately. This pref is only read once at startup:
|
||||
// a restart is required to enable a new value.
|
||||
pref("network.activity.blipIntervalMilliseconds", 250);
|
||||
|
@ -3745,3 +3745,9 @@ pref("dom.mozApps.maxLocalId", 1000);
|
||||
// Let us know wether we should run the permissions update algorithm.
|
||||
// See Bug 787439
|
||||
pref("dom.mozApps.runUpdate", true);
|
||||
|
||||
// Minimum delay in milliseconds between network activity notifications (0 means
|
||||
// no notifications). The delay is the same for both download and upload, though
|
||||
// they are handled separately. This pref is only read once at startup:
|
||||
// a restart is required to enable a new value.
|
||||
pref("network.activity.blipIntervalMilliseconds", 0);
|
||||
|
@ -37,3 +37,16 @@ interface nsPISocketTransportService : nsISocketTransportService
|
||||
*/
|
||||
attribute boolean offline;
|
||||
};
|
||||
|
||||
%{C++
|
||||
/*
|
||||
* Network activity indicator: we send out these topics no more than every
|
||||
* blipIntervalMilliseconds (as set by the
|
||||
* "network.activity.blipIntervalMilliseconds" preference: if 0 no notifications
|
||||
* are sent) if the network is currently active (i.e. we're sending/receiving
|
||||
* data to/from the socket).
|
||||
*/
|
||||
#define NS_NETWORK_ACTIVITY_BLIP_UPLOAD_TOPIC "network-activity-blip-upload"
|
||||
#define NS_NETWORK_ACTIVITY_BLIP_DOWNLOAD_TOPIC "network-activity-blip-download"
|
||||
|
||||
%}
|
||||
|
@ -67,6 +67,7 @@ CPPSRCS = \
|
||||
nsPreloadedStream.cpp \
|
||||
nsStreamListenerWrapper.cpp \
|
||||
ProxyAutoConfig.cpp \
|
||||
NetworkActivityMonitor.cpp \
|
||||
$(NULL)
|
||||
|
||||
LOCAL_INCLUDES += -I$(topsrcdir)/dom/base
|
||||
|
294
netwerk/base/src/NetworkActivityMonitor.cpp
Normal file
294
netwerk/base/src/NetworkActivityMonitor.cpp
Normal file
@ -0,0 +1,294 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 "NetworkActivityMonitor.h"
|
||||
#include "prmem.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsPISocketTransportService.h"
|
||||
#include "nsSocketTransportService2.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "prerror.h"
|
||||
|
||||
using namespace mozilla::net;
|
||||
|
||||
static PRStatus
|
||||
nsNetMon_Connect(PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout)
|
||||
{
|
||||
PRStatus ret;
|
||||
PRErrorCode code;
|
||||
ret = fd->lower->methods->connect(fd->lower, addr, timeout);
|
||||
if (ret == PR_SUCCESS || (code = PR_GetError()) == PR_WOULD_BLOCK_ERROR ||
|
||||
code == PR_IN_PROGRESS_ERROR)
|
||||
NetworkActivityMonitor::DataInOut(NetworkActivityMonitor::kUpload);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
nsNetMon_Read(PRFileDesc *fd, void *buf, int32_t len)
|
||||
{
|
||||
int32_t ret;
|
||||
ret = fd->lower->methods->read(fd->lower, buf, len);
|
||||
if (ret >= 0)
|
||||
NetworkActivityMonitor::DataInOut(NetworkActivityMonitor::kDownload);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
nsNetMon_Write(PRFileDesc *fd, const void *buf, int32_t len)
|
||||
{
|
||||
int32_t ret;
|
||||
ret = fd->lower->methods->write(fd->lower, buf, len);
|
||||
if (ret > 0)
|
||||
NetworkActivityMonitor::DataInOut(NetworkActivityMonitor::kUpload);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
nsNetMon_Writev(PRFileDesc *fd,
|
||||
const PRIOVec *iov,
|
||||
int32_t size,
|
||||
PRIntervalTime timeout)
|
||||
{
|
||||
int32_t ret;
|
||||
ret = fd->lower->methods->writev(fd->lower, iov, size, timeout);
|
||||
if (ret > 0)
|
||||
NetworkActivityMonitor::DataInOut(NetworkActivityMonitor::kUpload);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
nsNetMon_Recv(PRFileDesc *fd,
|
||||
void *buf,
|
||||
int32_t amount,
|
||||
int flags,
|
||||
PRIntervalTime timeout)
|
||||
{
|
||||
int32_t ret;
|
||||
ret = fd->lower->methods->recv(fd->lower, buf, amount, flags, timeout);
|
||||
if (ret >= 0)
|
||||
NetworkActivityMonitor::DataInOut(NetworkActivityMonitor::kDownload);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
nsNetMon_Send(PRFileDesc *fd,
|
||||
const void *buf,
|
||||
int32_t amount,
|
||||
int flags,
|
||||
PRIntervalTime timeout)
|
||||
{
|
||||
int32_t ret;
|
||||
ret = fd->lower->methods->send(fd->lower, buf, amount, flags, timeout);
|
||||
if (ret > 0)
|
||||
NetworkActivityMonitor::DataInOut(NetworkActivityMonitor::kUpload);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
nsNetMon_RecvFrom(PRFileDesc *fd,
|
||||
void *buf,
|
||||
int32_t amount,
|
||||
int flags,
|
||||
PRNetAddr *addr,
|
||||
PRIntervalTime timeout)
|
||||
{
|
||||
int32_t ret;
|
||||
ret = fd->lower->methods->recvfrom(fd->lower,
|
||||
buf,
|
||||
amount,
|
||||
flags,
|
||||
addr,
|
||||
timeout);
|
||||
if (ret >= 0)
|
||||
NetworkActivityMonitor::DataInOut(NetworkActivityMonitor::kDownload);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
nsNetMon_SendTo(PRFileDesc *fd,
|
||||
const void *buf,
|
||||
int32_t amount,
|
||||
int flags,
|
||||
const PRNetAddr *addr,
|
||||
PRIntervalTime timeout)
|
||||
{
|
||||
int32_t ret;
|
||||
ret = fd->lower->methods->sendto(fd->lower,
|
||||
buf,
|
||||
amount,
|
||||
flags,
|
||||
addr,
|
||||
timeout);
|
||||
if (ret > 0)
|
||||
NetworkActivityMonitor::DataInOut(NetworkActivityMonitor::kUpload);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
nsNetMon_AcceptRead(PRFileDesc *listenSock,
|
||||
PRFileDesc **acceptedSock,
|
||||
PRNetAddr **peerAddr,
|
||||
void *buf,
|
||||
int32_t amount,
|
||||
PRIntervalTime timeout)
|
||||
{
|
||||
int32_t ret;
|
||||
ret = listenSock->lower->methods->acceptread(listenSock->lower,
|
||||
acceptedSock,
|
||||
peerAddr,
|
||||
buf,
|
||||
amount,
|
||||
timeout);
|
||||
if (ret > 0)
|
||||
NetworkActivityMonitor::DataInOut(NetworkActivityMonitor::kDownload);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
class NotifyNetworkActivity : public nsRunnable {
|
||||
public:
|
||||
NotifyNetworkActivity(nsIObserverService* aObs,
|
||||
NetworkActivityMonitor::Direction aDirection)
|
||||
: mObs(aObs)
|
||||
, mDirection(aDirection)
|
||||
{}
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
mObs->NotifyObservers(nullptr,
|
||||
mDirection == NetworkActivityMonitor::kUpload
|
||||
? NS_NETWORK_ACTIVITY_BLIP_UPLOAD_TOPIC
|
||||
: NS_NETWORK_ACTIVITY_BLIP_DOWNLOAD_TOPIC,
|
||||
nullptr);
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
nsCOMPtr<nsIObserverService> mObs;
|
||||
NetworkActivityMonitor::Direction mDirection;
|
||||
};
|
||||
|
||||
NetworkActivityMonitor * NetworkActivityMonitor::gInstance = nullptr;
|
||||
|
||||
NetworkActivityMonitor::NetworkActivityMonitor()
|
||||
: mLayerIdentity(PR_INVALID_IO_LAYER)
|
||||
, mBlipInterval(PR_INTERVAL_NO_TIMEOUT)
|
||||
, mLastNotificationTime({PR_INTERVAL_NO_TIMEOUT, PR_INTERVAL_NO_TIMEOUT})
|
||||
{
|
||||
NS_ASSERTION(gInstance==nullptr,
|
||||
"multiple NetworkActivityMonitor instances!");
|
||||
}
|
||||
|
||||
NetworkActivityMonitor::~NetworkActivityMonitor()
|
||||
{
|
||||
gInstance = nullptr;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NetworkActivityMonitor::Init(int32_t blipInterval)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (gInstance)
|
||||
return NS_ERROR_ALREADY_INITIALIZED;
|
||||
|
||||
NetworkActivityMonitor * mon = new NetworkActivityMonitor();
|
||||
rv = mon->Init_Internal(blipInterval);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete mon;
|
||||
return rv;
|
||||
}
|
||||
|
||||
gInstance = mon;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NetworkActivityMonitor::Shutdown()
|
||||
{
|
||||
if (!gInstance)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
delete gInstance;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NetworkActivityMonitor::Init_Internal(int32_t blipInterval)
|
||||
{
|
||||
mLayerIdentity = PR_GetUniqueIdentity("network activity monitor layer");
|
||||
mLayerMethods = *PR_GetDefaultIOMethods();
|
||||
mLayerMethods.connect = nsNetMon_Connect;
|
||||
mLayerMethods.read = nsNetMon_Read;
|
||||
mLayerMethods.write = nsNetMon_Write;
|
||||
mLayerMethods.writev = nsNetMon_Writev;
|
||||
mLayerMethods.recv = nsNetMon_Recv;
|
||||
mLayerMethods.send = nsNetMon_Send;
|
||||
mLayerMethods.recvfrom = nsNetMon_RecvFrom;
|
||||
mLayerMethods.sendto = nsNetMon_SendTo;
|
||||
mLayerMethods.acceptread = nsNetMon_AcceptRead;
|
||||
|
||||
mObserverService = mozilla::services::GetObserverService();
|
||||
if (!mObserverService)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mBlipInterval = PR_MillisecondsToInterval(blipInterval);
|
||||
// Set the last notification times to time that has just expired, so any
|
||||
// activity even right now will trigger notification.
|
||||
mLastNotificationTime[kUpload] = PR_IntervalNow() - mBlipInterval;
|
||||
mLastNotificationTime[kDownload] = mLastNotificationTime[kUpload];
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NetworkActivityMonitor::AttachIOLayer(PRFileDesc *fd)
|
||||
{
|
||||
if (!gInstance)
|
||||
return NS_OK;
|
||||
|
||||
PRFileDesc * layer;
|
||||
PRStatus status;
|
||||
|
||||
layer = PR_CreateIOLayerStub(gInstance->mLayerIdentity,
|
||||
&gInstance->mLayerMethods);
|
||||
if (!layer) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
status = PR_PushIOLayer(fd, PR_NSPR_IO_LAYER, layer);
|
||||
|
||||
if (status == PR_FAILURE) {
|
||||
PR_DELETE(layer);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NetworkActivityMonitor::DataInOut(Direction direction)
|
||||
{
|
||||
NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread");
|
||||
|
||||
if (gInstance) {
|
||||
PRIntervalTime now = PR_IntervalNow();
|
||||
if ((now - gInstance->mLastNotificationTime[direction]) >
|
||||
gInstance->mBlipInterval) {
|
||||
gInstance->mLastNotificationTime[direction] = now;
|
||||
gInstance->PostNotification(direction);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
NetworkActivityMonitor::PostNotification(Direction direction)
|
||||
{
|
||||
nsRefPtr<nsIRunnable> ev = new NotifyNetworkActivity(mObserverService,
|
||||
direction);
|
||||
NS_DispatchToMainThread(ev);
|
||||
}
|
49
netwerk/base/src/NetworkActivityMonitor.h
Normal file
49
netwerk/base/src/NetworkActivityMonitor.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#ifndef NetworkActivityMonitor_h___
|
||||
#define NetworkActivityMonitor_h___
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "prio.h"
|
||||
#include "prinrval.h"
|
||||
|
||||
class nsIObserverService;
|
||||
|
||||
namespace mozilla { namespace net {
|
||||
|
||||
class NetworkActivityMonitor
|
||||
{
|
||||
public:
|
||||
enum Direction {
|
||||
kUpload = 0,
|
||||
kDownload = 1
|
||||
};
|
||||
|
||||
NetworkActivityMonitor();
|
||||
~NetworkActivityMonitor();
|
||||
|
||||
static nsresult Init(int32_t blipInterval);
|
||||
static nsresult Shutdown();
|
||||
|
||||
static nsresult AttachIOLayer(PRFileDesc *fd);
|
||||
static nsresult DataInOut(Direction direction);
|
||||
|
||||
private:
|
||||
nsresult Init_Internal(int32_t blipInterval);
|
||||
void PostNotification(Direction direction);
|
||||
|
||||
static NetworkActivityMonitor * gInstance;
|
||||
PRDescIdentity mLayerIdentity;
|
||||
PRIOMethods mLayerMethods;
|
||||
PRIntervalTime mBlipInterval;
|
||||
PRIntervalTime mLastNotificationTime[2];
|
||||
nsCOMPtr<nsIObserverService> mObserverService;
|
||||
};
|
||||
|
||||
}} // namespace mozilla::net
|
||||
|
||||
#endif /* NetworkActivityMonitor_h___ */
|
@ -24,6 +24,7 @@
|
||||
#include "prnetdb.h"
|
||||
#include "prerror.h"
|
||||
#include "prerr.h"
|
||||
#include "NetworkActivityMonitor.h"
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsISocketProviderService.h"
|
||||
@ -1095,6 +1096,9 @@ nsSocketTransport::InitiateSocket()
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Attach network activity monitor
|
||||
mozilla::net::NetworkActivityMonitor::AttachIOLayer(fd);
|
||||
|
||||
PRStatus status;
|
||||
|
||||
// Make the socket non-blocking...
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIOService.h"
|
||||
#include "NetworkActivityMonitor.h"
|
||||
|
||||
|
||||
// XXX: There is no good header file to put these in. :(
|
||||
@ -40,6 +41,7 @@ PRThread *gSocketThread = nullptr;
|
||||
#define SEND_BUFFER_PREF "network.tcp.sendbuffer"
|
||||
#define SOCKET_LIMIT_TARGET 550U
|
||||
#define SOCKET_LIMIT_MIN 50U
|
||||
#define BLIB_INTERVAL_PREF "network.activity.blipIntervalMilliseconds"
|
||||
|
||||
uint32_t nsSocketTransportService::gMaxCount;
|
||||
PRCallOnceType nsSocketTransportService::gMaxCountInitOnce;
|
||||
@ -455,8 +457,18 @@ nsSocketTransportService::Init()
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> tmpPrefService = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
if (tmpPrefService)
|
||||
if (tmpPrefService) {
|
||||
tmpPrefService->AddObserver(SEND_BUFFER_PREF, this, false);
|
||||
|
||||
int32_t blipInterval = 0;
|
||||
rv = tmpPrefService->GetIntPref(BLIB_INTERVAL_PREF, &blipInterval);
|
||||
if (NS_SUCCEEDED(rv) && blipInterval > 0) {
|
||||
rv = mozilla::net::NetworkActivityMonitor::Init(blipInterval);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Can't initialize NetworkActivityMonitor");
|
||||
}
|
||||
}
|
||||
}
|
||||
UpdatePrefs();
|
||||
|
||||
mInitialized = true;
|
||||
@ -501,6 +513,8 @@ nsSocketTransportService::Shutdown()
|
||||
if (tmpPrefService)
|
||||
tmpPrefService->RemoveObserver(SEND_BUFFER_PREF, this);
|
||||
|
||||
mozilla::net::NetworkActivityMonitor::Shutdown();
|
||||
|
||||
mInitialized = false;
|
||||
mShuttingDown = false;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user