1 /*
<lambda>null2  * Copyright (C) 2024 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.traces.parsers.perfetto
18 
19 import android.tools.Timestamp
20 import android.tools.parsers.AbstractTraceParser
21 import android.tools.traces.protolog.ProtoLogMessage
22 import android.tools.traces.protolog.ProtoLogTrace
23 import com.android.internal.protolog.common.LogLevel
24 
25 class ProtoLogTraceParser :
26     AbstractTraceParser<TraceProcessorSession, ProtoLogMessage, ProtoLogMessage, ProtoLogTrace>() {
27 
28     override val traceName = "Transitions Trace"
29 
30     override fun createTrace(entries: Collection<ProtoLogMessage>): ProtoLogTrace {
31         return ProtoLogTrace(entries)
32     }
33 
34     override fun doDecodeByteArray(bytes: ByteArray): TraceProcessorSession {
35         error("This parser can only read from perfetto trace processor")
36     }
37 
38     override fun shouldParseEntry(entry: ProtoLogMessage) = true
39 
40     override fun getEntries(input: TraceProcessorSession): List<ProtoLogMessage> {
41         val messages: List<ProtoLogMessage> =
42             mutableListOf<ProtoLogMessage>().apply {
43                 input.query(getSqlQueryProtoLogMessages()) { rows ->
44                     this.addAll(
45                         rows.map {
46                             ProtoLogMessage(
47                                 it["ts"] as Long,
48                                 LogLevel.entries.firstOrNull { entry ->
49                                     it["level"] == entry.toString()
50                                 }
51                                     ?: error("Failed to convert ${it["level"]} to LogLevel enum"),
52                                 it["tag"] as String,
53                                 it["message"] as String,
54                                 it["stacktrace"]?.let { it as String },
55                             )
56                         }
57                     )
58                 }
59             }
60 
61         return messages
62     }
63 
64     override fun getTimestamp(entry: ProtoLogMessage): Timestamp = entry.timestamp
65 
66     override fun doParseEntry(entry: ProtoLogMessage) = entry
67 
68     companion object {
69         private fun getSqlQueryProtoLogMessages() =
70             "SELECT ts, level, tag, message, stacktrace FROM protolog;"
71     }
72 }
73