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