Bug 1772094 - Part 7: Use plain object for lazy getter in dom/push/. r=dragana

Differential Revision: https://phabricator.services.mozilla.com/D147914
This commit is contained in:
Tooru Fujisawa 2022-06-07 16:23:07 +00:00
Родитель 0ad74bb155
Коммит 46fd03515a
10 изменённых файлов: 403 добавлений и 334 удалений

Просмотреть файл

@ -12,7 +12,9 @@ const { DOMRequestIpcHelper } = ChromeUtils.import(
"resource://gre/modules/DOMRequestHelper.jsm"
);
XPCOMUtils.defineLazyGetter(this, "console", () => {
const lazy = {};
XPCOMUtils.defineLazyGetter(lazy, "console", () => {
let { ConsoleAPI } = ChromeUtils.import("resource://gre/modules/Console.jsm");
return new ConsoleAPI({
maxLogLevelPref: "dom.push.loglevel",
@ -21,7 +23,7 @@ XPCOMUtils.defineLazyGetter(this, "console", () => {
});
XPCOMUtils.defineLazyServiceGetter(
this,
lazy,
"PushService",
"@mozilla.org/push/Service;1",
"nsIPushService"
@ -35,7 +37,7 @@ const PUSH_CID = Components.ID("{cde1d019-fad8-4044-b141-65fb4fb7a245}");
* one actually performing all operations.
*/
function Push() {
console.debug("Push()");
lazy.console.debug("Push()");
}
Push.prototype = {
@ -52,7 +54,7 @@ Push.prototype = {
]),
init(win) {
console.debug("init()");
lazy.console.debug("init()");
this._window = win;
@ -79,7 +81,7 @@ Push.prototype = {
},
askPermission() {
console.debug("askPermission()");
lazy.console.debug("askPermission()");
let hasValidTransientUserGestureActivation = this._window.document
.hasValidTransientUserGestureActivation;
@ -110,14 +112,14 @@ Push.prototype = {
},
subscribe(options) {
console.debug("subscribe()", this._scope);
lazy.console.debug("subscribe()", this._scope);
return this.askPermission().then(() =>
this.createPromise((resolve, reject) => {
let callback = new PushSubscriptionCallback(this, resolve, reject);
if (!options || options.applicationServerKey === null) {
PushService.subscribe(this._scope, this._principal, callback);
lazy.PushService.subscribe(this._scope, this._principal, callback);
return;
}
@ -126,7 +128,7 @@ Push.prototype = {
callback._rejectWithError(Cr.NS_ERROR_DOM_PUSH_INVALID_KEY_ERR);
return;
}
PushService.subscribeWithKey(
lazy.PushService.subscribeWithKey(
this._scope,
this._principal,
keyView,
@ -162,16 +164,16 @@ Push.prototype = {
},
getSubscription() {
console.debug("getSubscription()", this._scope);
lazy.console.debug("getSubscription()", this._scope);
return this.createPromise((resolve, reject) => {
let callback = new PushSubscriptionCallback(this, resolve, reject);
PushService.getSubscription(this._scope, this._principal, callback);
lazy.PushService.getSubscription(this._scope, this._principal, callback);
});
},
permissionState() {
console.debug("permissionState()", this._scope);
lazy.console.debug("permissionState()", this._scope);
return this.createPromise((resolve, reject) => {
let permission = Ci.nsIPermissionManager.UNKNOWN_ACTION;

Просмотреть файл

@ -8,8 +8,9 @@ const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
const lazy = {};
ChromeUtils.defineModuleGetter(
this,
lazy,
"JSONFile",
"resource://gre/modules/JSONFile.jsm"
);
@ -20,7 +21,7 @@ const EXPORTED_SYMBOLS = ["pushBroadcastService", "BroadcastService"];
// We are supposed to ignore any updates with this version.
const DUMMY_VERSION_STRING = "____NOP____";
XPCOMUtils.defineLazyGetter(this, "console", () => {
XPCOMUtils.defineLazyGetter(lazy, "console", () => {
let { ConsoleAPI } = ChromeUtils.import("resource://gre/modules/Console.jsm");
return new ConsoleAPI({
maxLogLevelPref: "dom.push.loglevel",
@ -28,7 +29,7 @@ XPCOMUtils.defineLazyGetter(this, "console", () => {
});
});
ChromeUtils.defineModuleGetter(
this,
lazy,
"PushService",
"resource://gre/modules/PushService.jsm"
);
@ -51,7 +52,7 @@ var BroadcastService = class {
};
this.pushService = pushService;
this.jsonFile = new JSONFile({
this.jsonFile = new lazy.JSONFile({
path,
dataPostProcessor: this._initializeJSONFile,
});
@ -129,7 +130,7 @@ var BroadcastService = class {
* updates on this broadcastID
*/
async addListener(broadcastId, version, sourceInfo) {
console.info(
lazy.console.info(
"addListener: adding listener",
broadcastId,
version,
@ -148,7 +149,7 @@ var BroadcastService = class {
const oldVersion =
!isNew && this.jsonFile.data.listeners[broadcastId].version;
if (!isNew && oldVersion != version) {
console.warn(
lazy.console.warn(
"Versions differ while adding listener for",
broadcastId,
". Got",
@ -188,17 +189,21 @@ var BroadcastService = class {
* @param {String} context.phase One of `BroadcastService.PHASES`
*/
async receivedBroadcastMessage(broadcasts, context) {
console.info("receivedBroadcastMessage:", broadcasts, context);
lazy.console.info("receivedBroadcastMessage:", broadcasts, context);
await this.initializePromise;
for (const broadcastId in broadcasts) {
const version = broadcasts[broadcastId];
if (version === DUMMY_VERSION_STRING) {
console.info("Ignoring", version, "because it's the dummy version");
lazy.console.info(
"Ignoring",
version,
"because it's the dummy version"
);
continue;
}
// We don't know this broadcastID. This is probably a bug?
if (!this.jsonFile.data.listeners.hasOwnProperty(broadcastId)) {
console.warn(
lazy.console.warn(
"receivedBroadcastMessage: unknown broadcastId",
broadcastId
);
@ -209,7 +214,7 @@ var BroadcastService = class {
try {
this._validateSourceInfo(sourceInfo);
} catch (e) {
console.error(
lazy.console.error(
"receivedBroadcastMessage: malformed sourceInfo",
sourceInfo,
e
@ -223,7 +228,7 @@ var BroadcastService = class {
try {
module = ChromeUtils.import(moduleURI);
} catch (e) {
console.error(
lazy.console.error(
"receivedBroadcastMessage: couldn't invoke",
broadcastId,
"because import of module",
@ -235,7 +240,7 @@ var BroadcastService = class {
}
if (!module[symbolName]) {
console.error(
lazy.console.error(
"receivedBroadcastMessage: couldn't invoke",
broadcastId,
"because module",
@ -249,7 +254,7 @@ var BroadcastService = class {
const handler = module[symbolName];
if (!handler.receivedBroadcastMessage) {
console.error(
lazy.console.error(
"receivedBroadcastMessage: couldn't invoke",
broadcastId,
"because handler returned by",
@ -262,7 +267,7 @@ var BroadcastService = class {
try {
await handler.receivedBroadcastMessage(version, broadcastId, context);
} catch (e) {
console.error(
lazy.console.error(
"receivedBroadcastMessage: handler for",
broadcastId,
"threw error:",
@ -296,7 +301,7 @@ function initializeBroadcastService() {
// Real path for use in a real profile.
path = OS.Path.join(OS.Constants.Path.profileDir, path);
}
return new BroadcastService(PushService, path);
return new BroadcastService(lazy.PushService, path);
}
var pushBroadcastService = initializeBroadcastService();

Просмотреть файл

@ -17,8 +17,10 @@ const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
var isParent =
Services.appinfo.processType === Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
const lazy = {};
// The default Push service implementation.
XPCOMUtils.defineLazyGetter(this, "PushService", function() {
XPCOMUtils.defineLazyGetter(lazy, "PushService", function() {
if (Services.prefs.getBoolPref("dom.push.enabled")) {
const { PushService } = ChromeUtils.import(
"resource://gre/modules/PushService.jsm"
@ -328,7 +330,7 @@ Object.assign(PushServiceParent.prototype, {
// Used to replace the implementation with a mock.
Object.defineProperty(PushServiceParent.prototype, "service", {
get() {
return this._service || PushService;
return this._service || lazy.PushService;
},
set(impl) {
this._service = impl;

Просмотреть файл

@ -9,11 +9,13 @@ const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
XPCOMUtils.defineLazyGetter(this, "gDOMBundle", () =>
const lazy = {};
XPCOMUtils.defineLazyGetter(lazy, "gDOMBundle", () =>
Services.strings.createBundle("chrome://global/locale/dom/dom.properties")
);
XPCOMUtils.defineLazyGlobalGetters(this, ["crypto"]);
XPCOMUtils.defineLazyGlobalGetters(lazy, ["crypto"]);
// getCryptoParamsFromHeaders is exported for test purposes.
const EXPORTED_SYMBOLS = ["PushCrypto", "getCryptoParamsFromHeaders"];
@ -76,7 +78,7 @@ class CryptoError extends Error {
*/
format(scope) {
let params = [scope, ...this.params].map(String);
return gDOMBundle.formatStringFromName(this.property, params);
return lazy.gDOMBundle.formatStringFromName(this.property, params);
}
}
@ -241,13 +243,17 @@ function concatArray(arrays) {
}
function hmac(key) {
this.keyPromise = crypto.subtle.importKey("raw", key, HMAC_SHA256, false, [
"sign",
]);
this.keyPromise = lazy.crypto.subtle.importKey(
"raw",
key,
HMAC_SHA256,
false,
["sign"]
);
}
hmac.prototype.hash = function(input) {
return this.keyPromise.then(k => crypto.subtle.sign("HMAC", k, input));
return this.keyPromise.then(k => lazy.crypto.subtle.sign("HMAC", k, input));
};
function hkdf(salt, ikm) {
@ -325,7 +331,7 @@ class Decoder {
try {
let ikm = await this.computeSharedSecret();
let [gcmBits, nonce] = await this.deriveKeyAndNonce(ikm);
let key = await crypto.subtle.importKey(
let key = await lazy.crypto.subtle.importKey(
"raw",
gcmBits,
"AES-GCM",
@ -362,14 +368,14 @@ class Decoder {
*/
async computeSharedSecret() {
let [appServerKey, subscriptionPrivateKey] = await Promise.all([
crypto.subtle.importKey("raw", this.senderKey, ECDH_KEY, false, [
lazy.crypto.subtle.importKey("raw", this.senderKey, ECDH_KEY, false, [
"deriveBits",
]),
crypto.subtle.importKey("jwk", this.privateKey, ECDH_KEY, false, [
lazy.crypto.subtle.importKey("jwk", this.privateKey, ECDH_KEY, false, [
"deriveBits",
]),
]);
return crypto.subtle.deriveBits(
return lazy.crypto.subtle.deriveBits(
{ name: "ECDH", public: appServerKey },
subscriptionPrivateKey,
256
@ -402,7 +408,7 @@ class Decoder {
name: "AES-GCM",
iv: generateNonce(nonce, index),
};
let decoded = await crypto.subtle.decrypt(params, key, slice);
let decoded = await lazy.crypto.subtle.decrypt(params, key, slice);
return this.unpadChunk(new Uint8Array(decoded), last);
}
@ -603,22 +609,22 @@ var PushCrypto = {
concatArray,
generateAuthenticationSecret() {
return crypto.getRandomValues(new Uint8Array(16));
return lazy.crypto.getRandomValues(new Uint8Array(16));
},
validateAppServerKey(key) {
return crypto.subtle
return lazy.crypto.subtle
.importKey("raw", key, ECDSA_KEY, true, ["verify"])
.then(_ => key);
},
generateKeys() {
return crypto.subtle
return lazy.crypto.subtle
.generateKey(ECDH_KEY, true, ["deriveBits"])
.then(cryptoKey =>
Promise.all([
crypto.subtle.exportKey("raw", cryptoKey.publicKey),
crypto.subtle.exportKey("jwk", cryptoKey.privateKey),
lazy.crypto.subtle.exportKey("raw", cryptoKey.publicKey),
lazy.crypto.subtle.exportKey("jwk", cryptoKey.privateKey),
])
);
},
@ -725,9 +731,10 @@ var PushCrypto = {
// purposes we allow it to be specified.
const senderKeyPair =
options.senderKeyPair ||
(await crypto.subtle.generateKey(ECDH_KEY, true, ["deriveBits"]));
(await lazy.crypto.subtle.generateKey(ECDH_KEY, true, ["deriveBits"]));
// allowing a salt to be specified is useful for tests.
const salt = options.salt || crypto.getRandomValues(new Uint8Array(16));
const salt =
options.salt || lazy.crypto.getRandomValues(new Uint8Array(16));
const rs = options.rs === undefined ? 4096 : options.rs;
const encoder = new aes128gcmEncoder(
@ -766,7 +773,7 @@ class aes128gcmEncoder {
this.senderKeyPair.privateKey
);
const rawSenderPublicKey = await crypto.subtle.exportKey(
const rawSenderPublicKey = await lazy.crypto.subtle.exportKey(
"raw",
this.senderKeyPair.publicKey
);
@ -775,7 +782,7 @@ class aes128gcmEncoder {
rawSenderPublicKey
);
const contentEncryptionKey = await crypto.subtle.importKey(
const contentEncryptionKey = await lazy.crypto.subtle.importKey(
"raw",
gcmBits,
"AES-GCM",
@ -801,7 +808,7 @@ class aes128gcmEncoder {
if (this.plaintext.byteLength === 0) {
// Send an authentication tag for empty messages.
chunks = [
await crypto.subtle.encrypt(
await lazy.crypto.subtle.encrypt(
{
name: "AES-GCM",
iv: generateNonce(nonce, 0),
@ -819,7 +826,7 @@ class aes128gcmEncoder {
let isLast = index == inChunks.length - 1;
let padding = new Uint8Array([isLast ? 2 : 1]);
let input = concatArray([slice, padding]);
return crypto.subtle.encrypt(
return lazy.crypto.subtle.encrypt(
{
name: "AES-GCM",
iv: generateNonce(nonce, index),
@ -853,7 +860,7 @@ class aes128gcmEncoder {
// Note: this duplicates some of Decoder.computeSharedSecret, but the key
// management is slightly different.
async computeSharedSecret(receiverPublicKey, senderPrivateKey) {
const receiverPublicCryptoKey = await crypto.subtle.importKey(
const receiverPublicCryptoKey = await lazy.crypto.subtle.importKey(
"raw",
receiverPublicKey,
ECDH_KEY,
@ -861,7 +868,7 @@ class aes128gcmEncoder {
["deriveBits"]
);
return crypto.subtle.deriveBits(
return lazy.crypto.subtle.deriveBits(
{ name: "ECDH", public: receiverPublicCryptoKey },
senderPrivateKey,
256

Просмотреть файл

@ -13,7 +13,9 @@ const { XPCOMUtils } = ChromeUtils.import(
const EXPORTED_SYMBOLS = ["PushDB"];
XPCOMUtils.defineLazyGetter(this, "console", () => {
const lazy = {};
XPCOMUtils.defineLazyGetter(lazy, "console", () => {
let { ConsoleAPI } = ChromeUtils.import("resource://gre/modules/Console.jsm");
return new ConsoleAPI({
maxLogLevelPref: "dom.push.loglevel",
@ -22,7 +24,7 @@ XPCOMUtils.defineLazyGetter(this, "console", () => {
});
function PushDB(dbName, dbVersion, dbStoreName, keyPath, model) {
console.debug("PushDB()");
lazy.console.debug("PushDB()");
this._dbStoreName = dbStoreName;
this._keyPath = keyPath;
this._model = model;
@ -93,7 +95,7 @@ PushDB.prototype = {
*/
put(aRecord) {
console.debug("put()", aRecord);
lazy.console.debug("put()", aRecord);
if (!this.isValidRecord(aRecord)) {
return Promise.reject(
new TypeError(
@ -111,7 +113,7 @@ PushDB.prototype = {
aTxn.result = undefined;
aStore.put(aRecord).onsuccess = aEvent => {
console.debug(
lazy.console.debug(
"put: Request successful. Updated record",
aEvent.target.result
);
@ -129,14 +131,14 @@ PushDB.prototype = {
* The ID of record to be deleted.
*/
delete(aKeyID) {
console.debug("delete()");
lazy.console.debug("delete()");
return new Promise((resolve, reject) =>
this.newTxn(
"readwrite",
this._dbStoreName,
(aTxn, aStore) => {
console.debug("delete: Removing record", aKeyID);
lazy.console.debug("delete: Removing record", aKeyID);
aStore.get(aKeyID).onsuccess = event => {
aTxn.result = this.toPushRecord(event.target.result);
aStore.delete(aKeyID);
@ -151,7 +153,7 @@ PushDB.prototype = {
// testFn(record) is called with a database record and should return true if
// that record should be deleted.
clearIf(testFn) {
console.debug("clearIf()");
lazy.console.debug("clearIf()");
return new Promise((resolve, reject) =>
this.newTxn(
"readwrite",
@ -166,7 +168,7 @@ PushDB.prototype = {
if (testFn(record)) {
let deleteRequest = cursor.delete();
deleteRequest.onerror = e => {
console.error(
lazy.console.error(
"clearIf: Error removing record",
record.keyID,
e
@ -184,7 +186,7 @@ PushDB.prototype = {
},
getByPushEndpoint(aPushEndpoint) {
console.debug("getByPushEndpoint()");
lazy.console.debug("getByPushEndpoint()");
return new Promise((resolve, reject) =>
this.newTxn(
@ -196,7 +198,7 @@ PushDB.prototype = {
let index = aStore.index("pushEndpoint");
index.get(aPushEndpoint).onsuccess = aEvent => {
let record = this.toPushRecord(aEvent.target.result);
console.debug("getByPushEndpoint: Got record", record);
lazy.console.debug("getByPushEndpoint: Got record", record);
aTxn.result = record;
};
},
@ -207,7 +209,7 @@ PushDB.prototype = {
},
getByKeyID(aKeyID) {
console.debug("getByKeyID()");
lazy.console.debug("getByKeyID()");
return new Promise((resolve, reject) =>
this.newTxn(
@ -218,7 +220,7 @@ PushDB.prototype = {
aStore.get(aKeyID).onsuccess = aEvent => {
let record = this.toPushRecord(aEvent.target.result);
console.debug("getByKeyID: Got record", record);
lazy.console.debug("getByKeyID: Got record", record);
aTxn.result = record;
};
},
@ -240,7 +242,7 @@ PushDB.prototype = {
* @returns {Promise} Resolves once all records have been processed.
*/
forEachOrigin(origin, originAttributes, callback) {
console.debug("forEachOrigin()");
lazy.console.debug("forEachOrigin()");
return new Promise((resolve, reject) =>
this.newTxn(
@ -271,9 +273,9 @@ PushDB.prototype = {
// Perform a unique match against { scope, originAttributes }
getByIdentifiers(aPageRecord) {
console.debug("getByIdentifiers()", aPageRecord);
lazy.console.debug("getByIdentifiers()", aPageRecord);
if (!aPageRecord.scope || aPageRecord.originAttributes == undefined) {
console.error(
lazy.console.error(
"getByIdentifiers: Scope and originAttributes are required",
aPageRecord
);
@ -335,7 +337,7 @@ PushDB.prototype = {
},
getAllKeyIDs() {
console.debug("getAllKeyIDs()");
lazy.console.debug("getAllKeyIDs()");
return new Promise((resolve, reject) =>
this.newTxn(
@ -356,7 +358,7 @@ PushDB.prototype = {
},
_getAllByPushQuota(range) {
console.debug("getAllByPushQuota()");
lazy.console.debug("getAllByPushQuota()");
return new Promise((resolve, reject) =>
this.newTxn(
@ -381,12 +383,12 @@ PushDB.prototype = {
},
getAllUnexpired() {
console.debug("getAllUnexpired()");
lazy.console.debug("getAllUnexpired()");
return this._getAllByPushQuota(IDBKeyRange.lowerBound(1));
},
getAllExpired() {
console.debug("getAllExpired()");
lazy.console.debug("getAllExpired()");
return this._getAllByPushQuota(IDBKeyRange.only(0));
},
@ -415,7 +417,7 @@ PushDB.prototype = {
}
let newRecord = aUpdateFunc(this.toPushRecord(record));
if (!this.isValidRecord(newRecord)) {
console.error(
lazy.console.error(
"update: Ignoring invalid update",
aKeyID,
newRecord
@ -425,7 +427,11 @@ PushDB.prototype = {
function putRecord() {
let req = aStore.put(newRecord);
req.onsuccess = aEvent => {
console.debug("update: Update successful", aKeyID, newRecord);
lazy.console.debug(
"update: Update successful",
aKeyID,
newRecord
);
aTxn.result = newRecord;
};
}
@ -445,7 +451,7 @@ PushDB.prototype = {
},
drop() {
console.debug("drop()");
lazy.console.debug("drop()");
return new Promise((resolve, reject) =>
this.newTxn(

Просмотреть файл

@ -9,19 +9,21 @@ const { AppConstants } = ChromeUtils.import(
);
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const lazy = {};
ChromeUtils.defineModuleGetter(
this,
lazy,
"EventDispatcher",
"resource://gre/modules/Messaging.jsm"
);
ChromeUtils.defineModuleGetter(
this,
lazy,
"PlacesUtils",
"resource://gre/modules/PlacesUtils.jsm"
);
ChromeUtils.defineModuleGetter(
this,
lazy,
"PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm"
);
@ -145,7 +147,7 @@ PushRecord.prototype = {
}
if (AppConstants.MOZ_ANDROID_HISTORY) {
let result = await EventDispatcher.instance.sendRequestForResult({
let result = await lazy.EventDispatcher.instance.sendRequestForResult({
type: "History:GetPrePathLastVisitedTimeMilliseconds",
prePath: this.uri.prePath,
});
@ -164,7 +166,7 @@ PushRecord.prototype = {
Ci.nsINavHistoryService.TRANSITION_REDIRECT_TEMPORARY,
].join(",");
let db = await PlacesUtils.promiseDBConnection();
let db = await lazy.PlacesUtils.promiseDBConnection();
// We're using a custom query instead of `nsINavHistoryQueryOptions`
// because the latter doesn't expose a way to filter by transition type:
// `setTransitions` performs a logical "and," but we want an "or." We
@ -196,7 +198,7 @@ PushRecord.prototype = {
isTabOpen() {
for (let window of Services.wm.getEnumerator("navigator:browser")) {
if (window.closed || PrivateBrowsingUtils.isWindowPrivate(window)) {
if (window.closed || lazy.PrivateBrowsingUtils.isWindowPrivate(window)) {
continue;
}
for (let tab of window.gBrowser.tabs) {

Просмотреть файл

@ -17,24 +17,26 @@ const { XPCOMUtils } = ChromeUtils.import(
var PushServiceWebSocket, PushServiceHttp2;
const lazy = {};
XPCOMUtils.defineLazyServiceGetter(
this,
lazy,
"gPushNotifier",
"@mozilla.org/push/Notifier;1",
"nsIPushNotifier"
);
ChromeUtils.defineModuleGetter(
this,
lazy,
"pushBroadcastService",
"resource://gre/modules/PushBroadcastService.jsm"
);
ChromeUtils.defineModuleGetter(
this,
lazy,
"PushCrypto",
"resource://gre/modules/PushCrypto.jsm"
);
ChromeUtils.defineModuleGetter(
this,
lazy,
"PushServiceAndroidGCM",
"resource://gre/modules/PushServiceAndroidGCM.jsm"
);
@ -49,7 +51,7 @@ const CONNECTION_PROTOCOLS = (function() {
));
return [PushServiceWebSocket, PushServiceHttp2];
}
return [PushServiceAndroidGCM];
return [lazy.PushServiceAndroidGCM];
})();
const EXPORTED_SYMBOLS = [
@ -59,7 +61,7 @@ const EXPORTED_SYMBOLS = [
"PushServiceWebSocket",
];
XPCOMUtils.defineLazyGetter(this, "console", () => {
XPCOMUtils.defineLazyGetter(lazy, "console", () => {
let { ConsoleAPI } = ChromeUtils.import("resource://gre/modules/Console.jsm");
return new ConsoleAPI({
maxLogLevelPref: "dom.push.loglevel",
@ -161,14 +163,14 @@ var PushService = {
this._stateChangeProcessQueue = this._stateChangeProcessQueue
.then(op)
.catch(error => {
console.error(
lazy.console.error(
"stateChangeProcessEnqueue: Error transitioning state",
error
);
return this._shutdownService();
})
.catch(error => {
console.error(
lazy.console.error(
"stateChangeProcessEnqueue: Error shutting down service",
error
);
@ -220,7 +222,7 @@ var PushService = {
},
_setState(aNewState) {
console.debug(
lazy.console.debug(
"setState()",
"new state",
aNewState,
@ -249,7 +251,7 @@ var PushService = {
},
async _changeStateOfflineEvent(offline, calledFromConnEnabledEvent) {
console.debug("changeStateOfflineEvent()", offline);
lazy.console.debug("changeStateOfflineEvent()", offline);
if (
this._state < PUSH_SERVICE_ACTIVE_OFFLINE &&
@ -274,7 +276,7 @@ var PushService = {
this._service.disconnect();
}
let broadcastListeners = await pushBroadcastService.getListeners();
let broadcastListeners = await lazy.pushBroadcastService.getListeners();
// In principle, a listener could be added to the
// pushBroadcastService here, after we have gotten listeners and
@ -290,7 +292,7 @@ var PushService = {
},
_changeStateConnectionEnabledEvent(enabled) {
console.debug("changeStateConnectionEnabledEvent()", enabled);
lazy.console.debug("changeStateConnectionEnabledEvent()", enabled);
if (
this._state < PUSH_SERVICE_CONNECTION_DISABLE &&
@ -312,11 +314,11 @@ var PushService = {
// Used for testing.
changeTestServer(url, options = {}) {
console.debug("changeTestServer()");
lazy.console.debug("changeTestServer()");
return this._stateChangeProcessEnqueue(_ => {
if (this._state < PUSH_SERVICE_ACTIVATING) {
console.debug("changeTestServer: PushService not activated?");
lazy.console.debug("changeTestServer: PushService not activated?");
return Promise.resolve();
}
@ -342,7 +344,7 @@ var PushService = {
case "nsPref:changed":
if (aData == "serverURL") {
console.debug(
lazy.console.debug(
"observe: dom.push.serverURL changed for websocket",
prefs.getStringPref("serverURL")
);
@ -363,13 +365,16 @@ var PushService = {
case "idle-daily":
this._dropExpiredRegistrations().catch(error => {
console.error("Failed to drop expired registrations on idle", error);
lazy.console.error(
"Failed to drop expired registrations on idle",
error
);
});
break;
case "perm-changed":
this._onPermissionChange(aSubject, aData).catch(error => {
console.error(
lazy.console.error(
"onPermissionChange: Error updating registrations:",
error
);
@ -378,14 +383,17 @@ var PushService = {
case "clear-origin-attributes-data":
this._clearOriginData(aData).catch(error => {
console.error("clearOriginData: Error clearing origin data:", error);
lazy.console.error(
"clearOriginData: Error clearing origin data:",
error
);
});
break;
}
},
_clearOriginData(data) {
console.log("clearOriginData()");
lazy.console.log("clearOriginData()");
if (!data) {
return Promise.resolve();
@ -406,30 +414,30 @@ var PushService = {
* indicating why this record was removed.
*/
_backgroundUnregister(record, reason) {
console.debug("backgroundUnregister()");
lazy.console.debug("backgroundUnregister()");
if (!this._service.isConnected() || !record) {
return;
}
console.debug("backgroundUnregister: Notifying server", record);
lazy.console.debug("backgroundUnregister: Notifying server", record);
this._sendUnregister(record, reason)
.then(() => {
gPushNotifier.notifySubscriptionModified(
lazy.gPushNotifier.notifySubscriptionModified(
record.scope,
record.principal
);
})
.catch(e => {
console.error("backgroundUnregister: Error notifying server", e);
lazy.console.error("backgroundUnregister: Error notifying server", e);
});
},
_findService(serverURL) {
console.debug("findService()");
lazy.console.debug("findService()");
if (!serverURL) {
console.warn("findService: No dom.push.serverURL found");
lazy.console.warn("findService: No dom.push.serverURL found");
return [];
}
@ -437,7 +445,7 @@ var PushService = {
try {
uri = Services.io.newURI(serverURL);
} catch (e) {
console.warn(
lazy.console.warn(
"findService: Error creating valid URI from",
"dom.push.serverURL",
serverURL
@ -450,7 +458,7 @@ var PushService = {
},
_changeServerURL(serverURI, event, options = {}) {
console.debug("changeServerURL()");
lazy.console.debug("changeServerURL()");
switch (event) {
case UNINIT_EVENT:
@ -500,7 +508,7 @@ var PushService = {
return this._stopService(STOPPING_SERVICE_EVENT);
default:
console.error("Unexpected event in _changeServerURL", event);
lazy.console.error("Unexpected event in _changeServerURL", event);
return Promise.reject(new Error(`Unexpected event ${event}`));
}
},
@ -521,7 +529,7 @@ var PushService = {
* PUSH_SERVICE_CONNECTION_DISABLE.
*/
async init(options = {}) {
console.debug("init()");
lazy.console.debug("init()");
if (this._state > PUSH_SERVICE_UNINIT) {
return;
@ -555,7 +563,7 @@ var PushService = {
},
_startObservers() {
console.debug("startObservers()");
lazy.console.debug("startObservers()");
if (this._state != PUSH_SERVICE_ACTIVATING) {
return;
@ -580,7 +588,7 @@ var PushService = {
},
_startService(service, serverURI, options) {
console.debug("startService()");
lazy.console.debug("startService()");
if (this._state != PUSH_SERVICE_ACTIVATING) {
return Promise.reject();
@ -609,7 +617,7 @@ var PushService = {
* state is change to PUSH_SERVICE_UNINIT
*/
_stopService(event) {
console.debug("stopService()");
lazy.console.debug("stopService()");
if (this._state < PUSH_SERVICE_ACTIVATING) {
return Promise.resolve();
@ -647,7 +655,7 @@ var PushService = {
},
_stopObservers() {
console.debug("stopObservers()");
lazy.console.debug("stopObservers()");
if (this._state < PUSH_SERVICE_ACTIVATING) {
return;
@ -664,12 +672,12 @@ var PushService = {
_shutdownService() {
let promiseChangeURL = this._changeServerURL("", UNINIT_EVENT);
this._setState(PUSH_SERVICE_UNINIT);
console.debug("shutdownService: shutdown complete!");
lazy.console.debug("shutdownService: shutdown complete!");
return promiseChangeURL;
},
async uninit() {
console.debug("uninit()");
lazy.console.debug("uninit()");
if (this._state == PUSH_SERVICE_UNINIT) {
return;
@ -706,7 +714,7 @@ var PushService = {
if (!record) {
return;
}
gPushNotifier.notifySubscriptionChange(record.scope, record.principal);
lazy.gPushNotifier.notifySubscriptionChange(record.scope, record.principal);
},
/**
@ -759,7 +767,7 @@ var PushService = {
let keygen = Promise.resolve([]);
if (!record.p256dhPublicKey || !record.p256dhPrivateKey) {
keygen = PushCrypto.generateKeys();
keygen = lazy.PushCrypto.generateKeys();
}
// We do not have a encryption key. so we need to generate it. This
// is only going to happen on db upgrade from version 4 to higher.
@ -771,7 +779,7 @@ var PushService = {
record.p256dhPrivateKey = privKey;
}
if (!record.hasAuthenticationSecret()) {
record.authenticationSecret = PushCrypto.generateAuthenticationSecret();
record.authenticationSecret = lazy.PushCrypto.generateAuthenticationSecret();
}
return record;
});
@ -805,7 +813,7 @@ var PushService = {
* code, indicating whether the message was delivered successfully.
*/
receivedPushMessage(keyID, messageID, headers, data, updateFunc) {
console.debug("receivedPushMessage()");
lazy.console.debug("receivedPushMessage()");
return this._updateRecordAfterPush(keyID, updateFunc)
.then(record => {
@ -815,7 +823,7 @@ var PushService = {
let timeoutID = setTimeout(_ => {
this._updateQuota(keyID);
if (!this._updateQuotaTimeouts.delete(timeoutID)) {
console.debug(
lazy.console.debug(
"receivedPushMessage: quota update timeout missing?"
);
}
@ -825,7 +833,7 @@ var PushService = {
return this._decryptAndNotifyApp(record, messageID, headers, data);
})
.catch(error => {
console.error("receivedPushMessage: Error notifying app", error);
lazy.console.error("receivedPushMessage: Error notifying app", error);
return Ci.nsIPushErrorReporter.ACK_NOT_DELIVERED;
});
},
@ -838,10 +846,10 @@ var PushService = {
* notification was received.
*/
receivedBroadcastMessage(message, context) {
pushBroadcastService
lazy.pushBroadcastService
.receivedBroadcastMessage(message.broadcasts, context)
.catch(e => {
console.error(e);
lazy.console.error(e);
});
},
@ -890,7 +898,7 @@ var PushService = {
});
})
.then(record => {
gPushNotifier.notifySubscriptionModified(
lazy.gPushNotifier.notifySubscriptionModified(
record.scope,
record.principal
);
@ -908,7 +916,7 @@ var PushService = {
* @returns {Promise} Resolves with an ack status code.
*/
_decryptAndNotifyApp(record, messageID, headers, data) {
return PushCrypto.decrypt(
return lazy.PushCrypto.decrypt(
record.p256dhPrivateKey,
record.p256dhPublicKey,
record.authenticationSecret,
@ -917,7 +925,7 @@ var PushService = {
).then(
message => this._notifyApp(record, messageID, message),
error => {
console.warn(
lazy.console.warn(
"decryptAndNotifyApp: Error decrypting message",
record.scope,
messageID,
@ -925,7 +933,7 @@ var PushService = {
);
let message = error.format(record.scope);
gPushNotifier.notifyError(
lazy.gPushNotifier.notifyError(
record.scope,
record.principal,
message,
@ -937,13 +945,13 @@ var PushService = {
},
_updateQuota(keyID) {
console.debug("updateQuota()");
lazy.console.debug("updateQuota()");
this._db
.update(keyID, record => {
// Record may have expired from an earlier quota update.
if (record.isExpired()) {
console.debug(
lazy.console.debug(
"updateQuota: Trying to update quota for expired record",
record
);
@ -966,7 +974,7 @@ var PushService = {
Ci.nsIPushErrorReporter.UNSUBSCRIBE_QUOTA_EXCEEDED
);
} else {
gPushNotifier.notifySubscriptionModified(
lazy.gPushNotifier.notifySubscriptionModified(
record.scope,
record.principal
);
@ -977,12 +985,15 @@ var PushService = {
}
})
.catch(error => {
console.debug("updateQuota: Error while trying to update quota", error);
lazy.console.debug(
"updateQuota: Error while trying to update quota",
error
);
});
},
notificationForOriginShown(origin) {
console.debug("notificationForOriginShown()", origin);
lazy.console.debug("notificationForOriginShown()", origin);
let count;
if (this._visibleNotifications.has(origin)) {
count = this._visibleNotifications.get(origin);
@ -993,12 +1004,12 @@ var PushService = {
},
notificationForOriginClosed(origin) {
console.debug("notificationForOriginClosed()", origin);
lazy.console.debug("notificationForOriginClosed()", origin);
let count;
if (this._visibleNotifications.has(origin)) {
count = this._visibleNotifications.get(origin);
} else {
console.debug(
lazy.console.debug(
"notificationForOriginClosed: closing notification that has not been shown?"
);
return;
@ -1011,7 +1022,7 @@ var PushService = {
},
reportDeliveryError(messageID, reason) {
console.debug("reportDeliveryError()", messageID, reason);
lazy.console.debug("reportDeliveryError()", messageID, reason);
if (this._state == PUSH_SERVICE_RUNNING && this._service.isConnected()) {
// Only report errors if we're initialized and connected.
this._service.reportDeliveryError(messageID, reason);
@ -1024,15 +1035,15 @@ var PushService = {
!aPushRecord.scope ||
aPushRecord.originAttributes === undefined
) {
console.error("notifyApp: Invalid record", aPushRecord);
lazy.console.error("notifyApp: Invalid record", aPushRecord);
return Ci.nsIPushErrorReporter.ACK_NOT_DELIVERED;
}
console.debug("notifyApp()", aPushRecord.scope);
lazy.console.debug("notifyApp()", aPushRecord.scope);
// If permission has been revoked, trash the message.
if (!aPushRecord.hasPermission()) {
console.warn("notifyApp: Missing push permission", aPushRecord);
lazy.console.warn("notifyApp: Missing push permission", aPushRecord);
return Ci.nsIPushErrorReporter.ACK_NOT_DELIVERED;
}
@ -1046,14 +1057,14 @@ var PushService = {
}
if (payload) {
gPushNotifier.notifyPushWithData(
lazy.gPushNotifier.notifyPushWithData(
aPushRecord.scope,
aPushRecord.principal,
messageID,
payload
);
} else {
gPushNotifier.notifyPush(
lazy.gPushNotifier.notifyPush(
aPushRecord.scope,
aPushRecord.principal,
messageID
@ -1097,7 +1108,7 @@ var PushService = {
* the push manager, identifying the sending page and other fields.
*/
_registerWithServer(aPageRecord) {
console.debug("registerWithServer()", aPageRecord);
lazy.console.debug("registerWithServer()", aPageRecord);
return this._sendRequest("register", aPageRecord)
.then(
@ -1107,7 +1118,7 @@ var PushService = {
.then(
record => {
this._deletePendingRequest(aPageRecord);
gPushNotifier.notifySubscriptionModified(
lazy.gPushNotifier.notifySubscriptionModified(
record.scope,
record.principal
);
@ -1129,7 +1140,7 @@ var PushService = {
* from _service.request, causing the promise to be rejected instead.
*/
_onRegisterSuccess(aRecord) {
console.debug("_onRegisterSuccess()");
lazy.console.debug("_onRegisterSuccess()");
return this._db.put(aRecord).catch(error => {
// Unable to save. Destroy the subscription in the background.
@ -1146,10 +1157,10 @@ var PushService = {
* from _service.request, causing the promise to be rejected instead.
*/
_onRegisterError(reply) {
console.debug("_onRegisterError()");
lazy.console.debug("_onRegisterError()");
if (!reply.error) {
console.warn(
lazy.console.warn(
"onRegisterError: Called without valid error message!",
reply
);
@ -1169,20 +1180,22 @@ var PushService = {
},
register(aPageRecord) {
console.debug("register()", aPageRecord);
lazy.console.debug("register()", aPageRecord);
let keyPromise;
if (aPageRecord.appServerKey && aPageRecord.appServerKey.length != 0) {
let keyView = new Uint8Array(aPageRecord.appServerKey);
keyPromise = PushCrypto.validateAppServerKey(keyView).catch(error => {
// Normalize Web Crypto exceptions. `nsIPushService` will forward the
// error result to the DOM API implementation in `PushManager.cpp` or
// `Push.js`, which will convert it to the correct `DOMException`.
throw errorWithResult(
"Invalid app server key",
Cr.NS_ERROR_DOM_PUSH_INVALID_KEY_ERR
);
});
keyPromise = lazy.PushCrypto.validateAppServerKey(keyView).catch(
error => {
// Normalize Web Crypto exceptions. `nsIPushService` will forward the
// error result to the DOM API implementation in `PushManager.cpp` or
// `Push.js`, which will convert it to the correct `DOMException`.
throw errorWithResult(
"Invalid app server key",
Cr.NS_ERROR_DOM_PUSH_INVALID_KEY_ERR
);
}
);
} else {
keyPromise = Promise.resolve(null);
}
@ -1258,7 +1271,7 @@ var PushService = {
* not.
*/
unregister(aPageRecord) {
console.debug("unregister()", aPageRecord);
lazy.console.debug("unregister()", aPageRecord);
return this._getByPageRecord(aPageRecord).then(record => {
if (record === null) {
@ -1270,7 +1283,10 @@ var PushService = {
this._sendUnregister(record, reason),
this._db.delete(record.keyID).then(rec => {
if (rec) {
gPushNotifier.notifySubscriptionModified(rec.scope, rec.principal);
lazy.gPushNotifier.notifySubscriptionModified(
rec.scope,
rec.principal
);
}
}),
]).then(([success]) => success);
@ -1288,7 +1304,7 @@ var PushService = {
);
})
.catch(e => {
console.warn(
lazy.console.warn(
"clear: Error dropping subscriptions for domain",
info.domain,
e
@ -1298,7 +1314,7 @@ var PushService = {
},
registration(aPageRecord) {
console.debug("registration()");
lazy.console.debug("registration()");
return this._getByPageRecord(aPageRecord).then(record => {
if (!record) {
@ -1319,7 +1335,7 @@ var PushService = {
},
_dropExpiredRegistrations() {
console.debug("dropExpiredRegistrations()");
lazy.console.debug("dropExpiredRegistrations()");
return this._db.getAllExpired().then(records => {
return Promise.all(
@ -1334,7 +1350,7 @@ var PushService = {
}
})
.catch(error => {
console.error(
lazy.console.error(
"dropExpiredRegistrations: Error dropping registration",
record.keyID,
error
@ -1346,7 +1362,7 @@ var PushService = {
},
_onPermissionChange(subject, data) {
console.debug("onPermissionChange()");
lazy.console.debug("onPermissionChange()");
if (data == "cleared") {
return this._clearPermissions();
@ -1361,7 +1377,7 @@ var PushService = {
},
_clearPermissions() {
console.debug("clearPermissions()");
lazy.console.debug("clearPermissions()");
return this._db.clearIf(record => {
if (!record.quotaApplies()) {
@ -1377,7 +1393,7 @@ var PushService = {
},
_updatePermission(permission, type) {
console.debug("updatePermission()");
lazy.console.debug("updatePermission()");
let isAllow = permission.capability == Ci.nsIPermissionManager.ALLOW_ACTION;
let isChange = type == "added" || type == "changed";
@ -1419,7 +1435,7 @@ var PushService = {
* @param {IDBCursor} cursor The IndexedDB cursor.
*/
_permissionDenied(record, cursor) {
console.debug("permissionDenied()");
lazy.console.debug("permissionDenied()");
if (!record.quotaApplies() || record.isExpired()) {
// Ignore already-expired records.
@ -1443,7 +1459,7 @@ var PushService = {
* @param {IDBCursor} cursor The IndexedDB cursor.
*/
_permissionAllowed(record, cursor) {
console.debug("permissionAllowed()");
lazy.console.debug("permissionAllowed()");
if (!record.quotaApplies()) {
return;

Просмотреть файл

@ -9,33 +9,35 @@ const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
const lazy = {};
ChromeUtils.defineModuleGetter(
this,
lazy,
"PushDB",
"resource://gre/modules/PushDB.jsm"
);
ChromeUtils.defineModuleGetter(
this,
lazy,
"PushRecord",
"resource://gre/modules/PushRecord.jsm"
);
ChromeUtils.defineModuleGetter(
this,
lazy,
"PushCrypto",
"resource://gre/modules/PushCrypto.jsm"
);
ChromeUtils.defineModuleGetter(
this,
lazy,
"EventDispatcher",
"resource://gre/modules/Messaging.jsm"
);
ChromeUtils.defineModuleGetter(
this,
lazy,
"Preferences",
"resource://gre/modules/Preferences.jsm"
);
XPCOMUtils.defineLazyGetter(this, "Log", () => {
XPCOMUtils.defineLazyGetter(lazy, "Log", () => {
return ChromeUtils.import(
"resource://gre/modules/AndroidLog.jsm"
).AndroidLog.bind("Push");
@ -43,10 +45,10 @@ XPCOMUtils.defineLazyGetter(this, "Log", () => {
const EXPORTED_SYMBOLS = ["PushServiceAndroidGCM"];
XPCOMUtils.defineLazyGetter(this, "console", () => {
XPCOMUtils.defineLazyGetter(lazy, "console", () => {
let { ConsoleAPI } = ChromeUtils.import("resource://gre/modules/Console.jsm");
return new ConsoleAPI({
dump: Log.i,
dump: lazy.Log.i,
maxLogLevelPref: "dom.push.loglevel",
prefix: "PushServiceAndroidGCM",
});
@ -58,7 +60,7 @@ const kPUSHANDROIDGCMDB_STORE_NAME = "pushAndroidGCM";
const FXA_PUSH_SCOPE = "chrome://fxa-push";
const prefs = new Preferences("dom.push.");
const prefs = new lazy.Preferences("dom.push.");
/**
* The implementation of WebPush push backed by Android's GCM
@ -69,7 +71,7 @@ var PushServiceAndroidGCM = {
_serverURI: null,
newPushDB() {
return new PushDB(
return new lazy.PushDB(
kPUSHANDROIDGCMDB_DB_NAME,
kPUSHANDROIDGCMDB_DB_VERSION,
kPUSHANDROIDGCMDB_STORE_NAME,
@ -84,7 +86,7 @@ var PushServiceAndroidGCM = {
if (data == "dom.push.debug") {
// Reconfigure.
let debug = !!prefs.get("debug");
console.info(
lazy.console.info(
"Debug parameter changed; updating configuration with new debug",
debug
);
@ -103,19 +105,23 @@ var PushServiceAndroidGCM = {
// TODO: Use Messaging.jsm for this.
if (this._mainPushService == null) {
// Shouldn't ever happen, but let's be careful.
console.error("No main PushService! Dropping message.");
lazy.console.error("No main PushService! Dropping message.");
return;
}
if (!data) {
console.error("No data from Java! Dropping message.");
lazy.console.error("No data from Java! Dropping message.");
return;
}
data = JSON.parse(data);
console.debug("ReceivedPushMessage with data", data);
lazy.console.debug("ReceivedPushMessage with data", data);
let { headers, message } = this._messageAndHeaders(data);
console.debug("Delivering message to main PushService:", message, headers);
lazy.console.debug(
"Delivering message to main PushService:",
message,
headers
);
this._mainPushService.receivedPushMessage(
data.channelID,
"",
@ -157,7 +163,7 @@ var PushServiceAndroidGCM = {
},
_configure(serverURL, debug) {
return EventDispatcher.instance.sendRequestForResult({
return lazy.EventDispatcher.instance.sendRequestForResult({
type: "PushServiceAndroidGCM:Configure",
endpoint: serverURL.spec,
debug,
@ -165,7 +171,7 @@ var PushServiceAndroidGCM = {
},
init(options, mainPushService, serverURL) {
console.debug("init()");
lazy.console.debug("init()");
this._mainPushService = mainPushService;
this._serverURI = serverURL;
@ -173,15 +179,15 @@ var PushServiceAndroidGCM = {
Services.obs.addObserver(this, "PushServiceAndroidGCM:ReceivedPushMessage");
return this._configure(serverURL, !!prefs.get("debug")).then(() => {
EventDispatcher.instance.sendRequestForResult({
lazy.EventDispatcher.instance.sendRequestForResult({
type: "PushServiceAndroidGCM:Initialized",
});
});
},
uninit() {
console.debug("uninit()");
EventDispatcher.instance.sendRequestForResult({
lazy.console.debug("uninit()");
lazy.EventDispatcher.instance.sendRequestForResult({
type: "PushServiceAndroidGCM:Uninitialized",
});
@ -198,30 +204,30 @@ var PushServiceAndroidGCM = {
},
connect(records, broadcastListeners) {
console.debug("connect:", records);
lazy.console.debug("connect:", records);
// It's possible for the registration or subscriptions backing the
// PushService to not be registered with the underlying AndroidPushService.
// Expire those that are unrecognized.
return EventDispatcher.instance
return lazy.EventDispatcher.instance
.sendRequestForResult({
type: "PushServiceAndroidGCM:DumpSubscriptions",
})
.then(subscriptions => {
subscriptions = JSON.parse(subscriptions);
console.debug("connect:", subscriptions);
lazy.console.debug("connect:", subscriptions);
// subscriptions maps chid => subscription data.
return Promise.all(
records.map(record => {
if (subscriptions.hasOwnProperty(record.keyID)) {
console.debug("connect:", "hasOwnProperty", record.keyID);
lazy.console.debug("connect:", "hasOwnProperty", record.keyID);
return Promise.resolve();
}
console.debug("connect:", "!hasOwnProperty", record.keyID);
lazy.console.debug("connect:", "!hasOwnProperty", record.keyID);
// Subscription is known to PushService.jsm but not to AndroidPushService. Drop it.
return this._mainPushService
.dropRegistrationAndNotifyApp(record.keyID)
.catch(error => {
console.error(
lazy.console.error(
"connect: Error dropping registration",
record.keyID,
error
@ -241,11 +247,11 @@ var PushServiceAndroidGCM = {
},
disconnect() {
console.debug("disconnect");
lazy.console.debug("disconnect");
},
register(record) {
console.debug("register:", record);
lazy.console.debug("register:", record);
let ctime = Date.now();
let appServerKey = record.appServerKey
? ChromeUtils.base64URLEncode(record.appServerKey, {
@ -261,40 +267,42 @@ var PushServiceAndroidGCM = {
message.service = "fxa";
}
// Caller handles errors.
return EventDispatcher.instance.sendRequestForResult(message).then(data => {
data = JSON.parse(data);
console.debug("Got data:", data);
return PushCrypto.generateKeys().then(
exportedKeys =>
new PushRecordAndroidGCM({
// Straight from autopush.
channelID: data.channelID,
pushEndpoint: data.endpoint,
// Common to all PushRecord implementations.
scope: record.scope,
originAttributes: record.originAttributes,
ctime,
systemRecord: record.systemRecord,
// Cryptography!
p256dhPublicKey: exportedKeys[0],
p256dhPrivateKey: exportedKeys[1],
authenticationSecret: PushCrypto.generateAuthenticationSecret(),
appServerKey: record.appServerKey,
})
);
});
return lazy.EventDispatcher.instance
.sendRequestForResult(message)
.then(data => {
data = JSON.parse(data);
lazy.console.debug("Got data:", data);
return lazy.PushCrypto.generateKeys().then(
exportedKeys =>
new PushRecordAndroidGCM({
// Straight from autopush.
channelID: data.channelID,
pushEndpoint: data.endpoint,
// Common to all PushRecord implementations.
scope: record.scope,
originAttributes: record.originAttributes,
ctime,
systemRecord: record.systemRecord,
// Cryptography!
p256dhPublicKey: exportedKeys[0],
p256dhPrivateKey: exportedKeys[1],
authenticationSecret: lazy.PushCrypto.generateAuthenticationSecret(),
appServerKey: record.appServerKey,
})
);
});
},
unregister(record) {
console.debug("unregister: ", record);
return EventDispatcher.instance.sendRequestForResult({
lazy.console.debug("unregister: ", record);
return lazy.EventDispatcher.instance.sendRequestForResult({
type: "PushServiceAndroidGCM:UnsubscribeChannel",
channelID: record.keyID,
});
},
reportDeliveryError(messageID, reason) {
console.warn(
lazy.console.warn(
"reportDeliveryError: Ignoring message delivery error",
messageID,
reason
@ -303,11 +311,11 @@ var PushServiceAndroidGCM = {
};
function PushRecordAndroidGCM(record) {
PushRecord.call(this, record);
lazy.PushRecord.call(this, record);
this.channelID = record.channelID;
}
PushRecordAndroidGCM.prototype = Object.create(PushRecord.prototype, {
PushRecordAndroidGCM.prototype = Object.create(lazy.PushRecord.prototype, {
keyID: {
get() {
return this.channelID;

Просмотреть файл

@ -23,7 +23,9 @@ const { PushCrypto } = ChromeUtils.import(
var EXPORTED_SYMBOLS = ["PushServiceHttp2"];
XPCOMUtils.defineLazyGetter(this, "console", () => {
const lazy = {};
XPCOMUtils.defineLazyGetter(lazy, "console", () => {
let { ConsoleAPI } = ChromeUtils.import("resource://gre/modules/Console.jsm");
return new ConsoleAPI({
maxLogLevelPref: "dom.push.loglevel",
@ -46,7 +48,7 @@ const kPUSHHTTP2DB_STORE_NAME = "pushHttp2";
* It's easier to stop listening than to have checks at specific points.
*/
var PushSubscriptionListener = function(pushService, uri) {
console.debug("PushSubscriptionListener()");
lazy.console.debug("PushSubscriptionListener()");
this._pushService = pushService;
this.uri = uri;
};
@ -62,12 +64,12 @@ PushSubscriptionListener.prototype = {
},
onStartRequest(aRequest) {
console.debug("PushSubscriptionListener: onStartRequest()");
lazy.console.debug("PushSubscriptionListener: onStartRequest()");
// We do not do anything here.
},
onDataAvailable(aRequest, aStream, aOffset, aCount) {
console.debug("PushSubscriptionListener: onDataAvailable()");
lazy.console.debug("PushSubscriptionListener: onDataAvailable()");
// Nobody should send data, but just to be sure, otherwise necko will
// complain.
if (aCount === 0) {
@ -83,7 +85,7 @@ PushSubscriptionListener.prototype = {
},
onStopRequest(aRequest, aStatusCode) {
console.debug("PushSubscriptionListener: onStopRequest()");
lazy.console.debug("PushSubscriptionListener: onStopRequest()");
if (!this._pushService) {
return;
}
@ -96,7 +98,7 @@ PushSubscriptionListener.prototype = {
},
onPush(associatedChannel, pushChannel) {
console.debug("PushSubscriptionListener: onPush()");
lazy.console.debug("PushSubscriptionListener: onPush()");
var pushChannelListener = new PushChannelListener(this);
pushChannel.asyncOpen(pushChannelListener);
},
@ -111,7 +113,7 @@ PushSubscriptionListener.prototype = {
* OnDataAvailable and send to the app in OnStopRequest.
*/
var PushChannelListener = function(pushSubscriptionListener) {
console.debug("PushChannelListener()");
lazy.console.debug("PushChannelListener()");
this._mainListener = pushSubscriptionListener;
this._message = [];
this._ackUri = null;
@ -123,7 +125,7 @@ PushChannelListener.prototype = {
},
onDataAvailable(aRequest, aStream, aOffset, aCount) {
console.debug("PushChannelListener: onDataAvailable()");
lazy.console.debug("PushChannelListener: onDataAvailable()");
if (aCount === 0) {
return;
@ -140,7 +142,7 @@ PushChannelListener.prototype = {
},
onStopRequest(aRequest, aStatusCode) {
console.debug(
lazy.console.debug(
"PushChannelListener: onStopRequest()",
"status code",
aStatusCode
@ -216,7 +218,7 @@ var SubscriptionListener = function(
aServerURI,
aPushServiceHttp2
) {
console.debug("SubscriptionListener()");
lazy.console.debug("SubscriptionListener()");
this._subInfo = aSubInfo;
this._resolve = aResolve;
this._reject = aReject;
@ -232,7 +234,7 @@ SubscriptionListener.prototype = {
onDataAvailable(aRequest, aStream, aOffset, aCount) {},
onStopRequest(aRequest, aStatus) {
console.debug("SubscriptionListener: onStopRequest()");
lazy.console.debug("SubscriptionListener: onStopRequest()");
// Check if pushService is still active.
if (!this._service.hasmainPushService()) {
@ -277,7 +279,7 @@ SubscriptionListener.prototype = {
return;
}
console.debug("onStopRequest: subscriptionUri", subscriptionUri);
lazy.console.debug("onStopRequest: subscriptionUri", subscriptionUri);
var linkList;
try {
@ -302,7 +304,10 @@ SubscriptionListener.prototype = {
try {
Services.io.newURI(subscriptionUri);
} catch (e) {
console.error("onStopRequest: Invalid subscription URI", subscriptionUri);
lazy.console.error(
"onStopRequest: Invalid subscription URI",
subscriptionUri
);
this._reject(
new Error("Invalid subscription endpoint: " + subscriptionUri)
);
@ -328,7 +333,7 @@ SubscriptionListener.prototype = {
clearTimeout(this._retryTimeoutID);
this._retryTimeoutID = null;
} else {
console.debug(
lazy.console.debug(
"SubscriptionListener.abortRetry: aborting non-existent retry?"
);
}
@ -377,8 +382,8 @@ function linkParser(linkHeader, serverURI) {
}
});
console.debug("linkParser: pushEndpoint", pushEndpoint);
console.debug("linkParser: pushReceiptEndpoint", pushReceiptEndpoint);
lazy.console.debug("linkParser: pushEndpoint", pushEndpoint);
lazy.console.debug("linkParser: pushReceiptEndpoint", pushReceiptEndpoint);
// Missing pushReceiptEndpoint is allowed.
if (!pushEndpoint) {
throw new Error("Missing push endpoint");
@ -458,7 +463,7 @@ var PushServiceHttp2 = {
* Subscribe new resource.
*/
register(aRecord) {
console.debug("subscribeResource()");
lazy.console.debug("subscribeResource()");
return this._subscribeResourceInternal({
record: aRecord,
@ -482,7 +487,7 @@ var PushServiceHttp2 = {
},
_subscribeResourceInternal(aSubInfo) {
console.debug("subscribeResourceInternal()");
lazy.console.debug("subscribeResourceInternal()");
return new Promise((resolve, reject) => {
var listener = new SubscriptionListener(
@ -517,7 +522,7 @@ var PushServiceHttp2 = {
* We can't do anything about it if it fails, so we don't listen for response.
*/
_unsubscribeResource(aSubscriptionUri) {
console.debug("unsubscribeResource()");
lazy.console.debug("unsubscribeResource()");
return this._deleteResource(aSubscriptionUri);
},
@ -526,9 +531,9 @@ var PushServiceHttp2 = {
* Start listening for messages.
*/
_listenForMsgs(aSubscriptionUri) {
console.debug("listenForMsgs()", aSubscriptionUri);
lazy.console.debug("listenForMsgs()", aSubscriptionUri);
if (!this._conns[aSubscriptionUri]) {
console.warn(
lazy.console.warn(
"listenForMsgs: We do not have this subscription",
aSubscriptionUri
);
@ -546,7 +551,7 @@ var PushServiceHttp2 = {
try {
chan.asyncOpen(listener);
} catch (e) {
console.error(
lazy.console.error(
"listenForMsgs: Error connecting to push server.",
"asyncOpen failed",
e
@ -563,12 +568,12 @@ var PushServiceHttp2 = {
},
_ackMsgRecv(aAckUri) {
console.debug("ackMsgRecv()", aAckUri);
lazy.console.debug("ackMsgRecv()", aAckUri);
return this._deleteResource(aAckUri);
},
init(aOptions, aMainPushService, aServerURL) {
console.debug("init()");
lazy.console.debug("init()");
this._mainPushService = aMainPushService;
this._serverURI = aServerURL;
@ -576,7 +581,7 @@ var PushServiceHttp2 = {
},
_retryAfterBackoff(aSubscriptionUri, retryAfter) {
console.debug("retryAfterBackoff()");
lazy.console.debug("retryAfterBackoff()");
var resetRetryCount = prefs.getIntPref("http2.reset_retry_count_after_ms");
// If it was running for some time, reset retry counter.
@ -616,12 +621,12 @@ var PushServiceHttp2 = {
retryAfter
);
console.debug("retryAfterBackoff: Retry in", retryAfter);
lazy.console.debug("retryAfterBackoff: Retry in", retryAfter);
},
// Close connections.
_shutdownConnections(deleteInfo) {
console.debug("shutdownConnections()");
lazy.console.debug("shutdownConnections()");
for (let subscriptionUri in this._conns) {
if (this._conns[subscriptionUri]) {
@ -650,7 +655,7 @@ var PushServiceHttp2 = {
// Start listening if subscriptions present.
startConnections(aSubscriptions) {
console.debug("startConnections()", aSubscriptions.length);
lazy.console.debug("startConnections()", aSubscriptions.length);
for (let i = 0; i < aSubscriptions.length; i++) {
let record = aSubscriptions[i];
@ -659,7 +664,7 @@ var PushServiceHttp2 = {
this._startSingleConnection(record);
},
error => {
console.error(
lazy.console.error(
"startConnections: Error updating record",
record.keyID,
error
@ -670,7 +675,7 @@ var PushServiceHttp2 = {
},
_startSingleConnection(record) {
console.debug("_startSingleConnection()");
lazy.console.debug("_startSingleConnection()");
if (typeof this._conns[record.subscriptionUri] != "object") {
this._conns[record.subscriptionUri] = {
channel: null,
@ -686,7 +691,7 @@ var PushServiceHttp2 = {
// Close connection and notify apps that subscription are gone.
_shutdownSubscription(aSubscriptionUri) {
console.debug("shutdownSubscriptions()");
lazy.console.debug("shutdownSubscriptions()");
if (typeof this._conns[aSubscriptionUri] == "object") {
if (this._conns[aSubscriptionUri].listener) {
@ -703,7 +708,7 @@ var PushServiceHttp2 = {
},
uninit() {
console.debug("uninit()");
lazy.console.debug("uninit()");
this._abortPendingSubscriptionRetries();
this._shutdownConnections(true);
this._mainPushService = null;
@ -720,7 +725,7 @@ var PushServiceHttp2 = {
},
reportDeliveryError(messageID, reason) {
console.warn(
lazy.console.warn(
"reportDeliveryError: Ignoring message delivery error",
messageID,
reason
@ -755,7 +760,7 @@ var PushServiceHttp2 = {
},
connOnStop(aRequest, aSuccess, aSubscriptionUri) {
console.debug("connOnStop() succeeded", aSuccess);
lazy.console.debug("connOnStop() succeeded", aSuccess);
var conn = this._conns[aSubscriptionUri];
if (!conn) {
@ -790,12 +795,12 @@ var PushServiceHttp2 = {
removeListenerPendingRetry(aListener) {
if (!this._listenersPendingRetry.remove(aListener)) {
console.debug("removeListenerPendingRetry: listener not in list?");
lazy.console.debug("removeListenerPendingRetry: listener not in list?");
}
},
_pushChannelOnStop(aUri, aAckUri, aHeaders, aMessage) {
console.debug("pushChannelOnStop()");
lazy.console.debug("pushChannelOnStop()");
this._mainPushService
.receivedPushMessage(aUri, "", aHeaders, aMessage, record => {
@ -804,7 +809,7 @@ var PushServiceHttp2 = {
})
.then(_ => this._ackMsgRecv(aAckUri))
.catch(err => {
console.error("pushChannelOnStop: Error receiving message", err);
lazy.console.error("pushChannelOnStop: Error receiving message", err);
});
},
};

Просмотреть файл

@ -17,13 +17,15 @@ const { PushCrypto } = ChromeUtils.import(
"resource://gre/modules/PushCrypto.jsm"
);
const lazy = {};
ChromeUtils.defineModuleGetter(
this,
lazy,
"pushBroadcastService",
"resource://gre/modules/PushBroadcastService.jsm"
);
ChromeUtils.defineModuleGetter(
this,
lazy,
"ObjectUtils",
"resource://gre/modules/ObjectUtils.jsm"
);
@ -60,7 +62,7 @@ const prefs = Services.prefs.getBranch("dom.push.");
const EXPORTED_SYMBOLS = ["PushServiceWebSocket"];
XPCOMUtils.defineLazyGetter(this, "console", () => {
XPCOMUtils.defineLazyGetter(lazy, "console", () => {
let { ConsoleAPI } = ChromeUtils.import("resource://gre/modules/Console.jsm");
return new ConsoleAPI({
maxLogLevelPref: "dom.push.loglevel",
@ -162,7 +164,7 @@ var PushServiceWebSocket = {
* dropped on reconnect.
*/
_onUAIDChanged() {
console.debug("onUAIDChanged()");
lazy.console.debug("onUAIDChanged()");
this._shutdownWS();
this._startBackoffTimer();
@ -170,7 +172,7 @@ var PushServiceWebSocket = {
/** Handles a ping, backoff, or request timeout timer event. */
_onTimerFired(timer) {
console.debug("onTimerFired()");
lazy.console.debug("onTimerFired()");
if (timer == this._pingTimer) {
this._sendPing();
@ -178,7 +180,7 @@ var PushServiceWebSocket = {
}
if (timer == this._backoffTimer) {
console.debug("onTimerFired: Reconnecting after backoff");
lazy.console.debug("onTimerFired: Reconnecting after backoff");
this._beginWSSetup();
return;
}
@ -194,21 +196,21 @@ var PushServiceWebSocket = {
* does not respond within the timeout, the client will reconnect.
*/
_sendPing() {
console.debug("sendPing()");
lazy.console.debug("sendPing()");
this._startRequestTimeoutTimer();
try {
this._wsSendMessage({});
this._lastPingTime = Date.now();
} catch (e) {
console.debug("sendPing: Error sending ping", e);
lazy.console.debug("sendPing: Error sending ping", e);
this._reconnect();
}
},
/** Times out any pending requests. */
_timeOutRequests() {
console.debug("timeOutRequests()");
lazy.console.debug("timeOutRequests()");
if (!this._hasPendingRequests()) {
// Cancel the repeating timer and exit early if we aren't waiting for
@ -227,7 +229,7 @@ var PushServiceWebSocket = {
this._lastPingTime > 0 &&
now - this._lastPingTime > this._requestTimeout
) {
console.debug("timeOutRequests: Did not receive pong in time");
lazy.console.debug("timeOutRequests: Did not receive pong in time");
requestTimedOut = true;
} else {
for (let [key, request] of this._pendingRequests) {
@ -256,14 +258,14 @@ var PushServiceWebSocket = {
set _UAID(newID) {
if (typeof newID !== "string") {
console.warn(
lazy.console.warn(
"Got invalid, non-string UAID",
newID,
"Not updating userAgentID"
);
return;
}
console.debug("New _UAID", newID);
lazy.console.debug("New _UAID", newID);
prefs.setStringPref("userAgentID", newID);
},
@ -311,19 +313,19 @@ var PushServiceWebSocket = {
*/
_wsSendMessage(msg) {
if (!this._ws) {
console.warn(
lazy.console.warn(
"wsSendMessage: No WebSocket initialized.",
"Cannot send a message"
);
return;
}
msg = JSON.stringify(msg);
console.debug("wsSendMessage: Sending message", msg);
lazy.console.debug("wsSendMessage: Sending message", msg);
this._ws.sendMsg(msg);
},
init(options, mainPushService, serverURI) {
console.debug("init()");
lazy.console.debug("init()");
this._mainPushService = mainPushService;
this._serverURI = serverURI;
@ -343,13 +345,13 @@ var PushServiceWebSocket = {
},
_reconnect() {
console.debug("reconnect()");
lazy.console.debug("reconnect()");
this._shutdownWS(false);
this._startBackoffTimer();
},
_shutdownWS(shouldCancelPending = true) {
console.debug("shutdownWS()");
lazy.console.debug("shutdownWS()");
if (this._currentState == STATE_READY) {
prefs.removeObserver("userAgentID", this);
@ -413,7 +415,7 @@ var PushServiceWebSocket = {
* cancelled), so the connection won't be reset.
*/
_startBackoffTimer() {
console.debug("startBackoffTimer()");
lazy.console.debug("startBackoffTimer()");
// Calculate new timeout, but cap it to pingInterval.
let retryTimeout =
@ -422,7 +424,7 @@ var PushServiceWebSocket = {
this._retryFailCount++;
console.debug(
lazy.console.debug(
"startBackoffTimer: Retry in",
retryTimeout,
"Try number",
@ -476,14 +478,14 @@ var PushServiceWebSocket = {
_makeWebSocket(uri) {
if (!prefs.getBoolPref("connection.enabled")) {
console.warn(
lazy.console.warn(
"makeWebSocket: connection.enabled is not set to true.",
"Aborting."
);
return null;
}
if (Services.io.offline) {
console.warn("makeWebSocket: Network is offline.");
lazy.console.warn("makeWebSocket: Network is offline.");
return null;
}
let contractId =
@ -506,9 +508,9 @@ var PushServiceWebSocket = {
},
_beginWSSetup() {
console.debug("beginWSSetup()");
lazy.console.debug("beginWSSetup()");
if (this._currentState != STATE_SHUT_DOWN) {
console.error(
lazy.console.error(
"_beginWSSetup: Not in shutdown state! Current state",
this._currentState
);
@ -530,7 +532,7 @@ var PushServiceWebSocket = {
}
this._ws = socket.QueryInterface(Ci.nsIWebSocketChannel);
console.debug("beginWSSetup: Connecting to", uri.spec);
lazy.console.debug("beginWSSetup: Connecting to", uri.spec);
this._wsListener = new PushWebSocketListener(this);
this._ws.protocol = "push-notification";
@ -540,7 +542,7 @@ var PushServiceWebSocket = {
this._ws.asyncOpen(uri, uri.spec, {}, 0, this._wsListener, null);
this._currentState = STATE_WAITING_FOR_WS_START;
} catch (e) {
console.error(
lazy.console.error(
"beginWSSetup: Error opening websocket.",
"asyncOpen failed",
e
@ -550,7 +552,7 @@ var PushServiceWebSocket = {
},
connect(broadcastListeners) {
console.debug("connect()", broadcastListeners);
lazy.console.debug("connect()", broadcastListeners);
this._broadcastListeners = broadcastListeners;
this._beginWSSetup();
},
@ -563,9 +565,9 @@ var PushServiceWebSocket = {
* Protocol handler invoked by server message.
*/
_handleHelloReply(reply) {
console.debug("handleHelloReply()");
lazy.console.debug("handleHelloReply()");
if (this._currentState != STATE_WAITING_FOR_HELLO) {
console.error(
lazy.console.error(
"handleHelloReply: Unexpected state",
this._currentState,
"(expected STATE_WAITING_FOR_HELLO)"
@ -575,20 +577,20 @@ var PushServiceWebSocket = {
}
if (typeof reply.uaid !== "string") {
console.error("handleHelloReply: Received invalid UAID", reply.uaid);
lazy.console.error("handleHelloReply: Received invalid UAID", reply.uaid);
this._shutdownWS();
return;
}
if (reply.uaid === "") {
console.error("handleHelloReply: Received empty UAID");
lazy.console.error("handleHelloReply: Received empty UAID");
this._shutdownWS();
return;
}
// To avoid sticking extra large values sent by an evil server into prefs.
if (reply.uaid.length > 128) {
console.error(
lazy.console.error(
"handleHelloReply: UAID received from server was too long",
reply.uaid
);
@ -610,10 +612,10 @@ var PushServiceWebSocket = {
prefs.addObserver("userAgentID", this);
// Handle broadcasts received in response to the "hello" message.
if (!ObjectUtils.isEmpty(reply.broadcasts)) {
if (!lazy.ObjectUtils.isEmpty(reply.broadcasts)) {
// The reply isn't technically a broadcast message, but it has
// the shape of a broadcast message (it has a broadcasts field).
const context = { phase: pushBroadcastService.PHASES.HELLO };
const context = { phase: lazy.pushBroadcastService.PHASES.HELLO };
this._mainPushService.receivedBroadcastMessage(reply, context);
}
@ -625,7 +627,7 @@ var PushServiceWebSocket = {
Promise.all(
records.map(record =>
this._mainPushService.ensureCrypto(record).catch(error => {
console.error(
lazy.console.error(
"finishHandshake: Error updating record",
record.keyID,
error
@ -647,7 +649,7 @@ var PushServiceWebSocket = {
// workers if we receive a new UAID. This ensures we expunge all stale
// registrations if the `userAgentID` pref is reset.
if (this._UAID != reply.uaid) {
console.debug("handleHelloReply: Received new UAID");
lazy.console.debug("handleHelloReply: Received new UAID");
this._mainPushService
.dropUnexpiredRegistrations()
@ -664,7 +666,7 @@ var PushServiceWebSocket = {
* Protocol handler invoked by server message.
*/
_handleRegisterReply(reply) {
console.debug("handleRegisterReply()");
lazy.console.debug("handleRegisterReply()");
let tmp = this._takeRequestForReply(reply);
if (!tmp) {
@ -691,7 +693,10 @@ var PushServiceWebSocket = {
});
tmp.resolve(record);
} else {
console.error("handleRegisterReply: Unexpected server response", reply);
lazy.console.error(
"handleRegisterReply: Unexpected server response",
reply
);
tmp.reject(
new Error("Wrong status code for register reply: " + reply.status)
);
@ -699,7 +704,7 @@ var PushServiceWebSocket = {
},
_handleUnregisterReply(reply) {
console.debug("handleUnregisterReply()");
lazy.console.debug("handleUnregisterReply()");
let request = this._takeRequestForReply(reply);
if (!request) {
@ -713,7 +718,7 @@ var PushServiceWebSocket = {
_handleDataUpdate(update) {
let promise;
if (typeof update.channelID != "string") {
console.warn(
lazy.console.warn(
"handleDataUpdate: Discarding update without channel ID",
update
);
@ -725,7 +730,7 @@ var PushServiceWebSocket = {
// the message. In that case, the server will re-send the message on
// reconnect.
if (record.hasRecentMessageID(update.version)) {
console.warn(
lazy.console.warn(
"handleDataUpdate: Ignoring duplicate message",
update.version
);
@ -761,7 +766,7 @@ var PushServiceWebSocket = {
this._sendAck(update.channelID, update.version, status);
},
err => {
console.error(
lazy.console.error(
"handleDataUpdate: Error delivering message",
update,
err
@ -774,7 +779,7 @@ var PushServiceWebSocket = {
}
)
.catch(err => {
console.error(
lazy.console.error(
"handleDataUpdate: Error acknowledging message",
update,
err
@ -786,23 +791,26 @@ var PushServiceWebSocket = {
* Protocol handler invoked by server message.
*/
_handleNotificationReply(reply) {
console.debug("handleNotificationReply()");
lazy.console.debug("handleNotificationReply()");
if (this._dataEnabled) {
this._handleDataUpdate(reply);
return;
}
if (typeof reply.updates !== "object") {
console.warn("handleNotificationReply: Missing updates", reply.updates);
lazy.console.warn(
"handleNotificationReply: Missing updates",
reply.updates
);
return;
}
console.debug("handleNotificationReply: Got updates", reply.updates);
lazy.console.debug("handleNotificationReply: Got updates", reply.updates);
for (let i = 0; i < reply.updates.length; i++) {
let update = reply.updates[i];
console.debug("handleNotificationReply: Handling update", update);
lazy.console.debug("handleNotificationReply: Handling update", update);
if (typeof update.channelID !== "string") {
console.debug(
lazy.console.debug(
"handleNotificationReply: Invalid update at index",
i,
update
@ -811,7 +819,7 @@ var PushServiceWebSocket = {
}
if (update.version === undefined) {
console.debug("handleNotificationReply: Missing version", update);
lazy.console.debug("handleNotificationReply: Missing version", update);
continue;
}
@ -830,7 +838,7 @@ var PushServiceWebSocket = {
},
_handleBroadcastReply(reply) {
let phase = pushBroadcastService.PHASES.BROADCAST;
let phase = lazy.pushBroadcastService.PHASES.BROADCAST;
// Check if this reply is the result of registration.
for (const id of Object.keys(reply.broadcasts)) {
const wasRegistering = this._currentlyRegistering.delete(id);
@ -839,7 +847,7 @@ var PushServiceWebSocket = {
// then we consider the phase to be REGISTER for all of them.
// It is acceptable since registrations do not happen so often,
// and are all very likely to occur soon after browser startup.
phase = pushBroadcastService.PHASES.REGISTER;
phase = lazy.pushBroadcastService.PHASES.REGISTER;
}
}
const context = { phase };
@ -847,7 +855,7 @@ var PushServiceWebSocket = {
},
reportDeliveryError(messageID, reason) {
console.debug("reportDeliveryError()");
lazy.console.debug("reportDeliveryError()");
let code = kDELIVERY_REASON_TO_CODE[reason];
if (!code) {
throw new Error("Invalid delivery error reason");
@ -857,7 +865,7 @@ var PushServiceWebSocket = {
},
_sendAck(channelID, version, status) {
console.debug("sendAck()");
lazy.console.debug("sendAck()");
let code = kACK_STATUS_TO_CODE[status];
if (!code) {
throw new Error("Invalid ack status");
@ -875,7 +883,7 @@ var PushServiceWebSocket = {
},
register(record) {
console.debug("register() ", record);
lazy.console.debug("register() ", record);
let data = { channelID: this._generateID(), messageType: "register" };
@ -900,7 +908,7 @@ var PushServiceWebSocket = {
},
unregister(record, reason) {
console.debug("unregister() ", record, reason);
lazy.console.debug("unregister() ", record, reason);
return Promise.resolve().then(_ => {
let code = kUNREGISTER_REASON_TO_CODE[reason];
@ -921,7 +929,7 @@ var PushServiceWebSocket = {
_notifyRequestQueue: null,
_queue: null,
_enqueue(op) {
console.debug("enqueue()");
lazy.console.debug("enqueue()");
if (!this._queue) {
this._queue = this._queueStart;
}
@ -931,7 +939,7 @@ var PushServiceWebSocket = {
/** Sends a request to the server. */
_send(data) {
if (this._currentState != STATE_READY) {
console.warn(
lazy.console.warn(
"send: Unexpected state; ignoring message",
this._currentState
);
@ -944,7 +952,7 @@ var PushServiceWebSocket = {
// If we're expecting a reply, check that we haven't cancelled the request.
let key = this._makePendingRequestKey(data);
if (!this._pendingRequests.has(key)) {
console.log("send: Request cancelled; ignoring message", key);
lazy.console.log("send: Request cancelled; ignoring message", key);
return;
}
this._wsSendMessage(data);
@ -969,7 +977,7 @@ var PushServiceWebSocket = {
/** Queues an outgoing request, establishing a connection if necessary. */
_queueRequest(data) {
console.debug("queueRequest()", data);
lazy.console.debug("queueRequest()", data);
if (this._currentState == STATE_READY) {
// If we're ready, no need to queue; just send the request.
@ -1007,12 +1015,17 @@ var PushServiceWebSocket = {
},
_receivedUpdate(aChannelID, aLatestVersion) {
console.debug("receivedUpdate: Updating", aChannelID, "->", aLatestVersion);
lazy.console.debug(
"receivedUpdate: Updating",
aChannelID,
"->",
aLatestVersion
);
this._mainPushService
.receivedPushMessage(aChannelID, "", null, null, record => {
if (record.version === null || record.version < aLatestVersion) {
console.debug(
lazy.console.debug(
"receivedUpdate: Version changed for",
aChannelID,
aLatestVersion
@ -1020,7 +1033,7 @@ var PushServiceWebSocket = {
record.version = aLatestVersion;
return record;
}
console.debug(
lazy.console.debug(
"receivedUpdate: No significant version change for",
aChannelID,
aLatestVersion
@ -1031,7 +1044,7 @@ var PushServiceWebSocket = {
this._sendAck(aChannelID, aLatestVersion, status);
})
.catch(err => {
console.error(
lazy.console.error(
"receivedUpdate: Error acknowledging message",
aChannelID,
aLatestVersion,
@ -1042,10 +1055,10 @@ var PushServiceWebSocket = {
// begin Push protocol handshake
_wsOnStart(context) {
console.debug("wsOnStart()");
lazy.console.debug("wsOnStart()");
if (this._currentState != STATE_WAITING_FOR_WS_START) {
console.error(
lazy.console.error(
"wsOnStart: NOT in STATE_WAITING_FOR_WS_START. Current",
"state",
this._currentState,
@ -1059,7 +1072,7 @@ var PushServiceWebSocket = {
.then(
records => this._sendHello(records),
err => {
console.warn(
lazy.console.warn(
"Error fetching existing records before handshake; assuming none",
err
);
@ -1068,7 +1081,7 @@ var PushServiceWebSocket = {
)
.catch(err => {
// If we failed to send the handshake, back off and reconnect.
console.warn("Failed to send handshake; reconnecting", err);
lazy.console.warn("Failed to send handshake; reconnecting", err);
this._reconnect();
});
},
@ -1109,10 +1122,13 @@ var PushServiceWebSocket = {
* NS_BASE_STREAM_CLOSED, even on a successful close.
*/
_wsOnStop(context, statusCode) {
console.debug("wsOnStop()");
lazy.console.debug("wsOnStop()");
if (statusCode != Cr.NS_OK && !this._skipReconnect) {
console.debug("wsOnStop: Reconnecting after socket error", statusCode);
lazy.console.debug(
"wsOnStop: Reconnecting after socket error",
statusCode
);
this._reconnect();
return;
}
@ -1121,7 +1137,7 @@ var PushServiceWebSocket = {
},
_wsOnMessageAvailable(context, message) {
console.debug("wsOnMessageAvailable()", message);
lazy.console.debug("wsOnMessageAvailable()", message);
// Clearing the last ping time indicates we're no longer waiting for a pong.
this._lastPingTime = 0;
@ -1130,7 +1146,7 @@ var PushServiceWebSocket = {
try {
reply = JSON.parse(message);
} catch (e) {
console.warn("wsOnMessageAvailable: Invalid JSON", message, e);
lazy.console.warn("wsOnMessageAvailable: Invalid JSON", message, e);
return;
}
@ -1145,7 +1161,7 @@ var PushServiceWebSocket = {
reply.messageType === "ping" ||
typeof reply.messageType != "string"
) {
console.debug("wsOnMessageAvailable: Pong received");
lazy.console.debug("wsOnMessageAvailable: Pong received");
doNotHandle = true;
}
@ -1175,7 +1191,7 @@ var PushServiceWebSocket = {
reply.messageType.slice(1).toLowerCase();
if (!handlers.includes(handlerName)) {
console.warn(
lazy.console.warn(
"wsOnMessageAvailable: No whitelisted handler",
handlerName,
"for message",
@ -1187,7 +1203,7 @@ var PushServiceWebSocket = {
let handler = "_handle" + handlerName + "Reply";
if (typeof this[handler] !== "function") {
console.warn(
lazy.console.warn(
"wsOnMessageAvailable: Handler",
handler,
"whitelisted but not implemented"
@ -1209,10 +1225,10 @@ var PushServiceWebSocket = {
* request.
*/
_wsOnServerClose(context, aStatusCode, aReason) {
console.debug("wsOnServerClose()", aStatusCode, aReason);
lazy.console.debug("wsOnServerClose()", aStatusCode, aReason);
if (aStatusCode == kBACKOFF_WS_STATUS_CODE) {
console.debug("wsOnServerClose: Skipping automatic reconnect");
lazy.console.debug("wsOnServerClose: Skipping automatic reconnect");
this._skipReconnect = true;
}
},