• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.base;
6 
7 import android.os.SystemClock;
8 
9 import org.chromium.build.annotations.CheckDiscard;
10 
11 /**
12  * Utilities related to timestamps, including the ability to use fake time for tests via
13  * FakeTimeTestRule.
14  */
15 public class TimeUtils {
16     /**
17      * Interval timer using SystemClock.uptimeMillis() (excludes deep sleep).
18      * See: https://developer.android.com/reference/android/os/SystemClock
19      */
20     @CheckDiscard("Class should get inlined by R8.")
21     public static class UptimeMillisTimer {
22         private final long mStart = uptimeMillis();
23 
getElapsedMillis()24         public long getElapsedMillis() {
25             return uptimeMillis() - mStart;
26         }
27     }
28 
29     /**
30      * Interval timer using SystemClock.elapsedRealtime() (includes deep sleep).
31      * See: https://developer.android.com/reference/android/os/SystemClock
32      */
33     @CheckDiscard("Class should get inlined by R8.")
34     public static class ElapsedRealtimeMillisTimer {
35         private final long mStart = elapsedRealtimeMillis();
36 
getElapsedMillis()37         public long getElapsedMillis() {
38             return elapsedRealtimeMillis() - mStart;
39         }
40     }
41 
42     /**
43      * Interval timer using SystemClock.elapsedRealtimeNanos() (includes deep sleep).
44      * See: https://developer.android.com/reference/android/os/SystemClock
45      */
46     @CheckDiscard("Class should get inlined by R8.")
47     public static class ElapsedRealtimeNanosTimer {
48         private final long mStart = elapsedRealtimeNanos();
49 
getElapsedNanos()50         public long getElapsedNanos() {
51             return elapsedRealtimeNanos() - mStart;
52         }
53     }
54 
55     /**
56      * Interval timer using SystemClock.currentThreadTimeMillis() (excludes blocking time).
57      * See: https://developer.android.com/reference/android/os/SystemClock
58      */
59     @CheckDiscard("Class should get inlined by R8.")
60     public static class CurrentThreadTimeMillisTimer {
61         private final long mStart = currentThreadTimeMillis();
62 
getElapsedMillis()63         public long getElapsedMillis() {
64             return currentThreadTimeMillis() - mStart;
65         }
66     }
67 
68     interface FakeClock {
uptimeMillis()69         long uptimeMillis();
elapsedRealtimeNanos()70         long elapsedRealtimeNanos();
currentThreadTimeMillis()71         long currentThreadTimeMillis();
currentTimeMillis()72         long currentTimeMillis();
73     }
74 
TimeUtils()75     private TimeUtils() {}
76 
77     // Use these in favor of TimeUnit.convert() in order to avoid the overhead of a
78     // static-get / static-invoke.
79     public static final long SECONDS_PER_MINUTE = 60;
80     public static final long SECONDS_PER_HOUR = SECONDS_PER_MINUTE * 60;
81     public static final long SECONDS_PER_DAY = SECONDS_PER_HOUR * 24;
82     public static final long MILLISECONDS_PER_MINUTE = SECONDS_PER_MINUTE * 1000;
83     public static final long NANOSECONDS_PER_MICROSECOND = 1000;
84     public static final long NANOSECONDS_PER_MILLISECOND = 1000000;
85 
86     // Used by FakeTimeTestRule. Visibility is restricted to ensure tests use the rule, which
87     // restores the value to null in its clean-up logic.
88     static FakeClock sFakeClock;
89 
90     /**
91      * Wrapper for System.currentTimeMillis() (milliseconds since the epoch).
92      * Can be faked in tests using FakeTimeTestRule.
93      * See: https://developer.android.com/reference/android/os/SystemClock
94      */
95     @CheckDiscard("Should get inlined by R8.")
currentTimeMillis()96     public static long currentTimeMillis() {
97         if (sFakeClock != null) {
98             return sFakeClock.currentTimeMillis();
99         }
100         return System.currentTimeMillis();
101     }
102 
103     /**
104      * Wrapper for SystemClock.uptimeMillis() (uptime excluding deep sleep).
105      * Can be faked in tests using FakeTimeTestRule.
106      * See: https://developer.android.com/reference/android/os/SystemClock
107      */
108     @CheckDiscard("Should get inlined by R8.")
uptimeMillis()109     public static long uptimeMillis() {
110         if (sFakeClock != null) {
111             return sFakeClock.uptimeMillis();
112         }
113         return SystemClock.uptimeMillis();
114     }
115 
116     /**
117      * Wrapper for SystemClock.elapsedRealtimeNanos() (uptime including deep sleep).
118      * Can be faked in tests using FakeTimeTestRule.
119      * See: https://developer.android.com/reference/android/os/SystemClock
120      */
121     @CheckDiscard("Should get inlined by R8.")
elapsedRealtimeNanos()122     public static long elapsedRealtimeNanos() {
123         if (sFakeClock != null) {
124             return sFakeClock.elapsedRealtimeNanos();
125         }
126         return SystemClock.elapsedRealtimeNanos();
127     }
128 
129     /**
130      * Wrapper for SystemClock.elapsedRealtimeMillis() (uptime including deep sleep).
131      * Can be faked in tests using FakeTimeTestRule.
132      * See: https://developer.android.com/reference/android/os/SystemClock
133      */
134     @CheckDiscard("Should get inlined by R8.")
elapsedRealtimeMillis()135     public static long elapsedRealtimeMillis() {
136         if (sFakeClock != null) {
137             return sFakeClock.elapsedRealtimeNanos() / NANOSECONDS_PER_MILLISECOND;
138         }
139         return SystemClock.elapsedRealtime();
140     }
141 
142     /**
143      * Wrapper for SystemClock.currentThreadTimeMillis() (excludes blocking time).
144      * Can be faked in tests using FakeTimeTestRule.
145      * See: https://developer.android.com/reference/android/os/SystemClock
146      */
147     @CheckDiscard("Should get inlined by R8.")
currentThreadTimeMillis()148     public static long currentThreadTimeMillis() {
149         if (sFakeClock != null) {
150             return sFakeClock.currentThreadTimeMillis();
151         }
152         return SystemClock.currentThreadTimeMillis();
153     }
154 }
155