dom/src/notification/NotificationStorage.js

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:7c1aff5ca874
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 "use strict";
6
7 const DEBUG = false;
8 function debug(s) { dump("-*- NotificationStorage.js: " + s + "\n"); }
9
10 const Cc = Components.classes;
11 const Ci = Components.interfaces;
12 const Cu = Components.utils;
13
14 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
15
16 const NOTIFICATIONSTORAGE_CID = "{37f819b0-0b5c-11e3-8ffd-0800200c9a66}";
17 const NOTIFICATIONSTORAGE_CONTRACTID = "@mozilla.org/notificationStorage;1";
18
19 XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
20 "@mozilla.org/childprocessmessagemanager;1",
21 "nsIMessageSender");
22
23
24 function NotificationStorage() {
25 // cache objects
26 this._notifications = {};
27 this._byTag = {};
28 this._cached = false;
29
30 this._requests = {};
31 this._requestCount = 0;
32
33 // Register for message listeners.
34 cpmm.addMessageListener("Notification:GetAll:Return:OK", this);
35 }
36
37 NotificationStorage.prototype = {
38
39 put: function(origin, id, title, dir, lang, body, tag, icon) {
40 if (DEBUG) { debug("PUT: " + id + ": " + title); }
41 var notification = {
42 id: id,
43 title: title,
44 dir: dir,
45 lang: lang,
46 body: body,
47 tag: tag,
48 icon: icon,
49 origin: origin
50 };
51
52 this._notifications[id] = notification;
53 if (tag) {
54 if (!this._byTag[origin]) {
55 this._byTag[origin] = {};
56 }
57
58 // We might have existing notification with this tag,
59 // if so we need to remove it from our cache.
60 if (this._byTag[origin][tag]) {
61 var oldNotification = this._byTag[origin][tag];
62 delete this._notifications[oldNotification.id];
63 }
64
65 this._byTag[origin][tag] = notification;
66 };
67
68 cpmm.sendAsyncMessage("Notification:Save", {
69 origin: origin,
70 notification: notification
71 });
72 },
73
74 get: function(origin, tag, callback) {
75 if (DEBUG) { debug("GET: " + origin + " " + tag); }
76 if (this._cached) {
77 this._fetchFromCache(origin, tag, callback);
78 } else {
79 this._fetchFromDB(origin, tag, callback);
80 }
81 },
82
83 delete: function(origin, id) {
84 if (DEBUG) { debug("DELETE: " + id); }
85 var notification = this._notifications[id];
86 if (notification) {
87 if (notification.tag) {
88 delete this._byTag[origin][notification.tag];
89 }
90 delete this._notifications[id];
91 }
92
93 cpmm.sendAsyncMessage("Notification:Delete", {
94 origin: origin,
95 id: id
96 });
97 },
98
99 receiveMessage: function(message) {
100 switch (message.name) {
101 case "Notification:GetAll:Return:OK":
102 var request = this._requests[message.data.requestID];
103 delete this._requests[message.data.requestID];
104 this._populateCache(message.data.notifications);
105 this._fetchFromCache(request.origin, request.tag, request.callback);
106 break;
107
108 default:
109 if (DEBUG) debug("Unrecognized message: " + message.name);
110 break;
111 }
112 },
113
114 _fetchFromDB: function(origin, tag, callback) {
115 var request = {
116 origin: origin,
117 tag: tag,
118 callback: callback
119 };
120 var requestID = this._requestCount++;
121 this._requests[requestID] = request;
122 cpmm.sendAsyncMessage("Notification:GetAll", {
123 origin: origin,
124 requestID: requestID
125 });
126 },
127
128 _fetchFromCache: function(origin, tag, callback) {
129 var notifications = [];
130 // If a tag was specified and we have a notification
131 // with this tag, return that. If no tag was specified
132 // simple return all stored notifications.
133 if (tag && this._byTag[origin] && this._byTag[origin][tag]) {
134 notifications.push(this._byTag[origin][tag]);
135 } else if (!tag) {
136 for (var id in this._notifications) {
137 if (this._notifications[id].origin === origin) {
138 notifications.push(this._notifications[id]);
139 }
140 }
141 }
142
143 // Pass each notification back separately.
144 notifications.forEach(function(notification) {
145 try {
146 callback.handle(notification.id,
147 notification.title,
148 notification.dir,
149 notification.lang,
150 notification.body,
151 notification.tag,
152 notification.icon);
153 } catch (e) {
154 if (DEBUG) { debug("Error calling callback handle: " + e); }
155 }
156 });
157 try {
158 callback.done();
159 } catch (e) {
160 if (DEBUG) { debug("Error calling callback done: " + e); }
161 }
162 },
163
164 _populateCache: function(notifications) {
165 notifications.forEach(function(notification) {
166 this._notifications[notification.id] = notification;
167 if (notification.tag && notification.origin) {
168 let tag = notification.tag;
169 let origin = notification.origin;
170 if (!this._byTag[origin]) {
171 this._byTag[origin] = {};
172 }
173 this._byTag[origin][tag] = notification;
174 }
175 }.bind(this));
176 this._cached = true;
177 },
178
179 classID : Components.ID(NOTIFICATIONSTORAGE_CID),
180 contractID : NOTIFICATIONSTORAGE_CONTRACTID,
181 QueryInterface: XPCOMUtils.generateQI([Ci.nsINotificationStorage,
182 Ci.nsIMessageListener]),
183 };
184
185
186 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([NotificationStorage]);

mercurial