Source code

Revision control

Copy as Markdown

Other Tools

/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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/. */
/* eslint-env mozilla/browser-window */
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs",
});
/**
* Helper for determining whether we're in the process of tearing down a
* private browsing session. Teardown is started when closing of the last
* private browsing window and stops once the last private browsing Browsing
* Context has been discarded.
* If a new private browsing window is opened during teardown telemetry is
* collected.
*/
export const PBMExitStatus = {
_isInitialized: false,
// Keeps track of whether a PBM session is currently exiting.
_isExiting: false,
/**
* Initialize the helper. Needs to be called before isExiting.
*/
init() {
// Init only once.
if (this._isInitialized) {
return;
}
this._isInitialized = true;
Services.obs.addObserver(this, "last-pb-context-exiting-granted");
Services.obs.addObserver(this, "last-pb-context-exited");
Services.ww.registerNotification(this);
},
/**
* Handler for PBM exited message.
*/
_handlePrivateBrowsingExitStop() {
// If we didn't see an exit start message don't record anything. This is for
// skipping features like the PBM reset button which directly dispatches
// "last-pb-context-exited" without all PBM windows being closed.
if (!this._isExiting) {
return;
}
this._isExiting = false;
// Increase counter for total private browsing sessions.
Glean.privateBrowsing.windowOpenDuringTeardown.addToDenominator(1);
},
/**
* Handler for new chrome windows opened. Collects telemetry if we hit the PBM
* teardown race condition.
* @param {ChromeWindow} subject - The Chrome window that has been opened.
*/
_handleDomWindowOpened(subject) {
if (
!this._isExiting ||
!lazy.PrivateBrowsingUtils.isWindowPrivate(subject)
) {
return;
}
// Set exiting flag to false. We don't expect to see a
// "last-pb-context-exited" message now that a new PBM window has been
// opened. The PBM session continues.
this._isExiting = false;
// Private browsing window opened while we're exiting private browsing.
// Increase counter for race condition.
Glean.privateBrowsing.windowOpenDuringTeardown.addToNumerator(1);
},
observe(subject, topic) {
if (topic == "last-pb-context-exiting-granted") {
this._isExiting = true;
} else if (topic == "last-pb-context-exited") {
this._handlePrivateBrowsingExitStop();
} else if (topic == "domwindowopened") {
this._handleDomWindowOpened(subject);
}
},
};