author | Dorel Luca <dluca@mozilla.com> |
Fri, 13 Sep 2019 00:42:28 +0300 | |
changeset 492912 | e2f842a491c9dee26d4f47c57c9ac7e7c29428e3 |
parent 492911 | 63a10d0c96ce1e86e1f7bffffb9b3b20b003a090 |
child 492913 | 641f75b6c5d8d475ea7645aca80cb7237764cead |
push id | 95233 |
push user | dluca@mozilla.com |
push date | Thu, 12 Sep 2019 21:46:41 +0000 |
treeherder | autoland@e2f842a491c9 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 1369436 |
milestone | 71.0a1 |
backs out | a956d11fef6eae7ba0f9fe2f5219ed9df3c9a713 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/browser/base/content/test/performance/browser_startup.js +++ b/browser/base/content/test/performance/browser_startup.js @@ -31,16 +31,18 @@ const startupPhases = { "resource:///modules/BrowserGlue.jsm", "resource://gre/modules/AppConstants.jsm", "resource://gre/modules/ActorManagerParent.jsm", "resource://gre/modules/CustomElementsListener.jsm", "resource://gre/modules/ExtensionUtils.jsm", "resource://gre/modules/MainProcessSingleton.jsm", "resource://gre/modules/XPCOMUtils.jsm", "resource://gre/modules/Services.jsm", + // Bugs to fix: The following components shouldn't be initialized that early. + "resource://gre/modules/PushComponents.jsm", // bug 1369436 ]), }, }, // For the following phases of startup we have only a black list for now // We are at this phase after creating the first browser window (ie. after final-ui-startup). "before opening first browser window": { @@ -75,17 +77,16 @@ const startupPhases = { // We are at this phase once we are ready to handle user events. // Anything loaded at this phase or before gets in the way of the user // interacting with the first browser window. "before handling user events": { blacklist: { components: new Set([ "PageIconProtocolHandler.js", "PlacesCategoriesStarter.js", - "PushComponents.jsm", "nsPlacesExpiration.js", ]), modules: new Set([ // Bug 1391495 - BrowserWindowTracker.jsm is intermittently used. // "resource:///modules/BrowserWindowTracker.jsm", "resource://gre/modules/BookmarkHTMLUtils.jsm", "resource://gre/modules/Bookmarks.jsm", "resource://gre/modules/ContextualIdentityService.jsm",
--- a/browser/components/BrowserGlue.jsm +++ b/browser/components/BrowserGlue.jsm @@ -15,22 +15,16 @@ const { AppConstants } = ChromeUtils.imp ); ChromeUtils.defineModuleGetter( this, "ActorManagerParent", "resource://gre/modules/ActorManagerParent.jsm" ); -ChromeUtils.defineModuleGetter( - this, - "PushService", - "resource://gre/modules/PushService.jsm" -); - const PREF_PDFJS_ENABLED_CACHE_STATE = "pdfjs.enabledCache.state"; let ACTORS = { BrowserTab: { parent: { moduleURI: "resource:///actors/BrowserTabParent.jsm", }, child: { @@ -2002,21 +1996,16 @@ BrowserGlue.prototype = { * to the other ones scheduled together. */ _scheduleStartupIdleTasks() { Services.tm.idleDispatchToMainThread(async () => { await ContextualIdentityService.load(); Discovery.update(); }); - // Begin listening for incoming push messages. - Services.tm.idleDispatchToMainThread(() => { - PushService.ensureReady(); - }); - Services.tm.idleDispatchToMainThread(() => { let enableCertErrorUITelemetry = Services.prefs.getBoolPref( "security.certerrors.recordEventTelemetry", false ); Services.telemetry.setEventRecordingEnabled( "security.ui.certerror", enableCertErrorUITelemetry
--- a/dom/push/PushComponents.jsm +++ b/dom/push/PushComponents.jsm @@ -64,32 +64,41 @@ PushServiceBase.prototype = { Ci.nsIPushQuotaManager, Ci.nsIPushErrorReporter, ]), pushTopic: OBSERVER_TOPIC_PUSH, subscriptionChangeTopic: OBSERVER_TOPIC_SUBSCRIPTION_CHANGE, subscriptionModifiedTopic: OBSERVER_TOPIC_SUBSCRIPTION_MODIFIED, - ensureReady() {}, + _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; + } if (topic === "android-push-service") { // Load PushService immediately. - this.ensureReady(); + this._handleReady(); } }, _deliverSubscription(request, props) { if (!props) { request.onPushSubscription(Cr.NS_OK, null); return; } @@ -251,17 +260,17 @@ Object.assign(PushServiceParent.prototyp requestID: data.requestID, result: error.result, }); } ) .catch(Cu.reportError); }, - ensureReady() { + _handleReady() { this.service.init(); }, _toPageRecord(principal, data) { if (!data.scope) { throw new Error("Invalid page record: missing scope"); } if (!principal) {
--- a/dom/push/PushCrypto.jsm +++ b/dom/push/PushCrypto.jsm @@ -10,17 +10,17 @@ const { XPCOMUtils } = ChromeUtils.impor ); XPCOMUtils.defineLazyGetter(this, "gDOMBundle", () => Services.strings.createBundle("chrome://global/locale/dom/dom.properties") ); XPCOMUtils.defineLazyGlobalGetters(this, ["crypto"]); -const EXPORTED_SYMBOLS = ["PushCrypto"]; +const EXPORTED_SYMBOLS = ["PushCrypto", "concatArray"]; const UTF8 = new TextEncoder("utf-8"); const ECDH_KEY = { name: "ECDH", namedCurve: "P-256" }; const ECDSA_KEY = { name: "ECDSA", namedCurve: "P-256" }; const HMAC_SHA256 = { name: "HMAC", hash: "SHA-256" }; const NONCE_INFO = UTF8.encode("Content-Encoding: nonce"); @@ -598,18 +598,16 @@ class aesgcm128Decoder extends OldScheme } get padSize() { return 1; } } var PushCrypto = { - concatArray, - generateAuthenticationSecret() { return crypto.getRandomValues(new Uint8Array(16)); }, validateAppServerKey(key) { return crypto.subtle .importKey("raw", key, ECDSA_KEY, true, ["verify"]) .then(_ => key);
--- a/dom/push/PushService.jsm +++ b/dom/push/PushService.jsm @@ -15,16 +15,32 @@ const { clearTimeout, setTimeout } = Chr "resource://gre/modules/Timer.jsm" ); const { XPCOMUtils } = ChromeUtils.import( "resource://gre/modules/XPCOMUtils.jsm" ); var PushServiceWebSocket, PushServiceHttp2; +const CONNECTION_PROTOCOLS = (function() { + if ("android" != AppConstants.MOZ_WIDGET_TOOLKIT) { + ({ PushServiceWebSocket } = ChromeUtils.import( + "resource://gre/modules/PushServiceWebSocket.jsm" + )); + ({ PushServiceHttp2 } = ChromeUtils.import( + "resource://gre/modules/PushServiceHttp2.jsm" + )); + return [PushServiceWebSocket, PushServiceHttp2]; + } + const { PushServiceAndroidGCM } = ChromeUtils.import( + "resource://gre/modules/PushServiceAndroidGCM.jsm" + ); + return [PushServiceAndroidGCM]; +})(); + XPCOMUtils.defineLazyServiceGetter( this, "gPushNotifier", "@mozilla.org/push/Notifier;1", "nsIPushNotifier" ); XPCOMUtils.defineLazyServiceGetter( this, @@ -37,34 +53,16 @@ ChromeUtils.defineModuleGetter( "pushBroadcastService", "resource://gre/modules/PushBroadcastService.jsm" ); ChromeUtils.defineModuleGetter( this, "PushCrypto", "resource://gre/modules/PushCrypto.jsm" ); -ChromeUtils.defineModuleGetter( - this, - "PushServiceAndroidGCM", - "resource://gre/modules/PushServiceAndroidGCM.jsm" -); - -const CONNECTION_PROTOCOLS = (function() { - if ("android" != AppConstants.MOZ_WIDGET_TOOLKIT) { - ({ PushServiceWebSocket } = ChromeUtils.import( - "resource://gre/modules/PushServiceWebSocket.jsm" - )); - ({ PushServiceHttp2 } = ChromeUtils.import( - "resource://gre/modules/PushServiceHttp2.jsm" - )); - return [PushServiceWebSocket, PushServiceHttp2]; - } - return [PushServiceAndroidGCM]; -})(); const EXPORTED_SYMBOLS = ["PushService"]; XPCOMUtils.defineLazyGetter(this, "console", () => { let { ConsoleAPI } = ChromeUtils.import("resource://gre/modules/Console.jsm"); return new ConsoleAPI({ maxLogLevelPref: "dom.push.loglevel", prefix: "PushService", @@ -97,35 +95,16 @@ const PUSH_SERVICE_RUNNING = 5; **/ // This is for starting and stopping service. const STARTING_SERVICE_EVENT = 0; const CHANGING_SERVICE_EVENT = 1; const STOPPING_SERVICE_EVENT = 2; const UNINIT_EVENT = 3; -// Returns the backend for the given server URI. -function getServiceForServerURI(uri) { - // Insecure server URLs are allowed for development and testing. - let allowInsecure = prefs.get("testing.allowInsecureServerURL"); - if (AppConstants.MOZ_WIDGET_TOOLKIT == "android") { - if (uri.scheme == "https" || (allowInsecure && uri.scheme == "http")) { - return CONNECTION_PROTOCOLS; - } - return null; - } - if (uri.scheme == "wss" || (allowInsecure && uri.scheme == "ws")) { - return PushServiceWebSocket; - } - if (uri.scheme == "https" || (allowInsecure && uri.scheme == "http")) { - return PushServiceHttp2; - } - return null; -} - /** * Annotates an error with an XPCOM result code. We use this helper * instead of `Components.Exception` because the latter can assert in * `nsXPCComponents_Exception::HasInstance` when inspected at shutdown. */ function errorWithResult(message, result = Cr.NS_ERROR_FAILURE) { let error = new Error(message); error.result = result; @@ -424,34 +403,41 @@ var PushService = { .catch(e => { console.error("backgroundUnregister: Error notifying server", e); }); }, _findService(serverURL) { console.debug("findService()"); + let uri; + let service; + if (!serverURL) { console.warn("findService: No dom.push.serverURL found"); return []; } - let uri; try { uri = Services.io.newURI(serverURL); } catch (e) { console.warn( "findService: Error creating valid URI from", "dom.push.serverURL", serverURL ); return []; } - let service = getServiceForServerURI(uri); + for (let connProtocol of CONNECTION_PROTOCOLS) { + if (connProtocol.validServerURI(uri)) { + service = connProtocol; + break; + } + } return [service, uri]; }, _changeServerURL(serverURI, event, options = {}) { console.debug("changeServerURL()"); switch (event) { case UNINIT_EVENT:
--- a/dom/push/PushServiceAndroidGCM.jsm +++ b/dom/push/PushServiceAndroidGCM.jsm @@ -74,16 +74,35 @@ var PushServiceAndroidGCM = { kPUSHANDROIDGCMDB_DB_NAME, kPUSHANDROIDGCMDB_DB_VERSION, kPUSHANDROIDGCMDB_STORE_NAME, "channelID", PushRecordAndroidGCM ); }, + validServerURI(serverURI) { + if (!serverURI) { + return false; + } + + if (serverURI.scheme == "https") { + return true; + } + if (serverURI.scheme == "http") { + // Allow insecure server URLs for development and testing. + return !!prefs.get("testing.allowInsecureServerURL"); + } + console.info( + "Unsupported Android GCM dom.push.serverURL scheme", + serverURI.scheme + ); + return false; + }, + observe(subject, topic, data) { switch (topic) { case "nsPref:changed": if (data == "dom.push.debug") { // Reconfigure. let debug = !!prefs.get("debug"); console.info( "Debug parameter changed; updating configuration with new debug",
--- a/dom/push/PushServiceHttp2.jsm +++ b/dom/push/PushServiceHttp2.jsm @@ -420,16 +420,23 @@ var PushServiceHttp2 = { PushRecordHttp2 ); }, hasmainPushService() { return this._mainPushService !== null; }, + validServerURI(serverURI) { + if (serverURI.scheme == "http") { + return !!prefs.getBoolPref("testing.allowInsecureServerURL", false); + } + return serverURI.scheme == "https"; + }, + async connect(broadcastListeners) { let subscriptions = await this._mainPushService.getAllUnexpired(); this.startConnections(subscriptions); }, async sendSubscribeBroadcast(serviceId, version) { // Not implemented yet },
--- a/dom/push/PushServiceWebSocket.jsm +++ b/dom/push/PushServiceWebSocket.jsm @@ -249,16 +249,23 @@ var PushServiceWebSocket = { // The most likely reason for a pong or registration request timing out is // that the socket has disconnected. Best to reconnect. if (requestTimedOut) { this._reconnect(); } }, + validServerURI(serverURI) { + if (serverURI.scheme == "ws") { + return !!prefs.get("testing.allowInsecureServerURL"); + } + return serverURI.scheme == "wss"; + }, + get _UAID() { return prefs.get("userAgentID"); }, set _UAID(newID) { if (typeof newID !== "string") { console.warn( "Got invalid, non-string UAID",