GnssStatus for GnssMeasurement-only VTS test

Update VTS test case: GnssStatus should be reported when only
measurement is registered.

Test: atest VtsHalGnssTargetTest
Bug: 274653052
Change-Id: I53c741d2cee7a4c36ad0a2744ccb8b3e917b7996
diff --git a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
index ee21011..0200625 100644
--- a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
@@ -214,9 +214,12 @@
     /**
      * Callback for the HAL to pass a vector of GnssSvInfo back to the client.
      *
-     * If GnssMeasurement is registered, the SvStatus report interval is the same as the measurement
-     * interval, i.e., the interval the measurement engine runs at. If GnssMeasurement is not
-     * registered, the SvStatus interval is the same as the location interval.
+     * If only GnssMeasurement is registered, the SvStatus reporting interval must be
+     * the same as the measurement interval, i.e., the interval the measurement
+     * engine runs at. If only location is registered, the SvStatus interval must
+     * be the same as the location interval. If both GnssMeasurement and location
+     * are registered, then the SvStatus interval is the same as the lesser interval
+     * between the two.
      *
      * @param svInfo SV status information from HAL.
      */
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index ec86d2e..f1b9cbf 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -325,6 +325,7 @@
     ALOGD("getExtensionGnssMeasurement");
     if (mGnssMeasurementInterface == nullptr) {
         mGnssMeasurementInterface = SharedRefBase::make<GnssMeasurementInterface>();
+        mGnssMeasurementInterface->setGnssInterface(static_cast<std::shared_ptr<Gnss>>(this));
     }
     *iGnssMeasurement = mGnssMeasurementInterface;
     return ScopedAStatus::ok();
diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h
index df10fc8..00540cd 100644
--- a/gnss/aidl/default/Gnss.h
+++ b/gnss/aidl/default/Gnss.h
@@ -84,13 +84,13 @@
                                     IMeasurementCorrectionsInterface>* iMeasurementCorrections)
             override;
 
+    void reportSvStatus() const;
     std::shared_ptr<GnssConfiguration> mGnssConfiguration;
     std::shared_ptr<GnssPowerIndication> mGnssPowerIndication;
     std::shared_ptr<GnssMeasurementInterface> mGnssMeasurementInterface;
 
   private:
     void reportLocation(const GnssLocation&) const;
-    void reportSvStatus() const;
     void reportSvStatus(const std::vector<IGnssCallback::GnssSvInfo>& svInfoList) const;
     std::vector<IGnssCallback::GnssSvInfo> filterBlocklistedSatellites(
             std::vector<IGnssCallback::GnssSvInfo> gnssSvInfoList) const;
diff --git a/gnss/aidl/default/GnssMeasurementInterface.cpp b/gnss/aidl/default/GnssMeasurementInterface.cpp
index 90056ce..aab9e03 100644
--- a/gnss/aidl/default/GnssMeasurementInterface.cpp
+++ b/gnss/aidl/default/GnssMeasurementInterface.cpp
@@ -20,6 +20,7 @@
 #include <aidl/android/hardware/gnss/BnGnss.h>
 #include <log/log.h>
 #include "DeviceFileReader.h"
+#include "Gnss.h"
 #include "GnssRawMeasurementParser.h"
 #include "GnssReplayUtils.h"
 #include "Utils.h"
@@ -126,6 +127,9 @@
                 auto measurement =
                         Utils::getMockMeasurement(enableCorrVecOutputs, enableFullTracking);
                 this->reportMeasurement(measurement);
+                if (!mLocationEnabled) {
+                    mGnss->reportSvStatus();
+                }
             }
             intervalMs =
                     (mLocationEnabled) ? std::min(mLocationIntervalMs, mIntervalMs) : mIntervalMs;
@@ -164,6 +168,10 @@
     mLocationEnabled = enabled;
 }
 
