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.surfaceflinger 18 19 import android.surfaceflinger.proto.Transactions 20 import android.surfaceflinger.proto.Transactions.TransactionState 21 import android.surfaceflinger.proto.Transactions.TransactionTraceFile 22 import android.tools.common.Timestamp 23 import android.tools.common.Timestamps 24 import android.tools.common.parsers.AbstractTraceParser 25 import android.tools.common.traces.surfaceflinger.Transaction 26 import android.tools.common.traces.surfaceflinger.TransactionsTrace 27 import android.tools.common.traces.surfaceflinger.TransactionsTraceEntry 28 import android.tools.common.traces.wm.TransitionsTrace 29 30 /** Parser for [TransitionsTrace] objects */ 31 class TransactionsTraceParser : 32 AbstractTraceParser< 33 TransactionTraceFile, 34 Transactions.TransactionTraceEntry, 35 TransactionsTraceEntry, 36 TransactionsTrace 37 >() { 38 private var timestampOffset = 0L 39 override val traceName: String = "Transactions trace" 40 onBeforeParsenull41 override fun onBeforeParse(input: TransactionTraceFile) { 42 timestampOffset = input.realToElapsedTimeOffsetNanos 43 } 44 getTimestampnull45 override fun getTimestamp(entry: Transactions.TransactionTraceEntry): Timestamp { 46 require(timestampOffset != 0L) 47 return Timestamps.from( 48 elapsedNanos = entry.elapsedRealtimeNanos, 49 unixNanos = entry.elapsedRealtimeNanos + timestampOffset 50 ) 51 } 52 createTracenull53 override fun createTrace(entries: List<TransactionsTraceEntry>): TransactionsTrace = 54 TransactionsTrace(entries.toTypedArray()) 55 56 override fun getEntries(input: TransactionTraceFile): List<Transactions.TransactionTraceEntry> = 57 input.entryList 58 59 override fun doDecodeByteArray(bytes: ByteArray): TransactionTraceFile = 60 TransactionTraceFile.parseFrom(bytes) 61 62 override fun doParseEntry(entry: Transactions.TransactionTraceEntry): TransactionsTraceEntry { 63 val transactions = parseTransactionsProto(entry.transactionsList) 64 val transactionsTraceEntry = 65 TransactionsTraceEntry( 66 Timestamps.from( 67 elapsedNanos = entry.elapsedRealtimeNanos, 68 elapsedOffsetNanos = timestampOffset 69 ), 70 entry.vsyncId, 71 transactions 72 ) 73 transactions.forEach { it.appliedInEntry = transactionsTraceEntry } 74 return transactionsTraceEntry 75 } 76 parseTransactionsProtonull77 private fun parseTransactionsProto( 78 transactionStates: List<TransactionState> 79 ): Array<Transaction> { 80 val transactions = mutableListOf<Transaction>() 81 for (state in transactionStates) { 82 val transaction = 83 Transaction( 84 state.pid, 85 state.uid, 86 state.vsyncId, 87 state.postTime, 88 state.transactionId, 89 state.mergedTransactionIdsList.toTypedArray() 90 ) 91 transactions.add(transaction) 92 } 93 94 return transactions.toTypedArray() 95 } 96 } 97