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, InputTypeEntry, OutputTypeEntry, OutputTypeTrace> : 27 AbstractParser<InputTypeTrace, OutputTypeTrace>() { onBeforeParsenull28 protected open fun onBeforeParse(input: InputTypeTrace) {} getEntriesnull29 protected abstract fun getEntries(input: InputTypeTrace): Collection<InputTypeEntry> 30 protected abstract fun getTimestamp(entry: InputTypeEntry): Timestamp 31 protected abstract fun doParseEntry(entry: InputTypeEntry): OutputTypeEntry 32 protected abstract fun createTrace(entries: Collection<OutputTypeEntry>): OutputTypeTrace 33 34 open fun shouldParseEntry(entry: InputTypeEntry) = true 35 36 final override fun parse(bytes: ByteArray, clearCache: Boolean): OutputTypeTrace { 37 return parse( 38 bytes, 39 from = Timestamps.min(), 40 to = Timestamps.max(), 41 addInitialEntry = true, 42 clearCache = clearCache 43 ) 44 } 45 parsenull46 final override fun parse(input: InputTypeTrace, clearCache: Boolean): OutputTypeTrace { 47 return parse( 48 input, 49 from = Timestamps.min(), 50 to = Timestamps.max(), 51 addInitialEntry = true, 52 clearCache = clearCache 53 ) 54 } 55 doParsenull56 final override fun doParse(input: InputTypeTrace): OutputTypeTrace { 57 return doParse( 58 input, 59 from = Timestamps.min(), 60 to = Timestamps.max(), 61 addInitialEntry = true 62 ) 63 } 64 65 /** 66 * Uses [InputTypeTrace] to generates a trace 67 * 68 * @param input Parsed proto data 69 * @param from Initial timestamp to be parsed 70 * @param to Final timestamp to be parsed 71 * @param addInitialEntry If the last entry smaller than [from] should be included as well 72 */ doParsenull73 protected open fun doParse( 74 input: InputTypeTrace, 75 from: Timestamp, 76 to: Timestamp, 77 addInitialEntry: Boolean 78 ): OutputTypeTrace { 79 onBeforeParse(input) 80 val parsedEntries = mutableListOf<OutputTypeEntry>() 81 val rawEntries = getEntries(input) 82 val allInputTimestamps = rawEntries.map { getTimestamp(it) } 83 val selectedInputTimestamps = 84 getTimestampsInRange(allInputTimestamps, from, to, addInitialEntry) 85 for (rawEntry in rawEntries) { 86 val currTimestamp = getTimestamp(rawEntry) 87 if (!selectedInputTimestamps.contains(currTimestamp) || !shouldParseEntry(rawEntry)) { 88 continue 89 } 90 val parsedEntry = withTracing("doParseEntry") { doParseEntry(rawEntry) } 91 parsedEntries.add(parsedEntry) 92 } 93 return createTrace(parsedEntries) 94 } 95 96 /** 97 * Uses [InputTypeTrace] to generates a trace 98 * 99 * @param input Parsed proto data 100 * @param from Initial timestamp to be parsed 101 * @param to Final timestamp to be parsed 102 * @param addInitialEntry If the last entry smaller than [from] should be included as well 103 * @param clearCache If the caching used while parsing the object should be cleared 104 */ parsenull105 fun parse( 106 input: InputTypeTrace, 107 from: Timestamp, 108 to: Timestamp, 109 addInitialEntry: Boolean = true, 110 clearCache: Boolean = true 111 ): OutputTypeTrace { 112 return withTracing("${this::class.simpleName}#parse") { 113 try { 114 doParse(input, from, to, addInitialEntry) 115 } finally { 116 if (clearCache) { 117 Cache.clear() 118 } 119 } 120 } 121 } 122 123 /** 124 * Uses a [ByteArray] to generates a trace 125 * 126 * @param bytes Parsed proto data 127 * @param from Initial timestamp to be parsed 128 * @param to Final timestamp to be parsed 129 * @param addInitialEntry If the last entry smaller than [from] should be included as well 130 * @param clearCache If the caching used while parsing the object should be cleared 131 */ parsenull132 fun parse( 133 bytes: ByteArray, 134 from: Timestamp, 135 to: Timestamp, 136 addInitialEntry: Boolean = true, 137 clearCache: Boolean = true 138 ): OutputTypeTrace { 139 val input = decodeByteArray(bytes) 140 return parse(input, from, to, addInitialEntry, clearCache) 141 } 142 } 143