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 17import {Transformer} from 'app/components/timeline/mini-timeline/transformer'; 18import {Segment} from 'app/components/timeline/segment'; 19import {TimelineUtils} from 'app/components/timeline/timeline_utils'; 20import {TimelineData} from 'app/timeline_data'; 21import {assertDefined} from 'common/assert_utils'; 22import {TimeRange, Timestamp} from 'common/time'; 23import {Trace, TraceEntry} from 'trace/trace'; 24import {TraceType} from 'trace/trace_type'; 25import {PropertyTreeNode} from 'trace/tree_node/property_tree_node'; 26import { 27 MiniCanvasDrawerData, 28 TimelineTrace, 29 TimelineTraces, 30} from './mini_canvas_drawer_data'; 31 32export class MiniTimelineDrawerInput { 33 constructor( 34 public fullRange: TimeRange, 35 public selectedPosition: Timestamp, 36 public selection: TimeRange, 37 public zoomRange: TimeRange, 38 public traces: Array<Trace<object>>, 39 public timelineData: TimelineData, 40 public bookmarks: Timestamp[], 41 public isDarkMode: boolean, 42 ) {} 43 44 transform(mapToRange: Segment): MiniCanvasDrawerData { 45 const transformer = new Transformer( 46 this.zoomRange, 47 mapToRange, 48 assertDefined(this.timelineData.getTimestampConverter()), 49 ); 50 51 return new MiniCanvasDrawerData( 52 transformer.transform(this.selectedPosition), 53 { 54 from: transformer.transform(this.selection.from), 55 to: transformer.transform(this.selection.to), 56 }, 57 () => { 58 return this.transformTracesTimestamps(transformer); 59 }, 60 transformer, 61 this.transformBookmarks(transformer), 62 ); 63 } 64 65 private async transformTracesTimestamps( 66 transformer: Transformer, 67 ): Promise<TimelineTraces> { 68 const transformedTraceSegments = new Map<Trace<object>, TimelineTrace>(); 69 70 this.traces.forEach((trace) => { 71 const activeEntry = this.timelineData.findCurrentEntryFor(trace); 72 73 if (trace.type === TraceType.TRANSITION) { 74 // Transition trace is a special case, with entries with time ranges 75 transformedTraceSegments.set(trace, { 76 points: [], 77 activePoint: undefined, 78 segments: this.transformTransitionTraceTimestamps( 79 transformer, 80 trace as Trace<PropertyTreeNode>, 81 ), 82 activeSegment: activeEntry 83 ? this.transformTransitionEntry( 84 transformer, 85 activeEntry as TraceEntry<PropertyTreeNode>, 86 ) 87 : undefined, 88 }); 89 } else { 90 transformedTraceSegments.set(trace, { 91 points: this.transformTraceTimestamps(transformer, trace), 92 activePoint: activeEntry 93 ? transformer.transform(activeEntry.getTimestamp()) 94 : undefined, 95 segments: [], 96 activeSegment: undefined, 97 }); 98 } 99 }); 100 101 return transformedTraceSegments; 102 } 103 104 private transformTransitionTraceTimestamps( 105 transformer: Transformer, 106 trace: Trace<PropertyTreeNode>, 107 ): Segment[] { 108 return trace 109 .mapEntry((entry) => this.transformTransitionEntry(transformer, entry)) 110 .filter((it) => it !== undefined) as Segment[]; 111 } 112 113 private transformBookmarks(transformer: Transformer): number[] { 114 return this.bookmarks.map((bookmarkedTimestamp) => 115 transformer.transform(bookmarkedTimestamp), 116 ); 117 } 118 119 private transformTransitionEntry( 120 transformer: Transformer, 121 entry: TraceEntry<PropertyTreeNode>, 122 ): Segment | undefined { 123 const transition: PropertyTreeNode = 124 this.timelineData.getTransitions()[entry.getIndex()]; 125 126 const timeRange = TimelineUtils.getTimeRangeForTransition( 127 transition, 128 this.selection, 129 assertDefined(this.timelineData.getTimestampConverter()), 130 ); 131 132 if (!timeRange) { 133 return undefined; 134 } 135 136 return { 137 from: transformer.transform(timeRange.from), 138 to: transformer.transform(timeRange.to), 139 }; 140 } 141 142 private transformTraceTimestamps( 143 transformer: Transformer, 144 trace: Trace<{}>, 145 ): number[] { 146 const result: number[] = []; 147 148 trace.forEachTimestamp((timestamp) => { 149 result.push(transformer.transform(timestamp)); 150 }); 151 152 return result; 153 } 154} 155