Stop location to avoid timing issue

Before setting constellation blacklist, the location report should
be stopped first. Otherwise, the sv status which contains blacklist
constellation is still reporting and may be counted in checking
SvList. According to the comments of this case, location should be
turned off as 2a step.

Also adding another test that a blacklist request that comes in
while tracking is started, takes effect after a stop/start cycle.

Bug: 144675840
Test: on device
Change-Id: I975d6036c742b8b825c742dca8fdcfe1dc1c1ee9
Merged-In: I04894426e8384d25f2b5e269961a9cf051cab40f
diff --git a/gnss/1.1/vts/functional/gnss_hal_test.cpp b/gnss/1.1/vts/functional/gnss_hal_test.cpp
index f3b376e..e6e3c85 100644
--- a/gnss/1.1/vts/functional/gnss_hal_test.cpp
+++ b/gnss/1.1/vts/functional/gnss_hal_test.cpp
@@ -177,6 +177,42 @@
     return hasGnssHalVersion_1_1 && !hasGnssHalVersion_2_0;
 }
 
+GnssConstellationType GnssHalTest::startLocationAndGetNonGpsConstellation() {
+    const int kLocationsToAwait = 3;
+
+    StartAndCheckLocations(kLocationsToAwait);
+
+    // Tolerate 1 less sv status to handle edge cases in reporting.
+    EXPECT_GE((int)list_gnss_sv_status_.size() + 1, kLocationsToAwait);
+    ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations (%d received)",
+          (int)list_gnss_sv_status_.size(), kLocationsToAwait, location_called_count_);
+
+    // Find first non-GPS constellation
+    GnssConstellationType constellation_to_blacklist = GnssConstellationType::UNKNOWN;
+    for (const auto& gnss_sv_status : list_gnss_sv_status_) {
+        for (uint32_t iSv = 0; iSv < gnss_sv_status.numSvs; iSv++) {
+            const auto& gnss_sv = gnss_sv_status.gnssSvList[iSv];
+            if ((gnss_sv.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX) &&
+                (gnss_sv.constellation != GnssConstellationType::UNKNOWN) &&
+                (gnss_sv.constellation != GnssConstellationType::GPS)) {
+                // found a non-GPS constellation
+                constellation_to_blacklist = gnss_sv.constellation;
+                break;
+            }
+        }
+        if (constellation_to_blacklist != GnssConstellationType::UNKNOWN) {
+            break;
+        }
+    }
+
+    if (constellation_to_blacklist == GnssConstellationType::UNKNOWN) {
+        ALOGI("No non-GPS constellations found, constellation blacklist test less effective.");
+        // Proceed functionally to return something.
+        constellation_to_blacklist = GnssConstellationType::GLONASS;
+    }
+    return constellation_to_blacklist;
+}
+
 void GnssHalTest::notify() {
     std::unique_lock<std::mutex> lock(mtx_);
     notify_count_++;
diff --git a/gnss/1.1/vts/functional/gnss_hal_test.h b/gnss/1.1/vts/functional/gnss_hal_test.h
index 84a9f84..09ebadc 100644
--- a/gnss/1.1/vts/functional/gnss_hal_test.h
+++ b/gnss/1.1/vts/functional/gnss_hal_test.h
@@ -31,9 +31,10 @@
 
 using android::hardware::gnss::V1_0::GnssLocation;
 
+using android::hardware::gnss::V1_0::GnssConstellationType;
+using android::hardware::gnss::V1_0::GnssLocationFlags;
 using android::hardware::gnss::V1_1::IGnss;
 using android::hardware::gnss::V1_1::IGnssCallback;
-using android::hardware::gnss::V1_0::GnssLocationFlags;
 
 using android::sp;
 
@@ -151,6 +152,16 @@
      */
     bool IsGnssHalVersion_1_1() const;
 
+    /*
+     * startLocationAndGetNonGpsConstellation:
+     * 1. Start location
+     * 2. Find and return first non-GPS constellation
+     *
+     * Note that location is not stopped in this method. The client should call
+     * StopAndClearLocations() after the call.
+     */
+    GnssConstellationType startLocationAndGetNonGpsConstellation();
+
     sp<IGnss> gnss_hal_;         // GNSS HAL to call into
     sp<IGnssCallback> gnss_cb_;  // Primary callback interface
 
diff --git a/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp b/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
index ee236ba..503e419 100644
--- a/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
@@ -330,7 +330,7 @@
 }
 
 /*
- * BlacklistConstellation:
+ * BlacklistConstellationWithLocationOff:
  *
  * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
  * GnssStatus for any non-GPS constellations.
@@ -339,44 +339,19 @@
  * GnssStatus does not use any constellation but GPS.
  * 4a & b) Clean up by turning off location, and send in empty blacklist.
  */
