• 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();
70 
elapsedRealtimeNanos()71         long elapsedRealtimeNanos();
72 
currentThreadTimeMillis()73         long currentThreadTimeMillis();
74 
currentTimeMillis()75         long currentTimeMillis();
76     }
77 
TimeUtils()78     private TimeUtils() {}
79 
80     // Use these in favor of TimeUnit.convert() in order to avoid the overhead of a
81     // static-get / static-invoke.
82     public static final long SECONDS_PER_MINUTE = 60;
83     public static final long SECONDS_PER_HOUR = SECONDS_PER_MINUTE * 60;
84     public static final long SECONDS_PER_DAY = SECONDS_PER_HOUR * 24;
85     public static final long MILLISECONDS_PER_MINUTE = SECONDS_PER_MINUTE * 1000;
86     public static final long NANOSECONDS_PER_MICROSECOND = 1000;
87     public static final long NANOSECONDS_PER_MILLISECOND = 1000000;
88 
89     // Used by FakeTimeTestRule. Visibility is restricted to ensure tests use the rule, which
90     // restores the value to null in its clean-up logic.
91     static FakeClock sFakeClock;
92 
93     /**
94      * Wrapper for System.currentTimeMillis() (milliseconds since the epoch).
95      * Can be faked in tests using FakeTimeTestRule.
96      * See: https://developer.android.com/reference/android/os/SystemClock
97      */
98     @CheckDiscard("Should get inlined by R8.")
currentTimeMillis()99     public static long currentTimeMillis() {
100         if (sFakeClock != null) {
101             return sFakeClock.currentTimeMillis();
102         }
103         return System.currentTimeMillis();
104     }
105 
106     /**
107      * Wrapper for SystemClock.uptimeMillis() (uptime excluding deep sleep).
108      * Can be faked in tests using FakeTimeTestRule.
109      * See: https://developer.android.com/reference/android/os/SystemClock
110      */
111     @CheckDiscard("Should get inlined by R8.")
uptimeMillis()112     public static long uptimeMillis() {
113         if (sFakeClock != null) {
114             return sFakeClock.uptimeMillis();
115         }
116         return SystemClock.uptimeMillis();
117     }
118 
119     /**
120      * Wrapper for SystemClock.elapsedRealtimeNanos() (uptime including deep sleep).
121      * Can be faked in tests using FakeTimeTestRule.
122      * See: https://developer.android.com/reference/android/os/SystemClock
123      */
124     @CheckDiscard("Should get inlined by R8.")
elapsedRealtimeNanos()125     public static long elapsedRealtimeNanos() {
126         if (sFakeClock != null) {
127             return sFakeClock.elapsedRealtimeNanos();
128         }
129         return SystemClock.elapsedRealtimeNanos();
130     }
131 
132     /**
133      * Wrapper for SystemClock.elapsedRealtimeMillis() (uptime including deep sleep).
134      * Can be faked in tests using FakeTimeTestRule.
135      * See: https://developer.android.com/reference/android/os/SystemClock
136      */
137     @CheckDiscard("Should get inlined by R8.")
elapsedRealtimeMillis()138     public static long elapsedRealtimeMillis() {
139         if (sFakeClock != null) {
140             return sFakeClock.elapsedRealtimeNanos() / NANOSECONDS_PER_MILLISECOND;
141         }
142         return SystemClock.elapsedRealtime();
143     }
144 
145     /**
146      * Wrapper for SystemClock.currentThreadTimeMillis() (excludes blocking time).
147      * Can be faked in tests using FakeTimeTestRule.
148      * See: https://developer.android.com/reference/android/os/SystemClock
149      */
150     @CheckDiscard("Should get inlined by R8.")
currentThreadTimeMillis()151     public static long currentThreadTimeMillis() {
152         if (sFakeClock != null) {
153             return sFakeClock.currentThreadTimeMillis();
154         }
155         return SystemClock.currentThreadTimeMillis();
156     }
157 }
158