Bug 1264815 - Add a component to handle 'persisent-notification-click'. r=kcambridge
☠☠ backed out by b98fa78343cd ☠ ☠
authorSUN Haitao <sunhaitao@devtaste.com>
Thu, 12 May 2016 09:28:46 +0800
changeset 299543 d049a47c24c1889cb547d4d899e998c75367e315
parent 299542 20d0b05e708bdf6f76450f147d706def62b0e158
child 299544 dd9e8143abd8b62b708cc886863781603dae1397
push id19444
push usercbook@mozilla.com
push dateTue, 31 May 2016 03:59:34 +0000
treeherderfx-team@d049a47c24c1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskcambridge
bugs1264815
milestone49.0a1
Bug 1264815 - Add a component to handle 'persisent-notification-click'. r=kcambridge
dom/notification/NotificationDB.jsm
dom/notification/NotificationStorage.js
mobile/android/components/MobileComponents.manifest
mobile/android/components/PersistentNotificationHandler.js
mobile/android/components/moz.build
mobile/android/installer/package-manifest.in
--- a/dom/notification/NotificationDB.jsm
+++ b/dom/notification/NotificationDB.jsm
@@ -77,36 +77,45 @@ var NotificationDB = {
     if (aTopic == "xpcom-shutdown") {
       this._shutdownInProgress = true;
       Services.obs.removeObserver(this, "xpcom-shutdown");
       this.unregisterListeners();
     }
   },
 
   filterNonAppNotifications: function(notifications) {
-    let origins = Object.keys(notifications);
-    for (let origin of origins) {
+    for (let origin in notifications) {
       let canPut = notificationStorage.canPut(origin);
       if (!canPut) {
-        if (DEBUG) debug("Origin " + origin + " is not linked to an app manifest, deleting.");
-	delete notifications[origin];
+        let persistentNotificationCount = 0;
+        for (let id in notifications[origin]) {
+          if (notifications[origin][id].serviceWorkerRegistrationScope) {
+            persistentNotificationCount++;
+          } else {
+            delete notifications[origin][id];
+          }
+        }
+        if (persistentNotificationCount == 0) {
+          if (DEBUG) debug("Origin " + origin + " is not linked to an app manifest, deleting.");
+          delete notifications[origin];
+        }
       }
     }
     return notifications;
   },
 
   // Attempt to read notification file, if it's not there we will create it.
   load: function() {
     var promise = OS.File.read(NOTIFICATION_STORE_PATH, { encoding: "utf-8"});
     return promise.then(
       function onSuccess(data) {
         if (data.length > 0) {
-	  // Preprocessing phase intends to cleanly separate any migration-related
+          // Preprocessing phase intends to cleanly separate any migration-related
           // tasks.
-	  this.notifications = this.filterNonAppNotifications(JSON.parse(data));
+          this.notifications = this.filterNonAppNotifications(JSON.parse(data));
         }
 
         // populate the list of notifications by tag
         if (this.notifications) {
           for (var origin in this.notifications) {
             this.byTag[origin] = {};
             for (var id in this.notifications[origin]) {
               var curNotification = this.notifications[origin][id];
--- a/dom/notification/NotificationStorage.js
+++ b/dom/notification/NotificationStorage.js
@@ -113,17 +113,17 @@ NotificationStorage.prototype = {
       if (this._byTag[origin][tag]) {
         var oldNotification = this._byTag[origin][tag];
         delete this._notifications[oldNotification.id];
       }
 
       this._byTag[origin][tag] = notification;
     };
 
-    if (this.canPut(origin)) {
+    if (serviceWorkerRegistrationScope || this.canPut(origin)) {
       cpmm.sendAsyncMessage("Notification:Save", {
         origin: origin,
         notification: notification
       });
     }
   },
 
   get: function(origin, tag, callback) {
--- a/mobile/android/components/MobileComponents.manifest
+++ b/mobile/android/components/MobileComponents.manifest
@@ -111,8 +111,13 @@ category update-timer Snippets @mozilla.
 
 # ColorPicker.js
 component {430b987f-bb9f-46a3-99a5-241749220b29} ColorPicker.js
 contract @mozilla.org/colorpicker;1 {430b987f-bb9f-46a3-99a5-241749220b29}
 
 # AndroidActivitiesGlue.js
 component {e4deb5f6-d5e3-4fce-bc53-901dd9951c48} AndroidActivitiesGlue.js
 contract @mozilla.org/dom/activities/ui-glue;1 {e4deb5f6-d5e3-4fce-bc53-901dd9951c48}
+
+# PersistentNotificationHandler.js
+component {75390fe7-f8a3-423a-b3b1-258d7eabed40} PersistentNotificationHandler.js
+contract @mozilla.org/persistent-notification-handler;1 {75390fe7-f8a3-423a-b3b1-258d7eabed40}
+category persistent-notification-click PersistentNotificationHandler @mozilla.org/persistent-notification-handler;1
new file mode 100644
--- /dev/null
+++ b/mobile/android/components/PersistentNotificationHandler.js
@@ -0,0 +1,57 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Messaging.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, 'Services', // jshint ignore:line
+                                  'resource://gre/modules/Services.jsm');
+XPCOMUtils.defineLazyServiceGetter(this, "notificationStorage",
+                                   "@mozilla.org/notificationStorage;1",
+                                   "nsINotificationStorage");
+XPCOMUtils.defineLazyServiceGetter(this, "serviceWorkerManager",
+                                   "@mozilla.org/serviceworkers/manager;1",
+                                   "nsIServiceWorkerManager");
+
+function PersistentNotificationHandler() {
+}
+
+PersistentNotificationHandler.prototype = {
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
+  classID: Components.ID("{75390fe7-f8a3-423a-b3b1-258d7eabed40}"),
+
+  observe(subject, topic, data) {
+    if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_DEFAULT) {
+      Cu.import("resource://gre/modules/NotificationDB.jsm");
+    }
+    const persistentInfo = JSON.parse(data);
+
+    notificationStorage.getByID(persistentInfo.origin, persistentInfo.id, {
+      handle(id, title, dir, lang, body, tag, icon, data, behavior, serviceWorkerRegistrationScope) {
+        serviceWorkerManager.sendNotificationClickEvent(
+          persistentInfo.originSuffix,
+          serviceWorkerRegistrationScope,
+          id,
+          title,
+          dir,
+          lang,
+          body,
+          tag,
+          icon,
+          data,
+          behavior
+        );
+        notificationStorage.delete(persistentInfo.origin, persistentInfo.id);
+      }
+    });
+  }
+};
+
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([
+  PersistentNotificationHandler
+]);
--- a/mobile/android/components/moz.build
+++ b/mobile/android/components/moz.build
@@ -20,16 +20,17 @@ EXTRA_COMPONENTS += [
     'ContentDispatchChooser.js',
     'ContentPermissionPrompt.js',
     'DirectoryProvider.js',
     'FilePicker.js',
     'HelperAppDialog.js',
     'ImageBlockingPolicy.js',
     'LoginManagerPrompter.js',
     'NSSDialogService.js',
+    'PersistentNotificationHandler.js',
     'PresentationDevicePrompt.js',
     'PromptService.js',
     'SessionStore.js',
     'SiteSpecificUserAgent.js',
     'Snippets.js',
     'TabSource.js',
     'XPIDialogService.js',
 ]
--- a/mobile/android/installer/package-manifest.in
+++ b/mobile/android/installer/package-manifest.in
@@ -533,16 +533,17 @@
 @BINPATH@/components/ImageBlockingPolicy.js
 @BINPATH@/components/DirectoryProvider.js
 @BINPATH@/components/FilePicker.js
 @BINPATH@/components/HelperAppDialog.js
 @BINPATH@/components/LoginManagerPrompter.js
 @BINPATH@/components/MobileComponents.manifest
 @BINPATH@/components/MobileComponents.xpt
 @BINPATH@/components/NSSDialogService.js
+@BINPATH@/components/PersistentNotificationHandler.js
 @BINPATH@/components/PresentationDevicePrompt.js
 @BINPATH@/components/PromptService.js
 @BINPATH@/components/SessionStore.js
 @BINPATH@/components/SiteSpecificUserAgent.js
 @BINPATH@/components/Snippets.js
 
 @BINPATH@/components/XPIDialogService.js