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