• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.robolectric.shadows;
2 
3 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
4 import static android.os.Build.VERSION_CODES.P;
5 
6 import android.os.SystemClock;
7 import java.time.DateTimeException;
8 import org.robolectric.annotation.HiddenApi;
9 import org.robolectric.annotation.Implementation;
10 import org.robolectric.annotation.Implements;
11 import org.robolectric.annotation.Resetter;
12 
13 /**
14  * Robolectric's concept of current time is base on the current time of the UI Scheduler for
15  * consistency with previous implementations. This is not ideal, since both schedulers
16  * (background and foreground), can see different values for the current time.
17  */
18 @Implements(SystemClock.class)
19 public class ShadowSystemClock {
20   private static long bootedAt = 0;
21   private static long nanoTime = 0;
22   private static final int MILLIS_PER_NANO = 1000000;
23   private static boolean networkTimeAvailable = true;
24 
now()25   static long now() {
26     if (ShadowApplication.getInstance() == null) {
27       return 0;
28     }
29     return ShadowApplication.getInstance().getForegroundThreadScheduler().getCurrentTime();
30   }
31 
32   @Implementation
sleep(long millis)33   protected static void sleep(long millis) {
34     if (ShadowApplication.getInstance() == null) {
35       return;
36     }
37 
38     nanoTime = millis * MILLIS_PER_NANO;
39     ShadowApplication.getInstance().getForegroundThreadScheduler().advanceBy(millis);
40   }
41 
42   @Implementation
setCurrentTimeMillis(long millis)43   protected static boolean setCurrentTimeMillis(long millis) {
44     if (ShadowApplication.getInstance() == null) {
45       return false;
46     }
47 
48     if (now() > millis) {
49       return false;
50     }
51     nanoTime = millis * MILLIS_PER_NANO;
52     ShadowApplication.getInstance().getForegroundThreadScheduler().advanceTo(millis);
53     return true;
54   }
55 
56   @Implementation
uptimeMillis()57   protected static long uptimeMillis() {
58     return now() - bootedAt;
59   }
60 
61   @Implementation
elapsedRealtime()62   protected static long elapsedRealtime() {
63     return uptimeMillis();
64   }
65 
66   @Implementation(minSdk = JELLY_BEAN_MR1)
elapsedRealtimeNanos()67   protected static long elapsedRealtimeNanos() {
68     return elapsedRealtime() * MILLIS_PER_NANO;
69   }
70 
71   @Implementation
currentThreadTimeMillis()72   protected static long currentThreadTimeMillis() {
73     return uptimeMillis();
74   }
75 
76   @HiddenApi
77   @Implementation
currentThreadTimeMicro()78   public static long currentThreadTimeMicro() {
79     return uptimeMillis() * 1000;
80   }
81 
82   @HiddenApi
83   @Implementation
currentTimeMicro()84   public static long currentTimeMicro() {
85     return now() * 1000;
86   }
87 
88   /**
89    * Implements {@link System#currentTimeMillis} through ShadowWrangler.
90    *
91    * @return Current time in millis.
92    */
93   @SuppressWarnings("unused")
currentTimeMillis()94   public static long currentTimeMillis() {
95     return nanoTime / MILLIS_PER_NANO;
96   }
97 
98   /**
99    * Implements {@link System#nanoTime} through ShadowWrangler.
100    *
101    * @return Current time with nanos.
102    */
103   @SuppressWarnings("unused")
nanoTime()104   public static long nanoTime() {
105     return nanoTime;
106   }
107 
setNanoTime(long nanoTime)108   public static void setNanoTime(long nanoTime) {
109     ShadowSystemClock.nanoTime = nanoTime;
110   }
111 
112   @Implementation(minSdk = P)
113   @HiddenApi
currentNetworkTimeMillis()114   protected static long currentNetworkTimeMillis() {
115     if (networkTimeAvailable) {
116       return currentTimeMillis();
117     } else {
118       throw new DateTimeException("Network time not available");
119     }
120   }
121 
122   /** Sets whether network time is available. */
setNetworkTimeAvailable(boolean available)123   public static void setNetworkTimeAvailable(boolean available) {
124     networkTimeAvailable = available;
125   }
126 
127   @Resetter
reset()128   public static void reset() {
129     networkTimeAvailable = true;
130   }
131 }
132