-TEST_F(GnssHalTest, BlacklistConstellation) {
+TEST_F(GnssHalTest, BlacklistConstellationWithLocationOff) {
     if (!IsGnssHalVersion_1_1()) {
         ALOGI("Test BlacklistConstellation skipped. GNSS HAL version is greater than 1.1.");
         return;
     }
 
     const int kLocationsToAwait = 3;
-
-    StartAndCheckLocations(kLocationsToAwait);
-
-    // Tolerate 1 less sv status to handle edge cases in reporting.
-    EXPECT_GE((int)list_gnss_sv_status_.size() + 1, kLocationsToAwait);
-    ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations (%d received)",
-          (int)list_gnss_sv_status_.size(), kLocationsToAwait, location_called_count_);
-
     // Find first non-GPS constellation to blacklist
-    GnssConstellationType constellation_to_blacklist = GnssConstellationType::UNKNOWN;
-    for (const auto& gnss_sv_status : list_gnss_sv_status_) {
-        for (uint32_t iSv = 0; iSv < gnss_sv_status.numSvs; iSv++) {
-            const auto& gnss_sv = gnss_sv_status.gnssSvList[iSv];
-            if ((gnss_sv.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX) &&
-                (gnss_sv.constellation != GnssConstellationType::UNKNOWN) &&
-                (gnss_sv.constellation != GnssConstellationType::GPS)) {
-                // found a non-GPS constellation
-                constellation_to_blacklist = gnss_sv.constellation;
-                break;
-            }
-        }
-        if (constellation_to_blacklist != GnssConstellationType::UNKNOWN) {
-            break;
-        }
-    }
+    GnssConstellationType constellation_to_blacklist = startLocationAndGetNonGpsConstellation();
 
-    if (constellation_to_blacklist == GnssConstellationType::UNKNOWN) {
-        ALOGI("No non-GPS constellations found, constellation blacklist test less effective.");
-        // Proceed functionally to blacklist something.
-        constellation_to_blacklist = GnssConstellationType::GLONASS;
-    }
+    // Turns off location
+    StopAndClearLocations();
+
     IGnssConfiguration::BlacklistedSource source_to_blacklist;
     source_to_blacklist.constellation = constellation_to_blacklist;
     source_to_blacklist.svid = 0;  // documented wildcard for all satellites in this constellation
@@ -421,6 +396,71 @@
 }
 
 /*
+ * BlacklistConstellationWithLocationOn:
+ *
+ * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus for any non-GPS constellations.
+ * 2a & b) Blacklist first non-GPS constellations, and turns off location.
+ * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
+ * GnssStatus does not use any constellation but GPS.
+ * 4a & b) Clean up by turning off location, and send in empty blacklist.
+ */
+TEST_F(GnssHalTest, BlacklistConstellationWithLocationOn) {
+    if (!IsGnssHalVersion_1_1()) {
+        ALOGI("Test BlacklistConstellation skipped. GNSS HAL version is greater than 1.1.");
+        return;
+    }
+
+    const int kLocationsToAwait = 3;
+    GnssConstellationType constellation_to_blacklist = startLocationAndGetNonGpsConstellation();
+
+    IGnssConfiguration::BlacklistedSource source_to_blacklist;
+    source_to_blacklist.constellation = constellation_to_blacklist;
+    source_to_blacklist.svid = 0;  // documented wildcard for all satellites in this constellation
+
+    auto gnss_configuration_hal_return = gnss_hal_->getExtensionGnssConfiguration_1_1();
+    ASSERT_TRUE(gnss_configuration_hal_return.isOk());
+    sp<IGnssConfiguration> gnss_configuration_hal = gnss_configuration_hal_return;
+    ASSERT_NE(gnss_configuration_hal, nullptr);
+
+    hidl_vec<IGnssConfiguration::BlacklistedSource> sources;
+    sources.resize(1);
+    sources[0] = source_to_blacklist;
+
+    auto result = gnss_configuration_hal->setBlacklist(sources);
+    ASSERT_TRUE(result.isOk());
+    EXPECT_TRUE(result);
+
+    // Turns off location
+    StopAndClearLocations();
+
+    // retry and ensure constellation not used
+    list_gnss_sv_status_.clear();
+
+    location_called_count_ = 0;
+    StartAndCheckLocations(kLocationsToAwait);
+
+    // Tolerate 1 less sv status to handle edge cases in reporting.
+    EXPECT_GE((int)list_gnss_sv_status_.size() + 1, kLocationsToAwait);
+    ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations", (int)list_gnss_sv_status_.size(),
+          kLocationsToAwait);
+    for (const auto& gnss_sv_status : list_gnss_sv_status_) {
+        for (uint32_t iSv = 0; iSv < gnss_sv_status.numSvs; iSv++) {
+            const auto& gnss_sv = gnss_sv_status.gnssSvList[iSv];
+            EXPECT_FALSE((gnss_sv.constellation == source_to_blacklist.constellation) &&
+                         (gnss_sv.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX));
+        }
+    }
+
+    // clean up
+    StopAndClearLocations();
+    sources.resize(0);
+    result = gnss_configuration_hal->setBlacklist(sources);
+    ASSERT_TRUE(result.isOk());
+    EXPECT_TRUE(result);
+}
+
+/*
  * InjectBestLocation
  *
  * Ensure successfully injecting a location.