/* 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 Cc = Components.classes; const Ci = Components.interfaces; const Cu = Components.utils; const Cr = Components.results; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); XPCOMUtils.defineLazyGetter(this, "console", () => { let {ConsoleAPI} = Cu.import("resource://gre/modules/Console.jsm", {}); return new ConsoleAPI({ maxLogLevelPref: "dom.push.loglevel", prefix: "PushClient", }); }); const kMessages = [ "PushService:Register:OK", "PushService:Register:KO", "PushService:Registration:OK", "PushService:Registration:KO", "PushService:Unregister:OK", "PushService:Unregister:KO", ]; this.PushClient = function PushClient() { console.debug("PushClient()"); this._cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"] .getService(Ci.nsISyncMessageSender); this._requests = {}; this.addListeners(); }; PushClient.prototype = { classID: Components.ID("{16042199-bec0-484a-9640-25ecc0c0a149}"), contractID: "@mozilla.org/push/PushClient;1", QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference, Ci.nsIPushClient, Ci.nsIMessageListener,]), _getRandomId: function() { return Cc["@mozilla.org/uuid-generator;1"] .getService(Ci.nsIUUIDGenerator).generateUUID().toString(); }, addRequest: function(data) { let id = this._getRandomId(); this._requests[id] = data; return id; }, takeRequest: function(requestId) { let d = this._requests[requestId]; delete this._requests[requestId]; return d; }, addListeners: function() { for (let message of kMessages) { this._cpmm.addWeakMessageListener(message, this); } }, subscribe: function(scope, principal, callback) { console.debug("subscribe()", scope); let requestId = this.addRequest(callback); this._cpmm.sendAsyncMessage("Push:Register", { scope: scope, requestID: requestId, }, null, principal); }, unsubscribe: function(scope, principal, callback) { console.debug("unsubscribe()", scope); let requestId = this.addRequest(callback); this._cpmm.sendAsyncMessage("Push:Unregister", { scope: scope, requestID: requestId, }, null, principal); }, getSubscription: function(scope, principal, callback) { console.debug("getSubscription()", scope); let requestId = this.addRequest(callback); console.debug("getSubscription: Going to send", scope, principal, requestId); this._cpmm.sendAsyncMessage("Push:Registration", { scope: scope, requestID: requestId, }, null, principal); }, _deliverPushEndpoint: function(request, registration) { if (!registration) { request.onPushEndpoint(Cr.NS_OK, "", 0, null, 0, null); return; } let key; if (registration.p256dhKey) { key = new Uint8Array(registration.p256dhKey); } let authSecret; if (registration.authSecret) { authSecret = new Uint8Array(registration.authSecret); } request.onPushEndpoint(Cr.NS_OK, registration.pushEndpoint, key ? key.length : 0, key, authSecret ? authSecret.length : 0, authSecret); }, receiveMessage: function(aMessage) { console.debug("receiveMessage()", aMessage); let json = aMessage.data; let request = this.takeRequest(json.requestID); if (!request) { console.error("receiveMessage: Unknown request ID", json.requestID); return; } switch (aMessage.name) { case "PushService:Register:OK": case "PushService:Registration:OK": this._deliverPushEndpoint(request, json.result); break; case "PushService:Register:KO": case "PushService:Registration:KO": request.onPushEndpoint(Cr.NS_ERROR_FAILURE, "", 0, null, 0, null); break; case "PushService:Unregister:OK": if (typeof json.result !== "boolean") { console.error("receiveMessage: Expected boolean for unregister response", json.result); request.onUnsubscribe(Cr.NS_ERROR_FAILURE, false); return; } request.onUnsubscribe(Cr.NS_OK, json.result); break; case "PushService:Unregister:KO": request.onUnsubscribe(Cr.NS_ERROR_FAILURE, false); break; default: console.error("receiveMessage: NOT IMPLEMENTED!", aMessage.name); } }, }; this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PushClient]);