• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 @file:JvmName("Utils")
18 
19 package android.tools.device.traces
20 
21 import android.app.UiAutomation
22 import android.os.IBinder
23 import android.os.ParcelFileDescriptor
24 import android.tools.common.Logger
25 import android.tools.common.MILLISECOND_AS_NANOSECONDS
26 import android.tools.common.io.TraceType
27 import android.tools.common.traces.DeviceStateDump
28 import android.tools.common.traces.NullableDeviceStateDump
29 import android.tools.common.traces.surfaceflinger.LayerTraceEntry
30 import android.tools.common.traces.wm.WindowManagerState
31 import android.tools.device.traces.parsers.DeviceDumpParser
32 import androidx.test.platform.app.InstrumentationRegistry
33 import java.text.SimpleDateFormat
34 import java.util.Date
35 import java.util.Locale
36 import java.util.TimeZone
37 
38 fun formatRealTimestamp(timestampNs: Long): String {
39     val timestampMs = timestampNs / MILLISECOND_AS_NANOSECONDS
40     val remainderNs = timestampNs % MILLISECOND_AS_NANOSECONDS
41     val date = Date(timestampMs)
42 
43     val timeFormatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.ENGLISH)
44     timeFormatter.timeZone = TimeZone.getTimeZone("UTC")
45 
46     return "${timeFormatter.format(date)}${remainderNs.toString().padStart(6, '0')}"
47 }
48 
executeShellCommandnull49 fun executeShellCommand(cmd: String): ByteArray {
50     val uiAutomation: UiAutomation = InstrumentationRegistry.getInstrumentation().uiAutomation
51     val fileDescriptor = uiAutomation.executeShellCommand(cmd)
52     ParcelFileDescriptor.AutoCloseInputStream(fileDescriptor).use { inputStream ->
53         return inputStream.readBytes()
54     }
55 }
56 
doBinderDumpnull57 private fun doBinderDump(name: String): ByteArray {
58     // create an fd for the binder transaction
59     val pipe = ParcelFileDescriptor.createPipe()
60     val source = pipe[0]
61     val sink = pipe[1]
62 
63     // ServiceManager isn't accessible from tests, so use reflection
64     // this should return an IBinder
65     val service =
66         Class.forName("android.os.ServiceManager")
67             .getMethod("getServiceOrThrow", String::class.java)
68             .invoke(null, name) as IBinder?
69 
70     // this is equal to ServiceManager::PROTO_ARG
71     val args = arrayOf("--proto")
72     service?.dump(sink.fileDescriptor, args)
73     sink.close()
74 
75     // convert the FD into a ByteArray
76     ParcelFileDescriptor.AutoCloseInputStream(source).use { inputStream ->
77         return inputStream.readBytes()
78     }
79 }
80 
getCurrentWindowManagerStatenull81 private fun getCurrentWindowManagerState() = doBinderDump("window")
82 
83 private fun getCurrentLayersState() = doBinderDump("SurfaceFlinger")
84 
85 /**
86  * Gets the current device state dump containing the [WindowManagerState] (optional) and the
87  * [LayerTraceEntry] (optional) in raw (byte) data.
88  *
89  * @param dumpTypes Flags determining which types of traces should be included in the dump
90  */
91 fun getCurrentState(
92     vararg dumpTypes: TraceType = arrayOf(TraceType.SF_DUMP, TraceType.WM_DUMP)
93 ): Pair<ByteArray, ByteArray> {
94     if (dumpTypes.isEmpty()) {
95         throw IllegalArgumentException("No dump specified")
96     }
97 
98     val traceTypes = dumpTypes.filter { it.isTrace }
99     if (traceTypes.isNotEmpty()) {
100         throw IllegalArgumentException("Only dump types are supported. Invalid types: $traceTypes")
101     }
102 
103     Logger.d(LOG_TAG, "Requesting new device state dump")
104     val wmTraceData =
105         if (dumpTypes.contains(TraceType.WM_DUMP)) {
106             getCurrentWindowManagerState()
107         } else {
108             ByteArray(0)
109         }
110     val layersTraceData =
111         if (dumpTypes.contains(TraceType.SF_DUMP)) {
112             getCurrentLayersState()
113         } else {
114             ByteArray(0)
115         }
116 
117     return Pair(wmTraceData, layersTraceData)
118 }
119 
120 /**
121  * Gets the current device state dump containing the [WindowManagerState] (optional) and the
122  * [LayerTraceEntry] (optional) parsed
123  *
124  * @param dumpTypes Flags determining which types of traces should be included in the dump
125  * @param clearCacheAfterParsing If the caching used while parsing the proto should be
126  *
127  * ```
128  *                               cleared or remain in memory
129  * ```
130  */
131 @JvmOverloads
getCurrentStateDumpNullablenull132 fun getCurrentStateDumpNullable(
133     vararg dumpTypes: TraceType = arrayOf(TraceType.SF_DUMP, TraceType.WM_DUMP),
134     clearCacheAfterParsing: Boolean = true
135 ): NullableDeviceStateDump {
136     val currentStateDump = getCurrentState(*dumpTypes)
137     return DeviceDumpParser.fromNullableDump(
138         currentStateDump.first,
139         currentStateDump.second,
140         clearCacheAfterParsing = clearCacheAfterParsing
141     )
142 }
143 
144 @JvmOverloads
getCurrentStateDumpnull145 fun getCurrentStateDump(
146     vararg dumpTypes: TraceType = arrayOf(TraceType.SF_DUMP, TraceType.WM_DUMP),
147     clearCacheAfterParsing: Boolean = true
148 ): DeviceStateDump {
149     val currentStateDump = getCurrentState(*dumpTypes)
150     return DeviceDumpParser.fromDump(
151         currentStateDump.first,
152         currentStateDump.second,
153         clearCacheAfterParsing = clearCacheAfterParsing
154     )
155 }
156