• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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