1 /*
2  * Copyright (C) 2020 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 <android/hardware/gnss/IAGnss.h>
20 #include <android/hardware/gnss/IGnss.h>
21 #include <android/hardware/gnss/IGnssAntennaInfo.h>
22 #include <android/hardware/gnss/IGnssBatching.h>
23 #include <android/hardware/gnss/IGnssDebug.h>
24 #include <android/hardware/gnss/IGnssMeasurementCallback.h>
25 #include <android/hardware/gnss/IGnssMeasurementInterface.h>
26 #include <android/hardware/gnss/IGnssPowerIndication.h>
27 #include <android/hardware/gnss/IGnssPsds.h>
28 #include <android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.h>
29 #include <android/hardware/gnss/visibility_control/IGnssVisibilityControl.h>
30 #include <cutils/properties.h>
31 #include <utils/SystemClock.h>
32 #include <cmath>
33 #include <utility>
34 #include "AGnssCallbackAidl.h"
35 #include "AGnssRilCallbackAidl.h"
36 #include "GnssAntennaInfoCallbackAidl.h"
37 #include "GnssBatchingCallback.h"
38 #include "GnssGeofenceCallback.h"
39 #include "GnssMeasurementCallbackAidl.h"
40 #include "GnssNavigationMessageCallback.h"
41 #include "GnssPowerIndicationCallback.h"
42 #include "GnssVisibilityControlCallback.h"
43 #include "MeasurementCorrectionsCallback.h"
44 #include "Utils.h"
45 #include "gnss_hal_test.h"
46 
47 using android::sp;
48 using android::hardware::gnss::BlocklistedSource;
49 using android::hardware::gnss::ElapsedRealtime;
50 using android::hardware::gnss::GnssClock;
51 using android::hardware::gnss::GnssConstellationType;
52 using android::hardware::gnss::GnssData;
53 using android::hardware::gnss::GnssLocation;
54 using android::hardware::gnss::GnssMeasurement;
55 using android::hardware::gnss::GnssPowerStats;
56 using android::hardware::gnss::IAGnss;
57 using android::hardware::gnss::IAGnssRil;
58 using android::hardware::gnss::IGnss;
59 using android::hardware::gnss::IGnssAntennaInfo;
60 using android::hardware::gnss::IGnssAntennaInfoCallback;
61 using android::hardware::gnss::IGnssBatching;
62 using android::hardware::gnss::IGnssBatchingCallback;
63 using android::hardware::gnss::IGnssCallback;
64 using android::hardware::gnss::IGnssConfiguration;
65 using android::hardware::gnss::IGnssDebug;
66 using android::hardware::gnss::IGnssGeofence;
67 using android::hardware::gnss::IGnssGeofenceCallback;
68 using android::hardware::gnss::IGnssMeasurementCallback;
69 using android::hardware::gnss::IGnssMeasurementInterface;
70 using android::hardware::gnss::IGnssNavigationMessageInterface;
71 using android::hardware::gnss::IGnssPowerIndication;
72 using android::hardware::gnss::IGnssPsds;
73 using android::hardware::gnss::PsdsType;
74 using android::hardware::gnss::SatellitePvt;
75 using android::hardware::gnss::common::Utils;
76 using android::hardware::gnss::measurement_corrections::IMeasurementCorrectionsInterface;
77 using android::hardware::gnss::visibility_control::IGnssVisibilityControl;
78 
79 using GnssConstellationTypeV2_0 = android::hardware::gnss::V2_0::GnssConstellationType;
80 
IsAutomotiveDevice()81 static bool IsAutomotiveDevice() {
82     char buffer[PROPERTY_VALUE_MAX] = {0};
83     property_get("ro.hardware.type", buffer, "");
84     return strncmp(buffer, "automotive", PROPERTY_VALUE_MAX) == 0;
85 }
86 
87 /*
88  * SetupTeardownCreateCleanup:
89  * Requests the gnss HAL then calls cleanup
90  *
91  * Empty test fixture to verify basic Setup & Teardown
92  */
TEST_P(GnssHalTest,SetupTeardownCreateCleanup)93 TEST_P(GnssHalTest, SetupTeardownCreateCleanup) {}
94 
95 /*
96  * GetLocation:
97  * Turns on location, waits 75 second for at least 5 locations,
98  * and checks them for reasonable validity.
99  */
TEST_P(GnssHalTest,GetLocations)100 TEST_P(GnssHalTest, GetLocations) {
101     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
102         return;
103     }
104     const int kMinIntervalMsec = 500;
105     const int kLocationsToCheck = 5;
106 
107     SetPositionMode(kMinIntervalMsec, /* low_power_mode= */ false);
108     StartAndCheckLocations(kLocationsToCheck);
109     StopAndClearLocations();
110 }
111 
112 /*
113  * InjectDelete:
114  * Ensures that calls to inject and/or delete information state are handled.
115  */
TEST_P(GnssHalTest,InjectDelete)116 TEST_P(GnssHalTest, InjectDelete) {
117     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
118         return;
119     }
120     // Confidently, well north of Alaska
121     auto status = aidl_gnss_hal_->injectLocation(Utils::getMockLocation(80.0, -170.0, 150.0));
122     ASSERT_TRUE(status.isOk());
123 
124     // Fake time, but generally reasonable values (time in Aug. 2018)
125     status =
126             aidl_gnss_hal_->injectTime(/* timeMs= */ 1534567890123L,
127                                        /* timeReferenceMs= */ 123456L, /* uncertaintyMs= */ 10000L);
128     ASSERT_TRUE(status.isOk());
129 
130     status = aidl_gnss_hal_->deleteAidingData(IGnss::GnssAidingData::POSITION);
131     ASSERT_TRUE(status.isOk());
132 
133     status = aidl_gnss_hal_->deleteAidingData(IGnss::GnssAidingData::TIME);
134     ASSERT_TRUE(status.isOk());
135 
136     // Ensure we can get a good location after a bad injection has been deleted
137     StartAndCheckFirstLocation(/* min_interval_msec= */ 1000, /* low_power_mode= */ false);
138     StopAndClearLocations();
139 }
140 
141 /*
142  * InjectSeedLocation:
143  * Injects a seed location and ensures the injected seed location is not fused in the resulting
144  * GNSS location.
145  */
TEST_P(GnssHalTest,InjectSeedLocation)146 TEST_P(GnssHalTest, InjectSeedLocation) {
147     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
148         return;
149     }
150     // An arbitrary position in North Pacific Ocean (where no VTS labs will ever likely be located).
151     const double seedLatDegrees = 32.312894;
152     const double seedLngDegrees = -172.954117;
153     const float seedAccuracyMeters = 150.0;
154 
155     auto status = aidl_gnss_hal_->injectLocation(
156             Utils::getMockLocation(seedLatDegrees, seedLngDegrees, seedAccuracyMeters));
157     ASSERT_TRUE(status.isOk());
158 
159     StartAndCheckFirstLocation(/* min_interval_msec= */ 1000, /* low_power_mode= */ false);
160 
161     // Ensure we don't get a location anywhere within 111km (1 degree of lat or lng) of the seed
162     // location.
163     EXPECT_TRUE(std::abs(aidl_gnss_cb_->last_location_.latitudeDegrees - seedLatDegrees) > 1.0 ||
164                 std::abs(aidl_gnss_cb_->last_location_.longitudeDegrees - seedLngDegrees) > 1.0);
165 
166     StopAndClearLocations();
167 
168     status = aidl_gnss_hal_->deleteAidingData(IGnss::GnssAidingData::POSITION);
169     ASSERT_TRUE(status.isOk());
170 }
171 
172 /*
173  * GnssCapabilities:
174  * 1. Verifies that GNSS hardware supports measurement capabilities.
175  * 2. Verifies that GNSS hardware supports Scheduling capabilities.
176  * 3. Verifies that GNSS hardware supports non-empty signal type capabilities.
177  */
TEST_P(GnssHalTest,GnssCapabilites)178 TEST_P(GnssHalTest, GnssCapabilites) {
179     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
180         return;
181     }
182     if (!IsAutomotiveDevice()) {
183         EXPECT_TRUE(aidl_gnss_cb_->last_capabilities_ & IGnssCallback::CAPABILITY_MEASUREMENTS);
184     }
185     EXPECT_TRUE(aidl_gnss_cb_->last_capabilities_ & IGnssCallback::CAPABILITY_SCHEDULING);
186     if (aidl_gnss_hal_->getInterfaceVersion() <= 2) {
187         return;
188     }
189     EXPECT_FALSE(aidl_gnss_cb_->last_signal_type_capabilities.empty());
190 }
191 
192 /*
193  * GetLocationLowPower:
194  * Turns on location, waits for at least 5 locations allowing max of LOCATION_TIMEOUT_SUBSEQUENT_SEC
195  * between one location and the next. Also ensure that MIN_INTERVAL_MSEC is respected by waiting
196  * NO_LOCATION_PERIOD_SEC and verfiy that no location is received. Also perform validity checks on
197  * each received location.
198  */
TEST_P(GnssHalTest,GetLocationLowPower)199 TEST_P(GnssHalTest, GetLocationLowPower) {
200     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
201         return;
202     }
203 
204     const int kMinIntervalMsec = 5000;
205     const int kLocationTimeoutSubsequentSec = (kMinIntervalMsec / 1000) * 2;
206     const int kNoLocationPeriodSec = (kMinIntervalMsec / 1000) / 2;
207     const int kLocationsToCheck = 5;
208     const bool kLowPowerMode = true;
209 
210     // Warmup period - VTS doesn't have AGPS access via GnssLocationProvider
211     aidl_gnss_cb_->location_cbq_.reset();
212     StartAndCheckLocations(kLocationsToCheck);
213     StopAndClearLocations();
214     aidl_gnss_cb_->location_cbq_.reset();
215 
216     // Start of Low Power Mode test
217     // Don't expect true - as without AGPS access
218     if (!StartAndCheckFirstLocation(kMinIntervalMsec, kLowPowerMode)) {
219         ALOGW("GetLocationLowPower test - no first low power location received.");
220     }
221 
222     for (int i = 1; i < kLocationsToCheck; i++) {
223         // Verify that kMinIntervalMsec is respected by waiting kNoLocationPeriodSec and
224         // ensure that no location is received yet
225 
226         aidl_gnss_cb_->location_cbq_.retrieve(aidl_gnss_cb_->last_location_, kNoLocationPeriodSec);
227         const int location_called_count = aidl_gnss_cb_->location_cbq_.calledCount();
228         // Tolerate (ignore) one extra location right after the first one
229         // to handle startup edge case scheduling limitations in some implementations
230         if ((i == 1) && (location_called_count == 2)) {
231             CheckLocation(aidl_gnss_cb_->last_location_, true);
232             continue;  // restart the quiet wait period after this too-fast location
233         }
234         EXPECT_LE(location_called_count, i);
235         if (location_called_count != i) {
236             ALOGW("GetLocationLowPower test - not enough locations received. %d vs. %d expected ",
237                   location_called_count, i);
238         }
239 
240         if (!aidl_gnss_cb_->location_cbq_.retrieve(
241                     aidl_gnss_cb_->last_location_,
242                     kLocationTimeoutSubsequentSec - kNoLocationPeriodSec)) {
243             ALOGW("GetLocationLowPower test - timeout awaiting location %d", i);
244         } else {
245             CheckLocation(aidl_gnss_cb_->last_location_, true);
246         }
247     }
248 
249     StopAndClearLocations();
250 }
251 
252 /*
253  * InjectBestLocation
254  *
255  * Ensure successfully injecting a location.
256  */
TEST_P(GnssHalTest,InjectBestLocation)257 TEST_P(GnssHalTest, InjectBestLocation) {
258     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
259         return;
260     }
261     StartAndCheckLocations(1);
262     GnssLocation gnssLocation = aidl_gnss_cb_->last_location_;
263     CheckLocation(gnssLocation, true);
264 
265     auto status = aidl_gnss_hal_->injectBestLocation(gnssLocation);
266 
267     ASSERT_TRUE(status.isOk());
268 
269     status = aidl_gnss_hal_->deleteAidingData(IGnss::GnssAidingData::POSITION);
270 
271     ASSERT_TRUE(status.isOk());
272 }
273 
274 /*
275  * TestGnssSvInfoFields:
276  * Gets 1 location and a (non-empty) GnssSvInfo, and verifies basebandCN0DbHz is valid.
277  */
TEST_P(GnssHalTest,TestGnssSvInfoFields)278 TEST_P(GnssHalTest, TestGnssSvInfoFields) {
279     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
280         return;
281     }
282     aidl_gnss_cb_->location_cbq_.reset();
283     aidl_gnss_cb_->sv_info_list_cbq_.reset();
284     StartAndCheckFirstLocation(/* min_interval_msec= */ 1000, /* low_power_mode= */ false);
285     int location_called_count = aidl_gnss_cb_->location_cbq_.calledCount();
286     ALOGD("Observed %d GnssSvStatus, while awaiting one location (%d received)",
287           aidl_gnss_cb_->sv_info_list_cbq_.size(), location_called_count);
288 
289     // Wait for up to kNumSvInfoLists events for kTimeoutSeconds for each event.
290     int kTimeoutSeconds = 2;
291     int kNumSvInfoLists = 4;
292     std::list<std::vector<IGnssCallback::GnssSvInfo>> sv_info_lists;
293     std::vector<IGnssCallback::GnssSvInfo> last_sv_info_list;
294 
295     do {
296         EXPECT_GT(aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_lists, kNumSvInfoLists,
297                                                             kTimeoutSeconds),
298                   0);
299         if (!sv_info_lists.empty()) {
300             last_sv_info_list = sv_info_lists.back();
301             ALOGD("last_sv_info size = %d", (int)last_sv_info_list.size());
302         }
303     } while (!sv_info_lists.empty() && last_sv_info_list.size() == 0);
304 
305     bool nonZeroCn0Found = false;
306     for (auto sv_info : last_sv_info_list) {
307         EXPECT_TRUE(sv_info.basebandCN0DbHz >= 0.0 && sv_info.basebandCN0DbHz <= 65.0);
308         if (sv_info.basebandCN0DbHz > 0.0) {
309             nonZeroCn0Found = true;
310         }
311     }
312     // Assert at least one value is non-zero. Zero is ok in status as it's possibly
313     // reporting a searched but not found satellite.
314     EXPECT_TRUE(nonZeroCn0Found);
315     StopAndClearLocations();
316 }
317 
318 /*
319  * TestPsdsExtension:
320  * 1. Gets the PsdsExtension
321  * 2. Injects empty PSDS data and verifies that it returns an error.
322  */
TEST_P(GnssHalTest,TestPsdsExtension)323 TEST_P(GnssHalTest, TestPsdsExtension) {
324     sp<IGnssPsds> iGnssPsds;
325     auto status = aidl_gnss_hal_->getExtensionPsds(&iGnssPsds);
326     if (status.isOk() && iGnssPsds != nullptr) {
327         status = iGnssPsds->injectPsdsData(PsdsType::LONG_TERM, std::vector<uint8_t>());
328         ASSERT_FALSE(status.isOk());
329     }
330 }
331 
CheckSatellitePvt(const SatellitePvt & satellitePvt,const int interfaceVersion)332 void CheckSatellitePvt(const SatellitePvt& satellitePvt, const int interfaceVersion) {
333     const double kMaxOrbitRadiusMeters = 43000000.0;
334     const double kMaxVelocityMps = 4000.0;
335     // The below values are determined using GPS ICD Table 20-1
336     const double kMinHardwareCodeBiasMeters = -17.869;
337     const double kMaxHardwareCodeBiasMeters = 17.729;
338     const double kMaxTimeCorrelationMeters = 3e6;
339     const double kMaxSatClkDriftMps = 1.117;
340 
341     ASSERT_TRUE(satellitePvt.flags & SatellitePvt::HAS_POSITION_VELOCITY_CLOCK_INFO ||
342                 satellitePvt.flags & SatellitePvt::HAS_IONO ||
343                 satellitePvt.flags & SatellitePvt::HAS_TROPO);
344     if (satellitePvt.flags & SatellitePvt::HAS_POSITION_VELOCITY_CLOCK_INFO) {
345         ALOGD("Found HAS_POSITION_VELOCITY_CLOCK_INFO");
346         ASSERT_TRUE(satellitePvt.satPosEcef.posXMeters >= -kMaxOrbitRadiusMeters &&
347                     satellitePvt.satPosEcef.posXMeters <= kMaxOrbitRadiusMeters);
348         ASSERT_TRUE(satellitePvt.satPosEcef.posYMeters >= -kMaxOrbitRadiusMeters &&
349                     satellitePvt.satPosEcef.posYMeters <= kMaxOrbitRadiusMeters);
350         ASSERT_TRUE(satellitePvt.satPosEcef.posZMeters >= -kMaxOrbitRadiusMeters &&
351                     satellitePvt.satPosEcef.posZMeters <= kMaxOrbitRadiusMeters);
352         ASSERT_TRUE(satellitePvt.satPosEcef.ureMeters > 0);
353         ASSERT_TRUE(satellitePvt.satVelEcef.velXMps >= -kMaxVelocityMps &&
354                     satellitePvt.satVelEcef.velXMps <= kMaxVelocityMps);
355         ASSERT_TRUE(satellitePvt.satVelEcef.velYMps >= -kMaxVelocityMps &&
356                     satellitePvt.satVelEcef.velYMps <= kMaxVelocityMps);
357         ASSERT_TRUE(satellitePvt.satVelEcef.velZMps >= -kMaxVelocityMps &&
358                     satellitePvt.satVelEcef.velZMps <= kMaxVelocityMps);
359         ASSERT_TRUE(satellitePvt.satVelEcef.ureRateMps > 0);
360         ASSERT_TRUE(
361                 satellitePvt.satClockInfo.satHardwareCodeBiasMeters > kMinHardwareCodeBiasMeters &&
362                 satellitePvt.satClockInfo.satHardwareCodeBiasMeters < kMaxHardwareCodeBiasMeters);
363         ASSERT_TRUE(satellitePvt.satClockInfo.satTimeCorrectionMeters >
364                             -kMaxTimeCorrelationMeters &&
365                     satellitePvt.satClockInfo.satTimeCorrectionMeters < kMaxTimeCorrelationMeters);
366         ASSERT_TRUE(satellitePvt.satClockInfo.satClkDriftMps > -kMaxSatClkDriftMps &&
367                     satellitePvt.satClockInfo.satClkDriftMps < kMaxSatClkDriftMps);
368     }
369     if (satellitePvt.flags & SatellitePvt::HAS_IONO) {
370         ALOGD("Found HAS_IONO");
371         ASSERT_TRUE(satellitePvt.ionoDelayMeters > 0 && satellitePvt.ionoDelayMeters < 100);
372     }
373     if (satellitePvt.flags & SatellitePvt::HAS_TROPO) {
374         ALOGD("Found HAS_TROPO");
375         ASSERT_TRUE(satellitePvt.tropoDelayMeters > 0 && satellitePvt.tropoDelayMeters < 100);
376     }
377     if (interfaceVersion >= 2) {
378         ASSERT_TRUE(satellitePvt.timeOfClockSeconds >= 0);
379         ASSERT_TRUE(satellitePvt.timeOfEphemerisSeconds >= 0);
380         // IODC has 10 bits
381         ASSERT_TRUE(satellitePvt.issueOfDataClock >= 0 && satellitePvt.issueOfDataClock <= 1023);
382         // IODE has 8 bits
383         ASSERT_TRUE(satellitePvt.issueOfDataEphemeris >= 0 &&
384                     satellitePvt.issueOfDataEphemeris <= 255);
385     }
386 }
387 
388 /*
389  * TestGnssMeasurementExtensionAndSatellitePvt:
390  * 1. Gets the GnssMeasurementExtension and verifies that it returns a non-null extension.
391  * 2. Sets a GnssMeasurementCallback, waits for a measurement, and verifies mandatory fields are
392  *    valid.
393  * 3. If SatellitePvt is supported, waits for a measurement with SatellitePvt, and verifies the
394  *    fields are valid.
395  */
TEST_P(GnssHalTest,TestGnssMeasurementExtensionAndSatellitePvt)396 TEST_P(GnssHalTest, TestGnssMeasurementExtensionAndSatellitePvt) {
397     const bool kIsSatellitePvtSupported =
398             aidl_gnss_cb_->last_capabilities_ & (int)GnssCallbackAidl::CAPABILITY_SATELLITE_PVT;
399     ALOGD("SatellitePvt supported: %s", kIsSatellitePvtSupported ? "true" : "false");
400     const int kFirstGnssMeasurementTimeoutSeconds = 10;
401     const int kNumMeasurementEvents = 75;
402 
403     sp<IGnssMeasurementInterface> iGnssMeasurement;
404     auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
405     ASSERT_TRUE(status.isOk());
406     ASSERT_TRUE(iGnssMeasurement != nullptr);
407 
408     auto callback = sp<GnssMeasurementCallbackAidl>::make();
409     status = iGnssMeasurement->setCallback(callback, /* enableFullTracking= */ true,
410                                            /* enableCorrVecOutputs */ false);
411     ASSERT_TRUE(status.isOk());
412 
413     bool satellitePvtFound = false;
414     for (int i = 0; i < kNumMeasurementEvents; i++) {
415         if (i > 0 && (!kIsSatellitePvtSupported || satellitePvtFound)) {
416             break;
417         }
418         GnssData lastMeasurement;
419         ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastMeasurement,
420                                                       kFirstGnssMeasurementTimeoutSeconds));
421         EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), i + 1);
422         ASSERT_TRUE(lastMeasurement.measurements.size() > 0);
423 
424         // Validity check GnssData fields
425         checkGnssMeasurementClockFields(lastMeasurement);
426 
427         for (const auto& measurement : lastMeasurement.measurements) {
428             checkGnssMeasurementFields(measurement, lastMeasurement);
429             if (measurement.flags & GnssMeasurement::HAS_SATELLITE_PVT &&
430                 kIsSatellitePvtSupported == true) {
431                 ALOGD("Found a measurement with SatellitePvt");
432                 satellitePvtFound = true;
433                 CheckSatellitePvt(measurement.satellitePvt, aidl_gnss_hal_->getInterfaceVersion());
434             }
435         }
436     }
437     if (kIsSatellitePvtSupported) {
438         ASSERT_TRUE(satellitePvtFound);
439     }
440 
441     status = iGnssMeasurement->close();
442     ASSERT_TRUE(status.isOk());
443 }
444 
445 /*
446  * TestCorrelationVector:
447  * 1. Gets the GnssMeasurementExtension and verifies that it returns a non-null extension.
448  * 2. Sets a GnssMeasurementCallback, waits for GnssMeasurements with CorrelationVector, and
449  *    verifies fields are valid.
450  */
TEST_P(GnssHalTest,TestCorrelationVector)451 TEST_P(GnssHalTest, TestCorrelationVector) {
452     const bool kIsCorrelationVectorSupported = aidl_gnss_cb_->last_capabilities_ &
453                                                (int)GnssCallbackAidl::CAPABILITY_CORRELATION_VECTOR;
454     const int kNumMeasurementEvents = 75;
455     // Pass the test if CorrelationVector is not supported
456     if (!kIsCorrelationVectorSupported) {
457         return;
458     }
459 
460     const int kFirstGnssMeasurementTimeoutSeconds = 10;
461     sp<IGnssMeasurementInterface> iGnssMeasurement;
462     auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
463     ASSERT_TRUE(status.isOk());
464     ASSERT_TRUE(iGnssMeasurement != nullptr);
465 
466     auto callback = sp<GnssMeasurementCallbackAidl>::make();
467     status =
468             iGnssMeasurement->setCallback(callback, /* enableFullTracking= */ true,
469                                           /* enableCorrVecOutputs */ kIsCorrelationVectorSupported);
470     ASSERT_TRUE(status.isOk());
471 
472     bool correlationVectorFound = false;
473     for (int i = 0; i < kNumMeasurementEvents; i++) {
474         // Pass the test if at least one CorrelationVector has been found.
475         if (correlationVectorFound) {
476             break;
477         }
478         GnssData lastMeasurement;
479         ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastMeasurement,
480                                                       kFirstGnssMeasurementTimeoutSeconds));
481         EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), i + 1);
482         ASSERT_TRUE(lastMeasurement.measurements.size() > 0);
483 
484         // Validity check GnssData fields
485         checkGnssMeasurementClockFields(lastMeasurement);
486 
487         for (const auto& measurement : lastMeasurement.measurements) {
488             checkGnssMeasurementFields(measurement, lastMeasurement);
489             if (measurement.flags & GnssMeasurement::HAS_CORRELATION_VECTOR) {
490                 correlationVectorFound = true;
491                 ASSERT_TRUE(measurement.correlationVectors.size() > 0);
492                 for (const auto& correlationVector : measurement.correlationVectors) {
493                     ASSERT_GE(correlationVector.frequencyOffsetMps, 0);
494                     ASSERT_GT(correlationVector.samplingWidthM, 0);
495                     ASSERT_TRUE(correlationVector.magnitude.size() > 0);
496                     for (const auto& magnitude : correlationVector.magnitude) {
497                         ASSERT_TRUE(magnitude >= -32768 && magnitude <= 32767);
498                     }
499                 }
500             }
501         }
502     }
503     ASSERT_TRUE(correlationVectorFound);
504 
505     status = iGnssMeasurement->close();
506     ASSERT_TRUE(status.isOk());
507 }
508 
509 /*
510  * TestGnssPowerIndication
511  * 1. Gets the GnssPowerIndicationExtension.
512  * 2. Sets a GnssPowerIndicationCallback.
513  * 3. Requests and verifies the 1st GnssPowerStats is received.
514  * 4. Gets a location.
515  * 5. Requests the 2nd GnssPowerStats, and verifies it has larger values than the 1st one.
516  */
TEST_P(GnssHalTest,TestGnssPowerIndication)517 TEST_P(GnssHalTest, TestGnssPowerIndication) {
518     // Set up gnssPowerIndication and callback
519     sp<IGnssPowerIndication> iGnssPowerIndication;
520     auto status = aidl_gnss_hal_->getExtensionGnssPowerIndication(&iGnssPowerIndication);
521     ASSERT_TRUE(status.isOk());
522     ASSERT_TRUE(iGnssPowerIndication != nullptr);
523 
524     auto gnssPowerIndicationCallback = sp<GnssPowerIndicationCallback>::make();
525     status = iGnssPowerIndication->setCallback(gnssPowerIndicationCallback);
526     ASSERT_TRUE(status.isOk());
527 
528     const int kTimeoutSec = 2;
529     EXPECT_TRUE(gnssPowerIndicationCallback->capabilities_cbq_.retrieve(
530             gnssPowerIndicationCallback->last_capabilities_, kTimeoutSec));
531 
532     EXPECT_EQ(gnssPowerIndicationCallback->capabilities_cbq_.calledCount(), 1);
533 
534     if (gnssPowerIndicationCallback->last_capabilities_ == 0) {
535         // Skipping the test since GnssPowerIndication is not supported.
536         return;
537     }
538 
539     // Request and verify a GnssPowerStats is received
540     gnssPowerIndicationCallback->gnss_power_stats_cbq_.reset();
541     iGnssPowerIndication->requestGnssPowerStats();
542 
543     EXPECT_TRUE(gnssPowerIndicationCallback->gnss_power_stats_cbq_.retrieve(
544             gnssPowerIndicationCallback->last_gnss_power_stats_, kTimeoutSec));
545     EXPECT_EQ(gnssPowerIndicationCallback->gnss_power_stats_cbq_.calledCount(), 1);
546     auto powerStats1 = gnssPowerIndicationCallback->last_gnss_power_stats_;
547 
548     // Get a location and request another GnssPowerStats
549     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
550         gnss_cb_->location_cbq_.reset();
551     } else {
552         aidl_gnss_cb_->location_cbq_.reset();
553     }
554     StartAndCheckFirstLocation(/* min_interval_msec= */ 1000, /* low_power_mode= */ false);
555 
556     // Request and verify the 2nd GnssPowerStats has larger values than the 1st one
557     iGnssPowerIndication->requestGnssPowerStats();
558 
559     EXPECT_TRUE(gnssPowerIndicationCallback->gnss_power_stats_cbq_.retrieve(
560             gnssPowerIndicationCallback->last_gnss_power_stats_, kTimeoutSec));
561     EXPECT_EQ(gnssPowerIndicationCallback->gnss_power_stats_cbq_.calledCount(), 2);
562 
563     auto powerStats2 = gnssPowerIndicationCallback->last_gnss_power_stats_;
564 
565     if ((gnssPowerIndicationCallback->last_capabilities_ &
566          (int)GnssPowerIndicationCallback::CAPABILITY_TOTAL)) {
567         // Elapsed realtime must increase
568         EXPECT_GT(powerStats2.elapsedRealtime.timestampNs, powerStats1.elapsedRealtime.timestampNs);
569 
570         // Total energy must increase
571         EXPECT_GT(powerStats2.totalEnergyMilliJoule, powerStats1.totalEnergyMilliJoule);
572     }
573 
574     // At least oone of singleband and multiband acquisition energy must increase
575     bool singlebandAcqEnergyIncreased = powerStats2.singlebandAcquisitionModeEnergyMilliJoule >
576                                         powerStats1.singlebandAcquisitionModeEnergyMilliJoule;
577     bool multibandAcqEnergyIncreased = powerStats2.multibandAcquisitionModeEnergyMilliJoule >
578                                        powerStats1.multibandAcquisitionModeEnergyMilliJoule;
579 
580     if ((gnssPowerIndicationCallback->last_capabilities_ &
581          (int)GnssPowerIndicationCallback::CAPABILITY_SINGLEBAND_ACQUISITION) ||
582         (gnssPowerIndicationCallback->last_capabilities_ &
583          (int)GnssPowerIndicationCallback::CAPABILITY_MULTIBAND_ACQUISITION)) {
584         EXPECT_TRUE(singlebandAcqEnergyIncreased || multibandAcqEnergyIncreased);
585     }
586 
587     // At least one of singleband and multiband tracking energy must increase
588     bool singlebandTrackingEnergyIncreased = powerStats2.singlebandTrackingModeEnergyMilliJoule >
589                                              powerStats1.singlebandTrackingModeEnergyMilliJoule;
590     bool multibandTrackingEnergyIncreased = powerStats2.multibandTrackingModeEnergyMilliJoule >
591                                             powerStats1.multibandTrackingModeEnergyMilliJoule;
592     if ((gnssPowerIndicationCallback->last_capabilities_ &
593          (int)GnssPowerIndicationCallback::CAPABILITY_SINGLEBAND_TRACKING) ||
594         (gnssPowerIndicationCallback->last_capabilities_ &
595          (int)GnssPowerIndicationCallback::CAPABILITY_MULTIBAND_TRACKING)) {
596         EXPECT_TRUE(singlebandTrackingEnergyIncreased || multibandTrackingEnergyIncreased);
597     }
598 
599     // Clean up
600     StopAndClearLocations();
601 }
602 
603 /*
604  * BlocklistIndividualSatellites:
605  *
606  * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
607  * GnssStatus for common satellites (strongest and one other.)
608  * 2a & b) Turns off location, and blocklists common satellites.
609  * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
610  * GnssStatus does not use those satellites.
611  * 4a & b) Turns off location, and send in empty blocklist.
612  * 5a) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
613  * GnssStatus does re-use at least the previously strongest satellite
614  * 5b) Retry a few times, in case GNSS search strategy takes a while to reacquire even the
615  * formerly strongest satellite
616  */
TEST_P(GnssHalTest,BlocklistIndividualSatellites)617 TEST_P(GnssHalTest, BlocklistIndividualSatellites) {
618     if (!(aidl_gnss_cb_->last_capabilities_ &
619           (int)GnssCallbackAidl::CAPABILITY_SATELLITE_BLOCKLIST)) {
620         ALOGI("Test BlocklistIndividualSatellites skipped. SATELLITE_BLOCKLIST capability not "
621               "supported.");
622         return;
623     }
624 
625     const int kLocationsToAwait = 3;
626     const int kRetriesToUnBlocklist = 10;
627 
628     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
629         gnss_cb_->location_cbq_.reset();
630     } else {
631         aidl_gnss_cb_->location_cbq_.reset();
632     }
633     StartAndCheckLocations(kLocationsToAwait);
634     int location_called_count = (aidl_gnss_hal_->getInterfaceVersion() <= 1)
635                                         ? gnss_cb_->location_cbq_.calledCount()
636                                         : aidl_gnss_cb_->location_cbq_.calledCount();
637 
638     // Tolerate 1 less sv status to handle edge cases in reporting.
639     int sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() <= 1)
640                                         ? gnss_cb_->sv_info_list_cbq_.size()
641                                         : aidl_gnss_cb_->sv_info_list_cbq_.size();
642     EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
643     ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
644           sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
645 
646     /*
647      * Identify strongest SV seen at least kLocationsToAwait -1 times
648      * Why -1?  To avoid test flakiness in case of (plausible) slight flakiness in strongest signal
649      * observability (one epoch RF null)
650      */
651 
652     const int kGnssSvInfoListTimeout = 2;
653     BlocklistedSource source_to_blocklist;
654     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
655         std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_vec_list;
656         int count = gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec_list, sv_info_list_cbq_size,
657                                                          kGnssSvInfoListTimeout);
658         ASSERT_EQ(count, sv_info_list_cbq_size);
659         source_to_blocklist =
660                 FindStrongFrequentNonGpsSource(sv_info_vec_list, kLocationsToAwait - 1);
661     } else {
662         std::list<std::vector<IGnssCallback::GnssSvInfo>> sv_info_vec_list;
663         int count = aidl_gnss_cb_->sv_info_list_cbq_.retrieve(
664                 sv_info_vec_list, sv_info_list_cbq_size, kGnssSvInfoListTimeout);
665         ASSERT_EQ(count, sv_info_list_cbq_size);
666         source_to_blocklist =
667                 FindStrongFrequentNonGpsSource(sv_info_vec_list, kLocationsToAwait - 1);
668     }
669 
670     if (source_to_blocklist.constellation == GnssConstellationType::UNKNOWN) {
671         // Cannot find a non-GPS satellite. Let the test pass.
672         ALOGD("Cannot find a non-GPS satellite. Letting the test pass.");
673         return;
674     }
675 
676     // Stop locations, blocklist the common SV
677     StopAndClearLocations();
678 
679     sp<IGnssConfiguration> gnss_configuration_hal;
680     auto status = aidl_gnss_hal_->getExtensionGnssConfiguration(&gnss_configuration_hal);
681     ASSERT_TRUE(status.isOk());
682     ASSERT_NE(gnss_configuration_hal, nullptr);
683 
684     std::vector<BlocklistedSource> sources;
685     sources.resize(1);
686     sources[0] = source_to_blocklist;
687 
688     status = gnss_configuration_hal->setBlocklist(sources);
689     ASSERT_TRUE(status.isOk());
690 
691     // retry and ensure satellite not used
692     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
693         gnss_cb_->sv_info_list_cbq_.reset();
694         gnss_cb_->location_cbq_.reset();
695     } else {
696         aidl_gnss_cb_->sv_info_list_cbq_.reset();
697         aidl_gnss_cb_->location_cbq_.reset();
698     }
699 
700     StartAndCheckLocations(kLocationsToAwait);
701 
702     // early exit if test is being run with insufficient signal
703     location_called_count = (aidl_gnss_hal_->getInterfaceVersion() <= 1)
704                                     ? gnss_cb_->location_cbq_.calledCount()
705                                     : aidl_gnss_cb_->location_cbq_.calledCount();
706     if (location_called_count == 0) {
707         ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
708     }
709     ASSERT_TRUE(location_called_count > 0);
710 
711     // Tolerate 1 less sv status to handle edge cases in reporting.
712     sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() <= 1)
713                                     ? gnss_cb_->sv_info_list_cbq_.size()
714                                     : aidl_gnss_cb_->sv_info_list_cbq_.size();
715     EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
716     ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
717           sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
718     for (int i = 0; i < sv_info_list_cbq_size; ++i) {
719         if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
720             hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
721             gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
722             for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
723                 auto& gnss_sv = sv_info_vec[iSv];
724                 EXPECT_FALSE(
725                         (gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) &&
726                         (static_cast<GnssConstellationType>(gnss_sv.v2_0.constellation) ==
727                          source_to_blocklist.constellation) &&
728                         (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
729             }
730         } else {
731             std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
732             aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
733             for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
734                 auto& gnss_sv = sv_info_vec[iSv];
735                 EXPECT_FALSE((gnss_sv.svid == source_to_blocklist.svid) &&
736                              (gnss_sv.constellation == source_to_blocklist.constellation) &&
737                              (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
738             }
739         }
740     }
741 
742     // clear blocklist and restart - this time updating the blocklist while location is still on
743     sources.resize(0);
744 
745     status = gnss_configuration_hal->setBlocklist(sources);
746     ASSERT_TRUE(status.isOk());
747 
748     bool strongest_sv_is_reobserved = false;
749     // do several loops awaiting a few locations, allowing non-immediate reacquisition strategies
750     int unblocklist_loops_remaining = kRetriesToUnBlocklist;
751     while (!strongest_sv_is_reobserved && (unblocklist_loops_remaining-- > 0)) {
752         StopAndClearLocations();
753 
754         if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
755             gnss_cb_->sv_info_list_cbq_.reset();
756             gnss_cb_->location_cbq_.reset();
757         } else {
758             aidl_gnss_cb_->sv_info_list_cbq_.reset();
759             aidl_gnss_cb_->location_cbq_.reset();
760         }
761         StartAndCheckLocations(kLocationsToAwait);
762 
763         // early exit loop if test is being run with insufficient signal
764         location_called_count = (aidl_gnss_hal_->getInterfaceVersion() <= 1)
765                                         ? gnss_cb_->location_cbq_.calledCount()
766                                         : aidl_gnss_cb_->location_cbq_.calledCount();
767         if (location_called_count == 0) {
768             ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
769         }
770         ASSERT_TRUE(location_called_count > 0);
771 
772         // Tolerate 1 less sv status to handle edge cases in reporting.
773         sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() <= 1)
774                                         ? gnss_cb_->sv_info_list_cbq_.size()
775                                         : aidl_gnss_cb_->sv_info_list_cbq_.size();
776         EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
777         ALOGD("Clear blocklist, observed %d GnssSvInfo, while awaiting %d Locations"
778               ", tries remaining %d",
779               sv_info_list_cbq_size, kLocationsToAwait, unblocklist_loops_remaining);
780 
781         for (int i = 0; i < sv_info_list_cbq_size; ++i) {
782             if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
783                 hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
784                 gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
785                 for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
786                     auto& gnss_sv = sv_info_vec[iSv];
787                     if ((gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) &&
788                         (static_cast<GnssConstellationType>(gnss_sv.v2_0.constellation) ==
789                          source_to_blocklist.constellation) &&
790                         (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX)) {
791                         strongest_sv_is_reobserved = true;
792                         break;
793                     }
794                 }
795             } else {
796                 std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
797                 aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
798                 for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
799                     auto& gnss_sv = sv_info_vec[iSv];
800                     if ((gnss_sv.svid == source_to_blocklist.svid) &&
801                         (gnss_sv.constellation == source_to_blocklist.constellation) &&
802                         (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX)) {
803                         strongest_sv_is_reobserved = true;
804                         break;
805                     }
806                 }
807             }
808             if (strongest_sv_is_reobserved) break;
809         }
810     }
811     EXPECT_TRUE(strongest_sv_is_reobserved);
812     StopAndClearLocations();
813 }
814 
815 /*
816  * BlocklistConstellationLocationOff:
817  *
818  * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
819  * GnssStatus for any non-GPS constellations.
820  * 2a & b) Turns off location, and blocklist first non-GPS constellations.
821  * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
822  * GnssStatus does not use any constellation but GPS.
823  * 4a & b) Clean up by turning off location, and send in empty blocklist.
824  */
TEST_P(GnssHalTest,BlocklistConstellationLocationOff)825 TEST_P(GnssHalTest, BlocklistConstellationLocationOff) {
826     if (!(aidl_gnss_cb_->last_capabilities_ &
827           (int)GnssCallbackAidl::CAPABILITY_SATELLITE_BLOCKLIST)) {
828         ALOGI("Test BlocklistConstellationLocationOff skipped. SATELLITE_BLOCKLIST capability not "
829               "supported.");
830         return;
831     }
832 
833     const int kLocationsToAwait = 3;
834     const int kGnssSvInfoListTimeout = 2;
835 
836     // Find first non-GPS constellation to blocklist
837     GnssConstellationType constellation_to_blocklist = static_cast<GnssConstellationType>(
838             startLocationAndGetNonGpsConstellation(kLocationsToAwait, kGnssSvInfoListTimeout));
839 
840     // Turns off location
841     StopAndClearLocations();
842 
843     BlocklistedSource source_to_blocklist_1;
844     source_to_blocklist_1.constellation = constellation_to_blocklist;
845     source_to_blocklist_1.svid = 0;  // documented wildcard for all satellites in this constellation
846 
847     // IRNSS was added in 2.0. Always attempt to blocklist IRNSS to verify that the new enum is
848     // supported.
849     BlocklistedSource source_to_blocklist_2;
850     source_to_blocklist_2.constellation = GnssConstellationType::IRNSS;
851     source_to_blocklist_2.svid = 0;  // documented wildcard for all satellites in this constellation
852 
853     sp<IGnssConfiguration> gnss_configuration_hal;
854     auto status = aidl_gnss_hal_->getExtensionGnssConfiguration(&gnss_configuration_hal);
855     ASSERT_TRUE(status.isOk());
856     ASSERT_NE(gnss_configuration_hal, nullptr);
857 
858     hidl_vec<BlocklistedSource> sources;
859     sources.resize(2);
860     sources[0] = source_to_blocklist_1;
861     sources[1] = source_to_blocklist_2;
862 
863     status = gnss_configuration_hal->setBlocklist(sources);
864     ASSERT_TRUE(status.isOk());
865 
866     // retry and ensure constellation not used
867     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
868         gnss_cb_->sv_info_list_cbq_.reset();
869         gnss_cb_->location_cbq_.reset();
870     } else {
871         aidl_gnss_cb_->sv_info_list_cbq_.reset();
872         aidl_gnss_cb_->location_cbq_.reset();
873     }
874     StartAndCheckLocations(kLocationsToAwait);
875 
876     // Tolerate 1 less sv status to handle edge cases in reporting.
877     int sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() <= 1)
878                                         ? gnss_cb_->sv_info_list_cbq_.size()
879                                         : aidl_gnss_cb_->sv_info_list_cbq_.size();
880     EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
881     ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations", sv_info_list_cbq_size,
882           kLocationsToAwait);
883     for (int i = 0; i < sv_info_list_cbq_size; ++i) {
884         if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
885             hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
886             gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
887             for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
888                 const auto& gnss_sv = sv_info_vec[iSv];
889                 EXPECT_FALSE(
890                         (static_cast<GnssConstellationType>(gnss_sv.v2_0.constellation) ==
891                          source_to_blocklist_1.constellation) &&
892                         (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
893                 EXPECT_FALSE(
894                         (static_cast<GnssConstellationType>(gnss_sv.v2_0.constellation) ==
895                          source_to_blocklist_2.constellation) &&
896                         (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
897             }
898         } else {
899             std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
900             aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
901             for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
902                 const auto& gnss_sv = sv_info_vec[iSv];
903                 EXPECT_FALSE((gnss_sv.constellation == source_to_blocklist_1.constellation) &&
904                              (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
905                 EXPECT_FALSE((gnss_sv.constellation == source_to_blocklist_2.constellation) &&
906                              (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
907             }
908         }
909     }
910 
911     // clean up
912     StopAndClearLocations();
913     sources.resize(0);
914     status = gnss_configuration_hal->setBlocklist(sources);
915     ASSERT_TRUE(status.isOk());
916 }
917 
918 /*
919  * BlocklistConstellationLocationOn:
920  *
921  * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
922  * GnssStatus for any non-GPS constellations.
923  * 2a & b) Blocklist first non-GPS constellation, and turn off location.
924  * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
925  * GnssStatus does not use any constellation but GPS.
926  * 4a & b) Clean up by turning off location, and send in empty blocklist.
927  */
TEST_P(GnssHalTest,BlocklistConstellationLocationOn)928 TEST_P(GnssHalTest, BlocklistConstellationLocationOn) {
929     if (!(aidl_gnss_cb_->last_capabilities_ &
930           (int)GnssCallbackAidl::CAPABILITY_SATELLITE_BLOCKLIST)) {
931         ALOGI("Test BlocklistConstellationLocationOn skipped. SATELLITE_BLOCKLIST capability not "
932               "supported.");
933         return;
934     }
935 
936     const int kLocationsToAwait = 3;
937     const int kGnssSvInfoListTimeout = 2;
938 
939     // Find first non-GPS constellation to blocklist
940     GnssConstellationType constellation_to_blocklist = static_cast<GnssConstellationType>(
941             startLocationAndGetNonGpsConstellation(kLocationsToAwait, kGnssSvInfoListTimeout));
942 
943     BlocklistedSource source_to_blocklist_1;
944     source_to_blocklist_1.constellation = constellation_to_blocklist;
945     source_to_blocklist_1.svid = 0;  // documented wildcard for all satellites in this constellation
946 
947     // IRNSS was added in 2.0. Always attempt to blocklist IRNSS to verify that the new enum is
948     // supported.
949     BlocklistedSource source_to_blocklist_2;
950     source_to_blocklist_2.constellation = GnssConstellationType::IRNSS;
951     source_to_blocklist_2.svid = 0;  // documented wildcard for all satellites in this constellation
952 
953     sp<IGnssConfiguration> gnss_configuration_hal;
954     auto status = aidl_gnss_hal_->getExtensionGnssConfiguration(&gnss_configuration_hal);
955     ASSERT_TRUE(status.isOk());
956     ASSERT_NE(gnss_configuration_hal, nullptr);
957 
958     hidl_vec<BlocklistedSource> sources;
959     sources.resize(2);
960     sources[0] = source_to_blocklist_1;
961     sources[1] = source_to_blocklist_2;
962 
963     status = gnss_configuration_hal->setBlocklist(sources);
964     ASSERT_TRUE(status.isOk());
965 
966     // Turns off location
967     StopAndClearLocations();
968 
969     // retry and ensure constellation not used
970     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
971         gnss_cb_->sv_info_list_cbq_.reset();
972         gnss_cb_->location_cbq_.reset();
973     } else {
974         aidl_gnss_cb_->sv_info_list_cbq_.reset();
975         aidl_gnss_cb_->location_cbq_.reset();
976     }
977     StartAndCheckLocations(kLocationsToAwait);
978 
979     // Tolerate 1 less sv status to handle edge cases in reporting.
980     int sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() <= 1)
981                                         ? gnss_cb_->sv_info_list_cbq_.size()
982                                         : aidl_gnss_cb_->sv_info_list_cbq_.size();
983     EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
984     ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations", sv_info_list_cbq_size,
985           kLocationsToAwait);
986     for (int i = 0; i < sv_info_list_cbq_size; ++i) {
987         if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
988             hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
989             gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
990             for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
991                 const auto& gnss_sv = sv_info_vec[iSv];
992                 EXPECT_FALSE(
993                         (static_cast<GnssConstellationType>(gnss_sv.v2_0.constellation) ==
994                          source_to_blocklist_1.constellation) &&
995                         (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
996                 EXPECT_FALSE(
997                         (static_cast<GnssConstellationType>(gnss_sv.v2_0.constellation) ==
998                          source_to_blocklist_2.constellation) &&
999                         (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
1000             }
1001         } else {
1002             std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
1003             aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
1004             for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
1005                 const auto& gnss_sv = sv_info_vec[iSv];
1006                 EXPECT_FALSE((gnss_sv.constellation == source_to_blocklist_1.constellation) &&
1007                              (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
1008                 EXPECT_FALSE((gnss_sv.constellation == source_to_blocklist_2.constellation) &&
1009                              (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
1010             }
1011         }
1012     }
1013 
1014     // clean up
1015     StopAndClearLocations();
1016     sources.resize(0);
1017     status = gnss_configuration_hal->setBlocklist(sources);
1018     ASSERT_TRUE(status.isOk());
1019 }
1020 
1021 /*
1022  * TestAllExtensions.
1023  */
TEST_P(GnssHalTest,TestAllExtensions)1024 TEST_P(GnssHalTest, TestAllExtensions) {
1025     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
1026         return;
1027     }
1028 
1029     sp<IGnssBatching> iGnssBatching;
1030     auto status = aidl_gnss_hal_->getExtensionGnssBatching(&iGnssBatching);
1031     if (status.isOk() && iGnssBatching != nullptr) {
1032         auto gnssBatchingCallback = sp<GnssBatchingCallback>::make();
1033         status = iGnssBatching->init(gnssBatchingCallback);
1034         ASSERT_TRUE(status.isOk());
1035 
1036         status = iGnssBatching->cleanup();
1037         ASSERT_TRUE(status.isOk());
1038     }
1039 
1040     sp<IGnssGeofence> iGnssGeofence;
1041     status = aidl_gnss_hal_->getExtensionGnssGeofence(&iGnssGeofence);
1042     if (status.isOk() && iGnssGeofence != nullptr) {
1043         auto gnssGeofenceCallback = sp<GnssGeofenceCallback>::make();
1044         status = iGnssGeofence->setCallback(gnssGeofenceCallback);
1045         ASSERT_TRUE(status.isOk());
1046     }
1047 
1048     sp<IGnssNavigationMessageInterface> iGnssNavMsgIface;
1049     status = aidl_gnss_hal_->getExtensionGnssNavigationMessage(&iGnssNavMsgIface);
1050     if (status.isOk() && iGnssNavMsgIface != nullptr) {
1051         auto gnssNavMsgCallback = sp<GnssNavigationMessageCallback>::make();
1052         status = iGnssNavMsgIface->setCallback(gnssNavMsgCallback);
1053         ASSERT_TRUE(status.isOk());
1054 
1055         status = iGnssNavMsgIface->close();
1056         ASSERT_TRUE(status.isOk());
1057     }
1058 }
1059 
1060 /*
1061  * TestAGnssExtension:
1062  * 1. Gets the IAGnss extension.
1063  * 2. Sets AGnssCallback.
1064  * 3. Sets SUPL server host/port.
1065  */
TEST_P(GnssHalTest,TestAGnssExtension)1066 TEST_P(GnssHalTest, TestAGnssExtension) {
1067     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
1068         return;
1069     }
1070     sp<IAGnss> iAGnss;
1071     auto status = aidl_gnss_hal_->getExtensionAGnss(&iAGnss);
1072     ASSERT_TRUE(status.isOk());
1073     ASSERT_TRUE(iAGnss != nullptr);
1074 
1075     auto agnssCallback = sp<AGnssCallbackAidl>::make();
1076     status = iAGnss->setCallback(agnssCallback);
1077     ASSERT_TRUE(status.isOk());
1078 
1079     // Set SUPL server host/port
1080     status = iAGnss->setServer(AGnssType::SUPL, std::string("supl.google.com"), 7275);
1081     ASSERT_TRUE(status.isOk());
1082 }
1083 
1084 /*
1085  * TestAGnssRilExtension:
1086  * 1. Gets the IAGnssRil extension.
1087  * 2. Sets AGnssRilCallback.
1088  * 3. Update network state to connected and then disconnected.
1089  * 4. Sets reference location.
1090  * 5. Injects empty NI message data and verifies that it returns an error.
1091  */
TEST_P(GnssHalTest,TestAGnssRilExtension)1092 TEST_P(GnssHalTest, TestAGnssRilExtension) {
1093     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
1094         return;
1095     }
1096     sp<IAGnssRil> iAGnssRil;
1097     auto status = aidl_gnss_hal_->getExtensionAGnssRil(&iAGnssRil);
1098     ASSERT_TRUE(status.isOk());
1099     ASSERT_TRUE(iAGnssRil != nullptr);
1100 
1101     auto agnssRilCallback = sp<AGnssRilCallbackAidl>::make();
1102     status = iAGnssRil->setCallback(agnssRilCallback);
1103     ASSERT_TRUE(status.isOk());
1104 
1105     // Update GNSS HAL that a network has connected.
1106     IAGnssRil::NetworkAttributes networkAttributes;
1107     networkAttributes.networkHandle = 7700664333L;
1108     networkAttributes.isConnected = true;
1109     networkAttributes.capabilities = IAGnssRil::NETWORK_CAPABILITY_NOT_ROAMING;
1110     networkAttributes.apn = "placeholder-apn";
1111     status = iAGnssRil->updateNetworkState(networkAttributes);
1112     ASSERT_TRUE(status.isOk());
1113 
1114     // Update GNSS HAL that network has disconnected.
1115     networkAttributes.isConnected = false;
1116     status = iAGnssRil->updateNetworkState(networkAttributes);
1117     ASSERT_TRUE(status.isOk());
1118 
1119     // Set RefLocation
1120     IAGnssRil::AGnssRefLocationCellID agnssReflocationCellId;
1121     agnssReflocationCellId.type = IAGnssRil::AGnssRefLocationType::LTE_CELLID;
1122     agnssReflocationCellId.mcc = 466;
1123     agnssReflocationCellId.mnc = 97;
1124     agnssReflocationCellId.lac = 46697;
1125     agnssReflocationCellId.cid = 59168142;
1126     agnssReflocationCellId.pcid = 420;
1127     agnssReflocationCellId.tac = 11460;
1128     IAGnssRil::AGnssRefLocation agnssReflocation;
1129     agnssReflocation.type = IAGnssRil::AGnssRefLocationType::LTE_CELLID;
1130     agnssReflocation.cellID = agnssReflocationCellId;
1131 
1132     status = iAGnssRil->setRefLocation(agnssReflocation);
1133     ASSERT_TRUE(status.isOk());
1134 
1135     if (aidl_gnss_hal_->getInterfaceVersion() >= 3) {
1136         status = iAGnssRil->injectNiSuplMessageData(std::vector<uint8_t>(), 0);
1137         ASSERT_FALSE(status.isOk());
1138     }
1139 }
1140 
1141 /*
1142  * GnssDebugValuesSanityTest:
1143  * Ensures that GnssDebug values make sense.
1144  */
TEST_P(GnssHalTest,GnssDebugValuesSanityTest)1145 TEST_P(GnssHalTest, GnssDebugValuesSanityTest) {
1146     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
1147         return;
1148     }
1149     sp<IGnssDebug> iGnssDebug;
1150     auto status = aidl_gnss_hal_->getExtensionGnssDebug(&iGnssDebug);
1151     ASSERT_TRUE(status.isOk());
1152     if (IsAutomotiveDevice()) {
1153         return;
1154     }
1155     ASSERT_TRUE(iGnssDebug != nullptr);
1156 
1157     IGnssDebug::DebugData data;
1158     status = iGnssDebug->getDebugData(&data);
1159     ASSERT_TRUE(status.isOk());
1160     Utils::checkPositionDebug(data);
1161 
1162     // Additional GnssDebug tests for AIDL version >= 4 (launched in Android 15(V)+)
1163     if (aidl_gnss_hal_->getInterfaceVersion() <= 3) {
1164         return;
1165     }
1166 
1167     // Start location and check the consistency between SvStatus and DebugData
1168     aidl_gnss_cb_->location_cbq_.reset();
1169     aidl_gnss_cb_->sv_info_list_cbq_.reset();
1170     StartAndCheckLocations(/* count= */ 2);
1171     int location_called_count = aidl_gnss_cb_->location_cbq_.calledCount();
1172     ALOGD("Observed %d GnssSvStatus, while awaiting 2 locations (%d received)",
1173           aidl_gnss_cb_->sv_info_list_cbq_.size(), location_called_count);
1174 
1175     // Wait for up to kNumSvInfoLists events for kTimeoutSeconds for each event.
1176     int kTimeoutSeconds = 2;
1177     int kNumSvInfoLists = 4;
1178     std::list<std::vector<IGnssCallback::GnssSvInfo>> sv_info_lists;
1179     std::vector<IGnssCallback::GnssSvInfo> last_sv_info_list;
1180 
1181     do {
1182         EXPECT_GT(aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_lists, kNumSvInfoLists,
1183                                                             kTimeoutSeconds),
1184                   0);
1185         if (!sv_info_lists.empty()) {
1186             last_sv_info_list = sv_info_lists.back();
1187             ALOGD("last_sv_info size = %d", (int)last_sv_info_list.size());
1188         }
1189     } while (!sv_info_lists.empty() && last_sv_info_list.size() == 0);
1190 
1191     StopAndClearLocations();
1192 
1193     status = iGnssDebug->getDebugData(&data);
1194     Utils::checkPositionDebug(data);
1195 
1196     // Validate SatelliteEphemerisType, SatelliteEphemerisSource, SatelliteEphemerisHealth
1197     for (auto sv_info : last_sv_info_list) {
1198         if ((sv_info.svFlag & static_cast<int>(IGnssCallback::GnssSvFlags::USED_IN_FIX)) == 0) {
1199             continue;
1200         }
1201         ALOGD("Found usedInFix const: %d, svid: %d", static_cast<int>(sv_info.constellation),
1202               sv_info.svid);
1203         bool foundDebugData = false;
1204         for (auto satelliteData : data.satelliteDataArray) {
1205             if (satelliteData.constellation == sv_info.constellation &&
1206                 satelliteData.svid == sv_info.svid) {
1207                 foundDebugData = true;
1208                 ALOGD("Found GnssDebug data for this sv.");
1209                 EXPECT_TRUE(satelliteData.serverPredictionIsAvailable ||
1210                             satelliteData.ephemerisType ==
1211                                     IGnssDebug::SatelliteEphemerisType::EPHEMERIS);
1212                 // for satellites with ephType=0, they need ephHealth=0 if used-in-fix
1213                 if (satelliteData.ephemerisType == IGnssDebug::SatelliteEphemerisType::EPHEMERIS) {
1214                     EXPECT_TRUE(satelliteData.ephemerisHealth ==
1215                                 IGnssDebug::SatelliteEphemerisHealth::GOOD);
1216                 }
1217                 break;
1218             }
1219         }
1220         // Every Satellite where GnssStatus says it is used-in-fix has a valid ephemeris - i.e. it's
1221         // it shows either a serverPredAvail: 1, or a ephType=0
1222         EXPECT_TRUE(foundDebugData);
1223     }
1224 
1225     bool hasServerPredictionAvailable = false;
1226     bool hasNoneZeroServerPredictionAgeSeconds = false;
1227     bool hasNoneDemodEphSource = false;
1228     for (auto satelliteData : data.satelliteDataArray) {
1229         // for satellites with serverPredAvail: 1, the serverPredAgeSec: is not 0 for all
1230         // satellites (at least not on 2 fixes in a row - it could get lucky once)
1231         if (satelliteData.serverPredictionIsAvailable) {
1232             hasServerPredictionAvailable = true;
1233             if (satelliteData.serverPredictionAgeSeconds != 0) {
1234                 hasNoneZeroServerPredictionAgeSeconds = true;
1235             }
1236         }
1237         // for satellites with ephType=0, they need ephSource 0-3
1238         if (satelliteData.ephemerisType == IGnssDebug::SatelliteEphemerisType::EPHEMERIS) {
1239             EXPECT_TRUE(satelliteData.ephemerisSource >=
1240                                 SatellitePvt::SatelliteEphemerisSource::DEMODULATED &&
1241                         satelliteData.ephemerisSource <=
1242                                 SatellitePvt::SatelliteEphemerisSource::OTHER);
1243             if (satelliteData.ephemerisSource !=
1244                 SatellitePvt::SatelliteEphemerisSource::DEMODULATED) {
1245                 hasNoneDemodEphSource = true;
1246             }
1247         }
1248     }
1249     if (hasNoneDemodEphSource && hasServerPredictionAvailable) {
1250         EXPECT_TRUE(hasNoneZeroServerPredictionAgeSeconds);
1251     }
1252 
1253     /**
1254     - Gnss Location Data:: should show some valid information, ideally reasonably close (+/-1km) to
1255         the Location output - at least after the 2nd valid location output (maybe in general, wait
1256         for 2 good Location outputs before checking this, in case they don't update the assistance
1257         until after they output the Location)
1258     */
1259     double distanceM =
1260             Utils::distanceMeters(data.position.latitudeDegrees, data.position.longitudeDegrees,
1261                                   aidl_gnss_cb_->last_location_.latitudeDegrees,
1262                                   aidl_gnss_cb_->last_location_.longitudeDegrees);
1263     ALOGD("distance between debug position and last position: %.2lf", distanceM);
1264     EXPECT_LT(distanceM, 1000.0);  // 1km
1265 
1266     /**
1267     - Gnss Time Data:: timeEstimate should be reasonably close to the current GPS time.
1268     - Gnss Time Data:: timeUncertaintyNs should always be > 0 and < 5e9 (could be large due
1269         to solve-for-time type solutions)
1270     - Gnss Time Data:: frequencyUncertaintyNsPerSec: should always be > 0 and < 1000 (1000 ns/s
1271         corresponds to roughly a 300 m/s speed error, which should be pretty rare)
1272     */
1273     ALOGD("debug time: %" PRId64 ", position time: %" PRId64, data.time.timeEstimateMs,
1274           aidl_gnss_cb_->last_location_.timestampMillis);
1275     // Allowing 5s between the last location time and the current GPS time
1276     EXPECT_LT(abs(data.time.timeEstimateMs - aidl_gnss_cb_->last_location_.timestampMillis), 5000);
1277 
1278     ALOGD("debug time uncertainty: %f ns", data.time.timeUncertaintyNs);
1279     EXPECT_GT(data.time.timeUncertaintyNs, 0);
1280     EXPECT_LT(data.time.timeUncertaintyNs, 5e9);
1281 
1282     ALOGD("debug freq uncertainty: %f ns/s", data.time.frequencyUncertaintyNsPerSec);
1283     EXPECT_GT(data.time.frequencyUncertaintyNsPerSec, 0);
1284     EXPECT_LT(data.time.frequencyUncertaintyNsPerSec, 1000);
1285 }
1286 
1287 /*
1288  * TestGnssVisibilityControlExtension:
1289  * 1. Gets the IGnssVisibilityControl extension.
1290  * 2. Sets GnssVisibilityControlCallback
1291  * 3. Sets proxy apps
1292  */
TEST_P(GnssHalTest,TestGnssVisibilityControlExtension)1293 TEST_P(GnssHalTest, TestGnssVisibilityControlExtension) {
1294     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
1295         return;
1296     }
1297     sp<IGnssVisibilityControl> iGnssVisibilityControl;
1298     auto status = aidl_gnss_hal_->getExtensionGnssVisibilityControl(&iGnssVisibilityControl);
1299     ASSERT_TRUE(status.isOk());
1300     ASSERT_TRUE(iGnssVisibilityControl != nullptr);
1301     auto gnssVisibilityControlCallback = sp<GnssVisibilityControlCallback>::make();
1302     status = iGnssVisibilityControl->setCallback(gnssVisibilityControlCallback);
1303     ASSERT_TRUE(status.isOk());
1304 
1305     std::vector<std::string> proxyApps{std::string("com.example.ims"),
1306                                        std::string("com.example.mdt")};
1307     status = iGnssVisibilityControl->enableNfwLocationAccess(proxyApps);
1308     ASSERT_TRUE(status.isOk());
1309 }
1310 
1311 /*
1312  * TestGnssAgcInGnssMeasurement:
1313  * 1. Gets the GnssMeasurementExtension and verifies that it returns a non-null extension.
1314  * 2. Sets a GnssMeasurementCallback, waits for a measurement.
1315  */
TEST_P(GnssHalTest,TestGnssAgcInGnssMeasurement)1316 TEST_P(GnssHalTest, TestGnssAgcInGnssMeasurement) {
1317     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
1318         return;
1319     }
1320     const int kFirstGnssMeasurementTimeoutSeconds = 10;
1321     const int kNumMeasurementEvents = 5;
1322 
1323     sp<IGnssMeasurementInterface> iGnssMeasurement;
1324     auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
1325     ASSERT_TRUE(status.isOk());
1326     ASSERT_TRUE(iGnssMeasurement != nullptr);
1327 
1328     auto callback = sp<GnssMeasurementCallbackAidl>::make();
1329     status = iGnssMeasurement->setCallback(callback, /* enableFullTracking= */ false,
1330                                            /* enableCorrVecOutputs */ false);
1331     ASSERT_TRUE(status.isOk());
1332 
1333     for (int i = 0; i < kNumMeasurementEvents; i++) {
1334         GnssData lastMeasurement;
1335         ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastMeasurement,
1336                                                       kFirstGnssMeasurementTimeoutSeconds));
1337         EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), i + 1);
1338         ASSERT_TRUE(lastMeasurement.measurements.size() > 0);
1339 
1340         // Validity check GnssData fields
1341         checkGnssMeasurementClockFields(lastMeasurement);
1342 
1343         ASSERT_TRUE(lastMeasurement.gnssAgcs.size() > 0);
1344         for (const auto& gnssAgc : lastMeasurement.gnssAgcs) {
1345             ASSERT_TRUE(gnssAgc.carrierFrequencyHz >= 0);
1346         }
1347     }
1348 
1349     status = iGnssMeasurement->close();
1350     ASSERT_TRUE(status.isOk());
1351 }
1352 
1353 /*
1354  * TestGnssAntennaInfo:
1355  * Sets a GnssAntennaInfoCallback, waits for report, and verifies
1356  * 1. phaseCenterOffsetCoordinateMillimeters is valid
1357  * 2. phaseCenterOffsetCoordinateUncertaintyMillimeters is valid.
1358  * PhaseCenterVariationCorrections and SignalGainCorrections are optional.
1359  */
TEST_P(GnssHalTest,TestGnssAntennaInfo)1360 TEST_P(GnssHalTest, TestGnssAntennaInfo) {
1361     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
1362         return;
1363     }
1364 
1365     const int kAntennaInfoTimeoutSeconds = 2;
1366     sp<IGnssAntennaInfo> iGnssAntennaInfo;
1367     auto status = aidl_gnss_hal_->getExtensionGnssAntennaInfo(&iGnssAntennaInfo);
1368     ASSERT_TRUE(status.isOk());
1369 
1370     if (!(aidl_gnss_cb_->last_capabilities_ & (int)GnssCallbackAidl::CAPABILITY_ANTENNA_INFO) ||
1371         iGnssAntennaInfo == nullptr) {
1372         ALOGD("GnssAntennaInfo AIDL is not supported.");
1373         return;
1374     }
1375 
1376     auto callback = sp<GnssAntennaInfoCallbackAidl>::make();
1377     status = iGnssAntennaInfo->setCallback(callback);
1378     ASSERT_TRUE(status.isOk());
1379 
1380     std::vector<IGnssAntennaInfoCallback::GnssAntennaInfo> antennaInfos;
1381     ASSERT_TRUE(callback->antenna_info_cbq_.retrieve(antennaInfos, kAntennaInfoTimeoutSeconds));
1382     EXPECT_EQ(callback->antenna_info_cbq_.calledCount(), 1);
1383     ASSERT_TRUE(antennaInfos.size() > 0);
1384 
1385     for (auto antennaInfo : antennaInfos) {
1386         // Remaining fields are optional
1387         if (!antennaInfo.phaseCenterVariationCorrectionMillimeters.empty()) {
1388             int numRows = antennaInfo.phaseCenterVariationCorrectionMillimeters.size();
1389             int numColumns = antennaInfo.phaseCenterVariationCorrectionMillimeters[0].row.size();
1390             // Must have at least 1 row and 2 columns
1391             ASSERT_TRUE(numRows >= 1 && numColumns >= 2);
1392 
1393             // Corrections and uncertainties must have same dimensions
1394             ASSERT_TRUE(antennaInfo.phaseCenterVariationCorrectionMillimeters.size() ==
1395                         antennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters.size());
1396             ASSERT_TRUE(
1397                     antennaInfo.phaseCenterVariationCorrectionMillimeters[0].row.size() ==
1398                     antennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters[0].row.size());
1399 
1400             // Must be rectangular
1401             for (auto row : antennaInfo.phaseCenterVariationCorrectionMillimeters) {
1402                 ASSERT_TRUE(row.row.size() == numColumns);
1403             }
1404             for (auto row : antennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters) {
1405                 ASSERT_TRUE(row.row.size() == numColumns);
1406             }
1407         }
1408         if (!antennaInfo.signalGainCorrectionDbi.empty()) {
1409             int numRows = antennaInfo.signalGainCorrectionDbi.size();
1410             int numColumns = antennaInfo.signalGainCorrectionUncertaintyDbi[0].row.size();
1411             // Must have at least 1 row and 2 columns
1412             ASSERT_TRUE(numRows >= 1 && numColumns >= 2);
1413 
1414             // Corrections and uncertainties must have same dimensions
1415             ASSERT_TRUE(antennaInfo.signalGainCorrectionDbi.size() ==
1416                         antennaInfo.signalGainCorrectionUncertaintyDbi.size());
1417             ASSERT_TRUE(antennaInfo.signalGainCorrectionDbi[0].row.size() ==
1418                         antennaInfo.signalGainCorrectionUncertaintyDbi[0].row.size());
1419 
1420             // Must be rectangular
1421             for (auto row : antennaInfo.signalGainCorrectionDbi) {
1422                 ASSERT_TRUE(row.row.size() == numColumns);
1423             }
1424             for (auto row : antennaInfo.signalGainCorrectionUncertaintyDbi) {
1425                 ASSERT_TRUE(row.row.size() == numColumns);
1426             }
1427         }
1428     }
1429 
1430     iGnssAntennaInfo->close();
1431 }
1432 
1433 /*
1434  * TestGnssMeasurementCorrections:
1435  * If measurement corrections capability is supported, verifies that the measurement corrections
1436  * capabilities are reported and the mandatory LOS_SATS or the EXCESS_PATH_LENGTH
1437  * capability flag is set.
1438  */
TEST_P(GnssHalTest,TestGnssMeasurementCorrections)1439 TEST_P(GnssHalTest, TestGnssMeasurementCorrections) {
1440     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
1441         return;
1442     }
1443     if (!(aidl_gnss_cb_->last_capabilities_ &
1444           (int)GnssCallbackAidl::CAPABILITY_MEASUREMENT_CORRECTIONS)) {
1445         return;
1446     }
1447 
1448     sp<IMeasurementCorrectionsInterface> iMeasurementCorrectionsAidl;
1449     auto status = aidl_gnss_hal_->getExtensionMeasurementCorrections(&iMeasurementCorrectionsAidl);
1450     ASSERT_TRUE(status.isOk());
1451     ASSERT_TRUE(iMeasurementCorrectionsAidl != nullptr);
1452 
1453     // Setup measurement corrections callback.
1454     auto gnssMeasurementCorrectionsCallback = sp<MeasurementCorrectionsCallback>::make();
1455     status = iMeasurementCorrectionsAidl->setCallback(gnssMeasurementCorrectionsCallback);
1456     ASSERT_TRUE(status.isOk());
1457 
1458     const int kTimeoutSec = 5;
1459     EXPECT_TRUE(gnssMeasurementCorrectionsCallback->capabilities_cbq_.retrieve(
1460             gnssMeasurementCorrectionsCallback->last_capabilities_, kTimeoutSec));
1461     ASSERT_TRUE(gnssMeasurementCorrectionsCallback->capabilities_cbq_.calledCount() > 0);
1462 
1463     ASSERT_TRUE((gnssMeasurementCorrectionsCallback->last_capabilities_ &
1464                  (MeasurementCorrectionsCallback::CAPABILITY_LOS_SATS |
1465                   MeasurementCorrectionsCallback::CAPABILITY_EXCESS_PATH_LENGTH)) != 0);
1466 
1467     // Set a mock MeasurementCorrections.
1468     status = iMeasurementCorrectionsAidl->setCorrections(
1469             Utils::getMockMeasurementCorrections_aidl());
1470     ASSERT_TRUE(status.isOk());
1471 }
1472 
1473 /*
1474  * TestStopSvStatusAndNmea:
1475  * 1. Call stopSvStatus and stopNmea.
1476  * 2. Start location and verify that
1477  *    - no SvStatus is received.
1478  *    - no Nmea is received.
1479  */
TEST_P(GnssHalTest,TestStopSvStatusAndNmea)1480 TEST_P(GnssHalTest, TestStopSvStatusAndNmea) {
1481     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
1482         return;
1483     }
1484     auto status = aidl_gnss_hal_->stopSvStatus();
1485     EXPECT_TRUE(status.isOk());
1486     status = aidl_gnss_hal_->stopNmea();
1487     EXPECT_TRUE(status.isOk());
1488 
1489     int kLocationsToAwait = 5;
1490     aidl_gnss_cb_->location_cbq_.reset();
1491     aidl_gnss_cb_->sv_info_list_cbq_.reset();
1492     aidl_gnss_cb_->nmea_cbq_.reset();
1493     StartAndCheckLocations(/* count= */ kLocationsToAwait,
1494                            /* start_sv_status= */ false, /* start_nmea= */ false);
1495     int location_called_count = aidl_gnss_cb_->location_cbq_.calledCount();
1496     ALOGD("Observed %d GnssSvStatus, and %d Nmea while awaiting %d locations (%d received)",
1497           aidl_gnss_cb_->sv_info_list_cbq_.size(), aidl_gnss_cb_->nmea_cbq_.size(),
1498           kLocationsToAwait, location_called_count);
1499 
1500     // Ensure that no SvStatus & no Nmea is received.
1501     EXPECT_EQ(aidl_gnss_cb_->sv_info_list_cbq_.size(), 0);
1502     EXPECT_EQ(aidl_gnss_cb_->nmea_cbq_.size(), 0);
1503 
1504     StopAndClearLocations();
1505 }
1506 
1507 /*
1508  * TestGnssMeasurementIntervals_WithoutLocation:
1509  * 1. Start measurement at intervals
1510  * 2. Verify measurement are received at expected intervals
1511  * 3. Verify status are reported at expected intervals
1512  */
TEST_P(GnssHalTest,TestGnssMeasurementIntervals_WithoutLocation)1513 TEST_P(GnssHalTest, TestGnssMeasurementIntervals_WithoutLocation) {
1514     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
1515         return;
1516     }
1517 
1518     std::vector<int> intervals({2000, 4000});
1519     std::vector<int> numEvents({10, 5});
1520 
1521     sp<IGnssMeasurementInterface> iGnssMeasurement;
1522     auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
1523     ASSERT_TRUE(status.isOk());
1524     ASSERT_TRUE(iGnssMeasurement != nullptr);
1525 
1526     ALOGD("TestGnssMeasurementIntervals_WithoutLocation");
1527     for (int i = 0; i < intervals.size(); i++) {
1528         auto callback = sp<GnssMeasurementCallbackAidl>::make();
1529         startMeasurementWithInterval(intervals[i], iGnssMeasurement, callback);
1530 
1531         std::vector<int> measurementDeltas;
1532         std::vector<int> svInfoListDeltas;
1533 
1534         collectMeasurementIntervals(callback, numEvents[i], /* timeoutSeconds= */ 10,
1535                                     measurementDeltas);
1536         if (aidl_gnss_hal_->getInterfaceVersion() >= 3) {
1537             collectSvInfoListTimestamps(numEvents[i], /* timeoutSeconds= */ 10, svInfoListDeltas);
1538             EXPECT_TRUE(aidl_gnss_cb_->sv_info_list_cbq_.size() > 0);
1539         }
1540         status = iGnssMeasurement->close();
1541         ASSERT_TRUE(status.isOk());
1542 
1543         assertMeanAndStdev(intervals[i], measurementDeltas);
1544 
1545         if (aidl_gnss_hal_->getInterfaceVersion() >= 3) {
1546             assertMeanAndStdev(intervals[i], svInfoListDeltas);
1547         }
1548     }
1549 }
1550 
1551 /*
1552  * TestGnssMeasurementIntervals_LocationOnBeforeMeasurement:
1553  * 1. Start location at 1s.
1554  * 2. Start measurement at 2s. Verify measurements are received at 1s.
1555  * 3. Stop measurement. Stop location.
1556  */
TEST_P(GnssHalTest,TestGnssMeasurementIntervals_LocationOnBeforeMeasurement)1557 TEST_P(GnssHalTest, TestGnssMeasurementIntervals_LocationOnBeforeMeasurement) {
1558     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
1559         return;
1560     }
1561 
1562     std::vector<int> intervals({2000});
1563 
1564     sp<IGnssMeasurementInterface> iGnssMeasurement;
1565     auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
1566     ASSERT_TRUE(status.isOk());
1567     ASSERT_TRUE(iGnssMeasurement != nullptr);
1568 
1569     int locationIntervalMs = 1000;
1570 
1571     // Start location first and then start measurement
1572     ALOGD("TestGnssMeasurementIntervals_LocationOnBeforeMeasurement");
1573     StartAndCheckFirstLocation(locationIntervalMs, /* lowPowerMode= */ false);
1574     for (auto& intervalMs : intervals) {
1575         auto callback = sp<GnssMeasurementCallbackAidl>::make();
1576         startMeasurementWithInterval(intervalMs, iGnssMeasurement, callback);
1577 
1578         std::vector<int> measurementDeltas;
1579         std::vector<int> svInfoListDeltas;
1580 
1581         collectMeasurementIntervals(callback, /*numEvents=*/10, /*timeoutSeconds=*/10,
1582                                     measurementDeltas);
1583         if (aidl_gnss_hal_->getInterfaceVersion() >= 3) {
1584             collectSvInfoListTimestamps(/*numEvents=*/10, /* timeoutSeconds= */ 10,
1585                                         svInfoListDeltas);
1586             EXPECT_TRUE(aidl_gnss_cb_->sv_info_list_cbq_.size() > 0);
1587         }
1588 
1589         status = iGnssMeasurement->close();
1590         ASSERT_TRUE(status.isOk());
1591 
1592         assertMeanAndStdev(locationIntervalMs, measurementDeltas);
1593         if (aidl_gnss_hal_->getInterfaceVersion() >= 3) {
1594             // Verify the SvStatus interval is 1s (not 2s)
1595             assertMeanAndStdev(locationIntervalMs, svInfoListDeltas);
1596         }
1597     }
1598     StopAndClearLocations();
1599 }
1600 
1601 /*
1602  * TestGnssMeasurementIntervals_LocationOnAfterMeasurement:
1603  * 1. Start measurement at 2s
1604  * 2. Start location at 1s. Verify measurements are received at 1s
1605  * 3. Stop location. Verify measurements are received at 2s
1606  * 4. Stop measurement
1607  */
TEST_P(GnssHalTest,TestGnssMeasurementIntervals_LocationOnAfterMeasurement)1608 TEST_P(GnssHalTest, TestGnssMeasurementIntervals_LocationOnAfterMeasurement) {
1609     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
1610         return;
1611     }
1612     const int kFirstMeasTimeoutSec = 10;
1613     std::vector<int> intervals({2000});
1614 
1615     sp<IGnssMeasurementInterface> iGnssMeasurement;
1616     auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
1617     ASSERT_TRUE(status.isOk());
1618     ASSERT_TRUE(iGnssMeasurement != nullptr);
1619 
1620     int locationIntervalMs = 1000;
1621     // Start measurement first and then start location
1622     ALOGD("TestGnssMeasurementIntervals_LocationOnAfterMeasurement");
1623     for (auto& intervalMs : intervals) {
1624         auto callback = sp<GnssMeasurementCallbackAidl>::make();
1625         startMeasurementWithInterval(intervalMs, iGnssMeasurement, callback);
1626 
1627         // Start location and verify the measurements are received at 1Hz
1628         StartAndCheckFirstLocation(locationIntervalMs, /* lowPowerMode= */ false);
1629         std::vector<int> measurementDeltas;
1630         std::vector<int> svInfoListDeltas;
1631         collectMeasurementIntervals(callback, /*numEvents=*/10, kFirstMeasTimeoutSec,
1632                                     measurementDeltas);
1633         assertMeanAndStdev(locationIntervalMs, measurementDeltas);
1634         if (aidl_gnss_hal_->getInterfaceVersion() >= 3) {
1635             collectSvInfoListTimestamps(/*numEvents=*/10, /* timeoutSeconds= */ 10,
1636                                         svInfoListDeltas);
1637             EXPECT_TRUE(aidl_gnss_cb_->sv_info_list_cbq_.size() > 0);
1638             // Verify the SvStatus intervals are at 1s interval
1639             assertMeanAndStdev(locationIntervalMs, svInfoListDeltas);
1640         }
1641 
1642         // Stop location request and verify the measurements are received at 2s intervals
1643         StopAndClearLocations();
1644         measurementDeltas.clear();
1645         collectMeasurementIntervals(callback, /*numEvents=*/5, kFirstMeasTimeoutSec,
1646                                     measurementDeltas);
1647         assertMeanAndStdev(intervalMs, measurementDeltas);
1648 
1649         if (aidl_gnss_hal_->getInterfaceVersion() >= 3) {
1650             svInfoListDeltas.clear();
1651             collectSvInfoListTimestamps(/*numEvents=*/5, /* timeoutSeconds= */ 10,
1652                                         svInfoListDeltas);
1653             EXPECT_TRUE(aidl_gnss_cb_->sv_info_list_cbq_.size() > 0);
1654             // Verify the SvStatus intervals are at 2s interval
1655             for (const int& delta : svInfoListDeltas) {
1656                 ALOGD("svInfoListDelta: %d", delta);
1657             }
1658             assertMeanAndStdev(intervalMs, svInfoListDeltas);
1659         }
1660 
1661         status = iGnssMeasurement->close();
1662         ASSERT_TRUE(status.isOk());
1663     }
1664 }
1665 
1666 /*
1667  * TestGnssMeasurementIntervals_changeIntervals:
1668  * This test ensures setCallback() can be called consecutively without close().
1669  * 1. Start measurement with 20s interval and wait for 1 measurement.
1670  * 2. Start measurement with 1s interval and wait for 5 measurements.
1671  *    Verify the measurements were received at 1Hz.
1672  * 3. Start measurement with 2s interval and wait for 5 measurements.
1673  *    Verify the measurements were received at 2s intervals.
1674  */
TEST_P(GnssHalTest,TestGnssMeasurementIntervals_changeIntervals)1675 TEST_P(GnssHalTest, TestGnssMeasurementIntervals_changeIntervals) {
1676     if (aidl_gnss_hal_->getInterfaceVersion() <= 2) {
1677         return;
1678     }
1679     const int kFirstGnssMeasurementTimeoutSeconds = 10;
1680     sp<IGnssMeasurementInterface> iGnssMeasurement;
1681     auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
1682     ASSERT_TRUE(status.isOk());
1683     ASSERT_TRUE(iGnssMeasurement != nullptr);
1684 
1685     auto callback = sp<GnssMeasurementCallbackAidl>::make();
1686     std::vector<int> deltas;
1687 
1688     // setCallback at 20s interval and wait for 1 measurement
1689     startMeasurementWithInterval(20000, iGnssMeasurement, callback);
1690     collectMeasurementIntervals(callback, /* numEvents= */ 1, kFirstGnssMeasurementTimeoutSeconds,
1691                                 deltas);
1692 
1693     // setCallback at 1s interval and wait for 5 measurements
1694     callback->gnss_data_cbq_.reset();
1695     deltas.clear();
1696     startMeasurementWithInterval(1000, iGnssMeasurement, callback);
1697     collectMeasurementIntervals(callback, /* numEvents= */ 5, kFirstGnssMeasurementTimeoutSeconds,
1698                                 deltas);
1699 
1700     // verify the measurements were received at 1Hz
1701     assertMeanAndStdev(1000, deltas);
1702 
1703     // setCallback at 2s interval and wait for 5 measurements
1704     callback->gnss_data_cbq_.reset();
1705     deltas.clear();
1706     startMeasurementWithInterval(2000, iGnssMeasurement, callback);
1707     collectMeasurementIntervals(callback, /* numEvents= */ 5, kFirstGnssMeasurementTimeoutSeconds,
1708                                 deltas);
1709 
1710     // verify the measurements were received at 2s intervals
1711     assertMeanAndStdev(2000, deltas);
1712 
1713     status = iGnssMeasurement->close();
1714     ASSERT_TRUE(status.isOk());
1715 }
1716 
1717 /*
1718  * TestGnssMeasurementIsFullTracking
1719  * 1. Start measurement with enableFullTracking=true. Verify the received measurements have
1720  *    isFullTracking=true.
1721  * 2. Start measurement with enableFullTracking = false.
1722  * 3. Do step 1 again.
1723  */
TEST_P(GnssHalTest,TestGnssMeasurementIsFullTracking)1724 TEST_P(GnssHalTest, TestGnssMeasurementIsFullTracking) {
1725     // GnssData.isFullTracking is added in the interface version 3
1726     if (aidl_gnss_hal_->getInterfaceVersion() <= 2) {
1727         return;
1728     }
1729     const int kFirstGnssMeasurementTimeoutSeconds = 10;
1730     const int kNumMeasurementEvents = 5;
1731     std::vector<bool> isFullTrackingList({true, false, true});
1732 
1733     sp<IGnssMeasurementInterface> iGnssMeasurement;
1734     auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
1735     ASSERT_TRUE(status.isOk());
1736     ASSERT_TRUE(iGnssMeasurement != nullptr);
1737 
1738     ALOGD("TestGnssMeasurementIsFullTracking");
1739     auto callback = sp<GnssMeasurementCallbackAidl>::make();
1740     IGnssMeasurementInterface::Options options;
1741     options.intervalMs = 1000;
1742 
1743     for (auto isFullTracking : isFullTrackingList) {
1744         options.enableFullTracking = isFullTracking;
1745 
1746         callback->gnss_data_cbq_.reset();
1747         auto status = iGnssMeasurement->setCallbackWithOptions(callback, options);
1748         checkGnssDataFields(callback, kNumMeasurementEvents, kFirstGnssMeasurementTimeoutSeconds,
1749                             isFullTracking);
1750     }
1751 
1752     status = iGnssMeasurement->close();
1753     ASSERT_TRUE(status.isOk());
1754 }
1755 
1756 /*
1757  * TestAccumulatedDeltaRange:
1758  * 1. Gets the GnssMeasurementExtension and verifies that it returns a non-null extension.
1759  * 2. Start measurement with 1s interval and wait for up to 15 measurements.
1760  * 3. Verify at least one measurement has a valid AccumulatedDeltaRange state.
1761  */
TEST_P(GnssHalTest,TestAccumulatedDeltaRange)1762 TEST_P(GnssHalTest, TestAccumulatedDeltaRange) {
1763     if (aidl_gnss_hal_->getInterfaceVersion() <= 2) {
1764         return;
1765     }
1766     if ((aidl_gnss_cb_->last_capabilities_ & IGnssCallback::CAPABILITY_ACCUMULATED_DELTA_RANGE) ==
1767         0) {
1768         return;
1769     }
1770 
1771     ALOGD("TestAccumulatedDeltaRange");
1772 
1773     auto callback = sp<GnssMeasurementCallbackAidl>::make();
1774     sp<IGnssMeasurementInterface> iGnssMeasurement;
1775     auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
1776     ASSERT_TRUE(status.isOk());
1777     ASSERT_TRUE(iGnssMeasurement != nullptr);
1778 
1779     IGnssMeasurementInterface::Options options;
1780     options.intervalMs = 1000;
1781     options.enableFullTracking = true;
1782     status = iGnssMeasurement->setCallbackWithOptions(callback, options);
1783     ASSERT_TRUE(status.isOk());
1784 
1785     bool accumulatedDeltaRangeFound = false;
1786     const int kNumMeasurementEvents = 15;
1787 
1788     // setCallback at 1s interval and wait for 15 measurements
1789     for (int i = 0; i < kNumMeasurementEvents; i++) {
1790         GnssData lastGnssData;
1791         ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastGnssData, 10));
1792         EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), i + 1);
1793         ASSERT_TRUE(lastGnssData.measurements.size() > 0);
1794 
1795         // Validity check GnssData fields
1796         checkGnssMeasurementClockFields(lastGnssData);
1797         for (const auto& measurement : lastGnssData.measurements) {
1798             if ((measurement.accumulatedDeltaRangeState & measurement.ADR_STATE_VALID) > 0) {
1799                 accumulatedDeltaRangeFound = true;
1800                 break;
1801             }
1802         }
1803         if (accumulatedDeltaRangeFound) break;
1804     }
1805     ASSERT_TRUE(accumulatedDeltaRangeFound);
1806     status = iGnssMeasurement->close();
1807     ASSERT_TRUE(status.isOk());
1808 }
1809 
1810 /*
1811  * TestSvStatusIntervals:
1812  * 1. start measurement and location with various intervals
1813  * 2. verify the SvStatus are received at expected interval
1814  */
TEST_P(GnssHalTest,TestSvStatusIntervals)1815 TEST_P(GnssHalTest, TestSvStatusIntervals) {
1816     // Only runs on devices launched in Android 15+
1817     if (aidl_gnss_hal_->getInterfaceVersion() <= 3) {
1818         return;
1819     }
1820     ALOGD("TestSvStatusIntervals");
1821     sp<IGnssMeasurementInterface> iGnssMeasurement;
1822     auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
1823     ASSERT_TRUE(status.isOk());
1824     ASSERT_TRUE(iGnssMeasurement != nullptr);
1825 
1826     std::vector<int> locationIntervals{1000, 2000, INT_MAX};
1827     std::vector<int> measurementIntervals{1000, 2000, INT_MAX};
1828 
1829     for (auto& locationIntervalMs : locationIntervals) {
1830         for (auto& measurementIntervalMs : measurementIntervals) {
1831             if (locationIntervalMs == INT_MAX && measurementIntervalMs == INT_MAX) {
1832                 continue;
1833             }
1834             auto measurementCallback = sp<GnssMeasurementCallbackAidl>::make();
1835             // Start measurement
1836             if (measurementIntervalMs < INT_MAX) {
1837                 startMeasurementWithInterval(measurementIntervalMs, iGnssMeasurement,
1838                                              measurementCallback);
1839             }
1840             // Start location
1841             if (locationIntervalMs < INT_MAX) {
1842                 StartAndCheckFirstLocation(locationIntervalMs, /* lowPowerMode= */ false);
1843             }
1844             ALOGD("location@%d(ms), measurement@%d(ms)", locationIntervalMs, measurementIntervalMs);
1845             std::vector<int> svInfoListDeltas;
1846             collectSvInfoListTimestamps(/*numEvents=*/5, /* timeoutSeconds= */ 10,
1847                                         svInfoListDeltas);
1848             EXPECT_TRUE(aidl_gnss_cb_->sv_info_list_cbq_.size() > 0);
1849 
1850             int svStatusInterval = std::min(locationIntervalMs, measurementIntervalMs);
1851             assertMeanAndStdev(svStatusInterval, svInfoListDeltas);
1852 
1853             if (locationIntervalMs < INT_MAX) {
1854                 // Stop location request
1855                 StopAndClearLocations();
1856             }
1857             if (measurementIntervalMs < INT_MAX) {
1858                 // Stop measurement request
1859                 status = iGnssMeasurement->close();
1860                 ASSERT_TRUE(status.isOk());
1861             }
1862         }
1863     }
1864 }
1865