Blocklist strongest Sv of each constellation

Bug: 365614812
Test: atest VtsHalGnssTargetTest
Change-Id: I73972002d20eb3d0b0c9f6b7e98b0793550965e4
diff --git a/gnss/aidl/default/GnssDebug.cpp b/gnss/aidl/default/GnssDebug.cpp
index 5ae6edd..185bfe4 100644
--- a/gnss/aidl/default/GnssDebug.cpp
+++ b/gnss/aidl/default/GnssDebug.cpp
@@ -126,9 +126,46 @@
             .ephemerisAgeSeconds = 12,
             .serverPredictionIsAvailable = true,
             .serverPredictionAgeSeconds = 30};
+    SatelliteData satelliteData10 = {
+            .svid = 2,
+            .constellation = GnssConstellationType::GALILEO,
+            .ephemerisType = SatelliteEphemerisType::EPHEMERIS,
+            .ephemerisSource = SatellitePvt::SatelliteEphemerisSource::SERVER_LONG_TERM,
+            .ephemerisHealth = SatelliteEphemerisHealth::GOOD,
+            .ephemerisAgeSeconds = 12,
+            .serverPredictionIsAvailable = true,
+            .serverPredictionAgeSeconds = 30};
+    SatelliteData satelliteData11 = {
+            .svid = 4,
+            .constellation = GnssConstellationType::GALILEO,
+            .ephemerisType = SatelliteEphemerisType::EPHEMERIS,
+            .ephemerisSource = SatellitePvt::SatelliteEphemerisSource::SERVER_LONG_TERM,
+            .ephemerisHealth = SatelliteEphemerisHealth::GOOD,
+            .ephemerisAgeSeconds = 12,
+            .serverPredictionIsAvailable = true,
+            .serverPredictionAgeSeconds = 30};
+    SatelliteData satelliteData12 = {
+            .svid = 10,
+            .constellation = GnssConstellationType::GALILEO,
+            .ephemerisType = SatelliteEphemerisType::EPHEMERIS,
+            .ephemerisSource = SatellitePvt::SatelliteEphemerisSource::SERVER_LONG_TERM,
+            .ephemerisHealth = SatelliteEphemerisHealth::GOOD,
+            .ephemerisAgeSeconds = 12,
+            .serverPredictionIsAvailable = true,
+            .serverPredictionAgeSeconds = 30};
+    SatelliteData satelliteData13 = {
+            .svid = 29,
+            .constellation = GnssConstellationType::GALILEO,
+            .ephemerisType = SatelliteEphemerisType::EPHEMERIS,
+            .ephemerisSource = SatellitePvt::SatelliteEphemerisSource::SERVER_LONG_TERM,
+            .ephemerisHealth = SatelliteEphemerisHealth::GOOD,
+            .ephemerisAgeSeconds = 12,
+            .serverPredictionIsAvailable = true,
+            .serverPredictionAgeSeconds = 30};
     std::vector<SatelliteData> satelliteDataArrayDebug = {
-            satelliteData1, satelliteData2, satelliteData3, satelliteData4, satelliteData5,
-            satelliteData6, satelliteData7, satelliteData8, satelliteData9};
+            satelliteData1,  satelliteData2,  satelliteData3, satelliteData4, satelliteData5,
+            satelliteData6,  satelliteData7,  satelliteData8, satelliteData9, satelliteData10,
+            satelliteData11, satelliteData12, satelliteData13};
     debugData->position = positionDebug;
     debugData->time = timeDebug;
     debugData->satelliteDataArray = satelliteDataArrayDebug;
diff --git a/gnss/aidl/vts/gnss_hal_test.cpp b/gnss/aidl/vts/gnss_hal_test.cpp
index 0dd8b32..f7deb29 100644
--- a/gnss/aidl/vts/gnss_hal_test.cpp
+++ b/gnss/aidl/vts/gnss_hal_test.cpp
@@ -276,35 +276,43 @@
 }
 
 /*
- * FindStrongFrequentBlockableSource:
+ * FindStrongFrequentSource:
  *
- * Search through a GnssSvStatus list for the strongest blockable satellite observed enough times
+ * Search through a GnssSvStatus list for the strongest satellite observed enough times per
+ * constellation
  *
- * returns the strongest source,
- *         or a source with constellation == UNKNOWN if none are found sufficient times
+ * returns the strongest sources for each constellation,
+ *         or an empty vector if none are found sufficient times
  */
