dom/alarm/AlarmsManager.js

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:7ae08d6d3a30
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 /* static functions */
8 const DEBUG = false;
9
10 function debug(aStr) {
11 if (DEBUG)
12 dump("AlarmsManager: " + aStr + "\n");
13 }
14
15 const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
16
17 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
18 Cu.import("resource://gre/modules/Services.jsm");
19 Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
20
21 const ALARMSMANAGER_CONTRACTID = "@mozilla.org/alarmsManager;1";
22 const ALARMSMANAGER_CID = Components.ID("{fea1e884-9b05-11e1-9b64-87a7016c3860}");
23 const nsIDOMMozAlarmsManager = Ci.nsIDOMMozAlarmsManager;
24 const nsIClassInfo = Ci.nsIClassInfo;
25
26 function AlarmsManager()
27 {
28 debug("Constructor");
29 }
30
31 AlarmsManager.prototype = {
32
33 __proto__: DOMRequestIpcHelper.prototype,
34
35 classID : ALARMSMANAGER_CID,
36
37 QueryInterface : XPCOMUtils.generateQI([nsIDOMMozAlarmsManager,
38 Ci.nsIDOMGlobalPropertyInitializer,
39 Ci.nsISupportsWeakReference,
40 Ci.nsIObserver]),
41
42 classInfo : XPCOMUtils.generateCI({ classID: ALARMSMANAGER_CID,
43 contractID: ALARMSMANAGER_CONTRACTID,
44 classDescription: "AlarmsManager",
45 interfaces: [nsIDOMMozAlarmsManager],
46 flags: nsIClassInfo.DOM_OBJECT }),
47
48 add: function add(aDate, aRespectTimezone, aData) {
49 debug("add()");
50
51 if (!this._manifestURL) {
52 debug("Cannot add alarms for non-installed apps.");
53 throw Components.results.NS_ERROR_FAILURE;
54 }
55
56 if (!aDate) {
57 throw Components.results.NS_ERROR_INVALID_ARG;
58 }
59
60 let isIgnoreTimezone = true;
61 switch (aRespectTimezone) {
62 case "honorTimezone":
63 isIgnoreTimezone = false;
64 break;
65
66 case "ignoreTimezone":
67 isIgnoreTimezone = true;
68 break;
69
70 default:
71 throw Components.results.NS_ERROR_INVALID_ARG;
72 break;
73 }
74
75 // Run JSON.stringify() in the sand box with the principal of the calling
76 // web page to ensure no cross-origin object is involved. A "Permission
77 // Denied" error will be thrown in case of privilege violation.
78 let sandbox = new Cu.Sandbox(this._window.document.nodePrincipal);
79 sandbox.data = aData;
80 let data = Cu.evalInSandbox("JSON.stringify(data)", sandbox);
81 let request = this.createRequest();
82 this._cpmm.sendAsyncMessage(
83 "AlarmsManager:Add",
84 { requestId: this.getRequestId(request),
85 date: aDate,
86 ignoreTimezone: isIgnoreTimezone,
87 data: JSON.parse(data),
88 pageURL: this._pageURL,
89 manifestURL: this._manifestURL }
90 );
91 return request;
92 },
93
94 remove: function remove(aId) {
95 debug("remove()");
96
97 this._cpmm.sendAsyncMessage(
98 "AlarmsManager:Remove",
99 { id: aId, manifestURL: this._manifestURL }
100 );
101 },
102
103 getAll: function getAll() {
104 debug("getAll()");
105
106 let request = this.createRequest();
107 this._cpmm.sendAsyncMessage(
108 "AlarmsManager:GetAll",
109 { requestId: this.getRequestId(request), manifestURL: this._manifestURL }
110 );
111 return request;
112 },
113
114 receiveMessage: function receiveMessage(aMessage) {
115 debug("receiveMessage(): " + aMessage.name);
116
117 let json = aMessage.json;
118 let request = this.getRequest(json.requestId);
119
120 if (!request) {
121 debug("No request stored! " + json.requestId);
122 return;
123 }
124
125 switch (aMessage.name) {
126 case "AlarmsManager:Add:Return:OK":
127 Services.DOMRequest.fireSuccess(request, json.id);
128 break;
129
130 case "AlarmsManager:GetAll:Return:OK":
131 // We don't need to expose everything to the web content.
132 let alarms = [];
133 json.alarms.forEach(function trimAlarmInfo(aAlarm) {
134 let alarm = { "id": aAlarm.id,
135 "date": aAlarm.date,
136 "respectTimezone": aAlarm.ignoreTimezone ?
137 "ignoreTimezone" : "honorTimezone",
138 "data": aAlarm.data };
139 alarms.push(alarm);
140 });
141 Services.DOMRequest.fireSuccess(request,
142 Cu.cloneInto(alarms, this._window));
143 break;
144
145 case "AlarmsManager:Add:Return:KO":
146 Services.DOMRequest.fireError(request, json.errorMsg);
147 break;
148
149 case "AlarmsManager:GetAll:Return:KO":
150 Services.DOMRequest.fireError(request, json.errorMsg);
151 break;
152
153 default:
154 debug("Wrong message: " + aMessage.name);
155 break;
156 }
157 this.removeRequest(json.requestId);
158 },
159
160 // nsIDOMGlobalPropertyInitializer implementation
161 init: function init(aWindow) {
162 debug("init()");
163
164 // Set navigator.mozAlarms to null.
165 if (!Services.prefs.getBoolPref("dom.mozAlarms.enabled")) {
166 return null;
167 }
168
169 // Only pages with perm set can use the alarms.
170 let principal = aWindow.document.nodePrincipal;
171 let perm =
172 Services.perms.testExactPermissionFromPrincipal(principal, "alarms");
173 if (perm != Ci.nsIPermissionManager.ALLOW_ACTION) {
174 return null;
175 }
176
177 // SystemPrincipal documents do not have any origin.
178 // Reject them for now.
179 if (!principal.URI) {
180 return null;
181 }
182
183 this._cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
184 .getService(Ci.nsISyncMessageSender);
185
186 // Add the valid messages to be listened.
187 this.initDOMRequestHelper(aWindow, ["AlarmsManager:Add:Return:OK",
188 "AlarmsManager:Add:Return:KO",
189 "AlarmsManager:GetAll:Return:OK",
190 "AlarmsManager:GetAll:Return:KO"]);
191
192 // Get the manifest URL if this is an installed app
193 let appsService = Cc["@mozilla.org/AppsService;1"]
194 .getService(Ci.nsIAppsService);
195 this._pageURL = principal.URI.spec;
196 this._manifestURL = appsService.getManifestURLByLocalId(principal.appId);
197 this._window = aWindow;
198 },
199
200 // Called from DOMRequestIpcHelper.
201 uninit: function uninit() {
202 debug("uninit()");
203 },
204 }
205
206 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([AlarmsManager])

mercurial