Add ExcessPathInfo (hardware/interfaces)

Bug: 201253590
Test: atest VtsHalGnssTargetTest
Change-Id: I68562d0332d161d31dbd494254ef404d110066dd
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl
index bb7d800..90c9e03 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl
@@ -38,5 +38,5 @@
   double latitudeDegrees;
   double longitudeDegrees;
   double altitudeMeters;
-  double azimuthDegrees;
+  double reflectingPlaneAzimuthDegrees;
 }
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl
index 53baa01..ebbe684 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl
@@ -40,11 +40,24 @@
   int svid;
   long carrierFrequencyHz;
   float probSatIsLos;
-  float excessPathLengthMeters;
-  float excessPathLengthUncertaintyMeters;
-  android.hardware.gnss.measurement_corrections.ReflectingPlane reflectingPlane;
+  float combinedExcessPathLengthMeters;
+  float combinedExcessPathLengthUncertaintyMeters;
+  float combinedAttenuationDb;
+  android.hardware.gnss.measurement_corrections.SingleSatCorrection.ExcessPathInfo[] excessPathInfos;
   const int SINGLE_SAT_CORRECTION_HAS_SAT_IS_LOS_PROBABILITY = 1;
-  const int SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH = 2;
-  const int SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH_UNC = 4;
-  const int SINGLE_SAT_CORRECTION_HAS_REFLECTING_PLANE = 8;
+  const int SINGLE_SAT_CORRECTION_HAS_COMBINED_EXCESS_PATH_LENGTH = 2;
+  const int SINGLE_SAT_CORRECTION_HAS_COMBINED_EXCESS_PATH_LENGTH_UNC = 4;
+  const int SINGLE_SAT_CORRECTION_HAS_COMBINED_ATTENUATION = 16;
+  @VintfStability
+  parcelable ExcessPathInfo {
+    int excessPathInfoFlags;
+    float excessPathLengthMeters;
+    float excessPathLengthUncertaintyMeters;
+    android.hardware.gnss.measurement_corrections.ReflectingPlane reflectingPlane;
+    float attenuationDb;
+    const int EXCESS_PATH_INFO_HAS_EXCESS_PATH_LENGTH = 1;
+    const int EXCESS_PATH_INFO_HAS_EXCESS_PATH_LENGTH_UNC = 2;
+    const int EXCESS_PATH_INFO_HAS_REFLECTING_PLANE = 4;
+    const int EXCESS_PATH_INFO_HAS_ATTENUATION = 8;
+  }
 }
diff --git a/gnss/aidl/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl b/gnss/aidl/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl
index abd29f0..8104372 100644
--- a/gnss/aidl/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl
+++ b/gnss/aidl/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl
@@ -41,5 +41,5 @@
     double altitudeMeters;
 
     /** Represents azimuth clockwise from north of the reflecting plane in degrees. */
-    double azimuthDegrees;
+    double reflectingPlaneAzimuthDegrees;
 }
