xref: /aosp_15_r20/external/perfetto/ui/src/bigtrace/index.ts (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker// Copyright (C) 2023 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/static_initializers';
17*6dbdd20aSAndroid Build Coastguard Workerimport m from 'mithril';
18*6dbdd20aSAndroid Build Coastguard Workerimport {defer} from '../base/deferred';
19*6dbdd20aSAndroid Build Coastguard Workerimport {reportError, addErrorHandler, ErrorDetails} from '../base/logging';
20*6dbdd20aSAndroid Build Coastguard Workerimport {initLiveReloadIfLocalhost} from '../core/live_reload';
21*6dbdd20aSAndroid Build Coastguard Workerimport {raf} from '../core/raf_scheduler';
22*6dbdd20aSAndroid Build Coastguard Workerimport {setScheduleFullRedraw} from '../widgets/raf';
23*6dbdd20aSAndroid Build Coastguard Worker
24*6dbdd20aSAndroid Build Coastguard Workerfunction getRoot() {
25*6dbdd20aSAndroid Build Coastguard Worker  // Works out the root directory where the content should be served from
26*6dbdd20aSAndroid Build Coastguard Worker  // e.g. `http://origin/v1.2.3/`.
27*6dbdd20aSAndroid Build Coastguard Worker  const script = document.currentScript as HTMLScriptElement;
28*6dbdd20aSAndroid Build Coastguard Worker
29*6dbdd20aSAndroid Build Coastguard Worker  // Needed for DOM tests, that do not have script element.
30*6dbdd20aSAndroid Build Coastguard Worker  if (script === null) {
31*6dbdd20aSAndroid Build Coastguard Worker    return '';
32*6dbdd20aSAndroid Build Coastguard Worker  }
33*6dbdd20aSAndroid Build Coastguard Worker
34*6dbdd20aSAndroid Build Coastguard Worker  let root = script.src;
35*6dbdd20aSAndroid Build Coastguard Worker  root = root.substr(0, root.lastIndexOf('/') + 1);
36*6dbdd20aSAndroid Build Coastguard Worker  return root;
37*6dbdd20aSAndroid Build Coastguard Worker}
38*6dbdd20aSAndroid Build Coastguard Worker
39*6dbdd20aSAndroid Build Coastguard Workerfunction setupContentSecurityPolicy() {
40*6dbdd20aSAndroid Build Coastguard Worker  // Note: self and sha-xxx must be quoted, urls data: and blob: must not.
41*6dbdd20aSAndroid Build Coastguard Worker  const policy = {
42*6dbdd20aSAndroid Build Coastguard Worker    'default-src': [
43*6dbdd20aSAndroid Build Coastguard Worker      `'self'`,
44*6dbdd20aSAndroid Build Coastguard Worker    ],
45*6dbdd20aSAndroid Build Coastguard Worker    'script-src': [
46*6dbdd20aSAndroid Build Coastguard Worker      `'self'`,
47*6dbdd20aSAndroid Build Coastguard Worker    ],
48*6dbdd20aSAndroid Build Coastguard Worker    'object-src': ['none'],
49*6dbdd20aSAndroid Build Coastguard Worker    'connect-src': [
50*6dbdd20aSAndroid Build Coastguard Worker      `'self'`,
51*6dbdd20aSAndroid Build Coastguard Worker    ],
52*6dbdd20aSAndroid Build Coastguard Worker    'img-src': [
53*6dbdd20aSAndroid Build Coastguard Worker      `'self'`,
54*6dbdd20aSAndroid Build Coastguard Worker      'data:',
55*6dbdd20aSAndroid Build Coastguard Worker      'blob:',
56*6dbdd20aSAndroid Build Coastguard Worker    ],
57*6dbdd20aSAndroid Build Coastguard Worker    'style-src': [
58*6dbdd20aSAndroid Build Coastguard Worker      `'self'`,
59*6dbdd20aSAndroid Build Coastguard Worker    ],
60*6dbdd20aSAndroid Build Coastguard Worker    'navigate-to': ['https://*.perfetto.dev', 'self'],
61*6dbdd20aSAndroid Build Coastguard Worker  };
62*6dbdd20aSAndroid Build Coastguard Worker  const meta = document.createElement('meta');
63*6dbdd20aSAndroid Build Coastguard Worker  meta.httpEquiv = 'Content-Security-Policy';
64*6dbdd20aSAndroid Build Coastguard Worker  let policyStr = '';
65*6dbdd20aSAndroid Build Coastguard Worker  for (const [key, list] of Object.entries(policy)) {
66*6dbdd20aSAndroid Build Coastguard Worker    policyStr += `${key} ${list.join(' ')}; `;
67*6dbdd20aSAndroid Build Coastguard Worker  }
68*6dbdd20aSAndroid Build Coastguard Worker  meta.content = policyStr;
69*6dbdd20aSAndroid Build Coastguard Worker  document.head.appendChild(meta);
70*6dbdd20aSAndroid Build Coastguard Worker}
71*6dbdd20aSAndroid Build Coastguard Worker
72*6dbdd20aSAndroid Build Coastguard Workerfunction main() {
73*6dbdd20aSAndroid Build Coastguard Worker  // Wire up raf for widgets.
74*6dbdd20aSAndroid Build Coastguard Worker  setScheduleFullRedraw(() => raf.scheduleFullRedraw());
75*6dbdd20aSAndroid Build Coastguard Worker
76*6dbdd20aSAndroid Build Coastguard Worker  setupContentSecurityPolicy();
77*6dbdd20aSAndroid Build Coastguard Worker
78*6dbdd20aSAndroid Build Coastguard Worker  // Load the css. The load is asynchronous and the CSS is not ready by the time
79*6dbdd20aSAndroid Build Coastguard Worker  // appendChild returns.
80*6dbdd20aSAndroid Build Coastguard Worker  const root = getRoot();
81*6dbdd20aSAndroid Build Coastguard Worker  const cssLoadPromise = defer<void>();
82*6dbdd20aSAndroid Build Coastguard Worker  const css = document.createElement('link');
83*6dbdd20aSAndroid Build Coastguard Worker  css.rel = 'stylesheet';
84*6dbdd20aSAndroid Build Coastguard Worker  css.href = root + 'perfetto.css';
85*6dbdd20aSAndroid Build Coastguard Worker  css.onload = () => cssLoadPromise.resolve();
86*6dbdd20aSAndroid Build Coastguard Worker  css.onerror = (err) => cssLoadPromise.reject(err);
87*6dbdd20aSAndroid Build Coastguard Worker  const favicon = document.head.querySelector('#favicon') as HTMLLinkElement;
88*6dbdd20aSAndroid Build Coastguard Worker  if (favicon) favicon.href = root + 'assets/favicon.png';
89*6dbdd20aSAndroid Build Coastguard Worker
90*6dbdd20aSAndroid Build Coastguard Worker  document.head.append(css);
91*6dbdd20aSAndroid Build Coastguard Worker
92*6dbdd20aSAndroid Build Coastguard Worker  // Add Error handlers for JS error and for uncaught exceptions in promises.
93*6dbdd20aSAndroid Build Coastguard Worker  addErrorHandler((err: ErrorDetails) => console.log(err.message, err.stack));
94*6dbdd20aSAndroid Build Coastguard Worker  window.addEventListener('error', (e) => reportError(e));
95*6dbdd20aSAndroid Build Coastguard Worker  window.addEventListener('unhandledrejection', (e) => reportError(e));
96*6dbdd20aSAndroid Build Coastguard Worker
97*6dbdd20aSAndroid Build Coastguard Worker  // Prevent pinch zoom.
98*6dbdd20aSAndroid Build Coastguard Worker  document.body.addEventListener('wheel', (e: MouseEvent) => {
99*6dbdd20aSAndroid Build Coastguard Worker    if (e.ctrlKey) e.preventDefault();
100*6dbdd20aSAndroid Build Coastguard Worker  }, {passive: false});
101*6dbdd20aSAndroid Build Coastguard Worker
102*6dbdd20aSAndroid Build Coastguard Worker  cssLoadPromise.then(() => onCssLoaded());
103*6dbdd20aSAndroid Build Coastguard Worker}
104*6dbdd20aSAndroid Build Coastguard Worker
105*6dbdd20aSAndroid Build Coastguard Workerfunction onCssLoaded() {
106*6dbdd20aSAndroid Build Coastguard Worker  // Clear all the contents of the initial page (e.g. the <pre> error message)
107*6dbdd20aSAndroid Build Coastguard Worker  // And replace it with the root <main> element which will be used by mithril.
108*6dbdd20aSAndroid Build Coastguard Worker  document.body.innerHTML = '';
109*6dbdd20aSAndroid Build Coastguard Worker
110*6dbdd20aSAndroid Build Coastguard Worker  raf.domRedraw = () => {
111*6dbdd20aSAndroid Build Coastguard Worker    m.render(document.body, m('div'));
112*6dbdd20aSAndroid Build Coastguard Worker  };
113*6dbdd20aSAndroid Build Coastguard Worker
114*6dbdd20aSAndroid Build Coastguard Worker  initLiveReloadIfLocalhost(false);
115*6dbdd20aSAndroid Build Coastguard Worker}
116*6dbdd20aSAndroid Build Coastguard Worker
117*6dbdd20aSAndroid Build Coastguard Workermain();
118