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