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