diff --git a/gnss/aidl/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl b/gnss/aidl/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl
index 36320eb..56c691c 100644
--- a/gnss/aidl/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl
+++ b/gnss/aidl/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl
@@ -29,14 +29,14 @@
 @VintfStability
 parcelable SingleSatCorrection {
     /** Bit mask to indicate which values are valid in a SingleSatCorrection object. */
-    /** GnssSingleSatCorrectionFlags has valid satellite-is-line-of-sight-probability field. */
+    /** GnssSingleSatCorrectionFlags has valid probSatIsLos field. */
     const int SINGLE_SAT_CORRECTION_HAS_SAT_IS_LOS_PROBABILITY = 0x0001;
-    /** GnssSingleSatCorrectionFlags has valid Excess Path Length field. */
-    const int SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH = 0x0002;
-    /** GnssSingleSatCorrectionFlags has valid Excess Path Length Uncertainty field. */
-    const int SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH_UNC = 0x0004;
-    /** GnssSingleSatCorrectionFlags has valid Reflecting Plane field. */
-    const int SINGLE_SAT_CORRECTION_HAS_REFLECTING_PLANE = 0x0008;
+    /** GnssSingleSatCorrectionFlags has valid combinedExcessPathLengthMeters field. */
+    const int SINGLE_SAT_CORRECTION_HAS_COMBINED_EXCESS_PATH_LENGTH = 0x0002;
+    /** GnssSingleSatCorrectionFlags has valid combinedExcessPathLengthUncertaintyMeters field. */
+    const int SINGLE_SAT_CORRECTION_HAS_COMBINED_EXCESS_PATH_LENGTH_UNC = 0x0004;
+    /** GnssSingleSatCorrectionFlags has valid combinedAttenuationDb field. */
+    const int SINGLE_SAT_CORRECTION_HAS_COMBINED_ATTENUATION = 0x0010;
 
     /** Contains GnssSingleSatCorrectionFlags bits. */
     int singleSatCorrectionFlags;
@@ -67,21 +67,74 @@
     float probSatIsLos;
 
     /**
-     * Excess path length to be subtracted from pseudorange before using it in calculating location.
+     * Combined excess path length to be subtracted from pseudorange before using it in
+     * calculating location.
      *
-     * Note this value is NOT to be used to adjust the GnsseasurementCallback outputs.
+     * The value is computed by correlating the individual paths and picking the delay at the
+     * highest peak.
+     *
+     * Note this value is NOT to be used to adjust the GnssMeasurementCallback outputs.
      */
-    float excessPathLengthMeters;
-
-    /** Error estimate (1-sigma) for the Excess path length estimate */
-    float excessPathLengthUncertaintyMeters;
+    float combinedExcessPathLengthMeters;
 
     /**
-     * Defines the reflecting plane characteristics such as location and azimuth
+     * Error estimate (1-sigma) for the Excess path length estimate.
      *
-     * The value is only valid if HAS_REFLECTING_PLANE flag is set. An invalid reflecting plane
-     * means either reflection planes serving is not supported or the satellite signal has gone
-     * through multiple reflections.
+     * The value is computed by combining the individual excessPathLengthUncertaintyMeters values
+     * into a single value for this satellite.
      */
-    ReflectingPlane reflectingPlane;
+    float combinedExcessPathLengthUncertaintyMeters;
+
+    /**
+     * Combined expected reduction of signal strength for this satellite in non-negative dB.
+     */
+    float combinedAttenuationDb;
+
+    /**
+     * A struct for the info of an excess path caused by reflection.
+     */
+    @VintfStability
+    parcelable ExcessPathInfo {
+        /** ExcessPathInfo has valid Excess Path Length field. */
+        const int EXCESS_PATH_INFO_HAS_EXCESS_PATH_LENGTH = 0x0001;
+        /** ExcessPathInfo has valid Excess Path Length Uncertainty field. */
+        const int EXCESS_PATH_INFO_HAS_EXCESS_PATH_LENGTH_UNC = 0x0002;
+        /** ExcessPathInfo has valid Reflecting Plane field. */
+        const int EXCESS_PATH_INFO_HAS_REFLECTING_PLANE = 0x0004;
+        /** ExcessPathInfo has valid Attenuation field. */
+        const int EXCESS_PATH_INFO_HAS_ATTENUATION = 0x0008;
+
+        /** Contains flag bits to indicate which fields exist in the ExcessPathInfo object. */
+        int excessPathInfoFlags;
+
+        /**
+         * Excess path length to be subtracted from pseudorange before using it in calculating
+         * location.
+         *
+         * Note this value is NOT to be used to adjust the GnssMeasurementCallback outputs.
+         */
+        float excessPathLengthMeters;
+
+        /** Error estimate (1-sigma) for the Excess path length estimate. */
+        float excessPathLengthUncertaintyMeters;
+
+        /**
+         * Defines the reflecting plane characteristics such as location and azimuth.
+         *
+         * The value is only valid if HAS_REFLECTING_PLANE flag is set. An invalid reflecting plane
+         * means either reflection planes serving is not supported or the satellite signal has gone
+         * through multiple reflections.
+         */
+        ReflectingPlane reflectingPlane;
+
+        /**
+         * The expected reduction of signal strength of this path in non-negative dB.
+         */
+        float attenuationDb;
+    }
+
+    /**
+     * A list of excess path info.
+     */
+    ExcessPathInfo[] excessPathInfos;
 }
