• 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.common.traces.events
18 
19 import android.tools.common.ITrace
20 import android.tools.common.Timestamp
21 import android.tools.common.Timestamps
22 import kotlin.js.JsExport
23 
24 @JsExport
25 class CujTrace(override val entries: Array<Cuj>) : ITrace<Cuj> {
26 
slicenull27     override fun slice(startTimestamp: Timestamp, endTimestamp: Timestamp): CujTrace {
28         return CujTrace(
29             entries
30                 .dropWhile { it.endTimestamp < startTimestamp }
31                 .dropLastWhile { it.startTimestamp > endTimestamp }
32                 .toTypedArray()
33         )
34     }
35 
36     companion object {
fromnull37         fun from(cujEvents: Array<CujEvent>): CujTrace {
38             val cujs = mutableListOf<Cuj>()
39 
40             val sortedCujEvents = cujEvents.sortedBy { it.timestamp.unixNanos }
41             val startEvents = sortedCujEvents.filter { it.type == CujEvent.Companion.Type.START }
42             val endEvents = sortedCujEvents.filter { it.type == CujEvent.Companion.Type.END }
43             val canceledEvents =
44                 sortedCujEvents.filter { it.type == CujEvent.Companion.Type.CANCEL }
45 
46             for (startEvent in startEvents) {
47                 val matchingEndEvent =
48                     endEvents.firstOrNull {
49                         it.cuj == startEvent.cuj && it.timestamp >= startEvent.timestamp
50                     }
51                 val matchingCancelEvent =
52                     canceledEvents.firstOrNull {
53                         it.cuj == startEvent.cuj && it.timestamp >= startEvent.timestamp
54                     }
55 
56                 if (matchingCancelEvent == null && matchingEndEvent == null) {
57                     // CUJ started but not ended within the trace
58                     continue
59                 }
60 
61                 val closingEvent =
62                     listOf(matchingCancelEvent, matchingEndEvent).minBy {
63                         it?.timestamp ?: Timestamps.max()
64                     }
65                         ?: error("Should have found one matching closing event")
66                 val canceled = closingEvent.type == CujEvent.Companion.Type.CANCEL
67 
68                 cujs.add(
69                     Cuj(startEvent.cuj, startEvent.timestamp, closingEvent.timestamp, canceled)
70                 )
71             }
72 
73             return CujTrace(cujs.toTypedArray())
74         }
75     }
76 }
77