1 /*
2 * Copyright (C) 2018 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 #ifndef GNSS_HAL_TEST_H_
18 #define GNSS_HAL_TEST_H_
19
20 #include <android/hardware/gnss/2.0/IGnss.h>
21 #include <VtsHalHidlTargetTestBase.h>
22 #include <VtsHalHidlTargetTestEnvBase.h>
23
24 #include <condition_variable>
25 #include <deque>
26 #include <mutex>
27
28 using android::hardware::hidl_vec;
29 using android::hardware::Return;
30 using android::hardware::Void;
31
32 using android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrectionsCallback;
33 using android::hardware::gnss::V1_0::GnssLocationFlags;
34 using android::hardware::gnss::V2_0::IGnss;
35
36 using GnssLocation_1_0 = android::hardware::gnss::V1_0::GnssLocation;
37 using GnssLocation_2_0 = android::hardware::gnss::V2_0::GnssLocation;
38
39 using IGnssCallback_1_0 = android::hardware::gnss::V1_0::IGnssCallback;
40 using IGnssCallback_2_0 = android::hardware::gnss::V2_0::IGnssCallback;
41
42 using IGnssMeasurementCallback_1_0 = android::hardware::gnss::V1_0::IGnssMeasurementCallback;
43 using IGnssMeasurementCallback_1_1 = android::hardware::gnss::V1_1::IGnssMeasurementCallback;
44 using IGnssMeasurementCallback_2_0 = android::hardware::gnss::V2_0::IGnssMeasurementCallback;
45
46 using android::sp;
47
48 #define TIMEOUT_SEC 2 // for basic commands/responses
49
50 // Test environment for GNSS HIDL HAL.
51 class GnssHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
52 public:
53 // get the test environment singleton
Instance()54 static GnssHidlEnvironment* Instance() {
55 static GnssHidlEnvironment* instance = new GnssHidlEnvironment;
56 return instance;
57 }
58
registerTestServices()59 virtual void registerTestServices() override { registerTestService<IGnss>(); }
60
61 private:
GnssHidlEnvironment()62 GnssHidlEnvironment() {}
63 };
64
65 // The main test class for GNSS HAL.
66 class GnssHalTest : public ::testing::VtsHalHidlTargetTestBase {
67 public:
68 virtual void SetUp() override;
69
70 virtual void TearDown() override;
71
72 /* Producer/consumer queue for storing/retrieving callback events from GNSS HAL */
73 template <class T>
74 class CallbackQueue {
75 public:
CallbackQueue(const std::string & name)76 CallbackQueue(const std::string& name) : name_(name), called_count_(0){};
~CallbackQueue()77 ~CallbackQueue() { reset(); }
78
79 /* Adds callback event to the end of the queue. */
80 void store(const T& event);
81
82 /*
83 * Removes the callack event at the front of the queue, stores it in event parameter
84 * and returns true. Returns false on timeout and event is not populated.
85 */
86 bool retrieve(T& event, int timeout_seconds);
87
88 /* Returns the number of events pending to be retrieved from the callback event queue. */
89 int size() const;
90
91 /* Returns the number of callback events received since last reset(). */
92 int calledCount() const;
93
94 /* Clears the callback event queue and resets the calledCount() to 0. */
95 void reset();
96
97 private:
98 CallbackQueue(const CallbackQueue&) = delete;
99 CallbackQueue& operator=(const CallbackQueue&) = delete;
100
101 std::string name_;
102 int called_count_;
103 mutable std::recursive_mutex mtx_;
104 std::condition_variable_any cv_;
105 std::deque<T> events_;
106 };
107
108 /* Callback class for data & Event. */
109 class GnssCallback : public IGnssCallback_2_0 {
110 public:
111 IGnssCallback_1_0::GnssSystemInfo last_info_;
112 android::hardware::hidl_string last_name_;
113 uint32_t last_capabilities_;
114 GnssLocation_2_0 last_location_;
115
116 CallbackQueue<IGnssCallback_1_0::GnssSystemInfo> info_cbq_;
117 CallbackQueue<android::hardware::hidl_string> name_cbq_;
118 CallbackQueue<uint32_t> capabilities_cbq_;
119 CallbackQueue<GnssLocation_2_0> location_cbq_;
120 CallbackQueue<hidl_vec<IGnssCallback_2_0::GnssSvInfo>> sv_info_cbq_;
121
122 GnssCallback();
123 virtual ~GnssCallback() = default;
124
125 // Dummy callback handlers
gnssStatusCb(const IGnssCallback_1_0::GnssStatusValue)126 Return<void> gnssStatusCb(const IGnssCallback_1_0::GnssStatusValue /* status */) override {
127 return Void();
128 }
gnssNmeaCb(int64_t,const android::hardware::hidl_string &)129 Return<void> gnssNmeaCb(int64_t /* timestamp */,
130 const android::hardware::hidl_string& /* nmea */) override {
131 return Void();
132 }
gnssAcquireWakelockCb()133 Return<void> gnssAcquireWakelockCb() override { return Void(); }
gnssReleaseWakelockCb()134 Return<void> gnssReleaseWakelockCb() override { return Void(); }
gnssRequestLocationCb(bool)135 Return<void> gnssRequestLocationCb(bool /* independentFromGnss */) override {
136 return Void();
137 }
gnssRequestTimeCb()138 Return<void> gnssRequestTimeCb() override { return Void(); }
139 // Actual (test) callback handlers
140 Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;
141 Return<void> gnssLocationCb(const GnssLocation_1_0& location) override;
142 Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
143 Return<void> gnssSetSystemInfoCb(const IGnssCallback_1_0::GnssSystemInfo& info) override;
144 Return<void> gnssSvStatusCb(const IGnssCallback_1_0::GnssSvStatus& svStatus) override;
145
146 // New in v2.0
147 Return<void> gnssLocationCb_2_0(const GnssLocation_2_0& location) override;
gnssRequestLocationCb_2_0(bool,bool)148 Return<void> gnssRequestLocationCb_2_0(bool /* independentFromGnss */,
149 bool /* isUserEmergency */) override {
150 return Void();
151 }
152 Return<void> gnssSetCapabilitiesCb_2_0(uint32_t capabilities) override;
153 Return<void> gnssSvStatusCb_2_0(
154 const hidl_vec<IGnssCallback_2_0::GnssSvInfo>& svInfoList) override;
155
156 private:
157 Return<void> gnssLocationCbImpl(const GnssLocation_2_0& location);
158 };
159
160 /* Callback class for GnssMeasurement. */
161 class GnssMeasurementCallback : public IGnssMeasurementCallback_2_0 {
162 public:
163 CallbackQueue<IGnssMeasurementCallback_2_0::GnssData> measurement_cbq_;
164
GnssMeasurementCallback()165 GnssMeasurementCallback() : measurement_cbq_("measurement"){};
166 virtual ~GnssMeasurementCallback() = default;
167
168 // Methods from V1_0::IGnssMeasurementCallback follow.
GnssMeasurementCb(const IGnssMeasurementCallback_1_0::GnssData &)169 Return<void> GnssMeasurementCb(const IGnssMeasurementCallback_1_0::GnssData&) override {
170 return Void();
171 }
172
173 // Methods from V1_1::IGnssMeasurementCallback follow.
gnssMeasurementCb(const IGnssMeasurementCallback_1_1::GnssData &)174 Return<void> gnssMeasurementCb(const IGnssMeasurementCallback_1_1::GnssData&) override {
175 return Void();
176 }
177
178 // Methods from V2_0::IGnssMeasurementCallback follow.
179 Return<void> gnssMeasurementCb_2_0(const IGnssMeasurementCallback_2_0::GnssData&) override;
180 };
181
182 /* Callback class for GnssMeasurementCorrections. */
183 class GnssMeasurementCorrectionsCallback : public IMeasurementCorrectionsCallback {
184 public:
185 uint32_t last_capabilities_;
186 CallbackQueue<uint32_t> capabilities_cbq_;
187
GnssMeasurementCorrectionsCallback()188 GnssMeasurementCorrectionsCallback() : capabilities_cbq_("capabilities"){};
189 virtual ~GnssMeasurementCorrectionsCallback() = default;
190
191 // Methods from V1_0::IMeasurementCorrectionsCallback follow.
192 Return<void> setCapabilitiesCb(uint32_t capabilities) override;
193 };
194
195 /*
196 * SetUpGnssCallback:
197 * Set GnssCallback and verify the result.
198 */
199 void SetUpGnssCallback();
200
201 /*
202 * StartAndCheckFirstLocation:
203 * Helper function to start location, and check the first one.
204 *
205 * <p> Note this leaves the Location request active, to enable Stop call vs. other call
206 * reordering tests.
207 *
208 * returns true if a location was successfully generated
209 */
210 bool StartAndCheckFirstLocation();
211
212 /*
213 * CheckLocation:
214 * Helper function to vet Location fields
215 *
216 * check_speed: true if speed related fields are also verified.
217 */
218 void CheckLocation(const GnssLocation_2_0& location, const bool check_speed);
219
220 /*
221 * StartAndCheckLocations:
222 * Helper function to collect, and check a number of
223 * normal ~1Hz locations.
224 *
225 * Note this leaves the Location request active, to enable Stop call vs. other call
226 * reordering tests.
227 */
228 void StartAndCheckLocations(int count);
229
230 /*
231 * StopAndClearLocations:
232 * Helper function to stop locations, and clear any remaining notifications
233 */
234 void StopAndClearLocations();
235
236 /*
237 * SetPositionMode:
238 * Helper function to set positioning mode and verify output
239 */
240 void SetPositionMode(const int min_interval_msec, const bool low_power_mode);
241
242 sp<IGnss> gnss_hal_; // GNSS HAL to call into
243 sp<GnssCallback> gnss_cb_; // Primary callback interface
244 };
245
246 template <class T>
store(const T & event)247 void GnssHalTest::CallbackQueue<T>::store(const T& event) {
248 std::unique_lock<std::recursive_mutex> lock(mtx_);
249 events_.push_back(event);
250 ++called_count_;
251 lock.unlock();
252 cv_.notify_all();
253 }
254
255 template <class T>
retrieve(T & event,int timeout_seconds)256 bool GnssHalTest::CallbackQueue<T>::retrieve(T& event, int timeout_seconds) {
257 std::unique_lock<std::recursive_mutex> lock(mtx_);
258 cv_.wait_for(lock, std::chrono::seconds(timeout_seconds), [&] { return !events_.empty(); });
259 if (events_.empty()) {
260 return false;
261 }
262 event = events_.front();
263 events_.pop_front();
264 return true;
265 }
266
267 template <class T>
size()268 int GnssHalTest::CallbackQueue<T>::size() const {
269 std::unique_lock<std::recursive_mutex> lock(mtx_);
270 return events_.size();
271 }
272
273 template <class T>
calledCount()274 int GnssHalTest::CallbackQueue<T>::calledCount() const {
275 std::unique_lock<std::recursive_mutex> lock(mtx_);
276 return called_count_;
277 }
278
279 template <class T>
reset()280 void GnssHalTest::CallbackQueue<T>::reset() {
281 std::unique_lock<std::recursive_mutex> lock(mtx_);
282 if (!events_.empty()) {
283 ALOGW("%u unprocessed events discarded in callback queue %s", (unsigned int)events_.size(),
284 name_.c_str());
285 }
286 events_.clear();
287 called_count_ = 0;
288 }
289
290 #endif // GNSS_HAL_TEST_H_
291