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 */
TEST_P(GnssHalTest,GnssCapabilites)177 TEST_P(GnssHalTest, GnssCapabilites) {
178 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
179 return;
180 }
181 if (!IsAutomotiveDevice()) {
182 EXPECT_TRUE(aidl_gnss_cb_->last_capabilities_ & IGnssCallback::CAPABILITY_MEASUREMENTS);
183 }
184 EXPECT_TRUE(aidl_gnss_cb_->last_capabilities_ & IGnssCallback::CAPABILITY_SCHEDULING);
185 }
186
187 /*
188 * GetLocationLowPower:
189 * Turns on location, waits for at least 5 locations allowing max of LOCATION_TIMEOUT_SUBSEQUENT_SEC
190 * between one location and the next. Also ensure that MIN_INTERVAL_MSEC is respected by waiting
191 * NO_LOCATION_PERIOD_SEC and verfiy that no location is received. Also perform validity checks on
192 * each received location.
193 */
TEST_P(GnssHalTest,GetLocationLowPower)194 TEST_P(GnssHalTest, GetLocationLowPower) {
195 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
196 return;
197 }
198
199 const int kMinIntervalMsec = 5000;
200 const int kLocationTimeoutSubsequentSec = (kMinIntervalMsec / 1000) * 2;
201 const int kNoLocationPeriodSec = (kMinIntervalMsec / 1000) / 2;
202 const int kLocationsToCheck = 5;
203 const bool kLowPowerMode = true;
204
205 // Warmup period - VTS doesn't have AGPS access via GnssLocationProvider
206 aidl_gnss_cb_->location_cbq_.reset();
207 StartAndCheckLocations(kLocationsToCheck);
208 StopAndClearLocations();
209 aidl_gnss_cb_->location_cbq_.reset();
210
211 // Start of Low Power Mode test
212 // Don't expect true - as without AGPS access
213 if (!StartAndCheckFirstLocation(kMinIntervalMsec, kLowPowerMode)) {
214 ALOGW("GetLocationLowPower test - no first low power location received.");
215 }
216
217 for (int i = 1; i < kLocationsToCheck; i++) {
218 // Verify that kMinIntervalMsec is respected by waiting kNoLocationPeriodSec and
219 // ensure that no location is received yet
220
221 aidl_gnss_cb_->location_cbq_.retrieve(aidl_gnss_cb_->last_location_, kNoLocationPeriodSec);
222 const int location_called_count = aidl_gnss_cb_->location_cbq_.calledCount();
223 // Tolerate (ignore) one extra location right after the first one
224 // to handle startup edge case scheduling limitations in some implementations
225 if ((i == 1) && (location_called_count == 2)) {
226 CheckLocation(aidl_gnss_cb_->last_location_, true);
227 continue; // restart the quiet wait period after this too-fast location
228 }
229 EXPECT_LE(location_called_count, i);
230 if (location_called_count != i) {
231 ALOGW("GetLocationLowPower test - not enough locations received. %d vs. %d expected ",
232 location_called_count, i);
233 }
234
235 if (!aidl_gnss_cb_->location_cbq_.retrieve(
236 aidl_gnss_cb_->last_location_,
237 kLocationTimeoutSubsequentSec - kNoLocationPeriodSec)) {
238 ALOGW("GetLocationLowPower test - timeout awaiting location %d", i);
239 } else {
240 CheckLocation(aidl_gnss_cb_->last_location_, true);
241 }
242 }
243
244 StopAndClearLocations();
245 }
246
247 /*
248 * InjectBestLocation
249 *
250 * Ensure successfully injecting a location.
251 */
TEST_P(GnssHalTest,InjectBestLocation)252 TEST_P(GnssHalTest, InjectBestLocation) {
253 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
254 return;
255 }
256 StartAndCheckLocations(1);
257 GnssLocation gnssLocation = aidl_gnss_cb_->last_location_;
258 CheckLocation(gnssLocation, true);
259
260 auto status = aidl_gnss_hal_->injectBestLocation(gnssLocation);
261
262 ASSERT_TRUE(status.isOk());
263
264 status = aidl_gnss_hal_->deleteAidingData(IGnss::GnssAidingData::POSITION);
265
266 ASSERT_TRUE(status.isOk());
267 }
268
269 /*
270 * TestGnssSvInfoFields:
271 * Gets 1 location and a (non-empty) GnssSvInfo, and verifies basebandCN0DbHz is valid.
272 */
TEST_P(GnssHalTest,TestGnssSvInfoFields)273 TEST_P(GnssHalTest, TestGnssSvInfoFields) {
274 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
275 return;
276 }
277 aidl_gnss_cb_->location_cbq_.reset();
278 aidl_gnss_cb_->sv_info_list_cbq_.reset();
279 StartAndCheckFirstLocation(/* min_interval_msec= */ 1000, /* low_power_mode= */ false);
280 int location_called_count = aidl_gnss_cb_->location_cbq_.calledCount();
281 ALOGD("Observed %d GnssSvStatus, while awaiting one location (%d received)",
282 aidl_gnss_cb_->sv_info_list_cbq_.size(), location_called_count);
283
284 // Wait for up to kNumSvInfoLists events for kTimeoutSeconds for each event.
285 int kTimeoutSeconds = 2;
286 int kNumSvInfoLists = 4;
287 std::list<std::vector<IGnssCallback::GnssSvInfo>> sv_info_lists;
288 std::vector<IGnssCallback::GnssSvInfo> last_sv_info_list;
289
290 do {
291 EXPECT_GT(aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_lists, kNumSvInfoLists,
292 kTimeoutSeconds),
293 0);
294 if (!sv_info_lists.empty()) {
295 last_sv_info_list = sv_info_lists.back();
296 ALOGD("last_sv_info size = %d", (int)last_sv_info_list.size());
297 }
298 } while (!sv_info_lists.empty() && last_sv_info_list.size() == 0);
299
300 bool nonZeroCn0Found = false;
301 for (auto sv_info : last_sv_info_list) {
302 EXPECT_TRUE(sv_info.basebandCN0DbHz >= 0.0 && sv_info.basebandCN0DbHz <= 65.0);
303 if (sv_info.basebandCN0DbHz > 0.0) {
304 nonZeroCn0Found = true;
305 }
306 }
307 // Assert at least one value is non-zero. Zero is ok in status as it's possibly
308 // reporting a searched but not found satellite.
309 EXPECT_TRUE(nonZeroCn0Found);
310 StopAndClearLocations();
311 }
312
313 /*
314 * TestPsdsExtension:
315 * 1. Gets the PsdsExtension
316 * 2. Injects empty PSDS data and verifies that it returns an error.
317 */
TEST_P(GnssHalTest,TestPsdsExtension)318 TEST_P(GnssHalTest, TestPsdsExtension) {
319 sp<IGnssPsds> iGnssPsds;
320 auto status = aidl_gnss_hal_->getExtensionPsds(&iGnssPsds);
321 if (status.isOk() && iGnssPsds != nullptr) {
322 status = iGnssPsds->injectPsdsData(PsdsType::LONG_TERM, std::vector<uint8_t>());
323 ASSERT_FALSE(status.isOk());
324 }
325 }
326
CheckSatellitePvt(const SatellitePvt & satellitePvt,const int interfaceVersion)327 void CheckSatellitePvt(const SatellitePvt& satellitePvt, const int interfaceVersion) {
328 const double kMaxOrbitRadiusMeters = 43000000.0;
329 const double kMaxVelocityMps = 4000.0;
330 // The below values are determined using GPS ICD Table 20-1
331 const double kMinHardwareCodeBiasMeters = -17.869;
332 const double kMaxHardwareCodeBiasMeters = 17.729;
333 const double kMaxTimeCorrelationMeters = 3e6;
334 const double kMaxSatClkDriftMps = 1.117;
335
336 ASSERT_TRUE(satellitePvt.flags & SatellitePvt::HAS_POSITION_VELOCITY_CLOCK_INFO ||
337 satellitePvt.flags & SatellitePvt::HAS_IONO ||
338 satellitePvt.flags & SatellitePvt::HAS_TROPO);
339 if (satellitePvt.flags & SatellitePvt::HAS_POSITION_VELOCITY_CLOCK_INFO) {
340 ALOGD("Found HAS_POSITION_VELOCITY_CLOCK_INFO");
341 ASSERT_TRUE(satellitePvt.satPosEcef.posXMeters >= -kMaxOrbitRadiusMeters &&
342 satellitePvt.satPosEcef.posXMeters <= kMaxOrbitRadiusMeters);
343 ASSERT_TRUE(satellitePvt.satPosEcef.posYMeters >= -kMaxOrbitRadiusMeters &&
344 satellitePvt.satPosEcef.posYMeters <= kMaxOrbitRadiusMeters);
345 ASSERT_TRUE(satellitePvt.satPosEcef.posZMeters >= -kMaxOrbitRadiusMeters &&
346 satellitePvt.satPosEcef.posZMeters <= kMaxOrbitRadiusMeters);
347 ASSERT_TRUE(satellitePvt.satPosEcef.ureMeters > 0);
348 ASSERT_TRUE(satellitePvt.satVelEcef.velXMps >= -kMaxVelocityMps &&
349 satellitePvt.satVelEcef.velXMps <= kMaxVelocityMps);
350 ASSERT_TRUE(satellitePvt.satVelEcef.velYMps >= -kMaxVelocityMps &&
351 satellitePvt.satVelEcef.velYMps <= kMaxVelocityMps);
352 ASSERT_TRUE(satellitePvt.satVelEcef.velZMps >= -kMaxVelocityMps &&
353 satellitePvt.satVelEcef.velZMps <= kMaxVelocityMps);
354 ASSERT_TRUE(satellitePvt.satVelEcef.ureRateMps > 0);
355 ASSERT_TRUE(
356 satellitePvt.satClockInfo.satHardwareCodeBiasMeters > kMinHardwareCodeBiasMeters &&
357 satellitePvt.satClockInfo.satHardwareCodeBiasMeters < kMaxHardwareCodeBiasMeters);
358 ASSERT_TRUE(satellitePvt.satClockInfo.satTimeCorrectionMeters >
359 -kMaxTimeCorrelationMeters &&
360 satellitePvt.satClockInfo.satTimeCorrectionMeters < kMaxTimeCorrelationMeters);
361 ASSERT_TRUE(satellitePvt.satClockInfo.satClkDriftMps > -kMaxSatClkDriftMps &&
362 satellitePvt.satClockInfo.satClkDriftMps < kMaxSatClkDriftMps);
363 }
364 if (satellitePvt.flags & SatellitePvt::HAS_IONO) {
365 ALOGD("Found HAS_IONO");
366 ASSERT_TRUE(satellitePvt.ionoDelayMeters > 0 && satellitePvt.ionoDelayMeters < 100);
367 }
368 if (satellitePvt.flags & SatellitePvt::HAS_TROPO) {
369 ALOGD("Found HAS_TROPO");
370 ASSERT_TRUE(satellitePvt.tropoDelayMeters > 0 && satellitePvt.tropoDelayMeters < 100);
371 }
372 if (interfaceVersion >= 2) {
373 ASSERT_TRUE(satellitePvt.timeOfClockSeconds >= 0);
374 ASSERT_TRUE(satellitePvt.timeOfEphemerisSeconds >= 0);
375 // IODC has 10 bits
376 ASSERT_TRUE(satellitePvt.issueOfDataClock >= 0 && satellitePvt.issueOfDataClock <= 1023);
377 // IODE has 8 bits
378 ASSERT_TRUE(satellitePvt.issueOfDataEphemeris >= 0 &&
379 satellitePvt.issueOfDataEphemeris <= 255);
380 }
381 }
382
383 /*
384 * TestGnssMeasurementExtensionAndSatellitePvt:
385 * 1. Gets the GnssMeasurementExtension and verifies that it returns a non-null extension.
386 * 2. Sets a GnssMeasurementCallback, waits for a measurement, and verifies mandatory fields are
387 * valid.
388 * 3. If SatellitePvt is supported, waits for a measurement with SatellitePvt, and verifies the
389 * fields are valid.
390 */
TEST_P(GnssHalTest,TestGnssMeasurementExtensionAndSatellitePvt)391 TEST_P(GnssHalTest, TestGnssMeasurementExtensionAndSatellitePvt) {
392 const bool kIsSatellitePvtSupported =
393 aidl_gnss_cb_->last_capabilities_ & (int)GnssCallbackAidl::CAPABILITY_SATELLITE_PVT;
394 ALOGD("SatellitePvt supported: %s", kIsSatellitePvtSupported ? "true" : "false");
395 const int kFirstGnssMeasurementTimeoutSeconds = 10;
396 const int kNumMeasurementEvents = 75;
397
398 sp<IGnssMeasurementInterface> iGnssMeasurement;
399 auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
400 ASSERT_TRUE(status.isOk());
401 ASSERT_TRUE(iGnssMeasurement != nullptr);
402
403 auto callback = sp<GnssMeasurementCallbackAidl>::make();
404 status = iGnssMeasurement->setCallback(callback, /* enableFullTracking= */ true,
405 /* enableCorrVecOutputs */ false);
406 ASSERT_TRUE(status.isOk());
407
408 bool satellitePvtFound = false;
409 for (int i = 0; i < kNumMeasurementEvents; i++) {
410 if (i > 0 && (!kIsSatellitePvtSupported || satellitePvtFound)) {
411 break;
412 }
413 GnssData lastMeasurement;
414 ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastMeasurement,
415 kFirstGnssMeasurementTimeoutSeconds));
416 EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), i + 1);
417 ASSERT_TRUE(lastMeasurement.measurements.size() > 0);
418
419 // Validity check GnssData fields
420 checkGnssMeasurementClockFields(lastMeasurement);
421
422 for (const auto& measurement : lastMeasurement.measurements) {
423 checkGnssMeasurementFields(measurement, lastMeasurement);
424 if (measurement.flags & GnssMeasurement::HAS_SATELLITE_PVT &&
425 kIsSatellitePvtSupported == true) {
426 ALOGD("Found a measurement with SatellitePvt");
427 satellitePvtFound = true;
428 CheckSatellitePvt(measurement.satellitePvt, aidl_gnss_hal_->getInterfaceVersion());
429 }
430 }
431 }
432 if (kIsSatellitePvtSupported) {
433 ASSERT_TRUE(satellitePvtFound);
434 }
435
436 status = iGnssMeasurement->close();
437 ASSERT_TRUE(status.isOk());
438 }
439
440 /*
441 * TestCorrelationVector:
442 * 1. Gets the GnssMeasurementExtension and verifies that it returns a non-null extension.
443 * 2. Sets a GnssMeasurementCallback, waits for GnssMeasurements with CorrelationVector, and
444 * verifies fields are valid.
445 */
TEST_P(GnssHalTest,TestCorrelationVector)446 TEST_P(GnssHalTest, TestCorrelationVector) {
447 const bool kIsCorrelationVectorSupported = aidl_gnss_cb_->last_capabilities_ &
448 (int)GnssCallbackAidl::CAPABILITY_CORRELATION_VECTOR;
449 const int kNumMeasurementEvents = 75;
450 // Pass the test if CorrelationVector is not supported
451 if (!kIsCorrelationVectorSupported) {
452 return;
453 }
454
455 const int kFirstGnssMeasurementTimeoutSeconds = 10;
456 sp<IGnssMeasurementInterface> iGnssMeasurement;
457 auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
458 ASSERT_TRUE(status.isOk());
459 ASSERT_TRUE(iGnssMeasurement != nullptr);
460
461 auto callback = sp<GnssMeasurementCallbackAidl>::make();
462 status =
463 iGnssMeasurement->setCallback(callback, /* enableFullTracking= */ true,
464 /* enableCorrVecOutputs */ kIsCorrelationVectorSupported);
465 ASSERT_TRUE(status.isOk());
466
467 bool correlationVectorFound = false;
468 for (int i = 0; i < kNumMeasurementEvents; i++) {
469 // Pass the test if at least one CorrelationVector has been found.
470 if (correlationVectorFound) {
471 break;
472 }
473 GnssData lastMeasurement;
474 ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastMeasurement,
475 kFirstGnssMeasurementTimeoutSeconds));
476 EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), i + 1);
477 ASSERT_TRUE(lastMeasurement.measurements.size() > 0);
478
479 // Validity check GnssData fields
480 checkGnssMeasurementClockFields(lastMeasurement);
481
482 for (const auto& measurement : lastMeasurement.measurements) {
483 checkGnssMeasurementFields(measurement, lastMeasurement);
484 if (measurement.flags & GnssMeasurement::HAS_CORRELATION_VECTOR) {
485 correlationVectorFound = true;
486 ASSERT_TRUE(measurement.correlationVectors.size() > 0);
487 for (const auto& correlationVector : measurement.correlationVectors) {
488 ASSERT_GE(correlationVector.frequencyOffsetMps, 0);
489 ASSERT_GT(correlationVector.samplingWidthM, 0);
490 ASSERT_TRUE(correlationVector.magnitude.size() > 0);
491 for (const auto& magnitude : correlationVector.magnitude) {
492 ASSERT_TRUE(magnitude >= -32768 && magnitude <= 32767);
493 }
494 }
495 }
496 }
497 }
498 ASSERT_TRUE(correlationVectorFound);
499
500 status = iGnssMeasurement->close();
501 ASSERT_TRUE(status.isOk());
502 }
503
504 /*
505 * TestGnssPowerIndication
506 * 1. Gets the GnssPowerIndicationExtension.
507 * 2. Sets a GnssPowerIndicationCallback.
508 * 3. Requests and verifies the 1st GnssPowerStats is received.
509 * 4. Gets a location.
510 * 5. Requests the 2nd GnssPowerStats, and verifies it has larger values than the 1st one.
511 */
TEST_P(GnssHalTest,TestGnssPowerIndication)512 TEST_P(GnssHalTest, TestGnssPowerIndication) {
513 // Set up gnssPowerIndication and callback
514 sp<IGnssPowerIndication> iGnssPowerIndication;
515 auto status = aidl_gnss_hal_->getExtensionGnssPowerIndication(&iGnssPowerIndication);
516 ASSERT_TRUE(status.isOk());
517 ASSERT_TRUE(iGnssPowerIndication != nullptr);
518
519 auto gnssPowerIndicationCallback = sp<GnssPowerIndicationCallback>::make();
520 status = iGnssPowerIndication->setCallback(gnssPowerIndicationCallback);
521 ASSERT_TRUE(status.isOk());
522
523 const int kTimeoutSec = 2;
524 EXPECT_TRUE(gnssPowerIndicationCallback->capabilities_cbq_.retrieve(
525 gnssPowerIndicationCallback->last_capabilities_, kTimeoutSec));
526
527 EXPECT_EQ(gnssPowerIndicationCallback->capabilities_cbq_.calledCount(), 1);
528
529 if (gnssPowerIndicationCallback->last_capabilities_ == 0) {
530 // Skipping the test since GnssPowerIndication is not supported.
531 return;
532 }
533
534 // Request and verify a GnssPowerStats is received
535 gnssPowerIndicationCallback->gnss_power_stats_cbq_.reset();
536 iGnssPowerIndication->requestGnssPowerStats();
537
538 EXPECT_TRUE(gnssPowerIndicationCallback->gnss_power_stats_cbq_.retrieve(
539 gnssPowerIndicationCallback->last_gnss_power_stats_, kTimeoutSec));
540 EXPECT_EQ(gnssPowerIndicationCallback->gnss_power_stats_cbq_.calledCount(), 1);
541 auto powerStats1 = gnssPowerIndicationCallback->last_gnss_power_stats_;
542
543 // Get a location and request another GnssPowerStats
544 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
545 gnss_cb_->location_cbq_.reset();
546 } else {
547 aidl_gnss_cb_->location_cbq_.reset();
548 }
549 StartAndCheckFirstLocation(/* min_interval_msec= */ 1000, /* low_power_mode= */ false);
550
551 // Request and verify the 2nd GnssPowerStats has larger values than the 1st one
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(), 2);
557
558 auto powerStats2 = gnssPowerIndicationCallback->last_gnss_power_stats_;
559
560 if ((gnssPowerIndicationCallback->last_capabilities_ &
561 (int)GnssPowerIndicationCallback::CAPABILITY_TOTAL)) {
562 // Elapsed realtime must increase
563 EXPECT_GT(powerStats2.elapsedRealtime.timestampNs, powerStats1.elapsedRealtime.timestampNs);
564
565 // Total energy must increase
566 EXPECT_GT(powerStats2.totalEnergyMilliJoule, powerStats1.totalEnergyMilliJoule);
567 }
568
569 // At least oone of singleband and multiband acquisition energy must increase
570 bool singlebandAcqEnergyIncreased = powerStats2.singlebandAcquisitionModeEnergyMilliJoule >
571 powerStats1.singlebandAcquisitionModeEnergyMilliJoule;
572 bool multibandAcqEnergyIncreased = powerStats2.multibandAcquisitionModeEnergyMilliJoule >
573 powerStats1.multibandAcquisitionModeEnergyMilliJoule;
574
575 if ((gnssPowerIndicationCallback->last_capabilities_ &
576 (int)GnssPowerIndicationCallback::CAPABILITY_SINGLEBAND_ACQUISITION) ||
577 (gnssPowerIndicationCallback->last_capabilities_ &
578 (int)GnssPowerIndicationCallback::CAPABILITY_MULTIBAND_ACQUISITION)) {
579 EXPECT_TRUE(singlebandAcqEnergyIncreased || multibandAcqEnergyIncreased);
580 }
581
582 // At least one of singleband and multiband tracking energy must increase
583 bool singlebandTrackingEnergyIncreased = powerStats2.singlebandTrackingModeEnergyMilliJoule >
584 powerStats1.singlebandTrackingModeEnergyMilliJoule;
585 bool multibandTrackingEnergyIncreased = powerStats2.multibandTrackingModeEnergyMilliJoule >
586 powerStats1.multibandTrackingModeEnergyMilliJoule;
587 if ((gnssPowerIndicationCallback->last_capabilities_ &
588 (int)GnssPowerIndicationCallback::CAPABILITY_SINGLEBAND_TRACKING) ||
589 (gnssPowerIndicationCallback->last_capabilities_ &
590 (int)GnssPowerIndicationCallback::CAPABILITY_MULTIBAND_TRACKING)) {
591 EXPECT_TRUE(singlebandTrackingEnergyIncreased || multibandTrackingEnergyIncreased);
592 }
593
594 // Clean up
595 StopAndClearLocations();
596 }
597
598 /*
599 * BlocklistIndividualSatellites:
600 *
601 * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
602 * GnssStatus for common satellites (strongest and one other.)
603 * 2a & b) Turns off location, and blocklists common satellites.
604 * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
605 * GnssStatus does not use those satellites.
606 * 4a & b) Turns off location, and send in empty blocklist.
607 * 5a) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
608 * GnssStatus does re-use at least the previously strongest satellite
609 * 5b) Retry a few times, in case GNSS search strategy takes a while to reacquire even the
610 * formerly strongest satellite
611 */
TEST_P(GnssHalTest,BlocklistIndividualSatellites)612 TEST_P(GnssHalTest, BlocklistIndividualSatellites) {
613 if (!(aidl_gnss_cb_->last_capabilities_ &
614 (int)GnssCallbackAidl::CAPABILITY_SATELLITE_BLOCKLIST)) {
615 ALOGI("Test BlocklistIndividualSatellites skipped. SATELLITE_BLOCKLIST capability not "
616 "supported.");
617 return;
618 }
619
620 const int kLocationsToAwait = 3;
621 const int kRetriesToUnBlocklist = 10;
622
623 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
624 gnss_cb_->location_cbq_.reset();
625 } else {
626 aidl_gnss_cb_->location_cbq_.reset();
627 }
628 StartAndCheckLocations(kLocationsToAwait);
629 int location_called_count = (aidl_gnss_hal_->getInterfaceVersion() <= 1)
630 ? gnss_cb_->location_cbq_.calledCount()
631 : aidl_gnss_cb_->location_cbq_.calledCount();
632
633 // Tolerate 1 less sv status to handle edge cases in reporting.
634 int sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() <= 1)
635 ? gnss_cb_->sv_info_list_cbq_.size()
636 : aidl_gnss_cb_->sv_info_list_cbq_.size();
637 EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
638 ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
639 sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
640
641 /*
642 * Identify strongest SV seen at least kLocationsToAwait -1 times
643 * Why -1? To avoid test flakiness in case of (plausible) slight flakiness in strongest signal
644 * observability (one epoch RF null)
645 */
646
647 const int kGnssSvInfoListTimeout = 2;
648 BlocklistedSource source_to_blocklist;
649 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
650 std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_vec_list;
651 int count = gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec_list, sv_info_list_cbq_size,
652 kGnssSvInfoListTimeout);
653 ASSERT_EQ(count, sv_info_list_cbq_size);
654 source_to_blocklist =
655 FindStrongFrequentNonGpsSource(sv_info_vec_list, kLocationsToAwait - 1);
656 } else {
657 std::list<std::vector<IGnssCallback::GnssSvInfo>> sv_info_vec_list;
658 int count = aidl_gnss_cb_->sv_info_list_cbq_.retrieve(
659 sv_info_vec_list, sv_info_list_cbq_size, kGnssSvInfoListTimeout);
660 ASSERT_EQ(count, sv_info_list_cbq_size);
661 source_to_blocklist =
662 FindStrongFrequentNonGpsSource(sv_info_vec_list, kLocationsToAwait - 1);
663 }
664
665 if (source_to_blocklist.constellation == GnssConstellationType::UNKNOWN) {
666 // Cannot find a non-GPS satellite. Let the test pass.
667 ALOGD("Cannot find a non-GPS satellite. Letting the test pass.");
668 return;
669 }
670
671 // Stop locations, blocklist the common SV
672 StopAndClearLocations();
673
674 sp<IGnssConfiguration> gnss_configuration_hal;
675 auto status = aidl_gnss_hal_->getExtensionGnssConfiguration(&gnss_configuration_hal);
676 ASSERT_TRUE(status.isOk());
677 ASSERT_NE(gnss_configuration_hal, nullptr);
678
679 std::vector<BlocklistedSource> sources;
680 sources.resize(1);
681 sources[0] = source_to_blocklist;
682
683 status = gnss_configuration_hal->setBlocklist(sources);
684 ASSERT_TRUE(status.isOk());
685
686 // retry and ensure satellite not used
687 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
688 gnss_cb_->sv_info_list_cbq_.reset();
689 gnss_cb_->location_cbq_.reset();
690 } else {
691 aidl_gnss_cb_->sv_info_list_cbq_.reset();
692 aidl_gnss_cb_->location_cbq_.reset();
693 }
694
695 StartAndCheckLocations(kLocationsToAwait);
696
697 // early exit if test is being run with insufficient signal
698 location_called_count = (aidl_gnss_hal_->getInterfaceVersion() <= 1)
699 ? gnss_cb_->location_cbq_.calledCount()
700 : aidl_gnss_cb_->location_cbq_.calledCount();
701 if (location_called_count == 0) {
702 ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
703 }
704 ASSERT_TRUE(location_called_count > 0);
705
706 // Tolerate 1 less sv status to handle edge cases in reporting.
707 sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() <= 1)
708 ? gnss_cb_->sv_info_list_cbq_.size()
709 : aidl_gnss_cb_->sv_info_list_cbq_.size();
710 EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
711 ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
712 sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
713 for (int i = 0; i < sv_info_list_cbq_size; ++i) {
714 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
715 hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
716 gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
717 for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
718 auto& gnss_sv = sv_info_vec[iSv];
719 EXPECT_FALSE(
720 (gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) &&
721 (static_cast<GnssConstellationType>(gnss_sv.v2_0.constellation) ==
722 source_to_blocklist.constellation) &&
723 (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
724 }
725 } else {
726 std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
727 aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
728 for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
729 auto& gnss_sv = sv_info_vec[iSv];
730 EXPECT_FALSE((gnss_sv.svid == source_to_blocklist.svid) &&
731 (gnss_sv.constellation == source_to_blocklist.constellation) &&
732 (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
733 }
734 }
735 }
736
737 // clear blocklist and restart - this time updating the blocklist while location is still on
738 sources.resize(0);
739
740 status = gnss_configuration_hal->setBlocklist(sources);
741 ASSERT_TRUE(status.isOk());
742
743 bool strongest_sv_is_reobserved = false;
744 // do several loops awaiting a few locations, allowing non-immediate reacquisition strategies
745 int unblocklist_loops_remaining = kRetriesToUnBlocklist;
746 while (!strongest_sv_is_reobserved && (unblocklist_loops_remaining-- > 0)) {
747 StopAndClearLocations();
748
749 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
750 gnss_cb_->sv_info_list_cbq_.reset();
751 gnss_cb_->location_cbq_.reset();
752 } else {
753 aidl_gnss_cb_->sv_info_list_cbq_.reset();
754 aidl_gnss_cb_->location_cbq_.reset();
755 }
756 StartAndCheckLocations(kLocationsToAwait);
757
758 // early exit loop if test is being run with insufficient signal
759 location_called_count = (aidl_gnss_hal_->getInterfaceVersion() <= 1)
760 ? gnss_cb_->location_cbq_.calledCount()
761 : aidl_gnss_cb_->location_cbq_.calledCount();
762 if (location_called_count == 0) {
763 ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
764 }
765 ASSERT_TRUE(location_called_count > 0);
766
767 // Tolerate 1 less sv status to handle edge cases in reporting.
768 sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() <= 1)
769 ? gnss_cb_->sv_info_list_cbq_.size()
770 : aidl_gnss_cb_->sv_info_list_cbq_.size();
771 EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
772 ALOGD("Clear blocklist, observed %d GnssSvInfo, while awaiting %d Locations"
773 ", tries remaining %d",
774 sv_info_list_cbq_size, kLocationsToAwait, unblocklist_loops_remaining);
775
776 for (int i = 0; i < sv_info_list_cbq_size; ++i) {
777 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
778 hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
779 gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
780 for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
781 auto& gnss_sv = sv_info_vec[iSv];
782 if ((gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) &&
783 (static_cast<GnssConstellationType>(gnss_sv.v2_0.constellation) ==
784 source_to_blocklist.constellation) &&
785 (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX)) {
786 strongest_sv_is_reobserved = true;
787 break;
788 }
789 }
790 } else {
791 std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
792 aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
793 for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
794 auto& gnss_sv = sv_info_vec[iSv];
795 if ((gnss_sv.svid == source_to_blocklist.svid) &&
796 (gnss_sv.constellation == source_to_blocklist.constellation) &&
797 (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX)) {
798 strongest_sv_is_reobserved = true;
799 break;
800 }
801 }
802 }
803 if (strongest_sv_is_reobserved) break;
804 }
805 }
806 EXPECT_TRUE(strongest_sv_is_reobserved);
807 StopAndClearLocations();
808 }
809
810 /*
811 * BlocklistConstellationLocationOff:
812 *
813 * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
814 * GnssStatus for any non-GPS constellations.
815 * 2a & b) Turns off location, and blocklist first non-GPS constellations.
816 * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
817 * GnssStatus does not use any constellation but GPS.
818 * 4a & b) Clean up by turning off location, and send in empty blocklist.
819 */
TEST_P(GnssHalTest,BlocklistConstellationLocationOff)820 TEST_P(GnssHalTest, BlocklistConstellationLocationOff) {
821 if (!(aidl_gnss_cb_->last_capabilities_ &
822 (int)GnssCallbackAidl::CAPABILITY_SATELLITE_BLOCKLIST)) {
823 ALOGI("Test BlocklistConstellationLocationOff skipped. SATELLITE_BLOCKLIST capability not "
824 "supported.");
825 return;
826 }
827
828 const int kLocationsToAwait = 3;
829 const int kGnssSvInfoListTimeout = 2;
830
831 // Find first non-GPS constellation to blocklist
832 GnssConstellationType constellation_to_blocklist = static_cast<GnssConstellationType>(
833 startLocationAndGetNonGpsConstellation(kLocationsToAwait, kGnssSvInfoListTimeout));
834
835 // Turns off location
836 StopAndClearLocations();
837
838 BlocklistedSource source_to_blocklist_1;
839 source_to_blocklist_1.constellation = constellation_to_blocklist;
840 source_to_blocklist_1.svid = 0; // documented wildcard for all satellites in this constellation
841
842 // IRNSS was added in 2.0. Always attempt to blocklist IRNSS to verify that the new enum is
843 // supported.
844 BlocklistedSource source_to_blocklist_2;
845 source_to_blocklist_2.constellation = GnssConstellationType::IRNSS;
846 source_to_blocklist_2.svid = 0; // documented wildcard for all satellites in this constellation
847
848 sp<IGnssConfiguration> gnss_configuration_hal;
849 auto status = aidl_gnss_hal_->getExtensionGnssConfiguration(&gnss_configuration_hal);
850 ASSERT_TRUE(status.isOk());
851 ASSERT_NE(gnss_configuration_hal, nullptr);
852
853 hidl_vec<BlocklistedSource> sources;
854 sources.resize(2);
855 sources[0] = source_to_blocklist_1;
856 sources[1] = source_to_blocklist_2;
857
858 status = gnss_configuration_hal->setBlocklist(sources);
859 ASSERT_TRUE(status.isOk());
860
861 // retry and ensure constellation not used
862 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
863 gnss_cb_->sv_info_list_cbq_.reset();
864 gnss_cb_->location_cbq_.reset();
865 } else {
866 aidl_gnss_cb_->sv_info_list_cbq_.reset();
867 aidl_gnss_cb_->location_cbq_.reset();
868 }
869 StartAndCheckLocations(kLocationsToAwait);
870
871 // Tolerate 1 less sv status to handle edge cases in reporting.
872 int sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() <= 1)
873 ? gnss_cb_->sv_info_list_cbq_.size()
874 : aidl_gnss_cb_->sv_info_list_cbq_.size();
875 EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
876 ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations", sv_info_list_cbq_size,
877 kLocationsToAwait);
878 for (int i = 0; i < sv_info_list_cbq_size; ++i) {
879 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
880 hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
881 gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
882 for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
883 const auto& gnss_sv = sv_info_vec[iSv];
884 EXPECT_FALSE(
885 (static_cast<GnssConstellationType>(gnss_sv.v2_0.constellation) ==
886 source_to_blocklist_1.constellation) &&
887 (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
888 EXPECT_FALSE(
889 (static_cast<GnssConstellationType>(gnss_sv.v2_0.constellation) ==
890 source_to_blocklist_2.constellation) &&
891 (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
892 }
893 } else {
894 std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
895 aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
896 for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
897 const auto& gnss_sv = sv_info_vec[iSv];
898 EXPECT_FALSE((gnss_sv.constellation == source_to_blocklist_1.constellation) &&
899 (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
900 EXPECT_FALSE((gnss_sv.constellation == source_to_blocklist_2.constellation) &&
901 (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
902 }
903 }
904 }
905
906 // clean up
907 StopAndClearLocations();
908 sources.resize(0);
909 status = gnss_configuration_hal->setBlocklist(sources);
910 ASSERT_TRUE(status.isOk());
911 }
912
913 /*
914 * BlocklistConstellationLocationOn:
915 *
916 * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
917 * GnssStatus for any non-GPS constellations.
918 * 2a & b) Blocklist first non-GPS constellation, and turn off location.
919 * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
920 * GnssStatus does not use any constellation but GPS.
921 * 4a & b) Clean up by turning off location, and send in empty blocklist.
922 */
TEST_P(GnssHalTest,BlocklistConstellationLocationOn)923 TEST_P(GnssHalTest, BlocklistConstellationLocationOn) {
924 if (!(aidl_gnss_cb_->last_capabilities_ &
925 (int)GnssCallbackAidl::CAPABILITY_SATELLITE_BLOCKLIST)) {
926 ALOGI("Test BlocklistConstellationLocationOn skipped. SATELLITE_BLOCKLIST capability not "
927 "supported.");
928 return;
929 }
930
931 const int kLocationsToAwait = 3;
932 const int kGnssSvInfoListTimeout = 2;
933
934 // Find first non-GPS constellation to blocklist
935 GnssConstellationType constellation_to_blocklist = static_cast<GnssConstellationType>(
936 startLocationAndGetNonGpsConstellation(kLocationsToAwait, kGnssSvInfoListTimeout));
937
938 BlocklistedSource source_to_blocklist_1;
939 source_to_blocklist_1.constellation = constellation_to_blocklist;
940 source_to_blocklist_1.svid = 0; // documented wildcard for all satellites in this constellation
941
942 // IRNSS was added in 2.0. Always attempt to blocklist IRNSS to verify that the new enum is
943 // supported.
944 BlocklistedSource source_to_blocklist_2;
945 source_to_blocklist_2.constellation = GnssConstellationType::IRNSS;
946 source_to_blocklist_2.svid = 0; // documented wildcard for all satellites in this constellation
947
948 sp<IGnssConfiguration> gnss_configuration_hal;
949 auto status = aidl_gnss_hal_->getExtensionGnssConfiguration(&gnss_configuration_hal);
950 ASSERT_TRUE(status.isOk());
951 ASSERT_NE(gnss_configuration_hal, nullptr);
952
953 hidl_vec<BlocklistedSource> sources;
954 sources.resize(2);
955 sources[0] = source_to_blocklist_1;
956 sources[1] = source_to_blocklist_2;
957
958 status = gnss_configuration_hal->setBlocklist(sources);
959 ASSERT_TRUE(status.isOk());
960
961 // Turns off location
962 StopAndClearLocations();
963
964 // retry and ensure constellation not used
965 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
966 gnss_cb_->sv_info_list_cbq_.reset();
967 gnss_cb_->location_cbq_.reset();
968 } else {
969 aidl_gnss_cb_->sv_info_list_cbq_.reset();
970 aidl_gnss_cb_->location_cbq_.reset();
971 }
972 StartAndCheckLocations(kLocationsToAwait);
973
974 // Tolerate 1 less sv status to handle edge cases in reporting.
975 int sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() <= 1)
976 ? gnss_cb_->sv_info_list_cbq_.size()
977 : aidl_gnss_cb_->sv_info_list_cbq_.size();
978 EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
979 ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations", sv_info_list_cbq_size,
980 kLocationsToAwait);
981 for (int i = 0; i < sv_info_list_cbq_size; ++i) {
982 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
983 hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
984 gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
985 for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
986 const auto& gnss_sv = sv_info_vec[iSv];
987 EXPECT_FALSE(
988 (static_cast<GnssConstellationType>(gnss_sv.v2_0.constellation) ==
989 source_to_blocklist_1.constellation) &&
990 (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
991 EXPECT_FALSE(
992 (static_cast<GnssConstellationType>(gnss_sv.v2_0.constellation) ==
993 source_to_blocklist_2.constellation) &&
994 (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
995 }
996 } else {
997 std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
998 aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
999 for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
1000 const auto& gnss_sv = sv_info_vec[iSv];
1001 EXPECT_FALSE((gnss_sv.constellation == source_to_blocklist_1.constellation) &&
1002 (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
1003 EXPECT_FALSE((gnss_sv.constellation == source_to_blocklist_2.constellation) &&
1004 (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
1005 }
1006 }
1007 }
1008
1009 // clean up
1010 StopAndClearLocations();
1011 sources.resize(0);
1012 status = gnss_configuration_hal->setBlocklist(sources);
1013 ASSERT_TRUE(status.isOk());
1014 }
1015
1016 /*
1017 * TestAllExtensions.
1018 */
TEST_P(GnssHalTest,TestAllExtensions)1019 TEST_P(GnssHalTest, TestAllExtensions) {
1020 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
1021 return;
1022 }
1023
1024 sp<IGnssBatching> iGnssBatching;
1025 auto status = aidl_gnss_hal_->getExtensionGnssBatching(&iGnssBatching);
1026 if (status.isOk() && iGnssBatching != nullptr) {
1027 auto gnssBatchingCallback = sp<GnssBatchingCallback>::make();
1028 status = iGnssBatching->init(gnssBatchingCallback);
1029 ASSERT_TRUE(status.isOk());
1030
1031 status = iGnssBatching->cleanup();
1032 ASSERT_TRUE(status.isOk());
1033 }
1034
1035 sp<IGnssGeofence> iGnssGeofence;
1036 status = aidl_gnss_hal_->getExtensionGnssGeofence(&iGnssGeofence);
1037 if (status.isOk() && iGnssGeofence != nullptr) {
1038 auto gnssGeofenceCallback = sp<GnssGeofenceCallback>::make();
1039 status = iGnssGeofence->setCallback(gnssGeofenceCallback);
1040 ASSERT_TRUE(status.isOk());
1041 }
1042
1043 sp<IGnssNavigationMessageInterface> iGnssNavMsgIface;
1044 status = aidl_gnss_hal_->getExtensionGnssNavigationMessage(&iGnssNavMsgIface);
1045 if (status.isOk() && iGnssNavMsgIface != nullptr) {
1046 auto gnssNavMsgCallback = sp<GnssNavigationMessageCallback>::make();
1047 status = iGnssNavMsgIface->setCallback(gnssNavMsgCallback);
1048 ASSERT_TRUE(status.isOk());
1049
1050 status = iGnssNavMsgIface->close();
1051 ASSERT_TRUE(status.isOk());
1052 }
1053 }
1054
1055 /*
1056 * TestAGnssExtension:
1057 * 1. Gets the IAGnss extension.
1058 * 2. Sets AGnssCallback.
1059 * 3. Sets SUPL server host/port.
1060 */
TEST_P(GnssHalTest,TestAGnssExtension)1061 TEST_P(GnssHalTest, TestAGnssExtension) {
1062 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
1063 return;
1064 }
1065 sp<IAGnss> iAGnss;
1066 auto status = aidl_gnss_hal_->getExtensionAGnss(&iAGnss);
1067 ASSERT_TRUE(status.isOk());
1068 ASSERT_TRUE(iAGnss != nullptr);
1069
1070 auto agnssCallback = sp<AGnssCallbackAidl>::make();
1071 status = iAGnss->setCallback(agnssCallback);
1072 ASSERT_TRUE(status.isOk());
1073
1074 // Set SUPL server host/port
1075 status = iAGnss->setServer(AGnssType::SUPL, std::string("supl.google.com"), 7275);
1076 ASSERT_TRUE(status.isOk());
1077 }
1078
1079 /*
1080 * TestAGnssRilExtension:
1081 * 1. Gets the IAGnssRil extension.
1082 * 2. Sets AGnssRilCallback.
1083 * 3. Update network state to connected and then disconnected.
1084 * 4. Sets reference location.
1085 */
TEST_P(GnssHalTest,TestAGnssRilExtension)1086 TEST_P(GnssHalTest, TestAGnssRilExtension) {
1087 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
1088 return;
1089 }
1090 sp<IAGnssRil> iAGnssRil;
1091 auto status = aidl_gnss_hal_->getExtensionAGnssRil(&iAGnssRil);
1092 ASSERT_TRUE(status.isOk());
1093 ASSERT_TRUE(iAGnssRil != nullptr);
1094
1095 auto agnssRilCallback = sp<AGnssRilCallbackAidl>::make();
1096 status = iAGnssRil->setCallback(agnssRilCallback);
1097 ASSERT_TRUE(status.isOk());
1098
1099 // Update GNSS HAL that a network has connected.
1100 IAGnssRil::NetworkAttributes networkAttributes;
1101 networkAttributes.networkHandle = 7700664333L;
1102 networkAttributes.isConnected = true;
1103 networkAttributes.capabilities = IAGnssRil::NETWORK_CAPABILITY_NOT_ROAMING;
1104 networkAttributes.apn = "placeholder-apn";
1105 status = iAGnssRil->updateNetworkState(networkAttributes);
1106 ASSERT_TRUE(status.isOk());
1107
1108 // Update GNSS HAL that network has disconnected.
1109 networkAttributes.isConnected = false;
1110 status = iAGnssRil->updateNetworkState(networkAttributes);
1111 ASSERT_TRUE(status.isOk());
1112
1113 // Set RefLocation
1114 IAGnssRil::AGnssRefLocationCellID agnssReflocationCellId;
1115 agnssReflocationCellId.type = IAGnssRil::AGnssRefLocationType::LTE_CELLID;
1116 agnssReflocationCellId.mcc = 466;
1117 agnssReflocationCellId.mnc = 97;
1118 agnssReflocationCellId.lac = 46697;
1119 agnssReflocationCellId.cid = 59168142;
1120 agnssReflocationCellId.pcid = 420;
1121 agnssReflocationCellId.tac = 11460;
1122 IAGnssRil::AGnssRefLocation agnssReflocation;
1123 agnssReflocation.type = IAGnssRil::AGnssRefLocationType::LTE_CELLID;
1124 agnssReflocation.cellID = agnssReflocationCellId;
1125
1126 status = iAGnssRil->setRefLocation(agnssReflocation);
1127 ASSERT_TRUE(status.isOk());
1128 }
1129
1130 /*
1131 * GnssDebugValuesSanityTest:
1132 * Ensures that GnssDebug values make sense.
1133 */
TEST_P(GnssHalTest,GnssDebugValuesSanityTest)1134 TEST_P(GnssHalTest, GnssDebugValuesSanityTest) {
1135 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
1136 return;
1137 }
1138 sp<IGnssDebug> iGnssDebug;
1139 auto status = aidl_gnss_hal_->getExtensionGnssDebug(&iGnssDebug);
1140 ASSERT_TRUE(status.isOk());
1141
1142 if (!IsAutomotiveDevice()) {
1143 ASSERT_TRUE(iGnssDebug != nullptr);
1144
1145 IGnssDebug::DebugData data;
1146 auto status = iGnssDebug->getDebugData(&data);
1147 ASSERT_TRUE(status.isOk());
1148
1149 if (data.position.valid) {
1150 ASSERT_TRUE(data.position.latitudeDegrees >= -90 &&
1151 data.position.latitudeDegrees <= 90);
1152 ASSERT_TRUE(data.position.longitudeDegrees >= -180 &&
1153 data.position.longitudeDegrees <= 180);
1154 ASSERT_TRUE(data.position.altitudeMeters >= -1000 && // Dead Sea: -414m
1155 data.position.altitudeMeters <= 20000); // Mount Everest: 8850m
1156 ASSERT_TRUE(data.position.speedMetersPerSec >= 0 &&
1157 data.position.speedMetersPerSec <= 600);
1158 ASSERT_TRUE(data.position.bearingDegrees >= -360 &&
1159 data.position.bearingDegrees <= 360);
1160 ASSERT_TRUE(data.position.horizontalAccuracyMeters > 0 &&
1161 data.position.horizontalAccuracyMeters <= 20000000);
1162 ASSERT_TRUE(data.position.verticalAccuracyMeters > 0 &&
1163 data.position.verticalAccuracyMeters <= 20000);
1164 ASSERT_TRUE(data.position.speedAccuracyMetersPerSecond > 0 &&
1165 data.position.speedAccuracyMetersPerSecond <= 500);
1166 ASSERT_TRUE(data.position.bearingAccuracyDegrees > 0 &&
1167 data.position.bearingAccuracyDegrees <= 180);
1168 ASSERT_TRUE(data.position.ageSeconds >= 0);
1169 }
1170 ASSERT_TRUE(data.time.timeEstimateMs >= 1483228800000); // Jan 01 2017 00:00:00 GMT.
1171 ASSERT_TRUE(data.time.timeUncertaintyNs > 0);
1172 ASSERT_TRUE(data.time.frequencyUncertaintyNsPerSec > 0 &&
1173 data.time.frequencyUncertaintyNsPerSec <= 2.0e5); // 200 ppm
1174 }
1175 }
1176
1177 /*
1178 * TestGnssVisibilityControlExtension:
1179 * 1. Gets the IGnssVisibilityControl extension.
1180 * 2. Sets GnssVisibilityControlCallback
1181 * 3. Sets proxy apps
1182 */
TEST_P(GnssHalTest,TestGnssVisibilityControlExtension)1183 TEST_P(GnssHalTest, TestGnssVisibilityControlExtension) {
1184 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
1185 return;
1186 }
1187 sp<IGnssVisibilityControl> iGnssVisibilityControl;
1188 auto status = aidl_gnss_hal_->getExtensionGnssVisibilityControl(&iGnssVisibilityControl);
1189 ASSERT_TRUE(status.isOk());
1190 ASSERT_TRUE(iGnssVisibilityControl != nullptr);
1191 auto gnssVisibilityControlCallback = sp<GnssVisibilityControlCallback>::make();
1192 status = iGnssVisibilityControl->setCallback(gnssVisibilityControlCallback);
1193 ASSERT_TRUE(status.isOk());
1194
1195 std::vector<std::string> proxyApps{std::string("com.example.ims"),
1196 std::string("com.example.mdt")};
1197 status = iGnssVisibilityControl->enableNfwLocationAccess(proxyApps);
1198 ASSERT_TRUE(status.isOk());
1199 }
1200
1201 /*
1202 * TestGnssAgcInGnssMeasurement:
1203 * 1. Gets the GnssMeasurementExtension and verifies that it returns a non-null extension.
1204 * 2. Sets a GnssMeasurementCallback, waits for a measurement.
1205 */
TEST_P(GnssHalTest,TestGnssAgcInGnssMeasurement)1206 TEST_P(GnssHalTest, TestGnssAgcInGnssMeasurement) {
1207 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
1208 return;
1209 }
1210 const int kFirstGnssMeasurementTimeoutSeconds = 10;
1211 const int kNumMeasurementEvents = 5;
1212
1213 sp<IGnssMeasurementInterface> iGnssMeasurement;
1214 auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
1215 ASSERT_TRUE(status.isOk());
1216 ASSERT_TRUE(iGnssMeasurement != nullptr);
1217
1218 auto callback = sp<GnssMeasurementCallbackAidl>::make();
1219 status = iGnssMeasurement->setCallback(callback, /* enableFullTracking= */ false,
1220 /* enableCorrVecOutputs */ false);
1221 ASSERT_TRUE(status.isOk());
1222
1223 for (int i = 0; i < kNumMeasurementEvents; i++) {
1224 GnssData lastMeasurement;
1225 ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastMeasurement,
1226 kFirstGnssMeasurementTimeoutSeconds));
1227 EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), i + 1);
1228 ASSERT_TRUE(lastMeasurement.measurements.size() > 0);
1229
1230 // Validity check GnssData fields
1231 checkGnssMeasurementClockFields(lastMeasurement);
1232
1233 ASSERT_TRUE(lastMeasurement.gnssAgcs.size() > 0);
1234 for (const auto& gnssAgc : lastMeasurement.gnssAgcs) {
1235 ASSERT_TRUE(gnssAgc.carrierFrequencyHz >= 0);
1236 }
1237 }
1238
1239 status = iGnssMeasurement->close();
1240 ASSERT_TRUE(status.isOk());
1241 }
1242
1243 /*
1244 * TestGnssAntennaInfo:
1245 * Sets a GnssAntennaInfoCallback, waits for report, and verifies
1246 * 1. phaseCenterOffsetCoordinateMillimeters is valid
1247 * 2. phaseCenterOffsetCoordinateUncertaintyMillimeters is valid.
1248 * PhaseCenterVariationCorrections and SignalGainCorrections are optional.
1249 */
TEST_P(GnssHalTest,TestGnssAntennaInfo)1250 TEST_P(GnssHalTest, TestGnssAntennaInfo) {
1251 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
1252 return;
1253 }
1254
1255 const int kAntennaInfoTimeoutSeconds = 2;
1256 sp<IGnssAntennaInfo> iGnssAntennaInfo;
1257 auto status = aidl_gnss_hal_->getExtensionGnssAntennaInfo(&iGnssAntennaInfo);
1258 ASSERT_TRUE(status.isOk());
1259
1260 if (!(aidl_gnss_cb_->last_capabilities_ & (int)GnssCallbackAidl::CAPABILITY_ANTENNA_INFO) ||
1261 iGnssAntennaInfo == nullptr) {
1262 ALOGD("GnssAntennaInfo AIDL is not supported.");
1263 return;
1264 }
1265
1266 auto callback = sp<GnssAntennaInfoCallbackAidl>::make();
1267 status = iGnssAntennaInfo->setCallback(callback);
1268 ASSERT_TRUE(status.isOk());
1269
1270 std::vector<IGnssAntennaInfoCallback::GnssAntennaInfo> antennaInfos;
1271 ASSERT_TRUE(callback->antenna_info_cbq_.retrieve(antennaInfos, kAntennaInfoTimeoutSeconds));
1272 EXPECT_EQ(callback->antenna_info_cbq_.calledCount(), 1);
1273 ASSERT_TRUE(antennaInfos.size() > 0);
1274
1275 for (auto antennaInfo : antennaInfos) {
1276 // Remaining fields are optional
1277 if (!antennaInfo.phaseCenterVariationCorrectionMillimeters.empty()) {
1278 int numRows = antennaInfo.phaseCenterVariationCorrectionMillimeters.size();
1279 int numColumns = antennaInfo.phaseCenterVariationCorrectionMillimeters[0].row.size();
1280 // Must have at least 1 row and 2 columns
1281 ASSERT_TRUE(numRows >= 1 && numColumns >= 2);
1282
1283 // Corrections and uncertainties must have same dimensions
1284 ASSERT_TRUE(antennaInfo.phaseCenterVariationCorrectionMillimeters.size() ==
1285 antennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters.size());
1286 ASSERT_TRUE(
1287 antennaInfo.phaseCenterVariationCorrectionMillimeters[0].row.size() ==
1288 antennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters[0].row.size());
1289
1290 // Must be rectangular
1291 for (auto row : antennaInfo.phaseCenterVariationCorrectionMillimeters) {
1292 ASSERT_TRUE(row.row.size() == numColumns);
1293 }
1294 for (auto row : antennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters) {
1295 ASSERT_TRUE(row.row.size() == numColumns);
1296 }
1297 }
1298 if (!antennaInfo.signalGainCorrectionDbi.empty()) {
1299 int numRows = antennaInfo.signalGainCorrectionDbi.size();
1300 int numColumns = antennaInfo.signalGainCorrectionUncertaintyDbi[0].row.size();
1301 // Must have at least 1 row and 2 columns
1302 ASSERT_TRUE(numRows >= 1 && numColumns >= 2);
1303
1304 // Corrections and uncertainties must have same dimensions
1305 ASSERT_TRUE(antennaInfo.signalGainCorrectionDbi.size() ==
1306 antennaInfo.signalGainCorrectionUncertaintyDbi.size());
1307 ASSERT_TRUE(antennaInfo.signalGainCorrectionDbi[0].row.size() ==
1308 antennaInfo.signalGainCorrectionUncertaintyDbi[0].row.size());
1309
1310 // Must be rectangular
1311 for (auto row : antennaInfo.signalGainCorrectionDbi) {
1312 ASSERT_TRUE(row.row.size() == numColumns);
1313 }
1314 for (auto row : antennaInfo.signalGainCorrectionUncertaintyDbi) {
1315 ASSERT_TRUE(row.row.size() == numColumns);
1316 }
1317 }
1318 }
1319
1320 iGnssAntennaInfo->close();
1321 }
1322
1323 /*
1324 * TestGnssMeasurementCorrections:
1325 * If measurement corrections capability is supported, verifies that the measurement corrections
1326 * capabilities are reported and the mandatory LOS_SATS or the EXCESS_PATH_LENGTH
1327 * capability flag is set.
1328 */
TEST_P(GnssHalTest,TestGnssMeasurementCorrections)1329 TEST_P(GnssHalTest, TestGnssMeasurementCorrections) {
1330 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
1331 return;
1332 }
1333 if (!(aidl_gnss_cb_->last_capabilities_ &
1334 (int)GnssCallbackAidl::CAPABILITY_MEASUREMENT_CORRECTIONS)) {
1335 return;
1336 }
1337
1338 sp<IMeasurementCorrectionsInterface> iMeasurementCorrectionsAidl;
1339 auto status = aidl_gnss_hal_->getExtensionMeasurementCorrections(&iMeasurementCorrectionsAidl);
1340 ASSERT_TRUE(status.isOk());
1341 ASSERT_TRUE(iMeasurementCorrectionsAidl != nullptr);
1342
1343 // Setup measurement corrections callback.
1344 auto gnssMeasurementCorrectionsCallback = sp<MeasurementCorrectionsCallback>::make();
1345 status = iMeasurementCorrectionsAidl->setCallback(gnssMeasurementCorrectionsCallback);
1346 ASSERT_TRUE(status.isOk());
1347
1348 const int kTimeoutSec = 5;
1349 EXPECT_TRUE(gnssMeasurementCorrectionsCallback->capabilities_cbq_.retrieve(
1350 gnssMeasurementCorrectionsCallback->last_capabilities_, kTimeoutSec));
1351 ASSERT_TRUE(gnssMeasurementCorrectionsCallback->capabilities_cbq_.calledCount() > 0);
1352
1353 ASSERT_TRUE((gnssMeasurementCorrectionsCallback->last_capabilities_ &
1354 (MeasurementCorrectionsCallback::CAPABILITY_LOS_SATS |
1355 MeasurementCorrectionsCallback::CAPABILITY_EXCESS_PATH_LENGTH)) != 0);
1356
1357 // Set a mock MeasurementCorrections.
1358 status = iMeasurementCorrectionsAidl->setCorrections(
1359 Utils::getMockMeasurementCorrections_aidl());
1360 ASSERT_TRUE(status.isOk());
1361 }
1362
1363 /*
1364 * TestStopSvStatusAndNmea:
1365 * 1. Call stopSvStatus and stopNmea.
1366 * 2. Start location and verify that
1367 * - no SvStatus is received.
1368 * - no Nmea is received.
1369 */
TEST_P(GnssHalTest,TestStopSvStatusAndNmea)1370 TEST_P(GnssHalTest, TestStopSvStatusAndNmea) {
1371 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
1372 return;
1373 }
1374 auto status = aidl_gnss_hal_->stopSvStatus();
1375 EXPECT_TRUE(status.isOk());
1376 status = aidl_gnss_hal_->stopNmea();
1377 EXPECT_TRUE(status.isOk());
1378
1379 int kLocationsToAwait = 5;
1380 aidl_gnss_cb_->location_cbq_.reset();
1381 aidl_gnss_cb_->sv_info_list_cbq_.reset();
1382 aidl_gnss_cb_->nmea_cbq_.reset();
1383 StartAndCheckLocations(/* count= */ kLocationsToAwait,
1384 /* start_sv_status= */ false, /* start_nmea= */ false);
1385 int location_called_count = aidl_gnss_cb_->location_cbq_.calledCount();
1386 ALOGD("Observed %d GnssSvStatus, and %d Nmea while awaiting %d locations (%d received)",
1387 aidl_gnss_cb_->sv_info_list_cbq_.size(), aidl_gnss_cb_->nmea_cbq_.size(),
1388 kLocationsToAwait, location_called_count);
1389
1390 // Ensure that no SvStatus & no Nmea is received.
1391 EXPECT_EQ(aidl_gnss_cb_->sv_info_list_cbq_.size(), 0);
1392 EXPECT_EQ(aidl_gnss_cb_->nmea_cbq_.size(), 0);
1393
1394 StopAndClearLocations();
1395 }
1396
1397 /*
1398 * TestGnssMeasurementIntervals_WithoutLocation:
1399 * 1. start measurement with interval
1400 * 2. verify that the received measurement intervals have expected mean and stdev
1401 */
TEST_P(GnssHalTest,TestGnssMeasurementIntervals_WithoutLocation)1402 TEST_P(GnssHalTest, TestGnssMeasurementIntervals_WithoutLocation) {
1403 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
1404 return;
1405 }
1406
1407 std::vector<int> intervals({2000, 4000});
1408 std::vector<int> numEvents({10, 5});
1409
1410 sp<IGnssMeasurementInterface> iGnssMeasurement;
1411 auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
1412 ASSERT_TRUE(status.isOk());
1413 ASSERT_TRUE(iGnssMeasurement != nullptr);
1414
1415 ALOGD("TestGnssMeasurementIntervals_WithoutLocation");
1416 for (int i = 0; i < intervals.size(); i++) {
1417 auto callback = sp<GnssMeasurementCallbackAidl>::make();
1418 startMeasurementWithInterval(intervals[i], iGnssMeasurement, callback);
1419
1420 std::vector<int> deltas;
1421 collectMeasurementIntervals(callback, numEvents[i], /* timeoutSeconds= */ 10, deltas);
1422
1423 status = iGnssMeasurement->close();
1424 ASSERT_TRUE(status.isOk());
1425
1426 assertMeanAndStdev(intervals[i], deltas);
1427 }
1428 }
1429
1430 /*
1431 * TestGnssMeasurementIntervals_LocationOnBeforeMeasurement:
1432 * 1. start measurement with interval
1433 * 2. verify that the received measurement intervals have expected mean and stdev
1434 */
TEST_P(GnssHalTest,TestGnssMeasurementIntervals_LocationOnBeforeMeasurement)1435 TEST_P(GnssHalTest, TestGnssMeasurementIntervals_LocationOnBeforeMeasurement) {
1436 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
1437 return;
1438 }
1439
1440 std::vector<int> intervals({2000});
1441
1442 sp<IGnssMeasurementInterface> iGnssMeasurement;
1443 auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
1444 ASSERT_TRUE(status.isOk());
1445 ASSERT_TRUE(iGnssMeasurement != nullptr);
1446
1447 int locationIntervalMs = 1000;
1448
1449 // Start location first and then start measurement
1450 ALOGD("TestGnssMeasurementIntervals_LocationOnBeforeMeasurement");
1451 StartAndCheckFirstLocation(locationIntervalMs, /* lowPowerMode= */ false);
1452 for (auto& intervalMs : intervals) {
1453 auto callback = sp<GnssMeasurementCallbackAidl>::make();
1454 startMeasurementWithInterval(intervalMs, iGnssMeasurement, callback);
1455
1456 std::vector<int> deltas;
1457 collectMeasurementIntervals(callback, /*numEvents=*/10, /*timeoutSeconds=*/10, deltas);
1458
1459 status = iGnssMeasurement->close();
1460 ASSERT_TRUE(status.isOk());
1461
1462 assertMeanAndStdev(locationIntervalMs, deltas);
1463 }
1464 StopAndClearLocations();
1465 }
1466
1467 /*
1468 * TestGnssMeasurementIntervals:
1469 * 1. start measurement with interval
1470 * 2. verify that the received measurement intervals have expected mean and stdev
1471 */
TEST_P(GnssHalTest,TestGnssMeasurementIntervals_LocationOnAfterMeasurement)1472 TEST_P(GnssHalTest, TestGnssMeasurementIntervals_LocationOnAfterMeasurement) {
1473 if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
1474 return;
1475 }
1476
1477 std::vector<int> intervals({2000});
1478
1479 sp<IGnssMeasurementInterface> iGnssMeasurement;
1480 auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
1481 ASSERT_TRUE(status.isOk());
1482 ASSERT_TRUE(iGnssMeasurement != nullptr);
1483
1484 int locationIntervalMs = 1000;
1485 // Start location first and then start measurement
1486 ALOGD("TestGnssMeasurementIntervals_LocationOnAfterMeasurement");
1487 for (auto& intervalMs : intervals) {
1488 auto callback = sp<GnssMeasurementCallbackAidl>::make();
1489 startMeasurementWithInterval(intervalMs, iGnssMeasurement, callback);
1490
1491 StartAndCheckFirstLocation(locationIntervalMs, /* lowPowerMode= */ false);
1492 std::vector<int> deltas;
1493 collectMeasurementIntervals(callback, /*numEvents=*/10, /*timeoutSeconds=*/10, deltas);
1494
1495 StopAndClearLocations();
1496 status = iGnssMeasurement->close();
1497 ASSERT_TRUE(status.isOk());
1498
1499 assertMeanAndStdev(locationIntervalMs, deltas);
1500 }
1501 }
1502