1*6dbdd20aSAndroid Build Coastguard Worker<!doctype html> 2*6dbdd20aSAndroid Build Coastguard Worker<html lang="en-us"> 3*6dbdd20aSAndroid Build Coastguard Worker<head> 4*6dbdd20aSAndroid Build Coastguard Worker <meta charset="utf-8"> 5*6dbdd20aSAndroid Build Coastguard Worker <title>Perfetto UI</title> 6*6dbdd20aSAndroid Build Coastguard Worker <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" /> 7*6dbdd20aSAndroid Build Coastguard Worker <link rel="shortcut icon" id="favicon" type="image/png" href="data:image/png;base64,iVBORw0KGgo="> 8*6dbdd20aSAndroid Build Coastguard Worker</head> 9*6dbdd20aSAndroid Build Coastguard Worker<body data-perfetto_version='{"filled_by_build_js":"."}'> 10*6dbdd20aSAndroid Build Coastguard Worker <!-- 11*6dbdd20aSAndroid Build Coastguard Worker Don't add any content here. The whole <body> is replaced by 12*6dbdd20aSAndroid Build Coastguard Worker frontend/index.ts when bootstrapping. This is only used for very early 13*6dbdd20aSAndroid Build Coastguard Worker error reporting. 14*6dbdd20aSAndroid Build Coastguard Worker --> 15*6dbdd20aSAndroid Build Coastguard Worker <style> 16*6dbdd20aSAndroid Build Coastguard Worker #app_load_failure {opacity:0;transition:opacity 1s ease;position:absolute;overflow:auto;background:#080082;top:0;left:0;width:100%;height:100%;bottom:0;right:0;margin:0;opacity:0;user-select:text} 17*6dbdd20aSAndroid Build Coastguard Worker #app_load_failure > pre {color:#fff;position:absolute;margin:auto;white-space:pre-wrap;top:10vh;max-width:90vw;width:880px;left:0;right:0;font-size:16px;line-height:30px;font-weight:700} 18*6dbdd20aSAndroid Build Coastguard Worker #app_load_failure > pre span {background:#fff;color:#080082;padding:2px} 19*6dbdd20aSAndroid Build Coastguard Worker #app_load_failure_dbg { overflow-wrap: break-word; font-size: 12px; line-height: 1; font-weight: initial;} 20*6dbdd20aSAndroid Build Coastguard Worker #app_load_failure a {color:#fff} 21*6dbdd20aSAndroid Build Coastguard Worker #app_load { position: absolute; top: 0; left: 0; right:0; bottom: 0; background-color: #2c3e50;} 22*6dbdd20aSAndroid Build Coastguard Worker #app_load_spinner { margin: 30vh auto; width: 150px; height: 150px; border: 3px solid rgba(255,255,255,.3); border-radius: 50%; border-top-color: #fff; animation: app_load_spin 1s ease-in-out infinite; } 23*6dbdd20aSAndroid Build Coastguard Worker @keyframes app_load_spin { to { transform: rotate(360deg); } } 24*6dbdd20aSAndroid Build Coastguard Worker </style> 25*6dbdd20aSAndroid Build Coastguard Worker <div id="app_load"><div id="app_load_spinner"></div></div> 26*6dbdd20aSAndroid Build Coastguard Worker <div id="app_load_failure"> 27*6dbdd20aSAndroid Build Coastguard Worker<pre> 28*6dbdd20aSAndroid Build Coastguard Worker<span>Perfetto UI - An unrecoverable problem occurred</span> 29*6dbdd20aSAndroid Build Coastguard Worker 30*6dbdd20aSAndroid Build Coastguard WorkerIf you are seeing this message, something went wrong while loading the UI. 31*6dbdd20aSAndroid Build Coastguard WorkerIn most cases this is due to very slow or flaky network and it goes away by 32*6dbdd20aSAndroid Build Coastguard Workerdisabling and re-enabling WiFi or trying reloading. 33*6dbdd20aSAndroid Build Coastguard Worker 34*6dbdd20aSAndroid Build Coastguard WorkerIf the problem persists try these remediation steps: 35*6dbdd20aSAndroid Build Coastguard Worker 36*6dbdd20aSAndroid Build Coastguard Worker* Force-reload the page with Ctrl+Shift+R (Mac: Meta+Shift+R) or 37*6dbdd20aSAndroid Build Coastguard Worker Shift + click on the refresh button. 38*6dbdd20aSAndroid Build Coastguard Worker 39*6dbdd20aSAndroid Build Coastguard Worker* <a href="javascript:clearAllCaches();">Clear all the site storage and caches</a> and reload the page. 40*6dbdd20aSAndroid Build Coastguard Worker 41*6dbdd20aSAndroid Build Coastguard Worker* Clear the site data and caches from devtools, following <a target="_blank" href="https://developers.google.com/web/tools/chrome-devtools/storage/cache#deletecache">these instructions</a>. 42*6dbdd20aSAndroid Build Coastguard Worker 43*6dbdd20aSAndroid Build Coastguard WorkerIf none of this works, file a bug attaching logs and screenshots from devtools. 44*6dbdd20aSAndroid Build Coastguard Worker Googlers: <a href="http://go/perfetto-ui-bug" target="_blank">go/perfetto-ui-bug</a> 45*6dbdd20aSAndroid Build Coastguard Worker Non-googlers: <a href="https://github.com/google/perfetto/issues/new" target="_blank">github.com/google/perfetto/issues/new</a> 46*6dbdd20aSAndroid Build Coastguard Worker 47*6dbdd20aSAndroid Build Coastguard Worker<div id=app_load_failure_err></div> 48*6dbdd20aSAndroid Build Coastguard WorkerTechnical Information: 49*6dbdd20aSAndroid Build Coastguard Worker<div id=app_load_failure_dbg></div> 50*6dbdd20aSAndroid Build Coastguard Worker</pre> 51*6dbdd20aSAndroid Build Coastguard Worker </div> 52*6dbdd20aSAndroid Build Coastguard Worker <script type="text/javascript"> 53*6dbdd20aSAndroid Build Coastguard Worker 'use strict'; 54*6dbdd20aSAndroid Build Coastguard Worker (function () { 55*6dbdd20aSAndroid Build Coastguard Worker const TIMEOUT_MS = 120000; 56*6dbdd20aSAndroid Build Coastguard Worker let errTimerId = undefined; 57*6dbdd20aSAndroid Build Coastguard Worker 58*6dbdd20aSAndroid Build Coastguard Worker function errHandler(err) { 59*6dbdd20aSAndroid Build Coastguard Worker // Note: we deliberately don't clearTimeout(), which means that this 60*6dbdd20aSAndroid Build Coastguard Worker // handler is called also in the happy case when the UI loads. In that 61*6dbdd20aSAndroid Build Coastguard Worker // case, though, the onCssLoaded() in frontend/index.ts will empty the 62*6dbdd20aSAndroid Build Coastguard Worker // <body>, so |div| below will be null and this function becomes a 63*6dbdd20aSAndroid Build Coastguard Worker // no-op. 64*6dbdd20aSAndroid Build Coastguard Worker const div = document.getElementById('app_load_failure'); 65*6dbdd20aSAndroid Build Coastguard Worker if (!div) return; 66*6dbdd20aSAndroid Build Coastguard Worker div.style.opacity ='1'; 67*6dbdd20aSAndroid Build Coastguard Worker const errDom = document.getElementById('app_load_failure_err'); 68*6dbdd20aSAndroid Build Coastguard Worker if (!errDom) return; 69*6dbdd20aSAndroid Build Coastguard Worker console.error(err); 70*6dbdd20aSAndroid Build Coastguard Worker errDom.innerText += `${err}\n`; 71*6dbdd20aSAndroid Build Coastguard Worker const storageJson = JSON.stringify(window.localStorage); 72*6dbdd20aSAndroid Build Coastguard Worker const dbg = document.getElementById('app_load_failure_dbg'); 73*6dbdd20aSAndroid Build Coastguard Worker if (!dbg) return; 74*6dbdd20aSAndroid Build Coastguard Worker dbg.innerText = `LocalStorage: ${storageJson}\n`; 75*6dbdd20aSAndroid Build Coastguard Worker if (errTimerId !== undefined) clearTimeout(errTimerId); 76*6dbdd20aSAndroid Build Coastguard Worker } 77*6dbdd20aSAndroid Build Coastguard Worker 78*6dbdd20aSAndroid Build Coastguard Worker // For the 'Click here to clear all caches'. 79*6dbdd20aSAndroid Build Coastguard Worker window.clearAllCaches = async () => { 80*6dbdd20aSAndroid Build Coastguard Worker if (window.localStorage) window.localStorage.clear(); 81*6dbdd20aSAndroid Build Coastguard Worker if (window.sessionStorage) window.sessionStorage.clear(); 82*6dbdd20aSAndroid Build Coastguard Worker const promises = []; 83*6dbdd20aSAndroid Build Coastguard Worker if (window.caches) { 84*6dbdd20aSAndroid Build Coastguard Worker try { 85*6dbdd20aSAndroid Build Coastguard Worker const keys = await window.caches.keys(); 86*6dbdd20aSAndroid Build Coastguard Worker keys.forEach(k => promises.push(window.caches.delete(k))); 87*6dbdd20aSAndroid Build Coastguard Worker } catch (_) { 88*6dbdd20aSAndroid Build Coastguard Worker // TODO(288483453) 89*6dbdd20aSAndroid Build Coastguard Worker } 90*6dbdd20aSAndroid Build Coastguard Worker } 91*6dbdd20aSAndroid Build Coastguard Worker if (navigator.serviceWorker) { 92*6dbdd20aSAndroid Build Coastguard Worker const regs = await navigator.serviceWorker.getRegistrations(); 93*6dbdd20aSAndroid Build Coastguard Worker regs.forEach(reg => promises.push(reg.unregister())); 94*6dbdd20aSAndroid Build Coastguard Worker } 95*6dbdd20aSAndroid Build Coastguard Worker try { 96*6dbdd20aSAndroid Build Coastguard Worker await Promise.all(promises); 97*6dbdd20aSAndroid Build Coastguard Worker } catch (_) { 98*6dbdd20aSAndroid Build Coastguard Worker // TODO(288483453) 99*6dbdd20aSAndroid Build Coastguard Worker } 100*6dbdd20aSAndroid Build Coastguard Worker window.location.reload(); 101*6dbdd20aSAndroid Build Coastguard Worker } 102*6dbdd20aSAndroid Build Coastguard Worker 103*6dbdd20aSAndroid Build Coastguard Worker // If the frontend doesn't come up, make the error page above visible. 104*6dbdd20aSAndroid Build Coastguard Worker errTimerId = setTimeout(() => errHandler('Timed out'), TIMEOUT_MS); 105*6dbdd20aSAndroid Build Coastguard Worker window.onerror = errHandler; 106*6dbdd20aSAndroid Build Coastguard Worker window.onunhandledrejection = errHandler; 107*6dbdd20aSAndroid Build Coastguard Worker 108*6dbdd20aSAndroid Build Coastguard Worker const versionStr = document.body.dataset['perfetto_version'] || '{}'; 109*6dbdd20aSAndroid Build Coastguard Worker const versionMap = JSON.parse(versionStr); 110*6dbdd20aSAndroid Build Coastguard Worker const channel = localStorage.getItem('perfettoUiChannel') || 'stable'; 111*6dbdd20aSAndroid Build Coastguard Worker 112*6dbdd20aSAndroid Build Coastguard Worker // The '.' below is a fallback for the case of opening a pinned version 113*6dbdd20aSAndroid Build Coastguard Worker // (e.g., ui.perfetto.dev/v1.2.3./). In that case, the index.html has no 114*6dbdd20aSAndroid Build Coastguard Worker // valid version map; we want to load the frontend from the same 115*6dbdd20aSAndroid Build Coastguard Worker // sub-directory directory, hence ./frontend_bundle.js. 116*6dbdd20aSAndroid Build Coastguard Worker const version = versionMap[channel] || versionMap['stable'] || '.'; 117*6dbdd20aSAndroid Build Coastguard Worker 118*6dbdd20aSAndroid Build Coastguard Worker const script = document.createElement('script'); 119*6dbdd20aSAndroid Build Coastguard Worker script.async = true; 120*6dbdd20aSAndroid Build Coastguard Worker script.src = version + '/frontend_bundle.js'; 121*6dbdd20aSAndroid Build Coastguard Worker script.onerror = () => errHandler(`Failed to load ${script.src}`); 122*6dbdd20aSAndroid Build Coastguard Worker 123*6dbdd20aSAndroid Build Coastguard Worker document.head.append(script); 124*6dbdd20aSAndroid Build Coastguard Worker })(); 125*6dbdd20aSAndroid Build Coastguard Worker </script> 126*6dbdd20aSAndroid Build Coastguard Worker</body> 127*6dbdd20aSAndroid Build Coastguard Worker</html> 128