mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
Make virtual radio space generic, not only FM-exclusive.
Bug: b/36864090 Test: VTS, instrumentalization Change-Id: I2764d09f56a397a1b80914a2634d6bad4b3bd3d2
This commit is contained in:
@@ -143,7 +143,7 @@ Return<void> BroadcastRadio::openTuner(const BandConfig& config, bool audio __un
|
||||
mTuner = nullptr;
|
||||
}
|
||||
|
||||
sp<Tuner> newTuner = new Tuner(callback);
|
||||
sp<Tuner> newTuner = new Tuner(mClassId, callback);
|
||||
mTuner = newTuner;
|
||||
if (mClassId == Class::AM_FM) {
|
||||
auto ret = newTuner->setConfiguration(config);
|
||||
|
||||
@@ -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<V1_0::ITunerCallback>& callback)
|
||||
: mCallback(callback),
|
||||
Tuner::Tuner(V1_0::Class classId, const sp<V1_0::ITunerCallback>& 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<Result> Tuner::setConfiguration(const BandConfig& config) {
|
||||
ALOGV("%s", __func__);
|
||||
lock_guard<mutex> 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<Result> 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<Result> Tuner::scan(Direction direction, bool skipSubChannel __unused) {
|
||||
lock_guard<mutex> lk(mMut);
|
||||
if (mIsClosed) return Result::NOT_INITIALIZED;
|
||||
|
||||
vector<VirtualProgram> list;
|
||||
|
||||
if (isFmLocked()) {
|
||||
list = mVirtualFm.getProgramList();
|
||||
}
|
||||
auto list = mVirtualRadio.get().getProgramList();
|
||||
|
||||
if (list.empty()) {
|
||||
mIsTuneCompleted = false;
|
||||
@@ -332,14 +330,7 @@ Return<void> 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 {};
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace V1_1 {
|
||||
namespace implementation {
|
||||
|
||||
struct Tuner : public ITuner {
|
||||
Tuner(const sp<V1_0::ITunerCallback>& callback);
|
||||
Tuner(V1_0::Class classId, const sp<V1_0::ITunerCallback>& callback);
|
||||
|
||||
void forceClose();
|
||||
|
||||
@@ -55,11 +55,11 @@ struct Tuner : public ITuner {
|
||||
WorkerThread mThread;
|
||||
bool mIsClosed = false;
|
||||
|
||||
V1_0::Class mClassId;
|
||||
const sp<V1_0::ITunerCallback> mCallback;
|
||||
const sp<V1_1::ITunerCallback> mCallback1_1;
|
||||
|
||||
VirtualRadio mVirtualFm;
|
||||
|
||||
std::reference_wrapper<VirtualRadio> 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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 <broadcastradio-utils/Utils.h>
|
||||
#include <log/log.h>
|
||||
|
||||
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<VirtualProgram> gInitialFmPrograms{
|
||||
static const vector<VirtualProgram> 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<VirtualProgram> 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<VirtualProgram> 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
|
||||
|
||||
@@ -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<VirtualProgram> initialList);
|
||||
|
||||
std::vector<VirtualProgram> getProgramList();
|
||||
@@ -40,7 +47,29 @@ class VirtualRadio {
|
||||
std::vector<VirtualProgram> 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
|
||||
|
||||
Reference in New Issue
Block a user