summaryrefslogtreecommitdiffstats
path: root/dom/notification
diff options
context:
space:
mode:
Diffstat (limited to 'dom/notification')
-rw-r--r--dom/notification/Notification.cpp13
-rw-r--r--dom/notification/Notification.h3
-rw-r--r--dom/notification/NotificationStorage.sys.mjs2
-rw-r--r--dom/notification/new/NotificationDB.sys.mjs25
-rw-r--r--dom/notification/old/NotificationDB.sys.mjs32
-rw-r--r--dom/notification/test/chrome/test_notification_system_principal.xhtml5
-rw-r--r--dom/notification/test/mochitest/NotificationTest.js2
-rw-r--r--dom/notification/test/mochitest/test_notification_basics.html2
-rw-r--r--dom/notification/test/mochitest/test_notification_tag.html7
-rw-r--r--dom/notification/test/unit/test_notificationdb.js2
10 files changed, 74 insertions, 19 deletions
diff --git a/dom/notification/Notification.cpp b/dom/notification/Notification.cpp
index 39ba7b23ff..fb5b0ea9a3 100644
--- a/dom/notification/Notification.cpp
+++ b/dom/notification/Notification.cpp
@@ -714,7 +714,12 @@ Notification::Notification(nsIGlobalObject* aGlobal, const nsAString& aID,
}
}
-nsresult Notification::Init() {
+nsresult Notification::MaybeObserveWindowFrozenOrDestroyed() {
+ // NOTE: Non-persistent notifications can also be opened from workers, but we
+ // don't care and nobody else cares. And it's not clear whether we even should
+ // do this for window at all, see
+ // https://github.com/whatwg/notifications/issues/204.
+ // TODO: Somehow extend GlobalTeardownObserver to deal with FROZEN_TOPIC?
if (!mWorkerPrivate) {
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
NS_ENSURE_TRUE(obs, NS_ERROR_FAILURE);
@@ -776,6 +781,10 @@ already_AddRefed<Notification> Notification::Constructor(
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
+ if (NS_WARN_IF(
+ NS_FAILED(notification->MaybeObserveWindowFrozenOrDestroyed()))) {
+ return nullptr;
+ }
// This is be ok since we are on the worker thread where this function will
// run to completion before the Notification has a chance to go away.
@@ -915,8 +924,6 @@ already_AddRefed<Notification> Notification::CreateInternal(
aGlobal, id, aTitle, aOptions.mBody, aOptions.mDir, aOptions.mLang,
aOptions.mTag, aOptions.mIcon, aOptions.mRequireInteraction, silent,
std::move(vibrate), aOptions.mMozbehavior);
- rv = notification->Init();
- NS_ENSURE_SUCCESS(rv, nullptr);
return notification.forget();
}
diff --git a/dom/notification/Notification.h b/dom/notification/Notification.h
index 4ffa69cf49..61f4a8f1c3 100644
--- a/dom/notification/Notification.h
+++ b/dom/notification/Notification.h
@@ -245,7 +245,8 @@ class Notification : public DOMEventTargetHelper,
nsIGlobalObject* aGlobal, const nsAString& aID, const nsAString& aTitle,
const NotificationOptions& aOptions, ErrorResult& aRv);
- nsresult Init();
+ // Triggers CloseInternal for non-persistent notifications if window goes away
+ nsresult MaybeObserveWindowFrozenOrDestroyed();
bool IsInPrivateBrowsing();
void ShowInternal();
void CloseInternal(bool aContextClosed = false);
diff --git a/dom/notification/NotificationStorage.sys.mjs b/dom/notification/NotificationStorage.sys.mjs
index 132771e088..46c9e2485c 100644
--- a/dom/notification/NotificationStorage.sys.mjs
+++ b/dom/notification/NotificationStorage.sys.mjs
@@ -42,7 +42,7 @@ NotificationStorage.prototype = {
}
},
- observe(aSubject, aTopic, aData) {
+ observe(aSubject, aTopic) {
if (DEBUG) {
debug("Topic: " + aTopic);
}
diff --git a/dom/notification/new/NotificationDB.sys.mjs b/dom/notification/new/NotificationDB.sys.mjs
index b607fdd234..d7e1d998c1 100644
--- a/dom/notification/new/NotificationDB.sys.mjs
+++ b/dom/notification/new/NotificationDB.sys.mjs
@@ -10,6 +10,7 @@ function debug(s) {
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
+ AsyncShutdown: "resource://gre/modules/AsyncShutdown.sys.mjs",
KeyValueService: "resource://gre/modules/kvstore.sys.mjs",
});
@@ -37,6 +38,11 @@ var NotificationDB = {
// of the load via its resolution.
_loadPromise: null,
+ // A promise that resolves once the ongoing task queue has been drained.
+ // The value will be reset when the queue starts again.
+ _queueDrainedPromise: null,
+ _queueDrainedPromiseResolve: null,
+
init() {
if (this._shutdownInProgress) {
return;
@@ -47,6 +53,13 @@ var NotificationDB = {
Services.obs.addObserver(this, "xpcom-shutdown");
this.registerListeners();
+
+ // This assumes that nothing will queue a new task at profile-change-teardown phase,
+ // potentially replacing the _queueDrainedPromise if there was no existing task run.
+ lazy.AsyncShutdown.profileChangeTeardown.addBlocker(
+ "NotificationDB: Need to make sure that all notification messages are processed",
+ () => this._queueDrainedPromise
+ );
},
registerListeners() {
@@ -61,7 +74,7 @@ var NotificationDB = {
}
},
- observe(aSubject, aTopic, aData) {
+ observe(aSubject, aTopic) {
if (DEBUG) {
debug("Topic: " + aTopic);
}
@@ -261,6 +274,9 @@ var NotificationDB = {
debug("Task queue was not running, starting now...");
}
this.runNextTask();
+ this._queueDrainedPromise = new Promise(resolve => {
+ this._queueDrainedPromiseResolve = resolve;
+ });
}
return promise;
@@ -272,6 +288,13 @@ var NotificationDB = {
debug("No more tasks to run, queue depleted");
}
this.runningTask = null;
+ if (this._queueDrainedPromiseResolve) {
+ this._queueDrainedPromiseResolve();
+ } else if (DEBUG) {
+ debug(
+ "_queueDrainedPromiseResolve was null somehow, no promise to resolve"
+ );
+ }
return;
}
this.runningTask = this.tasks.shift();
diff --git a/dom/notification/old/NotificationDB.sys.mjs b/dom/notification/old/NotificationDB.sys.mjs
index 79a9965628..7de9734450 100644
--- a/dom/notification/old/NotificationDB.sys.mjs
+++ b/dom/notification/old/NotificationDB.sys.mjs
@@ -7,6 +7,12 @@ function debug(s) {
dump("-*- NotificationDB component: " + s + "\n");
}
+const lazy = {};
+
+ChromeUtils.defineESModuleGetters(lazy, {
+ AsyncShutdown: "resource://gre/modules/AsyncShutdown.sys.mjs",
+});
+
const NOTIFICATION_STORE_DIR = PathUtils.profileDir;
const NOTIFICATION_STORE_PATH = PathUtils.join(
NOTIFICATION_STORE_DIR,
@@ -23,6 +29,11 @@ var NotificationDB = {
// Ensure we won't call init() while xpcom-shutdown is performed
_shutdownInProgress: false,
+ // A promise that resolves once the ongoing task queue has been drained.
+ // The value will be reset when the queue starts again.
+ _queueDrainedPromise: null,
+ _queueDrainedPromiseResolve: null,
+
init() {
if (this._shutdownInProgress) {
return;
@@ -37,6 +48,13 @@ var NotificationDB = {
Services.obs.addObserver(this, "xpcom-shutdown");
this.registerListeners();
+
+ // This assumes that nothing will queue a new task at profile-change-teardown phase,
+ // potentially replacing the _queueDrainedPromise if there was no existing task run.
+ lazy.AsyncShutdown.profileChangeTeardown.addBlocker(
+ "NotificationDB: Need to make sure that all notification messages are processed",
+ () => this._queueDrainedPromise
+ );
},
registerListeners() {
@@ -51,7 +69,7 @@ var NotificationDB = {
}
},
- observe(aSubject, aTopic, aData) {
+ observe(aSubject, aTopic) {
if (DEBUG) {
debug("Topic: " + aTopic);
}
@@ -114,7 +132,7 @@ var NotificationDB = {
},
// If read failed, we assume we have no notifications to load.
- reason => {
+ () => {
this.loaded = true;
return this.createStore();
}
@@ -251,6 +269,9 @@ var NotificationDB = {
debug("Task queue was not running, starting now...");
}
this.runNextTask();
+ this._queueDrainedPromise = new Promise(resolve => {
+ this._queueDrainedPromiseResolve = resolve;
+ });
}
return promise;
@@ -262,6 +283,13 @@ var NotificationDB = {
debug("No more tasks to run, queue depleted");
}
this.runningTask = null;
+ if (this._queueDrainedPromiseResolve) {
+ this._queueDrainedPromiseResolve();
+ } else if (DEBUG) {
+ debug(
+ "_queueDrainedPromiseResolve was null somehow, no promise to resolve"
+ );
+ }
return;
}
this.runningTask = this.tasks.shift();
diff --git a/dom/notification/test/chrome/test_notification_system_principal.xhtml b/dom/notification/test/chrome/test_notification_system_principal.xhtml
index 0700d59338..c563a817a8 100644
--- a/dom/notification/test/chrome/test_notification_system_principal.xhtml
+++ b/dom/notification/test/chrome/test_notification_system_principal.xhtml
@@ -23,14 +23,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=874090
const ALERTS_SERVICE_CONTRACT_ID = "@mozilla.org/alerts-service;1";
var mockAlertsService = {
- showAlert(alert, alertListener) {
+ showAlert() {
ok(true, "System principal was granted permission and is able to call showAlert.");
unregisterMock();
SimpleTest.finish();
},
- showAlertNotification(imageUrl, title, text, textClickable,
- cookie, alertListener, name, dir, lang, data) {
+ showAlertNotification() {
this.showAlert();
},
diff --git a/dom/notification/test/mochitest/NotificationTest.js b/dom/notification/test/mochitest/NotificationTest.js
index 400ff56253..8593125389 100644
--- a/dom/notification/test/mochitest/NotificationTest.js
+++ b/dom/notification/test/mochitest/NotificationTest.js
@@ -75,7 +75,7 @@ var NotificationTest = (function () {
);
},
- clickNotification(notification) {
+ clickNotification() {
// TODO: how??
},
diff --git a/dom/notification/test/mochitest/test_notification_basics.html b/dom/notification/test/mochitest/test_notification_basics.html
index 3dde839a96..ba2bd09174 100644
--- a/dom/notification/test/mochitest/test_notification_basics.html
+++ b/dom/notification/test/mochitest/test_notification_basics.html
@@ -68,7 +68,7 @@
Notification.requestPermission({})
.then(_ => {
ok(false, "Non callable arg to requestPermission should reject promise");
- }, err => {
+ }, () => {
ok(true, "Non callable arg to requestPermission should reject promise");
})
.then(done);
diff --git a/dom/notification/test/mochitest/test_notification_tag.html b/dom/notification/test/mochitest/test_notification_tag.html
index f4fc72bbe3..d2bc15418e 100644
--- a/dom/notification/test/mochitest/test_notification_tag.html
+++ b/dom/notification/test/mochitest/test_notification_tag.html
@@ -32,7 +32,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=782211
var notificationsCreated = [];
const mockAlertsService = {
- showAlert(alert, alertListener) {
+ showAlert(alert) {
notificationsCreated.push(alert.name);
if (notificationsCreated.length == 3) {
// notifications created by the test1 origin
@@ -78,10 +78,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=782211
textClickable,
cookie,
alertListener,
- name,
- dir,
- lang,
- data
+ name
) {
this.showAlert({ name });
},
diff --git a/dom/notification/test/unit/test_notificationdb.js b/dom/notification/test/unit/test_notificationdb.js
index 33397f87f3..b6ca8bd79c 100644
--- a/dom/notification/test/unit/test_notificationdb.js
+++ b/dom/notification/test/unit/test_notificationdb.js
@@ -112,7 +112,7 @@ add_test(function test_send_two_get_one() {
};
let msgSaveReply = "Notification:Save:Return:OK";
- let msgSaveHandler = function (message) {
+ let msgSaveHandler = function () {
calls += 1;
if (calls === 2) {
addAndSend("Notification:GetAll", msgGetReply, msgGetHandler, {