summaryrefslogtreecommitdiff
path: root/core/java/android/os/SystemClock.java
diff options
context:
space:
mode:
authorChad Brubaker <cbrubaker@google.com>2019-03-15 14:13:59 -0700
committerChad Brubaker <cbrubaker@google.com>2019-03-20 16:10:08 -0700
commitf113333b98385fcea5a7f5e596d2cd34ada05f1d (patch)
treeed420778b0802cb8f37cd06a1c3a07cc7496ec4a /core/java/android/os/SystemClock.java
parent72aa96ffb26fa264083a94e96828468225f1b6a0 (diff)
Add location backed system clock
This provides a permissionless way to use the location (e.g. GNSS) provided time data for more accurate time keeping. Test: atest LocationManagerTest#testGnssProvidedClock Bug: 123530510 Change-Id: Ifbc45997868040abbb3e1399a8649911afb0af05
Diffstat (limited to 'core/java/android/os/SystemClock.java')
-rw-r--r--core/java/android/os/SystemClock.java31
1 files changed, 31 insertions, 0 deletions
diff --git a/core/java/android/os/SystemClock.java b/core/java/android/os/SystemClock.java
index b254166303bc..a1432e602d75 100644
--- a/core/java/android/os/SystemClock.java
+++ b/core/java/android/os/SystemClock.java
@@ -19,6 +19,8 @@ package android.os;
import android.annotation.NonNull;
import android.app.IAlarmManager;
import android.content.Context;
+import android.location.ILocationManager;
+import android.location.LocationTime;
import android.util.Slog;
import dalvik.annotation.optimization.CriticalNative;
@@ -313,4 +315,33 @@ public final class SystemClock {
}
};
}
+
+ /**
+ * Returns a {@link Clock} that starts at January 1, 1970 00:00:00.0 UTC,
+ * synchronized using the device's location provider.
+ *
+ * @throws DateTimeException when the location provider has not had a location fix since boot.
+ */
+ public static @NonNull Clock currentGnssTimeClock() {
+ return new SimpleClock(ZoneOffset.UTC) {
+ private final ILocationManager mMgr = ILocationManager.Stub
+ .asInterface(ServiceManager.getService(Context.LOCATION_SERVICE));
+ @Override
+ public long millis() {
+ LocationTime time;
+ try {
+ time = mMgr.getGnssTimeMillis();
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ return 0;
+ }
+ if (time == null) {
+ throw new DateTimeException("Gnss based time is not available.");
+ }
+ long currentNanos = elapsedRealtimeNanos();
+ long deltaMs = (currentNanos - time.getElapsedRealtimeNanos()) / 1000000L;
+ return time.getTime() + deltaMs;
+ }
+ };
+ }
}