blob: 14b916d130277ba40144d84fb1942c6d44cade87 [file] [log] [blame]
# Copyright 2025 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import base64
from IPython.display import display, Javascript
def open_trace(trace):
"""Executes JavaScript to open a local trace in the Perfetto UI directly in
the browser.
Args:
trace: The trace file object
"""
trace_file_path = trace.trace_file
# Read the trace file content and encode in base64 to embed it in the
# JavaScript
with open(trace.trace_file, 'rb') as f:
trace_base64 = base64.b64encode(f.read()).decode('utf-8')
# Generate the JavaScript code to open the Perfetto UI and post the trace
# data. See:
# https://perfetto.dev/docs/visualization/deep-linking-to-perfetto-ui
js_code = f"""
const trace_base64 = "{trace_base64}";
const trace_title = "{trace_file_path}";
function base64ToArrayBuffer(base64) {{
const binary_string = window.atob(base64);
const len = binary_string.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {{
bytes[i] = binary_string.charCodeAt(i);
}}
return bytes.buffer;
}}
function openPerfettoUI() {{
const perfettoUI = window.open('https://ui.perfetto.dev');
if (!perfettoUI) {{
console.error('Error: Pop-up was blocked. Please allow pop-ups for this page.');
return;
}}
const traceBuffer = base64ToArrayBuffer(trace_base64);
const pingInterval = setInterval(() => {{
try {{
perfettoUI.postMessage('PING', 'https://ui.perfetto.dev');
}} catch (e) {{
console.error("Error sending PING:", e);
clearInterval(pingInterval);
}}
}}, 50);
const messageHandler = (event) => {{
if (event.origin !== 'https://ui.perfetto.dev') {{
return;
}}
if (event.data === 'PONG') {{
clearInterval(pingInterval);
window.removeEventListener('message', messageHandler); // Remove listener after receiving PONG
try {{
perfettoUI.postMessage({{
perfetto: {{
buffer: traceBuffer,
title: trace_title,
fileName: trace_title
}}
}}, 'https://ui.perfetto.dev');
}} catch (e) {{
console.error("Error posting trace data:", e);
}}
}}
}};
window.addEventListener('message', messageHandler);
}}
// Immediately call the function to open the Perfetto UI
openPerfettoUI();
"""
# Execute the JavaScript directly in the browser
display(Javascript(js_code))