• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.device.traces.parsers.wm
18 
19 import android.tools.common.Timestamp
20 import android.tools.common.Timestamps
21 import android.tools.common.parsers.AbstractTraceParser
22 import android.tools.common.traces.wm.ShellTransitionData
23 import android.tools.common.traces.wm.Transition
24 import android.tools.common.traces.wm.TransitionsTrace
25 import com.android.wm.shell.nano.WmShellTransitionTraceProto
26 
27 /** Parser for [TransitionsTrace] objects */
28 class ShellTransitionTraceParser :
29     AbstractTraceParser<
30         WmShellTransitionTraceProto,
31         com.android.wm.shell.nano.Transition,
32         Transition,
33         TransitionsTrace
34     >() {
35     override val traceName: String = "Transition trace (shell)"
36 
createTracenull37     override fun createTrace(entries: List<Transition>): TransitionsTrace {
38         return TransitionsTrace(entries.toTypedArray())
39     }
40 
doDecodeByteArraynull41     override fun doDecodeByteArray(bytes: ByteArray): WmShellTransitionTraceProto =
42         WmShellTransitionTraceProto.parseFrom(bytes)
43 
44     override fun shouldParseEntry(entry: com.android.wm.shell.nano.Transition): Boolean {
45         return true
46     }
47 
getEntriesnull48     override fun getEntries(
49         input: WmShellTransitionTraceProto
50     ): List<com.android.wm.shell.nano.Transition> = input.transitions.toList()
51 
52     override fun getTimestamp(entry: com.android.wm.shell.nano.Transition): Timestamp {
53         requireValidTimestamp(entry)
54 
55         if (entry.dispatchTimeNs != 0L) {
56             return Timestamps.from(elapsedNanos = entry.dispatchTimeNs)
57         }
58         if (entry.mergeRequestTimeNs != 0L) {
59             return Timestamps.from(elapsedNanos = entry.mergeRequestTimeNs)
60         }
61         if (entry.mergeTimeNs != 0L) {
62             return Timestamps.from(elapsedNanos = entry.mergeTimeNs)
63         }
64         if (entry.abortTimeNs != 0L) {
65             return Timestamps.from(elapsedNanos = entry.abortTimeNs)
66         }
67 
68         error("No valid timestamp for entry")
69     }
70 
71     private val handlerMapping = mutableMapOf<Int, String>()
72 
onBeforeParsenull73     override fun onBeforeParse(input: WmShellTransitionTraceProto) {
74         handlerMapping.clear()
75         for (mapping in input.handlerMappings) {
76             handlerMapping[mapping.id] = mapping.name
77         }
78     }
79 
doParsenull80     override fun doParse(
81         input: WmShellTransitionTraceProto,
82         from: Timestamp,
83         to: Timestamp,
84         addInitialEntry: Boolean
85     ): TransitionsTrace {
86         val uncompressedTransitionsTrace = super.doParse(input, from, to, addInitialEntry)
87         return uncompressedTransitionsTrace.asCompressed()
88     }
89 
doParseEntrynull90     override fun doParseEntry(entry: com.android.wm.shell.nano.Transition): Transition {
91         require(entry.id != 0) { "Entry needs a non null id" }
92         requireValidTimestamp(entry)
93 
94         return Transition(
95             entry.id,
96             shellData =
97                 ShellTransitionData(
98                     dispatchTime =
99                         if (entry.dispatchTimeNs == 0L) null
100                         else Timestamps.from(elapsedNanos = entry.dispatchTimeNs),
101                     mergeRequestTime =
102                         if (entry.mergeRequestTimeNs == 0L) null
103                         else Timestamps.from(elapsedNanos = entry.mergeRequestTimeNs),
104                     mergeTime =
105                         if (entry.mergeTimeNs == 0L) null
106                         else Timestamps.from(elapsedNanos = entry.mergeTimeNs),
107                     abortTime =
108                         if (entry.abortTimeNs == 0L) null
109                         else Timestamps.from(elapsedNanos = entry.abortTimeNs),
110                     handler = handlerMapping[entry.handler],
111                     mergedInto = if (entry.mergedInto == 0) null else entry.mergedInto
112                 )
113         )
114     }
115 
116     companion object {
requireValidTimestampnull117         private fun requireValidTimestamp(entry: com.android.wm.shell.nano.Transition) {
118             require(
119                 entry.dispatchTimeNs != 0L ||
120                     entry.mergeRequestTimeNs != 0L ||
121                     entry.mergeTimeNs != 0L ||
122                     entry.abortTimeNs != 0L
123             ) {
124                 "Requires at least one non-null timestamp"
125             }
126         }
127     }
128 }
129