1// Copyright (C) 2021 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 {Actions} from '../common/actions'; 16import { 17 ConversionJobName, 18 ConversionJobStatus, 19} from '../common/conversion_jobs'; 20import {TPTime} from '../common/time'; 21 22import {download} from './clipboard'; 23import {maybeShowErrorDialog} from './error_dialog'; 24import {globals} from './globals'; 25import {openBufferWithLegacyTraceViewer} from './legacy_trace_viewer'; 26 27type Args = UpdateStatusArgs|UpdateJobStatusArgs|DownloadFileArgs| 28 OpenTraceInLegacyArgs|ErrorArgs; 29 30interface UpdateStatusArgs { 31 kind: 'updateStatus'; 32 status: string; 33} 34 35interface UpdateJobStatusArgs { 36 kind: 'updateJobStatus'; 37 name: ConversionJobName; 38 status: ConversionJobStatus; 39} 40 41interface DownloadFileArgs { 42 kind: 'downloadFile'; 43 buffer: Uint8Array; 44 name: string; 45} 46 47interface OpenTraceInLegacyArgs { 48 kind: 'openTraceInLegacy'; 49 buffer: Uint8Array; 50} 51 52interface ErrorArgs { 53 kind: 'error'; 54 error: string; 55} 56 57 58function handleOnMessage(msg: MessageEvent): void { 59 const args: Args = msg.data; 60 if (args.kind === 'updateStatus') { 61 globals.dispatch(Actions.updateStatus({ 62 msg: args.status, 63 timestamp: Date.now() / 1000, 64 })); 65 } else if (args.kind === 'updateJobStatus') { 66 globals.setConversionJobStatus(args.name, args.status); 67 } else if (args.kind === 'downloadFile') { 68 download(new File([new Blob([args.buffer])], args.name)); 69 } else if (args.kind === 'openTraceInLegacy') { 70 const str = (new TextDecoder('utf-8')).decode(args.buffer); 71 openBufferWithLegacyTraceViewer('trace.json', str, 0); 72 } else if (args.kind === 'error') { 73 maybeShowErrorDialog(args.error); 74 } else { 75 throw new Error(`Unhandled message ${JSON.stringify(args)}`); 76 } 77} 78 79function makeWorkerAndPost(msg: unknown) { 80 const worker = new Worker(globals.root + 'traceconv_bundle.js'); 81 worker.onmessage = handleOnMessage; 82 worker.postMessage(msg); 83} 84 85export function convertTraceToJsonAndDownload(trace: Blob) { 86 makeWorkerAndPost({ 87 kind: 'ConvertTraceAndDownload', 88 trace, 89 format: 'json', 90 }); 91} 92 93export function convertTraceToSystraceAndDownload(trace: Blob) { 94 makeWorkerAndPost({ 95 kind: 'ConvertTraceAndDownload', 96 trace, 97 format: 'systrace', 98 }); 99} 100 101export function convertToJson(trace: Blob, truncate?: 'start'|'end') { 102 makeWorkerAndPost({ 103 kind: 'ConvertTraceAndOpenInLegacy', 104 trace, 105 truncate, 106 }); 107} 108 109export function convertTraceToPprofAndDownload( 110 trace: Blob, pid: number, ts: TPTime) { 111 makeWorkerAndPost({ 112 kind: 'ConvertTraceToPprof', 113 trace, 114 pid, 115 ts, 116 }); 117} 118