mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 16:50:18 +00:00
Add VTS tests for measurementInterval, stopSvStatus, and stopNmea
Bug: 206670536 Test: atest VtsHalGnssTargetTest Change-Id: Id597c772fbe63789cb394b2aa14faeb755196f64
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
#include "Gnss.h"
|
||||
#include <inttypes.h>
|
||||
#include <log/log.h>
|
||||
#include <utils/Timers.h>
|
||||
#include "AGnss.h"
|
||||
#include "AGnssRil.h"
|
||||
#include "DeviceFileReader.h"
|
||||
@@ -28,7 +29,6 @@
|
||||
#include "GnssConfiguration.h"
|
||||
#include "GnssDebug.h"
|
||||
#include "GnssGeofence.h"
|
||||
#include "GnssMeasurementInterface.h"
|
||||
#include "GnssNavigationMessageInterface.h"
|
||||
#include "GnssPsds.h"
|
||||
#include "GnssVisibilityControl.h"
|
||||
@@ -95,6 +95,9 @@ ScopedAStatus Gnss::start() {
|
||||
}
|
||||
|
||||
mIsActive = true;
|
||||
mThreadBlocker.reset();
|
||||
// notify measurement engine to update measurement interval
|
||||
mGnssMeasurementInterface->setLocationEnabled(true);
|
||||
this->reportGnssStatusValue(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
|
||||
mThread = std::thread([this]() {
|
||||
this->reportSvStatus();
|
||||
@@ -102,8 +105,12 @@ ScopedAStatus Gnss::start() {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(TTFF_MILLIS));
|
||||
mFirstFixReceived = true;
|
||||
}
|
||||
while (mIsActive == true) {
|
||||
do {
|
||||
if (!mIsActive) {
|
||||
break;
|
||||
}
|
||||
this->reportSvStatus();
|
||||
this->reportNmea();
|
||||
|
||||
auto currentLocation = getLocationFromHW();
|
||||
mGnssPowerIndication->notePowerConsumption();
|
||||
@@ -113,12 +120,29 @@ ScopedAStatus Gnss::start() {
|
||||
const auto location = Utils::getMockLocation();
|
||||
this->reportLocation(location);
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
|
||||
}
|
||||
} while (mIsActive && mThreadBlocker.wait_for(std::chrono::milliseconds(mMinIntervalMs)));
|
||||
});
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ScopedAStatus Gnss::stop() {
|
||||
ALOGD("stop");
|
||||
mIsActive = false;
|
||||
mGnssMeasurementInterface->setLocationEnabled(false);
|
||||
this->reportGnssStatusValue(IGnssCallback::GnssStatusValue::SESSION_END);
|
||||
mThreadBlocker.notify();
|
||||
if (mThread.joinable()) {
|
||||
mThread.join();
|
||||
}
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ScopedAStatus Gnss::close() {
|
||||
ALOGD("close");
|
||||
sGnssCallback = nullptr;
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
void Gnss::reportLocation(const GnssLocation& location) const {
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
if (sGnssCallback == nullptr) {
|
||||
@@ -153,7 +177,6 @@ void Gnss::reportSvStatus(const std::vector<GnssSvInfo>& svInfoList) const {
|
||||
|
||||
std::vector<GnssSvInfo> Gnss::filterBlocklistedSatellites(
|
||||
std::vector<GnssSvInfo> gnssSvInfoList) const {
|
||||
ALOGD("filterBlocklistedSatellites");
|
||||
for (uint32_t i = 0; i < gnssSvInfoList.size(); i++) {
|
||||
if (mGnssConfiguration->isBlocklisted(gnssSvInfoList[i])) {
|
||||
gnssSvInfoList[i].svFlag &= ~(uint32_t)IGnssCallback::GnssSvFlags::USED_IN_FIX;
|
||||
@@ -174,14 +197,19 @@ void Gnss::reportGnssStatusValue(const IGnssCallback::GnssStatusValue gnssStatus
|
||||
}
|
||||
}
|
||||
|
||||
ScopedAStatus Gnss::stop() {
|
||||
ALOGD("stop");
|
||||
mIsActive = false;
|
||||
this->reportGnssStatusValue(IGnssCallback::GnssStatusValue::SESSION_END);
|
||||
if (mThread.joinable()) {
|
||||
mThread.join();
|
||||
void Gnss::reportNmea() const {
|
||||
if (mIsNmeaActive) {
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
if (sGnssCallback == nullptr) {
|
||||
ALOGE("%s: sGnssCallback is null.", __func__);
|
||||
return;
|
||||
}
|
||||
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
|
||||
auto status = sGnssCallback->gnssNmeaCb(now, "$TEST,0,1,2,3,4,5");
|
||||
if (!status.isOk()) {
|
||||
ALOGE("%s: Unable to invoke callback", __func__);
|
||||
}
|
||||
}
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ScopedAStatus Gnss::startSvStatus() {
|
||||
@@ -197,16 +225,12 @@ ScopedAStatus Gnss::stopSvStatus() {
|
||||
}
|
||||
ScopedAStatus Gnss::startNmea() {
|
||||
ALOGD("startNmea");
|
||||
mIsNmeaActive = true;
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
ScopedAStatus Gnss::stopNmea() {
|
||||
ALOGD("stopNmea");
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ScopedAStatus Gnss::close() {
|
||||
ALOGD("close");
|
||||
sGnssCallback = nullptr;
|
||||
mIsNmeaActive = false;
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
@@ -249,7 +273,8 @@ ScopedAStatus Gnss::deleteAidingData(GnssAidingData aidingDataFlags) {
|
||||
ScopedAStatus Gnss::setPositionMode(const PositionModeOptions& options) {
|
||||
ALOGD("setPositionMode. minIntervalMs:%d, lowPowerMode:%d", options.minIntervalMs,
|
||||
(int)options.lowPowerMode);
|
||||
mMinIntervalMs = options.minIntervalMs;
|
||||
mMinIntervalMs = std::max(1000, options.minIntervalMs);
|
||||
mGnssMeasurementInterface->setLocationInterval(mMinIntervalMs);
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
@@ -283,8 +308,10 @@ ScopedAStatus Gnss::getExtensionGnssPowerIndication(
|
||||
ScopedAStatus Gnss::getExtensionGnssMeasurement(
|
||||
std::shared_ptr<IGnssMeasurementInterface>* iGnssMeasurement) {
|
||||
ALOGD("getExtensionGnssMeasurement");
|
||||
|
||||
*iGnssMeasurement = SharedRefBase::make<GnssMeasurementInterface>();
|
||||
if (mGnssMeasurementInterface == nullptr) {
|
||||
mGnssMeasurementInterface = SharedRefBase::make<GnssMeasurementInterface>();
|
||||
}
|
||||
*iGnssMeasurement = mGnssMeasurementInterface;
|
||||
return ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,9 @@
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include "GnssConfiguration.h"
|
||||
#include "GnssMeasurementInterface.h"
|
||||
#include "GnssPowerIndication.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace aidl::android::hardware::gnss {
|
||||
|
||||
@@ -84,6 +86,7 @@ class Gnss : public BnGnss {
|
||||
|
||||
std::shared_ptr<GnssConfiguration> mGnssConfiguration;
|
||||
std::shared_ptr<GnssPowerIndication> mGnssPowerIndication;
|
||||
std::shared_ptr<GnssMeasurementInterface> mGnssMeasurementInterface;
|
||||
|
||||
private:
|
||||
void reportLocation(const GnssLocation&) const;
|
||||
@@ -93,14 +96,17 @@ class Gnss : public BnGnss {
|
||||
std::vector<IGnssCallback::GnssSvInfo> gnssSvInfoList) const;
|
||||
void reportGnssStatusValue(const IGnssCallback::GnssStatusValue gnssStatusValue) const;
|
||||
std::unique_ptr<GnssLocation> getLocationFromHW();
|
||||
void reportNmea() const;
|
||||
|
||||
static std::shared_ptr<IGnssCallback> sGnssCallback;
|
||||
|
||||
std::atomic<long> mMinIntervalMs;
|
||||
std::atomic<bool> mIsActive;
|
||||
std::atomic<bool> mIsSvStatusActive;
|
||||
std::atomic<bool> mIsNmeaActive;
|
||||
std::atomic<bool> mFirstFixReceived;
|
||||
std::thread mThread;
|
||||
::android::hardware::gnss::common::ThreadBlocker mThreadBlocker;
|
||||
|
||||
mutable std::mutex mMutex;
|
||||
};
|
||||
|
||||
@@ -33,10 +33,11 @@ using DeviceFileReader = ::android::hardware::gnss::common::DeviceFileReader;
|
||||
|
||||
std::shared_ptr<IGnssMeasurementCallback> GnssMeasurementInterface::sCallback = nullptr;
|
||||
|
||||
GnssMeasurementInterface::GnssMeasurementInterface() : mMinIntervalMillis(1000) {}
|
||||
GnssMeasurementInterface::GnssMeasurementInterface()
|
||||
: mIntervalMs(1000), mLocationIntervalMs(1000), mFutures(std::vector<std::future<void>>()) {}
|
||||
|
||||
GnssMeasurementInterface::~GnssMeasurementInterface() {
|
||||
stop();
|
||||
waitForStoppingThreads();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus GnssMeasurementInterface::setCallback(
|
||||
@@ -44,8 +45,10 @@ ndk::ScopedAStatus GnssMeasurementInterface::setCallback(
|
||||
const bool enableCorrVecOutputs) {
|
||||
ALOGD("setCallback: enableFullTracking: %d enableCorrVecOutputs: %d", (int)enableFullTracking,
|
||||
(int)enableCorrVecOutputs);
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
sCallback = callback;
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
sCallback = callback;
|
||||
}
|
||||
|
||||
if (mIsActive) {
|
||||
ALOGW("GnssMeasurement callback already set. Resetting the callback...");
|
||||
@@ -60,14 +63,16 @@ ndk::ScopedAStatus GnssMeasurementInterface::setCallbackWithOptions(
|
||||
const std::shared_ptr<IGnssMeasurementCallback>& callback, const Options& options) {
|
||||
ALOGD("setCallbackWithOptions: fullTracking:%d, corrVec:%d, intervalMs:%d",
|
||||
(int)options.enableFullTracking, (int)options.enableCorrVecOutputs, options.intervalMs);
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
sCallback = callback;
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
sCallback = callback;
|
||||
}
|
||||
|
||||
if (mIsActive) {
|
||||
ALOGW("GnssMeasurement callback already set. Resetting the callback...");
|
||||
stop();
|
||||
}
|
||||
mMinIntervalMillis = options.intervalMs;
|
||||
mIntervalMs = std::max(options.intervalMs, 1000);
|
||||
start(options.enableCorrVecOutputs);
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
@@ -75,18 +80,35 @@ ndk::ScopedAStatus GnssMeasurementInterface::setCallbackWithOptions(
|
||||
|
||||
ndk::ScopedAStatus GnssMeasurementInterface::close() {
|
||||
ALOGD("close");
|
||||
stop();
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
sCallback = nullptr;
|
||||
mMinIntervalMillis = 1000;
|
||||
if (mIsActive) {
|
||||
stop();
|
||||
}
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
sCallback = nullptr;
|
||||
}
|
||||
mIntervalMs = 1000;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
void GnssMeasurementInterface::start(const bool enableCorrVecOutputs) {
|
||||
ALOGD("start");
|
||||
|
||||
if (mIsActive) {
|
||||
ALOGD("restarting since measurement has started");
|
||||
stop();
|
||||
}
|
||||
// Wait for stopping previous thread.
|
||||
waitForStoppingThreads();
|
||||
|
||||
mIsActive = true;
|
||||
mThreadBlocker.reset();
|
||||
mThread = std::thread([this, enableCorrVecOutputs]() {
|
||||
while (mIsActive == true) {
|
||||
int intervalMs;
|
||||
do {
|
||||
if (!mIsActive) {
|
||||
break;
|
||||
}
|
||||
std::string rawMeasurementStr = "";
|
||||
if (ReplayUtils::hasGnssDeviceFile() &&
|
||||
ReplayUtils::isGnssRawMeasurement(
|
||||
@@ -103,15 +125,19 @@ void GnssMeasurementInterface::start(const bool enableCorrVecOutputs) {
|
||||
auto measurement = Utils::getMockMeasurement(enableCorrVecOutputs);
|
||||
this->reportMeasurement(measurement);
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis));
|
||||
}
|
||||
intervalMs =
|
||||
(mLocationEnabled) ? std::min(mLocationIntervalMs, mIntervalMs) : mIntervalMs;
|
||||
} while (mIsActive && mThreadBlocker.wait_for(std::chrono::milliseconds(intervalMs)));
|
||||
});
|
||||
mThread.detach();
|
||||
}
|
||||
|
||||
void GnssMeasurementInterface::stop() {
|
||||
ALOGD("stop");
|
||||
mIsActive = false;
|
||||
mThreadBlocker.notify();
|
||||
if (mThread.joinable()) {
|
||||
mFutures.push_back(std::async(std::launch::async, [this] { mThread.join(); }));
|
||||
}
|
||||
}
|
||||
|
||||
void GnssMeasurementInterface::reportMeasurement(const GnssData& data) {
|
||||
@@ -128,4 +154,21 @@ void GnssMeasurementInterface::reportMeasurement(const GnssData& data) {
|
||||
callbackCopy->gnssMeasurementCb(data);
|
||||
}
|
||||
|
||||
void GnssMeasurementInterface::setLocationInterval(const int intervalMs) {
|
||||
mLocationIntervalMs = intervalMs;
|
||||
}
|
||||
|
||||
void GnssMeasurementInterface::setLocationEnabled(const bool enabled) {
|
||||
mLocationEnabled = enabled;
|
||||
}
|
||||
|
||||
void GnssMeasurementInterface::waitForStoppingThreads() {
|
||||
for (auto& future : mFutures) {
|
||||
ALOGD("Stopping previous thread.");
|
||||
future.wait();
|
||||
ALOGD("Done stopping thread.");
|
||||
}
|
||||
mFutures.clear();
|
||||
}
|
||||
|
||||
} // namespace aidl::android::hardware::gnss
|
||||
|
||||
@@ -19,8 +19,10 @@
|
||||
#include <aidl/android/hardware/gnss/BnGnssMeasurementCallback.h>
|
||||
#include <aidl/android/hardware/gnss/BnGnssMeasurementInterface.h>
|
||||
#include <atomic>
|
||||
#include <future>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include "Utils.h"
|
||||
|
||||
namespace aidl::android::hardware::gnss {
|
||||
|
||||
@@ -35,15 +37,22 @@ struct GnssMeasurementInterface : public BnGnssMeasurementInterface {
|
||||
ndk::ScopedAStatus setCallbackWithOptions(
|
||||
const std::shared_ptr<IGnssMeasurementCallback>& callback,
|
||||
const Options& options) override;
|
||||
void setLocationInterval(const int intervalMs);
|
||||
void setLocationEnabled(const bool enabled);
|
||||
|
||||
private:
|
||||
void start(const bool enableCorrVecOutputs);
|
||||
void stop();
|
||||
void reportMeasurement(const GnssData&);
|
||||
void waitForStoppingThreads();
|
||||
|
||||
std::atomic<long> mMinIntervalMillis;
|
||||
std::atomic<long> mIntervalMs;
|
||||
std::atomic<long> mLocationIntervalMs;
|
||||
std::atomic<bool> mIsActive;
|
||||
std::atomic<bool> mLocationEnabled;
|
||||
std::thread mThread;
|
||||
std::vector<std::future<void>> mFutures;
|
||||
::android::hardware::gnss::common::ThreadBlocker mThreadBlocker;
|
||||
|
||||
// Guarded by mMutex
|
||||
static std::shared_ptr<IGnssMeasurementCallback> sCallback;
|
||||
|
||||
@@ -32,7 +32,7 @@ std::shared_ptr<IGnssNavigationMessageCallback> GnssNavigationMessageInterface::
|
||||
GnssNavigationMessageInterface::GnssNavigationMessageInterface() : mMinIntervalMillis(1000) {}
|
||||
|
||||
GnssNavigationMessageInterface::~GnssNavigationMessageInterface() {
|
||||
stop();
|
||||
waitForStoppingThreads();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus GnssNavigationMessageInterface::setCallback(
|
||||
@@ -46,7 +46,9 @@ ndk::ScopedAStatus GnssNavigationMessageInterface::setCallback(
|
||||
|
||||
ndk::ScopedAStatus GnssNavigationMessageInterface::close() {
|
||||
ALOGD("close");
|
||||
stop();
|
||||
if (mIsActive) {
|
||||
stop();
|
||||
}
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
sCallback = nullptr;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
@@ -54,9 +56,20 @@ ndk::ScopedAStatus GnssNavigationMessageInterface::close() {
|
||||
|
||||
void GnssNavigationMessageInterface::start() {
|
||||
ALOGD("start");
|
||||
|
||||
if (mIsActive) {
|
||||
ALOGD("restarting since nav msg has started");
|
||||
stop();
|
||||
}
|
||||
// Wait for stopping previous thread.
|
||||
waitForStoppingThreads();
|
||||
|
||||
mIsActive = true;
|
||||
mThread = std::thread([this]() {
|
||||
while (mIsActive == true) {
|
||||
do {
|
||||
if (!mIsActive) {
|
||||
break;
|
||||
}
|
||||
GnssNavigationMessage message = {
|
||||
.svid = 19,
|
||||
.type = GnssNavigationMessageType::GPS_L1CA,
|
||||
@@ -66,15 +79,18 @@ void GnssNavigationMessageInterface::start() {
|
||||
.data = std::vector<uint8_t>(40, 0xF9),
|
||||
};
|
||||
this->reportMessage(message);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis));
|
||||
}
|
||||
} while (mIsActive &&
|
||||
mThreadBlocker.wait_for(std::chrono::milliseconds(mMinIntervalMillis)));
|
||||
});
|
||||
mThread.detach();
|
||||
}
|
||||
|
||||
void GnssNavigationMessageInterface::stop() {
|
||||
ALOGD("stop");
|
||||
mIsActive = false;
|
||||
mThreadBlocker.notify();
|
||||
if (mThread.joinable()) {
|
||||
mFutures.push_back(std::async(std::launch::async, [this] { mThread.join(); }));
|
||||
}
|
||||
}
|
||||
|
||||
void GnssNavigationMessageInterface::reportMessage(const GnssNavigationMessage& message) {
|
||||
@@ -91,4 +107,13 @@ void GnssNavigationMessageInterface::reportMessage(const GnssNavigationMessage&
|
||||
callbackCopy->gnssNavigationMessageCb(message);
|
||||
}
|
||||
|
||||
void GnssNavigationMessageInterface::waitForStoppingThreads() {
|
||||
for (auto& future : mFutures) {
|
||||
ALOGD("Stopping previous thread.");
|
||||
future.wait();
|
||||
ALOGD("Done stopping thread.");
|
||||
}
|
||||
mFutures.clear();
|
||||
}
|
||||
|
||||
} // namespace aidl::android::hardware::gnss
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
|
||||
#include <aidl/android/hardware/gnss/BnGnssNavigationMessageInterface.h>
|
||||
#include <atomic>
|
||||
#include <future>
|
||||
#include <thread>
|
||||
#include "Utils.h"
|
||||
|
||||
namespace aidl::android::hardware::gnss {
|
||||
|
||||
@@ -34,10 +36,13 @@ struct GnssNavigationMessageInterface : public BnGnssNavigationMessageInterface
|
||||
void start();
|
||||
void stop();
|
||||
void reportMessage(const IGnssNavigationMessageCallback::GnssNavigationMessage& message);
|
||||
void waitForStoppingThreads();
|
||||
|
||||
std::atomic<long> mMinIntervalMillis;
|
||||
std::atomic<bool> mIsActive;
|
||||
std::thread mThread;
|
||||
std::vector<std::future<void>> mFutures;
|
||||
::android::hardware::gnss::common::ThreadBlocker mThreadBlocker;
|
||||
|
||||
// Guarded by mMutex
|
||||
static std::shared_ptr<IGnssNavigationMessageCallback> sCallback;
|
||||
|
||||
@@ -31,7 +31,7 @@ Status GnssCallbackAidl::gnssSetCapabilitiesCb(const int capabilities) {
|
||||
}
|
||||
|
||||
Status GnssCallbackAidl::gnssStatusCb(const GnssStatusValue /* status */) {
|
||||
ALOGI("gnssSvStatusCb");
|
||||
ALOGI("gnssStatusCb");
|
||||
return Status::ok();
|
||||
}
|
||||
|
||||
@@ -47,7 +47,8 @@ Status GnssCallbackAidl::gnssLocationCb(const GnssLocation& location) {
|
||||
return Status::ok();
|
||||
}
|
||||
|
||||
Status GnssCallbackAidl::gnssNmeaCb(const int64_t /* timestamp */, const std::string& /* nmea */) {
|
||||
Status GnssCallbackAidl::gnssNmeaCb(const int64_t timestamp, const std::string& nmea) {
|
||||
nmea_cbq_.store(std::make_pair(timestamp, nmea));
|
||||
return Status::ok();
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <android/hardware/gnss/BnGnssCallback.h>
|
||||
#include <utility>
|
||||
#include "GnssCallbackEventQueue.h"
|
||||
|
||||
/* Callback class for data & Event. */
|
||||
@@ -26,7 +27,8 @@ class GnssCallbackAidl : public android::hardware::gnss::BnGnssCallback {
|
||||
: capabilities_cbq_("capabilities"),
|
||||
info_cbq_("system_info"),
|
||||
location_cbq_("location"),
|
||||
sv_info_list_cbq_("sv_info"){};
|
||||
sv_info_list_cbq_("sv_info"),
|
||||
nmea_cbq_("nmea"){};
|
||||
~GnssCallbackAidl(){};
|
||||
|
||||
android::binder::Status gnssSetCapabilitiesCb(const int capabilities) override;
|
||||
@@ -55,4 +57,6 @@ class GnssCallbackAidl : public android::hardware::gnss::BnGnssCallback {
|
||||
android::hardware::gnss::common::GnssCallbackEventQueue<
|
||||
std::vector<android::hardware::gnss::IGnssCallback::GnssSvInfo>>
|
||||
sv_info_list_cbq_;
|
||||
android::hardware::gnss::common::GnssCallbackEventQueue<std::pair<int64_t, std::string>>
|
||||
nmea_cbq_;
|
||||
};
|
||||
@@ -24,12 +24,10 @@ using android::hardware::gnss::GnssData;
|
||||
|
||||
android::binder::Status GnssMeasurementCallbackAidl::gnssMeasurementCb(const GnssData& gnssData) {
|
||||
ALOGI("gnssMeasurementCb");
|
||||
ALOGI("elapsedRealtime: flags = %d, timestampNs: %" PRId64 ", timeUncertaintyNs=%lf",
|
||||
ALOGV("elapsedRealtime: flags = 0x%X, timestampNs: %" PRId64 ", timeUncertaintyNs=%lf",
|
||||
gnssData.elapsedRealtime.flags, gnssData.elapsedRealtime.timestampNs,
|
||||
gnssData.elapsedRealtime.timeUncertaintyNs);
|
||||
for (const auto& measurement : gnssData.measurements) {
|
||||
ALOGI("measurement.receivedSvTimeInNs=%" PRId64, measurement.receivedSvTimeInNs);
|
||||
}
|
||||
|
||||
gnss_data_cbq_.store(gnssData);
|
||||
return android::binder::Status::ok();
|
||||
}
|
||||
|
||||
@@ -18,15 +18,50 @@
|
||||
|
||||
#include "gnss_hal_test.h"
|
||||
#include <hidl/ServiceManagement.h>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include "Utils.h"
|
||||
|
||||
using android::hardware::gnss::GnssClock;
|
||||
using android::hardware::gnss::GnssConstellationType;
|
||||
using android::hardware::gnss::GnssData;
|
||||
using android::hardware::gnss::GnssLocation;
|
||||
using android::hardware::gnss::GnssMeasurement;
|
||||
using android::hardware::gnss::IGnss;
|
||||
using android::hardware::gnss::IGnssCallback;
|
||||
using android::hardware::gnss::IGnssMeasurementInterface;
|
||||
using android::hardware::gnss::common::Utils;
|
||||
using GnssConstellationTypeV2_0 = android::hardware::gnss::V2_0::GnssConstellationType;
|
||||
|
||||
namespace {
|
||||
// The difference between the mean of the received intervals and the requested interval should not
|
||||
// be larger mInterval * ALLOWED_MEAN_ERROR_RATIO
|
||||
constexpr double ALLOWED_MEAN_ERROR_RATIO = 0.25;
|
||||
|
||||
// The standard deviation computed for the deltas should not be bigger
|
||||
// than mInterval * ALLOWED_STDEV_ERROR_RATIO or MIN_STDEV_MS, whichever is higher.
|
||||
constexpr double ALLOWED_STDEV_ERROR_RATIO = 0.50;
|
||||
constexpr double MIN_STDEV_MS = 1000;
|
||||
|
||||
double computeMean(std::vector<int>& deltas) {
|
||||
long accumulator = 0;
|
||||
for (auto& d : deltas) {
|
||||
accumulator += d;
|
||||
}
|
||||
return accumulator / deltas.size();
|
||||
}
|
||||
|
||||
double computeStdev(double mean, std::vector<int>& deltas) {
|
||||
double accumulator = 0;
|
||||
for (auto& d : deltas) {
|
||||
double diff = d - mean;
|
||||
accumulator += diff * diff;
|
||||
}
|
||||
return std::sqrt(accumulator / (deltas.size() - 1));
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
void GnssHalTest::SetUp() {
|
||||
// Get AIDL handle
|
||||
aidl_gnss_hal_ = android::waitForDeclaredService<IGnssAidl>(String16(GetParam().c_str()));
|
||||
@@ -97,20 +132,26 @@ void GnssHalTest::SetPositionMode(const int min_interval_msec, const bool low_po
|
||||
ASSERT_TRUE(status.isOk());
|
||||
}
|
||||
|
||||
bool GnssHalTest::StartAndCheckFirstLocation(const int min_interval_msec,
|
||||
const bool low_power_mode) {
|
||||
bool GnssHalTest::StartAndCheckFirstLocation(const int min_interval_msec, const bool low_power_mode,
|
||||
const bool start_sv_status, const bool start_nmea) {
|
||||
if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
|
||||
// Invoke the super method.
|
||||
return GnssHalTestTemplate<IGnss_V2_1>::StartAndCheckFirstLocation(min_interval_msec,
|
||||
low_power_mode);
|
||||
}
|
||||
|
||||
SetPositionMode(min_interval_msec, low_power_mode);
|
||||
|
||||
auto status = aidl_gnss_hal_->start();
|
||||
EXPECT_TRUE(status.isOk());
|
||||
|
||||
status = aidl_gnss_hal_->startSvStatus();
|
||||
EXPECT_TRUE(status.isOk());
|
||||
if (start_sv_status) {
|
||||
status = aidl_gnss_hal_->startSvStatus();
|
||||
EXPECT_TRUE(status.isOk());
|
||||
}
|
||||
if (start_nmea) {
|
||||
status = aidl_gnss_hal_->startNmea();
|
||||
EXPECT_TRUE(status.isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* GnssLocationProvider support of AGPS SUPL & XtraDownloader is not available in VTS,
|
||||
@@ -131,6 +172,12 @@ bool GnssHalTest::StartAndCheckFirstLocation(const int min_interval_msec,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GnssHalTest::StartAndCheckFirstLocation(const int min_interval_msec,
|
||||
const bool low_power_mode) {
|
||||
return StartAndCheckFirstLocation(min_interval_msec, low_power_mode,
|
||||
/* start_sv_status= */ true, /* start_nmea= */ true);
|
||||
}
|
||||
|
||||
void GnssHalTest::StopAndClearLocations() {
|
||||
ALOGD("StopAndClearLocations");
|
||||
if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
|
||||
@@ -139,6 +186,8 @@ void GnssHalTest::StopAndClearLocations() {
|
||||
}
|
||||
auto status = aidl_gnss_hal_->stopSvStatus();
|
||||
EXPECT_TRUE(status.isOk());
|
||||
status = aidl_gnss_hal_->stopNmea();
|
||||
EXPECT_TRUE(status.isOk());
|
||||
|
||||
status = aidl_gnss_hal_->stop();
|
||||
EXPECT_TRUE(status.isOk());
|
||||
@@ -153,7 +202,8 @@ void GnssHalTest::StopAndClearLocations() {
|
||||
aidl_gnss_cb_->location_cbq_.reset();
|
||||
}
|
||||
|
||||
void GnssHalTest::StartAndCheckLocations(int count) {
|
||||
void GnssHalTest::StartAndCheckLocations(const int count, const bool start_sv_status,
|
||||
const bool start_nmea) {
|
||||
if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
|
||||
// Invoke the super method.
|
||||
return GnssHalTestTemplate<IGnss_V2_1>::StartAndCheckLocations(count);
|
||||
@@ -162,7 +212,8 @@ void GnssHalTest::StartAndCheckLocations(int count) {
|
||||
const int kLocationTimeoutSubsequentSec = 2;
|
||||
const bool kLowPowerMode = false;
|
||||
|
||||
EXPECT_TRUE(StartAndCheckFirstLocation(kMinIntervalMsec, kLowPowerMode));
|
||||
EXPECT_TRUE(StartAndCheckFirstLocation(kMinIntervalMsec, kLowPowerMode, start_sv_status,
|
||||
start_nmea));
|
||||
|
||||
for (int i = 1; i < count; i++) {
|
||||
EXPECT_TRUE(aidl_gnss_cb_->location_cbq_.retrieve(aidl_gnss_cb_->last_location_,
|
||||
@@ -177,6 +228,10 @@ void GnssHalTest::StartAndCheckLocations(int count) {
|
||||
}
|
||||
}
|
||||
|
||||
void GnssHalTest::StartAndCheckLocations(const int count) {
|
||||
StartAndCheckLocations(count, /* start_sv_status= */ true, /* start_nmea= */ true);
|
||||
}
|
||||
|
||||
std::list<std::vector<IGnssCallback::GnssSvInfo>> GnssHalTest::convertToAidl(
|
||||
const std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>>& sv_info_list) {
|
||||
std::list<std::vector<IGnssCallback::GnssSvInfo>> aidl_sv_info_list;
|
||||
@@ -313,3 +368,109 @@ GnssConstellationType GnssHalTest::startLocationAndGetNonGpsConstellation(
|
||||
|
||||
return constellation_to_blocklist;
|
||||
}
|
||||
|
||||
void GnssHalTest::checkGnssMeasurementClockFields(const GnssData& measurement) {
|
||||
Utils::checkElapsedRealtime(measurement.elapsedRealtime);
|
||||
ASSERT_TRUE(measurement.clock.gnssClockFlags >= 0 &&
|
||||
measurement.clock.gnssClockFlags <=
|
||||
(GnssClock::HAS_LEAP_SECOND | GnssClock::HAS_TIME_UNCERTAINTY |
|
||||
GnssClock::HAS_FULL_BIAS | GnssClock::HAS_BIAS |
|
||||
GnssClock::HAS_BIAS_UNCERTAINTY | GnssClock::HAS_DRIFT |
|
||||
GnssClock::HAS_DRIFT_UNCERTAINTY));
|
||||
}
|
||||
|
||||
void GnssHalTest::checkGnssMeasurementFlags(const GnssMeasurement& measurement) {
|
||||
ASSERT_TRUE(measurement.flags >= 0 &&
|
||||
measurement.flags <=
|
||||
(GnssMeasurement::HAS_SNR | GnssMeasurement::HAS_CARRIER_FREQUENCY |
|
||||
GnssMeasurement::HAS_CARRIER_CYCLES | GnssMeasurement::HAS_CARRIER_PHASE |
|
||||
GnssMeasurement::HAS_CARRIER_PHASE_UNCERTAINTY |
|
||||
GnssMeasurement::HAS_AUTOMATIC_GAIN_CONTROL |
|
||||
GnssMeasurement::HAS_FULL_ISB | GnssMeasurement::HAS_FULL_ISB_UNCERTAINTY |
|
||||
GnssMeasurement::HAS_SATELLITE_ISB |
|
||||
GnssMeasurement::HAS_SATELLITE_ISB_UNCERTAINTY |
|
||||
GnssMeasurement::HAS_SATELLITE_PVT |
|
||||
GnssMeasurement::HAS_CORRELATION_VECTOR));
|
||||
}
|
||||
|
||||
void GnssHalTest::checkGnssMeasurementFields(const GnssMeasurement& measurement,
|
||||
const GnssData& data) {
|
||||
checkGnssMeasurementFlags(measurement);
|
||||
// Verify CodeType is valid.
|
||||
ASSERT_NE(measurement.signalType.codeType, "");
|
||||
// Verify basebandCn0DbHz is valid.
|
||||
ASSERT_TRUE(measurement.basebandCN0DbHz > 0.0 && measurement.basebandCN0DbHz <= 65.0);
|
||||
|
||||
if (((measurement.flags & GnssMeasurement::HAS_FULL_ISB) > 0) &&
|
||||
((measurement.flags & GnssMeasurement::HAS_FULL_ISB_UNCERTAINTY) > 0) &&
|
||||
((measurement.flags & GnssMeasurement::HAS_SATELLITE_ISB) > 0) &&
|
||||
((measurement.flags & GnssMeasurement::HAS_SATELLITE_ISB_UNCERTAINTY) > 0)) {
|
||||
GnssConstellationType referenceConstellation =
|
||||
data.clock.referenceSignalTypeForIsb.constellation;
|
||||
double carrierFrequencyHz = data.clock.referenceSignalTypeForIsb.carrierFrequencyHz;
|
||||
std::string codeType = data.clock.referenceSignalTypeForIsb.codeType;
|
||||
|
||||
ASSERT_TRUE(referenceConstellation >= GnssConstellationType::UNKNOWN &&
|
||||
referenceConstellation <= GnssConstellationType::IRNSS);
|
||||
ASSERT_TRUE(carrierFrequencyHz > 0);
|
||||
ASSERT_NE(codeType, "");
|
||||
|
||||
ASSERT_TRUE(std::abs(measurement.fullInterSignalBiasNs) < 1.0e6);
|
||||
ASSERT_TRUE(measurement.fullInterSignalBiasUncertaintyNs >= 0);
|
||||
ASSERT_TRUE(std::abs(measurement.satelliteInterSignalBiasNs) < 1.0e6);
|
||||
ASSERT_TRUE(measurement.satelliteInterSignalBiasUncertaintyNs >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
void GnssHalTest::startMeasurementWithInterval(
|
||||
int intervalMs, const sp<IGnssMeasurementInterface>& iGnssMeasurement,
|
||||
sp<GnssMeasurementCallbackAidl>& callback) {
|
||||
ALOGD("Start requesting measurement at interval of %d millis.", intervalMs);
|
||||
IGnssMeasurementInterface::Options options;
|
||||
options.intervalMs = intervalMs;
|
||||
auto status = iGnssMeasurement->setCallbackWithOptions(callback, options);
|
||||
ASSERT_TRUE(status.isOk());
|
||||
}
|
||||
|
||||
void GnssHalTest::collectMeasurementIntervals(const sp<GnssMeasurementCallbackAidl>& callback,
|
||||
const int numMeasurementEvents,
|
||||
const int timeoutSeconds,
|
||||
std::vector<int>& deltasMs) {
|
||||
int64_t lastElapsedRealtimeMillis = 0;
|
||||
for (int i = 0; i < numMeasurementEvents; i++) {
|
||||
GnssData lastGnssData;
|
||||
ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastGnssData, timeoutSeconds));
|
||||
EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), i + 1);
|
||||
ASSERT_TRUE(lastGnssData.measurements.size() > 0);
|
||||
|
||||
// Validity check GnssData fields
|
||||
checkGnssMeasurementClockFields(lastGnssData);
|
||||
for (const auto& measurement : lastGnssData.measurements) {
|
||||
checkGnssMeasurementFields(measurement, lastGnssData);
|
||||
}
|
||||
|
||||
long currentElapsedRealtimeMillis = lastGnssData.elapsedRealtime.timestampNs * 1e-6;
|
||||
if (lastElapsedRealtimeMillis != 0) {
|
||||
deltasMs.push_back(currentElapsedRealtimeMillis - lastElapsedRealtimeMillis);
|
||||
}
|
||||
lastElapsedRealtimeMillis = currentElapsedRealtimeMillis;
|
||||
}
|
||||
}
|
||||
|
||||
void GnssHalTest::assertMeanAndStdev(int intervalMs, std::vector<int>& deltasMs) {
|
||||
double mean = computeMean(deltasMs);
|
||||
double stdev = computeStdev(mean, deltasMs);
|
||||
EXPECT_TRUE(std::abs(mean - intervalMs) <= intervalMs * ALLOWED_MEAN_ERROR_RATIO)
|
||||
<< "Test failed, because the mean of intervals is " << mean
|
||||
<< " millis. The test requires that abs(" << mean << " - " << intervalMs
|
||||
<< ") <= " << intervalMs * ALLOWED_MEAN_ERROR_RATIO
|
||||
<< " millis, when the requested interval is " << intervalMs << " millis.";
|
||||
|
||||
double maxStdev = std::max(MIN_STDEV_MS, intervalMs * ALLOWED_STDEV_ERROR_RATIO);
|
||||
EXPECT_TRUE(stdev <= maxStdev)
|
||||
<< "Test failed, because the stdev of intervals is " << stdev
|
||||
<< " millis, which must be <= " << maxStdev
|
||||
<< " millis, when the requested interval is " << intervalMs << " millis.";
|
||||
ALOGD("Mean of interval deltas in millis: %.1lf", mean);
|
||||
ALOGD("Stdev of interval deltas in millis: %.1lf", stdev);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <android/hardware/gnss/2.1/IGnss.h>
|
||||
#include "GnssBatchingCallback.h"
|
||||
#include "GnssCallbackAidl.h"
|
||||
#include "GnssMeasurementCallbackAidl.h"
|
||||
#include "v2_1/gnss_hal_test_template.h"
|
||||
|
||||
using IGnss_V2_1 = android::hardware::gnss::V2_1::IGnss;
|
||||
@@ -68,8 +69,11 @@ class GnssHalTest : public android::hardware::gnss::common::GnssHalTestTemplate<
|
||||
const bool check_speed);
|
||||
void SetPositionMode(const int min_interval_msec, const bool low_power_mode);
|
||||
bool StartAndCheckFirstLocation(const int min_interval_msec, const bool low_power_mode);
|
||||
bool StartAndCheckFirstLocation(const int min_interval_msec, const bool low_power_mode,
|
||||
const bool start_sv_status, const bool start_nmea);
|
||||
void StopAndClearLocations();
|
||||
void StartAndCheckLocations(int count);
|
||||
void StartAndCheckLocations(const int count);
|
||||
void StartAndCheckLocations(const int count, const bool start_sv_status, const bool start_nmea);
|
||||
|
||||
android::hardware::gnss::GnssConstellationType startLocationAndGetNonGpsConstellation(
|
||||
const int locations_to_await, const int gnss_sv_info_list_timeout);
|
||||
@@ -85,6 +89,19 @@ class GnssHalTest : public android::hardware::gnss::common::GnssHalTestTemplate<
|
||||
sv_info_list,
|
||||
const int min_observations);
|
||||
|
||||
void checkGnssMeasurementClockFields(const android::hardware::gnss::GnssData& measurement);
|
||||
void checkGnssMeasurementFlags(const android::hardware::gnss::GnssMeasurement& measurement);
|
||||
void checkGnssMeasurementFields(const android::hardware::gnss::GnssMeasurement& measurement,
|
||||
const android::hardware::gnss::GnssData& data);
|
||||
void startMeasurementWithInterval(
|
||||
int intervalMillis,
|
||||
const sp<android::hardware::gnss::IGnssMeasurementInterface>& iMeasurement,
|
||||
sp<GnssMeasurementCallbackAidl>& callback);
|
||||
void collectMeasurementIntervals(const sp<GnssMeasurementCallbackAidl>& callback,
|
||||
const int numMeasurementEvents, const int timeoutSeconds,
|
||||
std::vector<int>& deltaMs);
|
||||
void assertMeanAndStdev(int intervalMillis, std::vector<int>& deltasMillis);
|
||||
|
||||
sp<IGnssAidl> aidl_gnss_hal_;
|
||||
sp<GnssCallbackAidl> aidl_gnss_cb_; // Primary callback interface
|
||||
};
|
||||
|
||||
@@ -28,7 +28,9 @@
|
||||
#include <android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.h>
|
||||
#include <android/hardware/gnss/visibility_control/IGnssVisibilityControl.h>
|
||||
#include <cutils/properties.h>
|
||||
#include <utils/SystemClock.h>
|
||||
#include <cmath>
|
||||
#include <utility>
|
||||
#include "AGnssCallbackAidl.h"
|
||||
#include "AGnssRilCallbackAidl.h"
|
||||
#include "GnssAntennaInfoCallbackAidl.h"
|
||||
@@ -376,58 +378,6 @@ void CheckSatellitePvt(const SatellitePvt& satellitePvt, const int interfaceVers
|
||||
}
|
||||
}
|
||||
|
||||
void CheckGnssMeasurementClockFields(const GnssData& measurement) {
|
||||
Utils::checkElapsedRealtime(measurement.elapsedRealtime);
|
||||
ASSERT_TRUE(measurement.clock.gnssClockFlags >= 0 &&
|
||||
measurement.clock.gnssClockFlags <=
|
||||
(GnssClock::HAS_LEAP_SECOND | GnssClock::HAS_TIME_UNCERTAINTY |
|
||||
GnssClock::HAS_FULL_BIAS | GnssClock::HAS_BIAS |
|
||||
GnssClock::HAS_BIAS_UNCERTAINTY | GnssClock::HAS_DRIFT |
|
||||
GnssClock::HAS_DRIFT_UNCERTAINTY));
|
||||
}
|
||||
|
||||
void CheckGnssMeasurementFlags(const GnssMeasurement& measurement) {
|
||||
ASSERT_TRUE(measurement.flags >= 0 &&
|
||||
measurement.flags <=
|
||||
(GnssMeasurement::HAS_SNR | GnssMeasurement::HAS_CARRIER_FREQUENCY |
|
||||
GnssMeasurement::HAS_CARRIER_CYCLES | GnssMeasurement::HAS_CARRIER_PHASE |
|
||||
GnssMeasurement::HAS_CARRIER_PHASE_UNCERTAINTY |
|
||||
GnssMeasurement::HAS_AUTOMATIC_GAIN_CONTROL |
|
||||
GnssMeasurement::HAS_FULL_ISB | GnssMeasurement::HAS_FULL_ISB_UNCERTAINTY |
|
||||
GnssMeasurement::HAS_SATELLITE_ISB |
|
||||
GnssMeasurement::HAS_SATELLITE_ISB_UNCERTAINTY |
|
||||
GnssMeasurement::HAS_SATELLITE_PVT |
|
||||
GnssMeasurement::HAS_CORRELATION_VECTOR));
|
||||
}
|
||||
|
||||
void CheckGnssMeasurementFields(const GnssMeasurement& measurement, const GnssData& data) {
|
||||
CheckGnssMeasurementFlags(measurement);
|
||||
// Verify CodeType is valid.
|
||||
ASSERT_NE(measurement.signalType.codeType, "");
|
||||
// Verify basebandCn0DbHz is valid.
|
||||
ASSERT_TRUE(measurement.basebandCN0DbHz > 0.0 && measurement.basebandCN0DbHz <= 65.0);
|
||||
|
||||
if (((measurement.flags & GnssMeasurement::HAS_FULL_ISB) > 0) &&
|
||||
((measurement.flags & GnssMeasurement::HAS_FULL_ISB_UNCERTAINTY) > 0) &&
|
||||
((measurement.flags & GnssMeasurement::HAS_SATELLITE_ISB) > 0) &&
|
||||
((measurement.flags & GnssMeasurement::HAS_SATELLITE_ISB_UNCERTAINTY) > 0)) {
|
||||
GnssConstellationType referenceConstellation =
|
||||
data.clock.referenceSignalTypeForIsb.constellation;
|
||||
double carrierFrequencyHz = data.clock.referenceSignalTypeForIsb.carrierFrequencyHz;
|
||||
std::string codeType = data.clock.referenceSignalTypeForIsb.codeType;
|
||||
|
||||
ASSERT_TRUE(referenceConstellation >= GnssConstellationType::UNKNOWN &&
|
||||
referenceConstellation <= GnssConstellationType::IRNSS);
|
||||
ASSERT_TRUE(carrierFrequencyHz > 0);
|
||||
ASSERT_NE(codeType, "");
|
||||
|
||||
ASSERT_TRUE(std::abs(measurement.fullInterSignalBiasNs) < 1.0e6);
|
||||
ASSERT_TRUE(measurement.fullInterSignalBiasUncertaintyNs >= 0);
|
||||
ASSERT_TRUE(std::abs(measurement.satelliteInterSignalBiasNs) < 1.0e6);
|
||||
ASSERT_TRUE(measurement.satelliteInterSignalBiasUncertaintyNs >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TestGnssMeasurementExtensionAndSatellitePvt:
|
||||
* 1. Gets the GnssMeasurementExtension and verifies that it returns a non-null extension.
|
||||
@@ -465,10 +415,10 @@ TEST_P(GnssHalTest, TestGnssMeasurementExtensionAndSatellitePvt) {
|
||||
ASSERT_TRUE(lastMeasurement.measurements.size() > 0);
|
||||
|
||||
// Validity check GnssData fields
|
||||
CheckGnssMeasurementClockFields(lastMeasurement);
|
||||
checkGnssMeasurementClockFields(lastMeasurement);
|
||||
|
||||
for (const auto& measurement : lastMeasurement.measurements) {
|
||||
CheckGnssMeasurementFields(measurement, lastMeasurement);
|
||||
checkGnssMeasurementFields(measurement, lastMeasurement);
|
||||
if (measurement.flags & GnssMeasurement::HAS_SATELLITE_PVT &&
|
||||
kIsSatellitePvtSupported == true) {
|
||||
ALOGD("Found a measurement with SatellitePvt");
|
||||
@@ -525,10 +475,10 @@ TEST_P(GnssHalTest, TestCorrelationVector) {
|
||||
ASSERT_TRUE(lastMeasurement.measurements.size() > 0);
|
||||
|
||||
// Validity check GnssData fields
|
||||
CheckGnssMeasurementClockFields(lastMeasurement);
|
||||
checkGnssMeasurementClockFields(lastMeasurement);
|
||||
|
||||
for (const auto& measurement : lastMeasurement.measurements) {
|
||||
CheckGnssMeasurementFields(measurement, lastMeasurement);
|
||||
checkGnssMeasurementFields(measurement, lastMeasurement);
|
||||
if (measurement.flags & GnssMeasurement::HAS_CORRELATION_VECTOR) {
|
||||
correlationVectorFound = true;
|
||||
ASSERT_TRUE(measurement.correlationVectors.size() > 0);
|
||||
@@ -1241,48 +1191,6 @@ TEST_P(GnssHalTest, TestGnssVisibilityControlExtension) {
|
||||
ASSERT_TRUE(status.isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* TestGnssMeasurementSetCallbackWithOptions:
|
||||
* 1. Gets the GnssMeasurementExtension and verifies that it returns a non-null extension.
|
||||
* 2. Sets a GnssMeasurementCallback with intervalMillis option, waits for measurements reported,
|
||||
* and verifies mandatory fields are valid.
|
||||
*/
|
||||
TEST_P(GnssHalTest, TestGnssMeasurementSetCallbackWithOptions) {
|
||||
if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
|
||||
return;
|
||||
}
|
||||
const int kFirstGnssMeasurementTimeoutSeconds = 10;
|
||||
const int kNumMeasurementEvents = 5;
|
||||
|
||||
sp<IGnssMeasurementInterface> iGnssMeasurement;
|
||||
auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
|
||||
ASSERT_TRUE(status.isOk());
|
||||
ASSERT_TRUE(iGnssMeasurement != nullptr);
|
||||
|
||||
auto callback = sp<GnssMeasurementCallbackAidl>::make();
|
||||
IGnssMeasurementInterface::Options options;
|
||||
options.intervalMs = 2000;
|
||||
status = iGnssMeasurement->setCallbackWithOptions(callback, options);
|
||||
ASSERT_TRUE(status.isOk());
|
||||
|
||||
for (int i = 0; i < kNumMeasurementEvents; i++) {
|
||||
GnssData lastMeasurement;
|
||||
ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastMeasurement,
|
||||
kFirstGnssMeasurementTimeoutSeconds));
|
||||
EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), i + 1);
|
||||
ASSERT_TRUE(lastMeasurement.measurements.size() > 0);
|
||||
|
||||
// Validity check GnssData fields
|
||||
CheckGnssMeasurementClockFields(lastMeasurement);
|
||||
for (const auto& measurement : lastMeasurement.measurements) {
|
||||
CheckGnssMeasurementFields(measurement, lastMeasurement);
|
||||
}
|
||||
}
|
||||
|
||||
status = iGnssMeasurement->close();
|
||||
ASSERT_TRUE(status.isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* TestGnssAgcInGnssMeasurement:
|
||||
* 1. Gets the GnssMeasurementExtension and verifies that it returns a non-null extension.
|
||||
@@ -1293,7 +1201,7 @@ TEST_P(GnssHalTest, TestGnssAgcInGnssMeasurement) {
|
||||
return;
|
||||
}
|
||||
const int kFirstGnssMeasurementTimeoutSeconds = 10;
|
||||
const int kNumMeasurementEvents = 15;
|
||||
const int kNumMeasurementEvents = 5;
|
||||
|
||||
sp<IGnssMeasurementInterface> iGnssMeasurement;
|
||||
auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
|
||||
@@ -1313,7 +1221,7 @@ TEST_P(GnssHalTest, TestGnssAgcInGnssMeasurement) {
|
||||
ASSERT_TRUE(lastMeasurement.measurements.size() > 0);
|
||||
|
||||
// Validity check GnssData fields
|
||||
CheckGnssMeasurementClockFields(lastMeasurement);
|
||||
checkGnssMeasurementClockFields(lastMeasurement);
|
||||
|
||||
ASSERT_TRUE(lastMeasurement.gnssAgcs.size() > 0);
|
||||
for (const auto& gnssAgc : lastMeasurement.gnssAgcs) {
|
||||
@@ -1444,3 +1352,143 @@ TEST_P(GnssHalTest, TestGnssMeasurementCorrections) {
|
||||
Utils::getMockMeasurementCorrections_aidl());
|
||||
ASSERT_TRUE(status.isOk());
|
||||
}
|
||||
|
||||
/*
|
||||
* TestStopSvStatusAndNmea:
|
||||
* 1. Call stopSvStatus and stopNmea.
|
||||
* 2. Start location and verify that
|
||||
* - no SvStatus is received.
|
||||
* - no Nmea is received.
|
||||
*/
|
||||
TEST_P(GnssHalTest, TestStopSvStatusAndNmea) {
|
||||
if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
|
||||
return;
|
||||
}
|
||||
auto status = aidl_gnss_hal_->stopSvStatus();
|
||||
EXPECT_TRUE(status.isOk());
|
||||
status = aidl_gnss_hal_->stopNmea();
|
||||
EXPECT_TRUE(status.isOk());
|
||||
|
||||
int kLocationsToAwait = 5;
|
||||
aidl_gnss_cb_->location_cbq_.reset();
|
||||
aidl_gnss_cb_->sv_info_list_cbq_.reset();
|
||||
aidl_gnss_cb_->nmea_cbq_.reset();
|
||||
StartAndCheckLocations(/* count= */ kLocationsToAwait,
|
||||
/* start_sv_status= */ false, /* start_nmea= */ false);
|
||||
int location_called_count = aidl_gnss_cb_->location_cbq_.calledCount();
|
||||
ALOGD("Observed %d GnssSvStatus, and %d Nmea while awaiting %d locations (%d received)",
|
||||
aidl_gnss_cb_->sv_info_list_cbq_.size(), aidl_gnss_cb_->nmea_cbq_.size(),
|
||||
kLocationsToAwait, location_called_count);
|
||||
|
||||
// Ensure that no SvStatus & no Nmea is received.
|
||||
EXPECT_EQ(aidl_gnss_cb_->sv_info_list_cbq_.size(), 0);
|
||||
EXPECT_EQ(aidl_gnss_cb_->nmea_cbq_.size(), 0);
|
||||
|
||||
StopAndClearLocations();
|
||||
}
|
||||
|
||||
/*
|
||||
* TestGnssMeasurementIntervals_WithoutLocation:
|
||||
* 1. start measurement with interval
|
||||
* 2. verify that the received measurement intervals have expected mean and stdev
|
||||
*/
|
||||
TEST_P(GnssHalTest, TestGnssMeasurementIntervals_WithoutLocation) {
|
||||
if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<int> intervals({2000, 4000});
|
||||
std::vector<int> numEvents({10, 5});
|
||||
|
||||
sp<IGnssMeasurementInterface> iGnssMeasurement;
|
||||
auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
|
||||
ASSERT_TRUE(status.isOk());
|
||||
ASSERT_TRUE(iGnssMeasurement != nullptr);
|
||||
|
||||
ALOGD("TestGnssMeasurementIntervals_WithoutLocation");
|
||||
for (int i = 0; i < intervals.size(); i++) {
|
||||
auto callback = sp<GnssMeasurementCallbackAidl>::make();
|
||||
startMeasurementWithInterval(intervals[i], iGnssMeasurement, callback);
|
||||
|
||||
std::vector<int> deltas;
|
||||
collectMeasurementIntervals(callback, numEvents[i], /* timeoutSeconds= */ 10, deltas);
|
||||
|
||||
status = iGnssMeasurement->close();
|
||||
ASSERT_TRUE(status.isOk());
|
||||
|
||||
assertMeanAndStdev(intervals[i], deltas);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TestGnssMeasurementIntervals_LocationOnBeforeMeasurement:
|
||||
* 1. start measurement with interval
|
||||
* 2. verify that the received measurement intervals have expected mean and stdev
|
||||
*/
|
||||
TEST_P(GnssHalTest, TestGnssMeasurementIntervals_LocationOnBeforeMeasurement) {
|
||||
if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<int> intervals({2000});
|
||||
|
||||
sp<IGnssMeasurementInterface> iGnssMeasurement;
|
||||
auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
|
||||
ASSERT_TRUE(status.isOk());
|
||||
ASSERT_TRUE(iGnssMeasurement != nullptr);
|
||||
|
||||
int locationIntervalMs = 1000;
|
||||
|
||||
// Start location first and then start measurement
|
||||
ALOGD("TestGnssMeasurementIntervals_LocationOnBeforeMeasurement");
|
||||
StartAndCheckFirstLocation(locationIntervalMs, /* lowPowerMode= */ false);
|
||||
for (auto& intervalMs : intervals) {
|
||||
auto callback = sp<GnssMeasurementCallbackAidl>::make();
|
||||
startMeasurementWithInterval(intervalMs, iGnssMeasurement, callback);
|
||||
|
||||
std::vector<int> deltas;
|
||||
collectMeasurementIntervals(callback, /*numEvents=*/10, /*timeoutSeconds=*/10, deltas);
|
||||
|
||||
status = iGnssMeasurement->close();
|
||||
ASSERT_TRUE(status.isOk());
|
||||
|
||||
assertMeanAndStdev(locationIntervalMs, deltas);
|
||||
}
|
||||
StopAndClearLocations();
|
||||
}
|
||||
|
||||
/*
|
||||
* TestGnssMeasurementIntervals:
|
||||
* 1. start measurement with interval
|
||||
* 2. verify that the received measurement intervals have expected mean and stdev
|
||||
*/
|
||||
TEST_P(GnssHalTest, TestGnssMeasurementIntervals_LocationOnAfterMeasurement) {
|
||||
if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<int> intervals({2000});
|
||||
|
||||
sp<IGnssMeasurementInterface> iGnssMeasurement;
|
||||
auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
|
||||
ASSERT_TRUE(status.isOk());
|
||||
ASSERT_TRUE(iGnssMeasurement != nullptr);
|
||||
|
||||
int locationIntervalMs = 1000;
|
||||
// Start location first and then start measurement
|
||||
ALOGD("TestGnssMeasurementIntervals_LocationOnAfterMeasurement");
|
||||
for (auto& intervalMs : intervals) {
|
||||
auto callback = sp<GnssMeasurementCallbackAidl>::make();
|
||||
startMeasurementWithInterval(intervalMs, iGnssMeasurement, callback);
|
||||
|
||||
StartAndCheckFirstLocation(locationIntervalMs, /* lowPowerMode= */ false);
|
||||
std::vector<int> deltas;
|
||||
collectMeasurementIntervals(callback, /*numEvents=*/10, /*timeoutSeconds=*/10, deltas);
|
||||
|
||||
StopAndClearLocations();
|
||||
status = iGnssMeasurement->close();
|
||||
ASSERT_TRUE(status.isOk());
|
||||
|
||||
assertMeanAndStdev(locationIntervalMs, deltas);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,31 @@ struct Utils {
|
||||
static hidl_vec<V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo> getMockAntennaInfos();
|
||||
};
|
||||
|
||||
struct ThreadBlocker {
|
||||
// returns false if unblocked:
|
||||
template <class R, class P>
|
||||
bool wait_for(std::chrono::duration<R, P> const& time) {
|
||||
std::unique_lock<std::mutex> lock(m);
|
||||
return !cv.wait_for(lock, time, [&] { return terminate; });
|
||||
}
|
||||
|
||||
void notify() {
|
||||
std::unique_lock<std::mutex> lock(m);
|
||||
terminate = true;
|
||||
cv.notify_all();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
std::unique_lock<std::mutex> lock(m);
|
||||
terminate = false;
|
||||
}
|
||||
|
||||
private:
|
||||
std::condition_variable cv;
|
||||
std::mutex m;
|
||||
bool terminate = false;
|
||||
};
|
||||
|
||||
} // namespace common
|
||||
} // namespace gnss
|
||||
} // namespace hardware
|
||||
|
||||
Reference in New Issue
Block a user