• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {PersistentStoreProxy} from 'common/persistent_store_proxy';
18import {INVALID_TIME_NS} from 'common/time';
19import {WinscopeEvent, WinscopeEventType} from 'messaging/winscope_event';
20import {Trace} from 'trace/trace';
21import {Traces} from 'trace/traces';
22import {HierarchyTreeNode} from 'trace/tree_node/hierarchy_tree_node';
23import {
24  AbstractHierarchyViewerPresenter,
25  NotifyHierarchyViewCallbackType,
26} from 'viewers/common/abstract_hierarchy_viewer_presenter';
27import {VISIBLE_CHIP} from 'viewers/common/chip';
28import {DisplayIdentifier} from 'viewers/common/display_identifier';
29import {HierarchyPresenter} from 'viewers/common/hierarchy_presenter';
30import {PropertiesPresenter} from 'viewers/common/properties_presenter';
31import {RectsPresenter} from 'viewers/common/rects_presenter';
32import {UiHierarchyTreeNode} from 'viewers/common/ui_hierarchy_tree_node';
33import {UI_RECT_FACTORY} from 'viewers/common/ui_rect_factory';
34import {UserOptions} from 'viewers/common/user_options';
35import {UiRect} from 'viewers/components/rects/types2d';
36import {UpdateDisplayNames} from './operations/update_display_names';
37import {UiData} from './ui_data';
38
39export class Presenter extends AbstractHierarchyViewerPresenter {
40  static readonly DENYLIST_PROPERTY_NAMES = [
41    'name',
42    'children',
43    'dpiX',
44    'dpiY',
45  ];
46
47  protected override hierarchyPresenter = new HierarchyPresenter(
48    PersistentStoreProxy.new<UserOptions>(
49      'WmHierarchyOptions',
50      {
51        showDiff: {
52          name: 'Show diff',
53          enabled: false,
54          isUnavailable: false,
55        },
56        showOnlyVisible: {
57          name: 'Show only',
58          chip: VISIBLE_CHIP,
59          enabled: false,
60        },
61        simplifyNames: {
62          name: 'Simplify names',
63          enabled: true,
64        },
65        flat: {
66          name: 'Flat',
67          enabled: false,
68        },
69      },
70      this.storage,
71    ),
72    Presenter.DENYLIST_PROPERTY_NAMES,
73    true,
74    false,
75    (entry) => {
76      if (
77        entry.getFullTrace().lengthEntries === 1 &&
78        entry.getTimestamp().getValueNs() === INVALID_TIME_NS
79      ) {
80        return 'Dump';
81      }
82      return entry.getTimestamp().format();
83    },
84    [new UpdateDisplayNames()],
85  );
86  protected override rectsPresenter = new RectsPresenter(
87    PersistentStoreProxy.new<UserOptions>(
88      'WmRectsOptions',
89      {
90        ignoreNonHidden: {
91          name: 'Ignore',
92          icon: 'visibility',
93          enabled: false,
94        },
95        showOnlyVisible: {
96          name: 'Show only',
97          chip: VISIBLE_CHIP,
98          enabled: false,
99        },
100      },
101      this.storage,
102    ),
103    (tree: HierarchyTreeNode) => UI_RECT_FACTORY.makeUiRects(tree),
104    this.getDisplays,
105  );
106  protected override propertiesPresenter = new PropertiesPresenter(
107    PersistentStoreProxy.new<UserOptions>(
108      'WmPropertyOptions',
109      {
110        showDiff: {
111          name: 'Show diff',
112          enabled: false,
113          isUnavailable: false,
114        },
115        showDefaults: {
116          name: 'Show defaults',
117          enabled: false,
118          tooltip: `
119                If checked, shows the value of all properties.
120                Otherwise, hides all properties whose value is
121                the default for its data type.
122              `,
123        },
124      },
125      this.storage,
126    ),
127    Presenter.DENYLIST_PROPERTY_NAMES,
128  );
129  protected override multiTraceType = undefined;
130
131  constructor(
132    trace: Trace<HierarchyTreeNode>,
133    traces: Traces,
134    storage: Readonly<Storage>,
135    notifyViewCallback: NotifyHierarchyViewCallbackType,
136  ) {
137    super(trace, traces, storage, notifyViewCallback, new UiData());
138  }
139
140  override async onAppEvent(event: WinscopeEvent) {
141    await event.visit(
142      WinscopeEventType.TRACE_POSITION_UPDATE,
143      async (event) => {
144        await this.applyTracePositionUpdate(event);
145        this.refreshUIData();
146      },
147    );
148  }
149
150  override async onHighlightedNodeChange(item: UiHierarchyTreeNode) {
151    await this.applyHighlightedNodeChange(item);
152    this.refreshUIData();
153  }
154
155  override async onHighlightedIdChange(newId: string) {
156    await this.applyHighlightedIdChange(newId);
157    this.refreshUIData();
158  }
159
160  protected override getOverrideDisplayName(
161    selected: [Trace<HierarchyTreeNode>, HierarchyTreeNode],
162  ): string | undefined {
163    if (!selected[1].isRoot()) {
164      return undefined;
165    }
166    return this.hierarchyPresenter
167      .getCurrentHierarchyTreeNames(selected[0])
168      ?.at(0);
169  }
170
171  protected override keepCalculated(tree: HierarchyTreeNode): boolean {
172    return tree.isRoot();
173  }
174
175  private getDisplays(rects: UiRect[]): DisplayIdentifier[] {
176    const ids: DisplayIdentifier[] = [];
177    rects.forEach((rect: UiRect) => {
178      if (!rect.isDisplay) return;
179      const displayName = rect.label.slice(10, rect.label.length);
180      ids.push({displayId: rect.id, groupId: rect.groupId, name: displayName});
181    });
182    return ids.sort((a, b) => {
183      if (a.name < b.name) {
184        return -1;
185      }
186      if (a.name > b.name) {
187        return 1;
188      }
189      return 0;
190    });
191  }
192
193  private refreshUIData() {
194    this.refreshHierarchyViewerUiData(new UiData());
195  }
196}
197