xref: /aosp_15_r20/development/tools/winscope/src/viewers/common/rects_presenter.ts (revision 90c8c64db3049935a07c6143d7fd006e26f8ecca)
1/*
2 * Copyright (C) 2024 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 {Trace} from 'trace/trace';
18import {HierarchyTreeNode} from 'trace/tree_node/hierarchy_tree_node';
19import {UiRect} from 'viewers/components/rects/ui_rect';
20import {DisplayIdentifier} from './display_identifier';
21import {RectFilter} from './rect_filter';
22import {RectShowState} from './rect_show_state';
23import {UserOptions} from './user_options';
24
25export class RectsPresenter {
26  private readonly rectFilter = new RectFilter(this.convertToKey);
27  private allCurrentRects: UiRect[] = [];
28  private rectsToDraw: UiRect[] = [];
29  private displays: DisplayIdentifier[] = [];
30  private rectIdToShowState: Map<string, RectShowState> | undefined;
31
32  constructor(
33    private userOptions: UserOptions,
34    private makeUiRectsStrategy: (
35      tree: HierarchyTreeNode,
36      trace: Trace<HierarchyTreeNode>,
37    ) => UiRect[],
38    private makeDisplaysStrategy?: (rects: UiRect[]) => DisplayIdentifier[],
39    private convertToKey: (rectId: string) => string = (id: string) => id,
40  ) {}
41
42  getUserOptions(): UserOptions {
43    return this.userOptions;
44  }
45
46  getRectsToDraw(): UiRect[] {
47    return this.rectsToDraw;
48  }
49
50  getRectIdToShowState(): Map<string, RectShowState> | undefined {
51    return this.rectIdToShowState;
52  }
53
54  getDisplays(): DisplayIdentifier[] {
55    return this.displays;
56  }
57
58  setDisplays(displays: DisplayIdentifier[]) {
59    this.displays = displays;
60  }
61
62  applyHierarchyTreesChange(
63    hierarchyTrees: Array<[Trace<HierarchyTreeNode>, HierarchyTreeNode[]]>,
64  ) {
65    this.allCurrentRects = [];
66    for (const [trace, trees] of hierarchyTrees) {
67      trees.forEach((tree) => {
68        this.allCurrentRects.push(...this.makeUiRectsStrategy(tree, trace));
69      });
70    }
71    this.updateRectsToDrawAndRectIdToShowState();
72    if (this.makeDisplaysStrategy) {
73      this.displays = this.makeDisplaysStrategy(this.rectsToDraw);
74    }
75  }
76
77  applyRectsUserOptionsChange(userOptions: UserOptions) {
78    this.userOptions = userOptions;
79    this.updateRectsToDrawAndRectIdToShowState();
80  }
81
82  applyRectShowStateChange(id: string, newShowState: RectShowState) {
83    this.rectFilter.updateRectShowState(id, newShowState);
84    this.updateRectsToDrawAndRectIdToShowState();
85  }
86
87  updateRectShowStates(
88    rectIdToShowState: Map<string, RectShowState> | undefined,
89  ) {
90    this.rectFilter.clear();
91    if (rectIdToShowState) {
92      for (const [id, state] of rectIdToShowState.entries()) {
93        this.rectFilter.updateRectShowState(id, state);
94      }
95    }
96    this.updateRectsToDrawAndRectIdToShowState();
97  }
98
99  clear() {
100    this.allCurrentRects = [];
101    this.rectsToDraw = [];
102    this.displays = [];
103    this.rectIdToShowState = undefined;
104    this.rectFilter.clear();
105  }
106
107  private updateRectsToDrawAndRectIdToShowState() {
108    this.rectsToDraw = this.filterRects(this.allCurrentRects);
109    this.rectIdToShowState = this.rectFilter.getRectIdToShowState(
110      this.allCurrentRects,
111      this.rectsToDraw,
112    );
113  }
114
115  private filterRects(rects: UiRect[]): UiRect[] {
116    const isOnlyVisibleMode =
117      this.userOptions['showOnlyVisible']?.enabled ?? false;
118    const isIgnoreRectShowStateMode =
119      this.userOptions['ignoreRectShowState']?.enabled ?? false;
120    const isOnlyWithContentMode =
121      this.userOptions['showOnlyWithContent']?.enabled ?? false;
122    return this.rectFilter.filterRects(
123      rects,
124      isOnlyVisibleMode,
125      isIgnoreRectShowStateMode,
126      isOnlyWithContentMode,
127    );
128  }
129}
130