+void GnssMeasurementInterface::setGnssInterface(const std::shared_ptr<Gnss>& gnss) {
+    mGnss = gnss;
+}
+
 void GnssMeasurementInterface::waitForStoppingThreads() {
     for (auto& future : mFutures) {
         ALOGD("Stopping previous thread.");
diff --git a/gnss/aidl/default/GnssMeasurementInterface.h b/gnss/aidl/default/GnssMeasurementInterface.h
index d2737e5..926a4e7 100644
--- a/gnss/aidl/default/GnssMeasurementInterface.h
+++ b/gnss/aidl/default/GnssMeasurementInterface.h
@@ -25,6 +25,7 @@
 #include "Utils.h"
 
 namespace aidl::android::hardware::gnss {
+class Gnss;
 
 struct GnssMeasurementInterface : public BnGnssMeasurementInterface {
   public:
@@ -39,6 +40,7 @@
             const Options& options) override;
     void setLocationInterval(const int intervalMs);
     void setLocationEnabled(const bool enabled);
+    void setGnssInterface(const std::shared_ptr<Gnss>& gnss);
 
   private:
     void start(const bool enableCorrVecOutputs, const bool enableFullTracking);
@@ -59,6 +61,8 @@
 
     // Synchronization lock for sCallback
     mutable std::mutex mMutex;
+
+    std::shared_ptr<Gnss> mGnss;
 };
 
 }  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/vts/GnssCallbackAidl.cpp b/gnss/aidl/vts/GnssCallbackAidl.cpp
index d3be414..2e34921 100644
--- a/gnss/aidl/vts/GnssCallbackAidl.cpp
+++ b/gnss/aidl/vts/GnssCallbackAidl.cpp
@@ -18,6 +18,7 @@
 
 #include "GnssCallbackAidl.h"
 #include <log/log.h>
+#include <utils/SystemClock.h>
 
 using android::binder::Status;
 using android::hardware::gnss::GnssLocation;
@@ -53,6 +54,7 @@
 Status GnssCallbackAidl::gnssSvStatusCb(const std::vector<GnssSvInfo>& svInfoList) {
     ALOGI("gnssSvStatusCb. Size = %d", (int)svInfoList.size());
     sv_info_list_cbq_.store(svInfoList);
+    sv_info_list_timestamps_millis_cbq_.store(::android::elapsedRealtime());
     return Status::ok();
 }
 
diff --git a/gnss/aidl/vts/GnssCallbackAidl.h b/gnss/aidl/vts/GnssCallbackAidl.h
index 06526d3..82a0df4 100644
--- a/gnss/aidl/vts/GnssCallbackAidl.h
+++ b/gnss/aidl/vts/GnssCallbackAidl.h
@@ -29,6 +29,7 @@
           info_cbq_("system_info"),
           location_cbq_("location"),
           sv_info_list_cbq_("sv_info"),
+          sv_info_list_timestamps_millis_cbq_("sv_info_timestamps"),
           nmea_cbq_("nmea"){};
     ~GnssCallbackAidl(){};
 
@@ -64,6 +65,8 @@
     android::hardware::gnss::common::GnssCallbackEventQueue<
             std::vector<android::hardware::gnss::IGnssCallback::GnssSvInfo>>
             sv_info_list_cbq_;
+    android::hardware::gnss::common::GnssCallbackEventQueue<long>
+            sv_info_list_timestamps_millis_cbq_;
     android::hardware::gnss::common::GnssCallbackEventQueue<std::pair<int64_t, std::string>>
             nmea_cbq_;
 };
\ No newline at end of file
diff --git a/gnss/aidl/vts/gnss_hal_test.cpp b/gnss/aidl/vts/gnss_hal_test.cpp
index fb9af52..4f5e6a0 100644
--- a/gnss/aidl/vts/gnss_hal_test.cpp
+++ b/gnss/aidl/vts/gnss_hal_test.cpp
@@ -478,6 +478,30 @@
     }
 }
 
