Merge "Revert "Revert "This CL introduces new member variable on android.location.Location (see api/current.txt)."""
diff --git a/api/current.txt b/api/current.txt
index 56cf517..e16004c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -22859,6 +22859,7 @@
     method public float getBearing();
     method public float getBearingAccuracyDegrees();
     method public long getElapsedRealtimeNanos();
+    method public long getElapsedRealtimeUncertaintyNanos();
     method public android.os.Bundle getExtras();
     method public double getLatitude();
     method public double getLongitude();
@@ -22871,6 +22872,7 @@
     method public boolean hasAltitude();
     method public boolean hasBearing();
     method public boolean hasBearingAccuracy();
+    method public boolean hasElapsedRealtimeUncertaintyNanos();
     method public boolean hasSpeed();
     method public boolean hasSpeedAccuracy();
     method public boolean hasVerticalAccuracy();
@@ -22886,6 +22888,7 @@
     method public void setBearing(float);
     method public void setBearingAccuracyDegrees(float);
     method public void setElapsedRealtimeNanos(long);
+    method public void setElapsedRealtimeUncertaintyNanos(long);
     method public void setExtras(android.os.Bundle);
     method public void setLatitude(double);
     method public void setLongitude(double);
diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java
index 17e2509..ed74333 100644
--- a/location/java/android/location/Location.java
+++ b/location/java/android/location/Location.java
@@ -113,6 +113,10 @@
      * Bit mask for mFieldsMask indicating the presence of mBearingAccuracy.
      */
     private static final int HAS_BEARING_ACCURACY_MASK = 128;
+    /**
+     * Bit mask for mFieldsMask indicating the presence of mElapsedRealtimeUncertaintyNanos.
+     */
+    private static final int HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK = 256;
 
     // Cached data to make bearing/distance computations more efficient for the case
     // where distanceTo and bearingTo are called in sequence.  Assume this typically happens
@@ -130,6 +134,9 @@
     private long mTime = 0;
     @UnsupportedAppUsage
     private long mElapsedRealtimeNanos = 0;
+    // Estimate of the relative precision of the alignment of this SystemClock
+    // timestamp, with the reported measurements in nanoseconds (68% confidence).
+    private long mElapsedRealtimeUncertaintyNanos = 0;
     private double mLatitude = 0.0;
     private double mLongitude = 0.0;
     private double mAltitude = 0.0f;
@@ -171,6 +178,7 @@
         mProvider = l.mProvider;
         mTime = l.mTime;
         mElapsedRealtimeNanos = l.mElapsedRealtimeNanos;
+        mElapsedRealtimeUncertaintyNanos = l.mElapsedRealtimeUncertaintyNanos;
         mFieldsMask = l.mFieldsMask;
         mLatitude = l.mLatitude;
         mLongitude = l.mLongitude;
@@ -191,6 +199,7 @@
         mProvider = null;
         mTime = 0;
         mElapsedRealtimeNanos = 0;
+        mElapsedRealtimeUncertaintyNanos = 0;
         mFieldsMask = 0;
         mLatitude = 0;
         mLongitude = 0;
@@ -586,6 +595,37 @@
     }
 
     /**
+     * Get estimate of the relative precision of the alignment of the
+     * ElapsedRealtimeNanos timestamp, with the reported measurements in
+     * nanoseconds (68% confidence).
+     *
+     * @return uncertainty of elapsed real-time of fix, in nanoseconds.
+     */
+    public long getElapsedRealtimeUncertaintyNanos() {
+        return mElapsedRealtimeUncertaintyNanos;
+    }
+
+    /**
+     * Set estimate of the relative precision of the alignment of the
+     * ElapsedRealtimeNanos timestamp, with the reported measurements in
+     * nanoseconds (68% confidence).
+     *
+     * @param time uncertainty of the elapsed real-time of fix, in nanoseconds.
+     */
+    public void setElapsedRealtimeUncertaintyNanos(long time) {
+        mElapsedRealtimeUncertaintyNanos = time;
+        mFieldsMask |= HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK;
+    }
+
+    /**
+     * True if this location has a elapsed realtime accuracy.
+     */
+    public boolean hasElapsedRealtimeUncertaintyNanos() {
+        return (mFieldsMask & HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK) != 0;
+    }
+
+
+    /**
      * Get the latitude, in degrees.
      *
      * <p>All locations generated by the {@link LocationManager}
@@ -1062,6 +1102,10 @@
             s.append(" et=");
             TimeUtils.formatDuration(mElapsedRealtimeNanos / 1000000L, s);
         }
+        if (hasElapsedRealtimeUncertaintyNanos()) {
+            s.append(" etAcc=");
+            TimeUtils.formatDuration(mElapsedRealtimeUncertaintyNanos / 1000000L, s);
+        }
         if (hasAltitude()) s.append(" alt=").append(mAltitude);
         if (hasSpeed()) s.append(" vel=").append(mSpeed);
         if (hasBearing()) s.append(" bear=").append(mBearing);
@@ -1092,6 +1136,7 @@
             Location l = new Location(provider);
             l.mTime = in.readLong();
             l.mElapsedRealtimeNanos = in.readLong();
+            l.mElapsedRealtimeUncertaintyNanos = in.readLong();
             l.mFieldsMask = in.readByte();
             l.mLatitude = in.readDouble();
             l.mLongitude = in.readDouble();
@@ -1122,6 +1167,7 @@
         parcel.writeString(mProvider);
         parcel.writeLong(mTime);
         parcel.writeLong(mElapsedRealtimeNanos);
+        parcel.writeLong(mElapsedRealtimeUncertaintyNanos);
         parcel.writeByte(mFieldsMask);
         parcel.writeDouble(mLatitude);
         parcel.writeDouble(mLongitude);
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 71ec5b0..9ab9975 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -142,6 +142,7 @@
 
     // these need to match ElapsedRealtimeFlags enum in types.hal
     private static final int ELAPSED_REALTIME_HAS_TIMESTAMP_NS = 1;
+    private static final int ELAPSED_REALTIME_HAS_TIME_UNCERTAINTY_NS = 2;
 
     // IMPORTANT - the GPS_DELETE_* symbols here must match GnssAidingData enum in IGnss.hal
     private static final int GPS_DELETE_EPHEMERIS = 0x0001;
@@ -768,15 +769,18 @@
         float bearingAccuracyDegrees = location.getBearingAccuracyDegrees();
         long timestamp = location.getTime();
 
-        int elapsedRealtimeFlags = ELAPSED_REALTIME_HAS_TIMESTAMP_NS;
+        int elapsedRealtimeFlags = ELAPSED_REALTIME_HAS_TIMESTAMP_NS
+                | (location.hasElapsedRealtimeUncertaintyNanos()
+                        ? ELAPSED_REALTIME_HAS_TIME_UNCERTAINTY_NS : 0);
         long elapsedRealtimeNanos = location.getElapsedRealtimeNanos();
+        long elapsedRealtimeUncertaintyNanos = location.getElapsedRealtimeUncertaintyNanos();
 
         native_inject_best_location(
                 gnssLocationFlags, latitudeDegrees, longitudeDegrees,
                 altitudeMeters, speedMetersPerSec, bearingDegrees,
                 horizontalAccuracyMeters, verticalAccuracyMeters,
                 speedAccuracyMetersPerSecond, bearingAccuracyDegrees, timestamp,
-                elapsedRealtimeFlags, elapsedRealtimeNanos);
+                elapsedRealtimeFlags, elapsedRealtimeNanos, elapsedRealtimeUncertaintyNanos);
     }
 
     /** Returns true if the location request is too frequent. */
