Add register/unregister methods for SvStatus and NMEA
(hardware/interfaces)

Bug: 213375506
Test: atest VtsHalGnssTargetTest
Change-Id: I7468336b5e1759f4ce90a42fbfd19e3bb17baaa9
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
index affef2b..5657434 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
@@ -56,6 +56,10 @@
   void setPositionMode(in android.hardware.gnss.IGnss.PositionModeOptions options);
   android.hardware.gnss.IGnssAntennaInfo getExtensionGnssAntennaInfo();
   @nullable android.hardware.gnss.measurement_corrections.IMeasurementCorrectionsInterface getExtensionMeasurementCorrections();
+  void startSvStatus();
+  void stopSvStatus();
+  void startNmea();
+  void stopNmea();
   const int ERROR_INVALID_ARGUMENT = 1;
   const int ERROR_ALREADY_INIT = 2;
   const int ERROR_GENERIC = 3;
diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl
index 79950ad..12fdbb4 100644
--- a/gnss/aidl/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl
@@ -320,4 +320,25 @@
      * @return Handle to the IMeasurementCorrectionsInterface.
      */
     @nullable IMeasurementCorrectionsInterface getExtensionMeasurementCorrections();
+
+    /**
+     * Starts a SvStatus output stream using the IGnssCallback gnssSvStatusCb().
+     */
+    void startSvStatus();
+
+    /**
+     * Stops the SvStatus output stream.
+     */
+    void stopSvStatus();
+
+    /**
+     * Starts an NMEA (National Marine Electronics Association) output stream using the
+     * IGnssCallback gnssNmeaCb().
+     */
+    void startNmea();
+
+    /**
+     * Stops the NMEA output stream.
+     */
+    void stopNmea();
 }
diff --git a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
index a74d097..866606f 100644
--- a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
@@ -202,6 +202,10 @@
     /**
      * 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.
+     *
      * @param svInfo SV status information from HAL.
      */
     void gnssSvStatusCb(in GnssSvInfo[] svInfoList);
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index eb17bbf..af1dd5c 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -87,15 +87,13 @@
     mIsActive = true;
     this->reportGnssStatusValue(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
     mThread = std::thread([this]() {
-        auto svStatus = filterBlocklistedSatellites(Utils::getMockSvInfoList());
-        this->reportSvStatus(svStatus);
+        this->reportSvStatus();
         if (!mFirstFixReceived) {
             std::this_thread::sleep_for(std::chrono::milliseconds(TTFF_MILLIS));
             mFirstFixReceived = true;
         }
         while (mIsActive == true) {
-            auto svStatus = filterBlocklistedSatellites(Utils::getMockSvInfoList());
-            this->reportSvStatus(svStatus);
+            this->reportSvStatus();
 
             auto currentLocation = getLocationFromHW();
             mGnssPowerIndication->notePowerConsumption();
@@ -124,6 +122,13 @@
     return;
 }
 
+void Gnss::reportSvStatus() const {
+    if (mIsSvStatusActive) {
+        auto svStatus = filterBlocklistedSatellites(Utils::getMockSvInfoList());
+        reportSvStatus(svStatus);
+    }
+}
+
 void Gnss::reportSvStatus(const std::vector<GnssSvInfo>& svInfoList) const {
     std::unique_lock<std::mutex> lock(mMutex);
     if (sGnssCallback == nullptr) {
@@ -136,7 +141,8 @@
     }
 }
 
-std::vector<GnssSvInfo> Gnss::filterBlocklistedSatellites(std::vector<GnssSvInfo> gnssSvInfoList) {
+std::vector<GnssSvInfo> Gnss::filterBlocklistedSatellites(
+        std::vector<GnssSvInfo> gnssSvInfoList) const {
     ALOGD("filterBlocklistedSatellites");
     for (uint32_t i = 0; i < gnssSvInfoList.size(); i++) {
         if (mGnssConfiguration->isBlocklisted(gnssSvInfoList[i])) {
@@ -168,6 +174,26 @@
     return ScopedAStatus::ok();
 }
 
+ScopedAStatus Gnss::startSvStatus() {
+    ALOGD("startSvStatus");
+    mIsSvStatusActive = true;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Gnss::stopSvStatus() {
+    ALOGD("stopSvStatus");
+    mIsSvStatusActive = false;
+    return ScopedAStatus::ok();
+}
+ScopedAStatus Gnss::startNmea() {
+    ALOGD("startNmea");
+    return ScopedAStatus::ok();
+}
+ScopedAStatus Gnss::stopNmea() {
+    ALOGD("stopNmea");
+    return ScopedAStatus::ok();
+}
+
 ScopedAStatus Gnss::close() {
     ALOGD("close");
     sGnssCallback = nullptr;
diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h
index b50a1ae..1489b4b 100644
--- a/gnss/aidl/default/Gnss.h
+++ b/gnss/aidl/default/Gnss.h
@@ -51,6 +51,10 @@
     ndk::ScopedAStatus injectBestLocation(const GnssLocation& location) override;
     ndk::ScopedAStatus deleteAidingData(GnssAidingData aidingDataFlags) override;
     ndk::ScopedAStatus setPositionMode(const PositionModeOptions& options) override;
+    ndk::ScopedAStatus startSvStatus() override;
+    ndk::ScopedAStatus stopSvStatus() override;
+    ndk::ScopedAStatus startNmea() override;
+    ndk::ScopedAStatus stopNmea() override;
 
     ndk::ScopedAStatus getExtensionPsds(std::shared_ptr<IGnssPsds>* iGnssPsds) override;
     ndk::ScopedAStatus getExtensionGnssConfiguration(
@@ -83,9 +87,10 @@
 
   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);
+            std::vector<IGnssCallback::GnssSvInfo> gnssSvInfoList) const;
     void reportGnssStatusValue(const IGnssCallback::GnssStatusValue gnssStatusValue) const;
     std::unique_ptr<GnssLocation> getLocationFromHW();
 
@@ -93,6 +98,7 @@
 
     std::atomic<long> mMinIntervalMs;
     std::atomic<bool> mIsActive;
+    std::atomic<bool> mIsSvStatusActive;
     std::atomic<bool> mFirstFixReceived;
     std::thread mThread;
 
diff --git a/gnss/aidl/vts/gnss_hal_test.cpp b/gnss/aidl/vts/gnss_hal_test.cpp
index 4828f19..c1128ba 100644
--- a/gnss/aidl/vts/gnss_hal_test.cpp
+++ b/gnss/aidl/vts/gnss_hal_test.cpp
@@ -100,9 +100,11 @@
     }
 
     SetPositionMode(min_interval_msec, low_power_mode);
-    auto result = aidl_gnss_hal_->start();
+    auto status = aidl_gnss_hal_->start();
+    EXPECT_TRUE(status.isOk());
 
-    EXPECT_TRUE(result.isOk());
+    status = aidl_gnss_hal_->startSvStatus();
+    EXPECT_TRUE(status.isOk());
 
     /*
      * GnssLocationProvider support of AGPS SUPL & XtraDownloader is not available in VTS,
@@ -129,8 +131,10 @@
         // Invoke the super method.
         return GnssHalTestTemplate<IGnss_V2_1>::StopAndClearLocations();
     }
+    auto status = aidl_gnss_hal_->stopSvStatus();
+    EXPECT_TRUE(status.isOk());
 
-    auto status = aidl_gnss_hal_->stop();
+    status = aidl_gnss_hal_->stop();
     EXPECT_TRUE(status.isOk());
 
     /*