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 "GnssHalTest"
18
19 #include <gnss_hal_test.h>
20
21 #include <chrono>
22
23 // Implementations for the main test class for GNSS HAL
GnssHalTest()24 GnssHalTest::GnssHalTest()
25 : info_called_count_(0),
26 capabilities_called_count_(0),
27 location_called_count_(0),
28 name_called_count_(0),
29 notify_count_(0) {}
30
SetUp()31 void GnssHalTest::SetUp() {
32 gnss_hal_ = ::testing::VtsHalHidlTargetTestBase::getService<IGnss>(
33 GnssHidlEnvironment::Instance()->getServiceName<IGnss>());
34 list_gnss_sv_status_.clear();
35 ASSERT_NE(gnss_hal_, nullptr);
36
37 SetUpGnssCallback();
38 }
39
TearDown()40 void GnssHalTest::TearDown() {
41 if (gnss_hal_ != nullptr) {
42 gnss_hal_->cleanup();
43 }
44 if (notify_count_ > 0) {
45 ALOGW("%d unprocessed callbacks discarded", notify_count_);
46 }
47 }
48
SetUpGnssCallback()49 void GnssHalTest::SetUpGnssCallback() {
50 gnss_cb_ = new GnssCallback(*this);
51 ASSERT_NE(gnss_cb_, nullptr);
52
53 auto result = gnss_hal_->setCallback_1_1(gnss_cb_);
54 if (!result.isOk()) {
55 ALOGE("result of failed setCallback %s", result.description().c_str());
56 }
57
58 ASSERT_TRUE(result.isOk());
59 ASSERT_TRUE(result);
60
61 /*
62 * All capabilities, name and systemInfo callbacks should trigger
63 */
64 EXPECT_EQ(std::cv_status::no_timeout, wait(TIMEOUT_SEC));
65 EXPECT_EQ(std::cv_status::no_timeout, wait(TIMEOUT_SEC));
66 EXPECT_EQ(std::cv_status::no_timeout, wait(TIMEOUT_SEC));
67
68 EXPECT_EQ(capabilities_called_count_, 1);
69 EXPECT_EQ(info_called_count_, 1);
70 EXPECT_EQ(name_called_count_, 1);
71 }
72
StopAndClearLocations()73 void GnssHalTest::StopAndClearLocations() {
74 auto result = gnss_hal_->stop();
75
76 EXPECT_TRUE(result.isOk());
77 EXPECT_TRUE(result);
78
79 /*
80 * Clear notify/waiting counter, allowing up till the timeout after
81 * the last reply for final startup messages to arrive (esp. system
82 * info.)
83 */
84 while (wait(TIMEOUT_SEC) == std::cv_status::no_timeout) {
85 }
86 }
87
SetPositionMode(const int min_interval_msec,const bool low_power_mode)88 void GnssHalTest::SetPositionMode(const int min_interval_msec, const bool low_power_mode) {
89 const int kPreferredAccuracy = 0; // Ideally perfect (matches GnssLocationProvider)
90 const int kPreferredTimeMsec = 0; // Ideally immediate
91
92 auto result = gnss_hal_->setPositionMode_1_1(
93 IGnss::GnssPositionMode::MS_BASED, IGnss::GnssPositionRecurrence::RECURRENCE_PERIODIC,
94 min_interval_msec, kPreferredAccuracy, kPreferredTimeMsec, low_power_mode);
95
96 ASSERT_TRUE(result.isOk());
97 EXPECT_TRUE(result);
98 }
99
StartAndGetSingleLocation()100 bool GnssHalTest::StartAndGetSingleLocation() {
101 auto result = gnss_hal_->start();
102
103 EXPECT_TRUE(result.isOk());
104 EXPECT_TRUE(result);
105
106 /*
107 * GPS signals initially optional for this test, so don't expect fast fix,
108 * or no timeout, unless signal is present
109 */
110 const int kFirstGnssLocationTimeoutSeconds = 15;
111
112 wait(kFirstGnssLocationTimeoutSeconds);
113 EXPECT_EQ(location_called_count_, 1);
114
115 if (location_called_count_ > 0) {
116 // don't require speed on first fix
117 CheckLocation(last_location_, false);
118 return true;
119 }
120 return false;
121 }
122
CheckLocation(GnssLocation & location,bool check_speed)123 void GnssHalTest::CheckLocation(GnssLocation& location, bool check_speed) {
124 bool check_more_accuracies = (info_called_count_ > 0 && last_info_.yearOfHw >= 2017);
125
126 EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG);
127 EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE);
128 if (check_speed) {
129 EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED);
130 }
131 EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY);
132 // New uncertainties available in O must be provided,
133 // at least when paired with modern hardware (2017+)
134 if (check_more_accuracies) {
135 EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY);
136 if (check_speed) {
137 EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY);
138 if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
139 EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY);
140 }
141 }
142 }
143 EXPECT_GE(location.latitudeDegrees, -90.0);
144 EXPECT_LE(location.latitudeDegrees, 90.0);
145 EXPECT_GE(location.longitudeDegrees, -180.0);
146 EXPECT_LE(location.longitudeDegrees, 180.0);
147 EXPECT_GE(location.altitudeMeters, -1000.0);
148 EXPECT_LE(location.altitudeMeters, 30000.0);
149 if (check_speed) {
150 EXPECT_GE(location.speedMetersPerSec, 0.0);
151 EXPECT_LE(location.speedMetersPerSec, 5.0); // VTS tests are stationary.
152
153 // Non-zero speeds must be reported with an associated bearing
154 if (location.speedMetersPerSec > 0.0) {
155 EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING);
156 }
157 }
158
159 /*
160 * Tolerating some especially high values for accuracy estimate, in case of
161 * first fix with especially poor geometry (happens occasionally)
162 */
163 EXPECT_GT(location.horizontalAccuracyMeters, 0.0);
164 EXPECT_LE(location.horizontalAccuracyMeters, 250.0);
165
166 /*
167 * Some devices may define bearing as -180 to +180, others as 0 to 360.
168 * Both are okay & understandable.
169 */
170 if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
171 EXPECT_GE(location.bearingDegrees, -180.0);
172 EXPECT_LE(location.bearingDegrees, 360.0);
173 }
174 if (location.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
175 EXPECT_GT(location.verticalAccuracyMeters, 0.0);
176 EXPECT_LE(location.verticalAccuracyMeters, 500.0);
177 }
178 if (location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
179 EXPECT_GT(location.speedAccuracyMetersPerSecond, 0.0);
180 EXPECT_LE(location.speedAccuracyMetersPerSecond, 50.0);
181 }
182 if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
183 EXPECT_GT(location.bearingAccuracyDegrees, 0.0);
184 EXPECT_LE(location.bearingAccuracyDegrees, 360.0);
185 }
186
187 // Check timestamp > 1.48e12 (47 years in msec - 1970->2017+)
188 EXPECT_GT(location.timestamp, 1.48e12);
189 }
190
StartAndCheckLocations(int count)191 void GnssHalTest::StartAndCheckLocations(int count) {
192 const int kMinIntervalMsec = 500;
193 const int kLocationTimeoutSubsequentSec = 2;
194 const bool kLowPowerMode = false;
195
196 SetPositionMode(kMinIntervalMsec, kLowPowerMode);
197
198 EXPECT_TRUE(StartAndGetSingleLocation());
199
200 for (int i = 1; i < count; i++) {
201 EXPECT_EQ(std::cv_status::no_timeout, wait(kLocationTimeoutSubsequentSec));
202 EXPECT_EQ(location_called_count_, i + 1);
203 // Don't cause confusion by checking details if no location yet
204 if (location_called_count_ > 0) {
205 // Should be more than 1 location by now, but if not, still don't check first fix speed
206 CheckLocation(last_location_, location_called_count_ > 1);
207 }
208 }
209 }
210
notify()211 void GnssHalTest::notify() {
212 std::unique_lock<std::mutex> lock(mtx_);
213 notify_count_++;
214 cv_.notify_one();
215 }
216
wait(int timeout_seconds)217 std::cv_status GnssHalTest::wait(int timeout_seconds) {
218 std::unique_lock<std::mutex> lock(mtx_);
219
220 auto status = std::cv_status::no_timeout;
221 while (notify_count_ == 0) {
222 status = cv_.wait_for(lock, std::chrono::seconds(timeout_seconds));
223 if (status == std::cv_status::timeout) return status;
224 }
225 notify_count_--;
226 return status;
227 }
228
gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo & info)229 Return<void> GnssHalTest::GnssCallback::gnssSetSystemInfoCb(
230 const IGnssCallback::GnssSystemInfo& info) {
231 ALOGI("Info received, year %d", info.yearOfHw);
232 parent_.info_called_count_++;
233 parent_.last_info_ = info;
234 parent_.notify();
235 return Void();
236 }
237
gnssSetCapabilitesCb(uint32_t capabilities)238 Return<void> GnssHalTest::GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
239 ALOGI("Capabilities received %d", capabilities);
240 parent_.capabilities_called_count_++;
241 parent_.last_capabilities_ = capabilities;
242 parent_.notify();
243 return Void();
244 }
245
gnssNameCb(const android::hardware::hidl_string & name)246 Return<void> GnssHalTest::GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) {
247 ALOGI("Name received: %s", name.c_str());
248 parent_.name_called_count_++;
249 parent_.last_name_ = name;
250 parent_.notify();
251 return Void();
252 }
253
gnssLocationCb(const GnssLocation & location)254 Return<void> GnssHalTest::GnssCallback::gnssLocationCb(const GnssLocation& location) {
255 ALOGI("Location received");
256 parent_.location_called_count_++;
257 parent_.last_location_ = location;
258 parent_.notify();
259 return Void();
260 }
261
gnssSvStatusCb(const IGnssCallback::GnssSvStatus & svStatus)262 Return<void> GnssHalTest::GnssCallback::gnssSvStatusCb(
263 const IGnssCallback::GnssSvStatus& svStatus) {
264 ALOGI("GnssSvStatus received");
265 parent_.list_gnss_sv_status_.emplace_back(svStatus);
266 return Void();
267 }
268