Bug 1639716 - [profiler] Remove the profiler disabling by private browsing r=jdescottes,gerald,devtools-backward-compat-reviewers

Differential Revision: https://phabricator.services.mozilla.com/D129417
This commit is contained in:
Julien Wajsberg 2022-01-26 17:26:21 +00:00
Родитель c52080ea1a
Коммит ff988ebecd
19 изменённых файлов: 29 добавлений и 441 удалений

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

@ -313,8 +313,6 @@
<label class="PanelUI-profiler-recording-label" data-l10n-id="profiler-popup-recording-screen" />
<spacer flex="1" />
</hbox>
<description id="PanelUI-profiler-locked"
data-l10n-id="profiler-popup-disabled" />
<hbox id="PanelUI-profiler-inactive" class="PanelUI-profiler-buttons">
<spacer flex="1" />
<vbox>

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

@ -165,10 +165,6 @@ profiler-popup-settings =
profiler-popup-edit-settings-button =
.label = Edit Settings…
profiler-popup-disabled =
The profiler is currently disabled, most likely due to a Private Browsing window
being open.
profiler-popup-recording-screen = Recording…
profiler-popup-start-recording-button =

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

@ -138,7 +138,6 @@ declare namespace MockedExports {
type Services = {
prefs: nsIPrefBranch;
profiler: {
CanProfile: () => boolean;
StartProfiler: (
entryCount: number,
interval: number,

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

@ -70,7 +70,6 @@ function selectElementsInPanelview(panelview) {
window: chromeWindow,
inactive: getElementById("PanelUI-profiler-inactive"),
active: getElementById("PanelUI-profiler-active"),
locked: getElementById("PanelUI-profiler-locked"),
presetDescription: getElementById("PanelUI-profiler-content-description"),
presetsEditSettings: getElementById(
"PanelUI-profiler-content-edit-settings"
@ -148,45 +147,17 @@ function createViewControllers(state, elements) {
updateProfilerState() {
const { Services } = lazy.Services();
/**
* Convert two boolean values into a "profilerState" enum.
*
* @type {"active" | "inactive" | "locked"}
*/
let profilerState = Services.profiler.IsActive() ? "active" : "inactive";
if (!Services.profiler.CanProfile()) {
// In private browsing mode, the profiler is locked.
profilerState = "locked";
}
switch (profilerState) {
case "active":
elements.inactive.hidden = true;
elements.active.hidden = false;
elements.settingsSection.hidden = true;
elements.contentRecording.hidden = false;
elements.locked.hidden = true;
break;
case "inactive":
elements.inactive.hidden = false;
elements.active.hidden = true;
elements.settingsSection.hidden = false;
elements.contentRecording.hidden = true;
elements.locked.hidden = true;
break;
case "locked": {
elements.inactive.hidden = true;
elements.active.hidden = true;
elements.settingsSection.hidden = true;
elements.contentRecording.hidden = true;
elements.locked.hidden = false;
// This works around XULElement height issues.
const { height } = elements.locked.getBoundingClientRect();
elements.locked.style.height = `${height}px`;
break;
}
default:
throw new Error("Unhandled profiler state.");
if (Services.profiler.IsActive()) {
elements.inactive.hidden = true;
elements.active.hidden = false;
elements.settingsSection.hidden = true;
elements.contentRecording.hidden = false;
} else {
elements.inactive.hidden = false;
elements.active.hidden = true;
elements.settingsSection.hidden = false;
elements.contentRecording.hidden = true;
}
},
@ -359,12 +330,7 @@ function addPopupEventHandlers(state, elements, view) {
const { Services } = lazy.Services();
// These are all events that can affect the current state of the profiler.
const events = [
"profiler-started",
"profiler-stopped",
"chrome-document-global-created", // This is potentially a private browser.
"last-pb-context-exited",
];
const events = ["profiler-started", "profiler-stopped"];
for (const event of events) {
Services.obs.addObserver(view.updateProfilerState, event);
state.cleanup.push(() => {

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

@ -25,7 +25,6 @@ skip-if = tsan # Frequently times out on TSan
[browser_devtools-onboarding.js]
[browser_devtools-presets.js]
[browser_devtools-previously-started.js]
[browser_devtools-private-window.js]
[browser_devtools-record-capture.js]
https_first_disabled = true
[browser_devtools-record-discard.js]
@ -41,14 +40,6 @@ https_first_disabled = true
https_first_disabled = true
[browser_popup-record-discard.js]
# The popupshown and popuphidden events are not firing correctly on linux, as of
# Bug 1625044. It could be because of the opening of a second private browsing
# window. There should be good enough coverage of this feature with it disabled
# on Linux. This bug appears to have been around for awhile see:
# Bug 941073. Also see: 1178420, 1115757, 1401049, 1269392
[browser_popup-private-browsing.js]
skip-if = os == 'linux'
[browser_split-toolbar-button.js]
https_first_disabled = true

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

@ -1,57 +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/. */
"use strict";
add_task(async function test() {
info("Test opening a private browsing window while the profiler is active.");
await withDevToolsPanel(async document => {
const getRecordingState = setupGetRecordingState(document);
const startRecording = await getActiveButtonFromText(
document,
"Start recording"
);
ok(!startRecording.disabled, "The start recording button is not disabled.");
is(
getRecordingState(),
"available-to-record",
"The panel is available to record."
);
const privateWindow = await BrowserTestUtils.openNewBrowserWindow({
private: true,
});
await getElementFromDocumentByText(
document,
"The profiler is disabled when Private Browsing is enabled"
);
ok(
startRecording.disabled,
"The start recording button is disabled when a private browsing window is open."
);
is(
getRecordingState(),
"locked-by-private-browsing",
"The client knows about the private window."
);
info("Closing the private window");
await BrowserTestUtils.closeWindow(privateWindow);
info("Finally wait for the start recording button to become active again.");
await getActiveButtonFromText(document, "Start recording");
is(
getRecordingState(),
"available-to-record",
"The panel is available to record again."
);
});
});

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

@ -1,48 +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/. */
"use strict";
add_task(async function test() {
info(
"Test that the profiler popup gets disabled when a private browsing window is open."
);
await makeSureProfilerPopupIsEnabled();
const getRecordingButton = () =>
getElementByLabel(document, "Start Recording");
const getDisabledMessage = () =>
getElementFromDocumentByText(
document,
"The profiler is currently disabled"
);
await withPopupOpen(window, async () => {
ok(await getRecordingButton(), "The start recording button is available");
});
info("Open a private browsing window.");
const privateWindow = await BrowserTestUtils.openNewBrowserWindow({
private: true,
});
info("Switch back to the main window and open the popup again.");
window.focus();
await withPopupOpen(window, async () => {
ok(await getDisabledMessage(), "The disabled message is displayed.");
});
info("Close the private window");
await BrowserTestUtils.closeWindow(privateWindow);
info("Make sure the first window is focused, and open the popup back up.");
window.focus();
await withPopupOpen(window, async () => {
ok(
await getRecordingButton(),
"The start recording button is available once again."
);
});
});

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

@ -77,8 +77,6 @@ disabled=TODO bug 1256350
[browser_perf-overview-selection-02.js]
[browser_perf-overview-selection-03.js]
[browser_perf-overview-time-interval.js]
[browser_perf-private-browsing.js]
disabled=TODO bug 1256350
[browser_perf-range-changed-render.js]
[browser_perf-recording-notices-01.js]
[browser_perf-recording-notices-02.js]

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

@ -1,136 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that the frontend is disabled when in private browsing mode.
*/
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const {
initPerformanceInNewTab,
teardownToolboxAndRemoveTab,
} = require("devtools/client/performance/test/helpers/panel-utils");
const {
startRecording,
stopRecording,
} = require("devtools/client/performance/test/helpers/actions");
const {
once,
} = require("devtools/client/performance/test/helpers/event-utils");
let gPanelWinTuples = [];
add_task(async function() {
await testNormalWindow();
await testPrivateWindow();
await testRecordingFailingInWindow(0);
await testRecordingFailingInWindow(1);
await teardownPerfInWindow(1, { shouldCloseWindow: true });
await testRecordingSucceedingInWindow(0);
await teardownPerfInWindow(0, { shouldCloseWindow: false });
gPanelWinTuples = null;
});
async function createPanelInNewWindow(options) {
const win = await BrowserTestUtils.openNewBrowserWindow(options);
return createPanelInWindow(options, win);
}
async function createPanelInWindow(options, win = window) {
const { panel } = await initPerformanceInNewTab(
{
url: SIMPLE_URL,
win: win,
},
options
);
gPanelWinTuples.push({ panel, win });
return { panel, win };
}
async function testNormalWindow() {
const { panel } = await createPanelInWindow({
private: false,
});
const { PerformanceView } = panel.panelWin;
is(
PerformanceView.getState(),
"empty",
"The initial state of the performance panel view is correct (1)."
);
}
async function testPrivateWindow() {
const { panel } = await createPanelInNewWindow({
private: true,
// The add-on SDK can't seem to be able to listen to "ready" or "close"
// events for private tabs. Don't really absolutely need to though.
dontWaitForTabReady: true,
});
const { PerformanceView } = panel.panelWin;
is(
PerformanceView.getState(),
"unavailable",
"The initial state of the performance panel view is correct (2)."
);
}
async function testRecordingFailingInWindow(index) {
const { panel } = gPanelWinTuples[index];
const { EVENTS, PerformanceController } = panel.panelWin;
const onRecordingStarted = () => {
ok(false, "Recording should not start while a private window is present.");
};
PerformanceController.on(EVENTS.RECORDING_STATE_CHANGE, onRecordingStarted);
const whenFailed = once(
PerformanceController,
EVENTS.BACKEND_FAILED_AFTER_RECORDING_START
);
PerformanceController.startRecording();
await whenFailed;
ok(true, "Recording has failed.");
PerformanceController.off(EVENTS.RECORDING_STATE_CHANGE, onRecordingStarted);
}
async function testRecordingSucceedingInWindow(index) {
const { panel } = gPanelWinTuples[index];
const { EVENTS, PerformanceController } = panel.panelWin;
const onRecordingFailed = () => {
ok(false, "Recording should start while now private windows are present.");
};
PerformanceController.on(
EVENTS.BACKEND_FAILED_AFTER_RECORDING_START,
onRecordingFailed
);
await startRecording(panel);
await stopRecording(panel);
ok(true, "Recording has succeeded.");
PerformanceController.off(
EVENTS.BACKEND_FAILED_AFTER_RECORDING_START,
onRecordingFailed
);
}
async function teardownPerfInWindow(index, options) {
const { panel, win } = gPanelWinTuples[index];
await teardownToolboxAndRemoveTab(panel);
if (options.shouldCloseWindow) {
win.close();
}
}

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

@ -555,14 +555,6 @@ class Profiler {
});
return { registered: response };
}
/**
* Checks whether or not the profiler module can currently run.
* @return boolean
*/
static canProfile() {
return Services.profiler.CanProfile();
}
}
/**

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

@ -289,16 +289,15 @@ PerformanceRecorder.prototype = {
/**
* Checks whether or not recording is currently supported. At the moment,
* this is only influenced by private browsing mode and the profiler.
* This function looks useless after some recent changes -- and it is.
* Removing it would involve a lot of cleanup including backward
* incompatibility work, which is a lot of work for this panel that's due to
* be removed in the near future.
*/
canCurrentlyRecord: function() {
let success = true;
const success = true;
const reasons = [];
if (!Profiler.canProfile()) {
success = false;
reasons.push("profiler-unavailable");
}
// Check other factors that will affect the possibility of successfully
// starting a recording here.

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

@ -11,12 +11,6 @@
const { Ci } = require("chrome");
const Services = require("Services");
loader.lazyImporter(
this,
"PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm"
);
loader.lazyRequireGetter(this, "EventEmitter", "devtools/shared/event-emitter");
loader.lazyRequireGetter(
this,
@ -41,11 +35,6 @@ class ActorReadyGeckoProfilerInterface {
};
Services.obs.addObserver(this._observer, "profiler-started");
Services.obs.addObserver(this._observer, "profiler-stopped");
Services.obs.addObserver(
this._observer,
"chrome-document-global-created"
);
Services.obs.addObserver(this._observer, "last-pb-context-exited");
}
EventEmitter.decorate(this);
@ -57,11 +46,6 @@ class ActorReadyGeckoProfilerInterface {
}
Services.obs.removeObserver(this._observer, "profiler-started");
Services.obs.removeObserver(this._observer, "profiler-stopped");
Services.obs.removeObserver(
this._observer,
"chrome-document-global-created"
);
Services.obs.removeObserver(this._observer, "last-pb-context-exited");
}
startProfiler(options) {
@ -172,13 +156,6 @@ class ActorReadyGeckoProfilerInterface {
return IS_SUPPORTED_PLATFORM;
}
isLockedForPrivateBrowsing() {
if (!IS_SUPPORTED_PLATFORM) {
return false;
}
return !Services.profiler.CanProfile();
}
/**
* Watch for events that happen within the browser. These can affect the
* current availability and state of the Gecko Profiler.
@ -187,17 +164,6 @@ class ActorReadyGeckoProfilerInterface {
// Note! If emitting new events make sure and update the list of bridged
// events in the perf actor.
switch (topic) {
case "chrome-document-global-created":
if (
subject.isChromeWindow &&
PrivateBrowsingUtils.isWindowPrivate(subject)
) {
this.emit("profile-locked-by-private-browsing");
}
break;
case "last-pb-context-exited":
this.emit("profile-unlocked-from-private-browsing");
break;
case "profiler-started":
const param = subject.QueryInterface(Ci.nsIProfilerStartParams);
this.emit(

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

@ -31,6 +31,10 @@ const perfDescription = {
"profiler-stopped": {
type: "profiler-stopped",
},
// @backward-compat { version 98 } These 2 events are not used anymore since
// Firefox 98. Instead we expose the information about private browsing in
// captured profile and show a warning in the profiler frontend UI. We can
// remove these 2 events once Firefox 98 hits release.
"profile-locked-by-private-browsing": {
type: "profile-locked-by-private-browsing",
},

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

@ -7,19 +7,13 @@ function ensureProfilerInitialized() {
// Starting and stopping the profiler with the "stackwalk" flag will cause the
// profiler's stackwalking features to be synchronously initialized. This
// should prevent us from not initializing BHR quickly enough.
if (!Services.profiler.CanProfile()) {
return false;
}
let features = ["stackwalk"];
Services.profiler.StartProfiler(1000, 10, features);
Services.profiler.StopProfiler();
return true;
}
add_task(async function childCauseHang() {
if (!ensureProfilerInitialized()) {
return;
}
ensureProfilerInitialized();
executeSoon(() => {
let startTime = Date.now();

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

@ -10,13 +10,9 @@ function ensureProfilerInitialized() {
// Starting and stopping the profiler with the "stackwalk" flag will cause the
// profiler's stackwalking features to be synchronously initialized. This
// should prevent us from not initializing BHR quickly enough.
if (!Services.profiler.CanProfile()) {
return false;
}
let features = ["stackwalk"];
Services.profiler.StartProfiler(1000, 10, features);
Services.profiler.StopProfiler();
return true;
}
add_task(async function test_BHRObserver() {
@ -25,9 +21,7 @@ add_task(async function test_BHRObserver() {
return;
}
if (!ensureProfilerInitialized()) {
return;
}
ensureProfilerInitialized();
let telSvc = Cc["@mozilla.org/bhr-telemetry-service;1"].getService()
.wrappedJSObject;

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

@ -60,13 +60,8 @@ async function hangAndWaitForReport(expectTestAnnotation) {
* of making sure that BHR is initialized as well.
*/
function ensureProfilerInitialized() {
if (!Services.profiler.CanProfile()) {
return false;
}
startProfiler();
stopProfiler();
return true;
}
function stopProfiler() {
@ -166,9 +161,7 @@ add_task(async function test_recording_annotations_and_markers() {
return;
}
if (!ensureProfilerInitialized()) {
return;
}
ensureProfilerInitialized();
Services.prefs.setBoolPref(
TelemetryUtils.Preferences.OverridePreRelease,
@ -270,9 +263,7 @@ add_task(async function test_updating_annotations_and_markers() {
return;
}
if (!ensureProfilerInitialized()) {
return;
}
ensureProfilerInitialized();
// First, we'll check to see if we can get a single annotation and
// profiler marker to be set.
@ -371,9 +362,7 @@ add_task(async function test_cancelling_annotations_and_markers() {
return;
}
if (!ensureProfilerInitialized()) {
return;
}
ensureProfilerInitialized();
// First, we'll check to see if we can get a single annotation and
// profiler marker to be set.

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

@ -34,7 +34,6 @@ interface nsIProfilerStartParams : nsISupports
[scriptable, builtinclass, uuid(ead3f75c-0e0e-4fbb-901c-1e5392ef5b2a)]
interface nsIProfiler : nsISupports
{
boolean CanProfile();
void StartProfiler(in uint32_t aEntries, in double aInterval,
in Array<AUTF8String> aFeatures,
[optional] in Array<AUTF8String> aFilters,

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

@ -27,7 +27,6 @@
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsILoadContext.h"
#include "nsIObserverService.h"
#include "nsIWebNavigation.h"
#include "nsLocalFile.h"
#include "nsMemory.h"
@ -45,65 +44,18 @@ using dom::AutoJSAPI;
using dom::Promise;
using std::string;
NS_IMPL_ISUPPORTS(nsProfiler, nsIProfiler, nsIObserver)
NS_IMPL_ISUPPORTS(nsProfiler, nsIProfiler)
nsProfiler::nsProfiler()
: mLockedForPrivateBrowsing(false),
mPendingProfiles(0),
mGathering(false) {}
nsProfiler::nsProfiler() : mPendingProfiles(0), mGathering(false) {}
nsProfiler::~nsProfiler() {
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
if (observerService) {
observerService->RemoveObserver(this, "chrome-document-global-created");
observerService->RemoveObserver(this, "last-pb-context-exited");
}
if (mSymbolTableThread) {
mSymbolTableThread->Shutdown();
}
ResetGathering();
}
nsresult nsProfiler::Init() {
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
if (observerService) {
observerService->AddObserver(this, "chrome-document-global-created", false);
observerService->AddObserver(this, "last-pb-context-exited", false);
}
return NS_OK;
}
NS_IMETHODIMP
nsProfiler::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData) {
// The profiler's handling of private browsing is as simple as possible: it
// is stopped when the first PB window opens, and left stopped when the last
// PB window closes.
if (strcmp(aTopic, "chrome-document-global-created") == 0) {
nsCOMPtr<nsIInterfaceRequestor> requestor = do_QueryInterface(aSubject);
nsCOMPtr<nsIWebNavigation> parentWebNav = do_GetInterface(requestor);
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(parentWebNav);
if (loadContext && loadContext->UsePrivateBrowsing() &&
!mLockedForPrivateBrowsing) {
mLockedForPrivateBrowsing = true;
// Allow profiling tests that trigger private browsing.
if (!xpc::IsInAutomation()) {
profiler_stop();
}
}
} else if (strcmp(aTopic, "last-pb-context-exited") == 0) {
mLockedForPrivateBrowsing = false;
}
return NS_OK;
}
NS_IMETHODIMP
nsProfiler::CanProfile(bool* aCanProfile) {
*aCanProfile = !mLockedForPrivateBrowsing;
return NS_OK;
}
nsresult nsProfiler::Init() { return NS_OK; }
static nsresult FillVectorFromStringArray(Vector<const char*>& aVector,
const nsTArray<nsCString>& aArray) {
@ -121,10 +73,6 @@ nsProfiler::StartProfiler(uint32_t aEntries, double aInterval,
const nsTArray<nsCString>& aFeatures,
const nsTArray<nsCString>& aFilters,
uint64_t aActiveTabID, double aDuration) {
if (mLockedForPrivateBrowsing) {
return NS_ERROR_NOT_AVAILABLE;
}
ResetGathering();
Vector<const char*> featureStringVector;

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

@ -13,18 +13,16 @@
#include "mozilla/ProfileJSONWriter.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/Vector.h"
#include "nsIObserver.h"
#include "nsIProfiler.h"
#include "nsITimer.h"
#include "nsServiceManagerUtils.h"
#include "ProfilerCodeAddressService.h"
class nsProfiler final : public nsIProfiler, public nsIObserver {
class nsProfiler final : public nsIProfiler {
public:
nsProfiler();
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
NS_DECL_NSIPROFILER
nsresult Init();
@ -52,8 +50,6 @@ class nsProfiler final : public nsIProfiler, public nsIObserver {
RefPtr<SymbolTablePromise> GetSymbolTableMozPromise(
const nsACString& aDebugPath, const nsACString& aBreakpadID);
bool mLockedForPrivateBrowsing;
struct ExitProfile {
nsCString mJSON;
uint64_t mBufferPositionAtGatherTime;