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

Commit c863a957 authored by Tomasz Wasilczyk's avatar Tomasz Wasilczyk
Browse files

Fix boadcastradio HAL 1.1 tuneByProgramSelector implementation.

It was not compliant with the HAL definition - it didn't auto-change
band if necessary.

Bug: 74353024
Test: manual
Change-Id: I015faffc42778fa27fca3030306f31b0abe409c7
parent 486c1de2
Loading
Loading
Loading
Loading
+29 −23
Original line number Diff line number Diff line
@@ -122,28 +122,7 @@ Return<void> BroadcastRadio::getProperties_1_1(getProperties_1_1_cb _hidl_cb) {
        {"com.google.dummy", "dummy"},
    });

    prop10.bands.resize(mConfig.amFmBands.size());
    for (size_t i = 0; i < mConfig.amFmBands.size(); i++) {
        auto& src = mConfig.amFmBands[i];
        auto& dst = prop10.bands[i];

        dst.type = src.type;
        dst.antennaConnected = true;
        dst.lowerLimit = src.lowerLimit;
        dst.upperLimit = src.upperLimit;
        dst.spacings = src.spacings;

        if (utils::isAm(src.type)) {
            dst.ext.am.stereo = true;
        } else if (utils::isFm(src.type)) {
            dst.ext.fm.deemphasis = static_cast<Deemphasis>(Deemphasis::D50 | Deemphasis::D75);
            dst.ext.fm.stereo = true;
            dst.ext.fm.rds = static_cast<Rds>(Rds::WORLD | Rds::US);
            dst.ext.fm.ta = true;
            dst.ext.fm.af = true;
            dst.ext.fm.ea = true;
        }
    }
    prop10.bands = getAmFmBands();

    _hidl_cb(prop11);
    return Void();
@@ -162,7 +141,7 @@ Return<void> BroadcastRadio::openTuner(const BandConfig& config, bool audio __un
        mTuner = nullptr;
    }

    sp<Tuner> newTuner = new Tuner(mClassId, callback);
    sp<Tuner> newTuner = new Tuner(this, mClassId, callback);
    mTuner = newTuner;
    if (mClassId == Class::AM_FM) {
        auto ret = newTuner->setConfiguration(config);
@@ -189,6 +168,33 @@ Return<void> BroadcastRadio::getImage(int32_t id, getImage_cb _hidl_cb) {
    return Void();
}

std::vector<V1_0::BandConfig> BroadcastRadio::getAmFmBands() const {
    std::vector<V1_0::BandConfig> out;
    for (auto&& src : mConfig.amFmBands) {
        V1_0::BandConfig dst;

        dst.type = src.type;
        dst.antennaConnected = true;
        dst.lowerLimit = src.lowerLimit;
        dst.upperLimit = src.upperLimit;
        dst.spacings = src.spacings;

        if (utils::isAm(src.type)) {
            dst.ext.am.stereo = true;
        } else if (utils::isFm(src.type)) {
            dst.ext.fm.deemphasis = static_cast<Deemphasis>(Deemphasis::D50 | Deemphasis::D75);
            dst.ext.fm.stereo = true;
            dst.ext.fm.rds = static_cast<Rds>(Rds::WORLD | Rds::US);
            dst.ext.fm.ta = true;
            dst.ext.fm.af = true;
            dst.ext.fm.ea = true;
        }

        out.push_back(dst);
    }
    return out;
}

}  // namespace implementation
}  // namespace V1_1
}  // namespace broadcastradio
+2 −0
Original line number Diff line number Diff line
@@ -65,6 +65,8 @@ struct BroadcastRadio : public V1_1::IBroadcastRadio {
                           openTuner_cb _hidl_cb) override;
    Return<void> getImage(int32_t id, getImage_cb _hidl_cb);

    std::vector<V1_0::BandConfig> getAmFmBands() const;

   private:
    std::mutex mMut;
    V1_0::Class mClassId;
+33 −16
Original line number Diff line number Diff line
@@ -58,8 +58,10 @@ const struct {
    milliseconds tune = 150ms;
} gDefaultDelay;

Tuner::Tuner(V1_0::Class classId, const sp<V1_0::ITunerCallback>& callback)
    : mClassId(classId),
