1 /*
2  * Copyright 2020 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 @file:Suppress("NOTHING_TO_INLINE")
18 
19 package androidx.camera.camera2.pipe.core
20 
21 import android.os.SystemClock
22 import javax.inject.Inject
23 import javax.inject.Singleton
24 
25 /** A nanosecond timestamp */
26 @JvmInline
27 public value class TimestampNs constructor(public val value: Long) {
minusnull28     public inline operator fun minus(other: TimestampNs): DurationNs =
29         DurationNs(value - other.value)
30 
31     public inline operator fun plus(other: DurationNs): TimestampNs =
32         TimestampNs(value + other.value)
33 }
34 
35 @JvmInline
36 public value class DurationNs(public val value: Long) {
37     public inline operator fun minus(other: DurationNs): DurationNs =
38         DurationNs(value - other.value)
39 
40     public inline operator fun plus(other: DurationNs): DurationNs = DurationNs(value + other.value)
41 
42     public inline operator fun plus(other: TimestampNs): TimestampNs =
43         TimestampNs(value + other.value)
44 
45     public operator fun compareTo(other: DurationNs): Int {
46         return if (value == other.value) {
47             0
48         } else if (value < other.value) {
49             -1
50         } else {
51             1
52         }
53     }
54 
55     public companion object {
56         public inline fun fromMs(durationMs: Long): DurationNs = DurationNs(durationMs * 1_000_000L)
57     }
58 }
59 
60 public interface TimeSource {
nownull61     public fun now(): TimestampNs
62 }
63 
64 @Singleton
65 public class SystemTimeSource @Inject constructor() : TimeSource {
66     override fun now(): TimestampNs = TimestampNs(SystemClock.elapsedRealtimeNanos())
67 }
68 
69 public object Timestamps {
nownull70     public inline fun now(timeSource: TimeSource): TimestampNs = timeSource.now()
71 
72     public inline fun DurationNs.formatNs(): String = "$this ns"
73 
74     public inline fun DurationNs.formatMs(decimals: Int = 3): String =
75         "%.${decimals}f ms".format(null, this.value / 1_000_000.0)
76 
77     public inline fun TimestampNs.formatNs(): String = "$this ns"
78 
79     public inline fun TimestampNs.formatMs(): String = "${this.value / 1_000_000} ms"
80 
81     public inline fun TimestampNs.measureNow(
82         timeSource: TimeSource = SystemTimeSource()
83     ): DurationNs = now(timeSource) - this
84 }
85