• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "GnssHalTestCases"
18 
19 #include <gnss_hal_test.h>
20 #include <cmath>
21 #include "Utils.h"
22 
23 #include <gtest/gtest.h>
24 
25 using android::hardware::hidl_string;
26 using android::hardware::hidl_vec;
27 
28 using android::hardware::gnss::common::Utils;
29 
30 using IGnssMeasurement_2_1 = android::hardware::gnss::V2_1::IGnssMeasurement;
31 using IGnssMeasurement_2_0 = android::hardware::gnss::V2_0::IGnssMeasurement;
32 using IGnssMeasurement_1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
33 using IGnssMeasurement_1_0 = android::hardware::gnss::V1_0::IGnssMeasurement;
34 
35 using IGnssConfiguration_2_1 = android::hardware::gnss::V2_1::IGnssConfiguration;
36 using IGnssConfiguration_2_0 = android::hardware::gnss::V2_0::IGnssConfiguration;
37 using IGnssConfiguration_1_1 = android::hardware::gnss::V1_1::IGnssConfiguration;
38 using IGnssConfiguration_1_0 = android::hardware::gnss::V1_0::IGnssConfiguration;
39 
40 using android::hardware::gnss::V2_0::GnssConstellationType;
41 using android::hardware::gnss::V2_1::IGnssConfiguration;
42 
43 using GnssMeasurementFlags = IGnssMeasurementCallback_2_1::GnssMeasurementFlags;
44 using IMeasurementCorrections_1_1 =
45         android::hardware::gnss::measurement_corrections::V1_1::IMeasurementCorrections;
46 
47 /*
48  * SetupTeardownCreateCleanup:
49  * Requests the gnss HAL then calls cleanup
50  *
51  * Empty test fixture to verify basic Setup & Teardown
52  */
TEST_P(GnssHalTest,SetupTeardownCreateCleanup)53 TEST_P(GnssHalTest, SetupTeardownCreateCleanup) {}
54 
55 /*
56  * TestGnssMeasurementExtension:
57  * Gets the GnssMeasurementExtension and verifies that it returns an actual extension.
58  */
TEST_P(GnssHalTest,TestGnssMeasurementExtension)59 TEST_P(GnssHalTest, TestGnssMeasurementExtension) {
60     auto gnssMeasurement_2_1 = gnss_hal_->getExtensionGnssMeasurement_2_1();
61     auto gnssMeasurement_2_0 = gnss_hal_->getExtensionGnssMeasurement_2_0();
62     auto gnssMeasurement_1_1 = gnss_hal_->getExtensionGnssMeasurement_1_1();
63     auto gnssMeasurement_1_0 = gnss_hal_->getExtensionGnssMeasurement();
64     ASSERT_TRUE(gnssMeasurement_2_1.isOk() && gnssMeasurement_2_0.isOk() &&
65                 gnssMeasurement_1_1.isOk() && gnssMeasurement_1_0.isOk());
66     sp<IGnssMeasurement_2_1> iGnssMeas_2_1 = gnssMeasurement_2_1;
67     sp<IGnssMeasurement_2_0> iGnssMeas_2_0 = gnssMeasurement_2_0;
68     sp<IGnssMeasurement_1_1> iGnssMeas_1_1 = gnssMeasurement_1_1;
69     sp<IGnssMeasurement_1_0> iGnssMeas_1_0 = gnssMeasurement_1_0;
70     // At least one interface is non-null.
71     int numNonNull = (int)(iGnssMeas_2_1 != nullptr) + (int)(iGnssMeas_2_0 != nullptr) +
72                      (int)(iGnssMeas_1_1 != nullptr) + (int)(iGnssMeas_1_0 != nullptr);
73     ASSERT_TRUE(numNonNull >= 1);
74 }
75 
76 /*
77  * TestGnssConfigurationExtension:
78  * Gets the GnssConfigurationExtension and verifies that it returns an actual extension.
79  */
TEST_P(GnssHalTest,TestGnssConfigurationExtension)80 TEST_P(GnssHalTest, TestGnssConfigurationExtension) {
81     auto gnssConfiguration_2_1 = gnss_hal_->getExtensionGnssConfiguration_2_1();
82     auto gnssConfiguration_2_0 = gnss_hal_->getExtensionGnssConfiguration_2_0();
83     auto gnssConfiguration_1_1 = gnss_hal_->getExtensionGnssConfiguration_1_1();
84     auto gnssConfiguration_1_0 = gnss_hal_->getExtensionGnssConfiguration();
85     ASSERT_TRUE(gnssConfiguration_2_1.isOk() && gnssConfiguration_2_0.isOk() &&
86                 gnssConfiguration_1_1.isOk() && gnssConfiguration_1_0.isOk());
87     sp<IGnssConfiguration_2_1> iGnssConfig_2_1 = gnssConfiguration_2_1;
88     sp<IGnssConfiguration_2_0> iGnssConfig_2_0 = gnssConfiguration_2_0;
89     sp<IGnssConfiguration_1_1> iGnssConfig_1_1 = gnssConfiguration_1_1;
90     sp<IGnssConfiguration_1_0> iGnssConfig_1_0 = gnssConfiguration_1_0;
91     // At least one interface is non-null.
92     int numNonNull = (int)(iGnssConfig_2_1 != nullptr) + (int)(iGnssConfig_2_0 != nullptr) +
93                      (int)(iGnssConfig_1_1 != nullptr) + (int)(iGnssConfig_1_0 != nullptr);
94     ASSERT_TRUE(numNonNull >= 1);
95 }
96 
97 /*
98  * TestGnssMeasurementFields:
99  * Sets a GnssMeasurementCallback, waits for a measurement, and verifies
100  * 1. basebandCN0DbHz is valid
101  * 2. ISB fields are valid
102  */
TEST_P(GnssHalTest,TestGnssMeasurementFields)103 TEST_P(GnssHalTest, TestGnssMeasurementFields) {
104     const int kFirstGnssMeasurementTimeoutSeconds = 10;
105 
106     auto gnssMeasurement = gnss_hal_->getExtensionGnssMeasurement_2_1();
107     ASSERT_TRUE(gnssMeasurement.isOk());
108 
109     // Skip test if GnssMeasurement v2.1 is not supported
110     sp<IGnssMeasurement_2_1> iGnssMeasurement = gnssMeasurement;
111     if (iGnssMeasurement == nullptr) {
112         return;
113     }
114 
115     sp<GnssMeasurementCallback> callback = new GnssMeasurementCallback();
116     auto result = iGnssMeasurement->setCallback_2_1(callback, /* enableFullTracking= */ true);
117     ASSERT_TRUE(result.isOk());
118     EXPECT_EQ(result, IGnssMeasurement_1_0::GnssMeasurementStatus::SUCCESS);
119 
120     IGnssMeasurementCallback_2_1::GnssData lastMeasurement;
121     ASSERT_TRUE(callback->measurement_cbq_.retrieve(lastMeasurement,
122                                                     kFirstGnssMeasurementTimeoutSeconds));
123     EXPECT_EQ(callback->measurement_cbq_.calledCount(), 1);
124     ASSERT_TRUE(lastMeasurement.measurements.size() > 0);
125     for (auto measurement : lastMeasurement.measurements) {
126         // Verify basebandCn0DbHz is valid.
127         ASSERT_TRUE(measurement.basebandCN0DbHz > 0.0 && measurement.basebandCN0DbHz <= 65.0);
128 
129         if (((uint32_t)(measurement.flags & GnssMeasurementFlags::HAS_FULL_ISB) > 0) &&
130             ((uint32_t)(measurement.flags & GnssMeasurementFlags::HAS_FULL_ISB_UNCERTAINTY) > 0) &&
131             ((uint32_t)(measurement.flags & GnssMeasurementFlags::HAS_SATELLITE_ISB) > 0) &&
132             ((uint32_t)(measurement.flags & GnssMeasurementFlags::HAS_SATELLITE_ISB_UNCERTAINTY) >
133              0)) {
134             GnssConstellationType referenceConstellation =
135                     lastMeasurement.clock.referenceSignalTypeForIsb.constellation;
136             double carrierFrequencyHz =
137                     lastMeasurement.clock.referenceSignalTypeForIsb.carrierFrequencyHz;
138             std::string codeType = lastMeasurement.clock.referenceSignalTypeForIsb.codeType;
139 
140             ASSERT_TRUE(referenceConstellation >= GnssConstellationType::UNKNOWN &&
141                         referenceConstellation <= GnssConstellationType::IRNSS);
142             ASSERT_TRUE(carrierFrequencyHz > 0);
143             ASSERT_TRUE(codeType != "");
144 
145             ASSERT_TRUE(std::abs(measurement.fullInterSignalBiasNs) < 1.0e6);
146             ASSERT_TRUE(measurement.fullInterSignalBiasUncertaintyNs >= 0);
147             ASSERT_TRUE(std::abs(measurement.satelliteInterSignalBiasNs) < 1.0e6);
148             ASSERT_TRUE(measurement.satelliteInterSignalBiasUncertaintyNs >= 0);
149         }
150     }
151 
152     iGnssMeasurement->close();
153 }
154 
155 /*
156  * TestGnssAntennaInfo:
157  * Sets a GnssAntennaInfoCallback, waits for report, and verifies
158  * 1. phaseCenterOffsetCoordinateMillimeters is valid
159  * 2. phaseCenterOffsetCoordinateUncertaintyMillimeters is valid.
160  * PhaseCenterVariationCorrections and SignalGainCorrections are optional.
161  */
TEST_P(GnssHalTest,TestGnssAntennaInfo)162 TEST_P(GnssHalTest, TestGnssAntennaInfo) {
163     const int kAntennaInfoTimeoutSeconds = 2;
164 
165     auto gnssAntennaInfo = gnss_hal_->getExtensionGnssAntennaInfo();
166     ASSERT_TRUE(gnssAntennaInfo.isOk());
167 
168     // Skip test if GnssAntennaInfo v2.1 is not supported
169     sp<IGnssAntennaInfo> iGnssAntennaInfo = gnssAntennaInfo;
170     if (!(gnss_cb_->last_capabilities_ & IGnssCallback_2_1::Capabilities::ANTENNA_INFO) ||
171         iGnssAntennaInfo == nullptr) {
172         ALOGD("GnssAntennaInfo v2.1 is not supported.");
173         return;
174     }
175 
176     sp<GnssAntennaInfoCallback> callback = new GnssAntennaInfoCallback();
177     auto result = iGnssAntennaInfo->setCallback(callback);
178     ASSERT_TRUE(result.isOk());
179     EXPECT_EQ(result, IGnssAntennaInfo::GnssAntennaInfoStatus::SUCCESS);
180 
181     hidl_vec<IGnssAntennaInfoCallback::GnssAntennaInfo> antennaInfos;
182     ASSERT_TRUE(callback->antenna_info_cbq_.retrieve(antennaInfos, kAntennaInfoTimeoutSeconds));
183     EXPECT_EQ(callback->antenna_info_cbq_.calledCount(), 1);
184     ASSERT_TRUE(antennaInfos.size() > 0);
185 
186     for (auto antennaInfo : antennaInfos) {
187         // Remaining fields are optional
188         if (antennaInfo.phaseCenterVariationCorrectionMillimeters != NULL) {
189             int numRows = antennaInfo.phaseCenterVariationCorrectionMillimeters.size();
190             int numColumns = antennaInfo.phaseCenterVariationCorrectionMillimeters[0].row.size();
191             // Must have at least 1 row and 2 columns
192             ASSERT_TRUE(numRows >= 1 && numColumns >= 2);
193 
194             // Corrections and uncertainties must have same dimensions
195             ASSERT_TRUE(antennaInfo.phaseCenterVariationCorrectionMillimeters.size() ==
196                         antennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters.size());
197             ASSERT_TRUE(
198                     antennaInfo.phaseCenterVariationCorrectionMillimeters[0].row.size() ==
199                     antennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters[0].row.size());
200 
201             // Must be rectangular
202             for (auto row : antennaInfo.phaseCenterVariationCorrectionMillimeters) {
203                 ASSERT_TRUE(row.row.size() == numColumns);
204             }
205             for (auto row : antennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters) {
206                 ASSERT_TRUE(row.row.size() == numColumns);
207             }
208         }
209         if (antennaInfo.signalGainCorrectionDbi != NULL) {
210             int numRows = antennaInfo.signalGainCorrectionDbi.size();
211             int numColumns = antennaInfo.signalGainCorrectionUncertaintyDbi[0].row.size();
212             // Must have at least 1 row and 2 columns
213             ASSERT_TRUE(numRows >= 1 && numColumns >= 2);
214 
215             // Corrections and uncertainties must have same dimensions
216             ASSERT_TRUE(antennaInfo.signalGainCorrectionDbi.size() ==
217                         antennaInfo.signalGainCorrectionUncertaintyDbi.size());
218             ASSERT_TRUE(antennaInfo.signalGainCorrectionDbi[0].row.size() ==
219                         antennaInfo.signalGainCorrectionUncertaintyDbi[0].row.size());
220 
221             // Must be rectangular
222             for (auto row : antennaInfo.signalGainCorrectionDbi) {
223                 ASSERT_TRUE(row.row.size() == numColumns);
224             }
225             for (auto row : antennaInfo.signalGainCorrectionUncertaintyDbi) {
226                 ASSERT_TRUE(row.row.size() == numColumns);
227             }
228         }
229     }
230 
231     iGnssAntennaInfo->close();
232 }
233 
234 /*
235  * TestGnssSvInfoFields:
236  * Gets 1 location and a GnssSvInfo, and verifies
237  * 1. basebandCN0DbHz is valid.
238  */
TEST_P(GnssHalTest,TestGnssSvInfoFields)239 TEST_P(GnssHalTest, TestGnssSvInfoFields) {
240     gnss_cb_->location_cbq_.reset();
241     StartAndCheckFirstLocation();
242     int location_called_count = gnss_cb_->location_cbq_.calledCount();
243 
244     // Tolerate 1 less sv status to handle edge cases in reporting.
245     int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
246     EXPECT_GE(sv_info_list_cbq_size, 0);
247     ALOGD("Observed %d GnssSvStatus, while awaiting one location (%d received)",
248           sv_info_list_cbq_size, location_called_count);
249 
250     // Get the last sv_info_list
251     std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_vec_list;
252     gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec_list, sv_info_list_cbq_size, 1);
253     hidl_vec<IGnssCallback_2_1::GnssSvInfo> last_sv_info_list = sv_info_vec_list.back();
254 
255     bool nonZeroCn0Found = false;
256     for (auto sv_info : last_sv_info_list) {
257         ASSERT_TRUE(sv_info.basebandCN0DbHz >= 0.0 && sv_info.basebandCN0DbHz <= 65.0);
258         if (sv_info.basebandCN0DbHz > 0.0) {
259             nonZeroCn0Found = true;
260         }
261     }
262     // Assert at least one value is non-zero. Zero is ok in status as it's possibly
263     // reporting a searched but not found satellite.
264     ASSERT_TRUE(nonZeroCn0Found);
265     StopAndClearLocations();
266 }
267 
268 /*
269  * FindStrongFrequentNonGpsSource:
270  *
271  * Search through a GnssSvStatus list for the strongest non-GPS satellite observed enough times
272  *
273  * returns the strongest source,
274  *         or a source with constellation == UNKNOWN if none are found sufficient times
275  * TODO(skz): create a template for this to reduce code duplication of v2.1 and v2.0 since both
276  * are using vectors.
277  */
FindStrongFrequentNonGpsSource(const std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_list,const int min_observations)278 IGnssConfiguration::BlacklistedSource FindStrongFrequentNonGpsSource(
279         const std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_list,
280         const int min_observations) {
281     struct ComparableBlacklistedSource {
282         IGnssConfiguration::BlacklistedSource id;
283 
284         ComparableBlacklistedSource() {
285             id.constellation = GnssConstellationType::UNKNOWN;
286             id.svid = 0;
287         }
288 
289         bool operator<(const ComparableBlacklistedSource& compare) const {
290             return ((id.svid < compare.id.svid) || ((id.svid == compare.id.svid) &&
291                                                     (id.constellation < compare.id.constellation)));
292         }
293     };
294 
295     struct SignalCounts {
296         int observations;
297         float max_cn0_dbhz;
298     };
299 
300     std::map<ComparableBlacklistedSource, SignalCounts> mapSignals;
301 
302     for (const auto& sv_info_vec : sv_info_list) {
303         for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
304             const auto& gnss_sv = sv_info_vec[iSv];
305             if ((gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX) &&
306                 (gnss_sv.v2_0.constellation != GnssConstellationType::GPS)) {
307                 ComparableBlacklistedSource source;
308                 source.id.svid = gnss_sv.v2_0.v1_0.svid;
309                 source.id.constellation = gnss_sv.v2_0.constellation;
310 
311                 const auto& itSignal = mapSignals.find(source);
312                 if (itSignal == mapSignals.end()) {
313                     SignalCounts counts;
314                     counts.observations = 1;
315                     counts.max_cn0_dbhz = gnss_sv.v2_0.v1_0.cN0Dbhz;
316                     mapSignals.insert(
317                             std::pair<ComparableBlacklistedSource, SignalCounts>(source, counts));
318                 } else {
319                     itSignal->second.observations++;
320                     if (itSignal->second.max_cn0_dbhz < gnss_sv.v2_0.v1_0.cN0Dbhz) {
321                         itSignal->second.max_cn0_dbhz = gnss_sv.v2_0.v1_0.cN0Dbhz;
322                     }
323                 }
324             }
325         }
326     }
327 
328     float max_cn0_dbhz_with_sufficient_count = 0.;
329     int total_observation_count = 0;
330     int blacklisted_source_count_observation = 0;
331 
332     ComparableBlacklistedSource source_to_blacklist;  // initializes to zero = UNKNOWN constellation
333     for (auto const& pairSignal : mapSignals) {
334         total_observation_count += pairSignal.second.observations;
335         if ((pairSignal.second.observations >= min_observations) &&
336             (pairSignal.second.max_cn0_dbhz > max_cn0_dbhz_with_sufficient_count)) {
337             source_to_blacklist = pairSignal.first;
338             blacklisted_source_count_observation = pairSignal.second.observations;
339             max_cn0_dbhz_with_sufficient_count = pairSignal.second.max_cn0_dbhz;
340         }
341     }
342     ALOGD("Among %d observations, chose svid %d, constellation %d, "
343           "with %d observations at %.1f max CNo",
344           total_observation_count, source_to_blacklist.id.svid,
345           (int)source_to_blacklist.id.constellation, blacklisted_source_count_observation,
346           max_cn0_dbhz_with_sufficient_count);
347 
348     return source_to_blacklist.id;
349 }
350 
351 /*
352  * BlacklistIndividualSatellites:
353  *
354  * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
355  * GnssStatus for common satellites (strongest and one other.)
356  * 2a & b) Turns off location, and blacklists common satellites.
357  * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
358  * GnssStatus does not use those satellites.
359  * 4a & b) Turns off location, and send in empty blacklist.
360  * 5a) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
361  * GnssStatus does re-use at least the previously strongest satellite
362  * 5b) Retry a few times, in case GNSS search strategy takes a while to reacquire even the
363  * formerly strongest satellite
364  */
TEST_P(GnssHalTest,BlacklistIndividualSatellites)365 TEST_P(GnssHalTest, BlacklistIndividualSatellites) {
366     if (!(gnss_cb_->last_capabilities_ & IGnssCallback_2_1::Capabilities::SATELLITE_BLACKLIST)) {
367         ALOGI("Test BlacklistIndividualSatellites skipped. SATELLITE_BLACKLIST capability not "
368               "supported.");
369         return;
370     }
371 
372     const int kLocationsToAwait = 3;
373     const int kRetriesToUnBlacklist = 10;
374 
375     gnss_cb_->location_cbq_.reset();
376     StartAndCheckLocations(kLocationsToAwait);
377     int location_called_count = gnss_cb_->location_cbq_.calledCount();
378 
379     // Tolerate 1 less sv status to handle edge cases in reporting.
380     int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
381     EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
382     ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
383           sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
384 
385     /*
386      * Identify strongest SV seen at least kLocationsToAwait -1 times
387      * Why -1?  To avoid test flakiness in case of (plausible) slight flakiness in strongest signal
388      * observability (one epoch RF null)
389      */
390 
391     const int kGnssSvInfoListTimeout = 2;
392     std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_vec_list;
393     int count = gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec_list, sv_info_list_cbq_size,
394                                                      kGnssSvInfoListTimeout);
395 
396     ASSERT_EQ(count, sv_info_list_cbq_size);
397 
398     IGnssConfiguration::BlacklistedSource source_to_blacklist =
399             FindStrongFrequentNonGpsSource(sv_info_vec_list, kLocationsToAwait - 1);
400 
401     if (source_to_blacklist.constellation == GnssConstellationType::UNKNOWN) {
402         // Cannot find a non-GPS satellite. Let the test pass.
403         ALOGD("Cannot find a non-GPS satellite. Letting the test pass.");
404         return;
405     }
406 
407     // Stop locations, blacklist the common SV
408     StopAndClearLocations();
409 
410     auto gnss_configuration_hal_return = gnss_hal_->getExtensionGnssConfiguration_2_1();
411     ASSERT_TRUE(gnss_configuration_hal_return.isOk());
412     sp<IGnssConfiguration> gnss_configuration_hal = gnss_configuration_hal_return;
413     ASSERT_NE(gnss_configuration_hal, nullptr);
414 
415     hidl_vec<IGnssConfiguration::BlacklistedSource> sources;
416     sources.resize(1);
417     sources[0] = source_to_blacklist;
418 
419     auto result = gnss_configuration_hal->setBlacklist_2_1(sources);
420     ASSERT_TRUE(result.isOk());
421     EXPECT_TRUE(result);
422 
423     // retry and ensure satellite not used
424     gnss_cb_->sv_info_list_cbq_.reset();
425 
426     gnss_cb_->location_cbq_.reset();
427     StartAndCheckLocations(kLocationsToAwait);
428 
429     // early exit if test is being run with insufficient signal
430     location_called_count = gnss_cb_->location_cbq_.calledCount();
431     if (location_called_count == 0) {
432         ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
433     }
434     ASSERT_TRUE(location_called_count > 0);
435 
436     // Tolerate 1 less sv status to handle edge cases in reporting.
437     sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
438     EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
439     ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
440           sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
441     for (int i = 0; i < sv_info_list_cbq_size; ++i) {
442         hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
443         gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
444         for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
445             const auto& gnss_sv = sv_info_vec[iSv];
446             EXPECT_FALSE((gnss_sv.v2_0.v1_0.svid == source_to_blacklist.svid) &&
447                          (gnss_sv.v2_0.constellation == source_to_blacklist.constellation) &&
448                          (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
449         }
450     }
451 
452     // clear blacklist and restart - this time updating the blacklist while location is still on
453     sources.resize(0);
454 
455     result = gnss_configuration_hal->setBlacklist_2_1(sources);
456     ASSERT_TRUE(result.isOk());
457     EXPECT_TRUE(result);
458 
459     bool strongest_sv_is_reobserved = false;
460     // do several loops awaiting a few locations, allowing non-immediate reacquisition strategies
461     int unblacklist_loops_remaining = kRetriesToUnBlacklist;
462     while (!strongest_sv_is_reobserved && (unblacklist_loops_remaining-- > 0)) {
463         StopAndClearLocations();
464         gnss_cb_->sv_info_list_cbq_.reset();
465 
466         gnss_cb_->location_cbq_.reset();
467         StartAndCheckLocations(kLocationsToAwait);
468 
469         // early exit loop if test is being run with insufficient signal
470         location_called_count = gnss_cb_->location_cbq_.calledCount();
471         if (location_called_count == 0) {
472             ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
473         }
474         ASSERT_TRUE(location_called_count > 0);
475 
476         // Tolerate 1 less sv status to handle edge cases in reporting.
477         sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
478         EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
479         ALOGD("Clear blacklist, observed %d GnssSvInfo, while awaiting %d Locations"
480               ", tries remaining %d",
481               sv_info_list_cbq_size, kLocationsToAwait, unblacklist_loops_remaining);
482 
483         for (int i = 0; i < sv_info_list_cbq_size; ++i) {
484             hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
485             gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
486             for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
487                 const auto& gnss_sv = sv_info_vec[iSv];
488                 if ((gnss_sv.v2_0.v1_0.svid == source_to_blacklist.svid) &&
489                     (gnss_sv.v2_0.constellation == source_to_blacklist.constellation) &&
490                     (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX)) {
491                     strongest_sv_is_reobserved = true;
492                     break;
493                 }
494             }
495             if (strongest_sv_is_reobserved) break;
496         }
497     }
498     EXPECT_TRUE(strongest_sv_is_reobserved);
499     StopAndClearLocations();
500 }
501 
502 /*
503  * BlacklistConstellationLocationOff:
504  *
505  * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
506  * GnssStatus for any non-GPS constellations.
507  * 2a & b) Turns off location, and blacklist first non-GPS constellations.
508  * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
509  * GnssStatus does not use any constellation but GPS.
510  * 4a & b) Clean up by turning off location, and send in empty blacklist.
511  */
TEST_P(GnssHalTest,BlacklistConstellationLocationOff)512 TEST_P(GnssHalTest, BlacklistConstellationLocationOff) {
513     if (!(gnss_cb_->last_capabilities_ & IGnssCallback_2_1::Capabilities::SATELLITE_BLACKLIST)) {
514         ALOGI("Test BlacklistConstellationLocationOff skipped. SATELLITE_BLACKLIST capability not "
515               "supported.");
516         return;
517     }
518 
519     const int kLocationsToAwait = 3;
520     const int kGnssSvInfoListTimeout = 2;
521 
522     // Find first non-GPS constellation to blacklist
523     GnssConstellationType constellation_to_blacklist =
524             startLocationAndGetNonGpsConstellation(kLocationsToAwait, kGnssSvInfoListTimeout);
525 
526     // Turns off location
527     StopAndClearLocations();
528 
529     IGnssConfiguration::BlacklistedSource source_to_blacklist_1;
530     source_to_blacklist_1.constellation = constellation_to_blacklist;
531     source_to_blacklist_1.svid = 0;  // documented wildcard for all satellites in this constellation
532 
533     // IRNSS was added in 2.0. Always attempt to blacklist IRNSS to verify that the new enum is
534     // supported.
535     IGnssConfiguration::BlacklistedSource source_to_blacklist_2;
536     source_to_blacklist_2.constellation = GnssConstellationType::IRNSS;
537     source_to_blacklist_2.svid = 0;  // documented wildcard for all satellites in this constellation
538 
539     auto gnss_configuration_hal_return = gnss_hal_->getExtensionGnssConfiguration_2_1();
540     ASSERT_TRUE(gnss_configuration_hal_return.isOk());
541     sp<IGnssConfiguration> gnss_configuration_hal = gnss_configuration_hal_return;
542     ASSERT_NE(gnss_configuration_hal, nullptr);
543 
544     hidl_vec<IGnssConfiguration::BlacklistedSource> sources;
545     sources.resize(2);
546     sources[0] = source_to_blacklist_1;
547     sources[1] = source_to_blacklist_2;
548 
549     auto result = gnss_configuration_hal->setBlacklist_2_1(sources);
550     ASSERT_TRUE(result.isOk());
551     EXPECT_TRUE(result);
552 
553     // retry and ensure constellation not used
554     gnss_cb_->sv_info_list_cbq_.reset();
555 
556     gnss_cb_->location_cbq_.reset();
557     StartAndCheckLocations(kLocationsToAwait);
558 
559     // Tolerate 1 less sv status to handle edge cases in reporting.
560     int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
561     EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
562     ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations", sv_info_list_cbq_size,
563           kLocationsToAwait);
564     for (int i = 0; i < sv_info_list_cbq_size; ++i) {
565         hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
566         gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
567         for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
568             const auto& gnss_sv = sv_info_vec[iSv];
569             EXPECT_FALSE((gnss_sv.v2_0.constellation == source_to_blacklist_1.constellation) &&
570                          (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
571             EXPECT_FALSE((gnss_sv.v2_0.constellation == source_to_blacklist_2.constellation) &&
572                          (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
573         }
574     }
575 
576     // clean up
577     StopAndClearLocations();
578     sources.resize(0);
579     result = gnss_configuration_hal->setBlacklist_2_1(sources);
580     ASSERT_TRUE(result.isOk());
581     EXPECT_TRUE(result);
582 }
583 
584 /*
585  * BlacklistConstellationLocationOn:
586  *
587  * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
588  * GnssStatus for any non-GPS constellations.
589  * 2a & b) Blacklist first non-GPS constellation, and turn off location.
590  * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
591  * GnssStatus does not use any constellation but GPS.
592  * 4a & b) Clean up by turning off location, and send in empty blacklist.
593  */
TEST_P(GnssHalTest,BlacklistConstellationLocationOn)594 TEST_P(GnssHalTest, BlacklistConstellationLocationOn) {
595     if (!(gnss_cb_->last_capabilities_ & IGnssCallback_2_1::Capabilities::SATELLITE_BLACKLIST)) {
596         ALOGI("Test BlacklistConstellationLocationOn skipped. SATELLITE_BLACKLIST capability not "
597               "supported.");
598         return;
599     }
600 
601     const int kLocationsToAwait = 3;
602     const int kGnssSvInfoListTimeout = 2;
603 
604     // Find first non-GPS constellation to blacklist
605     GnssConstellationType constellation_to_blacklist =
606             startLocationAndGetNonGpsConstellation(kLocationsToAwait, kGnssSvInfoListTimeout);
607 
608     IGnssConfiguration::BlacklistedSource source_to_blacklist_1;
609     source_to_blacklist_1.constellation = constellation_to_blacklist;
610     source_to_blacklist_1.svid = 0;  // documented wildcard for all satellites in this constellation
611 
612     // IRNSS was added in 2.0. Always attempt to blacklist IRNSS to verify that the new enum is
613     // supported.
614     IGnssConfiguration::BlacklistedSource source_to_blacklist_2;
615     source_to_blacklist_2.constellation = GnssConstellationType::IRNSS;
616     source_to_blacklist_2.svid = 0;  // documented wildcard for all satellites in this constellation
617 
618     auto gnss_configuration_hal_return = gnss_hal_->getExtensionGnssConfiguration_2_1();
619     ASSERT_TRUE(gnss_configuration_hal_return.isOk());
620     sp<IGnssConfiguration> gnss_configuration_hal = gnss_configuration_hal_return;
621     ASSERT_NE(gnss_configuration_hal, nullptr);
622 
623     hidl_vec<IGnssConfiguration::BlacklistedSource> sources;
624     sources.resize(2);
625     sources[0] = source_to_blacklist_1;
626     sources[1] = source_to_blacklist_2;
627 
628     auto result = gnss_configuration_hal->setBlacklist_2_1(sources);
629     ASSERT_TRUE(result.isOk());
630     EXPECT_TRUE(result);
631 
632     // Turns off location
633     StopAndClearLocations();
634 
635     // retry and ensure constellation not used
636     gnss_cb_->sv_info_list_cbq_.reset();
637 
638     gnss_cb_->location_cbq_.reset();
639     StartAndCheckLocations(kLocationsToAwait);
640 
641     // Tolerate 1 less sv status to handle edge cases in reporting.
642     int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
643     EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
644     ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations", sv_info_list_cbq_size,
645           kLocationsToAwait);
646     for (int i = 0; i < sv_info_list_cbq_size; ++i) {
647         hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
648         gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
649         for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
650             const auto& gnss_sv = sv_info_vec[iSv];
651             EXPECT_FALSE((gnss_sv.v2_0.constellation == source_to_blacklist_1.constellation) &&
652                          (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
653             EXPECT_FALSE((gnss_sv.v2_0.constellation == source_to_blacklist_2.constellation) &&
654                          (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
655         }
656     }
657 
658     // clean up
659     StopAndClearLocations();
660     sources.resize(0);
661     result = gnss_configuration_hal->setBlacklist_2_1(sources);
662     ASSERT_TRUE(result.isOk());
663     EXPECT_TRUE(result);
664 }
665 
666 /*
667  * TestGnssMeasurementCorrections:
668  * If measurement corrections capability is supported, verifies that it supports the
669  * gnss.measurement_corrections@1.1::IMeasurementCorrections interface by invoking a method.
670  */
TEST_P(GnssHalTest,TestGnssMeasurementCorrections)671 TEST_P(GnssHalTest, TestGnssMeasurementCorrections) {
672     if (!(gnss_cb_->last_capabilities_ &
673           IGnssCallback_2_1::Capabilities::MEASUREMENT_CORRECTIONS)) {
674         return;
675     }
676 
677     // Verify IMeasurementCorrections is supported.
678     auto measurementCorrections = gnss_hal_->getExtensionMeasurementCorrections_1_1();
679     ASSERT_TRUE(measurementCorrections.isOk());
680     sp<IMeasurementCorrections_1_1> iMeasurementCorrections = measurementCorrections;
681     ASSERT_NE(iMeasurementCorrections, nullptr);
682 
683     sp<GnssMeasurementCorrectionsCallback> callback = new GnssMeasurementCorrectionsCallback();
684     iMeasurementCorrections->setCallback(callback);
685 
686     const int kMeasurementCorrectionsCapabilitiesTimeoutSeconds = 5;
687     callback->capabilities_cbq_.retrieve(callback->last_capabilities_,
688                                          kMeasurementCorrectionsCapabilitiesTimeoutSeconds);
689     ASSERT_TRUE(callback->capabilities_cbq_.calledCount() > 0);
690 
691     // Set a mock MeasurementCorrections.
692     auto result =
693             iMeasurementCorrections->setCorrections_1_1(Utils::getMockMeasurementCorrections_1_1());
694     ASSERT_TRUE(result.isOk());
695     EXPECT_TRUE(result);
696 }
697