-BlocklistedSource GnssHalTest::FindStrongFrequentBlockableSource(
+std::vector<BlocklistedSource> GnssHalTest::FindStrongFrequentSources(
         const std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_list,
         const int min_observations) {
-    return FindStrongFrequentBlockableSource(convertToAidl(sv_info_list), min_observations);
+    return FindStrongFrequentSources(convertToAidl(sv_info_list), min_observations);
 }
 
-BlocklistedSource GnssHalTest::FindStrongFrequentBlockableSource(
+bool GnssHalTest::isBlockableConstellation(const GnssConstellationType constellation,
+                                           const bool isCnBuild) {
+    if (constellation == GnssConstellationType::GPS) {
+        return false;
+    }
+    if (isCnBuild && (constellation == GnssConstellationType::BEIDOU)) {
+        // Do not blocklist BDS on CN builds
+        return false;
+    }
+    return true;
+}
+
+std::vector<BlocklistedSource> GnssHalTest::FindStrongFrequentSources(
         const std::list<std::vector<IGnssCallback::GnssSvInfo>> sv_info_list,
         const int min_observations) {
-    std::map<ComparableBlocklistedSource, SignalCounts> mapSignals;
+    ALOGD("Find strongest sv from %d sv_info_list with %d min_observations.",
+          (int)sv_info_list.size(), min_observations);
 
-    bool isCnBuild = Utils::isCnBuild();
-    ALOGD("isCnBuild: %s", isCnBuild ? "true" : "false");
+    std::map<ComparableBlocklistedSource, SignalCounts> mapSignals;
     for (const auto& sv_info_vec : sv_info_list) {
         for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
             const auto& gnss_sv = sv_info_vec[iSv];
-            if ((gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX) &&
-                (gnss_sv.constellation != GnssConstellationType::GPS)) {
-                if (isCnBuild && (gnss_sv.constellation == GnssConstellationType::BEIDOU)) {
-                    // Do not blocklist BDS on CN builds
-                    continue;
-                }
+            if (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX) {
                 ComparableBlocklistedSource source;
                 source.id.svid = gnss_sv.svid;
                 source.id.constellation = gnss_sv.constellation;
@@ -326,27 +334,76 @@
         }
     }
 
-    float max_cn0_dbhz_with_sufficient_count = 0.;
-    int total_observation_count = 0;
-    int blocklisted_source_count_observation = 0;
+    // the Cn0 of the strongest SV per constellation
+    std::unordered_map<GnssConstellationType, float> max_cn0_map;
+    // # of total observations of all signals per constellation
+    std::unordered_map<GnssConstellationType, int> total_observation_count_map;
+    // # of observations of the strongest sv per constellation
+    std::unordered_map<GnssConstellationType, int> source_observation_count_map;
+    // the source to blocklist per constellation
+    std::unordered_map<GnssConstellationType, ComparableBlocklistedSource> source_map;
+    // # of signals per constellation
+    std::unordered_map<GnssConstellationType, int> signal_count_map;
 
-    ComparableBlocklistedSource source_to_blocklist;  // initializes to zero = UNKNOWN constellation
     for (auto const& pairSignal : mapSignals) {
-        total_observation_count += pairSignal.second.observations;
-        if ((pairSignal.second.observations >= min_observations) &&
-            (pairSignal.second.max_cn0_dbhz > max_cn0_dbhz_with_sufficient_count)) {
-            source_to_blocklist = pairSignal.first;
-            blocklisted_source_count_observation = pairSignal.second.observations;
-            max_cn0_dbhz_with_sufficient_count = pairSignal.second.max_cn0_dbhz;
+        ComparableBlocklistedSource source = pairSignal.first;
+        total_observation_count_map[source.id.constellation] += pairSignal.second.observations;
+        signal_count_map[source.id.constellation]++;
+        if (pairSignal.second.observations < min_observations) {
+            continue;
+        }
+        if (pairSignal.second.max_cn0_dbhz > max_cn0_map[source.id.constellation]) {
+            source_map[source.id.constellation] = pairSignal.first;
+            source_observation_count_map[source.id.constellation] = pairSignal.second.observations;
+            max_cn0_map[source.id.constellation] = pairSignal.second.max_cn0_dbhz;
         }
     }
-    ALOGD("Among %d observations, chose svid %d, constellation %d, "
-          "with %d observations at %.1f max CNo",
-          total_observation_count, source_to_blocklist.id.svid,
-          (int)source_to_blocklist.id.constellation, blocklisted_source_count_observation,
-          max_cn0_dbhz_with_sufficient_count);
 
-    return source_to_blocklist.id;
+    std::vector<BlocklistedSource> sources;
+    if (aidl_gnss_hal_->getInterfaceVersion() <= 4) {
+        /* For AIDL version <= 4 (launched-in-15 or earlier), only blocklist 1 sv */
+        float max_cn0 = 0;
+        ComparableBlocklistedSource source_to_blocklist;
+        for (auto const& pair : source_map) {
+            GnssConstellationType constellation = pair.first;
+            ComparableBlocklistedSource source = pair.second;
+            if (max_cn0_map[constellation] > max_cn0) {
+                max_cn0 = max_cn0_map[constellation];
+                source_to_blocklist = source;
+            }
+        }
+        if (source_to_blocklist.id.constellation != GnssConstellationType::UNKNOWN) {
+            ALOGD("In constellation %d, among %d observed SVs, svid %d is chosen to blocklist. "
+                  "It has %d observations with max Cn0: %.1f among %d total observations of this "
+                  "constellation.",
+                  (int)source_to_blocklist.id.constellation,
+                  signal_count_map[source_to_blocklist.id.constellation],
+                  source_to_blocklist.id.svid,
+                  source_observation_count_map[source_to_blocklist.id.constellation], max_cn0,
+                  total_observation_count_map[source_to_blocklist.id.constellation]);
+            sources.push_back(source_to_blocklist.id);
+        }
+    } else {
+        /* For AIDL version >= 5 (launched-in-16 or later), blocklist 1 sv per constellation */
+        for (auto const& pair : source_map) {
+            ComparableBlocklistedSource source = pair.second;
+            if (signal_count_map[source.id.constellation] < 4) {
+                // Skip the constellation with a small number of signals
+                // 4 is arbitrarily chosen to avoid affecting constellations with a limited coverage
+                continue;
+            }
+            ALOGD("In constellation %d, among %d observed SVs, svid %d is chosen to blocklist. "
+                  "It has %d observations with max Cn0: %.1f among %d total observations of this "
+                  "constellation.",
+                  (int)source.id.constellation, signal_count_map[source.id.constellation],
+                  source.id.svid, source_observation_count_map[source.id.constellation],
+                  max_cn0_map[source.id.constellation],
+                  total_observation_count_map[source.id.constellation]);
+            sources.push_back(source.id);
+        }
+    }
+
+    return sources;
 }
 
 GnssConstellationType GnssHalTest::startLocationAndGetBlockableConstellation(
diff --git a/gnss/aidl/vts/gnss_hal_test.h b/gnss/aidl/vts/gnss_hal_test.h
index dec5856..c41620a 100644
--- a/gnss/aidl/vts/gnss_hal_test.h
+++ b/gnss/aidl/vts/gnss_hal_test.h
@@ -81,14 +81,17 @@
     std::list<std::vector<android::hardware::gnss::IGnssCallback::GnssSvInfo>> convertToAidl(
             const std::list<hidl_vec<android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo>>&
                     sv_info_list);
-    android::hardware::gnss::BlocklistedSource FindStrongFrequentBlockableSource(
+    std::vector<android::hardware::gnss::BlocklistedSource> FindStrongFrequentSources(
             const std::list<hidl_vec<android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo>>
                     sv_info_list,
             const int min_observations);
-    android::hardware::gnss::BlocklistedSource FindStrongFrequentBlockableSource(
+    std::vector<android::hardware::gnss::BlocklistedSource> FindStrongFrequentSources(
             const std::list<std::vector<android::hardware::gnss::IGnssCallback::GnssSvInfo>>
                     sv_info_list,
             const int min_observations);
+    bool isBlockableConstellation(
+            const android::hardware::gnss::GnssConstellationType constellation,
+            const bool isCnBuild);
 
     void checkGnssMeasurementClockFields(const android::hardware::gnss::GnssData& measurement);
     void checkGnssMeasurementFlags(const android::hardware::gnss::GnssMeasurement& measurement);
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index a2e81d1..781476fd 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -615,7 +615,7 @@
  * BlocklistIndividualSatellites:
  *
  * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
- * GnssStatus for common satellites (strongest and one other.)
+ * GnssStatus for common satellites (strongest one in each constellation.)
  * 2a & b) Turns off location, and blocklists common satellites.
  * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
  * GnssStatus does not use those satellites.
@@ -633,6 +633,7 @@
         return;
     }
 
+    const int kWarmUpLocations = 3;
     const int kLocationsToAwait = 3;
     const int kRetriesToUnBlocklist = 10;
 
@@ -641,7 +642,7 @@
     } else {
         aidl_gnss_cb_->location_cbq_.reset();
     }
-    StartAndCheckLocations(kLocationsToAwait);
+    StartAndCheckLocations(kLocationsToAwait + kWarmUpLocations);
     int location_called_count = (aidl_gnss_hal_->getInterfaceVersion() <= 1)
                                         ? gnss_cb_->location_cbq_.calledCount()
                                         : aidl_gnss_cb_->location_cbq_.calledCount();
@@ -650,37 +651,50 @@
     int sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() <= 1)
                                         ? gnss_cb_->sv_info_list_cbq_.size()
                                         : aidl_gnss_cb_->sv_info_list_cbq_.size();
-    EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
+    EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait + kWarmUpLocations);
     ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
-          sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
+          sv_info_list_cbq_size, kLocationsToAwait + kWarmUpLocations, location_called_count);
 
     /*
-     * Identify strongest SV seen at least kLocationsToAwait -1 times
-     * Why -1?  To avoid test flakiness in case of (plausible) slight flakiness in strongest signal
-     * observability (one epoch RF null)
+     * Identify strongest SV per constellation seen seen at least kLocationsToAwait -1 times.
+     *
+     * Why not (kLocationsToAwait + kWarmUpLocations)?  To avoid test flakiness in case of
+     * (plausible) slight flakiness in strongest signal observability (one epoch RF null)
      */
 
     const int kGnssSvInfoListTimeout = 2;
-    BlocklistedSource source_to_blocklist;
+    std::vector<BlocklistedSource> sources_to_blocklist;
     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
+        // Discard kWarmUpLocations sv_info_vec
+        std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> tmp;
+        int count =
+                gnss_cb_->sv_info_list_cbq_.retrieve(tmp, kWarmUpLocations, kGnssSvInfoListTimeout);
+        ASSERT_EQ(count, kWarmUpLocations);
+
+        // Retrieve (sv_info_list_cbq_size - kWarmUpLocations) sv_info_vec
         std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_vec_list;
-        int count = gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec_list, sv_info_list_cbq_size,
-                                                         kGnssSvInfoListTimeout);
-        ASSERT_EQ(count, sv_info_list_cbq_size);
-        source_to_blocklist =
-                FindStrongFrequentBlockableSource(sv_info_vec_list, kLocationsToAwait - 1);
+        count = gnss_cb_->sv_info_list_cbq_.retrieve(
+                sv_info_vec_list, sv_info_list_cbq_size - kWarmUpLocations, kGnssSvInfoListTimeout);
+        ASSERT_EQ(count, sv_info_list_cbq_size - kWarmUpLocations);
+        sources_to_blocklist = FindStrongFrequentSources(sv_info_vec_list, kLocationsToAwait - 1);
     } else {
+        // Discard kWarmUpLocations sv_info_vec
+        std::list<std::vector<IGnssCallback::GnssSvInfo>> tmp;
+        int count = aidl_gnss_cb_->sv_info_list_cbq_.retrieve(tmp, kWarmUpLocations,
+                                                              kGnssSvInfoListTimeout);
+        ASSERT_EQ(count, kWarmUpLocations);
+
+        // Retrieve (sv_info_list_cbq_size - kWarmUpLocations) sv_info_vec
         std::list<std::vector<IGnssCallback::GnssSvInfo>> sv_info_vec_list;
-        int count = aidl_gnss_cb_->sv_info_list_cbq_.retrieve(
-                sv_info_vec_list, sv_info_list_cbq_size, kGnssSvInfoListTimeout);
-        ASSERT_EQ(count, sv_info_list_cbq_size);
-        source_to_blocklist =
-                FindStrongFrequentBlockableSource(sv_info_vec_list, kLocationsToAwait - 1);
+        count = aidl_gnss_cb_->sv_info_list_cbq_.retrieve(
+                sv_info_vec_list, sv_info_list_cbq_size - kWarmUpLocations, kGnssSvInfoListTimeout);
+        ASSERT_EQ(count, sv_info_list_cbq_size - kWarmUpLocations);
+        sources_to_blocklist = FindStrongFrequentSources(sv_info_vec_list, kLocationsToAwait - 1);
     }
 
