зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 4 changesets (bug 1576507) for causing xpcshell failures on test_firstStartup.js
Backed out changeset efca0164a762 (bug 1576507) Backed out changeset 2238ba5cec98 (bug 1576507) Backed out changeset f16714d49101 (bug 1576507) Backed out changeset 2d621070f778 (bug 1576507)
This commit is contained in:
Родитель
3157a68692
Коммит
4d3d0231a5
|
@ -19,7 +19,6 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
||||||
BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
|
BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
|
||||||
HeadlessShell: "resource:///modules/HeadlessShell.jsm",
|
HeadlessShell: "resource:///modules/HeadlessShell.jsm",
|
||||||
HomePage: "resource:///modules/HomePage.jsm",
|
HomePage: "resource:///modules/HomePage.jsm",
|
||||||
FirstStartup: "resource://gre/modules/FirstStartup.jsm",
|
|
||||||
LaterRun: "resource:///modules/LaterRun.jsm",
|
LaterRun: "resource:///modules/LaterRun.jsm",
|
||||||
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
|
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
|
||||||
SessionStartup: "resource:///modules/sessionstore/SessionStartup.jsm",
|
SessionStartup: "resource:///modules/sessionstore/SessionStartup.jsm",
|
||||||
|
@ -559,10 +558,6 @@ nsBrowserContentHandler.prototype = {
|
||||||
ShellService.setDefaultBrowser(true, true);
|
ShellService.setDefaultBrowser(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmdLine.handleFlag("first-startup", false)) {
|
|
||||||
FirstStartup.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
var fileParam = cmdLine.handleFlagWithParam("file", false);
|
var fileParam = cmdLine.handleFlagWithParam("file", false);
|
||||||
if (fileParam) {
|
if (fileParam) {
|
||||||
var file = cmdLine.resolveFile(fileParam);
|
var file = cmdLine.resolveFile(fileParam);
|
||||||
|
@ -604,8 +599,6 @@ nsBrowserContentHandler.prototype = {
|
||||||
info +=
|
info +=
|
||||||
" --search <term> Search <term> with your default search engine.\n";
|
" --search <term> Search <term> with your default search engine.\n";
|
||||||
info += " --setDefaultBrowser Set this app as the default browser.\n";
|
info += " --setDefaultBrowser Set this app as the default browser.\n";
|
||||||
info +=
|
|
||||||
" --first-startup Run post-install actions before opening a new window.\n";
|
|
||||||
return info;
|
return info;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ var Normandy = {
|
||||||
studyPrefsChanged: {},
|
studyPrefsChanged: {},
|
||||||
rolloutPrefsChanged: {},
|
rolloutPrefsChanged: {},
|
||||||
|
|
||||||
async init({ runAsync = true } = {}) {
|
async init() {
|
||||||
// Initialization that needs to happen before the first paint on startup.
|
// Initialization that needs to happen before the first paint on startup.
|
||||||
await NormandyMigrations.applyAll();
|
await NormandyMigrations.applyAll();
|
||||||
this.rolloutPrefsChanged = this.applyStartupPrefs(
|
this.rolloutPrefsChanged = this.applyStartupPrefs(
|
||||||
|
@ -53,16 +53,8 @@ var Normandy = {
|
||||||
STARTUP_EXPERIMENT_PREFS_BRANCH
|
STARTUP_EXPERIMENT_PREFS_BRANCH
|
||||||
);
|
);
|
||||||
|
|
||||||
if (runAsync) {
|
// Wait until the UI is available before finishing initialization.
|
||||||
Services.obs.addObserver(this, UI_AVAILABLE_NOTIFICATION);
|
Services.obs.addObserver(this, UI_AVAILABLE_NOTIFICATION);
|
||||||
} else {
|
|
||||||
// Remove any observers, if present.
|
|
||||||
try {
|
|
||||||
Services.obs.removeObserver(this, UI_AVAILABLE_NOTIFICATION);
|
|
||||||
} catch (e) {}
|
|
||||||
|
|
||||||
await this.finishInit();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
observe(subject, topic, data) {
|
observe(subject, topic, data) {
|
||||||
|
|
|
@ -4586,22 +4586,6 @@ blocklist:
|
||||||
record_in_processes:
|
record_in_processes:
|
||||||
- main
|
- main
|
||||||
|
|
||||||
firstStartup:
|
|
||||||
statusCode:
|
|
||||||
bug_numbers:
|
|
||||||
- 1515712
|
|
||||||
description: >-
|
|
||||||
Status of the FirstRun service, which runs post-install/early-startup in Firefox.
|
|
||||||
expires: "75"
|
|
||||||
kind: uint
|
|
||||||
notification_emails:
|
|
||||||
- rhelmer@mozilla.com
|
|
||||||
release_channel_collection: opt-out
|
|
||||||
products:
|
|
||||||
- 'firefox'
|
|
||||||
record_in_processes:
|
|
||||||
- main
|
|
||||||
|
|
||||||
# The following section is for probes testing the Telemetry system. They will not be
|
# The following section is for probes testing the Telemetry system. They will not be
|
||||||
# submitted in pings and are only used for testing.
|
# submitted in pings and are only used for testing.
|
||||||
telemetry.test:
|
telemetry.test:
|
||||||
|
|
|
@ -36,11 +36,6 @@ ChromeUtils.defineModuleGetter(
|
||||||
"AppConstants",
|
"AppConstants",
|
||||||
"resource://gre/modules/AppConstants.jsm"
|
"resource://gre/modules/AppConstants.jsm"
|
||||||
);
|
);
|
||||||
ChromeUtils.defineModuleGetter(
|
|
||||||
this,
|
|
||||||
"FirstStartup",
|
|
||||||
"resource://gre/modules/FirstStartup.jsm"
|
|
||||||
);
|
|
||||||
|
|
||||||
var EXPORTED_SYMBOLS = ["ClientEnvironmentBase"];
|
var EXPORTED_SYMBOLS = ["ClientEnvironmentBase"];
|
||||||
|
|
||||||
|
@ -101,11 +96,6 @@ class ClientEnvironmentBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
static get searchEngine() {
|
static get searchEngine() {
|
||||||
// Telemetry Environment is not available in early first-startup.
|
|
||||||
if (FirstStartup.state === FirstStartup.IN_PROGRESS) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (async () => {
|
return (async () => {
|
||||||
await TelemetryEnvironment.onInitialized();
|
await TelemetryEnvironment.onInitialized();
|
||||||
return TelemetryEnvironment.currentEnvironment.settings
|
return TelemetryEnvironment.currentEnvironment.settings
|
||||||
|
@ -174,11 +164,6 @@ class ClientEnvironmentBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
static get os() {
|
static get os() {
|
||||||
// Telemetry Environment is not available in early first-startup.
|
|
||||||
if (FirstStartup.state === FirstStartup.IN_PROGRESS) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
function coerceToNumber(version) {
|
function coerceToNumber(version) {
|
||||||
const parts = version.split(".");
|
const parts = version.split(".");
|
||||||
return parseFloat(parts.slice(0, 2).join("."));
|
return parseFloat(parts.slice(0, 2).join("."));
|
||||||
|
|
|
@ -1,75 +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/. */
|
|
||||||
|
|
||||||
var EXPORTED_SYMBOLS = ["FirstStartup"];
|
|
||||||
|
|
||||||
const { AppConstants } = ChromeUtils.import(
|
|
||||||
"resource://gre/modules/AppConstants.jsm"
|
|
||||||
);
|
|
||||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|
||||||
const { XPCOMUtils } = ChromeUtils.import(
|
|
||||||
"resource://gre/modules/XPCOMUtils.jsm"
|
|
||||||
);
|
|
||||||
|
|
||||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
|
||||||
Normandy: "resource://normandy/Normandy.jsm",
|
|
||||||
});
|
|
||||||
|
|
||||||
const PREF_TIMEOUT = "first-startup.timeout";
|
|
||||||
const PROBE_NAME = "firstStartup.statusCode";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Service for blocking application startup, to be used on the first install. The intended
|
|
||||||
* use case is for `FirstStartup` to be invoked when the application is called by an installer,
|
|
||||||
* such as the Windows Stub Installer, to allow the application to do some first-install tasks
|
|
||||||
* such as performance tuning and downloading critical data.
|
|
||||||
*
|
|
||||||
* In this scenario, the installer does not exit until the first application window appears,
|
|
||||||
* which gives the user experience of the application starting up quickly on first install.
|
|
||||||
*/
|
|
||||||
var FirstStartup = {
|
|
||||||
NOT_STARTED: 0,
|
|
||||||
IN_PROGRESS: 1,
|
|
||||||
TIMED_OUT: 2,
|
|
||||||
SUCCESS: 3,
|
|
||||||
|
|
||||||
_state: this.NOT_STARTED,
|
|
||||||
/**
|
|
||||||
* Initialize and run first-startup services. This will always run synchronously
|
|
||||||
* and spin the event loop until either all required services have
|
|
||||||
* completed, or until a timeout is reached.
|
|
||||||
*
|
|
||||||
* In the latter case, services are expected to run post-UI instead as usual.
|
|
||||||
*/
|
|
||||||
init() {
|
|
||||||
this._state = this.IN_PROGRESS;
|
|
||||||
const timeout = Services.prefs.getIntPref(PREF_TIMEOUT, 5000); // default to 5 seconds
|
|
||||||
let expiredTime = Date.now() + timeout;
|
|
||||||
|
|
||||||
if (AppConstants.MOZ_NORMANDY) {
|
|
||||||
let normandyInitialized = false;
|
|
||||||
|
|
||||||
Normandy.init({ runAsync: false }).then(
|
|
||||||
() => (normandyInitialized = true)
|
|
||||||
);
|
|
||||||
|
|
||||||
Services.tm.spinEventLoopUntil(() => {
|
|
||||||
if (Date.now() >= expiredTime) {
|
|
||||||
this._state = this.TIMED_OUT;
|
|
||||||
return true;
|
|
||||||
} else if (normandyInitialized) {
|
|
||||||
this._state = this.SUCCESS;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
Services.telemetry.scalarSet(PROBE_NAME, this._state);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
get state() {
|
|
||||||
return this._state;
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,74 +0,0 @@
|
||||||
.. _FirstStartup:
|
|
||||||
|
|
||||||
==============
|
|
||||||
FirstStartup
|
|
||||||
==============
|
|
||||||
|
|
||||||
``FirstStartup`` is a module which is invoked on application startup by the Windows Installer,
|
|
||||||
to initialize services before the first application window appears.
|
|
||||||
|
|
||||||
This is useful for:
|
|
||||||
|
|
||||||
- one-time performance tuning
|
|
||||||
- downloading critical data (hotfixes, experiments, etc)
|
|
||||||
|
|
||||||
Blocking until the first Application window appears is important because the Installer
|
|
||||||
will show a progress bar until this happens. This gives a user experience of:
|
|
||||||
|
|
||||||
1. User downloads and starts the Windows Stub Installer.
|
|
||||||
2. Progress bar advances while the application is downloaded and installed.
|
|
||||||
3. Installer invokes the application with ``--first-startup``.
|
|
||||||
4. Application window appears, and the installer window closes.
|
|
||||||
|
|
||||||
Overall, the user experiences a very fast first-startup, with critical tasks that normally
|
|
||||||
would be deferred until after UI startup already complete.
|
|
||||||
|
|
||||||
.. _FirstStartup Architecture:
|
|
||||||
|
|
||||||
FirstStartup: Example use case
|
|
||||||
==============================
|
|
||||||
|
|
||||||
An example use of the ``FirstStartup`` module is to invoke the Normandy client to download an experiment
|
|
||||||
that will be used to customize the first-run page that Firefox shows.
|
|
||||||
|
|
||||||
In this example, the first-run page would be loaded experimentally based on an attribution code provided
|
|
||||||
by the Installer. The flow for this looks like:
|
|
||||||
|
|
||||||
1. User clicks on download link containing an attribution (UTM) code(s).
|
|
||||||
2. The download page serves a custom Windows Stub Installer with the appropriate attribution code embedded.
|
|
||||||
3. The installer invokes Firefox with the `--first-startup` flag, which blocks the first window.
|
|
||||||
4. Normandy is run by ``FirstStartup`` and downloads a list of available experiments, or "recipes".
|
|
||||||
5. Recipes are evaluated and filtered based on local information, such as the OS platform and the attribution codes.
|
|
||||||
6. A recipe is found which matches the current attribution code, and appropriate data is made available to the first-run page.
|
|
||||||
7. ``FirstStartup`` completes and unblocks, which causes Firefox to show the first window and load the appropriate first-run data.
|
|
||||||
|
|
||||||
List of phases
|
|
||||||
==============
|
|
||||||
|
|
||||||
``FirstStartup.NOT_STARTED``
|
|
||||||
|
|
||||||
The ``FirstStartup`` module has not been initalized (the ``init()``
|
|
||||||
function has not been called). This is the default state.
|
|
||||||
|
|
||||||
``FirstStartup.IN_PROGRESS``
|
|
||||||
|
|
||||||
``FirstStartup.init()`` has been called, and the event loop is
|
|
||||||
spinning. This state will persist until either all startup tasks
|
|
||||||
have finished, or time-out has been reached.
|
|
||||||
|
|
||||||
The time-out defaults to 5 seconds, but is configurable via the
|
|
||||||
``first-startup.timeout`` pref, which is specified in milliseconds.
|
|
||||||
|
|
||||||
``FirstStartup.TIMED_OUT``
|
|
||||||
|
|
||||||
The time-out has been reached before startup tasks are complete.
|
|
||||||
|
|
||||||
This status code is reported to Telemetry via the ``firstStartup.statusCode``
|
|
||||||
scalar.
|
|
||||||
|
|
||||||
``FirstStartup.SUCCESS``
|
|
||||||
|
|
||||||
All startup tasks have completed successfully, and application startup may resume.
|
|
||||||
|
|
||||||
This status code is reported to Telemetry via the ``firstStartup.statusCode``
|
|
||||||
scalar.
|
|
|
@ -8,4 +8,3 @@ The ``/toolkit/modules`` directory contains a number of self-contained toolkit m
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
|
||||||
AsyncShutdown
|
AsyncShutdown
|
||||||
FirstStartup
|
|
||||||
|
|
|
@ -188,7 +188,6 @@ EXTRA_JS_MODULES += [
|
||||||
'FinderHighlighter.jsm',
|
'FinderHighlighter.jsm',
|
||||||
'FinderIterator.jsm',
|
'FinderIterator.jsm',
|
||||||
'FinderParent.jsm',
|
'FinderParent.jsm',
|
||||||
'FirstStartup.jsm',
|
|
||||||
'FormLikeFactory.jsm',
|
'FormLikeFactory.jsm',
|
||||||
'Geometry.jsm',
|
'Geometry.jsm',
|
||||||
'GMPExtractorWorker.js',
|
'GMPExtractorWorker.js',
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const { FirstStartup } = ChromeUtils.import(
|
|
||||||
"resource://gre/modules/FirstStartup.jsm"
|
|
||||||
);
|
|
||||||
|
|
||||||
const PREF_TIMEOUT = "first-startup.timeout";
|
|
||||||
const PROBE_NAME = "firstStartup.statusCode";
|
|
||||||
|
|
||||||
add_task(async function test_success() {
|
|
||||||
FirstStartup.init();
|
|
||||||
equal(FirstStartup.state, FirstStartup.SUCCESS);
|
|
||||||
|
|
||||||
const scalars = Services.telemetry.getSnapshotForScalars("main", false)
|
|
||||||
.parent;
|
|
||||||
ok(PROBE_NAME in scalars);
|
|
||||||
equal(scalars[PROBE_NAME], FirstStartup.SUCCESS);
|
|
||||||
});
|
|
||||||
|
|
||||||
add_task(async function test_timeout() {
|
|
||||||
Services.prefs.setIntPref(PREF_TIMEOUT, 0);
|
|
||||||
FirstStartup.init();
|
|
||||||
equal(FirstStartup.state, FirstStartup.TIMED_OUT);
|
|
||||||
|
|
||||||
const scalars = Services.telemetry.getSnapshotForScalars("main", false)
|
|
||||||
.parent;
|
|
||||||
ok(PROBE_NAME in scalars);
|
|
||||||
equal(scalars[PROBE_NAME], FirstStartup.TIMED_OUT);
|
|
||||||
});
|
|
|
@ -72,4 +72,3 @@ skip-if = toolkit == 'android'
|
||||||
[test_servicerequest_xhr.js]
|
[test_servicerequest_xhr.js]
|
||||||
[test_EventEmitter.js]
|
[test_EventEmitter.js]
|
||||||
[test_ProfileAge.js]
|
[test_ProfileAge.js]
|
||||||
[test_firstStartup.js]
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче