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