1/* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16import {assertTrue} from 'common/assert_utils'; 17import {ParserTimestampConverter} from 'common/timestamp_converter'; 18import {UserNotifier} from 'common/user_notifier'; 19import {ProgressListener} from 'messaging/progress_listener'; 20import { 21 InvalidLegacyTrace, 22 UnsupportedFileFormat, 23} from 'messaging/user_warnings'; 24import {ParserEventLog} from 'parsers/events/parser_eventlog'; 25import {FileAndParser} from 'parsers/file_and_parser'; 26import {ParserInputMethodClients} from 'parsers/input_method/legacy/parser_input_method_clients'; 27import {ParserInputMethodManagerService} from 'parsers/input_method/legacy/parser_input_method_manager_service'; 28import {ParserInputMethodService} from 'parsers/input_method/legacy/parser_input_method_service'; 29import {ParserProtoLog} from 'parsers/protolog/legacy/parser_protolog'; 30import {ParserScreenshot} from 'parsers/screenshot/parser_screenshot'; 31import {ParserScreenRecording} from 'parsers/screen_recording/parser_screen_recording'; 32import {ParserScreenRecordingLegacy} from 'parsers/screen_recording/parser_screen_recording_legacy'; 33import {ParserSurfaceFlinger} from 'parsers/surface_flinger/legacy/parser_surface_flinger'; 34import {ParserTransactions} from 'parsers/transactions/legacy/parser_transactions'; 35import {ParserTransitionsShell} from 'parsers/transitions/legacy/parser_transitions_shell'; 36import {ParserTransitionsWm} from 'parsers/transitions/legacy/parser_transitions_wm'; 37import {ParserViewCapture} from 'parsers/view_capture/legacy/parser_view_capture'; 38import {ParserWindowManager} from 'parsers/window_manager/legacy/parser_window_manager'; 39import {ParserWindowManagerDump} from 'parsers/window_manager/legacy/parser_window_manager_dump'; 40import {Parser} from 'trace/parser'; 41import {TraceFile} from 'trace/trace_file'; 42import {TraceMetadata} from 'trace/trace_metadata'; 43 44export class ParserFactory { 45 static readonly PARSERS = [ 46 ParserInputMethodClients, 47 ParserInputMethodManagerService, 48 ParserInputMethodService, 49 ParserProtoLog, 50 ParserScreenRecording, 51 ParserScreenRecordingLegacy, 52 ParserSurfaceFlinger, 53 ParserTransactions, 54 ParserWindowManager, 55 ParserWindowManagerDump, 56 ParserEventLog, 57 ParserTransitionsWm, 58 ParserTransitionsShell, 59 ParserViewCapture, 60 ParserScreenshot, 61 ]; 62 63 async createParsers( 64 traceFiles: TraceFile[], 65 timestampConverter: ParserTimestampConverter, 66 metadata: TraceMetadata, 67 progressListener?: ProgressListener, 68 ): Promise<FileAndParser[]> { 69 const parsers = new Array<{file: TraceFile; parser: Parser<object>}>(); 70 71 for (const [index, traceFile] of traceFiles.entries()) { 72 progressListener?.onProgressUpdate( 73 'Parsing proto files', 74 (index / traceFiles.length) * 100, 75 ); 76 77 let hasFoundParser = false; 78 79 for (const ParserType of ParserFactory.PARSERS) { 80 try { 81 const p = new ParserType(traceFile, timestampConverter, metadata); 82 await p.parse(); 83 hasFoundParser = true; 84 85 if (p instanceof ParserViewCapture) { 86 p.getWindowParsers().forEach((subParser) => { 87 assertTrue( 88 subParser.getLengthEntries() > 0, 89 () => 'Trace has no entries', 90 ); 91 parsers.push(new FileAndParser(traceFile, subParser)); 92 }); 93 } else { 94 assertTrue(p.getLengthEntries() > 0, () => 'Trace has no entries'); 95 parsers.push({file: traceFile, parser: p}); 96 } 97 break; 98 } catch (error) { 99 if (hasFoundParser) { 100 UserNotifier.add( 101 new InvalidLegacyTrace( 102 traceFile.getDescriptor(), 103 (error as Error).message, 104 ), 105 ); 106 break; 107 } 108 // skip current parser 109 } 110 } 111 112 if (!hasFoundParser) { 113 UserNotifier.add(new UnsupportedFileFormat(traceFile.getDescriptor())); 114 } 115 } 116 return parsers; 117 } 118} 119