1/*
2 * Copyright (C) 2024 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 {TimeRange, Timestamp} from 'common/time';
18import {ComponentTimestampConverter} from 'common/timestamp_converter';
19import {PropertyTreeNode} from 'trace/tree_node/property_tree_node';
20
21export class TimelineUtils {
22  static getTimeRangeForTransition(
23    transition: PropertyTreeNode,
24    fullTimeRange: TimeRange,
25    converter: ComponentTimestampConverter,
26  ): TimeRange | undefined {
27    const shellData = transition.getChildByName('shellData');
28    const wmData = transition.getChildByName('wmData');
29
30    const aborted = transition.getChildByName('aborted')?.getValue() ?? false;
31
32    const dispatchTimestamp: Timestamp | undefined = shellData
33      ?.getChildByName('dispatchTimeNs')
34      ?.getValue();
35    const createTimestamp: Timestamp | undefined = wmData
36      ?.getChildByName('createTimeNs')
37      ?.getValue();
38    const finishOrAbortTimestamp: Timestamp | undefined = aborted
39      ? shellData?.getChildByName('abortTimeNs')?.getValue()
40      : wmData?.getChildByName('finishTimeNs')?.getValue();
41
42    // currently we only render transitions during 'play' stage, so
43    // do not render if no dispatch time and no finish/shell abort time
44    // or if transition created but never dispatched to shell
45    // TODO (b/324056564): visualise transition lifecycle in timeline
46    if (
47      (!dispatchTimestamp && !finishOrAbortTimestamp) ||
48      (!dispatchTimestamp && createTimestamp)
49    ) {
50      return undefined;
51    }
52
53    const timeRangeMin = fullTimeRange.from.getValueNs();
54    const timeRangeMax = fullTimeRange.to.getValueNs();
55
56    const dispatchTimeNs = dispatchTimestamp
57      ? dispatchTimestamp.getValueNs()
58      : timeRangeMin;
59    const finishTimeNs = finishOrAbortTimestamp
60      ? finishOrAbortTimestamp.getValueNs()
61      : timeRangeMax;
62
63    const startTime = converter.makeTimestampFromNs(
64      dispatchTimeNs > timeRangeMin ? dispatchTimeNs : timeRangeMin,
65    );
66    const finishTime = converter.makeTimestampFromNs(finishTimeNs);
67
68    return new TimeRange(startTime, finishTime);
69  }
70}
71