forked from mirrors/gecko-dev
Bug 1671548 - Remove fission experiment support code and prefs, r=smaug,
r=tritter - backed out changesets: 1660057, 1667426, 1674214, 1669749, 1685801, 1667381 - fission.experiment support removed everywhere, including telemetry Differential Revision: https://phabricator.services.mozilla.com/D165169
This commit is contained in:
parent
2a721f9f6c
commit
c4ec4d7309
11 changed files with 8 additions and 701 deletions
|
|
@ -47,7 +47,6 @@ Please note that some targeting attributes require stricter controls on the tele
|
|||
* [profileRestartCount](#profilerestartcount)
|
||||
* [homePageSettings](#homepagesettings)
|
||||
* [newtabSettings](#newtabsettings)
|
||||
* [isFissionExperimentEnabled](#isfissionexperimentenabled)
|
||||
* [activeNotifications](#activenotifications)
|
||||
* [isMajorUpgrade](#ismajorupgrade)
|
||||
* [hasActiveEnterprisePolicies](#hasactiveenterprisepolicies)
|
||||
|
|
@ -822,10 +821,6 @@ Object {
|
|||
}
|
||||
```
|
||||
|
||||
### `isFissionExperimentEnabled`
|
||||
|
||||
A boolean. `true` if we're running Fission experiment, `false` otherwise.
|
||||
|
||||
### `activeNotifications`
|
||||
|
||||
True when an infobar style message is displayed or when the awesomebar is
|
||||
|
|
|
|||
|
|
@ -686,12 +686,6 @@ const TargetingGetters = {
|
|||
host: urls[0].host,
|
||||
};
|
||||
},
|
||||
get isFissionExperimentEnabled() {
|
||||
return (
|
||||
Services.appinfo.fissionExperimentStatus ===
|
||||
Ci.nsIXULRuntime.eExperimentStatusTreatment
|
||||
);
|
||||
},
|
||||
get activeNotifications() {
|
||||
let bts = Cc["@mozilla.org/backgroundtasks;1"]?.getService(
|
||||
Ci.nsIBackgroundTasks
|
||||
|
|
|
|||
|
|
@ -139,15 +139,6 @@ cfr-doorhanger-doh-primary-button-2 = Okay
|
|||
cfr-doorhanger-doh-secondary-button = Disable
|
||||
.accesskey = D
|
||||
|
||||
## Fission Experiment Message
|
||||
|
||||
cfr-doorhanger-fission-body-approved = Your privacy matters. { -brand-short-name } now isolates, or sandboxes, websites from each other, which makes it harder for hackers to steal passwords, credit card numbers, and other sensitive information.
|
||||
cfr-doorhanger-fission-header = Site Isolation
|
||||
cfr-doorhanger-fission-primary-button = OK, Got it
|
||||
.accesskey = O
|
||||
cfr-doorhanger-fission-secondary-button = Learn more
|
||||
.accesskey = L
|
||||
|
||||
## Full Video Support CFR message
|
||||
|
||||
cfr-doorhanger-video-support-body = Videos on this site may not play correctly on this version of { -brand-short-name }. For full video support, update { -brand-short-name } now.
|
||||
|
|
|
|||
|
|
@ -149,7 +149,6 @@ support-files =
|
|||
file_csp_sandbox_no_script_js_uri.html^headers^
|
||||
[browser_data_load_inherit_csp.js]
|
||||
[browser_dataURI_unique_opaque_origin.js]
|
||||
[browser_fission_maxOrigins.js]
|
||||
https_first_disabled = true
|
||||
[browser_frameloader_swap_with_bfcache.js]
|
||||
[browser_backforward_restore_scroll.js]
|
||||
|
|
|
|||
|
|
@ -1,222 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
SimpleTest.requestFlakyTimeout("Need to test expiration timeout");
|
||||
|
||||
function delay(msec) {
|
||||
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
|
||||
return new Promise(resolve => setTimeout(resolve, msec));
|
||||
}
|
||||
|
||||
function promiseIdle() {
|
||||
return new Promise(resolve => {
|
||||
Services.tm.idleDispatchToMainThread(resolve);
|
||||
});
|
||||
}
|
||||
|
||||
const ORIGIN_CAP = 5;
|
||||
const SLIDING_WINDOW_MS = 5000;
|
||||
|
||||
const PREF_ORIGIN_CAP = "fission.experiment.max-origins.origin-cap";
|
||||
const PREF_SLIDING_WINDOW_MS =
|
||||
"fission.experiment.max-origins.sliding-window-ms";
|
||||
const PREF_QUALIFIED = "fission.experiment.max-origins.qualified";
|
||||
const PREF_LAST_QUALIFIED = "fission.experiment.max-origins.last-qualified";
|
||||
const PREF_LAST_DISQUALIFIED =
|
||||
"fission.experiment.max-origins.last-disqualified";
|
||||
|
||||
const SITE_ORIGINS = [
|
||||
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
|
||||
"http://example.com/",
|
||||
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
|
||||
"http://example.org/",
|
||||
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
|
||||
"http://example.net/",
|
||||
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
|
||||
"http://example.tw/",
|
||||
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
|
||||
"http://example.cn/",
|
||||
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
|
||||
"http://example.fi/",
|
||||
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
|
||||
"http://example.in/",
|
||||
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
|
||||
"http://example.lk/",
|
||||
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
|
||||
"http://w3c-test.org/",
|
||||
"https://www.mozilla.org/",
|
||||
];
|
||||
|
||||
function openTab(url) {
|
||||
return BrowserTestUtils.openNewForegroundTab({
|
||||
gBrowser,
|
||||
url,
|
||||
waitForStateStop: true,
|
||||
});
|
||||
}
|
||||
|
||||
async function assertQualified() {
|
||||
// The unique origin calculation runs from an idle task, so make sure
|
||||
// the queued idle task has had a chance to run.
|
||||
await promiseIdle();
|
||||
|
||||
// Make sure the clock has advanced since the qualification timestamp
|
||||
// was recorded.
|
||||
await delay(1);
|
||||
|
||||
let qualified = Services.prefs.getBoolPref(PREF_QUALIFIED);
|
||||
let lastQualified = Services.prefs.getIntPref(PREF_LAST_QUALIFIED);
|
||||
let lastDisqualified = Services.prefs.getIntPref(PREF_LAST_DISQUALIFIED);
|
||||
let currentTime = Date.now() / 1000;
|
||||
|
||||
ok(qualified, "Should be qualified");
|
||||
ok(
|
||||
lastQualified > 0,
|
||||
`Last qualified timestamp (${lastQualified}) should be greater than 0`
|
||||
);
|
||||
ok(
|
||||
lastQualified < currentTime,
|
||||
`Last qualified timestamp (${lastQualified}) should be less than the current time (${currentTime})`
|
||||
);
|
||||
ok(
|
||||
lastQualified > lastDisqualified,
|
||||
`Last qualified timestamp (${lastQualified}) should be after the last disqualified time (${lastDisqualified})`
|
||||
);
|
||||
|
||||
ok(
|
||||
lastDisqualified < currentTime,
|
||||
`Last disqualified timestamp (${lastDisqualified}) should be less than the current time (${currentTime})`
|
||||
);
|
||||
}
|
||||
|
||||
async function assertDisqualified(opts) {
|
||||
// The unique origin calculation runs from an idle task, so make sure
|
||||
// the queued idle task has had a chance to run.
|
||||
await promiseIdle();
|
||||
|
||||
let qualified = Services.prefs.getBoolPref(PREF_QUALIFIED);
|
||||
let lastQualified = Services.prefs.getIntPref(PREF_LAST_QUALIFIED, 0);
|
||||
let lastDisqualified = Services.prefs.getIntPref(PREF_LAST_DISQUALIFIED);
|
||||
let currentTime = Date.now() / 1000;
|
||||
|
||||
ok(!qualified, "Should not be qualified");
|
||||
if (!opts.initialValues) {
|
||||
ok(
|
||||
lastQualified > 0,
|
||||
`Last qualified timestamp (${lastQualified}) should be greater than 0`
|
||||
);
|
||||
}
|
||||
ok(
|
||||
lastQualified < currentTime,
|
||||
`Last qualified timestamp (${lastQualified}) should be less than the current time (${currentTime})`
|
||||
);
|
||||
|
||||
ok(
|
||||
lastDisqualified < currentTime,
|
||||
`Last disqualified timestamp (${lastDisqualified}) should be less than the current time (${currentTime})`
|
||||
);
|
||||
|
||||
ok(
|
||||
lastDisqualified > 0,
|
||||
`Last disqualified timestamp (${lastDisqualified}) should be greater than 0`
|
||||
);
|
||||
|
||||
if (opts.qualificationPending) {
|
||||
ok(
|
||||
lastQualified > lastDisqualified,
|
||||
`Last qualified timestamp (${lastQualified}) should be after the last disqualified time (${lastDisqualified})`
|
||||
);
|
||||
} else {
|
||||
ok(
|
||||
lastDisqualified > lastQualified,
|
||||
`Last disqualified timestamp (${lastDisqualified}) should be after the last qualified time (${lastQualified})`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
add_task(async function() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[PREF_ORIGIN_CAP, ORIGIN_CAP],
|
||||
[PREF_SLIDING_WINDOW_MS, SLIDING_WINDOW_MS],
|
||||
],
|
||||
});
|
||||
|
||||
const { BrowserTelemetryUtils } = ChromeUtils.importESModule(
|
||||
"resource://gre/modules/BrowserTelemetryUtils.sys.mjs"
|
||||
);
|
||||
|
||||
// Make sure we actually record telemetry for our disqualifying origin
|
||||
// count.
|
||||
BrowserTelemetryUtils.min_interval = 1;
|
||||
|
||||
let tabs = [];
|
||||
|
||||
// Open one initial tab to make sure the origin counting code has had
|
||||
// a chance to run before checking the initial state.
|
||||
tabs.push(await openTab("http://mochi.test:8888/"));
|
||||
|
||||
await assertQualified();
|
||||
|
||||
let lastDisqualified = Services.prefs.getIntPref(PREF_LAST_DISQUALIFIED);
|
||||
is(lastDisqualified, 0, "Last disqualification timestamp should be 0");
|
||||
|
||||
info(
|
||||
`Opening ${SITE_ORIGINS.length} tabs with distinct origins to exceed the cap (${ORIGIN_CAP})`
|
||||
);
|
||||
ok(
|
||||
SITE_ORIGINS.length > ORIGIN_CAP,
|
||||
"Should have enough site origins to exceed the origin cap"
|
||||
);
|
||||
tabs.push(...(await Promise.all(SITE_ORIGINS.map(openTab))));
|
||||
|
||||
await assertDisqualified({ qualificationPending: false });
|
||||
|
||||
info("Close unique-origin tabs");
|
||||
await Promise.all(tabs.map(tab => BrowserTestUtils.removeTab(tab)));
|
||||
|
||||
info("Open a new tab to trigger the origin count code once more");
|
||||
tabs = [await openTab(SITE_ORIGINS[0])];
|
||||
|
||||
await assertDisqualified({ qualificationPending: true });
|
||||
|
||||
info(
|
||||
"Wait long enough to clear the sliding window since last disqualified state"
|
||||
);
|
||||
await delay(SLIDING_WINDOW_MS + 1000);
|
||||
|
||||
info("Open a new tab to trigger the origin count code again");
|
||||
tabs.push(await openTab(SITE_ORIGINS[0]));
|
||||
|
||||
await assertQualified();
|
||||
|
||||
info(
|
||||
"Clear preference values and re-populate the initial value from telemetry"
|
||||
);
|
||||
Services.prefs.clearUserPref(PREF_QUALIFIED);
|
||||
Services.prefs.clearUserPref(PREF_LAST_QUALIFIED);
|
||||
Services.prefs.clearUserPref(PREF_LAST_DISQUALIFIED);
|
||||
BrowserTelemetryUtils._checkedInitialExperimentQualification = false;
|
||||
|
||||
info("Open a new tab to trigger the origin count code again");
|
||||
tabs.push(await openTab(SITE_ORIGINS[0]));
|
||||
|
||||
await assertDisqualified({ initialValues: true });
|
||||
|
||||
info(
|
||||
"Wait long enough to clear the sliding window since last disqualified state"
|
||||
);
|
||||
await delay(SLIDING_WINDOW_MS + 1000);
|
||||
|
||||
info("Open a new tab to trigger the origin count code again");
|
||||
tabs.push(await openTab(SITE_ORIGINS[0]));
|
||||
|
||||
await assertQualified();
|
||||
|
||||
await Promise.all(tabs.map(tab => BrowserTestUtils.removeTab(tab)));
|
||||
|
||||
// Clear the cached recording interval so it resets to the default
|
||||
// value on the next call.
|
||||
BrowserTelemetryUtils.min_interval = null;
|
||||
});
|
||||
|
|
@ -6037,7 +6037,6 @@ static const PrefListEntry sParentOnlyPrefBranchList[] = {
|
|||
PREF_LIST_ENTRY("browser.newtabpage.activity-stream.discoverystream."),
|
||||
PREF_LIST_ENTRY("browser.sessionstore.upgradeBackup.latestBuildID"),
|
||||
PREF_LIST_ENTRY("browser.shell.mostRecentDateSetAsDefault"),
|
||||
PREF_LIST_ENTRY("fission.experiment.max-origins.last-"),
|
||||
PREF_LIST_ENTRY("idle.lastDailyNotification"),
|
||||
PREF_LIST_ENTRY("media.gmp-gmpopenh264.lastUpdate"),
|
||||
PREF_LIST_ENTRY("media.gmp-manager.lastCheck"),
|
||||
|
|
|
|||
|
|
@ -4980,18 +4980,6 @@
|
|||
value: @IS_NOT_ANDROID@
|
||||
mirror: never
|
||||
|
||||
# Prefs used by normandy to orchestrate the fission experiment. For more
|
||||
# details, see the comments in nsAppRunner.cpp.
|
||||
- name: fission.experiment.enrollmentStatus
|
||||
type: uint32_t
|
||||
value: 0
|
||||
mirror: never
|
||||
|
||||
- name: fission.experiment.startupEnrollmentStatus
|
||||
type: uint32_t
|
||||
value: 0
|
||||
mirror: never
|
||||
|
||||
# This pref has no effect within fission windows, it only controls the
|
||||
# behaviour within non-fission windows. If true, preserve browsing contexts
|
||||
# between process swaps.
|
||||
|
|
|
|||
|
|
@ -3,59 +3,6 @@
|
|||
* 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/. */
|
||||
|
||||
import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
|
||||
|
||||
const lazy = {};
|
||||
|
||||
// The maximum number of concurrently-loaded origins allowed in order to
|
||||
// qualify for the Fission rollout experiment.
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
lazy,
|
||||
"fissionExperimentMaxOrigins",
|
||||
"fission.experiment.max-origins.origin-cap",
|
||||
30
|
||||
);
|
||||
// The length of the sliding window during which a user must stay below
|
||||
// the max origin cap. If the last time a user passed the max origin cap
|
||||
// fell outside of this window, they will requalify for the experiment.
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
lazy,
|
||||
"fissionExperimentSlidingWindowMS",
|
||||
"fission.experiment.max-origins.sliding-window-ms",
|
||||
7 * 24 * 60 * 60 * 1000
|
||||
);
|
||||
// The pref holding the current qaualification state of the user. If
|
||||
// true, the user is currently qualified from the experiment.
|
||||
const FISSION_EXPERIMENT_PREF_QUALIFIED =
|
||||
"fission.experiment.max-origins.qualified";
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
lazy,
|
||||
"fissionExperimentQualified",
|
||||
FISSION_EXPERIMENT_PREF_QUALIFIED,
|
||||
false
|
||||
);
|
||||
// The pref holding the timestamp of the last time we saw an origin
|
||||
// count below the cap while the user was not currently marked as
|
||||
// qualified.
|
||||
const FISSION_EXPERIMENT_PREF_LAST_QUALIFIED =
|
||||
"fission.experiment.max-origins.last-qualified";
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
lazy,
|
||||
"fissionExperimentLastQualified",
|
||||
FISSION_EXPERIMENT_PREF_LAST_QUALIFIED,
|
||||
0
|
||||
);
|
||||
// The pref holding the timestamp of the last time we saw an origin
|
||||
// count exceeding the cap.
|
||||
const FISSION_EXPERIMENT_PREF_LAST_DISQUALIFIED =
|
||||
"fission.experiment.max-origins.last-disqualified";
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
lazy,
|
||||
"fissionExperimentLastDisqualified",
|
||||
FISSION_EXPERIMENT_PREF_LAST_DISQUALIFIED,
|
||||
0
|
||||
);
|
||||
|
||||
export var BrowserTelemetryUtils = {
|
||||
recordSiteOriginTelemetry(aWindows, aIsGeckoView) {
|
||||
Services.tm.idleDispatchToMainThread(() => {
|
||||
|
|
@ -122,73 +69,5 @@ export var BrowserTelemetryUtils = {
|
|||
|
||||
histogram.add(originCount);
|
||||
}
|
||||
|
||||
// Update the Fission experiment qualification state based on the
|
||||
// current origin count:
|
||||
|
||||
// If we don't already have a last disqualification timestamp, look
|
||||
// through the existing histogram values, and use the existing
|
||||
// maximum value as the initial count. This will prevent us from
|
||||
// enrolling users in the experiment if they have a history of
|
||||
// exceeding our origin cap.
|
||||
if (!this._checkedInitialExperimentQualification) {
|
||||
this._checkedInitialExperimentQualification = true;
|
||||
if (
|
||||
!Services.prefs.prefHasUserValue(
|
||||
FISSION_EXPERIMENT_PREF_LAST_DISQUALIFIED
|
||||
)
|
||||
) {
|
||||
for (let [bucketStr, entryCount] of Object.entries(
|
||||
histogram.snapshot().values
|
||||
)) {
|
||||
let bucket = Number(bucketStr);
|
||||
if (bucket > originCount && entryCount > 0) {
|
||||
originCount = bucket;
|
||||
}
|
||||
}
|
||||
Services.prefs.setIntPref(FISSION_EXPERIMENT_PREF_LAST_DISQUALIFIED, 0);
|
||||
}
|
||||
}
|
||||
|
||||
let currentTimeSec = currentTime / 1000;
|
||||
if (originCount < lazy.fissionExperimentMaxOrigins) {
|
||||
let lastDisqualified = lazy.fissionExperimentLastDisqualified;
|
||||
let lastQualified = lazy.fissionExperimentLastQualified;
|
||||
|
||||
// If the last time we saw a qualifying origin count was earlier
|
||||
// than the last time we say a disqualifying count, update any
|
||||
// existing last disqualified timestamp to just before now, on the
|
||||
// basis that our origin count has probably just fallen below the
|
||||
// cap.
|
||||
if (lastDisqualified > 0 && lastQualified <= lastDisqualified) {
|
||||
Services.prefs.setIntPref(
|
||||
FISSION_EXPERIMENT_PREF_LAST_DISQUALIFIED,
|
||||
currentTimeSec - 1
|
||||
);
|
||||
}
|
||||
|
||||
if (!lazy.fissionExperimentQualified) {
|
||||
Services.prefs.setIntPref(
|
||||
FISSION_EXPERIMENT_PREF_LAST_QUALIFIED,
|
||||
currentTimeSec
|
||||
);
|
||||
|
||||
// We have a qualifying origin count now. If the last time we were
|
||||
// disqualified was prior to the start of our current sliding
|
||||
// window, re-qualify the user.
|
||||
if (
|
||||
currentTimeSec - lastDisqualified >=
|
||||
lazy.fissionExperimentSlidingWindowMS / 1000
|
||||
) {
|
||||
Services.prefs.setBoolPref(FISSION_EXPERIMENT_PREF_QUALIFIED, true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Services.prefs.setIntPref(
|
||||
FISSION_EXPERIMENT_PREF_LAST_DISQUALIFIED,
|
||||
currentTimeSec
|
||||
);
|
||||
Services.prefs.setBoolPref(FISSION_EXPERIMENT_PREF_QUALIFIED, false);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -896,25 +896,6 @@ nsIXULRuntime::ContentWin32kLockdownState GetWin32kLockdownState() {
|
|||
//
|
||||
// - The 'fission.autostart' preference, if it has been configured by the user.
|
||||
static const char kPrefFissionAutostart[] = "fission.autostart";
|
||||
//
|
||||
// - The fission experiment enrollment status set during the previous run, which
|
||||
// is controlled by the following preferences:
|
||||
//
|
||||
// The current enrollment status as controlled by Normandy. This value is only
|
||||
// stored in the default preference branch, and is not persisted across
|
||||
// sessions by the preference service. It therefore isn't available early
|
||||
// enough at startup, and needs to be synced to a preference in the user
|
||||
// branch which is persisted across sessions.
|
||||
static const char kPrefFissionExperimentEnrollmentStatus[] =
|
||||
"fission.experiment.enrollmentStatus";
|
||||
//
|
||||
// The enrollment status to be used at browser startup. This automatically
|
||||
// synced from the above enrollmentStatus preference whenever the latter is
|
||||
// changed. It can have any of the values defined in the
|
||||
// `nsIXULRuntime_ExperimentStatus` enum. Meanings are documented in
|
||||
// the declaration of `nsIXULRuntime.fissionExperimentStatus`
|
||||
static const char kPrefFissionExperimentStartupEnrollmentStatus[] =
|
||||
"fission.experiment.startupEnrollmentStatus";
|
||||
|
||||
// The computed FissionAutostart value for the session, read by content
|
||||
// processes to initialize gFissionAutostart.
|
||||
|
|
@ -923,68 +904,13 @@ static const char kPrefFissionExperimentStartupEnrollmentStatus[] =
|
|||
// never be persisted in a profile.
|
||||
static const char kPrefFissionAutostartSession[] = "fission.autostart.session";
|
||||
|
||||
static nsIXULRuntime::ExperimentStatus gFissionExperimentStatus =
|
||||
nsIXULRuntime::eExperimentStatusUnenrolled;
|
||||
//
|
||||
// The computed FissionAutostart value for the session, read by content
|
||||
// processes to initialize gFissionAutostart.
|
||||
|
||||
static bool gFissionAutostart = false;
|
||||
static bool gFissionAutostartInitialized = false;
|
||||
static nsIXULRuntime::FissionDecisionStatus gFissionDecisionStatus;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
bool FissionExperimentEnrolled() {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
return gFissionExperimentStatus == nsIXULRuntime::eExperimentStatusControl ||
|
||||
gFissionExperimentStatus ==
|
||||
nsIXULRuntime::eExperimentStatusTreatment ||
|
||||
gFissionExperimentStatus == nsIXULRuntime::eExperimentStatusRollout;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
static void FissionExperimentDisqualify() {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
// Setting this pref's user value will be detected by Normandy, causing the
|
||||
// client to be unenrolled from the experiment.
|
||||
Preferences::SetUint(kPrefFissionExperimentEnrollmentStatus,
|
||||
nsIXULRuntime::eExperimentStatusDisqualified);
|
||||
}
|
||||
|
||||
static void OnFissionEnrollmentStatusChanged(const char* aPref, void* aData) {
|
||||
Preferences::SetUint(
|
||||
kPrefFissionExperimentStartupEnrollmentStatus,
|
||||
Preferences::GetUint(kPrefFissionExperimentEnrollmentStatus,
|
||||
nsIXULRuntime::eExperimentStatusUnenrolled));
|
||||
}
|
||||
|
||||
namespace {
|
||||
// This observer is notified during `profile-before-change`, and ensures that
|
||||
// the experiment enrollment status is synced over before the browser shuts
|
||||
// down, even if it was not modified since FissionAutostart was initialized.
|
||||
class FissionEnrollmentStatusShutdownObserver final : public nsIObserver {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Observe(nsISupports* aSubject, const char* aTopic,
|
||||
const char16_t* aData) override {
|
||||
MOZ_ASSERT(!strcmp("profile-before-change", aTopic));
|
||||
OnFissionEnrollmentStatusChanged(kPrefFissionExperimentEnrollmentStatus,
|
||||
nullptr);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
~FissionEnrollmentStatusShutdownObserver() = default;
|
||||
};
|
||||
NS_IMPL_ISUPPORTS(FissionEnrollmentStatusShutdownObserver, nsIObserver)
|
||||
} // namespace
|
||||
|
||||
static void OnFissionAutostartChanged(const char* aPref, void* aData) {
|
||||
MOZ_ASSERT(FissionExperimentEnrolled());
|
||||
if (Preferences::HasUserValue(kPrefFissionAutostart)) {
|
||||
FissionExperimentDisqualify();
|
||||
}
|
||||
}
|
||||
|
||||
static void EnsureFissionAutostartInitialized() {
|
||||
if (gFissionAutostartInitialized) {
|
||||
return;
|
||||
|
|
@ -998,48 +924,6 @@ static void EnsureFissionAutostartInitialized() {
|
|||
return;
|
||||
}
|
||||
|
||||
// Initialize the fission experiment, configuring fission.autostart's
|
||||
// default, before checking other overrides. This allows opting-out of a
|
||||
// fission experiment through about:preferences or about:config from a
|
||||
// safemode session.
|
||||
uint32_t experimentRaw =
|
||||
Preferences::GetUint(kPrefFissionExperimentStartupEnrollmentStatus,
|
||||
nsIXULRuntime::eExperimentStatusUnenrolled);
|
||||
gFissionExperimentStatus =
|
||||
experimentRaw < nsIXULRuntime::eExperimentStatusCount
|
||||
? nsIXULRuntime::ExperimentStatus(experimentRaw)
|
||||
: nsIXULRuntime::eExperimentStatusDisqualified;
|
||||
|
||||
// Watch the experiment enrollment status pref to detect experiment
|
||||
// disqualification, and ensure it is propagated for the next restart.
|
||||
Preferences::RegisterCallback(&OnFissionEnrollmentStatusChanged,
|
||||
kPrefFissionExperimentEnrollmentStatus);
|
||||
if (nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService()) {
|
||||
nsCOMPtr<nsIObserver> shutdownObserver =
|
||||
new FissionEnrollmentStatusShutdownObserver();
|
||||
observerService->AddObserver(shutdownObserver, "profile-before-change",
|
||||
false);
|
||||
}
|
||||
|
||||
// If the user has overridden an active experiment by setting a user value for
|
||||
// "fission.autostart", disqualify the user from the experiment.
|
||||
if (Preferences::HasUserValue(kPrefFissionAutostart) &&
|
||||
FissionExperimentEnrolled()) {
|
||||
FissionExperimentDisqualify();
|
||||
gFissionExperimentStatus = nsIXULRuntime::eExperimentStatusDisqualified;
|
||||
}
|
||||
|
||||
// Configure the default branch for "fission.autostart" based on experiment
|
||||
// enrollment status.
|
||||
if (FissionExperimentEnrolled()) {
|
||||
bool isTreatment =
|
||||
gFissionExperimentStatus == nsIXULRuntime::eExperimentStatusTreatment ||
|
||||
gFissionExperimentStatus == nsIXULRuntime::eExperimentStatusRollout;
|
||||
Preferences::SetBool(kPrefFissionAutostart, isTreatment,
|
||||
PrefValueKind::Default);
|
||||
}
|
||||
|
||||
if (!BrowserTabsRemoteAutostart()) {
|
||||
gFissionAutostart = false;
|
||||
if (gBrowserTabsRemoteStatus == kE10sForceDisabled) {
|
||||
|
|
@ -1057,15 +941,7 @@ static void EnsureFissionAutostartInitialized() {
|
|||
// NOTE: This will take into account changes to the default due to
|
||||
// `InitializeFissionExperimentStatus`.
|
||||
gFissionAutostart = Preferences::GetBool(kPrefFissionAutostart, false);
|
||||
if (gFissionExperimentStatus == nsIXULRuntime::eExperimentStatusControl) {
|
||||
gFissionDecisionStatus = nsIXULRuntime::eFissionExperimentControl;
|
||||
} else if (gFissionExperimentStatus ==
|
||||
nsIXULRuntime::eExperimentStatusTreatment) {
|
||||
gFissionDecisionStatus = nsIXULRuntime::eFissionExperimentTreatment;
|
||||
} else if (gFissionExperimentStatus ==
|
||||
nsIXULRuntime::eExperimentStatusRollout) {
|
||||
gFissionDecisionStatus = nsIXULRuntime::eFissionEnabledByRollout;
|
||||
} else if (Preferences::HasUserValue(kPrefFissionAutostart)) {
|
||||
if (Preferences::HasUserValue(kPrefFissionAutostart)) {
|
||||
gFissionDecisionStatus = gFissionAutostart
|
||||
? nsIXULRuntime::eFissionEnabledByUserPref
|
||||
: nsIXULRuntime::eFissionDisabledByUserPref;
|
||||
|
|
@ -1086,13 +962,6 @@ static void EnsureFissionAutostartInitialized() {
|
|||
Preferences::SetBool(kPrefFissionAutostartSession, gFissionAutostart,
|
||||
PrefValueKind::Default);
|
||||
Preferences::Lock(kPrefFissionAutostartSession);
|
||||
|
||||
// If we're actively enrolled in the fission experiment, disqualify the user
|
||||
// from the experiment if the fission pref is modified.
|
||||
if (FissionExperimentEnrolled()) {
|
||||
Preferences::RegisterCallback(&OnFissionAutostartChanged,
|
||||
kPrefFissionAutostart);
|
||||
}
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
|
|
@ -1452,17 +1321,6 @@ nsXULAppInfo::GetWin32kSessionStatus(
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULAppInfo::GetFissionExperimentStatus(ExperimentStatus* aResult) {
|
||||
if (!XRE_IsParentProcess()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
EnsureFissionAutostartInitialized();
|
||||
*aResult = gFissionExperimentStatus;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULAppInfo::GetFissionDecisionStatus(FissionDecisionStatus* aResult) {
|
||||
if (!XRE_IsParentProcess()) {
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@ class ExperimentStatus:
|
|||
|
||||
|
||||
class Prefs:
|
||||
ENROLLMENT_STATUS = "fission.experiment.enrollmentStatus"
|
||||
STARTUP_ENROLLMENT_STATUS = "fission.experiment.startupEnrollmentStatus"
|
||||
FISSION_AUTOSTART = "fission.autostart"
|
||||
FISSION_AUTOSTART_SESSION = "fission.autostart.session"
|
||||
|
||||
|
|
@ -51,7 +49,6 @@ class TestFissionAutostart(MarionetteTestCase):
|
|||
let win = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
return {
|
||||
fissionAutostart: Services.appinfo.fissionAutostart,
|
||||
fissionExperimentStatus: Services.appinfo.fissionExperimentStatus,
|
||||
decisionStatus: Services.appinfo.fissionDecisionStatus,
|
||||
decisionStatusString: Services.appinfo.fissionDecisionStatusString,
|
||||
useRemoteSubframes: win.docShell.nsILoadContext.useRemoteSubframes,
|
||||
|
|
@ -61,13 +58,12 @@ class TestFissionAutostart(MarionetteTestCase):
|
|||
"""
|
||||
)
|
||||
|
||||
def check_fission_status(self, enabled, experiment, decision, dynamic=None):
|
||||
def check_fission_status(self, enabled, decision, dynamic=None):
|
||||
if dynamic is None:
|
||||
dynamic = enabled
|
||||
|
||||
expected = {
|
||||
"fissionAutostart": enabled,
|
||||
"fissionExperimentStatus": experiment,
|
||||
"decisionStatus": DECISION_STATUS[decision],
|
||||
"decisionStatusString": decision,
|
||||
"useRemoteSubframes": enabled,
|
||||
|
|
@ -93,17 +89,6 @@ class TestFissionAutostart(MarionetteTestCase):
|
|||
def get_env(self, env):
|
||||
return self.execute_script("return env.get(arguments[0]);", script_args=(env,))
|
||||
|
||||
def set_enrollment_status(self, status):
|
||||
self.marionette.set_pref(Prefs.ENROLLMENT_STATUS, status, default_branch=True)
|
||||
|
||||
startup_status = self.marionette.get_pref(Prefs.STARTUP_ENROLLMENT_STATUS)
|
||||
self.assertEqual(
|
||||
startup_status,
|
||||
status,
|
||||
"Startup enrollment status (%r) should match new "
|
||||
"session status (%r)" % (startup_status, status),
|
||||
)
|
||||
|
||||
def restart(self, prefs=None, env=None):
|
||||
if prefs:
|
||||
self.marionette.set_prefs(prefs)
|
||||
|
|
@ -166,7 +151,6 @@ class TestFissionAutostart(MarionetteTestCase):
|
|||
# Fission status must start out with `enabledByDefault`
|
||||
self.check_fission_status(
|
||||
enabled=True,
|
||||
experiment=ExperimentStatus.UNENROLLED,
|
||||
decision="enabledByDefault",
|
||||
)
|
||||
|
||||
|
|
@ -185,7 +169,6 @@ class TestFissionAutostart(MarionetteTestCase):
|
|||
|
||||
self.check_fission_status(
|
||||
enabled=True,
|
||||
experiment=ExperimentStatus.UNENROLLED,
|
||||
decision="enabledByDefault",
|
||||
)
|
||||
|
||||
|
|
@ -193,21 +176,12 @@ class TestFissionAutostart(MarionetteTestCase):
|
|||
|
||||
self.check_fission_status(
|
||||
enabled=False,
|
||||
experiment=ExperimentStatus.UNENROLLED,
|
||||
decision="disabledByUserPref",
|
||||
)
|
||||
|
||||
self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
|
||||
self.check_fission_status(
|
||||
enabled=False,
|
||||
experiment=ExperimentStatus.UNENROLLED,
|
||||
decision="disabledByUserPref",
|
||||
)
|
||||
|
||||
self.marionette.set_pref(Prefs.FISSION_AUTOSTART, True)
|
||||
self.check_fission_status(
|
||||
enabled=False,
|
||||
experiment=ExperimentStatus.UNENROLLED,
|
||||
decision="disabledByUserPref",
|
||||
dynamic=True,
|
||||
)
|
||||
|
|
@ -215,38 +189,19 @@ class TestFissionAutostart(MarionetteTestCase):
|
|||
self.marionette.clear_pref(Prefs.FISSION_AUTOSTART)
|
||||
self.check_fission_status(
|
||||
enabled=False,
|
||||
experiment=ExperimentStatus.UNENROLLED,
|
||||
decision="disabledByUserPref",
|
||||
dynamic=True,
|
||||
)
|
||||
|
||||
self.restart()
|
||||
self.check_fission_status(
|
||||
enabled=False,
|
||||
experiment=ExperimentStatus.ENROLLED_CONTROL,
|
||||
decision="experimentControl",
|
||||
)
|
||||
|
||||
self.marionette.set_pref(
|
||||
Prefs.ENROLLMENT_STATUS, ExperimentStatus.UNENROLLED, default_branch=True
|
||||
)
|
||||
self.check_fission_status(
|
||||
enabled=False,
|
||||
experiment=ExperimentStatus.ENROLLED_CONTROL,
|
||||
decision="experimentControl",
|
||||
)
|
||||
|
||||
self.set_env(ENV_ENABLE_FISSION, "1")
|
||||
self.check_fission_status(
|
||||
enabled=False,
|
||||
experiment=ExperimentStatus.ENROLLED_CONTROL,
|
||||
decision="experimentControl",
|
||||
enabled=True,
|
||||
decision="enabledByDefault",
|
||||
)
|
||||
|
||||
def test_fission_precedence(self):
|
||||
self.check_fission_status(
|
||||
enabled=True,
|
||||
experiment=ExperimentStatus.UNENROLLED,
|
||||
decision="enabledByDefault",
|
||||
)
|
||||
|
||||
|
|
@ -255,7 +210,6 @@ class TestFissionAutostart(MarionetteTestCase):
|
|||
)
|
||||
self.check_fission_status(
|
||||
enabled=True,
|
||||
experiment=ExperimentStatus.UNENROLLED,
|
||||
decision="enabledByEnv",
|
||||
dynamic=False,
|
||||
)
|
||||
|
|
@ -266,7 +220,6 @@ class TestFissionAutostart(MarionetteTestCase):
|
|||
)
|
||||
self.check_fission_status(
|
||||
enabled=False,
|
||||
experiment=ExperimentStatus.UNENROLLED,
|
||||
decision="disabledByEnv",
|
||||
dynamic=True,
|
||||
)
|
||||
|
|
@ -276,135 +229,19 @@ class TestFissionAutostart(MarionetteTestCase):
|
|||
)
|
||||
self.check_fission_status(
|
||||
enabled=False,
|
||||
experiment=ExperimentStatus.UNENROLLED,
|
||||
decision="disabledByUserPref",
|
||||
)
|
||||
|
||||
self.restart(prefs={Prefs.FISSION_AUTOSTART: None})
|
||||
self.check_fission_status(
|
||||
enabled=True,
|
||||
experiment=ExperimentStatus.UNENROLLED,
|
||||
decision="enabledByDefault",
|
||||
)
|
||||
|
||||
self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
|
||||
self.restart()
|
||||
self.check_fission_status(
|
||||
enabled=True,
|
||||
experiment=ExperimentStatus.ENROLLED_TREATMENT,
|
||||
decision="experimentTreatment",
|
||||
)
|
||||
|
||||
self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
|
||||
self.restart()
|
||||
self.check_fission_status(
|
||||
enabled=False,
|
||||
experiment=ExperimentStatus.ENROLLED_CONTROL,
|
||||
decision="experimentControl",
|
||||
)
|
||||
|
||||
self.marionette.set_pref(Prefs.FISSION_AUTOSTART, True)
|
||||
self.check_fission_status(
|
||||
enabled=False,
|
||||
experiment=ExperimentStatus.ENROLLED_CONTROL,
|
||||
decision="experimentControl",
|
||||
dynamic=True,
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
self.marionette.get_pref(Prefs.ENROLLMENT_STATUS),
|
||||
ExperimentStatus.DISQUALIFIED,
|
||||
"Setting fission.autostart should disqualify",
|
||||
)
|
||||
|
||||
self.restart()
|
||||
self.check_fission_status(
|
||||
enabled=True,
|
||||
experiment=ExperimentStatus.DISQUALIFIED,
|
||||
decision="enabledByUserPref",
|
||||
)
|
||||
|
||||
app_version = self.execute_script("return Services.appinfo.version")
|
||||
self.restart(env={ENV_DISABLE_E10S: app_version})
|
||||
self.check_fission_status(
|
||||
enabled=False,
|
||||
experiment=ExperimentStatus.DISQUALIFIED,
|
||||
decision="disabledByE10sEnv",
|
||||
dynamic=True,
|
||||
)
|
||||
|
||||
def test_fission_startup(self):
|
||||
# Starting the browser with STARTUP_ENROLLMENT_STATUS set to treatment
|
||||
# should make the current session run under treatment.
|
||||
with self.full_restart() as profile:
|
||||
profile.set_preferences(
|
||||
{
|
||||
Prefs.STARTUP_ENROLLMENT_STATUS: ExperimentStatus.ENROLLED_TREATMENT,
|
||||
},
|
||||
filename="prefs.js",
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
self.marionette.get_pref(Prefs.ENROLLMENT_STATUS),
|
||||
ExperimentStatus.UNENROLLED,
|
||||
"Dynamic pref should be unenrolled",
|
||||
)
|
||||
self.assertEqual(
|
||||
self.marionette.get_pref(Prefs.STARTUP_ENROLLMENT_STATUS),
|
||||
ExperimentStatus.ENROLLED_TREATMENT,
|
||||
"Startup pref should be in treatment",
|
||||
)
|
||||
self.check_fission_status(
|
||||
enabled=True,
|
||||
experiment=ExperimentStatus.ENROLLED_TREATMENT,
|
||||
decision="experimentTreatment",
|
||||
)
|
||||
|
||||
# If normandy doesn't re-set `ENROLLMENT_STATUS` during the session, it
|
||||
# should be cleared back to disabled after a restart.
|
||||
self.marionette.restart(in_app=True, clean=False)
|
||||
|
||||
self.assertEqual(
|
||||
self.marionette.get_pref(Prefs.ENROLLMENT_STATUS),
|
||||
ExperimentStatus.UNENROLLED,
|
||||
"Should unenroll dynamic pref after shutdown",
|
||||
)
|
||||
self.assertEqual(
|
||||
self.marionette.get_pref(Prefs.STARTUP_ENROLLMENT_STATUS),
|
||||
ExperimentStatus.UNENROLLED,
|
||||
"Should unenroll startup pref after shutdown",
|
||||
)
|
||||
self.check_fission_status(
|
||||
enabled=True,
|
||||
experiment=ExperimentStatus.UNENROLLED,
|
||||
decision="enabledByDefault",
|
||||
)
|
||||
|
||||
# If the browser is started with a customized `fisison.autostart`,
|
||||
# while also enrolled in an experiment, the experiment should be
|
||||
# disqualified at startup.
|
||||
with self.full_restart() as profile:
|
||||
profile.set_preferences(
|
||||
{
|
||||
Prefs.FISSION_AUTOSTART: True,
|
||||
Prefs.STARTUP_ENROLLMENT_STATUS: ExperimentStatus.ENROLLED_TREATMENT,
|
||||
},
|
||||
filename="prefs.js",
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
self.marionette.get_pref(Prefs.ENROLLMENT_STATUS),
|
||||
ExperimentStatus.DISQUALIFIED,
|
||||
"Should disqualify dynamic pref on startup",
|
||||
)
|
||||
self.assertEqual(
|
||||
self.marionette.get_pref(Prefs.STARTUP_ENROLLMENT_STATUS),
|
||||
ExperimentStatus.DISQUALIFIED,
|
||||
"Should disqualify startup pref on startup",
|
||||
)
|
||||
|
||||
self.check_fission_status(
|
||||
enabled=True,
|
||||
experiment=ExperimentStatus.DISQUALIFIED,
|
||||
decision="enabledByUserPref",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -154,17 +154,6 @@ interface nsIXULRuntime : nsISupports
|
|||
*/
|
||||
readonly attribute boolean fissionAutostart;
|
||||
|
||||
/**
|
||||
* The user's enrollment status in the Fission experiment at process startup.
|
||||
* See `ExperimentStatus` for the potential values.
|
||||
*
|
||||
* Only available in the parent process.
|
||||
*
|
||||
* This value is guaranteed to remain constant for the length of a browser
|
||||
* session.
|
||||
*/
|
||||
readonly attribute nsIXULRuntime_ExperimentStatus fissionExperimentStatus;
|
||||
|
||||
/**
|
||||
* The deciding factor which caused Fission to be enabled or disabled in
|
||||
* this session. The string version is the same of the name of the constant,
|
||||
|
|
|
|||
Loading…
Reference in a new issue