• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (C) 2018 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15import {assertTrue} from '../base/logging';
16import {globals} from './globals';
17
18export function isLegacyTrace(fileName: string): boolean {
19  fileName = fileName.toLowerCase();
20  return (
21      fileName.endsWith('.json') || fileName.endsWith('.json.gz') ||
22      fileName.endsWith('.zip') || fileName.endsWith('.ctrace'));
23}
24
25export function openFileWithLegacyTraceViewer(file: File) {
26  const reader = new FileReader();
27  reader.onload = () => {
28    if (reader.result instanceof ArrayBuffer) {
29      return openBufferWithLegacyTraceViewer(
30          file.name, reader.result, reader.result.byteLength);
31    } else {
32      const str = reader.result as string;
33      return openBufferWithLegacyTraceViewer(file.name, str, str.length);
34    }
35  };
36  reader.onerror = err => {
37    console.error(err);
38  };
39  if (file.name.endsWith('.gz') || file.name.endsWith('.zip')) {
40    reader.readAsArrayBuffer(file);
41  } else {
42    reader.readAsText(file);
43  }
44}
45
46export function openBufferWithLegacyTraceViewer(
47    name: string, data: ArrayBuffer|string, size: number) {
48  if (data instanceof ArrayBuffer) {
49    assertTrue(size <= data.byteLength);
50    if (size !== data.byteLength) {
51      data = data.slice(0, size);
52    }
53  }
54  document.body.style.transition =
55      'filter 1s ease, transform 1s cubic-bezier(0.985, 0.005, 1.000, 0.225)';
56  document.body.style.filter = 'grayscale(1) blur(10px) opacity(0)';
57  document.body.style.transform = 'scale(0)';
58  const transitionPromise = new Promise(resolve => {
59    document.body.addEventListener('transitionend', (e: TransitionEvent) => {
60      if (e.propertyName === 'transform') {
61        resolve();
62      }
63    });
64  });
65
66  const loadPromise = new Promise(resolve => {
67    fetch('/assets/catapult_trace_viewer.html').then(resp => {
68      resp.text().then(content => {
69        resolve(content);
70      });
71    });
72  });
73
74  Promise.all([loadPromise, transitionPromise]).then(args => {
75    const fetchResult = args[0] as string;
76    replaceWindowWithTraceViewer(name, data, fetchResult);
77  });
78}
79
80// Replaces the contents of the current window with the Catapult's legacy
81// trace viewer HTML, passed in |htmlContent|.
82// This is in its own function to avoid leaking variables from the current
83// document we are about to destroy.
84function replaceWindowWithTraceViewer(
85    name: string, data: ArrayBuffer|string, htmlContent: string) {
86  globals.shutdown();
87  const newWin = window.open('', '_self') as Window;
88  newWin.document.open('text/html', 'replace');
89  newWin.document.addEventListener('readystatechange', () => {
90    const doc = newWin.document;
91    if (doc.readyState !== 'complete') return;
92    const ctl = doc.querySelector('x-profiling-view') as TraceViewerAPI;
93    ctl.setActiveTrace(name, data);
94  });
95  newWin.document.write(htmlContent);
96  newWin.document.close();
97}
98
99// TraceViewer method that we wire up to trigger the file load.
100interface TraceViewerAPI extends Element {
101  setActiveTrace(name: string, data: ArrayBuffer|string): void;
102}
103