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