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.common.traces.wm 18 19 import android.tools.common.ITrace 20 import android.tools.common.Timestamp 21 import kotlin.js.JsExport 22 import kotlin.js.JsName 23 import kotlin.text.StringBuilder 24 25 @JsExport 26 data class TransitionsTrace(override val entries: Array<Transition>) : ITrace<Transition> { equalsnull27 override fun equals(other: Any?): Boolean { 28 if (this === other) return true 29 if (other !is TransitionsTrace) return false 30 31 if (!entries.contentEquals(other.entries)) return false 32 33 return true 34 } 35 hashCodenull36 override fun hashCode(): Int { 37 return entries.contentHashCode() 38 } 39 40 @JsName("prettyPrint") prettyPrintnull41 fun prettyPrint(): String { 42 val sb = StringBuilder("TransitionTrace(") 43 44 for (transition in entries) { 45 sb.append("\n\t- ").append(transition) 46 } 47 if (entries.isEmpty()) { 48 sb.append("EMPTY)") 49 } else { 50 sb.append("\n)") 51 } 52 return sb.toString() 53 } 54 55 @JsName("asCompressed") asCompressednull56 fun asCompressed(): TransitionsTrace { 57 val transitionById = mutableMapOf<Int, Transition>() 58 59 for (transition in this.entries) { 60 require(transition.id != 0) { "Requires non-null transition id" } 61 val accumulatedTransition = transitionById[transition.id] 62 if (accumulatedTransition == null) { 63 transitionById[transition.id] = transition 64 } else { 65 transitionById[transition.id] = 66 Transition.mergePartialTransitions(accumulatedTransition, transition) 67 } 68 } 69 70 val sortedCompressedTransitions = 71 transitionById.values.sortedWith(compareBy { it.timestamp }) 72 73 return TransitionsTrace(sortedCompressedTransitions.toTypedArray()) 74 } 75 slicenull76 override fun slice(startTimestamp: Timestamp, endTimestamp: Timestamp): TransitionsTrace { 77 require(startTimestamp.hasElapsedTimestamp && endTimestamp.hasElapsedTimestamp) 78 return sliceElapsed(startTimestamp.elapsedNanos, endTimestamp.elapsedNanos) 79 } 80 sliceElapsednull81 private fun sliceElapsed(from: Long, to: Long): TransitionsTrace { 82 return TransitionsTrace( 83 this.entries 84 .dropWhile { it.sendTime.elapsedNanos < from } 85 .dropLastWhile { it.createTime.elapsedNanos > to } 86 .toTypedArray() 87 ) 88 } 89 } 90