• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.os;
18 
19 import android.annotation.NonNull;
20 import android.app.IAlarmManager;
21 import android.compat.annotation.UnsupportedAppUsage;
22 import android.content.Context;
23 import android.location.ILocationManager;
24 import android.location.LocationTime;
25 import android.util.Slog;
26 
27 import dalvik.annotation.optimization.CriticalNative;
28 
29 import java.time.Clock;
30 import java.time.DateTimeException;
31 import java.time.ZoneOffset;
32 
33 /**
34  * Core timekeeping facilities.
35  *
36  * <p> Three different clocks are available, and they should not be confused:
37  *
38  * <ul>
39  *     <li> <p> {@link System#currentTimeMillis System.currentTimeMillis()}
40  *     is the standard "wall" clock (time and date) expressing milliseconds
41  *     since the epoch.  The wall clock can be set by the user or the phone
42  *     network (see {@link #setCurrentTimeMillis}), so the time may jump
43  *     backwards or forwards unpredictably.  This clock should only be used
44  *     when correspondence with real-world dates and times is important, such
45  *     as in a calendar or alarm clock application.  Interval or elapsed
46  *     time measurements should use a different clock.  If you are using
47  *     System.currentTimeMillis(), consider listening to the
48  *     {@link android.content.Intent#ACTION_TIME_TICK ACTION_TIME_TICK},
49  *     {@link android.content.Intent#ACTION_TIME_CHANGED ACTION_TIME_CHANGED}
50  *     and {@link android.content.Intent#ACTION_TIMEZONE_CHANGED
51  *     ACTION_TIMEZONE_CHANGED} {@link android.content.Intent Intent}
52  *     broadcasts to find out when the time changes.
53  *
54  *     <li> <p> {@link #uptimeMillis} is counted in milliseconds since the
55  *     system was booted.  This clock stops when the system enters deep
56  *     sleep (CPU off, display dark, device waiting for external input),
57  *     but is not affected by clock scaling, idle, or other power saving
58  *     mechanisms.  This is the basis for most interval timing
59  *     such as {@link Thread#sleep(long) Thread.sleep(millls)},
60  *     {@link Object#wait(long) Object.wait(millis)}, and
61  *     {@link System#nanoTime System.nanoTime()}.  This clock is guaranteed
62  *     to be monotonic, and is suitable for interval timing when the
63  *     interval does not span device sleep.  Most methods that accept a
64  *     timestamp value currently expect the {@link #uptimeMillis} clock.
65  *
66  *     <li> <p> {@link #elapsedRealtime} and {@link #elapsedRealtimeNanos}
67  *     return the time since the system was booted, and include deep sleep.
68  *     This clock is guaranteed to be monotonic, and continues to tick even
69  *     when the CPU is in power saving modes, so is the recommend basis
70  *     for general purpose interval timing.
71  *
72  * </ul>
73  *
74  * There are several mechanisms for controlling the timing of events:
75  *
76  * <ul>
77  *     <li> <p> Standard functions like {@link Thread#sleep(long)
78  *     Thread.sleep(millis)} and {@link Object#wait(long) Object.wait(millis)}
79  *     are always available.  These functions use the {@link #uptimeMillis}
80  *     clock; if the device enters sleep, the remainder of the time will be
81  *     postponed until the device wakes up.  These synchronous functions may
82  *     be interrupted with {@link Thread#interrupt Thread.interrupt()}, and
83  *     you must handle {@link InterruptedException}.
84  *
85  *     <li> <p> {@link #sleep SystemClock.sleep(millis)} is a utility function
86  *     very similar to {@link Thread#sleep(long) Thread.sleep(millis)}, but it
87  *     ignores {@link InterruptedException}.  Use this function for delays if
88  *     you do not use {@link Thread#interrupt Thread.interrupt()}, as it will
89  *     preserve the interrupted state of the thread.
90  *
91  *     <li> <p> The {@link android.os.Handler} class can schedule asynchronous
92  *     callbacks at an absolute or relative time.  Handler objects also use the
93  *     {@link #uptimeMillis} clock, and require an {@link android.os.Looper
94  *     event loop} (normally present in any GUI application).
95  *
96  *     <li> <p> The {@link android.app.AlarmManager} can trigger one-time or
97  *     recurring events which occur even when the device is in deep sleep
98  *     or your application is not running.  Events may be scheduled with your
99  *     choice of {@link java.lang.System#currentTimeMillis} (RTC) or
100  *     {@link #elapsedRealtime} (ELAPSED_REALTIME), and cause an
101  *     {@link android.content.Intent} broadcast when they occur.
102  * </ul>
103  */
104 public final class SystemClock {
105     private static final String TAG = "SystemClock";
106 
107     private static volatile IAlarmManager sIAlarmManager;
108 
109     /**
110      * This class is uninstantiable.
111      */
112     @UnsupportedAppUsage
SystemClock()113     private SystemClock() {
114         // This space intentionally left blank.
115     }
116 
117     /**
118      * Waits a given number of milliseconds (of uptimeMillis) before returning.
119      * Similar to {@link java.lang.Thread#sleep(long)}, but does not throw
120      * {@link InterruptedException}; {@link Thread#interrupt()} events are
121      * deferred until the next interruptible operation.  Does not return until
122      * at least the specified number of milliseconds has elapsed.
123      *
124      * @param ms to sleep before returning, in milliseconds of uptime.
125      */
sleep(long ms)126     public static void sleep(long ms)
127     {
128         long start = uptimeMillis();
129         long duration = ms;
130         boolean interrupted = false;
131         do {
132             try {
133                 Thread.sleep(duration);
134             }
135             catch (InterruptedException e) {
136                 interrupted = true;
137             }
138             duration = start + ms - uptimeMillis();
139         } while (duration > 0);
140 
141         if (interrupted) {
142             // Important: we don't want to quietly eat an interrupt() event,
143             // so we make sure to re-interrupt the thread so that the next
144             // call to Thread.sleep() or Object.wait() will be interrupted.
145             Thread.currentThread().interrupt();
146         }
147     }
148 
149     /**
150      * Sets the current wall time, in milliseconds.  Requires the calling
151      * process to have appropriate permissions.
152      *
153      * @return if the clock was successfully set to the specified time.
154      */
setCurrentTimeMillis(long millis)155     public static boolean setCurrentTimeMillis(long millis) {
156         final IAlarmManager mgr = getIAlarmManager();
157         if (mgr == null) {
158             Slog.e(TAG, "Unable to set RTC: mgr == null");
159             return false;
160         }
161 
162         try {
163             return mgr.setTime(millis);
164         } catch (RemoteException e) {
165             Slog.e(TAG, "Unable to set RTC", e);
166         } catch (SecurityException e) {
167             Slog.e(TAG, "Unable to set RTC", e);
168         }
169 
170         return false;
171     }
172 
173     /**
174      * Returns milliseconds since boot, not counting time spent in deep sleep.
175      *
176      * @return milliseconds of non-sleep uptime since boot.
177      */
178     @CriticalNative
uptimeMillis()179     native public static long uptimeMillis();
180 
181     /**
182      * Returns nanoseconds since boot, not counting time spent in deep sleep.
183      *
184      * @return nanoseconds of non-sleep uptime since boot.
185      * @hide
186      */
187     @CriticalNative
uptimeNanos()188     public static native long uptimeNanos();
189 
190     /**
191      * Return {@link Clock} that starts at system boot, not counting time spent
192      * in deep sleep.
193      *
194      * @removed
195      */
uptimeClock()196     public static @NonNull Clock uptimeClock() {
197         return new SimpleClock(ZoneOffset.UTC) {
198             @Override
199             public long millis() {
200                 return SystemClock.uptimeMillis();
201             }
202         };
203     }
204 
205     /**
206      * Returns milliseconds since boot, including time spent in sleep.
207      *
208      * @return elapsed milliseconds since boot.
209      */
210     @CriticalNative
211     native public static long elapsedRealtime();
212 
213     /**
214      * Return {@link Clock} that starts at system boot, including time spent in
215      * sleep.
216      *
217      * @removed
218      */
219     public static @NonNull Clock elapsedRealtimeClock() {
220         return new SimpleClock(ZoneOffset.UTC) {
221             @Override
222             public long millis() {
223                 return SystemClock.elapsedRealtime();
224             }
225         };
226     }
227 
228     /**
229      * Returns nanoseconds since boot, including time spent in sleep.
230      *
231      * @return elapsed nanoseconds since boot.
232      */
233     @CriticalNative
234     public static native long elapsedRealtimeNanos();
235 
236     /**
237      * Returns milliseconds running in the current thread.
238      *
239      * @return elapsed milliseconds in the thread
240      */
241     @CriticalNative
242     public static native long currentThreadTimeMillis();
243 
244     /**
245      * Returns microseconds running in the current thread.
246      *
247      * @return elapsed microseconds in the thread
248      *
249      * @hide
250      */
251     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
252     @CriticalNative
253     public static native long currentThreadTimeMicro();
254 
255     /**
256      * Returns current wall time in  microseconds.
257      *
258      * @return elapsed microseconds in wall time
259      *
260      * @hide
261      */
262     @UnsupportedAppUsage
263     @CriticalNative
264     public static native long currentTimeMicro();
265 
266     /**
267      * Returns milliseconds since January 1, 1970 00:00:00.0 UTC, synchronized
268      * using a remote network source outside the device.
269      * <p>
270      * While the time returned by {@link System#currentTimeMillis()} can be
271      * adjusted by the user, the time returned by this method cannot be adjusted
272      * by the user. Note that synchronization may occur using an insecure
273      * network protocol, so the returned time should not be used for security
274      * purposes.
275      * <p>
276      * This performs no blocking network operations and returns values based on
277      * a recent successful synchronization event; it will either return a valid
278      * time or throw.
279      *
280      * @throws DateTimeException when no accurate network time can be provided.
281      * @hide
282      */
283     public static long currentNetworkTimeMillis() {
284         final IAlarmManager mgr = getIAlarmManager();
285         if (mgr != null) {
286             try {
287                 return mgr.currentNetworkTimeMillis();
288             } catch (ParcelableException e) {
289                 e.maybeRethrow(DateTimeException.class);
290                 throw new RuntimeException(e);
291             } catch (RemoteException e) {
292                 throw e.rethrowFromSystemServer();
293             }
294         } else {
295             throw new RuntimeException(new DeadSystemException());
296         }
297     }
298 
299     private static IAlarmManager getIAlarmManager() {
300         if (sIAlarmManager == null) {
301             sIAlarmManager = IAlarmManager.Stub
302                     .asInterface(ServiceManager.getService(Context.ALARM_SERVICE));
303         }
304         return sIAlarmManager;
305     }
306 
307     /**
308      * Returns a {@link Clock} that starts at January 1, 1970 00:00:00.0 UTC,
309      * synchronized using a remote network source outside the device.
310      * <p>
311      * While the time returned by {@link System#currentTimeMillis()} can be
312      * adjusted by the user, the time returned by this method cannot be adjusted
313      * by the user. Note that synchronization may occur using an insecure
314      * network protocol, so the returned time should not be used for security
315      * purposes.
316      * <p>
317      * This performs no blocking network operations and returns values based on
318      * a recent successful synchronization event; it will either return a valid
319      * time or throw.
320      *
321      * @throws DateTimeException when no accurate network time can be provided.
322      */
323     public static @NonNull Clock currentNetworkTimeClock() {
324         return new SimpleClock(ZoneOffset.UTC) {
325             @Override
326             public long millis() {
327                 return SystemClock.currentNetworkTimeMillis();
328             }
329         };
330     }
331 
332     /**
333      * Returns a {@link Clock} that starts at January 1, 1970 00:00:00.0 UTC,
334      * synchronized using the device's location provider.
335      *
336      * @throws DateTimeException when the location provider has not had a location fix since boot.
337      */
338     public static @NonNull Clock currentGnssTimeClock() {
339         return new SimpleClock(ZoneOffset.UTC) {
340             private final ILocationManager mMgr = ILocationManager.Stub
341                     .asInterface(ServiceManager.getService(Context.LOCATION_SERVICE));
342             @Override
343             public long millis() {
344                 LocationTime time;
345                 try {
346                     time = mMgr.getGnssTimeMillis();
347                 } catch (RemoteException e) {
348                     throw e.rethrowFromSystemServer();
349                 }
350                 if (time == null) {
351                     throw new DateTimeException("Gnss based time is not available.");
352                 }
353                 long currentNanos = elapsedRealtimeNanos();
354                 long deltaMs = (currentNanos - time.getElapsedRealtimeNanos()) / 1000000L;
355                 return time.getTime() + deltaMs;
356             }
357         };
358     }
359 }
360