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