Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 19a32b62 authored by Yu-Han Yang's avatar Yu-Han Yang
Browse files

Add VTS tests for measurementInterval, stopSvStatus, and stopNmea

Bug: 206670536
Test: atest VtsHalGnssTargetTest

Change-Id: Id597c772fbe63789cb394b2aa14faeb755196f64
parent dd890b58
Loading
Loading
Loading
Loading
+48 −21
Original line number Diff line number Diff line
@@ -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();
}

+6 −0
Original line number Diff line number Diff line
@@ -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;
};
+58 −15
Original line number Diff line number Diff line
@@ -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;
    }

    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;
    }

    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");
    if (mIsActive) {
        stop();
    }
    {
        std::unique_lock<std::mutex> lock(mMutex);
        sCallback = nullptr;
    mMinIntervalMillis = 1000;
    }
    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
+10 −1
Original line number Diff line number Diff line
@@ -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;
+31 −6
Original line number Diff line number Diff line
@@ -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");
    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
Loading