• 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.FlaggedApi;
20 import android.annotation.NonNull;
21 import android.app.IAlarmManager;
22 import android.app.time.UnixEpochTime;
23 import android.app.timedetector.ITimeDetectorService;
24 import android.compat.annotation.UnsupportedAppUsage;
25 import android.content.Context;
26 import android.location.ILocationManager;
27 import android.location.LocationTime;
28 import android.text.format.DateUtils;
29 import android.util.Slog;
30 
31 import com.android.internal.os.ApplicationSharedMemory;
32 
33 import dalvik.annotation.optimization.CriticalNative;
34 
35 import java.time.Clock;
36 import java.time.DateTimeException;
37 import java.time.ZoneOffset;
38 
39 /**
40  * Core timekeeping facilities.
41  *
42  * <p> Three different clocks are available, and they should not be confused:
43  *
44  * <ul>
45  *     <li> <p> {@link System#currentTimeMillis System.currentTimeMillis()}
46  *     is the standard "wall" clock (time and date) expressing milliseconds
47  *     since the epoch.  The wall clock can be set by the user or the phone
48  *     network (see {@link #setCurrentTimeMillis}), so the time may jump
49  *     backwards or forwards unpredictably.  This clock should only be used
50  *     when correspondence with real-world dates and times is important, such
51  *     as in a calendar or alarm clock application.  Interval or elapsed
52  *     time measurements should use a different clock.  If you are using
53  *     System.currentTimeMillis(), consider listening to the
54  *     {@link android.content.Intent#ACTION_TIME_TICK ACTION_TIME_TICK},
55  *     {@link android.content.Intent#ACTION_TIME_CHANGED ACTION_TIME_CHANGED}
56  *     and {@link android.content.Intent#ACTION_TIMEZONE_CHANGED
57  *     ACTION_TIMEZONE_CHANGED} {@link android.content.Intent Intent}
58  *     broadcasts to find out when the time changes.
59  *
60  *     <li> <p> {@link #uptimeMillis} is counted in milliseconds since the
61  *     system was booted.  This clock stops when the system enters deep
62  *     sleep (CPU off, display dark, device waiting for external input),
63  *     but is not affected by clock scaling, idle, or other power saving
64  *     mechanisms.  This is the basis for most interval timing
65  *     such as {@link Thread#sleep(long) Thread.sleep(millis)},
66  *     {@link Object#wait(long) Object.wait(millis)}, and
67  *     {@link System#nanoTime System.nanoTime()}.  This clock is guaranteed
68  *     to be monotonic, and is suitable for interval timing when the
69  *     interval does not span device sleep.  Most methods that accept a
70  *     timestamp value currently expect the {@link #uptimeMillis} clock.
71  *
72  *     <li> <p> {@link #elapsedRealtime} and {@link #elapsedRealtimeNanos}
73  *     return the time since the system was booted, and include deep sleep.
74  *     This clock is guaranteed to be monotonic, and continues to tick even
75  *     when the CPU is in power saving modes, so is the recommend basis
76  *     for general purpose interval timing.
77  *
78  * </ul>
79  *
80  * There are several mechanisms for controlling the timing of events:
81  *
82  * <ul>
83  *     <li> <p> Standard functions like {@link Thread#sleep(long)
84  *     Thread.sleep(millis)} and {@link Object#wait(long) Object.wait(millis)}
85  *     are always available.  These functions use the {@link #uptimeMillis}
86  *     clock; if the device enters sleep, the remainder of the time will be
87  *     postponed until the device wakes up.  These synchronous functions may
88  *     be interrupted with {@link Thread#interrupt Thread.interrupt()}, and
89  *     you must handle {@link InterruptedException}.
90  *
91  *     <li> <p> {@link #sleep SystemClock.sleep(millis)} is a utility function
92  *     very similar to {@link Thread#sleep(long) Thread.sleep(millis)}, but it
93  *     ignores {@link InterruptedException}.  Use this function for delays if
94  *     you do not use {@link Thread#interrupt Thread.interrupt()}, as it will
95  *     preserve the interrupted state of the thread.
96  *
97  *     <li> <p> The {@link android.os.Handler} class can schedule asynchronous
98  *     callbacks at an absolute or relative time.  Handler objects also use the
99  *     {@link #uptimeMillis} clock, and require an {@link android.os.Looper
100  *     event loop} (normally present in any GUI application).
101  *
102  *     <li> <p> The {@link android.app.AlarmManager} can trigger one-time or
103  *     recurring events which occur even when the device is in deep sleep
104  *     or your application is not running.  Events may be scheduled with your
105  *     choice of {@link java.lang.System#currentTimeMillis} (RTC) or
106  *     {@link #elapsedRealtime} (ELAPSED_REALTIME), and cause an
107  *     {@link android.content.Intent} broadcast when they occur.
108  * </ul>
109  */
110 public final class SystemClock {
111     private static final String TAG = "SystemClock";
112 
113     private static volatile IAlarmManager sIAlarmManager;
114     private static volatile ITimeDetectorService sITimeDetectorService;
115 
116     /**
117      * Since {@code nanoTime()} is arbitrary, anchor our Ravenwood clocks against it.
118      */
119     private static final long sAnchorNanoTime$ravenwood = System.nanoTime();
120 
121     /**
122      * This class is uninstantiable.
123      */
124     @UnsupportedAppUsage
SystemClock()125     private SystemClock() {
126         // This space intentionally left blank.
127     }
128 
129     /**
130      * Waits a given number of milliseconds (of uptimeMillis) before returning.
131      * Similar to {@link java.lang.Thread#sleep(long)}, but does not throw
132      * {@link InterruptedException}; {@link Thread#interrupt()} events are
133      * deferred until the next interruptible operation.  Does not return until
134      * at least the specified number of milliseconds has elapsed.
135      *
136      * @param ms to sleep before returning, in milliseconds of uptime.
137      */
138     @android.ravenwood.annotation.RavenwoodKeep
sleep(long ms)139     public static void sleep(long ms)
140     {
141         long start = uptimeMillis();
142         long duration = ms;
143         boolean interrupted = false;
144         do {
145             try {
146                 Thread.sleep(duration);
147             }
148             catch (InterruptedException e) {
149                 interrupted = true;
150             }
151             duration = start + ms - uptimeMillis();
152         } while (duration > 0);
153 
154         if (interrupted) {
155             // Important: we don't want to quietly eat an interrupt() event,
156             // so we make sure to re-interrupt the thread so that the next
157             // call to Thread.sleep() or Object.wait() will be interrupted.
158             Thread.currentThread().interrupt();
159         }
160     }
161 
162     /**
163      * Sets the current wall time, in milliseconds.  Requires the calling
164      * process to have appropriate permissions.
165      *
166      * @return if the clock was successfully set to the specified time.
167      */
setCurrentTimeMillis(long millis)168     public static boolean setCurrentTimeMillis(long millis) {
169         final IAlarmManager mgr = getIAlarmManager();
170         if (mgr == null) {
171             Slog.e(TAG, "Unable to set RTC: mgr == null");
172             return false;
173         }
174 
175         try {
176             return mgr.setTime(millis);
177         } catch (RemoteException e) {
178             Slog.e(TAG, "Unable to set RTC", e);
179         } catch (SecurityException e) {
180             Slog.e(TAG, "Unable to set RTC", e);
181         }
182 
183         return false;
184     }
185 
getIAlarmManager()186     private static IAlarmManager getIAlarmManager() {
187         if (sIAlarmManager == null) {
188             sIAlarmManager = IAlarmManager.Stub
189                     .asInterface(ServiceManager.getService(Context.ALARM_SERVICE));
190         }
191         return sIAlarmManager;
192     }
193 
getITimeDetectorService()194     private static ITimeDetectorService getITimeDetectorService() {
195         if (sITimeDetectorService == null) {
196             sITimeDetectorService = ITimeDetectorService.Stub
197                     .asInterface(ServiceManager.getService(Context.TIME_DETECTOR_SERVICE));
198         }
199         return sITimeDetectorService;
200     }
201 
202     /**
203      * Returns milliseconds since boot, not counting time spent in deep sleep.
204      *
205      * @return milliseconds of non-sleep uptime since boot.
206      */
207     @CriticalNative
208     @android.ravenwood.annotation.RavenwoodReplace
uptimeMillis()209     native public static long uptimeMillis();
210 
211     /** @hide */
uptimeMillis$ravenwood()212     public static long uptimeMillis$ravenwood() {
213         return uptimeNanos() / 1_000_000;
214     }
215 
216     /**
217      * Returns nanoseconds since boot, not counting time spent in deep sleep.
218      *
219      * @return nanoseconds of non-sleep uptime since boot.
220      */
221     @FlaggedApi(Flags.FLAG_ADPF_GPU_REPORT_ACTUAL_WORK_DURATION)
222     @CriticalNative
223     @android.ravenwood.annotation.RavenwoodReplace
uptimeNanos()224     public static native long uptimeNanos();
225 
226     /** @hide */
uptimeNanos$ravenwood()227     public static long uptimeNanos$ravenwood() {
228         return System.nanoTime() - sAnchorNanoTime$ravenwood;
229     }
230 
231     /**
232      * Return {@link Clock} that starts at system boot, not counting time spent
233      * in deep sleep.
234      *
235      * @removed
236      */
uptimeClock()237     public static @NonNull Clock uptimeClock() {
238         return new SimpleClock(ZoneOffset.UTC) {
239             @Override
240             public long millis() {
241                 return SystemClock.uptimeMillis();
242             }
243         };
244     }
245 
246     /**
247      * Returns milliseconds since boot, including time spent in sleep.
248      *
249      * @return elapsed milliseconds since boot.
250      */
251     @CriticalNative
252     @android.ravenwood.annotation.RavenwoodReplace
253     native public static long elapsedRealtime();
254 
255     /** @hide */
256     public static long elapsedRealtime$ravenwood() {
257         return elapsedRealtimeNanos() / 1_000_000;
258     }
259 
260     /**
261      * Return {@link Clock} that starts at system boot, including time spent in
262      * sleep.
263      *
264      * @removed
265      */
266     public static @NonNull Clock elapsedRealtimeClock() {
267         return new SimpleClock(ZoneOffset.UTC) {
268             @Override
269             public long millis() {
270                 return SystemClock.elapsedRealtime();
271             }
272         };
273     }
274 
275     /**
276      * Returns nanoseconds since boot, including time spent in sleep.
277      *
278      * @return elapsed nanoseconds since boot.
279      */
280     @CriticalNative
281     @android.ravenwood.annotation.RavenwoodReplace
282     public static native long elapsedRealtimeNanos();
283 
284     /** @hide */
285     public static long elapsedRealtimeNanos$ravenwood() {
286         // Elapsed realtime is uptime plus an hour that we've been "asleep"
287         return uptimeNanos() + (DateUtils.HOUR_IN_MILLIS * 1_000_000);
288     }
289 
290     /**
291      * Returns milliseconds running in the current thread.
292      *
293      * @return elapsed milliseconds in the thread
294      */
295     @CriticalNative
296     public static native long currentThreadTimeMillis();
297 
298     /**
299      * Returns microseconds running in the current thread.
300      *
301      * @return elapsed microseconds in the thread
302      *
303      * @hide
304      */
305     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
306     @CriticalNative
307     public static native long currentThreadTimeMicro();
308 
309     /**
310      * Returns current wall time in  microseconds.
311      *
312      * @return elapsed microseconds in wall time
313      *
314      * @hide
315      */
316     @UnsupportedAppUsage
317     @CriticalNative
318     @android.ravenwood.annotation.RavenwoodReplace
319     public static native long currentTimeMicro();
320 
321     /** @hide */
322     public static long currentTimeMicro$ravenwood() {
323         // Ravenwood booted in Jan 2023, and has been in deep sleep for one week
324         return System.nanoTime() / 1000L;
325     }
326 
327     /**
328      * Returns milliseconds since January 1, 1970 00:00:00.0 UTC, synchronized using a remote
329      * network source outside the device.
330      *
331      * <p>While the time returned by {@link System#currentTimeMillis()} can be adjusted by the user,
332      * the time returned by this method cannot be adjusted by the user.
333      *
334      * <p>This performs no blocking network operations and returns values based on a recent
335      * successful synchronization event; it will either return a valid time or throw.
336      *
337      * <p>Note that synchronization may occur using an insecure network protocol, so the returned
338      * time should not be used for security purposes. The device may resynchronize with the same or
339      * different network source at any time. Due to network delays, variations between servers, or
340      * local (client side) clock drift, the accuracy of the returned times cannot be guaranteed. In
341      * extreme cases, consecutive calls to {@link #currentNetworkTimeMillis()} could return times
342      * that are out of order.
343      *
344      * @throws DateTimeException when no network time can be provided.
345      * @hide
346      */
347     public static long currentNetworkTimeMillis() {
348         if (com.android.internal.os.Flags.applicationSharedMemoryEnabled()
349                 && Flags.networkTimeUsesSharedMemory()) {
350             final long latestNetworkTimeUnixEpochMillisAtZeroElapsedRealtimeMillis =
351                     ApplicationSharedMemory.getInstance()
352                             .getLatestNetworkTimeUnixEpochMillisAtZeroElapsedRealtimeMillis();
353             return latestNetworkTimeUnixEpochMillisAtZeroElapsedRealtimeMillis + elapsedRealtime();
354         } else {
355             ITimeDetectorService timeDetectorService = getITimeDetectorService();
356             if (timeDetectorService == null) {
357                 throw new RuntimeException(new DeadSystemException());
358             }
359 
360             UnixEpochTime time;
361             try {
362                 time = timeDetectorService.latestNetworkTime();
363             } catch (ParcelableException e) {
364                 e.maybeRethrow(DateTimeException.class);
365                 throw new RuntimeException(e);
366             } catch (RemoteException e) {
367                 throw e.rethrowFromSystemServer();
368             }
369             if (time == null) {
370                 // This is not expected.
371                 throw new DateTimeException("Network based time is not available.");
372             }
373 
374             long currentMillis = elapsedRealtime();
375             long deltaMs = currentMillis - time.getElapsedRealtimeMillis();
376             return time.getUnixEpochTimeMillis() + deltaMs;
377         }
378     }
379 
380     /**
381      * Returns a {@link Clock} that starts at January 1, 1970 00:00:00.0 UTC, synchronized using a
382      * remote network source outside the device.
383      *
384      * <p>While the time returned by {@link System#currentTimeMillis()} can be adjusted by the user,
385      * the time returned by this method cannot be adjusted by the user.
386      *
387      * <p>This performs no blocking network operations and returns values based on a recent
388      * successful synchronization event; it will either return a valid time or throw.
389      *
390      * <p>Note that synchronization may occur using an insecure network protocol, so the returned
391      * time should not be used for security purposes. The device may resynchronize with the same or
392      * different network source at any time. Due to network delays, variations between servers, or
393      * local (client side) clock drift, the accuracy of the returned times cannot be guaranteed. In
394      * extreme cases, consecutive calls to {@link Clock#millis()} on the returned {@link Clock}
395      * could return times that are out of order.
396      *
397      * @throws DateTimeException when no network time can be provided.
398      */
399     public static @NonNull Clock currentNetworkTimeClock() {
400         return new SimpleClock(ZoneOffset.UTC) {
401             @Override
402             public long millis() {
403                 return SystemClock.currentNetworkTimeMillis();
404             }
405         };
406     }
407 
408     /**
409      * Returns a {@link Clock} that starts at January 1, 1970 00:00:00.0 UTC,
410      * synchronized using the device's location provider.
411      *
412      * @throws DateTimeException when the location provider has not had a location fix since boot.
413      */
414     public static @NonNull Clock currentGnssTimeClock() {
415         return new SimpleClock(ZoneOffset.UTC) {
416             private final ILocationManager mMgr = ILocationManager.Stub
417                     .asInterface(ServiceManager.getService(Context.LOCATION_SERVICE));
418             @Override
419             public long millis() {
420                 LocationTime time;
421                 try {
422                     time = mMgr.getGnssTimeMillis();
423                 } catch (RemoteException e) {
424                     throw e.rethrowFromSystemServer();
425                 }
426                 if (time == null) {
427                     throw new DateTimeException("Gnss based time is not available.");
428                 }
429                 long currentNanos = elapsedRealtimeNanos();
430                 long deltaMs = (currentNanos - time.getElapsedRealtimeNanos()) / 1000000L;
431                 return time.getUnixEpochTimeMillis() + deltaMs;
432             }
433         };
434     }
435 }
436