1 /*
2 * Copyright (C) 2017 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 <gnss_hal_test.h>
20
21 #include <android/hardware/gnss/1.1/IGnssConfiguration.h>
22 #include <cutils/properties.h>
23 #include <gtest/gtest.h>
24
25 using android::hardware::hidl_vec;
26
27 using IGnssMeasurement_1_0 = android::hardware::gnss::V1_0::IGnssMeasurement;
28 using IGnssMeasurement_1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
29
30 using android::hardware::gnss::V1_0::GnssConstellationType;
31 using android::hardware::gnss::V1_0::GnssLocation;
32 using android::hardware::gnss::V1_0::IGnssDebug;
33 using android::hardware::gnss::V1_1::IGnssConfiguration;
34 using android::hardware::gnss::V1_1::IGnssMeasurement;
35
IsAutomotiveDevice()36 static bool IsAutomotiveDevice() {
37 char buffer[PROPERTY_VALUE_MAX] = {0};
38 property_get("ro.hardware.type", buffer, "");
39 return strncmp(buffer, "automotive", PROPERTY_VALUE_MAX) == 0;
40 }
41
42 /*
43 * SetupTeardownCreateCleanup:
44 * Requests the gnss HAL then calls cleanup
45 *
46 * Empty test fixture to verify basic Setup & Teardown
47 */
TEST_P(GnssHalTest,SetupTeardownCreateCleanup)48 TEST_P(GnssHalTest, SetupTeardownCreateCleanup) {}
49
50 /*
51 * TestGnssMeasurementCallback:
52 * Gets the GnssMeasurementExtension and verify that it returns an actual extension.
53 */
TEST_P(GnssHalTest,TestGnssMeasurementCallback)54 TEST_P(GnssHalTest, TestGnssMeasurementCallback) {
55 auto gnssMeasurement_1_1 = gnss_hal_->getExtensionGnssMeasurement_1_1();
56 ASSERT_TRUE(gnssMeasurement_1_1.isOk());
57 auto gnssMeasurement_1_0 = gnss_hal_->getExtensionGnssMeasurement();
58 ASSERT_TRUE(gnssMeasurement_1_0.isOk());
59 if (gnss_cb_->last_capabilities_ & IGnssCallback::Capabilities::MEASUREMENTS) {
60 sp<IGnssMeasurement_1_1> iGnssMeas_1_1 = gnssMeasurement_1_1;
61 sp<IGnssMeasurement_1_0> iGnssMeas_1_0 = gnssMeasurement_1_0;
62 // At least one interface must be non-null.
63 ASSERT_TRUE(iGnssMeas_1_1 != nullptr || iGnssMeas_1_0 != nullptr);
64 }
65 }
66
67 /*
68 * GetLocationLowPower:
69 * Turns on location, waits for at least 5 locations allowing max of LOCATION_TIMEOUT_SUBSEQUENT_SEC
70 * between one location and the next. Also ensure that MIN_INTERVAL_MSEC is respected by waiting
71 * NO_LOCATION_PERIOD_SEC and verfiy that no location is received. Also perform validity checks on
72 * each received location.
73 */
TEST_P(GnssHalTest,GetLocationLowPower)74 TEST_P(GnssHalTest, GetLocationLowPower) {
75 if (!IsGnssHalVersion_1_1()) {
76 ALOGI("Test GetLocationLowPower skipped. GNSS HAL version is greater than 1.1.");
77 return;
78 }
79
80 const int kMinIntervalMsec = 5000;
81 const int kLocationTimeoutSubsequentSec = (kMinIntervalMsec / 1000) * 2;
82 const int kNoLocationPeriodSec = (kMinIntervalMsec / 1000) / 2;
83 const int kLocationsToCheck = 5;
84 const bool kLowPowerMode = true;
85
86 // Warmup period - VTS doesn't have AGPS access via GnssLocationProvider
87 gnss_cb_->location_cbq_.reset();
88 StartAndCheckLocations(kLocationsToCheck);
89 StopAndClearLocations();
90 gnss_cb_->location_cbq_.reset();
91
92 // Start of Low Power Mode test
93 // Don't expect true - as without AGPS access
94 if (!StartAndCheckFirstLocation(/* strict= */ false, kMinIntervalMsec, kLowPowerMode)) {
95 ALOGW("GetLocationLowPower test - no first low power location received.");
96 }
97
98 for (int i = 1; i < kLocationsToCheck; i++) {
99 // Verify that kMinIntervalMsec is respected by waiting kNoLocationPeriodSec and
100 // ensure that no location is received yet
101
102 gnss_cb_->location_cbq_.retrieve(gnss_cb_->last_location_, kNoLocationPeriodSec);
103 const int location_called_count = gnss_cb_->location_cbq_.calledCount();
104 // Tolerate (ignore) one extra location right after the first one
105 // to handle startup edge case scheduling limitations in some implementations
106 if ((i == 1) && (location_called_count == 2)) {
107 CheckLocation(gnss_cb_->last_location_, true);
108 continue; // restart the quiet wait period after this too-fast location
109 }
110 EXPECT_LE(location_called_count, i);
111 if (location_called_count != i) {
112 ALOGW("GetLocationLowPower test - not enough locations received. %d vs. %d expected ",
113 location_called_count, i);
114 }
115
116 if (!gnss_cb_->location_cbq_.retrieve(
117 gnss_cb_->last_location_,
118 kLocationTimeoutSubsequentSec - kNoLocationPeriodSec)) {
119 ALOGW("GetLocationLowPower test - timeout awaiting location %d", i);
120 } else {
121 CheckLocation(gnss_cb_->last_location_, true);
122 }
123 }
124
125 StopAndClearLocations();
126 }
127
128 /*
129 * FindStrongFrequentNonGpsSource:
130 *
131 * Search through a GnssSvStatus list for the strongest non-GPS satellite observed enough times
132 *
133 * returns the strongest source,
134 * or a source with constellation == UNKNOWN if none are found sufficient times
135 */
136
FindStrongFrequentNonGpsSource(const std::list<IGnssCallback::GnssSvStatus> list_gnss_sv_status,const int min_observations)137 IGnssConfiguration::BlacklistedSource FindStrongFrequentNonGpsSource(
138 const std::list<IGnssCallback::GnssSvStatus> list_gnss_sv_status,
139 const int min_observations) {
140 struct ComparableBlacklistedSource {
141 IGnssConfiguration::BlacklistedSource id;
142
143 ComparableBlacklistedSource() {
144 id.constellation = GnssConstellationType::UNKNOWN;
145 id.svid = 0;
146 }
147
148 bool operator<(const ComparableBlacklistedSource& compare) const {
149 return ((id.svid < compare.id.svid) || ((id.svid == compare.id.svid) &&
150 (id.constellation < compare.id.constellation)));
151 }
152 };
153
154 struct SignalCounts {
155 int observations;
156 float max_cn0_dbhz;
157 };
158
159 std::map<ComparableBlacklistedSource, SignalCounts> mapSignals;
160
161 for (const auto& gnss_sv_status : list_gnss_sv_status) {
162 for (uint32_t iSv = 0; iSv < gnss_sv_status.numSvs; iSv++) {
163 const auto& gnss_sv = gnss_sv_status.gnssSvList[iSv];
164 if ((gnss_sv.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX) &&
165 (gnss_sv.constellation != GnssConstellationType::GPS)) {
166 ComparableBlacklistedSource source;
167 source.id.svid = gnss_sv.svid;
168 source.id.constellation = gnss_sv.constellation;
169
170 const auto& itSignal = mapSignals.find(source);
171 if (itSignal == mapSignals.end()) {
172 SignalCounts counts;
173 counts.observations = 1;
174 counts.max_cn0_dbhz = gnss_sv.cN0Dbhz;
175 mapSignals.insert(
176 std::pair<ComparableBlacklistedSource, SignalCounts>(source, counts));
177 } else {
178 itSignal->second.observations++;
179 if (itSignal->second.max_cn0_dbhz < gnss_sv.cN0Dbhz) {
180 itSignal->second.max_cn0_dbhz = gnss_sv.cN0Dbhz;
181 }
182 }
183 }
184 }
185 }
186
187 float max_cn0_dbhz_with_sufficient_count = 0.;
188 int total_observation_count = 0;
189 int blacklisted_source_count_observation = 0;
190
191 ComparableBlacklistedSource source_to_blacklist; // initializes to zero = UNKNOWN constellation
192 for (auto const& pairSignal : mapSignals) {
193 total_observation_count += pairSignal.second.observations;
194 if ((pairSignal.second.observations >= min_observations) &&
195 (pairSignal.second.max_cn0_dbhz > max_cn0_dbhz_with_sufficient_count)) {
196 source_to_blacklist = pairSignal.first;
197 blacklisted_source_count_observation = pairSignal.second.observations;
198 max_cn0_dbhz_with_sufficient_count = pairSignal.second.max_cn0_dbhz;
199 }
200 }
201 ALOGD(
202 "Among %d observations, chose svid %d, constellation %d, "
203 "with %d observations at %.1f max CNo",
204 total_observation_count, source_to_blacklist.id.svid,
205 (int)source_to_blacklist.id.constellation, blacklisted_source_count_observation,
206 max_cn0_dbhz_with_sufficient_count);
207
208 return source_to_blacklist.id;
209 }
210
211 /*
212 * BlacklistIndividualSatellites:
213 *
214 * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
215 * GnssStatus for common satellites (strongest and one other.)
216 * 2a & b) Turns off location, and blacklists common satellites.
217 * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
218 * GnssStatus does not use those satellites.
219 * 4a & b) Turns off location, and send in empty blacklist.
220 * 5a) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
221 * GnssStatus does re-use at least the previously strongest satellite
222 * 5b) Retry a few times, in case GNSS search strategy takes a while to reacquire even the
223 * formerly strongest satellite
224 */
TEST_P(GnssHalTest,BlacklistIndividualSatellites)225 TEST_P(GnssHalTest, BlacklistIndividualSatellites) {
226 if (!IsGnssHalVersion_1_1()) {
227 ALOGI("Test BlacklistIndividualSatellites skipped. GNSS HAL version is greater than 1.1.");
228 return;
229 }
230
231 const int kLocationsToAwait = 3;
232 const int kRetriesToUnBlacklist = 10;
233
234 gnss_cb_->location_cbq_.reset();
235 StartAndCheckLocations(kLocationsToAwait);
236 int location_called_count = gnss_cb_->location_cbq_.calledCount();
237
238 // Tolerate 1 less sv status to handle edge cases in reporting.
239 int sv_status_cbq_size = gnss_cb_->sv_status_cbq_.size();
240 EXPECT_GE(sv_status_cbq_size + 1, kLocationsToAwait);
241 ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations (%d received)", sv_status_cbq_size,
242 kLocationsToAwait, location_called_count);
243
244 /*
245 * Identify strongest SV seen at least kLocationsToAwait -1 times
246 * Why -1? To avoid test flakiness in case of (plausible) slight flakiness in strongest signal
247 * observability (one epoch RF null)
248 */
249
250 const int kGnssSvStatusTimeout = 2;
251 std::list<IGnssCallback::GnssSvStatus> sv_status_list;
252 int count = gnss_cb_->sv_status_cbq_.retrieve(sv_status_list, sv_status_cbq_size,
253 kGnssSvStatusTimeout);
254 ASSERT_EQ(count, sv_status_cbq_size);
255
256 IGnssConfiguration::BlacklistedSource source_to_blacklist =
257 FindStrongFrequentNonGpsSource(sv_status_list, kLocationsToAwait - 1);
258
259 if (source_to_blacklist.constellation == GnssConstellationType::UNKNOWN) {
260 // Cannot find a non-GPS satellite. Let the test pass.
261 return;
262 }
263
264 // Stop locations, blacklist the common SV
265 StopAndClearLocations();
266
267 auto gnss_configuration_hal_return = gnss_hal_->getExtensionGnssConfiguration_1_1();
268 ASSERT_TRUE(gnss_configuration_hal_return.isOk());
269 sp<IGnssConfiguration> gnss_configuration_hal = gnss_configuration_hal_return;
270 ASSERT_NE(gnss_configuration_hal, nullptr);
271
272 hidl_vec<IGnssConfiguration::BlacklistedSource> sources;
273 sources.resize(1);
274 sources[0] = source_to_blacklist;
275
276 auto result = gnss_configuration_hal->setBlacklist(sources);
277 ASSERT_TRUE(result.isOk());
278 EXPECT_TRUE(result);
279
280 // retry and ensure satellite not used
281 gnss_cb_->sv_status_cbq_.reset();
282
283 gnss_cb_->location_cbq_.reset();
284 StartAndCheckLocations(kLocationsToAwait);
285
286 // early exit if test is being run with insufficient signal
287 location_called_count = gnss_cb_->location_cbq_.calledCount();
288 if (location_called_count == 0) {
289 ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
290 }
291 ASSERT_TRUE(location_called_count > 0);
292
293 // Tolerate 1 less sv status to handle edge cases in reporting.
294 sv_status_cbq_size = gnss_cb_->sv_status_cbq_.size();
295 EXPECT_GE(sv_status_cbq_size + 1, kLocationsToAwait);
296 ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations (%d received)", sv_status_cbq_size,
297 kLocationsToAwait, location_called_count);
298 for (int i = 0; i < sv_status_cbq_size; ++i) {
299 IGnssCallback::GnssSvStatus gnss_sv_status;
300 gnss_cb_->sv_status_cbq_.retrieve(gnss_sv_status, kGnssSvStatusTimeout);
301 for (uint32_t iSv = 0; iSv < gnss_sv_status.numSvs; iSv++) {
302 const auto& gnss_sv = gnss_sv_status.gnssSvList[iSv];
303 EXPECT_FALSE((gnss_sv.svid == source_to_blacklist.svid) &&
304 (gnss_sv.constellation == source_to_blacklist.constellation) &&
305 (gnss_sv.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX));
306 }
307 }
308
309 // clear blacklist and restart - this time updating the blacklist while location is still on
310 sources.resize(0);
311
312 result = gnss_configuration_hal->setBlacklist(sources);
313 ASSERT_TRUE(result.isOk());
314 EXPECT_TRUE(result);
315
316 bool strongest_sv_is_reobserved = false;
317 // do several loops awaiting a few locations, allowing non-immediate reacquisition strategies
318 int unblacklist_loops_remaining = kRetriesToUnBlacklist;
319 while (!strongest_sv_is_reobserved && (unblacklist_loops_remaining-- > 0)) {
320 StopAndClearLocations();
321 gnss_cb_->sv_status_cbq_.reset();
322
323 gnss_cb_->location_cbq_.reset();
324 StartAndCheckLocations(kLocationsToAwait);
325
326 // early exit loop if test is being run with insufficient signal
327 location_called_count = gnss_cb_->location_cbq_.calledCount();
328 if (location_called_count == 0) {
329 ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
330 }
331 ASSERT_TRUE(location_called_count > 0);
332
333 // Tolerate 1 less sv status to handle edge cases in reporting.
334 sv_status_cbq_size = gnss_cb_->sv_status_cbq_.size();
335 EXPECT_GE(sv_status_cbq_size + 1, kLocationsToAwait);
336 ALOGD("Clear blacklist, observed %d GnssSvStatus, while awaiting %d Locations"
337 ", tries remaining %d",
338 sv_status_cbq_size, kLocationsToAwait, unblacklist_loops_remaining);
339
340 for (int i = 0; i < sv_status_cbq_size; ++i) {
341 IGnssCallback::GnssSvStatus gnss_sv_status;
342 gnss_cb_->sv_status_cbq_.retrieve(gnss_sv_status, kGnssSvStatusTimeout);
343 for (uint32_t iSv = 0; iSv < gnss_sv_status.numSvs; iSv++) {
344 const auto& gnss_sv = gnss_sv_status.gnssSvList[iSv];
345 if ((gnss_sv.svid == source_to_blacklist.svid) &&
346 (gnss_sv.constellation == source_to_blacklist.constellation) &&
347 (gnss_sv.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX)) {
348 strongest_sv_is_reobserved = true;
349 break;
350 }
351 }
352 if (strongest_sv_is_reobserved) break;
353 }
354 }
355 EXPECT_TRUE(strongest_sv_is_reobserved);
356 StopAndClearLocations();
357 }
358
359 /*
360 * BlacklistConstellationWithLocationOff:
361 *
362 * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
363 * GnssStatus for any non-GPS constellations.
364 * 2a & b) Turns off location, and blacklist first non-GPS constellations.
365 * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
366 * GnssStatus does not use any constellation but GPS.
367 * 4a & b) Clean up by turning off location, and send in empty blacklist.
368 */
TEST_P(GnssHalTest,BlacklistConstellationWithLocationOff)369 TEST_P(GnssHalTest, BlacklistConstellationWithLocationOff) {
370 if (!IsGnssHalVersion_1_1()) {
371 ALOGI("Test BlacklistConstellation skipped. GNSS HAL version is greater than 1.1.");
372 return;
373 }
374
375 const int kLocationsToAwait = 3;
376 const int kGnssSvStatusTimeout = 2;
377
378 // Find first non-GPS constellation to blacklist
379 GnssConstellationType constellation_to_blacklist =
380 startLocationAndGetNonGpsConstellation(kLocationsToAwait, kGnssSvStatusTimeout);
381
382 // Turns off location
383 StopAndClearLocations();
384
385 IGnssConfiguration::BlacklistedSource source_to_blacklist;
386 source_to_blacklist.constellation = constellation_to_blacklist;
387 source_to_blacklist.svid = 0; // documented wildcard for all satellites in this constellation
388
389 auto gnss_configuration_hal_return = gnss_hal_->getExtensionGnssConfiguration_1_1();
390 ASSERT_TRUE(gnss_configuration_hal_return.isOk());
391 sp<IGnssConfiguration> gnss_configuration_hal = gnss_configuration_hal_return;
392 ASSERT_NE(gnss_configuration_hal, nullptr);
393
394 hidl_vec<IGnssConfiguration::BlacklistedSource> sources;
395 sources.resize(1);
396 sources[0] = source_to_blacklist;
397
398 // setBlacklist when location is off.
399 auto result = gnss_configuration_hal->setBlacklist(sources);
400 ASSERT_TRUE(result.isOk());
401 EXPECT_TRUE(result);
402
403 // retry and ensure constellation not used
404 gnss_cb_->sv_status_cbq_.reset();
405
406 gnss_cb_->location_cbq_.reset();
407 StartAndCheckLocations(kLocationsToAwait);
408
409 // Tolerate 1 less sv status to handle edge cases in reporting.
410 int sv_status_cbq_size = gnss_cb_->sv_status_cbq_.size();
411 EXPECT_GE(sv_status_cbq_size + 1, kLocationsToAwait);
412 ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations", sv_status_cbq_size,
413 kLocationsToAwait);
414 for (int i = 0; i < sv_status_cbq_size; ++i) {
415 IGnssCallback::GnssSvStatus gnss_sv_status;
416 gnss_cb_->sv_status_cbq_.retrieve(gnss_sv_status, kGnssSvStatusTimeout);
417 for (uint32_t iSv = 0; iSv < gnss_sv_status.numSvs; iSv++) {
418 const auto& gnss_sv = gnss_sv_status.gnssSvList[iSv];
419 EXPECT_FALSE((gnss_sv.constellation == source_to_blacklist.constellation) &&
420 (gnss_sv.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX));
421 }
422 }
423
424 // clean up
425 StopAndClearLocations();
426 sources.resize(0);
427 result = gnss_configuration_hal->setBlacklist(sources);
428 ASSERT_TRUE(result.isOk());
429 EXPECT_TRUE(result);
430 }
431
432 /*
433 * BlacklistConstellationWithLocationOn:
434 *
435 * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
436 * GnssStatus for any non-GPS constellations.
437 * 2a & b) Blacklist first non-GPS constellation, and turn off location.
438 * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
439 * GnssStatus does not use any constellation but GPS.
440 * 4a & b) Clean up by turning off location, and send in empty blacklist.
441 */
TEST_P(GnssHalTest,BlacklistConstellationWithLocationOn)442 TEST_P(GnssHalTest, BlacklistConstellationWithLocationOn) {
443 if (!IsGnssHalVersion_1_1()) {
444 ALOGI("Test BlacklistConstellation skipped. GNSS HAL version is greater than 1.1.");
445 return;
446 }
447
448 const int kLocationsToAwait = 3;
449 const int kGnssSvStatusTimeout = 2;
450
451 // Find first non-GPS constellation to blacklist
452 GnssConstellationType constellation_to_blacklist =
453 startLocationAndGetNonGpsConstellation(kLocationsToAwait, kGnssSvStatusTimeout);
454
455 IGnssConfiguration::BlacklistedSource source_to_blacklist;
456 source_to_blacklist.constellation = constellation_to_blacklist;
457 source_to_blacklist.svid = 0; // documented wildcard for all satellites in this constellation
458
459 auto gnss_configuration_hal_return = gnss_hal_->getExtensionGnssConfiguration_1_1();
460 ASSERT_TRUE(gnss_configuration_hal_return.isOk());
461 sp<IGnssConfiguration> gnss_configuration_hal = gnss_configuration_hal_return;
462 ASSERT_NE(gnss_configuration_hal, nullptr);
463
464 hidl_vec<IGnssConfiguration::BlacklistedSource> sources;
465 sources.resize(1);
466 sources[0] = source_to_blacklist;
467
468 // setBlacklist when location is still on
469 auto result = gnss_configuration_hal->setBlacklist(sources);
470 ASSERT_TRUE(result.isOk());
471 EXPECT_TRUE(result);
472
473 // Turns off location
474 StopAndClearLocations();
475
476 // retry and ensure constellation not used
477 gnss_cb_->sv_status_cbq_.reset();
478
479 gnss_cb_->location_cbq_.reset();
480 StartAndCheckLocations(kLocationsToAwait);
481
482 // Tolerate 1 less sv status to handle edge cases in reporting.
483 int sv_status_cbq_size = gnss_cb_->sv_status_cbq_.size();
484 EXPECT_GE(sv_status_cbq_size + 1, kLocationsToAwait);
485 ALOGD("Observed %d GnssSvStatus, while awaiting %d Locations", sv_status_cbq_size,
486 kLocationsToAwait);
487 for (int i = 0; i < sv_status_cbq_size; ++i) {
488 IGnssCallback::GnssSvStatus gnss_sv_status;
489 gnss_cb_->sv_status_cbq_.retrieve(gnss_sv_status, kGnssSvStatusTimeout);
490 for (uint32_t iSv = 0; iSv < gnss_sv_status.numSvs; iSv++) {
491 const auto& gnss_sv = gnss_sv_status.gnssSvList[iSv];
492 EXPECT_FALSE((gnss_sv.constellation == source_to_blacklist.constellation) &&
493 (gnss_sv.svFlag & IGnssCallback::GnssSvFlags::USED_IN_FIX));
494 }
495 }
496
497 // clean up
498 StopAndClearLocations();
499 sources.resize(0);
500 result = gnss_configuration_hal->setBlacklist(sources);
501 ASSERT_TRUE(result.isOk());
502 EXPECT_TRUE(result);
503 }
504
505 /*
506 * InjectBestLocation
507 *
508 * Ensure successfully injecting a location.
509 */
TEST_P(GnssHalTest,InjectBestLocation)510 TEST_P(GnssHalTest, InjectBestLocation) {
511 StartAndCheckLocations(1);
512 GnssLocation gnssLocation = gnss_cb_->last_location_;
513 CheckLocation(gnssLocation, true);
514
515 auto result = gnss_hal_->injectBestLocation(gnssLocation);
516
517 ASSERT_TRUE(result.isOk());
518 EXPECT_TRUE(result);
519
520 auto resultVoid = gnss_hal_->deleteAidingData(IGnss::GnssAidingData::DELETE_POSITION);
521
522 ASSERT_TRUE(resultVoid.isOk());
523 }
524
525 /*
526 * GnssDebugValuesSanityTest:
527 * Ensures that GnssDebug values make sense.
528 */
TEST_P(GnssHalTest,GnssDebugValuesSanityTest)529 TEST_P(GnssHalTest, GnssDebugValuesSanityTest) {
530 auto gnssDebug = gnss_hal_->getExtensionGnssDebug();
531 ASSERT_TRUE(gnssDebug.isOk());
532 if (!IsAutomotiveDevice() && gnss_cb_->info_cbq_.calledCount() > 0 &&
533 gnss_cb_->last_info_.yearOfHw >= 2017) {
534 sp<IGnssDebug> iGnssDebug = gnssDebug;
535 EXPECT_NE(iGnssDebug, nullptr);
536
537 IGnssDebug::DebugData data;
538 iGnssDebug->getDebugData(
539 [&data](const IGnssDebug::DebugData& debugData) { data = debugData; });
540
541 if (data.position.valid) {
542 EXPECT_GE(data.position.latitudeDegrees, -90);
543 EXPECT_LE(data.position.latitudeDegrees, 90);
544
545 EXPECT_GE(data.position.longitudeDegrees, -180);
546 EXPECT_LE(data.position.longitudeDegrees, 180);
547
548 EXPECT_GE(data.position.altitudeMeters, -1000); // Dead Sea: -414m
549 EXPECT_LE(data.position.altitudeMeters, 20000); // Mount Everest: 8850m
550
551 EXPECT_GE(data.position.speedMetersPerSec, 0);
552 EXPECT_LE(data.position.speedMetersPerSec, 600);
553
554 EXPECT_GE(data.position.bearingDegrees, -360);
555 EXPECT_LE(data.position.bearingDegrees, 360);
556
557 EXPECT_GT(data.position.horizontalAccuracyMeters, 0);
558 EXPECT_LE(data.position.horizontalAccuracyMeters, 20000000);
559
560 EXPECT_GT(data.position.verticalAccuracyMeters, 0);
561 EXPECT_LE(data.position.verticalAccuracyMeters, 20000);
562
563 EXPECT_GT(data.position.speedAccuracyMetersPerSecond, 0);
564 EXPECT_LE(data.position.speedAccuracyMetersPerSecond, 500);
565
566 EXPECT_GT(data.position.bearingAccuracyDegrees, 0);
567 EXPECT_LE(data.position.bearingAccuracyDegrees, 180);
568
569 EXPECT_GE(data.position.ageSeconds, 0);
570 }
571
572 EXPECT_GE(data.time.timeEstimate, 1483228800000); // Jan 01 2017 00:00:00 GMT.
573
574 EXPECT_GT(data.time.timeUncertaintyNs, 0);
575
576 EXPECT_GT(data.time.frequencyUncertaintyNsPerSec, 0);
577 EXPECT_LE(data.time.frequencyUncertaintyNsPerSec, 2.0e5); // 200 ppm
578 }
579 }
580