Fix 2.0 VTS and 2.1 HAL/default implementation

Test: atest VtsHalGnssV2_0TargetTest && atest VtsHalGnssV2_1TargetTest
Bug: 145830353, 146216289
Change-Id: I77d614783ee5451368a0e93eddc5e71c571193ed
This commit is contained in:
Sasha Kuznetsov 2019-12-09 17:11:08 -08:00
parent 2a34cdb7ce
commit 7fd5cc3a4b
10 changed files with 248 additions and 28 deletions

View file

@ -172,7 +172,14 @@ bool GnssHalTest::IsGnssHalVersion_1_1() const {
hasGnssHalVersion_2_0 = registered.size() != 0; hasGnssHalVersion_2_0 = registered.size() != 0;
}); });
return hasGnssHalVersion_1_1 && !hasGnssHalVersion_2_0; bool hasGnssHalVersion_2_1 = false;
manager->listManifestByInterface(
"android.hardware.gnss@2.1::IGnss",
[&hasGnssHalVersion_2_1](const hidl_vec<hidl_string>& registered) {
hasGnssHalVersion_2_1 = registered.size() != 0;
});
return hasGnssHalVersion_1_1 && !hasGnssHalVersion_2_0 && !hasGnssHalVersion_2_1;
} }
GnssConstellationType GnssHalTest::startLocationAndGetNonGpsConstellation( GnssConstellationType GnssHalTest::startLocationAndGetNonGpsConstellation(

View file

@ -16,11 +16,14 @@
#define LOG_TAG "GnssHalTest" #define LOG_TAG "GnssHalTest"
#include <android/hidl/manager/1.2/IServiceManager.h>
#include <gnss_hal_test.h> #include <gnss_hal_test.h>
#include <gtest/gtest.h>
#include <hidl/ServiceManagement.h>
#include <chrono> #include <chrono>
#include "Utils.h" #include "Utils.h"
#include <gtest/gtest.h> using ::android::hardware::hidl_string;
using ::android::hardware::gnss::common::Utils; using ::android::hardware::gnss::common::Utils;
@ -99,7 +102,6 @@ bool GnssHalTest::StartAndCheckFirstLocation() {
EXPECT_TRUE(result.isOk()); EXPECT_TRUE(result.isOk());
EXPECT_TRUE(result); EXPECT_TRUE(result);
/* /*
* GnssLocationProvider support of AGPS SUPL & XtraDownloader is not available in VTS, * GnssLocationProvider support of AGPS SUPL & XtraDownloader is not available in VTS,
* so allow time to demodulate ephemeris over the air. * so allow time to demodulate ephemeris over the air.
@ -148,6 +150,27 @@ void GnssHalTest::StartAndCheckLocations(int count) {
} }
} }
bool GnssHalTest::IsGnssHalVersion_2_0() const {
using ::android::hidl::manager::V1_2::IServiceManager;
sp<IServiceManager> manager = ::android::hardware::defaultServiceManager1_2();
bool hasGnssHalVersion_2_0 = false;
manager->listManifestByInterface(
"android.hardware.gnss@2.0::IGnss",
[&hasGnssHalVersion_2_0](const hidl_vec<hidl_string>& registered) {
hasGnssHalVersion_2_0 = registered.size() != 0;
});
bool hasGnssHalVersion_2_1 = false;
manager->listManifestByInterface(
"android.hardware.gnss@2.1::IGnss",
[&hasGnssHalVersion_2_1](const hidl_vec<hidl_string>& registered) {
hasGnssHalVersion_2_1 = registered.size() != 0;
});
return hasGnssHalVersion_2_0 && !hasGnssHalVersion_2_1;
}
GnssHalTest::GnssCallback::GnssCallback() GnssHalTest::GnssCallback::GnssCallback()
: info_cbq_("system_info"), : info_cbq_("system_info"),
name_cbq_("name"), name_cbq_("name"),

View file

@ -180,6 +180,12 @@ class GnssHalTest : public testing::TestWithParam<std::string> {
*/ */
void StopAndClearLocations(); void StopAndClearLocations();
/*
* IsGnssHalVersion_2_0:
* returns true if the GNSS HAL version is exactly 2.0.
*/
bool IsGnssHalVersion_2_0() const;
/* /*
* SetPositionMode: * SetPositionMode:
* Helper function to set positioning mode and verify output * Helper function to set positioning mode and verify output

View file

@ -182,6 +182,10 @@ TEST_P(GnssHalTest, TestAGnssRil_UpdateNetworkState_2_0) {
* 3. state is valid. * 3. state is valid.
*/ */
TEST_P(GnssHalTest, TestGnssMeasurementFields) { TEST_P(GnssHalTest, TestGnssMeasurementFields) {
if (!IsGnssHalVersion_2_0()) {
ALOGI("Test GnssMeasurementFields skipped. GNSS HAL version is greater than 2.0.");
return;
}
const int kFirstGnssMeasurementTimeoutSeconds = 10; const int kFirstGnssMeasurementTimeoutSeconds = 10;
auto gnssMeasurement = gnss_hal_->getExtensionGnssMeasurement_2_0(); auto gnssMeasurement = gnss_hal_->getExtensionGnssMeasurement_2_0();
@ -464,7 +468,7 @@ TEST_P(GnssHalTest, GetLocationLowPower) {
} }
EXPECT_LE(location_called_count, i); EXPECT_LE(location_called_count, i);
if (location_called_count != i) { if (location_called_count != i) {
ALOGW("GetLocationLowPower test - not enough locations received. %d vs. %d expected ", ALOGW("GetLocationLowPower test - too many locations received. %d vs. %d expected ",
location_called_count, i); location_called_count, i);
} }
@ -601,6 +605,11 @@ IGnssConfiguration_1_1::BlacklistedSource FindStrongFrequentNonGpsSource(
* formerly strongest satellite * formerly strongest satellite
*/ */
TEST_P(GnssHalTest, BlacklistIndividualSatellites) { TEST_P(GnssHalTest, BlacklistIndividualSatellites) {
if (!IsGnssHalVersion_2_0()) {
ALOGI("Test BlacklistIndividualSatellites skipped. GNSS HAL version is greater than 2.0.");
return;
}
if (!(gnss_cb_->last_capabilities_ & IGnssCallback::Capabilities::SATELLITE_BLACKLIST)) { if (!(gnss_cb_->last_capabilities_ & IGnssCallback::Capabilities::SATELLITE_BLACKLIST)) {
ALOGI("Test BlacklistIndividualSatellites skipped. SATELLITE_BLACKLIST capability" ALOGI("Test BlacklistIndividualSatellites skipped. SATELLITE_BLACKLIST capability"
" not supported."); " not supported.");
@ -746,6 +755,11 @@ TEST_P(GnssHalTest, BlacklistIndividualSatellites) {
* 4a & b) Clean up by turning off location, and send in empty blacklist. * 4a & b) Clean up by turning off location, and send in empty blacklist.
*/ */
TEST_P(GnssHalTest, BlacklistConstellation) { TEST_P(GnssHalTest, BlacklistConstellation) {
if (!IsGnssHalVersion_2_0()) {
ALOGI("Test BlacklistConstellation skipped. GNSS HAL version is greater than 2.0.");
return;
}
if (!(gnss_cb_->last_capabilities_ & IGnssCallback::Capabilities::SATELLITE_BLACKLIST)) { if (!(gnss_cb_->last_capabilities_ & IGnssCallback::Capabilities::SATELLITE_BLACKLIST)) {
ALOGI("Test BlacklistConstellation skipped. SATELLITE_BLACKLIST capability not supported."); ALOGI("Test BlacklistConstellation skipped. SATELLITE_BLACKLIST capability not supported.");
return; return;

View file

@ -23,8 +23,9 @@ cc_binary {
srcs: [ srcs: [
"Gnss.cpp", "Gnss.cpp",
"GnssMeasurement.cpp", "GnssMeasurement.cpp",
"GnssMeasurementCorrections.cpp",
"GnssConfiguration.cpp", "GnssConfiguration.cpp",
"service.cpp" "service.cpp",
], ],
shared_libs: [ shared_libs: [
"libhidlbase", "libhidlbase",

View file

@ -18,11 +18,14 @@
#include "Gnss.h" #include "Gnss.h"
#include "GnssMeasurement.h" #include "GnssMeasurement.h"
#include "GnssMeasurementCorrections.h"
#include "Utils.h" #include "Utils.h"
#include <log/log.h> #include <log/log.h>
using ::android::hardware::gnss::common::Utils; using ::android::hardware::gnss::common::Utils;
using ::android::hardware::gnss::measurement_corrections::V1_0::implementation::
GnssMeasurementCorrections;
namespace android { namespace android {
namespace hardware { namespace hardware {
@ -87,7 +90,8 @@ Return<bool> Gnss::setCallback(const sp<V1_0::IGnssCallback>&) {
} }
Return<void> Gnss::cleanup() { Return<void> Gnss::cleanup() {
// TODO implement sGnssCallback_2_1 = nullptr;
sGnssCallback_2_0 = nullptr;
return Void(); return Void();
} }
@ -170,8 +174,9 @@ Return<bool> Gnss::setCallback_1_1(const sp<V1_1::IGnssCallback>&) {
} }
Return<bool> Gnss::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode, Return<bool> Gnss::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode,
V1_0::IGnss::GnssPositionRecurrence, uint32_t, uint32_t, V1_0::IGnss::GnssPositionRecurrence, uint32_t minIntervalMs,
uint32_t, bool) { uint32_t, uint32_t, bool) {
mMinIntervalMs = minIntervalMs;
return true; return true;
} }
@ -215,7 +220,7 @@ Return<bool> Gnss::setCallback_2_0(const sp<V2_0::IGnssCallback>& callback) {
ALOGE("%s: Unable to invoke callback", __func__); ALOGE("%s: Unable to invoke callback", __func__);
} }
auto gnssName = "Google Mock GNSS Implementation v2.0"; auto gnssName = "Google Mock GNSS Implementation v2.1";
ret = sGnssCallback_2_0->gnssNameCb(gnssName); ret = sGnssCallback_2_0->gnssNameCb(gnssName);
if (!ret.isOk()) { if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__); ALOGE("%s: Unable to invoke callback", __func__);
@ -251,8 +256,8 @@ Return<sp<V2_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_2_0() {
Return<sp<measurement_corrections::V1_0::IMeasurementCorrections>> Return<sp<measurement_corrections::V1_0::IMeasurementCorrections>>
Gnss::getExtensionMeasurementCorrections() { Gnss::getExtensionMeasurementCorrections() {
// TODO implement ALOGD("Gnss::getExtensionMeasurementCorrections()");
return ::android::sp<measurement_corrections::V1_0::IMeasurementCorrections>{}; return new GnssMeasurementCorrections();
} }
Return<sp<visibility_control::V1_0::IGnssVisibilityControl>> Gnss::getExtensionVisibilityControl() { Return<sp<visibility_control::V1_0::IGnssVisibilityControl>> Gnss::getExtensionVisibilityControl() {
@ -266,7 +271,7 @@ Return<sp<V2_0::IGnssBatching>> Gnss::getExtensionGnssBatching_2_0() {
} }
Return<bool> Gnss::injectBestLocation_2_0(const V2_0::GnssLocation&) { Return<bool> Gnss::injectBestLocation_2_0(const V2_0::GnssLocation&) {
// TODO implement // TODO(b/124012850): Implement function.
return bool{}; return bool{};
} }
@ -316,6 +321,7 @@ Return<sp<V2_1::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_2_1() {
void Gnss::reportSvStatus(const hidl_vec<GnssSvInfo>& svInfoList) const { void Gnss::reportSvStatus(const hidl_vec<GnssSvInfo>& svInfoList) const {
std::unique_lock<std::mutex> lock(mMutex); std::unique_lock<std::mutex> lock(mMutex);
// TODO(skz): update this to call 2_0 callback if non-null
if (sGnssCallback_2_1 == nullptr) { if (sGnssCallback_2_1 == nullptr) {
ALOGE("%s: sGnssCallback v2.1 is null.", __func__); ALOGE("%s: sGnssCallback v2.1 is null.", __func__);
return; return;
@ -328,13 +334,20 @@ void Gnss::reportSvStatus(const hidl_vec<GnssSvInfo>& svInfoList) const {
void Gnss::reportLocation(const V2_0::GnssLocation& location) const { void Gnss::reportLocation(const V2_0::GnssLocation& location) const {
std::unique_lock<std::mutex> lock(mMutex); std::unique_lock<std::mutex> lock(mMutex);
if (sGnssCallback_2_1 == nullptr) { if (sGnssCallback_2_1 != nullptr) {
ALOGE("%s: sGnssCallback v2.1 is null.", __func__); auto ret = sGnssCallback_2_1->gnssLocationCb_2_0(location);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback v2.1", __func__);
}
return; return;
} }
auto ret = sGnssCallback_2_1->gnssLocationCb_2_0(location); if (sGnssCallback_2_0 == nullptr) {
ALOGE("%s: No non-null callback", __func__);
return;
}
auto ret = sGnssCallback_2_0->gnssLocationCb_2_0(location);
if (!ret.isOk()) { if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__); ALOGE("%s: Unable to invoke callback v2.0", __func__);
} }
} }

View file

@ -29,7 +29,8 @@ using common::Utils;
namespace V2_1 { namespace V2_1 {
namespace implementation { namespace implementation {
sp<V2_1::IGnssMeasurementCallback> GnssMeasurement::sCallback = nullptr; sp<V2_1::IGnssMeasurementCallback> GnssMeasurement::sCallback_2_1 = nullptr;
sp<V2_0::IGnssMeasurementCallback> GnssMeasurement::sCallback_2_0 = nullptr;
GnssMeasurement::GnssMeasurement() : mMinIntervalMillis(1000) {} GnssMeasurement::GnssMeasurement() : mMinIntervalMillis(1000) {}
@ -48,7 +49,8 @@ Return<void> GnssMeasurement::close() {
ALOGD("close"); ALOGD("close");
std::unique_lock<std::mutex> lock(mMutex); std::unique_lock<std::mutex> lock(mMutex);
stop(); stop();
sCallback = nullptr; sCallback_2_1 = nullptr;
sCallback_2_0 = nullptr;
return Void(); return Void();
} }
@ -61,9 +63,18 @@ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallba
// Methods from V2_0::IGnssMeasurement follow. // Methods from V2_0::IGnssMeasurement follow.
Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_2_0( Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_2_0(
const sp<V2_0::IGnssMeasurementCallback>&, bool) { const sp<V2_0::IGnssMeasurementCallback>& callback, bool) {
// TODO implement ALOGD("setCallback_2_0");
return V1_0::IGnssMeasurement::GnssMeasurementStatus{}; std::unique_lock<std::mutex> lock(mMutex);
sCallback_2_0 = callback;
if (mIsActive) {
ALOGW("GnssMeasurement callback already set. Resetting the callback...");
stop();
}
start();
return V1_0::IGnssMeasurement::GnssMeasurementStatus::SUCCESS;
} }
// Methods from V2_1::IGnssMeasurement follow. // Methods from V2_1::IGnssMeasurement follow.
@ -71,7 +82,7 @@ Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallba
const sp<V2_1::IGnssMeasurementCallback>& callback, bool) { const sp<V2_1::IGnssMeasurementCallback>& callback, bool) {
ALOGD("setCallback_2_1"); ALOGD("setCallback_2_1");
std::unique_lock<std::mutex> lock(mMutex); std::unique_lock<std::mutex> lock(mMutex);
sCallback = callback; sCallback_2_1 = callback;
if (mIsActive) { if (mIsActive) {
ALOGW("GnssMeasurement callback already set. Resetting the callback..."); ALOGW("GnssMeasurement callback already set. Resetting the callback...");
@ -87,8 +98,13 @@ void GnssMeasurement::start() {
mIsActive = true; mIsActive = true;
mThread = std::thread([this]() { mThread = std::thread([this]() {
while (mIsActive == true) { while (mIsActive == true) {
auto measurement = Utils::getMockMeasurementV2_1(); if (sCallback_2_1 != nullptr) {
this->reportMeasurement(measurement); auto measurement = Utils::getMockMeasurementV2_1();
this->reportMeasurement(measurement);
} else {
auto measurement = Utils::getMockMeasurementV2_0();
this->reportMeasurement(measurement);
}
std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis)); std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis));
} }
@ -103,14 +119,27 @@ void GnssMeasurement::stop() {
} }
} }
void GnssMeasurement::reportMeasurement(const GnssDataV2_0& data) {
ALOGD("reportMeasurement()");
std::unique_lock<std::mutex> lock(mMutex);
if (sCallback_2_0 == nullptr) {
ALOGE("%s: GnssMeasurement::sCallback_2_0 is null.", __func__);
return;
}
auto ret = sCallback_2_0->gnssMeasurementCb_2_0(data);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
}
}
void GnssMeasurement::reportMeasurement(const GnssDataV2_1& data) { void GnssMeasurement::reportMeasurement(const GnssDataV2_1& data) {
ALOGD("reportMeasurement()"); ALOGD("reportMeasurement()");
std::unique_lock<std::mutex> lock(mMutex); std::unique_lock<std::mutex> lock(mMutex);
if (sCallback == nullptr) { if (sCallback_2_1 == nullptr) {
ALOGE("%s: GnssMeasurement::sCallback is null.", __func__); ALOGE("%s: GnssMeasurement::sCallback_2_1 is null.", __func__);
return; return;
} }
auto ret = sCallback->gnssMeasurementCb_2_1(data); auto ret = sCallback_2_1->gnssMeasurementCb_2_1(data);
if (!ret.isOk()) { if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__); ALOGE("%s: Unable to invoke callback", __func__);
} }

View file

@ -30,6 +30,7 @@ namespace V2_1 {
namespace implementation { namespace implementation {
using GnssDataV2_1 = V2_1::IGnssMeasurementCallback::GnssData; using GnssDataV2_1 = V2_1::IGnssMeasurementCallback::GnssData;
using GnssDataV2_0 = V2_0::IGnssMeasurementCallback::GnssData;
using ::android::sp; using ::android::sp;
using ::android::hardware::hidl_array; using ::android::hardware::hidl_array;
@ -62,9 +63,11 @@ struct GnssMeasurement : public IGnssMeasurement {
private: private:
void start(); void start();
void stop(); void stop();
void reportMeasurement(const GnssDataV2_0&);
void reportMeasurement(const GnssDataV2_1&); void reportMeasurement(const GnssDataV2_1&);
static sp<IGnssMeasurementCallback> sCallback; static sp<V2_1::IGnssMeasurementCallback> sCallback_2_1;
static sp<V2_0::IGnssMeasurementCallback> sCallback_2_0;
std::atomic<long> mMinIntervalMillis; std::atomic<long> mMinIntervalMillis;
std::atomic<bool> mIsActive; std::atomic<bool> mIsActive;
std::thread mThread; std::thread mThread;

View file

@ -0,0 +1,75 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "GnssMeasurementCorrections"
#include "GnssMeasurementCorrections.h"
#include <log/log.h>
namespace android {
namespace hardware {
namespace gnss {
namespace measurement_corrections {
namespace V1_0 {
namespace implementation {
// Methods from V1_0::IMeasurementCorrections follow.
Return<bool> GnssMeasurementCorrections::setCorrections(const MeasurementCorrections& corrections) {
ALOGD("setCorrections");
ALOGD("corrections = lat: %f, lng: %f, alt: %f, hUnc: %f, vUnc: %f, toa: %llu, "
"satCorrections.size: %d",
corrections.latitudeDegrees, corrections.longitudeDegrees, corrections.altitudeMeters,
corrections.horizontalPositionUncertaintyMeters,
corrections.verticalPositionUncertaintyMeters,
static_cast<unsigned long long>(corrections.toaGpsNanosecondsOfWeek),
static_cast<int>(corrections.satCorrections.size()));
for (auto singleSatCorrection : corrections.satCorrections) {
ALOGD("singleSatCorrection = flags: %d, constellation: %d, svid: %d, cfHz: %f, probLos: %f,"
" epl: %f, eplUnc: %f",
static_cast<int>(singleSatCorrection.singleSatCorrectionFlags),
static_cast<int>(singleSatCorrection.constellation),
static_cast<int>(singleSatCorrection.svid), singleSatCorrection.carrierFrequencyHz,
singleSatCorrection.probSatIsLos, singleSatCorrection.excessPathLengthMeters,
singleSatCorrection.excessPathLengthUncertaintyMeters);
ALOGD("reflecting plane = lat: %f, lng: %f, alt: %f, azm: %f",
singleSatCorrection.reflectingPlane.latitudeDegrees,
singleSatCorrection.reflectingPlane.longitudeDegrees,
singleSatCorrection.reflectingPlane.altitudeMeters,
singleSatCorrection.reflectingPlane.azimuthDegrees);
}
return true;
}
Return<bool> GnssMeasurementCorrections::setCallback(
const sp<V1_0::IMeasurementCorrectionsCallback>& callback) {
using Capabilities = V1_0::IMeasurementCorrectionsCallback::Capabilities;
auto ret =
callback->setCapabilitiesCb(Capabilities::LOS_SATS | Capabilities::EXCESS_PATH_LENGTH |
Capabilities::REFLECTING_PLANE);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
return false;
}
return true;
}
} // namespace implementation
} // namespace V1_0
} // namespace measurement_corrections
} // namespace gnss
} // namespace hardware
} // namespace android

View file

@ -0,0 +1,49 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrections.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
namespace android {
namespace hardware {
namespace gnss {
namespace measurement_corrections {
namespace V1_0 {
namespace implementation {
using ::android::sp;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_memory;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
struct GnssMeasurementCorrections : public IMeasurementCorrections {
// Methods from V1_0::IMeasurementCorrections follow.
Return<bool> setCorrections(const MeasurementCorrections& corrections) override;
Return<bool> setCallback(const sp<V1_0::IMeasurementCorrectionsCallback>& callback) override;
};
} // namespace implementation
} // namespace V1_0
} // namespace measurement_corrections
} // namespace gnss
} // namespace hardware
} // namespace android