From 030d033b3fb7818ecd2f4439f0457d62329f5cc4 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Sun, 9 Dec 2018 10:47:42 -0800 Subject: [PATCH] Add TestGnssMeasurementCodeType VTS test - add default implementation to mock reporting measurements. Bug: 120277977 Fixes: 120277977 Test: atest VtsHalGnssV2_0TargetTest Change-Id: I881f105874a992327551ef616860d7bd61e4bf83 --- gnss/2.0/default/Gnss.cpp | 15 +-- gnss/2.0/default/GnssMeasurement.cpp | 106 ++++++++++++++++-- gnss/2.0/default/GnssMeasurement.h | 19 ++++ gnss/2.0/vts/functional/gnss_hal_test.cpp | 16 +++ gnss/2.0/vts/functional/gnss_hal_test.h | 37 +++++- .../vts/functional/gnss_hal_test_cases.cpp | 51 ++++++++- 6 files changed, 219 insertions(+), 25 deletions(-) diff --git a/gnss/2.0/default/Gnss.cpp b/gnss/2.0/default/Gnss.cpp index 7f1ef9bdf8..886a3a8d7c 100644 --- a/gnss/2.0/default/Gnss.cpp +++ b/gnss/2.0/default/Gnss.cpp @@ -19,6 +19,7 @@ #include "Gnss.h" #include #include "AGnssRil.h" +#include "GnssMeasurement.h" namespace android { namespace hardware { @@ -93,8 +94,8 @@ Return> Gnss::getExtensionGnssNi() { } Return> Gnss::getExtensionGnssMeasurement() { - // TODO implement - return sp{}; + // Not supported + return nullptr; } Return> Gnss::getExtensionGnssNavigationMessage() { @@ -132,7 +133,7 @@ Return Gnss::setCallback_1_1(const sp& callback) { sGnssCallback_1_1 = callback; - uint32_t capabilities = 0x0; + uint32_t capabilities = (uint32_t)V1_0::IGnssCallback::Capabilities::MEASUREMENTS; auto ret = sGnssCallback_1_1->gnssSetCapabilitesCb(capabilities); if (!ret.isOk()) { ALOGE("%s: Unable to invoke callback", __func__); @@ -167,8 +168,8 @@ Return> Gnss::getExtensionGnssConfiguration_1_1() { } Return> Gnss::getExtensionGnssMeasurement_1_1() { - // TODO implement - return sp{}; + ALOGD("Gnss::getExtensionGnssMeasurement_1_1"); + return new GnssMeasurement(); } Return Gnss::injectBestLocation(const V1_0::GnssLocation&) { @@ -182,8 +183,8 @@ Return> Gnss::getExtensionAGnssRil_2_0() { } Return> Gnss::getExtensionGnssMeasurement_2_0() { - // TODO implement - return sp{}; + ALOGD("Gnss::getExtensionGnssMeasurement_2_0"); + return new GnssMeasurement(); } Return> diff --git a/gnss/2.0/default/GnssMeasurement.cpp b/gnss/2.0/default/GnssMeasurement.cpp index fbcdc12c5a..dc23db3163 100644 --- a/gnss/2.0/default/GnssMeasurement.cpp +++ b/gnss/2.0/default/GnssMeasurement.cpp @@ -13,8 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#define LOG_TAG "GnssMeasurement" #include "GnssMeasurement.h" +#include namespace android { namespace hardware { @@ -22,6 +24,18 @@ namespace gnss { namespace V2_0 { namespace implementation { +using GnssConstellationType = V1_0::GnssConstellationType; +using GnssMeasurementFlags = V1_0::IGnssMeasurementCallback::GnssMeasurementFlags; +using GnssMeasurementState = V1_0::IGnssMeasurementCallback::GnssMeasurementState; + +sp GnssMeasurement::sCallback = nullptr; + +GnssMeasurement::GnssMeasurement() : mMinIntervalMillis(1000) {} + +GnssMeasurement::~GnssMeasurement() { + stop(); +} + // Methods from V1_0::IGnssMeasurement follow. Return GnssMeasurement::setCallback( const sp&) { @@ -30,7 +44,9 @@ Return GnssMeasurement::setCallba } Return GnssMeasurement::close() { - // TODO implement + std::unique_lock lock(mMutex); + stop(); + sCallback = nullptr; return Void(); } @@ -43,17 +59,89 @@ Return GnssMeasurement::setCallba // Methods from V2_0::IGnssMeasurement follow. Return GnssMeasurement::setCallback_2_0( - const sp&, bool) { - // TODO implement - return V1_0::IGnssMeasurement::GnssMeasurementStatus{}; + const sp& callback, bool) { + std::unique_lock lock(mMutex); + sCallback = callback; + + if (mIsActive) { + ALOGW("GnssMeasurement callback already set. Resetting the callback..."); + stop(); + } + start(); + + return V1_0::IGnssMeasurement::GnssMeasurementStatus::SUCCESS; } -// Methods from ::android::hidl::base::V1_0::IBase follow. +void GnssMeasurement::start() { + mIsActive = true; + mThread = std::thread([this]() { + while (mIsActive == true) { + auto measurement = this->getMockMeasurement(); + this->reportMeasurement(measurement); + + std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis)); + } + }); +} + +void GnssMeasurement::stop() { + mIsActive = false; + if (mThread.joinable()) { + mThread.join(); + } +} + +GnssData GnssMeasurement::getMockMeasurement() { + V1_0::IGnssMeasurementCallback::GnssMeasurement measurement_1_0 = { + .flags = (uint32_t)GnssMeasurementFlags::HAS_CARRIER_FREQUENCY, + .svid = (int16_t)6, + .constellation = GnssConstellationType::GLONASS, + .timeOffsetNs = 0.0, + .state = GnssMeasurementState::STATE_CODE_LOCK | GnssMeasurementState::STATE_BIT_SYNC | + GnssMeasurementState::STATE_SUBFRAME_SYNC | + GnssMeasurementState::STATE_TOW_DECODED | + GnssMeasurementState::STATE_GLO_STRING_SYNC | + GnssMeasurementState::STATE_GLO_TOD_DECODED, + .receivedSvTimeInNs = 8195997131077, + .receivedSvTimeUncertaintyInNs = 15, + .cN0DbHz = 30.0, + .pseudorangeRateMps = -484.13739013671875, + .pseudorangeRateUncertaintyMps = 1.0379999876022339, + .accumulatedDeltaRangeState = (uint32_t) + V1_0::IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_UNKNOWN, + .accumulatedDeltaRangeM = 0.0, + .accumulatedDeltaRangeUncertaintyM = 0.0, + .carrierFrequencyHz = 1.59975e+09, + .multipathIndicator = + V1_0::IGnssMeasurementCallback::GnssMultipathIndicator::INDICATOR_UNKNOWN}; + V1_1::IGnssMeasurementCallback::GnssMeasurement measurement_1_1 = {.v1_0 = measurement_1_0}; + V2_0::IGnssMeasurementCallback::GnssMeasurement measurement_2_0 = { + .v1_1 = measurement_1_1, + .codeType = IGnssMeasurementCallback::GnssMeasurementCodeType::CODE_TYPE_C}; + + hidl_vec measurements(1); + measurements[0] = measurement_2_0; + V1_0::IGnssMeasurementCallback::GnssClock clock = {.timeNs = 2713545000000, + .fullBiasNs = -1226701900521857520, + .biasNs = 0.59689998626708984, + .biasUncertaintyNs = 47514.989972114563, + .driftNsps = -51.757811607455452, + .driftUncertaintyNsps = 310.64968328491528, + .hwClockDiscontinuityCount = 1}; + GnssData gnssData = {.measurements = measurements, .clock = clock}; + return gnssData; +} + +void GnssMeasurement::reportMeasurement(const GnssData& data) { + ALOGD("reportMeasurement()"); + std::unique_lock lock(mMutex); + if (sCallback == nullptr) { + ALOGE("%s: GnssMeasurement::sCallback is null.", __func__); + return; + } + sCallback->gnssMeasurementCb_2_0(data); +} -// IGnssMeasurement* HIDL_FETCH_IGnssMeasurement(const char* /* name */) { -// return new GnssMeasurement(); -//} -// } // namespace implementation } // namespace V2_0 } // namespace gnss diff --git a/gnss/2.0/default/GnssMeasurement.h b/gnss/2.0/default/GnssMeasurement.h index 8c621bb24a..c24c00e341 100644 --- a/gnss/2.0/default/GnssMeasurement.h +++ b/gnss/2.0/default/GnssMeasurement.h @@ -20,6 +20,9 @@ #include #include #include +#include +#include +#include namespace android { namespace hardware { @@ -35,7 +38,11 @@ using ::android::hardware::hidl_vec; using ::android::hardware::Return; using ::android::hardware::Void; +using GnssData = V2_0::IGnssMeasurementCallback::GnssData; + struct GnssMeasurement : public IGnssMeasurement { + GnssMeasurement(); + ~GnssMeasurement(); // Methods from V1_0::IGnssMeasurement follow. Return setCallback( const sp& callback) override; @@ -48,6 +55,18 @@ struct GnssMeasurement : public IGnssMeasurement { // Methods from V2_0::IGnssMeasurement follow. Return setCallback_2_0( const sp& callback, bool enableFullTracking) override; + + private: + void start(); + void stop(); + GnssData getMockMeasurement(); + void reportMeasurement(const GnssData&); + + static sp sCallback; + std::atomic mMinIntervalMillis; + std::atomic mIsActive; + std::thread mThread; + mutable std::mutex mMutex; }; } // namespace implementation diff --git a/gnss/2.0/vts/functional/gnss_hal_test.cpp b/gnss/2.0/vts/functional/gnss_hal_test.cpp index d7101a03b7..3a48c9e268 100644 --- a/gnss/2.0/vts/functional/gnss_hal_test.cpp +++ b/gnss/2.0/vts/functional/gnss_hal_test.cpp @@ -38,6 +38,13 @@ void GnssHalTest::SetUp() { } void GnssHalTest::TearDown() { + // Reset counters + info_called_count_ = 0; + capabilities_called_count_ = 0; + location_called_count_ = 0; + name_called_count_ = 0; + measurement_called_count_ = 0; + if (gnss_hal_ != nullptr) { gnss_hal_->cleanup(); } @@ -127,3 +134,12 @@ Return GnssHalTest::GnssCallback::gnssSvStatusCb( parent_.list_gnss_sv_status_.emplace_back(svStatus); return Void(); } + +Return GnssHalTest::GnssMeasurementCallback::gnssMeasurementCb_2_0( + const IGnssMeasurementCallback_2_0::GnssData& data) { + ALOGD("GnssMeasurement received. Size = %d", (int)data.measurements.size()); + parent_.measurement_called_count_++; + parent_.last_measurement_ = data; + parent_.notify(); + return Void(); +} diff --git a/gnss/2.0/vts/functional/gnss_hal_test.h b/gnss/2.0/vts/functional/gnss_hal_test.h index 64f3575419..5649b45bbd 100644 --- a/gnss/2.0/vts/functional/gnss_hal_test.h +++ b/gnss/2.0/vts/functional/gnss_hal_test.h @@ -34,6 +34,9 @@ using android::hardware::gnss::V1_0::GnssLocation; using android::hardware::gnss::V1_0::GnssLocationFlags; using android::hardware::gnss::V1_1::IGnssCallback; using android::hardware::gnss::V2_0::IGnss; +using IGnssMeasurementCallback_1_0 = android::hardware::gnss::V1_0::IGnssMeasurementCallback; +using IGnssMeasurementCallback_1_1 = android::hardware::gnss::V1_1::IGnssMeasurementCallback; +using IGnssMeasurementCallback_2_0 = android::hardware::gnss::V2_0::IGnssMeasurementCallback; using android::sp; @@ -100,6 +103,27 @@ class GnssHalTest : public ::testing::VtsHalHidlTargetTestBase { Return gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override; }; + /* Callback class for GnssMeasurement. */ + class GnssMeasurementCallback : public IGnssMeasurementCallback_2_0 { + public: + GnssHalTest& parent_; + GnssMeasurementCallback(GnssHalTest& parent) : parent_(parent){}; + virtual ~GnssMeasurementCallback() = default; + + // Methods from V1_0::IGnssMeasurementCallback follow. + Return GnssMeasurementCb(const IGnssMeasurementCallback_1_0::GnssData&) override { + return Void(); + } + + // Methods from V1_1::IGnssMeasurementCallback follow. + Return gnssMeasurementCb(const IGnssMeasurementCallback_1_1::GnssData&) override { + return Void(); + } + + // Methods from V2_0::IGnssMeasurementCallback follow. + Return gnssMeasurementCb_2_0(const IGnssMeasurementCallback_2_0::GnssData&) override; + }; + /* * SetUpGnssCallback: * Set GnssCallback and verify the result. @@ -113,16 +137,19 @@ class GnssHalTest : public ::testing::VtsHalHidlTargetTestBase { * test.) */ int info_called_count_; - IGnssCallback::GnssSystemInfo last_info_; - uint32_t last_capabilities_; int capabilities_called_count_; int location_called_count_; - GnssLocation last_location_; - list list_gnss_sv_status_; - + int measurement_called_count_; int name_called_count_; + + IGnssCallback::GnssSystemInfo last_info_; + uint32_t last_capabilities_; + GnssLocation last_location_; + IGnssMeasurementCallback_2_0::GnssData last_measurement_; android::hardware::hidl_string last_name_; + list list_gnss_sv_status_; + private: std::mutex mtx_; std::condition_variable cv_; diff --git a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp index 478a4b2b02..c1f1393db9 100644 --- a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp +++ b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp @@ -21,9 +21,10 @@ using android::hardware::hidl_vec; +using IAGnssRil_2_0 = android::hardware::gnss::V2_0::IAGnssRil; using IGnssMeasurement_2_0 = android::hardware::gnss::V2_0::IGnssMeasurement; using IGnssMeasurement_1_1 = android::hardware::gnss::V1_1::IGnssMeasurement; -using IAGnssRil_2_0 = android::hardware::gnss::V2_0::IAGnssRil; +using IGnssMeasurement_1_0 = android::hardware::gnss::V1_0::IGnssMeasurement; /* * SetupTeardownCreateCleanup: @@ -40,12 +41,17 @@ TEST_F(GnssHalTest, SetupTeardownCreateCleanup) {} TEST_F(GnssHalTest, TestGnssMeasurementCallback) { auto gnssMeasurement_2_0 = gnss_hal_->getExtensionGnssMeasurement_2_0(); auto gnssMeasurement_1_1 = gnss_hal_->getExtensionGnssMeasurement_1_1(); - ASSERT_TRUE(gnssMeasurement_2_0.isOk() || gnssMeasurement_1_1.isOk()); + auto gnssMeasurement_1_0 = gnss_hal_->getExtensionGnssMeasurement(); + ASSERT_TRUE(gnssMeasurement_2_0.isOk() || gnssMeasurement_1_1.isOk() || + gnssMeasurement_1_0.isOk()); if (last_capabilities_ & IGnssCallback::Capabilities::MEASUREMENTS) { sp iGnssMeas_2_0 = gnssMeasurement_2_0; sp iGnssMeas_1_1 = gnssMeasurement_1_1; - // Exactly one interface is non-null. - ASSERT_TRUE((iGnssMeas_1_1 != nullptr) != (iGnssMeas_2_0 != nullptr)); + sp iGnssMeas_1_0 = gnssMeasurement_1_0; + // At least one interface is non-null. + int numNonNull = (int)(iGnssMeas_2_0 != nullptr) + (int)(iGnssMeas_1_1 != nullptr) + + (int)(iGnssMeas_1_0 != nullptr); + ASSERT_TRUE(numNonNull >= 1); } } @@ -90,3 +96,40 @@ TEST_F(GnssHalTest, TestAGnssRilUpdateNetworkState_2_0) { ASSERT_TRUE(result.isOk()); EXPECT_TRUE(result); } + +/* + * TestGnssMeasurementCodeType: + * Sets a GnssMeasurementCallback, waits for a measurement, and verifies the codeType is valid. + */ +TEST_F(GnssHalTest, TestGnssMeasurementCodeType) { + const int kFirstGnssMeasurementTimeoutSeconds = 10; + + auto gnssMeasurement = gnss_hal_->getExtensionGnssMeasurement_2_0(); + if (!gnssMeasurement.isOk()) { + return; + } + + sp iGnssMeasurement = gnssMeasurement; + if (iGnssMeasurement == nullptr) { + return; + } + + sp callback = new GnssMeasurementCallback(*this); + + auto result = iGnssMeasurement->setCallback_2_0(callback, /* enableFullTracking= */ true); + ASSERT_TRUE(result.isOk()); + EXPECT_EQ(result, IGnssMeasurement_1_0::GnssMeasurementStatus::SUCCESS); + + wait(kFirstGnssMeasurementTimeoutSeconds); + EXPECT_EQ(measurement_called_count_, 1); + ASSERT_TRUE(last_measurement_.measurements.size() > 0); + for (auto measurement : last_measurement_.measurements) { + ASSERT_TRUE( + (int)measurement.codeType >= + (int)IGnssMeasurementCallback_2_0::GnssMeasurementCodeType::CODE_TYPE_A && + (int)measurement.codeType <= + (int)IGnssMeasurementCallback_2_0::GnssMeasurementCodeType::CODE_TYPE_CODELESS); + } + + iGnssMeasurement->close(); +}