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