From 5987eb9e339bed629c218f671bd4bba2b9bf2fbc Mon Sep 17 00:00:00 2001 From: Matthew Noorenberghe Date: Fri, 25 Sep 2015 13:18:28 -0700 Subject: [PATCH] Bug 1205399 - Backend for disabling of notifications for a site from the UI. r=nsm --- dom/notification/Notification.cpp | 71 ++++++++++++++++++++++++++----- dom/notification/Notification.h | 2 +- 2 files changed, 61 insertions(+), 12 deletions(-) diff --git a/dom/notification/Notification.cpp b/dom/notification/Notification.cpp index 493ba14e46e..9bf02b2b062 100644 --- a/dom/notification/Notification.cpp +++ b/dom/notification/Notification.cpp @@ -653,17 +653,22 @@ NotificationPermissionRequest::GetTypes(nsIArray** aTypes) aTypes); } -class NotificationObserver : public nsIObserver +// Observer that the alert service calls to do common tasks and/or dispatch to the +// specific observer for the context e.g. main thread, worker, or service worker. +class NotificationObserver final : public nsIObserver { public: - UniquePtr mNotificationRef; + nsCOMPtr mObserver; + nsCOMPtr mPrincipal; NS_DECL_ISUPPORTS NS_DECL_NSIOBSERVER - explicit NotificationObserver(UniquePtr aRef) - : mNotificationRef(Move(aRef)) + NotificationObserver(nsIObserver* aObserver, nsIPrincipal* aPrincipal) + : mObserver(aObserver), mPrincipal(aPrincipal) { AssertIsOnMainThread(); + MOZ_ASSERT(mObserver); + MOZ_ASSERT(mPrincipal); } protected: @@ -675,6 +680,28 @@ protected: NS_IMPL_ISUPPORTS(NotificationObserver, nsIObserver) +class MainThreadNotificationObserver : public nsIObserver +{ +public: + UniquePtr mNotificationRef; + NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER + + explicit MainThreadNotificationObserver(UniquePtr aRef) + : mNotificationRef(Move(aRef)) + { + AssertIsOnMainThread(); + } + +protected: + virtual ~MainThreadNotificationObserver() + { + AssertIsOnMainThread(); + } +}; + +NS_IMPL_ISUPPORTS(MainThreadNotificationObserver, nsIObserver) + NS_IMETHODIMP NotificationTask::Run() { @@ -984,14 +1011,14 @@ Notification::GetPrincipal() } } -class WorkerNotificationObserver final : public NotificationObserver +class WorkerNotificationObserver final : public MainThreadNotificationObserver { public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIOBSERVER explicit WorkerNotificationObserver(UniquePtr aRef) - : NotificationObserver(Move(aRef)) + : MainThreadNotificationObserver(Move(aRef)) { AssertIsOnMainThread(); MOZ_ASSERT(mNotificationRef->GetNotification()->mWorkerPrivate); @@ -1017,7 +1044,7 @@ protected: } }; -NS_IMPL_ISUPPORTS_INHERITED0(WorkerNotificationObserver, NotificationObserver) +NS_IMPL_ISUPPORTS_INHERITED0(WorkerNotificationObserver, MainThreadNotificationObserver) class ServiceWorkerNotificationObserver final : public nsIObserver { @@ -1125,6 +1152,25 @@ NotificationObserver::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData) { AssertIsOnMainThread(); + + if (!strcmp("alertdisablecallback", aTopic)) { + nsCOMPtr permissionManager = + mozilla::services::GetPermissionManager(); + if (!permissionManager) { + return NS_ERROR_FAILURE; + } + permissionManager->RemoveFromPrincipal(mPrincipal, "desktop-notification"); + return NS_OK; + } + + return mObserver->Observe(aSubject, aTopic, aData); +} + +NS_IMETHODIMP +MainThreadNotificationObserver::Observe(nsISupports* aSubject, const char* aTopic, + const char16_t* aData) +{ + AssertIsOnMainThread(); MOZ_ASSERT(mNotificationRef); Notification* notification = mNotificationRef->GetNotification(); MOZ_ASSERT(notification); @@ -1384,16 +1430,19 @@ Notification::ShowInternal() mObserver = new WorkerNotificationObserver(Move(ownership)); observer = mObserver; } else { - observer = new NotificationObserver(Move(ownership)); + observer = new MainThreadNotificationObserver(Move(ownership)); } } else { // This observer does not care about the Notification. It will be released // at the end of this function. // - // The observer is wholly owned by the alerts service. + // The observer is wholly owned by the NotificationObserver passed to the alert service. observer = new ServiceWorkerNotificationObserver(mScope, GetPrincipal(), mID); } MOZ_ASSERT(observer); + nsCOMPtr alertObserver = new NotificationObserver(observer, + GetPrincipal()); + #ifdef MOZ_B2G nsCOMPtr appNotifier = @@ -1432,7 +1481,7 @@ Notification::ShowInternal() } appNotifier->ShowAppNotification(iconUrl, mTitle, mBody, - observer, val); + alertObserver, val); return; } } @@ -1463,7 +1512,7 @@ Notification::ShowInternal() nsAutoString alertName; GetAlertName(alertName); alertService->ShowAlertNotification(iconUrl, mTitle, mBody, true, - uniqueCookie, observer, alertName, + uniqueCookie, alertObserver, alertName, DirectionToString(mDir), mLang, mDataAsBase64, GetPrincipal(), inPrivateBrowsing); diff --git a/dom/notification/Notification.h b/dom/notification/Notification.h index 5153a5b5ac9..7ae08656847 100644 --- a/dom/notification/Notification.h +++ b/dom/notification/Notification.h @@ -102,7 +102,7 @@ class Notification : public DOMEventTargetHelper friend class CloseNotificationRunnable; friend class NotificationTask; friend class NotificationPermissionRequest; - friend class NotificationObserver; + friend class MainThreadNotificationObserver; friend class NotificationStorageCallback; friend class ServiceWorkerNotificationObserver; friend class WorkerGetRunnable;