xref: /aosp_15_r20/development/tools/winscope/src/trace/custom_query.ts (revision 90c8c64db3049935a07c6143d7fd006e26f8ecca)
1/*
2 * Copyright (C) 2023 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 {RelativeEntryIndex, TraceEntryEager} from './trace';
18
19export enum CustomQueryType {
20  SF_LAYERS_ID_AND_NAME,
21  VIEW_CAPTURE_METADATA,
22  VSYNCID,
23  WM_WINDOWS_TOKEN_AND_TITLE,
24}
25
26export class ProcessParserResult {
27  static [CustomQueryType.SF_LAYERS_ID_AND_NAME]<T>(
28    parserResult: CustomQueryParserResultTypeMap[CustomQueryType.SF_LAYERS_ID_AND_NAME],
29  ): CustomQueryResultTypeMap<T>[CustomQueryType.SF_LAYERS_ID_AND_NAME] {
30    return parserResult;
31  }
32
33  static [CustomQueryType.VIEW_CAPTURE_METADATA]<T>(
34    parserResult: CustomQueryParserResultTypeMap[CustomQueryType.VIEW_CAPTURE_METADATA],
35  ): CustomQueryResultTypeMap<T>[CustomQueryType.VIEW_CAPTURE_METADATA] {
36    return parserResult;
37  }
38
39  static [CustomQueryType.VSYNCID]<T>(
40    parserResult: CustomQueryParserResultTypeMap[CustomQueryType.VSYNCID],
41    makeTraceEntry: (
42      index: RelativeEntryIndex,
43      vsyncId: bigint,
44    ) => TraceEntryEager<T, bigint>,
45  ): CustomQueryResultTypeMap<T>[CustomQueryType.VSYNCID] {
46    return parserResult.map((vsyncId, index) => {
47      return makeTraceEntry(index, vsyncId);
48    });
49  }
50
51  static [CustomQueryType.WM_WINDOWS_TOKEN_AND_TITLE]<T>(
52    parserResult: CustomQueryParserResultTypeMap[CustomQueryType.WM_WINDOWS_TOKEN_AND_TITLE],
53  ): CustomQueryResultTypeMap<T>[CustomQueryType.WM_WINDOWS_TOKEN_AND_TITLE] {
54    return parserResult;
55  }
56}
57
58export interface CustomQueryParamTypeMap {
59  [CustomQueryType.SF_LAYERS_ID_AND_NAME]: never;
60  [CustomQueryType.VIEW_CAPTURE_METADATA]: never;
61  [CustomQueryType.VSYNCID]: never;
62  [CustomQueryType.WM_WINDOWS_TOKEN_AND_TITLE]: never;
63}
64
65export interface CustomQueryParserResultTypeMap {
66  [CustomQueryType.SF_LAYERS_ID_AND_NAME]: Array<{id: number; name: string}>;
67  [CustomQueryType.VIEW_CAPTURE_METADATA]: {
68    packageName: string;
69    windowName: string;
70  };
71  [CustomQueryType.VSYNCID]: Array<bigint>;
72  [CustomQueryType.WM_WINDOWS_TOKEN_AND_TITLE]: Array<{
73    token: string;
74    title: string;
75  }>;
76}
77
78export interface CustomQueryResultTypeMap<T> {
79  [CustomQueryType.SF_LAYERS_ID_AND_NAME]: Array<{id: number; name: string}>;
80  [CustomQueryType.VIEW_CAPTURE_METADATA]: {
81    packageName: string;
82    windowName: string;
83  };
84  [CustomQueryType.VSYNCID]: Array<TraceEntryEager<T, bigint>>;
85  [CustomQueryType.WM_WINDOWS_TOKEN_AND_TITLE]: Array<{
86    token: string;
87    title: string;
88  }>;
89}
90
91export class VisitableParserCustomQuery<Q extends CustomQueryType> {
92  private readonly type: CustomQueryType;
93  private result: Promise<CustomQueryParserResultTypeMap[Q]> | undefined;
94
95  constructor(type: Q) {
96    this.type = type;
97  }
98
99  visit<R extends CustomQueryType>(
100    type: R,
101    visitor: () => Promise<CustomQueryParserResultTypeMap[R]>,
102  ): VisitableParserCustomQuery<Q> {
103    if (type !== this.type) {
104      return this;
105    }
106    this.result = visitor() as Promise<CustomQueryParserResultTypeMap[Q]>;
107    return this;
108  }
109
110  getResult(): Promise<CustomQueryParserResultTypeMap[Q]> {
111    if (this.result === undefined) {
112      throw new Error(
113        `No result available. Looks like custom query (type: ${this.type}) is not implemented!`,
114      );
115    }
116    return this.result;
117  }
118}
119