diff --git a/gnss/aidl/default/MeasurementCorrectionsInterface.cpp b/gnss/aidl/default/MeasurementCorrectionsInterface.cpp
index 0f1851c..66270c8 100644
--- a/gnss/aidl/default/MeasurementCorrectionsInterface.cpp
+++ b/gnss/aidl/default/MeasurementCorrectionsInterface.cpp
@@ -37,16 +37,26 @@
           static_cast<int>(corrections.satCorrections.size()));
     for (auto singleSatCorrection : corrections.satCorrections) {
         ALOGD("singleSatCorrection = flags: %d, constellation: %d, svid: %d"
-              ", cfHz: %" PRId64 ", probLos: %f, epl: %f, eplUnc: %f",
+              ", cfHz: %" PRId64
+              ", probLos: %f, combinedEpl: %f, combinedEplUnc: %f, combinedAttenuation: %f"
+              ", excessPathInfos.size: %d",
               singleSatCorrection.singleSatCorrectionFlags, singleSatCorrection.constellation,
               singleSatCorrection.svid, singleSatCorrection.carrierFrequencyHz,
-              singleSatCorrection.probSatIsLos, singleSatCorrection.excessPathLengthMeters,
-              singleSatCorrection.excessPathLengthUncertaintyMeters);
-        ALOGD("reflecting plane = lat: %f, lng: %f, alt: %f, azm: %f",
-              singleSatCorrection.reflectingPlane.latitudeDegrees,
-              singleSatCorrection.reflectingPlane.longitudeDegrees,
-              singleSatCorrection.reflectingPlane.altitudeMeters,
-              singleSatCorrection.reflectingPlane.azimuthDegrees);
+              singleSatCorrection.probSatIsLos, singleSatCorrection.combinedExcessPathLengthMeters,
+              singleSatCorrection.combinedExcessPathLengthUncertaintyMeters,
+              singleSatCorrection.combinedAttenuationDb,
+              static_cast<int>(singleSatCorrection.excessPathInfos.size()));
+
+        for (auto excessPathInfo : singleSatCorrection.excessPathInfos) {
+            ALOGD("excessPathInfo = epl: %f, eplUnc: %f, attenuation: %f",
+                  excessPathInfo.excessPathLengthMeters,
+                  excessPathInfo.excessPathLengthUncertaintyMeters, excessPathInfo.attenuationDb);
+            ALOGD("reflecting plane = lat: %f, lng: %f, alt: %f, azm: %f",
+                  excessPathInfo.reflectingPlane.latitudeDegrees,
+                  excessPathInfo.reflectingPlane.longitudeDegrees,
+                  excessPathInfo.reflectingPlane.altitudeMeters,
+                  excessPathInfo.reflectingPlane.reflectingPlaneAzimuthDegrees);
+        }
     }
     return ndk::ScopedAStatus::ok();
 }
diff --git a/gnss/common/utils/vts/Utils.cpp b/gnss/common/utils/vts/Utils.cpp
index 4c725a8..69e2b34 100644
--- a/gnss/common/utils/vts/Utils.cpp
+++ b/gnss/common/utils/vts/Utils.cpp
@@ -38,6 +38,7 @@
 using ReflectingPlaneAidl = android::hardware::gnss::measurement_corrections::ReflectingPlane;
 using SingleSatCorrectionAidl =
         android::hardware::gnss::measurement_corrections::SingleSatCorrection;
+using ExcessPathInfo = SingleSatCorrectionAidl::ExcessPathInfo;
 
 template <>
 int64_t Utils::getLocationTimestampMillis(const android::hardware::gnss::GnssLocation& location) {
@@ -170,38 +171,68 @@
     return mockCorrections_1_1;
 }
 
