1*6dbdd20aSAndroid Build Coastguard Worker// Copyright (C) 2018 The Android Open Source Project 2*6dbdd20aSAndroid Build Coastguard Worker// 3*6dbdd20aSAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*6dbdd20aSAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*6dbdd20aSAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*6dbdd20aSAndroid Build Coastguard Worker// 7*6dbdd20aSAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*6dbdd20aSAndroid Build Coastguard Worker// 9*6dbdd20aSAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*6dbdd20aSAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*6dbdd20aSAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*6dbdd20aSAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*6dbdd20aSAndroid Build Coastguard Worker// limitations under the License. 14*6dbdd20aSAndroid Build Coastguard Worker 15*6dbdd20aSAndroid Build Coastguard Worker// Keep this import first. 16*6dbdd20aSAndroid Build Coastguard Workerimport '../base/disposable_polyfill'; 17*6dbdd20aSAndroid Build Coastguard Workerimport '../base/static_initializers'; 18*6dbdd20aSAndroid Build Coastguard Workerimport NON_CORE_PLUGINS from '../gen/all_plugins'; 19*6dbdd20aSAndroid Build Coastguard Workerimport CORE_PLUGINS from '../gen/all_core_plugins'; 20*6dbdd20aSAndroid Build Coastguard Workerimport m from 'mithril'; 21*6dbdd20aSAndroid Build Coastguard Workerimport {defer} from '../base/deferred'; 22*6dbdd20aSAndroid Build Coastguard Workerimport {addErrorHandler, reportError} from '../base/logging'; 23*6dbdd20aSAndroid Build Coastguard Workerimport {featureFlags} from '../core/feature_flags'; 24*6dbdd20aSAndroid Build Coastguard Workerimport {initLiveReload} from '../core/live_reload'; 25*6dbdd20aSAndroid Build Coastguard Workerimport {raf} from '../core/raf_scheduler'; 26*6dbdd20aSAndroid Build Coastguard Workerimport {initWasm} from '../trace_processor/wasm_engine_proxy'; 27*6dbdd20aSAndroid Build Coastguard Workerimport {setScheduleFullRedraw} from '../widgets/raf'; 28*6dbdd20aSAndroid Build Coastguard Workerimport {UiMain} from './ui_main'; 29*6dbdd20aSAndroid Build Coastguard Workerimport {initCssConstants} from './css_constants'; 30*6dbdd20aSAndroid Build Coastguard Workerimport {registerDebugGlobals} from './debug'; 31*6dbdd20aSAndroid Build Coastguard Workerimport {maybeShowErrorDialog} from './error_dialog'; 32*6dbdd20aSAndroid Build Coastguard Workerimport {installFileDropHandler} from './file_drop_handler'; 33*6dbdd20aSAndroid Build Coastguard Workerimport {globals} from './globals'; 34*6dbdd20aSAndroid Build Coastguard Workerimport {HomePage} from './home_page'; 35*6dbdd20aSAndroid Build Coastguard Workerimport {postMessageHandler} from './post_message_handler'; 36*6dbdd20aSAndroid Build Coastguard Workerimport {Route, Router} from '../core/router'; 37*6dbdd20aSAndroid Build Coastguard Workerimport {CheckHttpRpcConnection} from './rpc_http_dialog'; 38*6dbdd20aSAndroid Build Coastguard Workerimport {maybeOpenTraceFromRoute} from './trace_url_handler'; 39*6dbdd20aSAndroid Build Coastguard Workerimport {ViewerPage} from './viewer_page'; 40*6dbdd20aSAndroid Build Coastguard Workerimport {HttpRpcEngine} from '../trace_processor/http_rpc_engine'; 41*6dbdd20aSAndroid Build Coastguard Workerimport {showModal} from '../widgets/modal'; 42*6dbdd20aSAndroid Build Coastguard Workerimport {IdleDetector} from './idle_detector'; 43*6dbdd20aSAndroid Build Coastguard Workerimport {IdleDetectorWindow} from './idle_detector_interface'; 44*6dbdd20aSAndroid Build Coastguard Workerimport {AppImpl} from '../core/app_impl'; 45*6dbdd20aSAndroid Build Coastguard Workerimport {addSqlTableTab} from '../components/details/sql_table_tab'; 46*6dbdd20aSAndroid Build Coastguard Workerimport {configureExtensions} from '../components/extensions'; 47*6dbdd20aSAndroid Build Coastguard Workerimport { 48*6dbdd20aSAndroid Build Coastguard Worker addDebugCounterTrack, 49*6dbdd20aSAndroid Build Coastguard Worker addDebugSliceTrack, 50*6dbdd20aSAndroid Build Coastguard Worker} from '../components/tracks/debug_tracks'; 51*6dbdd20aSAndroid Build Coastguard Workerimport {addVisualizedArgTracks} from '../components/tracks/visualized_args_tracks'; 52*6dbdd20aSAndroid Build Coastguard Workerimport {addQueryResultsTab} from '../components/query_table/query_result_tab'; 53*6dbdd20aSAndroid Build Coastguard Workerimport {assetSrc, initAssets} from '../base/assets'; 54*6dbdd20aSAndroid Build Coastguard Worker 55*6dbdd20aSAndroid Build Coastguard Workerconst CSP_WS_PERMISSIVE_PORT = featureFlags.register({ 56*6dbdd20aSAndroid Build Coastguard Worker id: 'cspAllowAnyWebsocketPort', 57*6dbdd20aSAndroid Build Coastguard Worker name: 'Relax Content Security Policy for 127.0.0.1:*', 58*6dbdd20aSAndroid Build Coastguard Worker description: 59*6dbdd20aSAndroid Build Coastguard Worker 'Allows simultaneous usage of several trace_processor_shell ' + 60*6dbdd20aSAndroid Build Coastguard Worker '-D --http-port 1234 by opening ' + 61*6dbdd20aSAndroid Build Coastguard Worker 'https://ui.perfetto.dev/#!/?rpc_port=1234', 62*6dbdd20aSAndroid Build Coastguard Worker defaultValue: false, 63*6dbdd20aSAndroid Build Coastguard Worker}); 64*6dbdd20aSAndroid Build Coastguard Worker 65*6dbdd20aSAndroid Build Coastguard Workerfunction routeChange(route: Route) { 66*6dbdd20aSAndroid Build Coastguard Worker raf.scheduleFullRedraw('force', () => { 67*6dbdd20aSAndroid Build Coastguard Worker if (route.fragment) { 68*6dbdd20aSAndroid Build Coastguard Worker // This needs to happen after the next redraw call. It's not enough 69*6dbdd20aSAndroid Build Coastguard Worker // to use setTimeout(..., 0); since that may occur before the 70*6dbdd20aSAndroid Build Coastguard Worker // redraw scheduled above. 71*6dbdd20aSAndroid Build Coastguard Worker const e = document.getElementById(route.fragment); 72*6dbdd20aSAndroid Build Coastguard Worker if (e) { 73*6dbdd20aSAndroid Build Coastguard Worker e.scrollIntoView(); 74*6dbdd20aSAndroid Build Coastguard Worker } 75*6dbdd20aSAndroid Build Coastguard Worker } 76*6dbdd20aSAndroid Build Coastguard Worker }); 77*6dbdd20aSAndroid Build Coastguard Worker maybeOpenTraceFromRoute(route); 78*6dbdd20aSAndroid Build Coastguard Worker} 79*6dbdd20aSAndroid Build Coastguard Worker 80*6dbdd20aSAndroid Build Coastguard Workerfunction setupContentSecurityPolicy() { 81*6dbdd20aSAndroid Build Coastguard Worker // Note: self and sha-xxx must be quoted, urls data: and blob: must not. 82*6dbdd20aSAndroid Build Coastguard Worker 83*6dbdd20aSAndroid Build Coastguard Worker let rpcPolicy = [ 84*6dbdd20aSAndroid Build Coastguard Worker 'http://127.0.0.1:9001', // For trace_processor_shell --httpd. 85*6dbdd20aSAndroid Build Coastguard Worker 'ws://127.0.0.1:9001', // Ditto, for the websocket RPC. 86*6dbdd20aSAndroid Build Coastguard Worker ]; 87*6dbdd20aSAndroid Build Coastguard Worker if (CSP_WS_PERMISSIVE_PORT.get()) { 88*6dbdd20aSAndroid Build Coastguard Worker const route = Router.parseUrl(window.location.href); 89*6dbdd20aSAndroid Build Coastguard Worker if (/^\d+$/.exec(route.args.rpc_port ?? '')) { 90*6dbdd20aSAndroid Build Coastguard Worker rpcPolicy = [ 91*6dbdd20aSAndroid Build Coastguard Worker `http://127.0.0.1:${route.args.rpc_port}`, 92*6dbdd20aSAndroid Build Coastguard Worker `ws://127.0.0.1:${route.args.rpc_port}`, 93*6dbdd20aSAndroid Build Coastguard Worker ]; 94*6dbdd20aSAndroid Build Coastguard Worker } 95*6dbdd20aSAndroid Build Coastguard Worker } 96*6dbdd20aSAndroid Build Coastguard Worker const policy = { 97*6dbdd20aSAndroid Build Coastguard Worker 'default-src': [ 98*6dbdd20aSAndroid Build Coastguard Worker `'self'`, 99*6dbdd20aSAndroid Build Coastguard Worker // Google Tag Manager bootstrap. 100*6dbdd20aSAndroid Build Coastguard Worker `'sha256-LirUKeorCU4uRNtNzr8tlB11uy8rzrdmqHCX38JSwHY='`, 101*6dbdd20aSAndroid Build Coastguard Worker ], 102*6dbdd20aSAndroid Build Coastguard Worker 'script-src': [ 103*6dbdd20aSAndroid Build Coastguard Worker `'self'`, 104*6dbdd20aSAndroid Build Coastguard Worker // TODO(b/201596551): this is required for Wasm after crrev.com/c/3179051 105*6dbdd20aSAndroid Build Coastguard Worker // and should be replaced with 'wasm-unsafe-eval'. 106*6dbdd20aSAndroid Build Coastguard Worker `'unsafe-eval'`, 107*6dbdd20aSAndroid Build Coastguard Worker 'https://*.google.com', 108*6dbdd20aSAndroid Build Coastguard Worker 'https://*.googleusercontent.com', 109*6dbdd20aSAndroid Build Coastguard Worker 'https://www.googletagmanager.com', 110*6dbdd20aSAndroid Build Coastguard Worker 'https://*.google-analytics.com', 111*6dbdd20aSAndroid Build Coastguard Worker ], 112*6dbdd20aSAndroid Build Coastguard Worker 'object-src': ['none'], 113*6dbdd20aSAndroid Build Coastguard Worker 'connect-src': [ 114*6dbdd20aSAndroid Build Coastguard Worker `'self'`, 115*6dbdd20aSAndroid Build Coastguard Worker 'ws://127.0.0.1:8037', // For the adb websocket server. 116*6dbdd20aSAndroid Build Coastguard Worker 'https://*.google-analytics.com', 117*6dbdd20aSAndroid Build Coastguard Worker 'https://*.googleapis.com', // For Google Cloud Storage fetches. 118*6dbdd20aSAndroid Build Coastguard Worker 'blob:', 119*6dbdd20aSAndroid Build Coastguard Worker 'data:', 120*6dbdd20aSAndroid Build Coastguard Worker ].concat(rpcPolicy), 121*6dbdd20aSAndroid Build Coastguard Worker 'img-src': [ 122*6dbdd20aSAndroid Build Coastguard Worker `'self'`, 123*6dbdd20aSAndroid Build Coastguard Worker 'data:', 124*6dbdd20aSAndroid Build Coastguard Worker 'blob:', 125*6dbdd20aSAndroid Build Coastguard Worker 'https://*.google-analytics.com', 126*6dbdd20aSAndroid Build Coastguard Worker 'https://www.googletagmanager.com', 127*6dbdd20aSAndroid Build Coastguard Worker 'https://*.googleapis.com', 128*6dbdd20aSAndroid Build Coastguard Worker ], 129*6dbdd20aSAndroid Build Coastguard Worker 'style-src': [`'self'`, `'unsafe-inline'`], 130*6dbdd20aSAndroid Build Coastguard Worker 'navigate-to': ['https://*.perfetto.dev', 'self'], 131*6dbdd20aSAndroid Build Coastguard Worker }; 132*6dbdd20aSAndroid Build Coastguard Worker const meta = document.createElement('meta'); 133*6dbdd20aSAndroid Build Coastguard Worker meta.httpEquiv = 'Content-Security-Policy'; 134*6dbdd20aSAndroid Build Coastguard Worker let policyStr = ''; 135*6dbdd20aSAndroid Build Coastguard Worker for (const [key, list] of Object.entries(policy)) { 136*6dbdd20aSAndroid Build Coastguard Worker policyStr += `${key} ${list.join(' ')}; `; 137*6dbdd20aSAndroid Build Coastguard Worker } 138*6dbdd20aSAndroid Build Coastguard Worker meta.content = policyStr; 139*6dbdd20aSAndroid Build Coastguard Worker document.head.appendChild(meta); 140*6dbdd20aSAndroid Build Coastguard Worker} 141*6dbdd20aSAndroid Build Coastguard Worker 142*6dbdd20aSAndroid Build Coastguard Workerfunction main() { 143*6dbdd20aSAndroid Build Coastguard Worker // Setup content security policy before anything else. 144*6dbdd20aSAndroid Build Coastguard Worker setupContentSecurityPolicy(); 145*6dbdd20aSAndroid Build Coastguard Worker initAssets(); 146*6dbdd20aSAndroid Build Coastguard Worker AppImpl.initialize({ 147*6dbdd20aSAndroid Build Coastguard Worker initialRouteArgs: Router.parseUrl(window.location.href).args, 148*6dbdd20aSAndroid Build Coastguard Worker }); 149*6dbdd20aSAndroid Build Coastguard Worker 150*6dbdd20aSAndroid Build Coastguard Worker // Wire up raf for widgets. 151*6dbdd20aSAndroid Build Coastguard Worker setScheduleFullRedraw((force?: 'force') => raf.scheduleFullRedraw(force)); 152*6dbdd20aSAndroid Build Coastguard Worker 153*6dbdd20aSAndroid Build Coastguard Worker // Load the css. The load is asynchronous and the CSS is not ready by the time 154*6dbdd20aSAndroid Build Coastguard Worker // appendChild returns. 155*6dbdd20aSAndroid Build Coastguard Worker const cssLoadPromise = defer<void>(); 156*6dbdd20aSAndroid Build Coastguard Worker const css = document.createElement('link'); 157*6dbdd20aSAndroid Build Coastguard Worker css.rel = 'stylesheet'; 158*6dbdd20aSAndroid Build Coastguard Worker css.href = assetSrc('perfetto.css'); 159*6dbdd20aSAndroid Build Coastguard Worker css.onload = () => cssLoadPromise.resolve(); 160*6dbdd20aSAndroid Build Coastguard Worker css.onerror = (err) => cssLoadPromise.reject(err); 161*6dbdd20aSAndroid Build Coastguard Worker const favicon = document.head.querySelector('#favicon'); 162*6dbdd20aSAndroid Build Coastguard Worker if (favicon instanceof HTMLLinkElement) { 163*6dbdd20aSAndroid Build Coastguard Worker favicon.href = assetSrc('assets/favicon.png'); 164*6dbdd20aSAndroid Build Coastguard Worker } 165*6dbdd20aSAndroid Build Coastguard Worker 166*6dbdd20aSAndroid Build Coastguard Worker // Load the script to detect if this is a Googler (see comments on globals.ts) 167*6dbdd20aSAndroid Build Coastguard Worker // and initialize GA after that (or after a timeout if something goes wrong). 168*6dbdd20aSAndroid Build Coastguard Worker function initAnalyticsOnScriptLoad() { 169*6dbdd20aSAndroid Build Coastguard Worker AppImpl.instance.analytics.initialize(globals.isInternalUser); 170*6dbdd20aSAndroid Build Coastguard Worker } 171*6dbdd20aSAndroid Build Coastguard Worker const script = document.createElement('script'); 172*6dbdd20aSAndroid Build Coastguard Worker script.src = 173*6dbdd20aSAndroid Build Coastguard Worker 'https://storage.cloud.google.com/perfetto-ui-internal/is_internal_user.js'; 174*6dbdd20aSAndroid Build Coastguard Worker script.async = true; 175*6dbdd20aSAndroid Build Coastguard Worker script.onerror = () => initAnalyticsOnScriptLoad(); 176*6dbdd20aSAndroid Build Coastguard Worker script.onload = () => initAnalyticsOnScriptLoad(); 177*6dbdd20aSAndroid Build Coastguard Worker setTimeout(() => initAnalyticsOnScriptLoad(), 5000); 178*6dbdd20aSAndroid Build Coastguard Worker 179*6dbdd20aSAndroid Build Coastguard Worker document.head.append(script, css); 180*6dbdd20aSAndroid Build Coastguard Worker 181*6dbdd20aSAndroid Build Coastguard Worker // Route errors to both the UI bugreport dialog and Analytics (if enabled). 182*6dbdd20aSAndroid Build Coastguard Worker addErrorHandler(maybeShowErrorDialog); 183*6dbdd20aSAndroid Build Coastguard Worker addErrorHandler((e) => AppImpl.instance.analytics.logError(e)); 184*6dbdd20aSAndroid Build Coastguard Worker 185*6dbdd20aSAndroid Build Coastguard Worker // Add Error handlers for JS error and for uncaught exceptions in promises. 186*6dbdd20aSAndroid Build Coastguard Worker window.addEventListener('error', (e) => reportError(e)); 187*6dbdd20aSAndroid Build Coastguard Worker window.addEventListener('unhandledrejection', (e) => reportError(e)); 188*6dbdd20aSAndroid Build Coastguard Worker 189*6dbdd20aSAndroid Build Coastguard Worker initWasm(); 190*6dbdd20aSAndroid Build Coastguard Worker AppImpl.instance.serviceWorkerController.install(); 191*6dbdd20aSAndroid Build Coastguard Worker 192*6dbdd20aSAndroid Build Coastguard Worker // Put debug variables in the global scope for better debugging. 193*6dbdd20aSAndroid Build Coastguard Worker registerDebugGlobals(); 194*6dbdd20aSAndroid Build Coastguard Worker 195*6dbdd20aSAndroid Build Coastguard Worker // Prevent pinch zoom. 196*6dbdd20aSAndroid Build Coastguard Worker document.body.addEventListener( 197*6dbdd20aSAndroid Build Coastguard Worker 'wheel', 198*6dbdd20aSAndroid Build Coastguard Worker (e: MouseEvent) => { 199*6dbdd20aSAndroid Build Coastguard Worker if (e.ctrlKey) e.preventDefault(); 200*6dbdd20aSAndroid Build Coastguard Worker }, 201*6dbdd20aSAndroid Build Coastguard Worker {passive: false}, 202*6dbdd20aSAndroid Build Coastguard Worker ); 203*6dbdd20aSAndroid Build Coastguard Worker 204*6dbdd20aSAndroid Build Coastguard Worker cssLoadPromise.then(() => onCssLoaded()); 205*6dbdd20aSAndroid Build Coastguard Worker 206*6dbdd20aSAndroid Build Coastguard Worker if (AppImpl.instance.testingMode) { 207*6dbdd20aSAndroid Build Coastguard Worker document.body.classList.add('testing'); 208*6dbdd20aSAndroid Build Coastguard Worker } 209*6dbdd20aSAndroid Build Coastguard Worker 210*6dbdd20aSAndroid Build Coastguard Worker (window as {} as IdleDetectorWindow).waitForPerfettoIdle = (ms?: number) => { 211*6dbdd20aSAndroid Build Coastguard Worker return new IdleDetector().waitForPerfettoIdle(ms); 212*6dbdd20aSAndroid Build Coastguard Worker }; 213*6dbdd20aSAndroid Build Coastguard Worker} 214*6dbdd20aSAndroid Build Coastguard Worker 215*6dbdd20aSAndroid Build Coastguard Workerfunction onCssLoaded() { 216*6dbdd20aSAndroid Build Coastguard Worker initCssConstants(); 217*6dbdd20aSAndroid Build Coastguard Worker // Clear all the contents of the initial page (e.g. the <pre> error message) 218*6dbdd20aSAndroid Build Coastguard Worker // And replace it with the root <main> element which will be used by mithril. 219*6dbdd20aSAndroid Build Coastguard Worker document.body.innerHTML = ''; 220*6dbdd20aSAndroid Build Coastguard Worker 221*6dbdd20aSAndroid Build Coastguard Worker const pages = AppImpl.instance.pages; 222*6dbdd20aSAndroid Build Coastguard Worker const traceless = true; 223*6dbdd20aSAndroid Build Coastguard Worker pages.registerPage({route: '/', traceless, page: HomePage}); 224*6dbdd20aSAndroid Build Coastguard Worker pages.registerPage({route: '/viewer', page: ViewerPage}); 225*6dbdd20aSAndroid Build Coastguard Worker const router = new Router(); 226*6dbdd20aSAndroid Build Coastguard Worker router.onRouteChanged = routeChange; 227*6dbdd20aSAndroid Build Coastguard Worker 228*6dbdd20aSAndroid Build Coastguard Worker // Mount the main mithril component. This also forces a sync render pass. 229*6dbdd20aSAndroid Build Coastguard Worker raf.mount(document.body, UiMain); 230*6dbdd20aSAndroid Build Coastguard Worker 231*6dbdd20aSAndroid Build Coastguard Worker if ( 232*6dbdd20aSAndroid Build Coastguard Worker (location.origin.startsWith('http://localhost:') || 233*6dbdd20aSAndroid Build Coastguard Worker location.origin.startsWith('http://127.0.0.1:')) && 234*6dbdd20aSAndroid Build Coastguard Worker !AppImpl.instance.embeddedMode && 235*6dbdd20aSAndroid Build Coastguard Worker !AppImpl.instance.testingMode 236*6dbdd20aSAndroid Build Coastguard Worker ) { 237*6dbdd20aSAndroid Build Coastguard Worker initLiveReload(); 238*6dbdd20aSAndroid Build Coastguard Worker } 239*6dbdd20aSAndroid Build Coastguard Worker 240*6dbdd20aSAndroid Build Coastguard Worker // Will update the chip on the sidebar footer that notifies that the RPC is 241*6dbdd20aSAndroid Build Coastguard Worker // connected. Has no effect on the controller (which will repeat this check 242*6dbdd20aSAndroid Build Coastguard Worker // before creating a new engine). 243*6dbdd20aSAndroid Build Coastguard Worker // Don't auto-open any trace URLs until we get a response here because we may 244*6dbdd20aSAndroid Build Coastguard Worker // accidentially clober the state of an open trace processor instance 245*6dbdd20aSAndroid Build Coastguard Worker // otherwise. 246*6dbdd20aSAndroid Build Coastguard Worker maybeChangeRpcPortFromFragment(); 247*6dbdd20aSAndroid Build Coastguard Worker CheckHttpRpcConnection().then(() => { 248*6dbdd20aSAndroid Build Coastguard Worker const route = Router.parseUrl(window.location.href); 249*6dbdd20aSAndroid Build Coastguard Worker if (!AppImpl.instance.embeddedMode) { 250*6dbdd20aSAndroid Build Coastguard Worker installFileDropHandler(); 251*6dbdd20aSAndroid Build Coastguard Worker } 252*6dbdd20aSAndroid Build Coastguard Worker 253*6dbdd20aSAndroid Build Coastguard Worker // Don't allow postMessage or opening trace from route when the user says 254*6dbdd20aSAndroid Build Coastguard Worker // that they want to reuse the already loaded trace in trace processor. 255*6dbdd20aSAndroid Build Coastguard Worker const traceSource = AppImpl.instance.trace?.traceInfo.source; 256*6dbdd20aSAndroid Build Coastguard Worker if (traceSource && traceSource.type === 'HTTP_RPC') { 257*6dbdd20aSAndroid Build Coastguard Worker return; 258*6dbdd20aSAndroid Build Coastguard Worker } 259*6dbdd20aSAndroid Build Coastguard Worker 260*6dbdd20aSAndroid Build Coastguard Worker // Add support for opening traces from postMessage(). 261*6dbdd20aSAndroid Build Coastguard Worker window.addEventListener('message', postMessageHandler, {passive: true}); 262*6dbdd20aSAndroid Build Coastguard Worker 263*6dbdd20aSAndroid Build Coastguard Worker // Handles the initial ?local_cache_key=123 or ?s=permalink or ?url=... 264*6dbdd20aSAndroid Build Coastguard Worker // cases. 265*6dbdd20aSAndroid Build Coastguard Worker routeChange(route); 266*6dbdd20aSAndroid Build Coastguard Worker }); 267*6dbdd20aSAndroid Build Coastguard Worker 268*6dbdd20aSAndroid Build Coastguard Worker // Initialize plugins, now that we are ready to go. 269*6dbdd20aSAndroid Build Coastguard Worker const pluginManager = AppImpl.instance.plugins; 270*6dbdd20aSAndroid Build Coastguard Worker CORE_PLUGINS.forEach((p) => pluginManager.registerPlugin(p)); 271*6dbdd20aSAndroid Build Coastguard Worker NON_CORE_PLUGINS.forEach((p) => pluginManager.registerPlugin(p)); 272*6dbdd20aSAndroid Build Coastguard Worker const route = Router.parseUrl(window.location.href); 273*6dbdd20aSAndroid Build Coastguard Worker const overrides = (route.args.enablePlugins ?? '').split(','); 274*6dbdd20aSAndroid Build Coastguard Worker pluginManager.activatePlugins(overrides); 275*6dbdd20aSAndroid Build Coastguard Worker} 276*6dbdd20aSAndroid Build Coastguard Worker 277*6dbdd20aSAndroid Build Coastguard Worker// If the URL is /#!?rpc_port=1234, change the default RPC port. 278*6dbdd20aSAndroid Build Coastguard Worker// For security reasons, this requires toggling a flag. Detect this and tell the 279*6dbdd20aSAndroid Build Coastguard Worker// user what to do in this case. 280*6dbdd20aSAndroid Build Coastguard Workerfunction maybeChangeRpcPortFromFragment() { 281*6dbdd20aSAndroid Build Coastguard Worker const route = Router.parseUrl(window.location.href); 282*6dbdd20aSAndroid Build Coastguard Worker if (route.args.rpc_port !== undefined) { 283*6dbdd20aSAndroid Build Coastguard Worker if (!CSP_WS_PERMISSIVE_PORT.get()) { 284*6dbdd20aSAndroid Build Coastguard Worker showModal({ 285*6dbdd20aSAndroid Build Coastguard Worker title: 'Using a different port requires a flag change', 286*6dbdd20aSAndroid Build Coastguard Worker content: m( 287*6dbdd20aSAndroid Build Coastguard Worker 'div', 288*6dbdd20aSAndroid Build Coastguard Worker m( 289*6dbdd20aSAndroid Build Coastguard Worker 'span', 290*6dbdd20aSAndroid Build Coastguard Worker 'For security reasons before connecting to a non-standard ' + 291*6dbdd20aSAndroid Build Coastguard Worker 'TraceProcessor port you need to manually enable the flag to ' + 292*6dbdd20aSAndroid Build Coastguard Worker 'relax the Content Security Policy and restart the UI.', 293*6dbdd20aSAndroid Build Coastguard Worker ), 294*6dbdd20aSAndroid Build Coastguard Worker ), 295*6dbdd20aSAndroid Build Coastguard Worker buttons: [ 296*6dbdd20aSAndroid Build Coastguard Worker { 297*6dbdd20aSAndroid Build Coastguard Worker text: 'Take me to the flags page', 298*6dbdd20aSAndroid Build Coastguard Worker primary: true, 299*6dbdd20aSAndroid Build Coastguard Worker action: () => Router.navigate('#!/flags/cspAllowAnyWebsocketPort'), 300*6dbdd20aSAndroid Build Coastguard Worker }, 301*6dbdd20aSAndroid Build Coastguard Worker ], 302*6dbdd20aSAndroid Build Coastguard Worker }); 303*6dbdd20aSAndroid Build Coastguard Worker } else { 304*6dbdd20aSAndroid Build Coastguard Worker HttpRpcEngine.rpcPort = route.args.rpc_port; 305*6dbdd20aSAndroid Build Coastguard Worker } 306*6dbdd20aSAndroid Build Coastguard Worker } 307*6dbdd20aSAndroid Build Coastguard Worker} 308*6dbdd20aSAndroid Build Coastguard Worker 309*6dbdd20aSAndroid Build Coastguard Worker// TODO(primiano): this injection is to break a cirular dependency. See 310*6dbdd20aSAndroid Build Coastguard Worker// comment in sql_table_tab_interface.ts. Remove once we add an extension 311*6dbdd20aSAndroid Build Coastguard Worker// point for context menus. 312*6dbdd20aSAndroid Build Coastguard WorkerconfigureExtensions({ 313*6dbdd20aSAndroid Build Coastguard Worker addDebugCounterTrack, 314*6dbdd20aSAndroid Build Coastguard Worker addDebugSliceTrack, 315*6dbdd20aSAndroid Build Coastguard Worker addVisualizedArgTracks, 316*6dbdd20aSAndroid Build Coastguard Worker addSqlTableTab, 317*6dbdd20aSAndroid Build Coastguard Worker addQueryResultsTab, 318*6dbdd20aSAndroid Build Coastguard Worker}); 319*6dbdd20aSAndroid Build Coastguard Worker 320*6dbdd20aSAndroid Build Coastguard Workermain(); 321