xref: /aosp_15_r20/development/tools/winscope/src/viewers/viewer_factory.ts (revision 90c8c64db3049935a07c6143d7fd006e26f8ecca)
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