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