-    if (source_to_blocklist.constellation == GnssConstellationType::UNKNOWN) {
-        // Cannot find a blockable satellite. Let the test pass.
-        ALOGD("Cannot find a blockable satellite. Letting the test pass.");
+    if (sources_to_blocklist.empty()) {
+        // Cannot find a satellite to blocklist. Let the test pass.
+        ALOGD("Cannot find a satellite to blocklist. Letting the test pass.");
         return;
     }
 
@@ -693,9 +707,7 @@
     ASSERT_NE(gnss_configuration_hal, nullptr);
 
     std::vector<BlocklistedSource> sources;
-    sources.resize(1);
-    sources[0] = source_to_blocklist;
-
+    sources = sources_to_blocklist;
     status = gnss_configuration_hal->setBlocklist(sources);
     ASSERT_TRUE(status.isOk());
 
@@ -726,26 +738,47 @@
     EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
     ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
           sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
+    bool isCnBuild = Utils::isCnBuild();
     for (int i = 0; i < sv_info_list_cbq_size; ++i) {
         if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
             hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
             gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
             for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
                 auto& gnss_sv = sv_info_vec[iSv];
-                EXPECT_FALSE(
-                        (gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) &&
-                        (static_cast<GnssConstellationType>(gnss_sv.v2_0.constellation) ==
-                         source_to_blocklist.constellation) &&
-                        (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+                if (!(gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX)) {
+                    continue;
+                }
+                for (auto const& source : sources_to_blocklist) {
+                    if (isBlockableConstellation(source.constellation, isCnBuild)) {
+                        EXPECT_FALSE((gnss_sv.v2_0.v1_0.svid == source.svid) &&
+                                     (static_cast<GnssConstellationType>(
+                                              gnss_sv.v2_0.constellation) == source.constellation));
+                    } else if ((gnss_sv.v2_0.v1_0.svid == source.svid) &&
+                               (static_cast<GnssConstellationType>(gnss_sv.v2_0.constellation) ==
+                                source.constellation)) {
+                        ALOGW("Found constellation %d, svid %d blocklisted but still used-in-fix.",
+                              source.constellation, source.svid);
+                    }
+                }
             }
         } else {
             std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
             aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
             for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
                 auto& gnss_sv = sv_info_vec[iSv];
-                EXPECT_FALSE((gnss_sv.svid == source_to_blocklist.svid) &&
-                             (gnss_sv.constellation == source_to_blocklist.constellation) &&
-                             (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
+                if (!(gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX)) {
+                    continue;
+                }
+                for (auto const& source : sources_to_blocklist) {
+                    if (isBlockableConstellation(source.constellation, isCnBuild)) {
+                        EXPECT_FALSE((gnss_sv.svid == source.svid) &&
+                                     (gnss_sv.constellation == source.constellation));
+                    } else if ((gnss_sv.svid == source.svid) &&
+                               (gnss_sv.constellation == source.constellation)) {
+                        ALOGW("Found constellation %d, svid %d blocklisted but still used-in-fix.",
+                              gnss_sv.constellation, gnss_sv.svid);
+                    }
+                }
             }
         }
     }
@@ -795,12 +828,15 @@
                 gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
                 for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
                     auto& gnss_sv = sv_info_vec[iSv];
-                    if ((gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) &&
-                        (static_cast<GnssConstellationType>(gnss_sv.v2_0.constellation) ==
-                         source_to_blocklist.constellation) &&
-                        (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX)) {
-                        strongest_sv_is_reobserved = true;
-                        break;
+                    for (auto const& source : sources_to_blocklist) {
+                        if ((gnss_sv.v2_0.v1_0.svid == source.svid) &&
+                            (static_cast<GnssConstellationType>(gnss_sv.v2_0.constellation) ==
+                             source.constellation) &&
+                            (gnss_sv.v2_0.v1_0.svFlag &
+                             IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX)) {
+                            strongest_sv_is_reobserved = true;
+                            break;
+                        }
                     }
                 }
             } else {
@@ -808,11 +844,13 @@
                 aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
                 for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
                     auto& gnss_sv = sv_info_vec[iSv];
-                    if ((gnss_sv.svid == source_to_blocklist.svid) &&
-                        (gnss_sv.constellation == source_to_blocklist.constellation) &&
-                        (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX)) {
-                        strongest_sv_is_reobserved = true;
-                        break;
+                    for (auto const& source : sources_to_blocklist) {
+                        if ((gnss_sv.svid == source.svid) &&
+                            (gnss_sv.constellation == source.constellation) &&
+                            (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX)) {
+                            strongest_sv_is_reobserved = true;
+                            break;
+                        }
                     }
                 }
             }
diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp
index 8303d93..740bc59 100644
--- a/gnss/common/utils/default/Utils.cpp
+++ b/gnss/common/utils/default/Utils.cpp
@@ -338,16 +338,25 @@
 
 std::vector<GnssSvInfo> Utils::getMockSvInfoList() {
     std::vector<GnssSvInfo> gnssSvInfoList = {
+            // svid in [1, 32] for GPS
             getMockSvInfo(3, GnssConstellationType::GPS, 32.5, 27.5, 59.1, 166.5, kGpsL1FreqHz),
             getMockSvInfo(5, GnssConstellationType::GPS, 27.0, 22.0, 29.0, 56.5, kGpsL1FreqHz),
             getMockSvInfo(17, GnssConstellationType::GPS, 30.5, 25.5, 71.0, 77.0, kGpsL5FreqHz),
             getMockSvInfo(26, GnssConstellationType::GPS, 24.1, 19.1, 28.0, 253.0, kGpsL5FreqHz),
+            // svid in [1, 36] for GAL
+            getMockSvInfo(2, GnssConstellationType::GALILEO, 33.5, 27.5, 59.1, 166.5, kGalE1FreqHz),
+            getMockSvInfo(4, GnssConstellationType::GALILEO, 28.0, 22.0, 29.0, 56.5, kGalE1FreqHz),
+            getMockSvInfo(10, GnssConstellationType::GALILEO, 35.5, 25.5, 71.0, 77.0, kGalE1FreqHz),
+            getMockSvInfo(29, GnssConstellationType::GALILEO, 34.1, 19.1, 28.0, 253.0,
+                          kGalE1FreqHz),
+            // "1 <= svid <= 25 || 93 <= svid <= 106" for GLO
             getMockSvInfo(5, GnssConstellationType::GLONASS, 20.5, 15.5, 11.5, 116.0, kGloG1FreqHz),
             getMockSvInfo(17, GnssConstellationType::GLONASS, 21.5, 16.5, 28.5, 186.0,
                           kGloG1FreqHz),
             getMockSvInfo(18, GnssConstellationType::GLONASS, 28.3, 25.3, 38.8, 69.0, kGloG1FreqHz),
             getMockSvInfo(10, GnssConstellationType::GLONASS, 25.0, 20.0, 66.0, 247.0,
                           kGloG1FreqHz),
+            // "1 <= X <= 14" for IRNSS
             getMockSvInfo(3, GnssConstellationType::IRNSS, 22.0, 19.7, 35.0, 112.0, kIrnssL5FreqHz),
     };
     return gnssSvInfoList;
diff --git a/gnss/common/utils/default/include/Constants.h b/gnss/common/utils/default/include/Constants.h
index 489413e..e6605c4 100644
--- a/gnss/common/utils/default/include/Constants.h
+++ b/gnss/common/utils/default/include/Constants.h
@@ -31,6 +31,7 @@
 const int64_t kMockTimestamp = 1519930775453L;
 const float kGpsL1FreqHz = 1575.42 * 1e6;
 const float kGpsL5FreqHz = 1176.45 * 1e6;
+const float kGalE1FreqHz = 1575.42 * 1e6;
 const float kGloG1FreqHz = 1602.0 * 1e6;
 const float kIrnssL5FreqHz = 1176.45 * 1e6;