blob: 21b71369d34ea809bc9ba45df1b9909020ac876c [file] [log] [blame]
Wyatt Riley6c26ed72017-02-21 17:21:53 -08001/*
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 "VtsHalGnssV1_0TargetTest"
18#include <android/hardware/gnss/1.0/IGnss.h>
19#include <android/log.h>
20
Yuexi Maed2bb4e2017-03-10 00:44:45 -080021#include <VtsHalHidlTargetTestBase.h>
Wyatt Riley6c26ed72017-02-21 17:21:53 -080022
23#include <chrono>
24#include <condition_variable>
25#include <mutex>
26
27using android::hardware::Return;
28using android::hardware::Void;
29
30using android::hardware::gnss::V1_0::GnssLocation;
31using android::hardware::gnss::V1_0::GnssLocationFlags;
32using android::hardware::gnss::V1_0::IGnss;
33using android::hardware::gnss::V1_0::IGnssCallback;
34using android::sp;
35
Wyatt Riley917640b2017-03-16 16:25:55 -070036#define TIMEOUT_SEC 3 // for basic commands/responses
Wyatt Riley6c26ed72017-02-21 17:21:53 -080037
38// The main test class for GNSS HAL.
Yuexi Maed2bb4e2017-03-10 00:44:45 -080039class GnssHalTest : public ::testing::VtsHalHidlTargetTestBase {
Wyatt Riley6c26ed72017-02-21 17:21:53 -080040 public:
41 virtual void SetUp() override {
Wyatt Riley917640b2017-03-16 16:25:55 -070042 // Clean between tests
43 capabilities_called_count_ = 0;
44 location_called_count_ = 0;
45 info_called_count_ = 0;
Wyatt Riley6c26ed72017-02-21 17:21:53 -080046
Yuexi Maed2bb4e2017-03-10 00:44:45 -080047 gnss_hal_ = ::testing::VtsHalHidlTargetTestBase::getService<IGnss>();
Wyatt Riley6c26ed72017-02-21 17:21:53 -080048 ASSERT_NE(gnss_hal_, nullptr);
49
50 gnss_cb_ = new GnssCallback(*this);
51 ASSERT_NE(gnss_cb_, nullptr);
52
53 auto result = gnss_hal_->setCallback(gnss_cb_);
54 if (!result.isOk()) {
Wyatt Riley917640b2017-03-16 16:25:55 -070055 ALOGE("result of failed setCallback %s", result.description().c_str());
Wyatt Riley6c26ed72017-02-21 17:21:53 -080056 }
57
58 ASSERT_TRUE(result.isOk());
59 ASSERT_TRUE(result);
60
Wyatt Riley917640b2017-03-16 16:25:55 -070061 /*
62 * At least one callback should trigger - it may be capabilites, or
63 * system info first, so wait again if capabilities not received.
Wyatt Riley6c26ed72017-02-21 17:21:53 -080064 */
Wyatt Riley917640b2017-03-16 16:25:55 -070065 EXPECT_EQ(std::cv_status::no_timeout, wait(TIMEOUT_SEC));
66 if (capabilities_called_count_ == 0) {
67 EXPECT_EQ(std::cv_status::no_timeout, wait(TIMEOUT_SEC));
68 }
69
70 /*
71 * Generally should be 1 capabilites callback -
72 * or possibly 2 in some recovery cases (default cached & refreshed)
73 */
74 EXPECT_GE(capabilities_called_count_, 1);
75 EXPECT_LE(capabilities_called_count_, 2);
76
77 /*
78 * Clear notify/waiting counter, allowing up till the timeout after
79 * the last reply for final startup messages to arrive (esp. system
80 * info.)
81 */
82 while (wait(TIMEOUT_SEC) == std::cv_status::no_timeout) {
83 }
Wyatt Riley6c26ed72017-02-21 17:21:53 -080084 }
85
86 virtual void TearDown() override {
87 if (gnss_hal_ != nullptr) {
88 gnss_hal_->cleanup();
89 }
90 }
91
92 /* Used as a mechanism to inform the test that a callback has occurred */
93 inline void notify() {
94 std::unique_lock<std::mutex> lock(mtx_);
95 count++;
96 cv_.notify_one();
97 }
98
99 /* Test code calls this function to wait for a callback */
100 inline std::cv_status wait(int timeoutSeconds) {
101 std::unique_lock<std::mutex> lock(mtx_);
102
103 std::cv_status status = std::cv_status::no_timeout;
104 auto now = std::chrono::system_clock::now();
105 while (count == 0) {
106 status = cv_.wait_until(lock, now + std::chrono::seconds(timeoutSeconds));
107 if (status == std::cv_status::timeout) return status;
108 }
109 count--;
110 return status;
111 }
112
113 /* Callback class for data & Event. */
114 class GnssCallback : public IGnssCallback {
Wyatt Riley917640b2017-03-16 16:25:55 -0700115 public:
Wyatt Riley6c26ed72017-02-21 17:21:53 -0800116 GnssHalTest& parent_;
117
Wyatt Riley6c26ed72017-02-21 17:21:53 -0800118 GnssCallback(GnssHalTest& parent) : parent_(parent){};
119
120 virtual ~GnssCallback() = default;
121
122 // Dummy callback handlers
123 Return<void> gnssStatusCb(
Steven Moreland4b523952017-03-08 19:20:30 -0800124 const IGnssCallback::GnssStatusValue /* status */) override {
Wyatt Riley6c26ed72017-02-21 17:21:53 -0800125 return Void();
126 }
127 Return<void> gnssSvStatusCb(
Steven Moreland4b523952017-03-08 19:20:30 -0800128 const IGnssCallback::GnssSvStatus& /* svStatus */) override {
Wyatt Riley6c26ed72017-02-21 17:21:53 -0800129 return Void();
130 }
131 Return<void> gnssNmeaCb(
Steven Moreland4b523952017-03-08 19:20:30 -0800132 int64_t /* timestamp */,
133 const android::hardware::hidl_string& /* nmea */) override {
Wyatt Riley6c26ed72017-02-21 17:21:53 -0800134 return Void();
135 }
136 Return<void> gnssAcquireWakelockCb() override { return Void(); }
137 Return<void> gnssReleaseWakelockCb() override { return Void(); }
138 Return<void> gnssRequestTimeCb() override { return Void(); }
139
140 // Actual (test) callback handlers
141 Return<void> gnssLocationCb(const GnssLocation& location) override {
142 ALOGI("Location received");
143 parent_.location_called_count_++;
144 parent_.last_location_ = location;
145 parent_.notify();
146 return Void();
147 }
148
149 Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override {
150 ALOGI("Capabilities received %d", capabilities);
151 parent_.capabilities_called_count_++;
152 parent_.last_capabilities_ = capabilities;
153 parent_.notify();
154 return Void();
155 }
156
157 Return<void> gnssSetSystemInfoCb(
158 const IGnssCallback::GnssSystemInfo& info) override {
159 ALOGI("Info received, year %d", info.yearOfHw);
160 parent_.info_called_count_++;
161 parent_.last_info_ = info;
162 parent_.notify();
163 return Void();
164 }
165 };
166
167 sp<IGnss> gnss_hal_; // GNSS HAL to call into
168 sp<IGnssCallback> gnss_cb_; // Primary callback interface
169
170 /* Count of calls to set the following items, and the latest item (used by
171 * test.)
172 */
173 int capabilities_called_count_;
174 uint32_t last_capabilities_;
175
176 int location_called_count_;
177 GnssLocation last_location_;
178
179 int info_called_count_;
180 IGnssCallback::GnssSystemInfo last_info_;
181
182 private:
183 std::mutex mtx_;
184 std::condition_variable cv_;
185 int count;
186};
187
188/*
189 * SetCallbackCapabilitiesCleanup:
190 * Sets up the callback, awaits the capabilities, and calls cleanup
191 *
192 * Since this is just the basic operation of SetUp() and TearDown(),
Wyatt Riley917640b2017-03-16 16:25:55 -0700193 * the function definition is intentionally empty
Wyatt Riley6c26ed72017-02-21 17:21:53 -0800194 */
195TEST_F(GnssHalTest, SetCallbackCapabilitiesCleanup) {}
196
Wyatt Riley917640b2017-03-16 16:25:55 -0700197/*
198 * CheckLocation:
199 * Helper function to vet Location fields
200 */
201
202void CheckLocation(GnssLocation& location, bool checkAccuracies) {
Wyatt Riley6c26ed72017-02-21 17:21:53 -0800203 EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG);
204 EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE);
205 EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED);
206 EXPECT_TRUE(location.gnssLocationFlags &
207 GnssLocationFlags::HAS_HORIZONTAL_ACCURACY);
Wyatt Riley917640b2017-03-16 16:25:55 -0700208 // New uncertainties available in O must be provided,
209 // at least when paired with modern hardware (2017+)
210 if (checkAccuracies) {
211 EXPECT_TRUE(location.gnssLocationFlags &
212 GnssLocationFlags::HAS_VERTICAL_ACCURACY);
213 EXPECT_TRUE(location.gnssLocationFlags &
214 GnssLocationFlags::HAS_SPEED_ACCURACY);
215 if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
216 EXPECT_TRUE(location.gnssLocationFlags &
217 GnssLocationFlags::HAS_BEARING_ACCURACY);
218 }
219 }
Wyatt Riley6c26ed72017-02-21 17:21:53 -0800220 EXPECT_GE(location.latitudeDegrees, -90.0);
221 EXPECT_LE(location.latitudeDegrees, 90.0);
222 EXPECT_GE(location.longitudeDegrees, -180.0);
223 EXPECT_LE(location.longitudeDegrees, 180.0);
224 EXPECT_GE(location.altitudeMeters, -1000.0);
225 EXPECT_LE(location.altitudeMeters, 30000.0);
226 EXPECT_GE(location.speedMetersPerSec, 0.0);
227 EXPECT_LE(location.speedMetersPerSec, 5.0); // VTS tests are stationary.
228
Wyatt Riley917640b2017-03-16 16:25:55 -0700229 // Non-zero speeds must be reported with an associated bearing
230 if (location.speedMetersPerSec > 0.0) {
231 EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING);
232 }
233
Wyatt Riley6c26ed72017-02-21 17:21:53 -0800234 /*
235 * Tolerating some especially high values for accuracy estimate, in case of
Wyatt Riley917640b2017-03-16 16:25:55 -0700236 * first fix with especially poor geometry (happens occasionally)
Wyatt Riley6c26ed72017-02-21 17:21:53 -0800237 */
238 EXPECT_GT(location.horizontalAccuracyMeters, 0.0);
Wyatt Riley917640b2017-03-16 16:25:55 -0700239 EXPECT_LE(location.horizontalAccuracyMeters, 250.0);
Wyatt Riley6c26ed72017-02-21 17:21:53 -0800240
241 /*
242 * Some devices may define bearing as -180 to +180, others as 0 to 360.
243 * Both are okay & understandable.
244 */
245 if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
246 EXPECT_GE(location.bearingDegrees, -180.0);
247 EXPECT_LE(location.bearingDegrees, 360.0);
248 }
249 if (location.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
250 EXPECT_GT(location.verticalAccuracyMeters, 0.0);
251 EXPECT_LE(location.verticalAccuracyMeters, 500.0);
252 }
253 if (location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
254 EXPECT_GT(location.speedAccuracyMetersPerSecond, 0.0);
255 EXPECT_LE(location.speedAccuracyMetersPerSecond, 50.0);
256 }
257 if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
258 EXPECT_GT(location.bearingAccuracyDegrees, 0.0);
259 EXPECT_LE(location.bearingAccuracyDegrees, 360.0);
260 }
261
262 // Check timestamp > 1.48e12 (47 years in msec - 1970->2017+)
263 EXPECT_GT(location.timestamp, 1.48e12);
Wyatt Riley6c26ed72017-02-21 17:21:53 -0800264}
265
266/*
267 * GetLocation:
268 * Turns on location, waits 45 second for at least 5 locations,
269 * and checks them for reasonable validity.
270 */
271TEST_F(GnssHalTest, GetLocation) {
272#define MIN_INTERVAL_MSEC 500
273#define PREFERRED_ACCURACY 0 // Ideally perfect (matches GnssLocationProvider)
274#define PREFERRED_TIME_MSEC 0 // Ideally immediate
275
276#define LOCATION_TIMEOUT_FIRST_SEC 45
277#define LOCATION_TIMEOUT_SUBSEQUENT_SEC 3
278#define LOCATIONS_TO_CHECK 5
279
Wyatt Riley917640b2017-03-16 16:25:55 -0700280 bool checkMoreAccuracies =
281 (info_called_count_ > 0 && last_info_.yearOfHw >= 2017);
282
Wyatt Riley6c26ed72017-02-21 17:21:53 -0800283 auto result = gnss_hal_->setPositionMode(
284 IGnss::GnssPositionMode::MS_BASED,
285 IGnss::GnssPositionRecurrence::RECURRENCE_PERIODIC, MIN_INTERVAL_MSEC,
286 PREFERRED_ACCURACY, PREFERRED_TIME_MSEC);
287
288 ASSERT_TRUE(result.isOk());
289 ASSERT_TRUE(result);
290
291 result = gnss_hal_->start();
292
293 ASSERT_TRUE(result.isOk());
294 ASSERT_TRUE(result);
295
Wyatt Riley917640b2017-03-16 16:25:55 -0700296 // GPS signals initially optional for this test, so don't expect no timeout
297 // yet
298 wait(LOCATION_TIMEOUT_FIRST_SEC);
299 if (location_called_count_ > 0) {
300 CheckLocation(last_location_, checkMoreAccuracies);
301 }
Wyatt Riley6c26ed72017-02-21 17:21:53 -0800302
303 for (int i = 1; i < LOCATIONS_TO_CHECK; i++) {
Wyatt Riley917640b2017-03-16 16:25:55 -0700304 wait(LOCATION_TIMEOUT_SUBSEQUENT_SEC);
305 if (location_called_count_ > 0) {
306 CheckLocation(last_location_, checkMoreAccuracies);
307 }
Wyatt Riley6c26ed72017-02-21 17:21:53 -0800308 }
309
310 result = gnss_hal_->stop();
311
312 ASSERT_TRUE(result.isOk());
313 ASSERT_TRUE(result);
314}
315
316int main(int argc, char** argv) {
317 ::testing::InitGoogleTest(&argc, argv);
318 int status = RUN_ALL_TESTS();
319 ALOGI("Test result = %d", status);
320 return status;
Wyatt Riley917640b2017-03-16 16:25:55 -0700321}