Bug 1259148 - Notify content when the notification permission pop-up is dismissed by the user. r=past,wchen draft
authorKit Cambridge <kcambridge@mozilla.com>
Wed, 30 Mar 2016 16:54:37 -0700
changeset 355173 9570019d29aafc1cc8527a568540efc6781ce40e
parent 353712 ae7413abfa4d3954a6a4ce7c1613a7100f367f9a
child 355174 7b8a8b25711d7a4669115b00a2f23cb87b584ddf
push id16215
push userkcambridge@mozilla.com
push dateFri, 22 Apr 2016 00:22:17 +0000
reviewerspast, wchen
bugs1259148
milestone48.0a1
Bug 1259148 - Notify content when the notification permission pop-up is dismissed by the user. r=past,wchen MozReview-Commit-ID: 8CcgQcJDeie
browser/components/nsBrowserGlue.js
dom/notification/Notification.cpp
dom/notification/Notification.h
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -2613,16 +2613,26 @@ ContentPermissionPrompt.prototype = {
           callback: function() {},
         },
       ];
     }
 
     var options = {
       learnMoreURL:
         Services.urlFormatter.formatURLPref("app.support.baseURL") + "push",
+      eventCallback(type) {
+        if (type == "dismissed") {
+          // Bug 1259148: Hide the doorhanger icon. Unlike other permission
+          // doorhangers, the user can't restore the doorhanger using the icon
+          // in the location bar. Instead, the site will be notified that the
+          // doorhanger was dismissed.
+          this.remove();
+          aRequest.cancel();
+        }
+      },
     };
 
     this._showPrompt(aRequest, message, "desktop-notification", actions,
                      "web-notifications",
                      "web-notifications-notification-icon", options);
   },
 
   _promptPointerLock: function CPP_promtPointerLock(aRequest, autoAllow) {
--- a/dom/notification/Notification.cpp
+++ b/dom/notification/Notification.cpp
@@ -609,17 +609,21 @@ NotificationPermissionRequest::GetElemen
   NS_ENSURE_ARG_POINTER(aElement);
   *aElement = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 NotificationPermissionRequest::Cancel()
 {
-  mPermission = NotificationPermission::Denied;
+  // `Cancel` is called if the user denied permission or dismissed the
+  // permission request. To distinguish between the two, we set the
+  // permission to "default" and query the permission manager in
+  // `ResolvePromise`.
+  mPermission = NotificationPermission::Default;
   return DispatchResolvePromise();
 }
 
 NS_IMETHODIMP
 NotificationPermissionRequest::Allow(JS::HandleValue aChoices)
 {
   MOZ_ASSERT(aChoices.isUndefined());
 
@@ -644,16 +648,21 @@ NotificationPermissionRequest::DispatchR
     &NotificationPermissionRequest::ResolvePromise);
   return NS_DispatchToMainThread(resolveRunnable);
 }
 
 nsresult
 NotificationPermissionRequest::ResolvePromise()
 {
   nsresult rv = NS_OK;
+  if (mPermission == NotificationPermission::Default) {
+    // This will still be "default" if the user dismissed the doorhanger,
+    // or "denied" otherwise.
+    mPermission = Notification::TestPermission(mPrincipal);
+  }
   if (mCallback) {
     ErrorResult error;
     mCallback->Call(mPermission, error);
     rv = error.StealNSResult();
   }
   Telemetry::Accumulate(
     Telemetry::WEB_NOTIFICATION_REQUEST_PERMISSION_CALLBACK, !!mCallback);
   mPromise->MaybeResolve(mPermission);
@@ -1942,20 +1951,31 @@ Notification::GetPermissionInternal(nsIP
   if (Preferences::GetBool("notification.prompt.testing", false)) {
     if (Preferences::GetBool("notification.prompt.testing.allow", true)) {
       return NotificationPermission::Granted;
     } else {
       return NotificationPermission::Denied;
     }
   }
 
+  return TestPermission(aPrincipal);
+}
+
+/* static */ NotificationPermission
+Notification::TestPermission(nsIPrincipal* aPrincipal)
+{
+  AssertIsOnMainThread();
+
   uint32_t permission = nsIPermissionManager::UNKNOWN_ACTION;
 
   nsCOMPtr<nsIPermissionManager> permissionManager =
     services::GetPermissionManager();
+  if (!permissionManager) {
+    return NotificationPermission::Default;
+  }
 
   permissionManager->TestExactPermissionFromPrincipal(aPrincipal,
                                                       "desktop-notification",
                                                       &permission);
 
   // Convert the result to one of the enum types.
   switch (permission) {
   case nsIPermissionManager::ALLOW_ACTION:
--- a/dom/notification/Notification.h
+++ b/dom/notification/Notification.h
@@ -312,16 +312,18 @@ public:
   void ReleaseObject();
 
   static NotificationPermission GetPermission(nsIGlobalObject* aGlobal,
                                               ErrorResult& aRv);
 
   static NotificationPermission GetPermissionInternal(nsIPrincipal* aPrincipal,
                                                       ErrorResult& rv);
 
+  static NotificationPermission TestPermission(nsIPrincipal* aPrincipal);
+
   bool DispatchClickEvent();
   bool DispatchNotificationClickEvent();
 
   static nsresult RemovePermission(nsIPrincipal* aPrincipal);
   static nsresult OpenSettings(nsIPrincipal* aPrincipal);
 protected:
   Notification(nsIGlobalObject* aGlobal, const nsAString& aID,
                const nsAString& aTitle, const nsAString& aBody,