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