@@ -2170,7 +2174,8 @@
             double altitudeMeters, float speedMetersPerSec, float bearingDegrees,
             float horizontalAccuracyMeters, float verticalAccuracyMeters,
             float speedAccuracyMetersPerSecond, float bearingAccuracyDegrees,
-            long timestamp, int elapsedRealtimeFlags, long elapsedRealtimeNanos);
+            long timestamp, int elapsedRealtimeFlags, long elapsedRealtimeNanos,
+            long elapsedRealtimeUncertaintyNanos);
 
     private native void native_inject_location(double latitude, double longitude, float accuracy);
 
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index d39f20c..298b664 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -491,6 +491,10 @@
         SET(ElapsedRealtimeNanos, location.elapsedRealtime.timestampNs);
     }
 
+    if (flags & ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS) {
+        SET(ElapsedRealtimeUncertaintyNanos, location.elapsedRealtime.timeUncertaintyNs);
+    }
+
     return object.get();
 }
 
@@ -521,7 +525,8 @@
         jdouble altitudeMeters, jfloat speedMetersPerSec, jfloat bearingDegrees,
         jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters,
         jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees,
-        jlong timestamp, jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos) {
+        jlong timestamp, jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos,
+        jlong elapsedRealtimeUncertaintyNanos) {
     GnssLocation_V2_0 location;
     location.v1_0 = createGnssLocation_V1_0(
             gnssLocationFlags, latitudeDegrees, longitudeDegrees, altitudeMeters,
@@ -531,6 +536,7 @@
 
     location.elapsedRealtime.flags = static_cast<uint16_t>(elapsedRealtimeFlags);
     location.elapsedRealtime.timestampNs = static_cast<uint64_t>(elapsedRealtimeNanos);
+    location.elapsedRealtime.timeUncertaintyNs = static_cast<uint64_t>(elapsedRealtimeUncertaintyNanos);
 
     return location;
 }
@@ -1887,7 +1893,8 @@
         jfloat bearingAccuracyDegrees,
         jlong timestamp,
         jint elapsedRealtimeFlags,
-        jlong elapsedRealtimeNanos) {
+        jlong elapsedRealtimeNanos,
+        jlong elapsedRealtimeUncertaintyNanos) {
     if (gnssHal_V2_0 != nullptr) {
         GnssLocation_V2_0 location = createGnssLocation_V2_0(
                 gnssLocationFlags,
@@ -1902,7 +1909,8 @@
                 bearingAccuracyDegrees,
                 timestamp,
                 elapsedRealtimeFlags,
-                elapsedRealtimeNanos);
+                elapsedRealtimeNanos,
+                elapsedRealtimeUncertaintyNanos);
         auto result = gnssHal_V2_0->injectBestLocation_2_0(location);
 
         if (!result.isOk() || !result) {
@@ -2813,7 +2821,7 @@
             android_location_GnssLocationProvider_read_nmea)},
     {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
             android_location_GnssLocationProvider_inject_time)},
-    {"native_inject_best_location", "(IDDDFFFFFFJIJ)V", reinterpret_cast<void *>(
+    {"native_inject_best_location", "(IDDDFFFFFFJIJJ)V", reinterpret_cast<void *>(
             android_location_GnssLocationProvider_inject_best_location)},
     {"native_inject_location", "(DDF)V", reinterpret_cast<void *>(
             android_location_GnssLocationProvider_inject_location)},