Bug 1210211 - Part 2: Notify Push service of visible notifications. r=baku a=ritu
authorWilliam Chen <wchen@mozilla.com>
Mon, 16 Nov 2015 21:33:17 -0800
changeset 305706 d7a61804d40ee969ab258a8509f87e184b6a7d11
parent 305705 2e2780789509cd4b281bffc004dff635d4930eca
child 305707 3a278f97f465784798a19227e37e66998371acbd
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku, ritu
bugs1210211
milestone44.0a2
Bug 1210211 - Part 2: Notify Push service of visible notifications. r=baku a=ritu
dom/interfaces/push/nsIPushNotificationService.idl
dom/notification/Notification.cpp
dom/push/PushNotificationService.js
--- a/dom/interfaces/push/nsIPushNotificationService.idl
+++ b/dom/interfaces/push/nsIPushNotificationService.idl
@@ -52,8 +52,26 @@ interface nsIPushNotificationService : n
    */
   jsval clearAll();
 
   /**
    * Clear subscriptions for a domain.
    */
   jsval clearForDomain(in string domain);
 };
+
+[scriptable, uuid(a2555e70-46f8-4b52-bf02-d978b979d143)]
+interface nsIPushQuotaManager : nsISupports
+{
+  /**
+   * Informs the quota manager that a notification
+   * for the given origin has been shown. Used to
+   * determine if push quota should be relaxed.
+   */
+  void notificationForOriginShown(in string origin);
+
+  /**
+   * Informs the quota manager that a notification
+   * for the given origin has been closed. Used to
+   * determine if push quota should be relaxed.
+   */
+  void notificationForOriginClosed(in string origin);
+};
--- a/dom/notification/Notification.cpp
+++ b/dom/notification/Notification.cpp
@@ -46,16 +46,20 @@
 #include "WorkerPrivate.h"
 #include "WorkerRunnable.h"
 #include "WorkerScope.h"
 
 #ifdef MOZ_B2G
 #include "nsIDOMDesktopNotification.h"
 #endif
 
+#ifndef MOZ_SIMPLEPUSH
+#include "nsIPushNotificationService.h"
+#endif
+
 namespace mozilla {
 namespace dom {
 
 using namespace workers;
 
 struct NotificationStrings
 {
   const nsString mID;
@@ -673,16 +677,18 @@ public:
     MOZ_ASSERT(mPrincipal);
   }
 
 protected:
   virtual ~NotificationObserver()
   {
     AssertIsOnMainThread();
   }
+
+  nsresult AdjustPushQuota(const char* aTopic);
 };
 
 NS_IMPL_ISUPPORTS(NotificationObserver, nsIObserver)
 
 class MainThreadNotificationObserver : public nsIObserver
 {
 public:
   UniquePtr<NotificationRef> mNotificationRef;
@@ -1169,21 +1175,49 @@ NotificationObserver::Observe(nsISupport
     if (XRE_IsParentProcess()) {
       return Notification::OpenSettings(mPrincipal);
     }
     // `ContentParent::RecvOpenNotificationSettings` notifies observers in the
     // parent process.
     ContentChild::GetSingleton()->SendOpenNotificationSettings(
       IPC::Principal(mPrincipal));
     return NS_OK;
+  } else if (!strcmp("alertshow", aTopic) ||
+             !strcmp("alertfinished", aTopic)) {
+    unused << NS_WARN_IF(NS_FAILED(AdjustPushQuota(aTopic)));
   }
 
   return mObserver->Observe(aSubject, aTopic, aData);
 }
 
+nsresult
+NotificationObserver::AdjustPushQuota(const char* aTopic)
+{
+#ifdef MOZ_SIMPLEPUSH
+  return NS_ERROR_NOT_IMPLEMENTED;
+#else
+  nsCOMPtr<nsIPushQuotaManager> pushQuotaManager =
+    do_GetService("@mozilla.org/push/NotificationService;1");
+  if (!pushQuotaManager) {
+    return NS_ERROR_FAILURE;
+  }
+
+  nsAutoCString origin;
+  nsresult rv = mPrincipal->GetOrigin(origin);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+
+  if (!strcmp("alertshow", aTopic)) {
+    return pushQuotaManager->NotificationForOriginShown(origin.get());
+  }
+  return pushQuotaManager->NotificationForOriginClosed(origin.get());
+#endif
+}
+
 NS_IMETHODIMP
 MainThreadNotificationObserver::Observe(nsISupports* aSubject, const char* aTopic,
                                         const char16_t* aData)
 {
   AssertIsOnMainThread();
   MOZ_ASSERT(mNotificationRef);
   Notification* notification = mNotificationRef->GetNotification();
   MOZ_ASSERT(notification);
--- a/dom/push/PushNotificationService.js
+++ b/dom/push/PushNotificationService.js
@@ -31,17 +31,18 @@ this.PushNotificationService = function 
 PushNotificationService.prototype = {
   classID: Components.ID("{32028e38-903b-4a64-a180-5857eb4cb3dd}"),
 
   contractID: "@mozilla.org/push/NotificationService;1",
 
   _xpcom_factory: XPCOMUtils.generateSingletonFactory(PushNotificationService),
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
                                          Ci.nsISupportsWeakReference,
-                                         Ci.nsIPushNotificationService]),
+                                         Ci.nsIPushNotificationService,
+                                         Ci.nsIPushQuotaManager,]),
 
   register: function register(scope, originAttributes) {
     return PushService._register({
       scope: scope,
       originAttributes: originAttributes,
       maxQuota: Infinity,
     });
   },
@@ -69,16 +70,36 @@ PushNotificationService.prototype = {
         break;
       case "sessionstore-windows-restored":
         Services.obs.removeObserver(this, "sessionstore-windows-restored");
         if (isParent) {
           PushService.init();
         }
         break;
     }
+  },
+
+  // nsIPushQuotaManager methods
+
+  notificationForOriginShown: function(origin) {
+    if (!isParent) {
+      Services.cpmm.sendAsyncMessage("Push:NotificationForOriginShown", origin);
+      return;
+    }
+
+    PushService._notificationForOriginShown(origin);
+  },
+
+  notificationForOriginClosed: function(origin) {
+    if (!isParent) {
+      Services.cpmm.sendAsyncMessage("Push:NotificationForOriginClosed", origin);
+      return;
+    }
+
+    PushService._notificationForOriginClosed(origin);
   }
 };
 
 this.PushObserverNotification = function PushObserverNotification() {};
 
 PushObserverNotification.prototype = {
   classID: Components.ID("{66a87970-6dc9-46e0-ac61-adb4a13791de}"),