Bug 795136 - 1/2 - Add events notifying the window if upload/download happen on the system. r=smaug sr=sicking

This commit is contained in:
Mounir Lamouri 2012-09-30 14:47:48 +01:00
parent 73187d5fd2
commit 990268d0ba
11 changed files with 220 additions and 5 deletions

View File

@ -727,6 +727,8 @@ GK_ATOM(onmozpointerlockerror, "onmozpointerlockerror")
GK_ATOM(onmoztimechange, "onmoztimechange")
GK_ATOM(onMozMousePixelScroll, "onMozMousePixelScroll")
GK_ATOM(onMozScrolledAreaChanged, "onMozScrolledAreaChanged")
GK_ATOM(onmoznetworkupload, "onmoznetworkupload")
GK_ATOM(onmoznetworkdownload, "onmoznetworkdownload")
GK_ATOM(onnoupdate, "onnoupdate")
GK_ATOM(onobsolete, "onobsolete")
GK_ATOM(ononline, "ononline")

View File

@ -467,6 +467,14 @@ WINDOW_ONLY_EVENT(moztimechange,
NS_MOZ_TIME_CHANGE_EVENT,
EventNameType_None,
NS_EVENT)
WINDOW_ONLY_EVENT(moznetworkupload,
NS_NETWORK_UPLOAD_EVENT,
EventNameType_None,
NS_EVENT)
WINDOW_ONLY_EVENT(moznetworkdownload,
NS_NETWORK_DOWNLOAD_EVENT,
EventNameType_None,
NS_EVENT)
TOUCH_EVENT(touchstart,
NS_TOUCH_START,

View File

@ -182,6 +182,18 @@ nsEventListenerManager::GetInnerWindowForTarget()
return nullptr;
}
already_AddRefed<nsPIDOMWindow>
nsEventListenerManager::GetTargetAsInnerWindow() const
{
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(mTarget);
if (!window) {
return nullptr;
}
NS_ASSERTION(window->IsInnerWindow(), "Target should not be an outer window");
return window.forget();
}
void
nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener,
uint32_t aType,
@ -279,6 +291,16 @@ nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener,
EnableDevice(NS_DEVICE_MOTION);
} else if (aTypeAtom == nsGkAtoms::onmoztimechange) {
EnableTimeChangeNotifications();
} else if (aTypeAtom == nsGkAtoms::onmoznetworkupload) {
nsCOMPtr<nsPIDOMWindow> window = GetTargetAsInnerWindow();
if (window) {
window->EnableNetworkEvent(NS_NETWORK_UPLOAD_EVENT);
}
} else if (aTypeAtom == nsGkAtoms::onmoznetworkdownload) {
nsCOMPtr<nsPIDOMWindow> window = GetTargetAsInnerWindow();
if (window) {
window->EnableNetworkEvent(NS_NETWORK_DOWNLOAD_EVENT);
}
} else if (aTypeAtom == nsGkAtoms::ontouchstart ||
aTypeAtom == nsGkAtoms::ontouchend ||
aTypeAtom == nsGkAtoms::ontouchmove ||
@ -404,6 +426,8 @@ nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener,
uint32_t typeCount = 0;
bool deviceType = IsDeviceType(aType);
bool timeChangeEvent = (aType == NS_MOZ_TIME_CHANGE_EVENT);
bool networkEvent = (aType == NS_NETWORK_UPLOAD_EVENT ||
aType == NS_NETWORK_DOWNLOAD_EVENT);
for (uint32_t i = 0; i < count; ++i) {
ls = &mListeners.ElementAt(i);
@ -417,7 +441,7 @@ nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener,
mNoListenerForEvent = NS_EVENT_TYPE_NULL;
mNoListenerForEventAtom = nullptr;
if (!deviceType && !timeChangeEvent) {
if (!deviceType && !timeChangeEvent && !networkEvent) {
return;
}
--typeCount;
@ -429,6 +453,11 @@ nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener,
DisableDevice(aType);
} else if (timeChangeEvent && typeCount == 0) {
DisableTimeChangeNotifications();
} else if (networkEvent && typeCount == 0) {
nsCOMPtr<nsPIDOMWindow> window = GetTargetAsInnerWindow();
if (window) {
window->DisableNetworkEvent(aType);
}
}
}

View File

@ -304,6 +304,7 @@ protected:
const EventTypeData* GetTypeDataForIID(const nsIID& aIID);
const EventTypeData* GetTypeDataForEventName(nsIAtom* aName);
nsPIDOMWindow* GetInnerWindowForTarget();
already_AddRefed<nsPIDOMWindow> GetTargetAsInnerWindow() const;
uint32_t mMayHavePaintEventListener : 1;
uint32_t mMayHaveMutationListeners : 1;

View File

@ -222,6 +222,7 @@
#include "prrng.h"
#include "nsSandboxFlags.h"
#include "TimeChangeObserver.h"
#include "nsPISocketTransportService.h"
#ifdef ANDROID
#include <android/log.h>
@ -416,6 +417,9 @@ static const char kPkcs11ContractID[] = NS_PKCS11_CONTRACTID;
#endif
static const char sPopStatePrefStr[] = "browser.history.allowPopState";
#define NETWORK_UPLOAD_EVENT_NAME NS_LITERAL_STRING("moznetworkupload")
#define NETWORK_DOWNLOAD_EVENT_NAME NS_LITERAL_STRING("moznetworkdownload")
/**
* An object implementing the window.URL property.
*/
@ -686,7 +690,9 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
mCallCleanUpAfterModalDialogCloses(false),
mDialogAbuseCount(0),
mStopAbuseDialogs(false),
mDialogsPermanentlyDisabled(false)
mDialogsPermanentlyDisabled(false),
mObservingNetworkUpload(false),
mObservingNetworkDownload(false)
{
nsLayoutStatics::AddRef();
@ -990,6 +996,9 @@ nsGlobalWindow::CleanUp(bool aIgnoreModalDialog)
os->RemoveObserver(mObserver, "dom-storage2-changed");
}
DisableNetworkEvent(NS_NETWORK_UPLOAD_EVENT);
DisableNetworkEvent(NS_NETWORK_DOWNLOAD_EVENT);
if (mIdleService) {
mIdleService->RemoveIdleObserver(mObserver, MIN_IDLE_NOTIFICATION_TIME_S);
}
@ -9050,6 +9059,23 @@ nsGlobalWindow::Observe(nsISupports* aSubject, const char* aTopic,
return NS_OK;
}
if (!nsCRT::strcmp(aTopic, NS_NETWORK_ACTIVITY_BLIP_UPLOAD_TOPIC) ||
!nsCRT::strcmp(aTopic, NS_NETWORK_ACTIVITY_BLIP_DOWNLOAD_TOPIC)) {
nsRefPtr<nsDOMEvent> event = new nsDOMEvent(nullptr, nullptr);
nsresult rv = event->InitEvent(
!nsCRT::strcmp(aTopic, NS_NETWORK_ACTIVITY_BLIP_UPLOAD_TOPIC)
? NETWORK_UPLOAD_EVENT_NAME
: NETWORK_DOWNLOAD_EVENT_NAME,
false, false);
NS_ENSURE_SUCCESS(rv, rv);
rv = event->SetTrusted(true);
NS_ENSURE_SUCCESS(rv, rv);
bool dummy;
return DispatchEvent(event, &dummy);
}
NS_WARNING("unrecognized topic in nsGlobalWindow::Observe");
return NS_ERROR_FAILURE;
}
@ -11102,6 +11128,58 @@ nsGlobalWindow::SetHasAudioAvailableEventListeners()
}
}
void
nsGlobalWindow::EnableNetworkEvent(uint32_t aType)
{
if ((mObservingNetworkUpload && aType == NS_NETWORK_UPLOAD_EVENT) ||
(mObservingNetworkDownload && aType == NS_NETWORK_DOWNLOAD_EVENT)) {
return;
}
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
if (!os) {
NS_ERROR("ObserverService should be available!");
return;
}
switch (aType) {
case NS_NETWORK_UPLOAD_EVENT:
os->AddObserver(mObserver, NS_NETWORK_ACTIVITY_BLIP_UPLOAD_TOPIC, false);
mObservingNetworkUpload = true;
break;
case NS_NETWORK_DOWNLOAD_EVENT:
os->AddObserver(mObserver, NS_NETWORK_ACTIVITY_BLIP_DOWNLOAD_TOPIC, false);
mObservingNetworkDownload = true;
break;
}
}
void
nsGlobalWindow::DisableNetworkEvent(uint32_t aType)
{
if ((!mObservingNetworkUpload && aType == NS_NETWORK_UPLOAD_EVENT) ||
(!mObservingNetworkDownload && aType == NS_NETWORK_DOWNLOAD_EVENT)) {
return;
}
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
if (!os) {
NS_ERROR("ObserverService should be available!");
return;
}
switch (aType) {
case NS_NETWORK_UPLOAD_EVENT:
os->RemoveObserver(mObserver, NS_NETWORK_ACTIVITY_BLIP_UPLOAD_TOPIC);
mObservingNetworkUpload = false;
break;
case NS_NETWORK_DOWNLOAD_EVENT:
os->RemoveObserver(mObserver, NS_NETWORK_ACTIVITY_BLIP_DOWNLOAD_TOPIC);
mObservingNetworkDownload = false;
break;
}
}
#define EVENT(name_, id_, type_, struct_) \
NS_IMETHODIMP nsGlobalWindow::GetOn##name_(JSContext *cx, \
jsval *vp) { \

View File

@ -537,6 +537,9 @@ public:
virtual void EnableTimeChangeNotifications();
virtual void DisableTimeChangeNotifications();
virtual void EnableNetworkEvent(uint32_t aType);
virtual void DisableNetworkEvent(uint32_t aType);
virtual nsresult SetArguments(nsIArray *aArguments, nsIPrincipal *aOrigin);
static bool DOMWindowDumpEnabled();
@ -1084,6 +1087,11 @@ protected:
// destroying this window).
bool mDialogsPermanentlyDisabled;
// Temporary booleans to know if we are currently observing network blips.
// Will be hopefully removed after bug 795703.
bool mObservingNetworkUpload;
bool mObservingNetworkDownload;
nsRefPtr<nsDOMMozURLProperty> mURLProperty;
nsTHashtable<nsPtrHashKey<nsDOMEventTargetHelper> > mEventTargetObjects;

View File

@ -48,8 +48,8 @@ class nsIArray;
class nsPIWindowRoot;
#define NS_PIDOMWINDOW_IID \
{ 0x0c5763c6, 0x5e87, 0x4f6f, \
{ 0xa2, 0xef, 0xcf, 0x4d, 0xeb, 0xd1, 0xbc, 0xc3 } }
{ 0x54fd92bd, 0xda33, 0x4451, \
{ 0x8f, 0xb5, 0x11, 0x20, 0x5c, 0x03, 0xce, 0xaa } }
class nsPIDOMWindow : public nsIDOMWindowInternal
{
@ -574,6 +574,18 @@ public:
virtual void EnableTimeChangeNotifications() = 0;
virtual void DisableTimeChangeNotifications() = 0;
/**
* Tell the window that it should start to listen to the network event of the
* given aType.
*/
virtual void EnableNetworkEvent(uint32_t aType) = 0;
/**
* Tell the window that it should stop to listen to the network event of the
* given aType.
*/
virtual void DisableNetworkEvent(uint32_t aType) = 0;
/**
* Set a arguments for this window. This will be set on the window
* right away (if there's an existing document) and it will also be

View File

@ -32,7 +32,7 @@ interface nsIDOMMozURLProperty : nsISupports
* @see <http://www.whatwg.org/html/#window>
*/
[scriptable, uuid(AB4ED3B8-84F8-4585-B413-0996A7F96D20)]
[scriptable, uuid(25404a1b-6c73-4850-af95-69aa095c8ad0)]
interface nsIDOMWindow : nsISupports
{
// the current browsing context
@ -501,6 +501,9 @@ interface nsIDOMWindow : nsISupports
[implicit_jscontext] attribute jsval onmouseenter;
[implicit_jscontext] attribute jsval onmouseleave;
[implicit_jscontext] attribute jsval onmoznetworkupload;
[implicit_jscontext] attribute jsval onmoznetworkdownload;
};
[scriptable, uuid(2146c906-57f7-486c-a1b4-8cdb57ef577f)]

View File

@ -46,6 +46,7 @@ MOCHITEST_FILES = \
file_moving_nodeList.html \
test_performance_now.html \
test_interfaces.html \
test_network_events.html \
$(NULL)
MOCHITEST_CHROME_FILES = \

View File

@ -0,0 +1,68 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=795136
-->
<head>
<meta charset="utf-8">
<title>Test for moznetworkupload and moznetworkdownload</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=795136">Mozilla Bug 795136</a>
<p id="display"></p>
<div id="content">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 795136 **/
SimpleTest.waitForExplicitFinish();
var gNetworkUpload = false;
var gNetworkDownload = false;
function isFinished() {
return gNetworkUpload && gNetworkDownload;
}
function finish() {
removeEventListener('moznetworkupload', uploadHandler);
removeEventListener('moznetworkdownload', downloadHandler);
SimpleTest.finish();
}
function uploadHandler() {
ok(true, 'got a network upload event');
gNetworkUpload = true;
if (isFinished()) {
finish();
}
}
function downloadHandler() {
ok(true, 'got a network download event');
gNetworkDownload = true;
if (isFinished()) {
finish();
}
}
addEventListener('moznetworkupload', uploadHandler);
addEventListener('moznetworkdownload', downloadHandler);
var iframe = document.createElement('iframe');
iframe.src = 'http://mozilla.org';
document.getElementById('content').appendChild(iframe);
</script>
</pre>
</body>
</html>

View File

@ -469,6 +469,11 @@ class nsHashKey;
//System time is changed
#define NS_MOZ_TIME_CHANGE_EVENT 5500
// Network packet events.
#define NS_NETWORK_EVENT_START 5600
#define NS_NETWORK_UPLOAD_EVENT (NS_NETWORK_EVENT_START + 1)
#define NS_NETWORK_DOWNLOAD_EVENT (NS_NETWORK_EVENT_START + 2)
/**
* Return status for event processors, nsEventStatus, is defined in
* nsEvent.h.