1 /*
<lambda>null2  * 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.traces.parsers
18 
19 import android.tools.traces.DeviceStateDump
20 import android.tools.traces.NullableDeviceStateDump
21 import android.tools.traces.parsers.perfetto.LayersTraceParser
22 import android.tools.traces.parsers.perfetto.TraceProcessorSession
23 import android.tools.traces.parsers.wm.WindowManagerDumpParser
24 import android.tools.traces.surfaceflinger.LayerTraceEntry
25 import android.tools.traces.surfaceflinger.LayersTrace
26 import android.tools.traces.wm.WindowManagerState
27 import android.tools.traces.wm.WindowManagerTrace
28 import android.tools.withTracing
29 
30 /**
31  * Represents a state dump containing the [WindowManagerTrace] and the [LayersTrace] both parsed and
32  * in raw (byte) data.
33  */
34 class DeviceDumpParser {
35     companion object {
36         var lastWmTraceData = ByteArray(0)
37         var lastLayersTraceData = ByteArray(0)
38 
39         /**
40          * Creates a device state dump containing the [WindowManagerTrace] and [LayersTrace]
41          * obtained from a `dumpsys` command. The parsed traces will contain a single
42          * [WindowManagerState] or [LayerTraceEntry].
43          *
44          * @param wmTraceData [WindowManagerTrace] content
45          * @param layersTraceData [LayersTrace] content
46          * @param clearCacheAfterParsing If the caching used while parsing the proto should be
47          *
48          * ```
49          *                               cleared or remain in memory
50          * ```
51          */
52         @JvmStatic
53         fun fromNullableDump(
54             wmTraceData: ByteArray,
55             layersTraceData: ByteArray,
56             clearCacheAfterParsing: Boolean
57         ): NullableDeviceStateDump {
58             return withTracing("fromNullableDump") {
59                     NullableDeviceStateDump(
60                         wmState =
61                             if (wmTraceData.isNotEmpty()) {
62                                 WindowManagerDumpParser()
63                                     .parse(wmTraceData, clearCache = clearCacheAfterParsing)
64                                     .entries
65                                     .first()
66                             } else {
67                                 null
68                             },
69                         layerState =
70                             if (layersTraceData.isNotEmpty()) {
71                                 TraceProcessorSession.loadPerfettoTrace(layersTraceData) { session
72                                     ->
73                                     LayersTraceParser()
74                                         .parse(session, clearCache = clearCacheAfterParsing)
75                                         .entries
76                                         .first()
77                                 }
78                             } else {
79                                 null
80                             }
81                     )
82                 }
83                 .also {
84                     lastWmTraceData = wmTraceData
85                     lastLayersTraceData = layersTraceData
86                 }
87         }
88 
89         /** See [fromNullableDump] */
90         @JvmStatic
91         fun fromDump(
92             wmTraceData: ByteArray,
93             layersTraceData: ByteArray,
94             clearCacheAfterParsing: Boolean
95         ): DeviceStateDump {
96             return withTracing("fromDump") {
97                     val nullableDump =
98                         fromNullableDump(wmTraceData, layersTraceData, clearCacheAfterParsing)
99                     DeviceStateDump(
100                         nullableDump.wmState ?: error("WMState dump missing"),
101                         nullableDump.layerState ?: error("Layer State dump missing")
102                     )
103                 }
104                 .also {
105                     lastWmTraceData = wmTraceData
106                     lastLayersTraceData = layersTraceData
107                 }
108         }
109     }
110 }
111