+void GnssHalTest::collectSvInfoListTimestamps(const int numMeasurementEvents,
+                                              const int timeoutSeconds,
+                                              std::vector<int>& deltasMs) {
+    aidl_gnss_cb_->sv_info_list_timestamps_millis_cbq_.reset();
+    aidl_gnss_cb_->sv_info_list_cbq_.reset();
+
+    auto status = aidl_gnss_hal_->startSvStatus();
+    EXPECT_TRUE(status.isOk());
+    ASSERT_TRUE(aidl_gnss_cb_->sv_info_list_timestamps_millis_cbq_.size() ==
+                aidl_gnss_cb_->sv_info_list_cbq_.size());
+    long lastElapsedRealtimeMillis = 0;
+    for (int i = 0; i < numMeasurementEvents; i++) {
+        long timeStamp;
+        ASSERT_TRUE(aidl_gnss_cb_->sv_info_list_timestamps_millis_cbq_.retrieve(timeStamp,
+                                                                                timeoutSeconds));
+        if (lastElapsedRealtimeMillis != 0) {
+            deltasMs.push_back(timeStamp - lastElapsedRealtimeMillis);
+        }
+        lastElapsedRealtimeMillis = timeStamp;
+    }
+    status = aidl_gnss_hal_->stopSvStatus();
+    EXPECT_TRUE(status.isOk());
+}
+
 void GnssHalTest::checkGnssDataFields(const sp<GnssMeasurementCallbackAidl>& callback,
                                       const int numMeasurementEvents, const int timeoutSeconds,
                                       const bool isFullTracking) {
diff --git a/gnss/aidl/vts/gnss_hal_test.h b/gnss/aidl/vts/gnss_hal_test.h
index 470294c..88d01c1 100644
--- a/gnss/aidl/vts/gnss_hal_test.h
+++ b/gnss/aidl/vts/gnss_hal_test.h
@@ -101,6 +101,8 @@
     void collectMeasurementIntervals(const sp<GnssMeasurementCallbackAidl>& callback,
                                      const int numMeasurementEvents, const int timeoutSeconds,
                                      std::vector<int>& deltaMs);
+    void collectSvInfoListTimestamps(const int numMeasurementEvents, const int timeoutSeconds,
+                                     std::vector<int>& deltasMs);
     void checkGnssDataFields(const sp<GnssMeasurementCallbackAidl>& callback,
                              const int numMeasurementEvents, const int timeoutSeconds,
                              const bool isFullTracking);
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index 96dece4..17d65f5 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -1407,6 +1407,7 @@
  * TestGnssMeasurementIntervals_WithoutLocation:
  * 1. Start measurement at intervals
  * 2. Verify measurement are received at expected intervals
+ * 3. Verify status are reported at expected intervals
  */
 TEST_P(GnssHalTest, TestGnssMeasurementIntervals_WithoutLocation) {
     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
@@ -1426,13 +1427,24 @@
         auto callback = sp<GnssMeasurementCallbackAidl>::make();
         startMeasurementWithInterval(intervals[i], iGnssMeasurement, callback);
 
-        std::vector<int> deltas;
-        collectMeasurementIntervals(callback, numEvents[i], /* timeoutSeconds= */ 10, deltas);
+        std::vector<int> measurementDeltas;
+        std::vector<int> svInfoListTimestampsDeltas;
 
+        collectMeasurementIntervals(callback, numEvents[i], /* timeoutSeconds= */ 10,
+                                    measurementDeltas);
+        if (aidl_gnss_hal_->getInterfaceVersion() >= 3) {
+            collectSvInfoListTimestamps(numEvents[i], /* timeoutSeconds= */ 10,
+                                        svInfoListTimestampsDeltas);
+        }
         status = iGnssMeasurement->close();
         ASSERT_TRUE(status.isOk());
 
-        assertMeanAndStdev(intervals[i], deltas);
+        assertMeanAndStdev(intervals[i], measurementDeltas);
+
+        if (aidl_gnss_hal_->getInterfaceVersion() >= 3) {
+            assertMeanAndStdev(intervals[i], svInfoListTimestampsDeltas);
+            EXPECT_TRUE(aidl_gnss_cb_->sv_info_list_cbq_.size() > 0);
+        }
     }
 }