0

[OOBE] Frontend Tracing Utilities

Add a new command line switch that prints the timings from oobe_trace.js
and the necessary function for it.

Bug: b:266939445
Change-Id: Icc4a82f053f6c907a02cf4a1082163e80c16a971
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4340153
Reviewed-by: Danila Kuzmin <dkuzmin@google.com>
Cr-Commit-Position: refs/heads/main@{#1123269}
This commit is contained in:
Renato Silva
2023-03-28 20:59:07 +00:00
committed by Chromium LUCI CQ
parent 15ba70270a
commit a28e099954
5 changed files with 87 additions and 50 deletions
ash/constants
chrome/browser
resources
ui
webui
ash

@ -791,6 +791,10 @@ const char kOobeForceTabletFirstRun[] = "oobe-force-tablet-first-run";
const char kOobeLargeScreenSpecialScaling[] =
"oobe-large-screen-special-scaling";
// When present, prints the time it takes for OOBE's frontend to load.
// See go/oobe-frontend-trace-timings for details.
const char kOobePrintFrontendLoadTimings[] = "oobe-print-frontend-load-timings";
// Specifies directory for screenshots taken with OOBE UI Debugger.
const char kOobeScreenshotDirectory[] = "oobe-screenshot-dir";

@ -257,6 +257,8 @@ COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kOobeEulaUrlForTests[];
COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kOobeForceTabletFirstRun[];
COMPONENT_EXPORT(ASH_CONSTANTS)
extern const char kOobeLargeScreenSpecialScaling[];
COMPONENT_EXPORT(ASH_CONSTANTS)
extern const char kOobePrintFrontendLoadTimings[];
COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kOobeScreenshotDirectory[];
COMPONENT_EXPORT(ASH_CONSTANTS)
extern const char kOobeShowAccessibilityButtonOnMarketingOptInForTesting[];

@ -124,43 +124,40 @@ function initializeOobe() {
/**
* ----------- OOBE Execution Begins -----------
*/
(function() {
// Ensure that there is a global error listener when OOBE starts.
// This error listener is added in the main HTML document.
assert(window.OobeErrorStore, 'OobeErrorStore not present on global object!');
function startOobe() {
// Ensure that there is a global error listener when OOBE starts.
// This error listener is added in the main HTML document.
assert(window.OobeErrorStore, 'OobeErrorStore not present on global object!');
// Update localized strings at the document level.
Oobe.updateDocumentLocalizedStrings();
// Update localized strings at the document level.
Oobe.updateDocumentLocalizedStrings();
prepareGlobalValues(window);
prepareGlobalValues(window);
// Add common screens to the document.
addScreensToMainContainer(commonScreensList);
traceExecution(TraceEvent.COMMON_SCREENS_ADDED);
// Add common screens to the document.
addScreensToMainContainer(commonScreensList);
traceExecution(TraceEvent.COMMON_SCREENS_ADDED);
// Add OOBE or LOGIN screens to the document.
const isOobeFlow = loadTimeData.getBoolean('isOobeFlow');
if (isOobeFlow) {
addScreensToMainContainer(oobeScreensList);
traceExecution(TraceEvent.OOBE_SCREENS_ADDED);
} else {
addScreensToMainContainer(loginScreensList);
traceExecution(TraceEvent.LOGIN_SCREENS_ADDED);
// Add OOBE or LOGIN screens to the document.
const isOobeFlow = loadTimeData.getBoolean('isOobeFlow');
addScreensToMainContainer(isOobeFlow ? oobeScreensList : loginScreensList);
traceExecution(TraceEvent.REMAINING_SCREENS_ADDED);
// The default is to have the class 'oobe-display' in <body> for the OOBE
// flow. For the 'Add Person' flow, we remove it.
if (!isOobeFlow) {
document.body.classList.remove('oobe-display');
} else {
assert(
document.body.classList.contains('oobe-display'),
'The body of the document must contain oobe-display as a class for the OOBE flow!');
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initializeOobe);
} else {
initializeOobe();
}
}
// The default is to have the class 'oobe-display' in <body> for the OOBE
// flow. For the 'Add Person' flow, we remove it.
if (!isOobeFlow) {
document.body.classList.remove('oobe-display');
} else {
assert(
document.body.classList.contains('oobe-display'),
'The body of the document must contain oobe-display as a class for the OOBE flow!');
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initializeOobe);
} else {
initializeOobe();
}
})();
startOobe();

@ -18,13 +18,15 @@
*/
import {assert} from '//resources/ash/common/assert.js';
import {loadTimeData} from './i18n_setup.js';
assert(window.oobeInitializationBeginTimestamp);
export const TraceEvent = {
FIRST_LINE_AFTER_IMPORTS: 'FIRST_LINE_AFTER_IMPORTS',
COMMON_SCREENS_ADDED: 'COMMON_SCREENS_ADDED',
OOBE_SCREENS_ADDED: 'OOBE_SCREENS_ADDED',
LOGIN_SCREENS_ADDED: 'LOGIN_SCREENS_ADDED',
REMAINING_SCREENS_ADDED: 'REMAINING_SCREENS_ADDED',
DOM_CONTENT_LOADED: 'DOM_CONTENT_LOADED',
OOBE_INITIALIZED: 'OOBE_INITIALIZED',
FIRST_SCREEN_SHOWN: 'FIRST_SCREEN_SHOWN',
@ -37,14 +39,12 @@ export const TraceEvent = {
const eventLogs = [];
window.oobeTraceLogs = eventLogs;
function createEventEntry(traceEvent) {
assert(traceEvent in TraceEvent);
const currentTimestamp = new Date();
const delta = currentTimestamp - window.oobeInitializationBeginTimestamp;
const eventEntry = {};
eventEntry[traceEvent] = delta;
return eventEntry;
class EventEntry {
constructor(traceEventName) {
assert(traceEventName in TraceEvent);
this.name = traceEventName;
this.delta = new Date() - window.oobeInitializationBeginTimestamp;
}
}
let firstScreenShownEventLogged = false;
@ -52,8 +52,7 @@ let welcomeAnimationPlayEventLogged = false;
let firstOobeLottieEventLogged = false;
export function traceExecution(traceEvent) {
const eventEntry = createEventEntry(traceEvent);
eventLogs.push(eventEntry);
eventLogs.push(new EventEntry(traceEvent));
}
export function traceFirstScreenShown() {
@ -90,13 +89,44 @@ export function traceOobeLottieExecution() {
let scheduledLastOobeLottieTrace = null;
function maybeTraceLastOobeLottieInitialization() {
// Amount of time to wait until logging the last OOBE Lottie Initialization.
const LAST_OOBE_LOTTIE_TIMEOUT_MSECS = 5 * 1000;
const LAST_OOBE_LOTTIE_TIMEOUT_MSECS = 3 * 1000;
if (scheduledLastOobeLottieTrace) {
clearTimeout(scheduledLastOobeLottieTrace);
}
const entry = createEventEntry(TraceEvent.LAST_OOBE_LOTTIE_INITIALIZED);
scheduledLastOobeLottieTrace =
setTimeout(() => eventLogs.push(entry), LAST_OOBE_LOTTIE_TIMEOUT_MSECS);
const entry = new EventEntry(TraceEvent.LAST_OOBE_LOTTIE_INITIALIZED);
scheduledLastOobeLottieTrace = setTimeout(() => {
eventLogs.push(entry);
maybePrintTraces();
}, LAST_OOBE_LOTTIE_TIMEOUT_MSECS);
}
// Maybe output the timings to the console to be parsed when the command line
// switch 'oobe-print-frontend-timings' is present. More details can be found in
// go/oobe-frontend-trace-timings
function maybePrintTraces() {
if (!loadTimeData.getBoolean('printFrontendTimings')) {
return;
}
const EventPrintOrder = [
TraceEvent.FIRST_LINE_AFTER_IMPORTS,
TraceEvent.COMMON_SCREENS_ADDED,
TraceEvent.REMAINING_SCREENS_ADDED,
TraceEvent.DOM_CONTENT_LOADED,
TraceEvent.OOBE_INITIALIZED,
TraceEvent.FIRST_SCREEN_SHOWN,
TraceEvent.FIRST_OOBE_LOTTIE_INITIALIZED,
TraceEvent.LAST_OOBE_LOTTIE_INITIALIZED,
TraceEvent.WELCOME_ANIMATION_PLAYING,
];
let output = 'OOBE_TRACE_BEGIN_';
for (const eventName of EventPrintOrder) {
const matchingEvent = eventLogs.find(e => e.name === eventName);
output += matchingEvent ? matchingEvent.delta + ';' : 'NaN;';
}
output += '_OOBE_TRACE_END';
console.error(output);
}

@ -297,6 +297,10 @@ void CreateAndAddOobeUIDataSource(Profile* profile,
source->AddBoolean("isTouchpadScrollEnabled",
(features::IsOobeChoobeEnabled() &&
features::IsOobeTouchpadScrollEnabled()));
// Whether the timings in oobe_trace.js will be output to the console.
source->AddBoolean(
"printFrontendTimings",
command_line->HasSwitch(switches::kOobePrintFrontendLoadTimings));
// Configure shared resources
AddProductLogoResources(source);