xref: /aosp_15_r20/platform_testing/libraries/flicker/utils/src/android/tools/parsers/AbstractTraceParser.kt (revision dd0948b35e70be4c0246aabd6c72554a5eb8b22a)
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 
17 package android.tools.parsers
18 
19 import android.tools.Cache
20 import android.tools.Timestamp
21 import android.tools.Timestamps
22 import android.tools.withTracing
23 
24 /** Base trace parser class */
25 abstract class AbstractTraceParser<
26     InputTypeTrace,
27     InputTypeEntry,
28     OutputTypeEntry,
29     OutputTypeTrace,
30 > : AbstractParser<InputTypeTrace, OutputTypeTrace>() {
onBeforeParsenull31     protected open fun onBeforeParse(input: InputTypeTrace) {}
32 
getEntriesnull33     protected abstract fun getEntries(input: InputTypeTrace): Collection<InputTypeEntry>
34 
35     protected abstract fun getTimestamp(entry: InputTypeEntry): Timestamp
36 
37     protected abstract fun doParseEntry(entry: InputTypeEntry): OutputTypeEntry
38 
39     protected abstract fun createTrace(entries: Collection<OutputTypeEntry>): OutputTypeTrace
40 
41     open fun shouldParseEntry(entry: InputTypeEntry) = true
42 
43     final override fun parse(bytes: ByteArray, clearCache: Boolean): OutputTypeTrace {
44         return parse(
45             bytes,
46             from = Timestamps.min(),
47             to = Timestamps.max(),
48             addInitialEntry = true,
49             clearCache = clearCache,
50         )
51     }
52 
parsenull53     final override fun parse(input: InputTypeTrace, clearCache: Boolean): OutputTypeTrace {
54         return parse(
55             input,
56             from = Timestamps.min(),
57             to = Timestamps.max(),
58             addInitialEntry = true,
59             clearCache = clearCache,
60         )
61     }
62 
doParsenull63     final override fun doParse(input: InputTypeTrace): OutputTypeTrace {
64         return doParse(
65             input,
66             from = Timestamps.min(),
67             to = Timestamps.max(),
68             addInitialEntry = true,
69         )
70     }
71 
72     /**
73      * Uses [InputTypeTrace] to generates a trace
74      *
75      * @param input Parsed proto data
76      * @param from Initial timestamp to be parsed
77      * @param to Final timestamp to be parsed
78      * @param addInitialEntry If the last entry smaller than [from] should be included as well
79      */
doParsenull80     protected open fun doParse(
81         input: InputTypeTrace,
82         from: Timestamp,
83         to: Timestamp,
84         addInitialEntry: Boolean,
85     ): OutputTypeTrace {
86         onBeforeParse(input)
87         val parsedEntries = mutableListOf<OutputTypeEntry>()
88         val rawEntries = getEntries(input)
89         val allInputTimestamps = rawEntries.map { getTimestamp(it) }
90         val selectedInputTimestamps =
91             getTimestampsInRange(allInputTimestamps, from, to, addInitialEntry)
92         for (rawEntry in rawEntries) {
93             val currTimestamp = getTimestamp(rawEntry)
94             if (!selectedInputTimestamps.contains(currTimestamp) || !shouldParseEntry(rawEntry)) {
95                 continue
96             }
97             val parsedEntry = withTracing("doParseEntry") { doParseEntry(rawEntry) }
98             parsedEntries.add(parsedEntry)
99         }
100         return createTrace(parsedEntries)
101     }
102 
103     /**
104      * Uses [InputTypeTrace] to generates a trace
105      *
106      * @param input Parsed proto data
107      * @param from Initial timestamp to be parsed
108      * @param to Final timestamp to be parsed
109      * @param addInitialEntry If the last entry smaller than [from] should be included as well
110      * @param clearCache If the caching used while parsing the object should be cleared
111      */
parsenull112     fun parse(
113         input: InputTypeTrace,
114         from: Timestamp,
115         to: Timestamp,
116         addInitialEntry: Boolean = true,
117         clearCache: Boolean = true,
118     ): OutputTypeTrace {
119         return withTracing("${this::class.simpleName}#parse") {
120             try {
121                 doParse(input, from, to, addInitialEntry)
122             } finally {
123                 if (clearCache) {
124                     Cache.clear()
125                 }
126             }
127         }
128     }
129 
130     /**
131      * Uses a [ByteArray] to generates a trace
132      *
133      * @param bytes Parsed proto data
134      * @param from Initial timestamp to be parsed
135      * @param to Final timestamp to be parsed
136      * @param addInitialEntry If the last entry smaller than [from] should be included as well
137      * @param clearCache If the caching used while parsing the object should be cleared
138      */
parsenull139     fun parse(
140         bytes: ByteArray,
141         from: Timestamp,
142         to: Timestamp,
143         addInitialEntry: Boolean = true,
144         clearCache: Boolean = true,
145     ): OutputTypeTrace {
146         val input = decodeByteArray(bytes)
147         return parse(input, from, to, addInitialEntry, clearCache)
148     }
149 }
150