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 */ 16 17import {assertTrue} from 'common/assert_utils'; 18import {Store} from 'common/store/store'; 19import {TimestampConverter} from 'common/time/timestamp_converter'; 20import {Trace} from 'trace/trace'; 21import {Traces} from 'trace/traces'; 22import {TraceType, TraceTypeUtils} from 'trace/trace_type'; 23import {Viewer, ViewType} from './viewer'; 24import {ViewerInput} from './viewer_input/viewer_input'; 25import {ViewerInputMethodClients} from './viewer_input_method_clients/viewer_input_method_clients'; 26import {ViewerInputMethodManagerService} from './viewer_input_method_manager_service/viewer_input_method_manager_service'; 27import {ViewerInputMethodService} from './viewer_input_method_service/viewer_input_method_service'; 28import {ViewerJankCujs} from './viewer_jank_cujs/viewer_jank_cujs'; 29import {ViewerScreenshot} from './viewer_media_based/viewer_screenshot'; 30import {ViewerScreenRecording} from './viewer_media_based/viewer_screen_recording'; 31import {ViewerProtoLog} from './viewer_protolog/viewer_protolog'; 32import {ViewerSearch} from './viewer_search/viewer_search'; 33import {ViewerSurfaceFlinger} from './viewer_surface_flinger/viewer_surface_flinger'; 34import {ViewerTransactions} from './viewer_transactions/viewer_transactions'; 35import {ViewerTransitions} from './viewer_transitions/viewer_transitions'; 36import {ViewerViewCapture} from './viewer_view_capture/viewer_view_capture'; 37import {ViewerWindowManager} from './viewer_window_manager/viewer_window_manager'; 38 39export class ViewerFactory { 40 static readonly SINGLE_TRACE_VIEWERS = [ 41 ViewerSurfaceFlinger, 42 ViewerWindowManager, 43 ViewerInputMethodClients, 44 ViewerInputMethodManagerService, 45 ViewerInputMethodService, 46 ViewerTransactions, 47 ViewerProtoLog, 48 ViewerTransitions, 49 ViewerJankCujs, 50 ]; 51 52 static readonly MULTI_TRACE_VIEWERS = [ 53 ViewerViewCapture, 54 ViewerInput, 55 ViewerScreenRecording, 56 ViewerScreenshot, 57 ]; 58 59 createViewers( 60 traces: Traces, 61 store: Store, 62 timestampConverter: TimestampConverter, 63 ): Viewer[] { 64 const viewers: Viewer[] = []; 65 66 for (const trace of traces) { 67 if (trace.isPerfetto()) { 68 viewers.push(new ViewerSearch(traces, store, timestampConverter)); 69 break; 70 } 71 } 72 73 // instantiate one viewer for one trace 74 traces.forEachTrace((trace) => { 75 ViewerFactory.SINGLE_TRACE_VIEWERS.forEach((Viewer) => { 76 assertTrue(Viewer.DEPENDENCIES.length === 1); 77 const isViewerDepSatisfied = trace.type === Viewer.DEPENDENCIES[0]; 78 if (isViewerDepSatisfied) { 79 viewers.push(new Viewer(trace as Trace<any>, traces, store)); 80 } 81 }); 82 }); 83 84 // instantiate one viewer for N traces 85 const availableTraceTypes = new Set(traces.mapTrace((trace) => trace.type)); 86 87 ViewerFactory.MULTI_TRACE_VIEWERS.forEach((Viewer) => { 88 const isViewerDepSatisfied = Viewer.DEPENDENCIES.some( 89 (traceType: TraceType) => availableTraceTypes.has(traceType), 90 ); 91 if (isViewerDepSatisfied) { 92 viewers.push(new Viewer(traces, store)); 93 } 94 }); 95 96 // Note: 97 // the final order of tabs/views in the UI corresponds the order of the 98 // respective viewers below 99 return viewers.sort((a, b) => { 100 const aView = a.getViews()[0]; 101 const bView = b.getViews()[0]; 102 if ( 103 aView.type === ViewType.TRACE_TAB && 104 bView.type === ViewType.TRACE_TAB 105 ) { 106 return TraceTypeUtils.compareByDisplayOrder( 107 a.getTraces()[0].type, 108 b.getTraces()[0].type, 109 ); 110 } else if ( 111 aView.type === ViewType.GLOBAL_SEARCH && 112 bView.type !== ViewType.GLOBAL_SEARCH 113 ) { 114 return -1; 115 } else if ( 116 aView.type !== ViewType.GLOBAL_SEARCH && 117 bView.type === ViewType.GLOBAL_SEARCH 118 ) { 119 return 1; 120 } else { 121 return aView.title < bView.title ? -1 : 1; 122 } 123 }); 124 } 125} 126