diff --git a/broadcastradio/1.1/default/BroadcastRadio.cpp b/broadcastradio/1.1/default/BroadcastRadio.cpp index 7916407bdf..17ec7803ae 100644 --- a/broadcastradio/1.1/default/BroadcastRadio.cpp +++ b/broadcastradio/1.1/default/BroadcastRadio.cpp @@ -143,7 +143,7 @@ Return BroadcastRadio::openTuner(const BandConfig& config, bool audio __un mTuner = nullptr; } - sp newTuner = new Tuner(callback); + sp newTuner = new Tuner(mClassId, callback); mTuner = newTuner; if (mClassId == Class::AM_FM) { auto ret = newTuner->setConfiguration(config); diff --git a/broadcastradio/1.1/default/Tuner.cpp b/broadcastradio/1.1/default/Tuner.cpp index 2af221eb34..f48a8db369 100644 --- a/broadcastradio/1.1/default/Tuner.cpp +++ b/broadcastradio/1.1/default/Tuner.cpp @@ -33,6 +33,7 @@ using namespace std::chrono_literals; using V1_0::Band; using V1_0::BandConfig; +using V1_0::Class; using V1_0::Direction; using utils::HalRevision; @@ -50,10 +51,11 @@ const struct { milliseconds tune = 150ms; } gDefaultDelay; -Tuner::Tuner(const sp& callback) - : mCallback(callback), +Tuner::Tuner(V1_0::Class classId, const sp& callback) + : mClassId(classId), + mCallback(callback), mCallback1_1(ITunerCallback::castFrom(callback).withDefault(nullptr)), - mVirtualFm(make_fm_radio()), + mVirtualRadio(getRadio(classId)), mIsAnalogForced(false) {} void Tuner::forceClose() { @@ -66,6 +68,10 @@ Return Tuner::setConfiguration(const BandConfig& config) { ALOGV("%s", __func__); lock_guard lk(mMut); if (mIsClosed) return Result::NOT_INITIALIZED; + if (mClassId != Class::AM_FM) { + ALOGE("Can't set AM/FM configuration on SAT/DT radio tuner"); + return Result::INVALID_STATE; + } if (config.lowerLimit >= config.upperLimit) return Result::INVALID_ARGUMENTS; @@ -77,6 +83,12 @@ Return Tuner::setConfiguration(const BandConfig& config) { mAmfmConfig.antennaConnected = true; mCurrentProgram = utils::make_selector(mAmfmConfig.type, mAmfmConfig.lowerLimit); + if (mAmfmConfig.type == Band::FM_HD || mAmfmConfig.type == Band::FM) { + mVirtualRadio = std::ref(getFmRadio()); + } else { + mVirtualRadio = std::ref(getAmRadio()); + } + mIsAmfmConfigSet = true; mCallback->configChange(Result::OK, mAmfmConfig); }; @@ -117,19 +129,9 @@ HalRevision Tuner::getHalRev() const { } } -bool Tuner::isFmLocked() { - if (!utils::isAmFm(utils::getType(mCurrentProgram))) return false; - return mAmfmConfig.type == Band::FM_HD || mAmfmConfig.type == Band::FM; -} - void Tuner::tuneInternalLocked(const ProgramSelector& sel) { - VirtualRadio* virtualRadio = nullptr; - if (isFmLocked()) { - virtualRadio = &mVirtualFm; - } - VirtualProgram virtualProgram; - if (virtualRadio != nullptr && virtualRadio->getProgram(sel, virtualProgram)) { + if (mVirtualRadio.get().getProgram(sel, virtualProgram)) { mCurrentProgram = virtualProgram.selector; mCurrentProgramInfo = virtualProgram.getProgramInfo(getHalRev()); } else { @@ -150,11 +152,7 @@ Return Tuner::scan(Direction direction, bool skipSubChannel __unused) { lock_guard lk(mMut); if (mIsClosed) return Result::NOT_INITIALIZED; - vector list; - - if (isFmLocked()) { - list = mVirtualFm.getProgramList(); - } + auto list = mVirtualRadio.get().getProgramList(); if (list.empty()) { mIsTuneCompleted = false; @@ -332,14 +330,7 @@ Return Tuner::getProgramList(const hidl_string& filter, getProgramList_cb return {}; } - auto& virtualRadio = mVirtualFm; - if (!isFmLocked()) { - ALOGI("bands other than FM are not supported yet"); - _hidl_cb(ProgramListResult::OK, {}); - return {}; - } - - auto list = virtualRadio.getProgramList(); + auto list = mVirtualRadio.get().getProgramList(); ALOGD("returning a list of %zu programs", list.size()); _hidl_cb(ProgramListResult::OK, getProgramInfoVector(list, getHalRev())); return {}; diff --git a/broadcastradio/1.1/default/Tuner.h b/broadcastradio/1.1/default/Tuner.h index af19ec0f02..c4efe6ec4c 100644 --- a/broadcastradio/1.1/default/Tuner.h +++ b/broadcastradio/1.1/default/Tuner.h @@ -29,7 +29,7 @@ namespace V1_1 { namespace implementation { struct Tuner : public ITuner { - Tuner(const sp& callback); + Tuner(V1_0::Class classId, const sp& callback); void forceClose(); @@ -55,11 +55,11 @@ struct Tuner : public ITuner { WorkerThread mThread; bool mIsClosed = false; + V1_0::Class mClassId; const sp mCallback; const sp mCallback1_1; - VirtualRadio mVirtualFm; - + std::reference_wrapper mVirtualRadio; bool mIsAmfmConfigSet = false; V1_0::BandConfig mAmfmConfig; bool mIsTuneCompleted = false; @@ -69,7 +69,6 @@ struct Tuner : public ITuner { utils::HalRevision getHalRev() const; void tuneInternalLocked(const ProgramSelector& sel); - bool isFmLocked(); // TODO(b/36864090): make it generic, not FM only }; } // namespace implementation diff --git a/broadcastradio/1.1/default/VirtualProgram.h b/broadcastradio/1.1/default/VirtualProgram.h index 33ec292215..a14830d77a 100644 --- a/broadcastradio/1.1/default/VirtualProgram.h +++ b/broadcastradio/1.1/default/VirtualProgram.h @@ -25,6 +25,12 @@ namespace broadcastradio { namespace V1_1 { namespace implementation { +/** + * A radio program mock. + * + * This represents broadcast waves flying over the air, + * not an entry for a captured station in the radio tuner memory. + */ struct VirtualProgram { ProgramSelector selector; diff --git a/broadcastradio/1.1/default/VirtualRadio.cpp b/broadcastradio/1.1/default/VirtualRadio.cpp index 692e7bc91c..36d47a92e7 100644 --- a/broadcastradio/1.1/default/VirtualRadio.cpp +++ b/broadcastradio/1.1/default/VirtualRadio.cpp @@ -13,9 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#define LOG_TAG "BroadcastRadioDefault.VirtualRadio" +//#define LOG_NDEBUG 0 + #include "VirtualRadio.h" #include +#include namespace android { namespace hardware { @@ -24,6 +28,7 @@ namespace V1_1 { namespace implementation { using V1_0::Band; +using V1_0::Class; using std::lock_guard; using std::move; @@ -32,7 +37,7 @@ using std::vector; using utils::make_selector; -const vector gInitialFmPrograms{ +static const vector gInitialFmPrograms{ {make_selector(Band::FM, 94900), "Wild 94.9", "Drake ft. Rihanna", "Too Good"}, {make_selector(Band::FM, 96500), "KOIT", "Celine Dion", "All By Myself"}, {make_selector(Band::FM, 97300), "Alice@97.3", "Drops of Jupiter", "Train"}, @@ -42,7 +47,8 @@ const vector gInitialFmPrograms{ {make_selector(Band::FM, 106100), "106 KMEL", "Drake", "Marvins Room"}, }; -VirtualRadio::VirtualRadio(VirtualRadio&& o) : mPrograms(move(o.mPrograms)) {} +static VirtualRadio gEmptyRadio({}); +static VirtualRadio gFmRadio(gInitialFmPrograms); VirtualRadio::VirtualRadio(const vector initialList) : mPrograms(initialList) {} @@ -62,8 +68,34 @@ bool VirtualRadio::getProgram(const ProgramSelector& selector, VirtualProgram& p return false; } -VirtualRadio make_fm_radio() { - return VirtualRadio(gInitialFmPrograms); +VirtualRadio& getRadio(V1_0::Class classId) { + switch (classId) { + case Class::AM_FM: + return getFmRadio(); + case Class::SAT: + return getSatRadio(); + case Class::DT: + return getDigitalRadio(); + default: + ALOGE("Invalid class ID"); + return gEmptyRadio; + } +} + +VirtualRadio& getAmRadio() { + return gEmptyRadio; +} + +VirtualRadio& getFmRadio() { + return gFmRadio; +} + +VirtualRadio& getSatRadio() { + return gEmptyRadio; +} + +VirtualRadio& getDigitalRadio() { + return gEmptyRadio; } } // namespace implementation diff --git a/broadcastradio/1.1/default/VirtualRadio.h b/broadcastradio/1.1/default/VirtualRadio.h index 4cdc72ffc8..3c7ae5c193 100644 --- a/broadcastradio/1.1/default/VirtualRadio.h +++ b/broadcastradio/1.1/default/VirtualRadio.h @@ -27,9 +27,16 @@ namespace broadcastradio { namespace V1_1 { namespace implementation { +/** + * A radio frequency space mock. + * + * This represents all broadcast waves in the air for a given radio technology, + * not a captured station list in the radio tuner memory. + * + * It's meant to abstract out radio content from default tuner implementation. + */ class VirtualRadio { public: - VirtualRadio(VirtualRadio&& o); VirtualRadio(const std::vector initialList); std::vector getProgramList(); @@ -40,7 +47,29 @@ class VirtualRadio { std::vector mPrograms; }; -VirtualRadio make_fm_radio(); +/** + * Get virtual radio space for a given radio class. + * + * As a space, each virtual radio always exists. For example, DAB frequencies + * exists in US, but contains no programs. + * + * The lifetime of the virtual radio space is virtually infinite, but for the + * needs of default implementation, it's bound with the lifetime of default + * implementation process. + * + * Internally, it's a static object, so trying to access the reference during + * default implementation library unloading may result in segmentation fault. + * It's unlikely for testing purposes. + * + * @param classId A class of radio technology. + * @return A reference to virtual radio space for a given technology. + */ +VirtualRadio& getRadio(V1_0::Class classId); + +VirtualRadio& getAmRadio(); +VirtualRadio& getFmRadio(); +VirtualRadio& getSatRadio(); +VirtualRadio& getDigitalRadio(); } // namespace implementation } // namespace V1_1