blob: f1cd9ec1f6ef5dea4140788b45d57ebd60d3487f [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
21#include <gtest/gtest.h>
22
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
36#define TIMEOUT_SECONDS 5 // for basic commands/responses
37
38// The main test class for GNSS HAL.
39class GnssHalTest : public ::testing::Test {
40 public:
41 virtual void SetUp() override {
42 /* TODO(b/35678469): Setup the init.rc for VTS such that there's a
43 * single caller
44 * to the GNSS HAL - as part of confirming that the info & capabilities
45 * callbacks trigger.
46 */
47
48 gnss_hal_ = IGnss::getService("gnss");
49 ASSERT_NE(gnss_hal_, nullptr);
50
51 gnss_cb_ = new GnssCallback(*this);
52 ASSERT_NE(gnss_cb_, nullptr);
53
54 auto result = gnss_hal_->setCallback(gnss_cb_);
55 if (!result.isOk()) {
56 ALOGE("result of failed callback set %s", result.description().c_str());
57 }
58
59 ASSERT_TRUE(result.isOk());
60 ASSERT_TRUE(result);
61
62 /* TODO(b/35678469): Implement the capabilities & info (year) checks &
63 * value store here.
64 */
65 }
66
67 virtual void TearDown() override {
68 if (gnss_hal_ != nullptr) {
69 gnss_hal_->cleanup();
70 }
71 }
72
73 /* Used as a mechanism to inform the test that a callback has occurred */
74 inline void notify() {
75 std::unique_lock<std::mutex> lock(mtx_);
76 count++;
77 cv_.notify_one();
78 }
79
80 /* Test code calls this function to wait for a callback */
81 inline std::cv_status wait(int timeoutSeconds) {
82 std::unique_lock<std::mutex> lock(mtx_);
83
84 std::cv_status status = std::cv_status::no_timeout;
85 auto now = std::chrono::system_clock::now();
86 while (count == 0) {
87 status = cv_.wait_until(lock, now + std::chrono::seconds(timeoutSeconds));
88 if (status == std::cv_status::timeout) return status;
89 }
90 count--;
91 return status;
92 }
93
94 /* Callback class for data & Event. */
95 class GnssCallback : public IGnssCallback {
96 GnssHalTest& parent_;
97
98 public:
99 GnssCallback(GnssHalTest& parent) : parent_(parent){};
100
101 virtual ~GnssCallback() = default;
102
103 // Dummy callback handlers
104 Return<void> gnssStatusCb(
105 const IGnssCallback::GnssStatusValue status) override {
106 return Void();
107 }
108 Return<void> gnssSvStatusCb(
109 const IGnssCallback::GnssSvStatus& svStatus) override {
110 return Void();
111 }
112 Return<void> gnssNmeaCb(
113 int64_t timestamp,
114 const android::hardware::hidl_string& nmea) override {
115 return Void();
116 }
117 Return<void> gnssAcquireWakelockCb() override { return Void(); }
118 Return<void> gnssReleaseWakelockCb() override { return Void(); }
119 Return<void> gnssRequestTimeCb() override { return Void(); }
120
121 // Actual (test) callback handlers
122 Return<void> gnssLocationCb(const GnssLocation& location) override {
123 ALOGI("Location received");
124 parent_.location_called_count_++;
125 parent_.last_location_ = location;
126 parent_.notify();
127 return Void();
128 }
129
130 Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override {
131 ALOGI("Capabilities received %d", capabilities);
132 parent_.capabilities_called_count_++;
133 parent_.last_capabilities_ = capabilities;
134 parent_.notify();
135 return Void();
136 }
137
138 Return<void> gnssSetSystemInfoCb(
139 const IGnssCallback::GnssSystemInfo& info) override {
140 ALOGI("Info received, year %d", info.yearOfHw);
141 parent_.info_called_count_++;
142 parent_.last_info_ = info;
143 parent_.notify();
144 return Void();
145 }
146 };
147
148 sp<IGnss> gnss_hal_; // GNSS HAL to call into
149 sp<IGnssCallback> gnss_cb_; // Primary callback interface
150
151 /* Count of calls to set the following items, and the latest item (used by
152 * test.)
153 */
154 int capabilities_called_count_;
155 uint32_t last_capabilities_;
156
157 int location_called_count_;
158 GnssLocation last_location_;
159
160 int info_called_count_;
161 IGnssCallback::GnssSystemInfo last_info_;
162
163 private:
164 std::mutex mtx_;
165 std::condition_variable cv_;
166 int count;
167};
168
169/*
170 * SetCallbackCapabilitiesCleanup:
171 * Sets up the callback, awaits the capabilities, and calls cleanup
172 *
173 * Since this is just the basic operation of SetUp() and TearDown(),
174 * the function definition is intentionally kept empty
175 */
176TEST_F(GnssHalTest, SetCallbackCapabilitiesCleanup) {}
177
178void CheckLocation(GnssLocation& location) {
179 EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG);
180 EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE);
181 EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED);
182 EXPECT_TRUE(location.gnssLocationFlags &
183 GnssLocationFlags::HAS_HORIZONTAL_ACCURACY);
184 EXPECT_GE(location.latitudeDegrees, -90.0);
185 EXPECT_LE(location.latitudeDegrees, 90.0);
186 EXPECT_GE(location.longitudeDegrees, -180.0);
187 EXPECT_LE(location.longitudeDegrees, 180.0);
188 EXPECT_GE(location.altitudeMeters, -1000.0);
189 EXPECT_LE(location.altitudeMeters, 30000.0);
190 EXPECT_GE(location.speedMetersPerSec, 0.0);
191 EXPECT_LE(location.speedMetersPerSec, 5.0); // VTS tests are stationary.
192
193 /*
194 * Tolerating some especially high values for accuracy estimate, in case of
195 * first fix with especially poor geoemtry (happens occasionally)
196 */
197 EXPECT_GT(location.horizontalAccuracyMeters, 0.0);
198 EXPECT_LE(location.horizontalAccuracyMeters, 200.0);
199
200 /*
201 * Some devices may define bearing as -180 to +180, others as 0 to 360.
202 * Both are okay & understandable.
203 */
204 if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
205 EXPECT_GE(location.bearingDegrees, -180.0);
206 EXPECT_LE(location.bearingDegrees, 360.0);
207 }
208 if (location.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
209 EXPECT_GT(location.verticalAccuracyMeters, 0.0);
210 EXPECT_LE(location.verticalAccuracyMeters, 500.0);
211 }
212 if (location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
213 EXPECT_GT(location.speedAccuracyMetersPerSecond, 0.0);
214 EXPECT_LE(location.speedAccuracyMetersPerSecond, 50.0);
215 }
216 if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
217 EXPECT_GT(location.bearingAccuracyDegrees, 0.0);
218 EXPECT_LE(location.bearingAccuracyDegrees, 360.0);
219 }
220
221 // Check timestamp > 1.48e12 (47 years in msec - 1970->2017+)
222 EXPECT_GT(location.timestamp, 1.48e12);
223
224 /* TODO(b/35678469): Check if the hardware year is 2017+, and if so,
225 * that bearing, plus vertical, speed & bearing accuracy are present.
226 * And allow bearing to be not present, only if associated with a speed of 0.0
227 */
228}
229
230/*
231 * GetLocation:
232 * Turns on location, waits 45 second for at least 5 locations,
233 * and checks them for reasonable validity.
234 */
235TEST_F(GnssHalTest, GetLocation) {
236#define MIN_INTERVAL_MSEC 500
237#define PREFERRED_ACCURACY 0 // Ideally perfect (matches GnssLocationProvider)
238#define PREFERRED_TIME_MSEC 0 // Ideally immediate
239
240#define LOCATION_TIMEOUT_FIRST_SEC 45
241#define LOCATION_TIMEOUT_SUBSEQUENT_SEC 3
242#define LOCATIONS_TO_CHECK 5
243
244 auto result = gnss_hal_->setPositionMode(
245 IGnss::GnssPositionMode::MS_BASED,
246 IGnss::GnssPositionRecurrence::RECURRENCE_PERIODIC, MIN_INTERVAL_MSEC,
247 PREFERRED_ACCURACY, PREFERRED_TIME_MSEC);
248
249 ASSERT_TRUE(result.isOk());
250 ASSERT_TRUE(result);
251
252 result = gnss_hal_->start();
253
254 ASSERT_TRUE(result.isOk());
255 ASSERT_TRUE(result);
256
257 EXPECT_EQ(std::cv_status::no_timeout, wait(LOCATION_TIMEOUT_FIRST_SEC));
258 EXPECT_EQ(location_called_count_, 1);
259 CheckLocation(last_location_);
260
261 for (int i = 1; i < LOCATIONS_TO_CHECK; i++) {
262 EXPECT_EQ(std::cv_status::no_timeout,
263 wait(LOCATION_TIMEOUT_SUBSEQUENT_SEC));
264 EXPECT_EQ(location_called_count_, i + 1);
265 CheckLocation(last_location_);
266 }
267
268 result = gnss_hal_->stop();
269
270 ASSERT_TRUE(result.isOk());
271 ASSERT_TRUE(result);
272}
273
274int main(int argc, char** argv) {
275 ::testing::InitGoogleTest(&argc, argv);
276 int status = RUN_ALL_TESTS();
277 ALOGI("Test result = %d", status);
278 return status;
279}