Tuner::Tuner(const sp<BroadcastRadio> module, V1_0::Class classId,
             const sp<V1_0::ITunerCallback>& callback)
    : mModule(module),
      mClassId(classId),
      mCallback(callback),
      mCallback1_1(V1_1::ITunerCallback::castFrom(callback).withDefault(nullptr)),
      mVirtualRadio(getRadio(classId)),
@@ -71,6 +73,33 @@ void Tuner::forceClose() {
    mThread.cancelAll();
}

void Tuner::setConfigurationInternalLocked(const BandConfig& config) {
    mAmfmConfig = config;
    mAmfmConfig.antennaConnected = true;
    mCurrentProgram = utils::make_selector(mAmfmConfig.type, mAmfmConfig.lowerLimit);

    if (utils::isFm(mAmfmConfig.type)) {
        mVirtualRadio = std::ref(getFmRadio());
    } else {
        mVirtualRadio = std::ref(getAmRadio());
    }

    mIsAmfmConfigSet = true;
    mCallback->configChange(Result::OK, mAmfmConfig);
}

bool Tuner::autoConfigureLocked(uint64_t frequency) {
    for (auto&& config : mModule->getAmFmBands()) {
        // The check here is rather poor, but it's enough for default implementation.
        if (config.lowerLimit <= frequency && config.upperLimit >= frequency) {
            ALOGI("Auto-switching band to %s", toString(config).c_str());
            setConfigurationInternalLocked(config);
            return true;
        }
    }
    return false;
}

Return<Result> Tuner::setConfiguration(const BandConfig& config) {
    ALOGV("%s", __func__);
    lock_guard<mutex> lk(mMut);
@@ -85,19 +114,7 @@ Return<Result> Tuner::setConfiguration(const BandConfig& config) {
    auto task = [this, config]() {
        ALOGI("Setting AM/FM config");
        lock_guard<mutex> lk(mMut);

        mAmfmConfig = move(config);
        mAmfmConfig.antennaConnected = true;
        mCurrentProgram = utils::make_selector(mAmfmConfig.type, mAmfmConfig.lowerLimit);

        if (utils::isFm(mAmfmConfig.type)) {
            mVirtualRadio = std::ref(getFmRadio());
        } else {
            mVirtualRadio = std::ref(getAmRadio());
        }

        mIsAmfmConfigSet = true;
        mCallback->configChange(Result::OK, mAmfmConfig);
        setConfigurationInternalLocked(config);
    };
    mThread.schedule(task, gDefaultDelay.config);

@@ -276,7 +293,7 @@ Return<Result> Tuner::tuneByProgramSelector(const ProgramSelector& sel) {

        auto freq = utils::getId(sel, IdentifierType::AMFM_FREQUENCY);
        if (freq < mAmfmConfig.lowerLimit || freq > mAmfmConfig.upperLimit) {
            return Result::INVALID_ARGUMENTS;
            if (!autoConfigureLocked(freq)) return Result::INVALID_ARGUMENTS;
        }
    } else if (programType == ProgramType::DAB) {
        if (!utils::hasId(sel, IdentifierType::DAB_SIDECC)) return Result::INVALID_ARGUMENTS;
+7 −1
Original line number Diff line number Diff line
@@ -28,8 +28,11 @@ namespace broadcastradio {
namespace V1_1 {
namespace implementation {

struct BroadcastRadio;

struct Tuner : public ITuner {
    Tuner(V1_0::Class classId, const sp<V1_0::ITunerCallback>& callback);
    Tuner(const sp<BroadcastRadio> module, V1_0::Class classId,
          const sp<V1_0::ITunerCallback>& callback);

    void forceClose();

@@ -55,6 +58,7 @@ struct Tuner : public ITuner {
    WorkerThread mThread;
    bool mIsClosed = false;

    const sp<BroadcastRadio> mModule;
    V1_0::Class mClassId;
    const sp<V1_0::ITunerCallback> mCallback;
    const sp<V1_1::ITunerCallback> mCallback1_1;
@@ -68,7 +72,9 @@ struct Tuner : public ITuner {
    std::atomic<bool> mIsAnalogForced;

    utils::HalRevision getHalRev() const;
    void setConfigurationInternalLocked(const V1_0::BandConfig& config);
    void tuneInternalLocked(const V1_1::ProgramSelector& sel);
    bool autoConfigureLocked(uint64_t frequency);
};

}  // namespace implementation