Bug 735947 - support the desktop notifications API in b2g [r=vingtetun]
authorFabrice Desré <fabrice@mozilla.com>
Fri, 16 Mar 2012 15:23:28 -0700
changeset 92944 e239861bd56e3d11164ab61f53d6d45e76940878
parent 92943 f2bacfc9013c5d0f8f9be5c213628bcab84de4b1
child 92945 9b7eb2c852660f7bb86dbb57a94c778b2163c791
push idunknown
push userunknown
push dateunknown
reviewersvingtetun
bugs735947
milestone14.0a1
Bug 735947 - support the desktop notifications API in b2g [r=vingtetun]
b2g/chrome/content/shell.js
b2g/components/AlertsService.js
b2g/components/B2GComponents.manifest
b2g/components/ContentPermissionPrompt.js
b2g/components/Makefile.in
b2g/installer/package-manifest.in
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -61,17 +61,17 @@ function startupHttpd(baseDir, port) {
 
 // FIXME Bug 707625
 // until we have a proper security model, add some rights to
 // the pre-installed web applications
 // XXX never grant 'content-camera' to non-gaia apps
 function addPermissions(urls) {
   let permissions = [
     'indexedDB', 'indexedDB-unlimited', 'webapps-manage', 'offline-app',
-    'content-camera', 'webcontacts-manage', 'wifi-manage'
+    'content-camera', 'webcontacts-manage', 'wifi-manage', 'desktop-notification'
   ];
   urls.forEach(function(url) {
     let uri = Services.io.newURI(url, null, null);
     let allow = Ci.nsIPermissionManager.ALLOW_ACTION;
 
     permissions.forEach(function(permission) {
       Services.perms.add(uri, permission, allow);
     });
@@ -160,16 +160,18 @@ var shell = {
     // Load webapi.js as a frame script
     let frameScriptUrl = 'chrome://browser/content/webapi.js';
     try {
       messageManager.loadFrameScript(frameScriptUrl, true);
     } catch (e) {
       dump('Error loading ' + frameScriptUrl + ' as a frame script: ' + e + '\n');
     }
 
+    CustomEventManager.init();
+
     let browser = this.contentBrowser;
     browser.homePage = homeURL;
     browser.goHome();
   },
 
   stop: function shell_stop() {
     window.removeEventListener('MozApplicationManifest', this);
     window.removeEventListener('mozfullscreenchange', this);
@@ -416,8 +418,58 @@ Services.obs.addObserver(function onCons
   let serverPort = Services.prefs.getIntPref('b2g.remote-js.port');
   let serverSocket = Cc['@mozilla.org/network/server-socket;1']
                        .createInstance(Ci.nsIServerSocket);
   serverSocket.init(serverPort, true, -1);
   dump('Opened socket on ' + serverSocket.port + '\n');
   serverSocket.asyncListen(listener);
 })();
 
+CustomEventManager = {
+  init: function custevt_init() {
+    window.addEventListener("ContentStart", (function(evt) {
+      content.addEventListener("mozContentEvent", this, false, true);
+    }).bind(this), false);
+  },
+
+  handleEvent: function custevt_handleEvent(evt) {
+    let detail = evt.detail;
+    dump("XXX FIXME : Got a mozContentEvent: " + detail.type);
+
+    switch(detail.type) {
+      case "desktop-notification-click":
+      case "desktop-notification-close":
+        AlertsHelper.handleEvent(detail);
+        break;
+    }
+  }
+}
+
+AlertsHelper = {
+  _listeners: {},
+  _count: 0,
+
+  handleEvent: function alert_handleEvent(detail) {
+    if (!detail || !detail.id)
+      return;
+
+    let listener = this._listeners[detail.id];
+    let topic = detail.type == "desktop-notification-click" ? "alertclickcallback" : "alertfinished";
+    listener.observer.observe(null, topic, listener.cookie);
+
+    // we're done with this notification
+    if (topic === "alertfinished")
+      delete this._listeners[detail.id];
+  },
+
+  registerListener: function alert_registerListener(cookie, alertListener) {
+    let id = "alert" + this._count++;
+    this._listeners[id] = { observer: alertListener, cookie: cookie };
+    return id;
+  },
+
+  showAlertNotification: function alert_showAlertNotification(imageUrl, title, text, textClickable, 
+                                                              cookie, alertListener, name) {
+    let id = this.registerListener(cookie, alertListener);
+    shell.sendEvent(content, "mozChromeEvent", { type: "desktop-notification", id: id, icon: imageUrl, 
+                                                 title: title, text: text } );
+  }
+}
new file mode 100644
--- /dev/null
+++ b/b2g/components/AlertsService.js
@@ -0,0 +1,27 @@
+/* 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/. */
+ 
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+
+// -----------------------------------------------------------------------
+// Alerts Service
+// -----------------------------------------------------------------------
+
+function AlertsService() { }
+
+AlertsService.prototype = {
+  classID: Components.ID("{5dce03b2-8faa-4b6e-9242-6ddb0411750c}"),
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIAlertsService]),
+
+  showAlertNotification: function(aImageUrl, aTitle, aText, aTextClickable, aCookie, aAlertListener, aName) {
+    let browser = Services.wm.getMostRecentWindow("navigator:browser");
+    browser.AlertsHelper.showAlertNotification(aImageUrl, aTitle, aText, aTextClickable, aCookie, aAlertListener, aName);
+  }
+};
+
+const NSGetFactory = XPCOMUtils.generateNSGetFactory([AlertsService]);
--- a/b2g/components/B2GComponents.manifest
+++ b/b2g/components/B2GComponents.manifest
@@ -1,7 +1,15 @@
 # Scrollbars
 category agent-style-sheets browser-content-stylesheet chrome://browser/content/content.css
 
 # CameraContent.js
 component {eff4231b-abce-4f7f-a40a-d646e8fde3ce} CameraContent.js
 contract @mozilla.org/b2g-camera-content;1 {eff4231b-abce-4f7f-a40a-d646e8fde3ce}
 category JavaScript-navigator-property mozCamera @mozilla.org/b2g-camera-content;1
+
+# AlertsService.js
+component {5dce03b2-8faa-4b6e-9242-6ddb0411750c} AlertsService.js
+contract @mozilla.org/alerts-service;1 {5dce03b2-8faa-4b6e-9242-6ddb0411750c}
+
+# ContentPermissionPrompt.js
+component {8c719f03-afe0-4aac-91ff-6c215895d467} ContentPermissionPrompt.js
+contract @mozilla.org/content-permission/prompt;1 {8c719f03-afe0-4aac-91ff-6c215895d467}
new file mode 100644
--- /dev/null
+++ b/b2g/components/ContentPermissionPrompt.js
@@ -0,0 +1,45 @@
+/* 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/. */
+
+const Ci = Components.interfaces;
+const Cr = Components.results;
+const Cu = Components.utils;
+const Cc = Components.classes;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+
+function ContentPermissionPrompt() {}
+
+ContentPermissionPrompt.prototype = {
+
+  handleExistingPermission: function handleExistingPermission(request) {
+    let result = Services.perms.testExactPermission(request.uri, request.type);
+    if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
+      request.allow();
+      return true;
+    }
+    if (result == Ci.nsIPermissionManager.DENY_ACTION) {
+      request.cancel();
+      return true;
+    }
+    return false;
+  },
+
+  prompt: function(request) {
+    // returns true if the request was handled
+    if (this.handleExistingPermission(request))
+       return;
+
+    // TODO : show UI to grant or deny permission
+  },
+
+  classID: Components.ID("{8c719f03-afe0-4aac-91ff-6c215895d467}"),
+
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionPrompt])
+};
+
+
+//module initialization
+const NSGetFactory = XPCOMUtils.generateNSGetFactory([ContentPermissionPrompt]);
--- a/b2g/components/Makefile.in
+++ b/b2g/components/Makefile.in
@@ -46,11 +46,13 @@ XPIDL_MODULE = B2GComponents
 
 XPIDLSRCS = \
         b2g.idl \
         $(NULL)
 
 EXTRA_PP_COMPONENTS = \
         B2GComponents.manifest \
         CameraContent.js \
+        AlertsService.js \
+        ContentPermissionPrompt.js \
         $(NULL)
 
 include $(topsrcdir)/config/rules.mk
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -610,8 +610,10 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DL
 
 [b2g]
 @BINPATH@/chrome/icons/
 @BINPATH@/chrome/chrome@JAREXT@
 @BINPATH@/chrome/chrome.manifest
 @BINPATH@/components/B2GComponents.manifest
 @BINPATH@/components/B2GComponents.xpt
 @BINPATH@/components/CameraContent.js
+@BINPATH@/components/AlertsService.js
+@BINPATH@/components/ContentPermissionPrompt.js