Bug 1965048 - Fire alertfinished for the previous same-tagged alert notification r=nalexander,geckoview-reviewers
Extracting from D242583 to land it separately. Differential Revision: https://phabricator.services.mozilla.com/D248312
This commit is contained in:
committed by
krosylight@mozilla.com
parent
3989028ce4
commit
4db6b6e5e0
@@ -1,10 +0,0 @@
|
|||||||
[tag.https.html]
|
|
||||||
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1891536
|
|
||||||
expected:
|
|
||||||
if os == "android": TIMEOUT
|
|
||||||
[Opening two notifications with the same tag should close the first one]
|
|
||||||
expected:
|
|
||||||
if os == "android": TIMEOUT
|
|
||||||
[Opening two notifications with the same tag should fire close event before show event]
|
|
||||||
expected:
|
|
||||||
if os == "android": NOTRUN
|
|
||||||
@@ -14,9 +14,19 @@ namespace widget {
|
|||||||
|
|
||||||
NS_IMPL_ISUPPORTS(AndroidAlerts, nsIAlertsService)
|
NS_IMPL_ISUPPORTS(AndroidAlerts, nsIAlertsService)
|
||||||
|
|
||||||
StaticAutoPtr<AndroidAlerts::ListenerMap> AndroidAlerts::sListenerMap;
|
struct AndroidNotificationTuple {
|
||||||
MOZ_RUNINIT nsTHashMap<nsStringHashKey, java::WebNotification::GlobalRef>
|
// Can be null if the caller doesn't care about the result.
|
||||||
AndroidAlerts::mNotificationsMap;
|
nsCOMPtr<nsIObserver> mObserver;
|
||||||
|
|
||||||
|
// The Gecko alert notification.
|
||||||
|
nsCOMPtr<nsIAlertNotification> mAlert;
|
||||||
|
|
||||||
|
// The Java represented form of mAlert.
|
||||||
|
mozilla::java::WebNotification::GlobalRef mNotificationRef;
|
||||||
|
};
|
||||||
|
|
||||||
|
using NotificationMap = nsTHashMap<nsStringHashKey, AndroidNotificationTuple>;
|
||||||
|
static StaticAutoPtr<NotificationMap> sNotificationMap;
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
AndroidAlerts::ShowAlertNotification(
|
AndroidAlerts::ShowAlertNotification(
|
||||||
@@ -92,45 +102,55 @@ AndroidAlerts::ShowAlert(nsIAlertNotification* aAlert,
|
|||||||
rv = aAlert->GetVibrate(vibrate);
|
rv = aAlert->GetVibrate(vibrate);
|
||||||
NS_ENSURE_SUCCESS(rv, NS_OK);
|
NS_ENSURE_SUCCESS(rv, NS_OK);
|
||||||
|
|
||||||
if (aAlertListener) {
|
if (!sNotificationMap) {
|
||||||
if (!sListenerMap) {
|
sNotificationMap = new NotificationMap();
|
||||||
sListenerMap = new ListenerMap();
|
} else if (Maybe<AndroidNotificationTuple> tuple =
|
||||||
|
sNotificationMap->Extract(name)) {
|
||||||
|
if (tuple->mObserver) {
|
||||||
|
tuple->mObserver->Observe(nullptr, "alertfinished", nullptr);
|
||||||
}
|
}
|
||||||
// This will remove any observers already registered for this name.
|
|
||||||
sListenerMap->InsertOrUpdate(name, aAlertListener);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
java::WebNotification::LocalRef notification = notification->New(
|
java::WebNotification::LocalRef notification = notification->New(
|
||||||
title, name, cookie, text, imageUrl, dir, lang, requireInteraction, spec,
|
title, name, cookie, text, imageUrl, dir, lang, requireInteraction, spec,
|
||||||
silent, privateBrowsing, jni::IntArray::From(vibrate));
|
silent, privateBrowsing, jni::IntArray::From(vibrate));
|
||||||
java::GeckoRuntime::LocalRef runtime = java::GeckoRuntime::GetInstance();
|
AndroidNotificationTuple tuple{
|
||||||
if (runtime != NULL) {
|
.mObserver = aAlertListener,
|
||||||
|
.mAlert = aAlert,
|
||||||
|
.mNotificationRef = notification,
|
||||||
|
};
|
||||||
|
sNotificationMap->InsertOrUpdate(name, std::move(tuple));
|
||||||
|
|
||||||
|
if (java::GeckoRuntime::LocalRef runtime =
|
||||||
|
java::GeckoRuntime::GetInstance()) {
|
||||||
runtime->NotifyOnShow(notification);
|
runtime->NotifyOnShow(notification);
|
||||||
}
|
}
|
||||||
mNotificationsMap.InsertOrUpdate(name, notification);
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
AndroidAlerts::CloseAlert(const nsAString& aAlertName, bool aContextClosed) {
|
AndroidAlerts::CloseAlert(const nsAString& aAlertName, bool aContextClosed) {
|
||||||
java::WebNotification::LocalRef notification =
|
if (!sNotificationMap) {
|
||||||
mNotificationsMap.Get(aAlertName);
|
return NS_OK;
|
||||||
if (!notification) {
|
}
|
||||||
|
|
||||||
|
Maybe<AndroidNotificationTuple> tuple =
|
||||||
|
sNotificationMap->MaybeGet(aAlertName);
|
||||||
|
if (!tuple) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
java::GeckoRuntime::LocalRef runtime = java::GeckoRuntime::GetInstance();
|
java::GeckoRuntime::LocalRef runtime = java::GeckoRuntime::GetInstance();
|
||||||
if (runtime != NULL) {
|
if (runtime != NULL) {
|
||||||
runtime->NotifyOnClose(notification);
|
runtime->NotifyOnClose(tuple->mNotificationRef);
|
||||||
}
|
}
|
||||||
mNotificationsMap.Remove(aAlertName);
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP AndroidAlerts::Teardown() {
|
NS_IMETHODIMP AndroidAlerts::Teardown() {
|
||||||
mNotificationsMap.Clear();
|
sNotificationMap = nullptr;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,20 +158,21 @@ NS_IMETHODIMP AndroidAlerts::PbmTeardown() { return NS_ERROR_NOT_IMPLEMENTED; }
|
|||||||
|
|
||||||
void AndroidAlerts::NotifyListener(const nsAString& aName, const char* aTopic,
|
void AndroidAlerts::NotifyListener(const nsAString& aName, const char* aTopic,
|
||||||
const char16_t* aCookie) {
|
const char16_t* aCookie) {
|
||||||
if (!sListenerMap) {
|
if (!sNotificationMap) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIObserver> listener = sListenerMap->Get(aName);
|
Maybe<AndroidNotificationTuple> tuple = sNotificationMap->MaybeGet(aName);
|
||||||
if (!listener) {
|
if (!tuple) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
listener->Observe(nullptr, aTopic, aCookie);
|
if (tuple->mObserver) {
|
||||||
|
tuple->mObserver->Observe(nullptr, aTopic, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
if ("alertfinished"_ns.Equals(aTopic)) {
|
if ("alertfinished"_ns.Equals(aTopic)) {
|
||||||
sListenerMap->Remove(aName);
|
sNotificationMap->Remove(aName);
|
||||||
mNotificationsMap.Remove(aName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,14 +30,8 @@ class AndroidAlerts : public nsIAlertsService {
|
|||||||
static void NotifyListener(const nsAString& aName, const char* aTopic,
|
static void NotifyListener(const nsAString& aName, const char* aTopic,
|
||||||
const char16_t* aCookie);
|
const char16_t* aCookie);
|
||||||
|
|
||||||
static nsTHashMap<nsStringHashKey, mozilla::java::WebNotification::GlobalRef>
|
|
||||||
mNotificationsMap;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~AndroidAlerts() { sListenerMap = nullptr; }
|
virtual ~AndroidAlerts() = default;
|
||||||
|
|
||||||
using ListenerMap = nsInterfaceHashtable<nsStringHashKey, nsIObserver>;
|
|
||||||
static StaticAutoPtr<ListenerMap> sListenerMap;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace widget
|
} // namespace widget
|
||||||
|
|||||||
Reference in New Issue
Block a user