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 54 static GnssHidlEnvironment* Instance() { 55 static GnssHidlEnvironment* instance = new GnssHidlEnvironment; 56 return instance; 57 } 58 59 virtual void registerTestServices() override { registerTestService<IGnss>(); } 60 61 private: 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: 76 CallbackQueue(const std::string& name) : name_(name), called_count_(0){}; 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 126 Return<void> gnssStatusCb(const IGnssCallback_1_0::GnssStatusValue /* status */) override { 127 return Void(); 128 } 129 Return<void> gnssNmeaCb(int64_t /* timestamp */, 130 const android::hardware::hidl_string& /* nmea */) override { 131 return Void(); 132 } 133 Return<void> gnssAcquireWakelockCb() override { return Void(); } 134 Return<void> gnssReleaseWakelockCb() override { return Void(); } 135 Return<void> gnssRequestLocationCb(bool /* independentFromGnss */) override { 136 return Void(); 137 } 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; 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 165 GnssMeasurementCallback() : measurement_cbq_("measurement"){}; 166 virtual ~GnssMeasurementCallback() = default; 167 168 // Methods from V1_0::IGnssMeasurementCallback follow. 169 Return<void> GnssMeasurementCb(const IGnssMeasurementCallback_1_0::GnssData&) override { 170 return Void(); 171 } 172 173 // Methods from V1_1::IGnssMeasurementCallback follow. 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 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> 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> 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> 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> 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> 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