mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 14:52:16 +00:00
Bug 1189998, Part 1 - Consolidate Push client interfaces. r=mt,dragana
--HG-- extra : commitid : GZtcmH86Wg4 extra : rebase_source : b1f7410370991819a29c9142d6dee11261f09905
This commit is contained in:
parent
4cd6379278
commit
d1e4feb4e5
@ -647,9 +647,11 @@
|
||||
@RESPATH@/components/AppsService.manifest
|
||||
@RESPATH@/components/Push.js
|
||||
@RESPATH@/components/Push.manifest
|
||||
@RESPATH@/components/PushClient.js
|
||||
@RESPATH@/components/PushNotificationService.js
|
||||
#ifdef MOZ_SIMPLEPUSH
|
||||
@RESPATH@/components/PushComponents.js
|
||||
#else
|
||||
@RESPATH@/components/PushServiceLauncher.js
|
||||
#endif
|
||||
|
||||
@RESPATH@/components/InterAppComm.manifest
|
||||
@RESPATH@/components/InterAppCommService.js
|
||||
|
@ -547,8 +547,7 @@
|
||||
@RESPATH@/components/AlarmsManager.manifest
|
||||
@RESPATH@/components/Push.js
|
||||
@RESPATH@/components/Push.manifest
|
||||
@RESPATH@/components/PushClient.js
|
||||
@RESPATH@/components/PushNotificationService.js
|
||||
@RESPATH@/components/PushComponents.js
|
||||
|
||||
@RESPATH@/components/SlowScriptDebug.manifest
|
||||
@RESPATH@/components/SlowScriptDebug.js
|
||||
|
@ -5,9 +5,8 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'nsIPushClient.idl',
|
||||
'nsIPushNotificationService.idl',
|
||||
'nsIPushObserverNotification.idl',
|
||||
'nsIPushService.idl',
|
||||
]
|
||||
|
||||
XPIDL_MODULE = 'dom_push'
|
||||
|
@ -1,58 +0,0 @@
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIPrincipal;
|
||||
|
||||
/**
|
||||
* Satisfies contracts similar to the Push API specification.
|
||||
*
|
||||
* If status is not NS_OK, endpoint should be ignored. When subscribing to
|
||||
* a new endpoint, endpoint will be a valid URL on success, when querying for
|
||||
* the presence of an existing subscription, this will be an empty string if
|
||||
* the calling {scope+principal} does not currently have an associated
|
||||
* endpoint.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(d83e398f-9920-4451-b23a-6d5a5ad2fa26)]
|
||||
interface nsIPushEndpointCallback : nsISupports
|
||||
{
|
||||
void onPushEndpoint(in nsresult status,
|
||||
in DOMString endpoint,
|
||||
in uint32_t keyLen,
|
||||
[array, size_is(keyLen)] in octet key,
|
||||
in uint32_t authSecretLen,
|
||||
[array, size_is(authSecretLen)] in octet authSecret);
|
||||
};
|
||||
|
||||
/**
|
||||
* Satisfies contracts similar to the Push API specification.
|
||||
*
|
||||
* If status is not NS_OK, there was a problem unsubscribing and success should
|
||||
* be ignored. success is true if unsubscribing was successful and false if
|
||||
* there was no subscription.
|
||||
*/
|
||||
[scriptable, uuid(9522934d-e844-4f2f-81e8-48c3947b44de)]
|
||||
interface nsIUnsubscribeResultCallback : nsISupports
|
||||
{
|
||||
void onUnsubscribe(in nsresult status, in bool success);
|
||||
};
|
||||
|
||||
/**
|
||||
* Provides an XPIDL component to interact with the PushService from content
|
||||
* processes. Unlike PushManager, this has no relationship to the DOM and is
|
||||
* not exposed to web content. This was added to allow ServiceWorkers to use
|
||||
* it by dispatching appropriate runnables to the main thread.
|
||||
*/
|
||||
[scriptable, uuid(6622d599-439e-4ad1-af32-c941bd2b9968)]
|
||||
interface nsIPushClient : nsISupports
|
||||
{
|
||||
void subscribe(in DOMString scope, in nsIPrincipal principal, in nsIPushEndpointCallback callback);
|
||||
|
||||
void unsubscribe(in DOMString scope, in nsIPrincipal principal, in nsIUnsubscribeResultCallback callback);
|
||||
|
||||
void getSubscription(in DOMString scope, in nsIPrincipal principal, in nsIPushEndpointCallback callback);
|
||||
};
|
@ -1,77 +0,0 @@
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
/**
|
||||
* A service for components to subscribe and receive push messages from web
|
||||
* services. This functionality is exposed to content via the Push API, which
|
||||
* uses service workers to notify applications. This interface exists to allow
|
||||
* privileged code to receive messages without migrating to service workers.
|
||||
*/
|
||||
[scriptable, uuid(74586476-d73f-4867-bece-87c1dea35750)]
|
||||
interface nsIPushNotificationService : nsISupports
|
||||
{
|
||||
/**
|
||||
* Creates a push subscription for the given |scope| URL and |pageURL|.
|
||||
* Returns a promise for the new subscription record, or the existing
|
||||
* record if this |scope| already has a subscription.
|
||||
*
|
||||
* The |pushEndpoint| property of the subscription record is a URL string
|
||||
* that can be used to send push messages to subscribers. For details,
|
||||
* please see the Simple Push protocol docs.
|
||||
*
|
||||
* Each incoming message fires a `push-notification` observer
|
||||
* notification, with an `nsIPushObserverNotification` as the subject and
|
||||
* the |scope| as the data.
|
||||
*
|
||||
* If the server drops a subscription, a `push-subscription-change` observer
|
||||
* will be fired, with the subject set to `null` and the data set to |scope|.
|
||||
* Servers may drop subscriptions at any time, so callers should recreate
|
||||
* subscriptions if desired.
|
||||
*/
|
||||
jsval register(in string scope, in jsval originAttributes);
|
||||
|
||||
/**
|
||||
* Revokes a push subscription for the given |scope|. Returns a promise
|
||||
* for the revoked subscription record, or `null` if the |scope| is not
|
||||
* subscribed to receive notifications.
|
||||
*/
|
||||
jsval unregister(in string scope, in jsval originAttributes);
|
||||
|
||||
/**
|
||||
* Returns a promise for the subscription record associated with the
|
||||
* given |scope|, or `null` if the |scope| does not have a subscription.
|
||||
*/
|
||||
jsval registration(in string scope, in jsval originAttributes);
|
||||
|
||||
/**
|
||||
* Clear all subscriptions.
|
||||
*/
|
||||
jsval clearAll();
|
||||
|
||||
/**
|
||||
* Clear subscriptions for a domain.
|
||||
*/
|
||||
jsval clearForDomain(in string domain);
|
||||
};
|
||||
|
||||
[scriptable, uuid(a2555e70-46f8-4b52-bf02-d978b979d143)]
|
||||
interface nsIPushQuotaManager : nsISupports
|
||||
{
|
||||
/**
|
||||
* Informs the quota manager that a notification
|
||||
* for the given origin has been shown. Used to
|
||||
* determine if push quota should be relaxed.
|
||||
*/
|
||||
void notificationForOriginShown(in string origin);
|
||||
|
||||
/**
|
||||
* Informs the quota manager that a notification
|
||||
* for the given origin has been closed. Used to
|
||||
* determine if push quota should be relaxed.
|
||||
*/
|
||||
void notificationForOriginClosed(in string origin);
|
||||
};
|
@ -6,8 +6,8 @@
|
||||
#include "nsISupports.idl"
|
||||
|
||||
/**
|
||||
* A push message received by an `nsIPushNotificationService`, used as the
|
||||
* subject of a `push-notification` observer notification.
|
||||
* A push message received by an `nsIPushService`, used as the subject of a
|
||||
* `push-notification` observer notification.
|
||||
*/
|
||||
[scriptable, uuid(56f57607-28b6-44b0-aa56-3d4d3c88be15)]
|
||||
interface nsIPushObserverNotification : nsISupports
|
||||
|
117
dom/interfaces/push/nsIPushService.idl
Normal file
117
dom/interfaces/push/nsIPushService.idl
Normal file
@ -0,0 +1,117 @@
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIPrincipal;
|
||||
|
||||
/**
|
||||
* A push subscription, passed as an argument to a subscription callback.
|
||||
* Similar to the `PushSubscription` WebIDL interface.
|
||||
*/
|
||||
[scriptable, uuid(1de32d5c-ea88-4c9e-9626-b032bd87f415)]
|
||||
interface nsIPushSubscription : nsISupports
|
||||
{
|
||||
readonly attribute DOMString endpoint;
|
||||
readonly attribute long long pushCount;
|
||||
readonly attribute long long lastPush;
|
||||
readonly attribute long quota;
|
||||
|
||||
bool quotaApplies();
|
||||
bool isExpired();
|
||||
|
||||
void getKey(in DOMString name,
|
||||
[optional] out uint32_t keyLen,
|
||||
[array, size_is(keyLen), retval] out uint8_t key);
|
||||
};
|
||||
|
||||
/**
|
||||
* Called by methods that return a push subscription. A non-success
|
||||
* |status| indicates that there was a problem returning the
|
||||
* subscription, and the |subscription| argument should be ignored. Otherwise,
|
||||
* |subscription| will point to a valid push subscription, or |null| if the
|
||||
* subscription does not exist.
|
||||
*/
|
||||
[scriptable, uuid(1799c074-9d52-46b0-ab3c-c09790732f6f), function]
|
||||
interface nsIPushSubscriptionCallback : nsISupports
|
||||
{
|
||||
void onPushSubscription(in nsresult status,
|
||||
in nsIPushSubscription subscription);
|
||||
};
|
||||
|
||||
/**
|
||||
* Called by the |unsubscribe| method. A non-success |status| indicates that
|
||||
* there was a problem unsubscribing, and the |success| argument should be
|
||||
* ignored. Otherwise, |success| is true if unsubscribing was successful, and
|
||||
* false if the subscription does not exist.
|
||||
*/
|
||||
[scriptable, uuid(d574118f-61a9-4270-b1f6-4461aa85c4f5), function]
|
||||
interface nsIUnsubscribeResultCallback : nsISupports
|
||||
{
|
||||
void onUnsubscribe(in nsresult status, in bool success);
|
||||
};
|
||||
|
||||
/**
|
||||
* A service for components to subscribe and receive push messages from web
|
||||
* services. This functionality is exposed to content via the Push DOM API,
|
||||
* which uses service workers. This interface exists to support the DOM API,
|
||||
* and allows privileged code to receive messages without migrating to service
|
||||
* workers.
|
||||
*/
|
||||
[scriptable, uuid(cf46905d-fb55-4f21-8927-31f821c371b6)]
|
||||
interface nsIPushService : nsISupports
|
||||
{
|
||||
/**
|
||||
* Creates a push subscription for the given |scope| URL and |principal|.
|
||||
* If a subscription already exists for this |(scope, principal)| pair,
|
||||
* the callback will receive the existing record as the second argument.
|
||||
*
|
||||
* The |endpoint| property of the subscription record is a URL string
|
||||
* that can be used to send push messages to subscribers.
|
||||
*
|
||||
* Each incoming message fires a `push-notification` observer
|
||||
* notification, with an `nsIPushObserverNotification` as the subject and
|
||||
* the |scope| as the data.
|
||||
*
|
||||
* If the server drops a subscription, a `push-subscription-change` observer
|
||||
* will be fired, with the subject set to `null` and the data set to |scope|.
|
||||
* Servers may drop subscriptions at any time, so callers should recreate
|
||||
* subscriptions if desired.
|
||||
*/
|
||||
void subscribe(in DOMString scope, in nsIPrincipal principal,
|
||||
in nsIPushSubscriptionCallback callback);
|
||||
|
||||
/**
|
||||
* Removes a push subscription for the given |scope|.
|
||||
*/
|
||||
void unsubscribe(in DOMString scope, in nsIPrincipal principal,
|
||||
in nsIUnsubscribeResultCallback callback);
|
||||
|
||||
/**
|
||||
* Retrieves the subscription record associated with the given
|
||||
* |(scope, principal)| pair. If the subscription does not exist, the
|
||||
* callback will receive |null| as the second argument.
|
||||
*/
|
||||
void getSubscription(in DOMString scope, in nsIPrincipal principal,
|
||||
in nsIPushSubscriptionCallback callback);
|
||||
};
|
||||
|
||||
[scriptable, uuid(a2555e70-46f8-4b52-bf02-d978b979d143)]
|
||||
interface nsIPushQuotaManager : nsISupports
|
||||
{
|
||||
/**
|
||||
* Informs the quota manager that a notification
|
||||
* for the given origin has been shown. Used to
|
||||
* determine if push quota should be relaxed.
|
||||
*/
|
||||
void notificationForOriginShown(in string origin);
|
||||
|
||||
/**
|
||||
* Informs the quota manager that a notification
|
||||
* for the given origin has been closed. Used to
|
||||
* determine if push quota should be relaxed.
|
||||
*/
|
||||
void notificationForOriginClosed(in string origin);
|
||||
};
|
@ -52,7 +52,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef MOZ_SIMPLEPUSH
|
||||
#include "nsIPushNotificationService.h"
|
||||
#include "nsIPushService.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
@ -1203,7 +1203,7 @@ NotificationObserver::AdjustPushQuota(const char* aTopic)
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#else
|
||||
nsCOMPtr<nsIPushQuotaManager> pushQuotaManager =
|
||||
do_GetService("@mozilla.org/push/NotificationService;1");
|
||||
do_GetService("@mozilla.org/push/Service;1");
|
||||
if (!pushQuotaManager) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -21,6 +21,9 @@ XPCOMUtils.defineLazyGetter(this, "console", () => {
|
||||
});
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "PushService",
|
||||
"@mozilla.org/push/Service;1", "nsIPushService");
|
||||
|
||||
const PUSH_CID = Components.ID("{cde1d019-fad8-4044-b141-65fb4fb7a245}");
|
||||
|
||||
/**
|
||||
@ -51,8 +54,6 @@ Push.prototype = {
|
||||
this.initDOMRequestHelper(aWindow);
|
||||
|
||||
this._principal = aWindow.document.nodePrincipal;
|
||||
|
||||
this._client = Cc["@mozilla.org/push/PushClient;1"].createInstance(Ci.nsIPushClient);
|
||||
},
|
||||
|
||||
setScope: function(scope){
|
||||
@ -96,8 +97,8 @@ Push.prototype = {
|
||||
histogram.add(true);
|
||||
return this.askPermission().then(() =>
|
||||
this.createPromise((resolve, reject) => {
|
||||
let callback = new PushEndpointCallback(this, resolve, reject);
|
||||
this._client.subscribe(this._scope, this._principal, callback);
|
||||
let callback = new PushSubscriptionCallback(this, resolve, reject);
|
||||
PushService.subscribe(this._scope, this._principal, callback);
|
||||
})
|
||||
);
|
||||
},
|
||||
@ -106,8 +107,8 @@ Push.prototype = {
|
||||
console.debug("getSubscription()", this._scope);
|
||||
|
||||
return this.createPromise((resolve, reject) => {
|
||||
let callback = new PushEndpointCallback(this, resolve, reject);
|
||||
this._client.getSubscription(this._scope, this._principal, callback);
|
||||
let callback = new PushSubscriptionCallback(this, resolve, reject);
|
||||
PushService.getSubscription(this._scope, this._principal, callback);
|
||||
});
|
||||
},
|
||||
|
||||
@ -178,16 +179,16 @@ Push.prototype = {
|
||||
},
|
||||
};
|
||||
|
||||
function PushEndpointCallback(pushManager, resolve, reject) {
|
||||
function PushSubscriptionCallback(pushManager, resolve, reject) {
|
||||
this.pushManager = pushManager;
|
||||
this.resolve = resolve;
|
||||
this.reject = reject;
|
||||
}
|
||||
|
||||
PushEndpointCallback.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPushEndpointCallback]),
|
||||
onPushEndpoint: function(ok, endpoint, keyLen, key,
|
||||
authSecretLen, authSecretIn) {
|
||||
PushSubscriptionCallback.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPushSubscriptionCallback]),
|
||||
|
||||
onPushSubscription: function(ok, subscription) {
|
||||
let {pushManager} = this;
|
||||
if (!Components.isSuccessCode(ok)) {
|
||||
this.reject(new pushManager._window.DOMException(
|
||||
@ -197,32 +198,32 @@ PushEndpointCallback.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!endpoint) {
|
||||
if (!subscription) {
|
||||
this.resolve(null);
|
||||
return;
|
||||
}
|
||||
|
||||
let publicKey = null;
|
||||
if (keyLen) {
|
||||
publicKey = new ArrayBuffer(keyLen);
|
||||
let keyView = new Uint8Array(publicKey);
|
||||
keyView.set(key);
|
||||
}
|
||||
|
||||
let authSecret = null;
|
||||
if (authSecretLen) {
|
||||
authSecret = new ArrayBuffer(authSecretLen);
|
||||
let secretView = new Uint8Array(authSecret);
|
||||
secretView.set(authSecretIn);
|
||||
}
|
||||
|
||||
let sub = new pushManager._window.PushSubscription(endpoint,
|
||||
let publicKey = this._getKey(subscription, "p256dh");
|
||||
let authSecret = this._getKey(subscription, "auth");
|
||||
let sub = new pushManager._window.PushSubscription(subscription.endpoint,
|
||||
pushManager._scope,
|
||||
publicKey,
|
||||
authSecret);
|
||||
sub.setPrincipal(pushManager._principal);
|
||||
this.resolve(sub);
|
||||
},
|
||||
|
||||
_getKey: function(subscription, name) {
|
||||
let outKeyLen = {};
|
||||
let rawKey = subscription.getKey(name, outKeyLen);
|
||||
if (!outKeyLen.value) {
|
||||
return null;
|
||||
}
|
||||
let key = new ArrayBuffer(outKeyLen.value);
|
||||
let keyView = new Uint8Array(key);
|
||||
keyView.set(rawKey);
|
||||
return key;
|
||||
},
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([Push]);
|
||||
|
@ -2,13 +2,10 @@
|
||||
component {cde1d019-fad8-4044-b141-65fb4fb7a245} Push.js
|
||||
contract @mozilla.org/push/PushManager;1 {cde1d019-fad8-4044-b141-65fb4fb7a245}
|
||||
|
||||
# XPCOM component; initializes the PushService on startup.
|
||||
component {32028e38-903b-4a64-a180-5857eb4cb3dd} PushNotificationService.js
|
||||
contract @mozilla.org/push/NotificationService;1 {32028e38-903b-4a64-a180-5857eb4cb3dd}
|
||||
category app-startup PushNotificationService @mozilla.org/push/NotificationService;1
|
||||
# XPCOM components.
|
||||
component {daaa8d73-677e-4233-8acd-2c404bd01658} PushComponents.js
|
||||
contract @mozilla.org/push/Service;1 {daaa8d73-677e-4233-8acd-2c404bd01658}
|
||||
category app-startup PushServiceParent @mozilla.org/push/Service;1
|
||||
|
||||
component {66a87970-6dc9-46e0-ac61-adb4a13791de} PushNotificationService.js
|
||||
contract @mozilla.org/push/ObserverNotification;1 {66a87970-6dc9-46e0-ac61-adb4a13791de}
|
||||
|
||||
component {16042199-bec0-484a-9640-25ecc0c0a149} PushClient.js
|
||||
contract @mozilla.org/push/PushClient;1 {16042199-bec0-484a-9640-25ecc0c0a149}
|
||||
component {e68997fd-8b92-49ee-af12-800830b023e8} PushComponents.js
|
||||
contract @mozilla.org/push/ObserverNotification;1 {e68997fd-8b92-49ee-af12-800830b023e8}
|
||||
|
@ -1,167 +0,0 @@
|
||||
/* 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]);
|
449
dom/push/PushComponents.js
Normal file
449
dom/push/PushComponents.js
Normal file
@ -0,0 +1,449 @@
|
||||
/* 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";
|
||||
|
||||
/**
|
||||
* This file exports XPCOM components for C++ and chrome JavaScript callers to
|
||||
* interact with the Push service.
|
||||
*/
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
var isParent = Services.appinfo.processType === Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
|
||||
|
||||
/**
|
||||
* `PushServiceBase`, `PushServiceParent`, and `PushServiceContent` collectively
|
||||
* implement the `nsIPushService` interface. This interface provides calls
|
||||
* similar to the Push DOM API, but does not require service workers.
|
||||
*
|
||||
* Push service methods may be called from the parent or content process. The
|
||||
* parent process implementation loads `PushService.jsm` at app startup, and
|
||||
* calls its methods directly. The content implementation forwards calls to
|
||||
* the parent Push service via IPC.
|
||||
*
|
||||
* The implementations share a class and contract ID.
|
||||
*/
|
||||
function PushServiceBase() {
|
||||
this.wrappedJSObject = this;
|
||||
this._addListeners();
|
||||
}
|
||||
|
||||
PushServiceBase.prototype = {
|
||||
classID: Components.ID("{daaa8d73-677e-4233-8acd-2c404bd01658}"),
|
||||
contractID: "@mozilla.org/push/Service;1",
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsIObserver,
|
||||
Ci.nsISupportsWeakReference,
|
||||
Ci.nsIPushService,
|
||||
Ci.nsIPushQuotaManager,
|
||||
]),
|
||||
|
||||
_handleReady() {},
|
||||
|
||||
_addListeners() {
|
||||
for (let message of this._messages) {
|
||||
this._mm.addMessageListener(message, this);
|
||||
}
|
||||
},
|
||||
|
||||
_isValidMessage(message) {
|
||||
return this._messages.includes(message.name);
|
||||
},
|
||||
|
||||
observe(subject, topic, data) {
|
||||
if (topic === "app-startup") {
|
||||
Services.obs.addObserver(this, "sessionstore-windows-restored", true);
|
||||
return;
|
||||
}
|
||||
if (topic === "sessionstore-windows-restored") {
|
||||
Services.obs.removeObserver(this, "sessionstore-windows-restored");
|
||||
this._handleReady();
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
||||
_deliverSubscription(request, props) {
|
||||
if (!props) {
|
||||
request.onPushSubscription(Cr.NS_OK, null);
|
||||
return;
|
||||
}
|
||||
request.onPushSubscription(Cr.NS_OK, new PushSubscription(props));
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* The parent process implementation of `nsIPushService`. This version loads
|
||||
* `PushService.jsm` at startup and calls its methods directly. It also
|
||||
* receives and responds to requests from the content process.
|
||||
*/
|
||||
function PushServiceParent() {
|
||||
PushServiceBase.call(this);
|
||||
}
|
||||
|
||||
PushServiceParent.prototype = Object.create(PushServiceBase.prototype);
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(PushServiceParent.prototype, "_mm",
|
||||
"@mozilla.org/parentprocessmessagemanager;1", "nsIMessageBroadcaster");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(PushServiceParent.prototype, "_service",
|
||||
function() {
|
||||
const {PushService} = Cu.import("resource://gre/modules/PushService.jsm",
|
||||
{});
|
||||
PushService.init();
|
||||
return PushService;
|
||||
});
|
||||
|
||||
Object.assign(PushServiceParent.prototype, {
|
||||
_xpcom_factory: XPCOMUtils.generateSingletonFactory(PushServiceParent),
|
||||
|
||||
_messages: [
|
||||
"Push:Register",
|
||||
"Push:Registration",
|
||||
"Push:Unregister",
|
||||
"Push:RegisterEventNotificationListener",
|
||||
"Push:NotificationForOriginShown",
|
||||
"Push:NotificationForOriginClosed",
|
||||
"child-process-shutdown",
|
||||
],
|
||||
|
||||
// nsIPushService methods
|
||||
|
||||
subscribe(scope, principal, callback) {
|
||||
return this._handleRequest("Push:Register", principal, {
|
||||
scope: scope,
|
||||
}).then(result => {
|
||||
this._deliverSubscription(callback, result);
|
||||
}, error => {
|
||||
callback.onPushSubscription(Cr.NS_ERROR_FAILURE, null);
|
||||
}).catch(Cu.reportError);
|
||||
},
|
||||
|
||||
unsubscribe(scope, principal, callback) {
|
||||
this._handleRequest("Push:Unregister", principal, {
|
||||
scope: scope,
|
||||
}).then(result => {
|
||||
callback.onUnsubscribe(Cr.NS_OK, result);
|
||||
}, error => {
|
||||
callback.onUnsubscribe(Cr.NS_ERROR_FAILURE, false);
|
||||
}).catch(Cu.reportError);
|
||||
},
|
||||
|
||||
getSubscription(scope, principal, callback) {
|
||||
return this._handleRequest("Push:Registration", principal, {
|
||||
scope: scope,
|
||||
}).then(result => {
|
||||
this._deliverSubscription(callback, result);
|
||||
}, error => {
|
||||
callback.onPushSubscription(Cr.NS_ERROR_FAILURE, null);
|
||||
}).catch(Cu.reportError);
|
||||
},
|
||||
|
||||
// nsIPushQuotaManager methods
|
||||
|
||||
notificationForOriginShown(origin) {
|
||||
this._service.notificationForOriginShown(origin);
|
||||
},
|
||||
|
||||
notificationForOriginClosed(origin) {
|
||||
this._service.notificationForOriginClosed(origin);
|
||||
},
|
||||
|
||||
receiveMessage(message) {
|
||||
if (!this._isValidMessage(message)) {
|
||||
return;
|
||||
}
|
||||
let {name, principal, target, data} = message;
|
||||
if (name === "Push:RegisterEventNotificationListener") {
|
||||
this._service.registerListener(target);
|
||||
return;
|
||||
}
|
||||
if (name === "child-process-shutdown") {
|
||||
this._service.unregisterListener(target);
|
||||
return;
|
||||
}
|
||||
if (name === "Push:NotificationForOriginShown") {
|
||||
this.notificationForOriginShown(data);
|
||||
return;
|
||||
}
|
||||
if (name === "Push:NotificationForOriginClosed") {
|
||||
this.notificationForOriginClosed(data);
|
||||
return;
|
||||
}
|
||||
if (!target.assertPermission("push")) {
|
||||
return;
|
||||
}
|
||||
let sender = target.QueryInterface(Ci.nsIMessageSender);
|
||||
return this._handleRequest(name, principal, data).then(result => {
|
||||
sender.sendAsyncMessage(this._getResponseName(name, "OK"), {
|
||||
requestID: data.requestID,
|
||||
result: result
|
||||
});
|
||||
}, error => {
|
||||
sender.sendAsyncMessage(this._getResponseName(name, "KO"), {
|
||||
requestID: data.requestID,
|
||||
});
|
||||
}).catch(Cu.reportError);
|
||||
},
|
||||
|
||||
_handleReady() {
|
||||
this._service.init();
|
||||
},
|
||||
|
||||
_toPageRecord(principal, data) {
|
||||
if (!data.scope) {
|
||||
throw new Error("Invalid page record: missing scope");
|
||||
}
|
||||
|
||||
data.originAttributes =
|
||||
ChromeUtils.originAttributesToSuffix(principal.originAttributes);
|
||||
|
||||
return data;
|
||||
},
|
||||
|
||||
_handleRequest(name, principal, data) {
|
||||
if (!principal) {
|
||||
return Promise.reject(new Error("Invalid request: missing principal"));
|
||||
}
|
||||
|
||||
let pageRecord;
|
||||
try {
|
||||
pageRecord = this._toPageRecord(principal, data);
|
||||
} catch (e) {
|
||||
return Promise.reject(e);
|
||||
}
|
||||
|
||||
if (name === "Push:Register") {
|
||||
return this._service.register(pageRecord);
|
||||
}
|
||||
if (name === "Push:Registration") {
|
||||
return this._service.registration(pageRecord);
|
||||
}
|
||||
if (name === "Push:Unregister") {
|
||||
return this._service.unregister(pageRecord);
|
||||
}
|
||||
|
||||
return Promise.reject(new Error("Invalid request: unknown name"));
|
||||
},
|
||||
|
||||
_getResponseName(requestName, suffix) {
|
||||
let name = requestName.slice("Push:".length);
|
||||
return "PushService:" + name + ":" + suffix;
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* The content process implementation of `nsIPushService`. This version
|
||||
* uses the child message manager to forward calls to the parent process.
|
||||
* The parent Push service instance handles the request, and responds with a
|
||||
* message containing the result.
|
||||
*/
|
||||
function PushServiceContent() {
|
||||
PushServiceBase.apply(this, arguments);
|
||||
this._requests = new Map();
|
||||
this._requestId = 0;
|
||||
}
|
||||
|
||||
PushServiceContent.prototype = Object.create(PushServiceBase.prototype);
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(PushServiceContent.prototype,
|
||||
"_mm", "@mozilla.org/childprocessmessagemanager;1",
|
||||
"nsISyncMessageSender");
|
||||
|
||||
Object.assign(PushServiceContent.prototype, {
|
||||
_xpcom_factory: XPCOMUtils.generateSingletonFactory(PushServiceContent),
|
||||
|
||||
_messages: [
|
||||
"PushService:Register:OK",
|
||||
"PushService:Register:KO",
|
||||
"PushService:Registration:OK",
|
||||
"PushService:Registration:KO",
|
||||
"PushService:Unregister:OK",
|
||||
"PushService:Unregister:KO",
|
||||
],
|
||||
|
||||
// nsIPushService methods
|
||||
|
||||
subscribe(scope, principal, callback) {
|
||||
let requestId = this._addRequest(callback);
|
||||
this._mm.sendAsyncMessage("Push:Register", {
|
||||
scope: scope,
|
||||
requestID: requestId,
|
||||
}, null, principal);
|
||||
},
|
||||
|
||||
unsubscribe(scope, principal, callback) {
|
||||
let requestId = this._addRequest(callback);
|
||||
this._mm.sendAsyncMessage("Push:Unregister", {
|
||||
scope: scope,
|
||||
requestID: requestId,
|
||||
}, null, principal);
|
||||
},
|
||||
|
||||
getSubscription(scope, principal, callback) {
|
||||
let requestId = this._addRequest(callback);
|
||||
this._mm.sendAsyncMessage("Push:Registration", {
|
||||
scope: scope,
|
||||
requestID: requestId,
|
||||
}, null, principal);
|
||||
},
|
||||
|
||||
// nsIPushQuotaManager methods
|
||||
|
||||
notificationForOriginShown(origin) {
|
||||
this._mm.sendAsyncMessage("Push:NotificationForOriginShown", origin);
|
||||
},
|
||||
|
||||
notificationForOriginClosed(origin) {
|
||||
this._mm.sendAsyncMessage("Push:NotificationForOriginClosed", origin);
|
||||
},
|
||||
|
||||
_addRequest(data) {
|
||||
let id = ++this._requestId;
|
||||
this._requests.set(id, data);
|
||||
return id;
|
||||
},
|
||||
|
||||
_takeRequest(requestId) {
|
||||
let d = this._requests.get(requestId);
|
||||
this._requests.delete(requestId);
|
||||
return d;
|
||||
},
|
||||
|
||||
receiveMessage(message) {
|
||||
if (!this._isValidMessage(message)) {
|
||||
return;
|
||||
}
|
||||
let {name, data} = message;
|
||||
let request = this._takeRequest(data.requestID);
|
||||
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (name) {
|
||||
case "PushService:Register:OK":
|
||||
case "PushService:Registration:OK":
|
||||
this._deliverSubscription(request, data.result);
|
||||
break;
|
||||
|
||||
case "PushService:Register:KO":
|
||||
case "PushService:Registration:KO":
|
||||
request.onPushSubscription(Cr.NS_ERROR_FAILURE, null);
|
||||
break;
|
||||
|
||||
case "PushService:Unregister:OK":
|
||||
if (typeof data.result === "boolean") {
|
||||
request.onUnsubscribe(Cr.NS_OK, data.result);
|
||||
} else {
|
||||
request.onUnsubscribe(Cr.NS_ERROR_FAILURE, false);
|
||||
}
|
||||
break;
|
||||
|
||||
case "PushService:Unregister:KO":
|
||||
request.onUnsubscribe(Cr.NS_ERROR_FAILURE, false);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
/** `PushSubscription` instances are passed to all subscription callbacks. */
|
||||
function PushSubscription(props) {
|
||||
this._props = props;
|
||||
}
|
||||
|
||||
PushSubscription.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPushSubscription]),
|
||||
|
||||
/** The URL for sending messages to this subscription. */
|
||||
get endpoint() {
|
||||
return this._props.endpoint;
|
||||
},
|
||||
|
||||
/** The last time a message was sent to this subscription. */
|
||||
get lastPush() {
|
||||
return this._props.lastPush;
|
||||
},
|
||||
|
||||
/** The total number of messages sent to this subscription. */
|
||||
get pushCount() {
|
||||
return this._props.pushCount;
|
||||
},
|
||||
|
||||
/** The number of remaining background messages that can be sent to this
|
||||
* subscription, or -1 of the subscription is exempt from the quota.
|
||||
*/
|
||||
get quota() {
|
||||
return this._props.quota;
|
||||
},
|
||||
|
||||
/**
|
||||
* Indicates whether this subscription is subject to the background message
|
||||
* quota.
|
||||
*/
|
||||
quotaApplies() {
|
||||
return this.quota >= 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Indicates whether this subscription exceeded the background message quota,
|
||||
* or the user revoked the notification permission. The caller must request a
|
||||
* new subscription to continue receiving push messages.
|
||||
*/
|
||||
isExpired() {
|
||||
return this.quota === 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a key for encrypting messages sent to this subscription. JS
|
||||
* callers receive the key buffer as a return value, while C++ callers
|
||||
* receive the key size and buffer as out parameters.
|
||||
*/
|
||||
getKey(name, outKeyLen) {
|
||||
if (name === "p256dh") {
|
||||
return this._getRawKey(this._props.p256dhKey, outKeyLen);
|
||||
}
|
||||
if (name === "auth") {
|
||||
return this._getRawKey(this._props.authenticationSecret, outKeyLen);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
_getRawKey(key, outKeyLen) {
|
||||
if (!key) {
|
||||
return null;
|
||||
}
|
||||
let rawKey = new Uint8Array(key);
|
||||
if (outKeyLen) {
|
||||
outKeyLen.value = rawKey.length;
|
||||
}
|
||||
return rawKey;
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* `PushObserverNotification` instances are passed to all
|
||||
* `push-notification` observers.
|
||||
*/
|
||||
function PushObserverNotification() {}
|
||||
|
||||
PushObserverNotification.prototype = {
|
||||
classID: Components.ID("{e68997fd-8b92-49ee-af12-800830b023e8}"),
|
||||
contractID: "@mozilla.org/push/ObserverNotification;1",
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPushObserverNotification]),
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([
|
||||
PushObserverNotification,
|
||||
|
||||
// Export the correct implementation depending on whether we're running in
|
||||
// the parent or content process.
|
||||
isParent ? PushServiceParent : PushServiceContent,
|
||||
]);
|
@ -19,7 +19,7 @@
|
||||
#include "nsIGlobalObject.h"
|
||||
#include "nsIPermissionManager.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIPushClient.h"
|
||||
#include "nsIPushService.h"
|
||||
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsFrameMessageManager.h"
|
||||
@ -104,9 +104,9 @@ PushSubscription::Unsubscribe(ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(mPrincipal);
|
||||
|
||||
nsCOMPtr<nsIPushClient> client =
|
||||
do_CreateInstance("@mozilla.org/push/PushClient;1");
|
||||
if (NS_WARN_IF(!client)) {
|
||||
nsCOMPtr<nsIPushService> service =
|
||||
do_GetService("@mozilla.org/push/Service;1");
|
||||
if (NS_WARN_IF(!service)) {
|
||||
aRv = NS_ERROR_FAILURE;
|
||||
return nullptr;
|
||||
}
|
||||
@ -118,7 +118,8 @@ PushSubscription::Unsubscribe(ErrorResult& aRv)
|
||||
|
||||
RefPtr<UnsubscribeResultCallback> callback =
|
||||
new UnsubscribeResultCallback(p);
|
||||
client->Unsubscribe(mScope, mPrincipal, callback);
|
||||
Unused << NS_WARN_IF(NS_FAILED(
|
||||
service->Unsubscribe(mScope, mPrincipal, callback)));
|
||||
return p.forget();
|
||||
}
|
||||
|
||||
@ -457,15 +458,15 @@ public:
|
||||
RefPtr<WorkerUnsubscribeResultCallback> callback =
|
||||
new WorkerUnsubscribeResultCallback(mProxy);
|
||||
|
||||
nsCOMPtr<nsIPushClient> client =
|
||||
do_CreateInstance("@mozilla.org/push/PushClient;1");
|
||||
if (!client) {
|
||||
nsCOMPtr<nsIPushService> service =
|
||||
do_GetService("@mozilla.org/push/Service;1");
|
||||
if (!service) {
|
||||
callback->OnUnsubscribe(NS_ERROR_FAILURE, false);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal = mProxy->GetWorkerPrivate()->GetPrincipal();
|
||||
if (NS_WARN_IF(NS_FAILED(client->Unsubscribe(mScope, principal, callback)))) {
|
||||
if (NS_WARN_IF(NS_FAILED(service->Unsubscribe(mScope, principal, callback)))) {
|
||||
callback->OnUnsubscribe(NS_ERROR_FAILURE, false);
|
||||
return NS_OK;
|
||||
}
|
||||
@ -578,7 +579,7 @@ private:
|
||||
nsTArray<uint8_t> mAuthSecret;
|
||||
};
|
||||
|
||||
class GetSubscriptionCallback final : public nsIPushEndpointCallback
|
||||
class GetSubscriptionCallback final : public nsIPushSubscriptionCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
@ -590,15 +591,11 @@ public:
|
||||
{}
|
||||
|
||||
NS_IMETHOD
|
||||
OnPushEndpoint(nsresult aStatus,
|
||||
const nsAString& aEndpoint,
|
||||
uint32_t aKeyLen,
|
||||
uint8_t* aKey,
|
||||
uint32_t aAuthSecretLen,
|
||||
uint8_t* aAuthSecret) override
|
||||
OnPushSubscription(nsresult aStatus,
|
||||
nsIPushSubscription* aSubscription) override
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(mProxy, "OnPushEndpoint() called twice?");
|
||||
MOZ_ASSERT(mProxy, "OnPushSubscription() called twice?");
|
||||
|
||||
RefPtr<PromiseWorkerProxy> proxy = mProxy.forget();
|
||||
|
||||
@ -610,17 +607,17 @@ public:
|
||||
AutoJSAPI jsapi;
|
||||
jsapi.Init();
|
||||
|
||||
nsTArray<uint8_t> rawP256dhKey(aKeyLen);
|
||||
rawP256dhKey.ReplaceElementsAt(0, aKeyLen, aKey, aKeyLen);
|
||||
|
||||
nsTArray<uint8_t> authSecret(aAuthSecretLen);
|
||||
authSecret.ReplaceElementsAt(0, aAuthSecretLen,
|
||||
aAuthSecret, aAuthSecretLen);
|
||||
nsAutoString endpoint;
|
||||
nsTArray<uint8_t> rawP256dhKey, authSecret;
|
||||
if (NS_SUCCEEDED(aStatus)) {
|
||||
aStatus = GetSubscriptionParams(aSubscription, endpoint, rawP256dhKey,
|
||||
authSecret);
|
||||
}
|
||||
|
||||
RefPtr<GetSubscriptionResultRunnable> r =
|
||||
new GetSubscriptionResultRunnable(proxy,
|
||||
aStatus,
|
||||
aEndpoint,
|
||||
endpoint,
|
||||
mScope,
|
||||
rawP256dhKey,
|
||||
authSecret);
|
||||
@ -630,23 +627,73 @@ public:
|
||||
|
||||
// Convenience method for use in this file.
|
||||
void
|
||||
OnPushEndpointError(nsresult aStatus)
|
||||
OnPushSubscriptionError(nsresult aStatus)
|
||||
{
|
||||
Unused << NS_WARN_IF(NS_FAILED(
|
||||
OnPushEndpoint(aStatus, EmptyString(), 0, nullptr, 0, nullptr)));
|
||||
OnPushSubscription(aStatus, nullptr)));
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
~GetSubscriptionCallback()
|
||||
{}
|
||||
|
||||
private:
|
||||
inline nsresult
|
||||
FreeKeys(nsresult aStatus, uint8_t* aKey, uint8_t* aAuthSecret)
|
||||
{
|
||||
NS_Free(aKey);
|
||||
NS_Free(aAuthSecret);
|
||||
return aStatus;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GetSubscriptionParams(nsIPushSubscription* aSubscription,
|
||||
nsAString& aEndpoint,
|
||||
nsTArray<uint8_t>& aRawP256dhKey,
|
||||
nsTArray<uint8_t>& aAuthSecret)
|
||||
{
|
||||
if (!aSubscription) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = aSubscription->GetEndpoint(aEndpoint);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint8_t* key = nullptr;
|
||||
uint8_t* authSecret = nullptr;
|
||||
|
||||
uint32_t keyLen;
|
||||
rv = aSubscription->GetKey(NS_LITERAL_STRING("p256dh"), &keyLen, &key);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return FreeKeys(rv, key, authSecret);
|
||||
}
|
||||
|
||||
uint32_t authSecretLen;
|
||||
rv = aSubscription->GetKey(NS_LITERAL_STRING("auth"), &authSecretLen,
|
||||
&authSecret);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return FreeKeys(rv, key, authSecret);
|
||||
}
|
||||
|
||||
if (!aRawP256dhKey.SetLength(keyLen, fallible) ||
|
||||
!aRawP256dhKey.ReplaceElementsAt(0, keyLen, key, keyLen, fallible) ||
|
||||
!aAuthSecret.SetLength(authSecretLen, fallible) ||
|
||||
!aAuthSecret.ReplaceElementsAt(0, authSecretLen, authSecret,
|
||||
authSecretLen, fallible)) {
|
||||
|
||||
return FreeKeys(NS_ERROR_OUT_OF_MEMORY, key, authSecret);
|
||||
}
|
||||
|
||||
return FreeKeys(NS_OK, key, authSecret);
|
||||
}
|
||||
|
||||
RefPtr<PromiseWorkerProxy> mProxy;
|
||||
nsString mScope;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(GetSubscriptionCallback, nsIPushEndpointCallback)
|
||||
NS_IMPL_ISUPPORTS(GetSubscriptionCallback, nsIPushSubscriptionCallback)
|
||||
|
||||
class GetSubscriptionRunnable final : public nsRunnable
|
||||
{
|
||||
@ -674,35 +721,35 @@ public:
|
||||
PushPermissionState state;
|
||||
nsresult rv = GetPermissionState(principal, state);
|
||||
if (NS_FAILED(rv)) {
|
||||
callback->OnPushEndpointError(NS_ERROR_FAILURE);
|
||||
callback->OnPushSubscriptionError(NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (state != PushPermissionState::Granted) {
|
||||
if (mAction == WorkerPushManager::GetSubscriptionAction) {
|
||||
callback->OnPushEndpointError(NS_OK);
|
||||
callback->OnPushSubscriptionError(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
callback->OnPushEndpointError(NS_ERROR_FAILURE);
|
||||
callback->OnPushSubscriptionError(NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPushClient> client =
|
||||
do_CreateInstance("@mozilla.org/push/PushClient;1");
|
||||
if (!client) {
|
||||
callback->OnPushEndpointError(NS_ERROR_FAILURE);
|
||||
nsCOMPtr<nsIPushService> service =
|
||||
do_GetService("@mozilla.org/push/Service;1");
|
||||
if (!service) {
|
||||
callback->OnPushSubscriptionError(NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mAction == WorkerPushManager::SubscribeAction) {
|
||||
rv = client->Subscribe(mScope, principal, callback);
|
||||
rv = service->Subscribe(mScope, principal, callback);
|
||||
} else {
|
||||
MOZ_ASSERT(mAction == WorkerPushManager::GetSubscriptionAction);
|
||||
rv = client->GetSubscription(mScope, principal, callback);
|
||||
rv = service->GetSubscription(mScope, principal, callback);
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
callback->OnPushEndpointError(NS_ERROR_FAILURE);
|
||||
callback->OnPushSubscriptionError(NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1,114 +0,0 @@
|
||||
/* 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");
|
||||
|
||||
var isParent = Cc["@mozilla.org/xre/runtime;1"]
|
||||
.getService(Ci.nsIXULRuntime)
|
||||
.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "PushService", function() {
|
||||
// Lazily initialize the PushService on
|
||||
// `sessionstore-windows-restored` or first use.
|
||||
const {PushService} = Cu.import("resource://gre/modules/PushService.jsm", {});
|
||||
if (isParent) {
|
||||
PushService.init();
|
||||
}
|
||||
return PushService;
|
||||
});
|
||||
|
||||
this.PushNotificationService = function PushNotificationService() {};
|
||||
|
||||
PushNotificationService.prototype = {
|
||||
classID: Components.ID("{32028e38-903b-4a64-a180-5857eb4cb3dd}"),
|
||||
|
||||
contractID: "@mozilla.org/push/NotificationService;1",
|
||||
|
||||
_xpcom_factory: XPCOMUtils.generateSingletonFactory(PushNotificationService),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
|
||||
Ci.nsISupportsWeakReference,
|
||||
Ci.nsIPushNotificationService,
|
||||
Ci.nsIPushQuotaManager,]),
|
||||
|
||||
register: function register(scope, originAttributes) {
|
||||
return PushService.register({
|
||||
scope: scope,
|
||||
originAttributes: originAttributes,
|
||||
maxQuota: Infinity,
|
||||
});
|
||||
},
|
||||
|
||||
unregister: function unregister(scope, originAttributes) {
|
||||
return PushService.unregister({scope, originAttributes});
|
||||
},
|
||||
|
||||
registration: function registration(scope, originAttributes) {
|
||||
return PushService.registration({scope, originAttributes});
|
||||
},
|
||||
|
||||
clearAll: function clearAll() {
|
||||
return PushService._clearAll();
|
||||
},
|
||||
|
||||
clearForDomain: function(domain) {
|
||||
return PushService._clearForDomain(domain);
|
||||
},
|
||||
|
||||
observe: function observe(subject, topic, data) {
|
||||
switch (topic) {
|
||||
case "app-startup":
|
||||
Services.obs.addObserver(this, "sessionstore-windows-restored", true);
|
||||
break;
|
||||
case "sessionstore-windows-restored":
|
||||
Services.obs.removeObserver(this, "sessionstore-windows-restored");
|
||||
if (isParent) {
|
||||
PushService.init();
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
// nsIPushQuotaManager methods
|
||||
|
||||
notificationForOriginShown: function(origin) {
|
||||
if (!isParent) {
|
||||
Services.cpmm.sendAsyncMessage("Push:NotificationForOriginShown", origin);
|
||||
return;
|
||||
}
|
||||
|
||||
PushService._notificationForOriginShown(origin);
|
||||
},
|
||||
|
||||
notificationForOriginClosed: function(origin) {
|
||||
if (!isParent) {
|
||||
Services.cpmm.sendAsyncMessage("Push:NotificationForOriginClosed", origin);
|
||||
return;
|
||||
}
|
||||
|
||||
PushService._notificationForOriginClosed(origin);
|
||||
}
|
||||
};
|
||||
|
||||
this.PushObserverNotification = function PushObserverNotification() {};
|
||||
|
||||
PushObserverNotification.prototype = {
|
||||
classID: Components.ID("{66a87970-6dc9-46e0-ac61-adb4a13791de}"),
|
||||
|
||||
contractID: "@mozilla.org/push/ObserverNotification;1",
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPushObserverNotification])
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([
|
||||
PushNotificationService,
|
||||
PushObserverNotification
|
||||
]);
|
@ -28,6 +28,9 @@ this.EXPORTED_SYMBOLS = ["PushRecord"];
|
||||
|
||||
const prefs = new Preferences("dom.push.");
|
||||
|
||||
/**
|
||||
* The push subscription record, stored in IndexedDB.
|
||||
*/
|
||||
function PushRecord(props) {
|
||||
this.pushEndpoint = props.pushEndpoint;
|
||||
this.scope = props.scope;
|
||||
@ -217,11 +220,12 @@ PushRecord.prototype = {
|
||||
|
||||
toSubscription() {
|
||||
return {
|
||||
pushEndpoint: this.pushEndpoint,
|
||||
endpoint: this.pushEndpoint,
|
||||
lastPush: this.lastPush,
|
||||
pushCount: this.pushCount,
|
||||
p256dhKey: this.p256dhPublicKey,
|
||||
authenticationSecret: this.authenticationSecret,
|
||||
quota: this.quotaApplies() ? this.quota : -1,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
@ -43,12 +43,6 @@ XPCOMUtils.defineLazyGetter(this, "console", () => {
|
||||
|
||||
const prefs = new Preferences("dom.push.");
|
||||
|
||||
const kCHILD_PROCESS_MESSAGES = ["Push:Register", "Push:Unregister",
|
||||
"Push:Registration", "Push:RegisterEventNotificationListener",
|
||||
"Push:NotificationForOriginShown",
|
||||
"Push:NotificationForOriginClosed",
|
||||
"child-process-shutdown"];
|
||||
|
||||
const PUSH_SERVICE_UNINIT = 0;
|
||||
const PUSH_SERVICE_INIT = 1; // No serverURI
|
||||
const PUSH_SERVICE_ACTIVATING = 2;//activating db
|
||||
@ -105,7 +99,7 @@ this.PushService = {
|
||||
// reduce the quota for a record. Used for testing purposes.
|
||||
_updateQuotaTestCallback: null,
|
||||
|
||||
_childListeners: [],
|
||||
_childListeners: new Set(),
|
||||
|
||||
// When serverURI changes (this is used for testing), db is cleaned up and a
|
||||
// a new db is started. This events must be sequential.
|
||||
@ -379,7 +373,7 @@ this.PushService = {
|
||||
this._setState(PUSH_SERVICE_INIT);
|
||||
return Promise.resolve();
|
||||
}
|
||||
return this._startService(service, uri, event)
|
||||
return this._startService(service, uri)
|
||||
.then(_ => this._stateChangeProcessEnqueue(_ =>
|
||||
this._changeStateConnectionEnabledEvent(prefs.get("connection.enabled")))
|
||||
);
|
||||
@ -390,7 +384,7 @@ this.PushService = {
|
||||
if (this._state == PUSH_SERVICE_INIT) {
|
||||
this._setState(PUSH_SERVICE_ACTIVATING);
|
||||
// The service has not been running - start it.
|
||||
return this._startService(service, uri, STARTING_SERVICE_EVENT)
|
||||
return this._startService(service, uri)
|
||||
.then(_ => this._stateChangeProcessEnqueue(_ =>
|
||||
this._changeStateConnectionEnabledEvent(prefs.get("connection.enabled")))
|
||||
);
|
||||
@ -402,7 +396,7 @@ this.PushService = {
|
||||
// check is called in changeStateConnectionEnabledEvent function)
|
||||
return this._stopService(CHANGING_SERVICE_EVENT)
|
||||
.then(_ =>
|
||||
this._startService(service, uri, CHANGING_SERVICE_EVENT)
|
||||
this._startService(service, uri)
|
||||
)
|
||||
.then(_ => this._stateChangeProcessEnqueue(_ =>
|
||||
this._changeStateConnectionEnabledEvent(prefs.get("connection.enabled")))
|
||||
@ -458,7 +452,7 @@ this.PushService = {
|
||||
}
|
||||
|
||||
// Start service.
|
||||
this._startService(service, uri, false, options).then(_ => {
|
||||
this._startService(service, uri, options).then(_ => {
|
||||
// Before completing the activation check prefs. This will first check
|
||||
// connection.enabled pref and then check offline state.
|
||||
this._changeStateConnectionEnabledEvent(prefs.get("connection.enabled"));
|
||||
@ -515,24 +509,13 @@ this.PushService = {
|
||||
Services.obs.addObserver(this, "perm-changed", false);
|
||||
},
|
||||
|
||||
_startService: function(service, serverURI, event, options = {}) {
|
||||
_startService: function(service, serverURI, options = {}) {
|
||||
console.debug("startService()");
|
||||
|
||||
if (this._state != PUSH_SERVICE_ACTIVATING) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event != CHANGING_SERVICE_EVENT) {
|
||||
// if only serverURL is changed we can keep listening for broadcast
|
||||
// messages and queue them.
|
||||
let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
|
||||
.getService(Ci.nsIMessageBroadcaster);
|
||||
|
||||
kCHILD_PROCESS_MESSAGES.forEach(msgName =>
|
||||
ppmm.addMessageListener(msgName, this)
|
||||
);
|
||||
}
|
||||
|
||||
this._service = service;
|
||||
|
||||
this._db = options.db;
|
||||
@ -564,15 +547,6 @@ this.PushService = {
|
||||
this.stopAlarm();
|
||||
this._stopObservers();
|
||||
|
||||
if (event != CHANGING_SERVICE_EVENT) {
|
||||
let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
|
||||
.getService(Ci.nsIMessageBroadcaster);
|
||||
|
||||
kCHILD_PROCESS_MESSAGES.forEach(
|
||||
msgName => ppmm.removeMessageListener(msgName, this)
|
||||
);
|
||||
}
|
||||
|
||||
this._service.disconnect();
|
||||
this._service.uninit();
|
||||
this._service = null;
|
||||
@ -616,7 +590,7 @@ this.PushService = {
|
||||
uninit: function() {
|
||||
console.debug("uninit()");
|
||||
|
||||
this._childListeners = [];
|
||||
this._childListeners.clear();
|
||||
|
||||
if (this._state == PUSH_SERVICE_UNINIT) {
|
||||
return;
|
||||
@ -725,14 +699,14 @@ this.PushService = {
|
||||
},
|
||||
|
||||
_notifyListeners: function(name, data) {
|
||||
if (this._childListeners.length > 0) {
|
||||
if (this._childListeners.size > 0) {
|
||||
// Try to send messages to all listeners, but remove any that fail since
|
||||
// the receiver is likely gone away.
|
||||
for (var i = this._childListeners.length - 1; i >= 0; --i) {
|
||||
for (let listener of this._childListeners) {
|
||||
try {
|
||||
this._childListeners[i].sendAsyncMessage(name, data);
|
||||
listener.sendAsyncMessage(name, data);
|
||||
} catch(e) {
|
||||
this._childListeners.splice(i, 1);
|
||||
this._childListeners.delete(listener);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -944,7 +918,7 @@ this.PushService = {
|
||||
});
|
||||
},
|
||||
|
||||
_notificationForOriginShown(origin) {
|
||||
notificationForOriginShown(origin) {
|
||||
console.debug("notificationForOriginShown()", origin);
|
||||
let count;
|
||||
if (this._visibleNotifications.has(origin)) {
|
||||
@ -955,7 +929,7 @@ this.PushService = {
|
||||
this._visibleNotifications.set(origin, count + 1);
|
||||
},
|
||||
|
||||
_notificationForOriginClosed(origin) {
|
||||
notificationForOriginClosed(origin) {
|
||||
console.debug("notificationForOriginClosed()", origin);
|
||||
let count;
|
||||
if (this._visibleNotifications.has(origin)) {
|
||||
@ -1106,99 +1080,27 @@ this.PushService = {
|
||||
throw reply.error;
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
console.debug("receiveMessage()", aMessage.name);
|
||||
|
||||
if (kCHILD_PROCESS_MESSAGES.indexOf(aMessage.name) == -1) {
|
||||
console.debug("receiveMessage: Invalid message from child",
|
||||
aMessage.name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (aMessage.name === "Push:RegisterEventNotificationListener") {
|
||||
console.debug("receiveMessage: Adding child listener");
|
||||
this._childListeners.push(aMessage.target);
|
||||
return;
|
||||
}
|
||||
|
||||
if (aMessage.name === "child-process-shutdown") {
|
||||
console.debug("receiveMessage: Possibly removing child listener");
|
||||
for (var i = this._childListeners.length - 1; i >= 0; --i) {
|
||||
if (this._childListeners[i] == aMessage.target) {
|
||||
console.debug("receiveMessage: Removed child listener");
|
||||
this._childListeners.splice(i, 1);
|
||||
}
|
||||
}
|
||||
console.debug("receiveMessage: Clearing notifications from child");
|
||||
this._visibleNotifications.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (aMessage.name === "Push:NotificationForOriginShown") {
|
||||
console.debug("receiveMessage: Notification shown from child");
|
||||
this._notificationForOriginShown(aMessage.data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (aMessage.name === "Push:NotificationForOriginClosed") {
|
||||
console.debug("receiveMessage: Notification closed from child");
|
||||
this._notificationForOriginClosed(aMessage.data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!aMessage.target.assertPermission("push")) {
|
||||
console.debug("receiveMessage: Got message from a child process that",
|
||||
"does not have 'push' permission");
|
||||
return null;
|
||||
}
|
||||
|
||||
let mm = aMessage.target.QueryInterface(Ci.nsIMessageSender);
|
||||
|
||||
let name = aMessage.name.slice("Push:".length);
|
||||
Promise.resolve().then(_ => {
|
||||
let pageRecord = this._validatePageRecord(aMessage);
|
||||
return this[name.toLowerCase()](pageRecord);
|
||||
}).then(result => {
|
||||
mm.sendAsyncMessage("PushService:" + name + ":OK", {
|
||||
requestID: aMessage.data.requestID,
|
||||
result: result,
|
||||
});
|
||||
}, error => {
|
||||
console.error("receiveMessage: Error handling message", aMessage, error);
|
||||
mm.sendAsyncMessage("PushService:" + name + ":KO", {
|
||||
requestID: aMessage.data.requestID,
|
||||
});
|
||||
}).catch(error => {
|
||||
console.error("receiveMessage: Error sending reply", error);
|
||||
});
|
||||
registerListener(listener) {
|
||||
console.debug("registerListener: Adding child listener");
|
||||
this._childListeners.add(listener);
|
||||
},
|
||||
|
||||
_validatePageRecord: function(aMessage) {
|
||||
let principal = aMessage.principal;
|
||||
if (!principal) {
|
||||
throw new Error("Missing message principal");
|
||||
}
|
||||
unregisterListener(listener) {
|
||||
console.debug("unregisterListener: Possibly removing child listener");
|
||||
this._childListeners.delete(listener);
|
||||
this._visibleNotifications.clear();
|
||||
},
|
||||
|
||||
let pageRecord = aMessage.data;
|
||||
if (!pageRecord.scope) {
|
||||
throw new Error("Missing page record scope");
|
||||
}
|
||||
|
||||
pageRecord.originAttributes =
|
||||
ChromeUtils.originAttributesToSuffix(principal.originAttributes);
|
||||
|
||||
return pageRecord;
|
||||
_getByPageRecord(pageRecord) {
|
||||
return this._checkActivated().then(_ =>
|
||||
this._db.getByIdentifiers(pageRecord)
|
||||
);
|
||||
},
|
||||
|
||||
register: function(aPageRecord) {
|
||||
console.debug("register()", aPageRecord);
|
||||
|
||||
if (!aPageRecord.scope || aPageRecord.originAttributes === undefined) {
|
||||
return Promise.reject(new Error("Invalid page record"));
|
||||
}
|
||||
|
||||
return this._checkActivated()
|
||||
.then(_ => this._db.getByIdentifiers(aPageRecord))
|
||||
return this._getByPageRecord(aPageRecord)
|
||||
.then(record => {
|
||||
if (!record) {
|
||||
return this._lookupOrPutPendingRequest(aPageRecord);
|
||||
@ -1245,12 +1147,7 @@ this.PushService = {
|
||||
unregister: function(aPageRecord) {
|
||||
console.debug("unregister()", aPageRecord);
|
||||
|
||||
if (!aPageRecord.scope || aPageRecord.originAttributes === undefined) {
|
||||
return Promise.reject(new Error("Invalid page record"));
|
||||
}
|
||||
|
||||
return this._checkActivated()
|
||||
.then(_ => this._db.getByIdentifiers(aPageRecord))
|
||||
return this._getByPageRecord(aPageRecord)
|
||||
.then(record => {
|
||||
if (record === undefined) {
|
||||
return false;
|
||||
@ -1313,12 +1210,8 @@ this.PushService = {
|
||||
|
||||
registration: function(aPageRecord) {
|
||||
console.debug("registration()");
|
||||
if (!aPageRecord.scope || aPageRecord.originAttributes === undefined) {
|
||||
return Promise.reject(new Error("Invalid page record"));
|
||||
}
|
||||
|
||||
return this._checkActivated()
|
||||
.then(_ => this._db.getByIdentifiers(aPageRecord))
|
||||
return this._getByPageRecord(aPageRecord)
|
||||
.then(record => {
|
||||
if (!record) {
|
||||
return null;
|
||||
|
@ -6,8 +6,7 @@
|
||||
EXTRA_COMPONENTS += [
|
||||
'Push.js',
|
||||
'Push.manifest',
|
||||
'PushClient.js',
|
||||
'PushNotificationService.js',
|
||||
'PushComponents.js',
|
||||
]
|
||||
|
||||
EXTRA_JS_MODULES += [
|
||||
|
Loading…
Reference in New Issue
Block a user