• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2019 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 com.android.protolog.tool
18 
19 import perfetto.protos.PerfettoTrace.ProtoLogLevel
20 import perfetto.protos.PerfettoTrace.ProtoLogViewerConfig
21 
22 /**
23  * A builder class to construct the viewer configuration (i.e. mappings of protolog hashes to log
24  * message information used to decode the protolog messages) encoded as a proto message.
25  */
26 class ViewerConfigProtoBuilder : ProtoLogTool.ProtologViewerConfigBuilder {
27     /**
28      * @return a byte array of a ProtoLogViewerConfig proto message encoding all the viewer
29      * configurations mapping protolog hashes to message information and log group information.
30      */
31     override fun build(groups: Collection<LogGroup>, statements: Map<ProtoLogTool.LogCall, Long>): ByteArray {
32         val configBuilder = ProtoLogViewerConfig.newBuilder()
33 
34         // TODO(b/373754057): We are passing all the groups now, because some groups might only be
35         //  used by Kotlin code that is not processed, but for group that get enabled to log to
36         //  logcat we try and load the viewer configurations for this group, so the group must exist
37         //  in the viewer config. Once Kotlin is pre-processed or this logic changes we should only
38         //  use the groups that are actually used as an optimization.
39         val groupIds = mutableMapOf<LogGroup, Int>()
40         groups.forEach {
41             groupIds.putIfAbsent(it, groupIds.size + 1)
42         }
43 
44         groupIds.forEach { (group, id) ->
45             configBuilder.addGroups(ProtoLogViewerConfig.Group.newBuilder()
46                     .setId(id)
47                     .setName(group.name)
48                     .setTag(group.tag)
49                     .build())
50         }
51 
52         statements.forEach { (log, key) ->
53             val groupId = groupIds[log.logGroup] ?: error("missing group id")
54 
55             configBuilder.addMessages(
56                 ProtoLogViewerConfig.MessageData.newBuilder()
57                         .setMessageId(key)
58                         .setMessage(log.messageString)
59                         .setLevel(
60                             ProtoLogLevel.forNumber(log.logLevel.id))
61                         .setGroupId(groupId)
62                         .setLocation("${log.position}:${log.lineNumber}")
63             )
64         }
65 
66         return configBuilder.build().toByteArray()
67     }
68 }
69