diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:13:27 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:13:27 +0000 |
commit | 40a355a42d4a9444dc753c04c6608dade2f06a23 (patch) | |
tree | 871fc667d2de662f171103ce5ec067014ef85e61 /dom/notification | |
parent | Adding upstream version 124.0.1. (diff) | |
download | firefox-upstream/125.0.1.tar.xz firefox-upstream/125.0.1.zip |
Adding upstream version 125.0.1.upstream/125.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/notification')
-rw-r--r-- | dom/notification/Notification.cpp | 13 | ||||
-rw-r--r-- | dom/notification/Notification.h | 3 | ||||
-rw-r--r-- | dom/notification/NotificationStorage.sys.mjs | 2 | ||||
-rw-r--r-- | dom/notification/new/NotificationDB.sys.mjs | 25 | ||||
-rw-r--r-- | dom/notification/old/NotificationDB.sys.mjs | 32 | ||||
-rw-r--r-- | dom/notification/test/chrome/test_notification_system_principal.xhtml | 5 | ||||
-rw-r--r-- | dom/notification/test/mochitest/NotificationTest.js | 2 | ||||
-rw-r--r-- | dom/notification/test/mochitest/test_notification_basics.html | 2 | ||||
-rw-r--r-- | dom/notification/test/mochitest/test_notification_tag.html | 7 | ||||
-rw-r--r-- | dom/notification/test/unit/test_notificationdb.js | 2 |
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, { |