+namespace {
+const ExcessPathInfo createExcessPathInfo(float excessPathLengthMeters,
+                                          float excessPathLengthUncertaintyMeters,
+                                          const ReflectingPlaneAidl* reflectingPlane,
+                                          float attenuationDb) {
+    ExcessPathInfo excessPathInfo;
+    excessPathInfo.excessPathInfoFlags =
+            ExcessPathInfo::EXCESS_PATH_INFO_HAS_EXCESS_PATH_LENGTH |
+            ExcessPathInfo::EXCESS_PATH_INFO_HAS_EXCESS_PATH_LENGTH_UNC |
+            ExcessPathInfo::EXCESS_PATH_INFO_HAS_ATTENUATION |
+            (reflectingPlane == nullptr ? 0
+                                        : ExcessPathInfo::EXCESS_PATH_INFO_HAS_REFLECTING_PLANE);
+    excessPathInfo.excessPathLengthMeters = excessPathLengthMeters;
+    excessPathInfo.excessPathLengthUncertaintyMeters = excessPathLengthUncertaintyMeters;
+    if (reflectingPlane != nullptr) {
+        excessPathInfo.reflectingPlane = *reflectingPlane;
+    }
+    excessPathInfo.attenuationDb = attenuationDb;
+    return excessPathInfo;
+}
+}  // anonymous namespace
+
 const MeasurementCorrectionsAidl Utils::getMockMeasurementCorrections_aidl() {
     ReflectingPlaneAidl reflectingPlane;
     reflectingPlane.latitudeDegrees = 37.4220039;
     reflectingPlane.longitudeDegrees = -122.0840991;
     reflectingPlane.altitudeMeters = 250.35;
-    reflectingPlane.azimuthDegrees = 203.0;
+    reflectingPlane.reflectingPlaneAzimuthDegrees = 203.0;
 
     SingleSatCorrectionAidl singleSatCorrection1;
     singleSatCorrection1.singleSatCorrectionFlags =
             SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_SAT_IS_LOS_PROBABILITY |
-            SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH |
-            SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH_UNC |
-            SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_REFLECTING_PLANE;
+            SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_COMBINED_EXCESS_PATH_LENGTH |
+            SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_COMBINED_EXCESS_PATH_LENGTH_UNC |
+            SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_COMBINED_ATTENUATION;
     singleSatCorrection1.constellation = android::hardware::gnss::GnssConstellationType::GPS;
     singleSatCorrection1.svid = 12;
     singleSatCorrection1.carrierFrequencyHz = 1.59975e+09;
     singleSatCorrection1.probSatIsLos = 0.50001;
-    singleSatCorrection1.excessPathLengthMeters = 137.4802;
-    singleSatCorrection1.excessPathLengthUncertaintyMeters = 25.5;
-    singleSatCorrection1.reflectingPlane = reflectingPlane;
+    singleSatCorrection1.combinedExcessPathLengthMeters = 203.5;
+    singleSatCorrection1.combinedExcessPathLengthUncertaintyMeters = 59.1;
+    singleSatCorrection1.combinedAttenuationDb = -4.3;
+    singleSatCorrection1.excessPathInfos.push_back(
+            createExcessPathInfo(137.4, 25.5, &reflectingPlane, -3.5));
+    singleSatCorrection1.excessPathInfos.push_back(
+            createExcessPathInfo(296.3, 87.2, &reflectingPlane, -5.1));
 
     SingleSatCorrectionAidl singleSatCorrection2;
     singleSatCorrection2.singleSatCorrectionFlags =
             SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_SAT_IS_LOS_PROBABILITY |
-            SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH |
-            SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH_UNC;
+            SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_COMBINED_EXCESS_PATH_LENGTH |
+            SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_COMBINED_EXCESS_PATH_LENGTH_UNC |
+            SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_COMBINED_ATTENUATION;
     singleSatCorrection2.constellation = GnssConstellationType::GPS;
     singleSatCorrection2.svid = 9;
     singleSatCorrection2.carrierFrequencyHz = 1.59975e+09;
     singleSatCorrection2.probSatIsLos = 0.873;
-    singleSatCorrection2.excessPathLengthMeters = 26.294;
-    singleSatCorrection2.excessPathLengthUncertaintyMeters = 10.0;
+    singleSatCorrection2.combinedExcessPathLengthMeters = 26.294;
+    singleSatCorrection2.combinedExcessPathLengthUncertaintyMeters = 10.0;
+    singleSatCorrection2.combinedAttenuationDb = -0.5;
+    singleSatCorrection2.excessPathInfos.push_back(
+            createExcessPathInfo(26.294, 10.0, nullptr, -0.5));
 
     std::vector<SingleSatCorrectionAidl> singleSatCorrections = {singleSatCorrection1,
                                                                  singleSatCorrection2};