1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/common/inter_process_time_ticks_converter.h"
7 #include "base/logging.h"
8 #include "base/strings/string_number_conversions.h"
12 InterProcessTimeTicksConverter::InterProcessTimeTicksConverter(
13 const LocalTimeTicks
& local_lower_bound
,
14 const LocalTimeTicks
& local_upper_bound
,
15 const RemoteTimeTicks
& remote_lower_bound
,
16 const RemoteTimeTicks
& remote_upper_bound
)
17 : remote_lower_bound_(remote_lower_bound
.value_
),
18 remote_upper_bound_(remote_upper_bound
.value_
) {
19 int64 target_range
= local_upper_bound
.value_
- local_lower_bound
.value_
;
20 int64 source_range
= remote_upper_bound
.value_
- remote_lower_bound
.value_
;
21 DCHECK_GE(target_range
, 0);
22 DCHECK_GE(source_range
, 0);
23 if (source_range
<= target_range
) {
24 // We fit! Center the source range on the target range.
28 local_lower_bound
.value_
+ (target_range
- source_range
) / 2;
29 // When converting times, remote bounds should fall within local bounds.
30 DCHECK_LE(local_lower_bound
.value_
,
31 ToLocalTimeTicks(remote_lower_bound
).value_
);
32 DCHECK_GE(local_upper_bound
.value_
,
33 ToLocalTimeTicks(remote_upper_bound
).value_
);
37 // Interpolate values so that remote range will be will exactly fit into the
38 // local range, if possible.
39 numerator_
= target_range
;
40 denominator_
= source_range
;
41 local_base_time_
= local_lower_bound
.value_
;
42 // When converting times, remote bounds should equal local bounds.
43 DCHECK_EQ(local_lower_bound
.value_
,
44 ToLocalTimeTicks(remote_lower_bound
).value_
);
45 DCHECK_EQ(local_upper_bound
.value_
,
46 ToLocalTimeTicks(remote_upper_bound
).value_
);
47 DCHECK_EQ(target_range
, Convert(source_range
));
50 LocalTimeTicks
InterProcessTimeTicksConverter::ToLocalTimeTicks(
51 const RemoteTimeTicks
& remote_ms
) const {
52 // If input time is "null", return another "null" time.
53 if (remote_ms
.value_
== 0)
54 return LocalTimeTicks(0);
55 DCHECK_LE(remote_lower_bound_
, remote_ms
.value_
);
56 DCHECK_GE(remote_upper_bound_
, remote_ms
.value_
);
57 RemoteTimeDelta remote_delta
= remote_ms
- remote_lower_bound_
;
58 return LocalTimeTicks(local_base_time_
+
59 ToLocalTimeDelta(remote_delta
).value_
);
62 LocalTimeDelta
InterProcessTimeTicksConverter::ToLocalTimeDelta(
63 const RemoteTimeDelta
& remote_delta
) const {
64 DCHECK_GE(remote_upper_bound_
, remote_lower_bound_
+ remote_delta
.value_
);
65 return LocalTimeDelta(Convert(remote_delta
.value_
));
68 int64
InterProcessTimeTicksConverter::Convert(int64 value
) const {
72 return numerator_
* value
/ denominator_
;
75 bool InterProcessTimeTicksConverter::IsSkewAdditiveForMetrics() const {
76 return numerator_
== 1 && denominator_
== 1;
79 base::TimeDelta
InterProcessTimeTicksConverter::GetSkewForMetrics() const {
80 return base::TimeTicks::FromInternalValue(remote_lower_bound_
) -
81 base::TimeTicks::FromInternalValue(local_base_time_
);
84 } // namespace content