Make virtual radio space generic, not only FM-exclusive.

Bug: b/36864090
Test: VTS, instrumentalization
Change-Id: I2764d09f56a397a1b80914a2634d6bad4b3bd3d2
This commit is contained in:
Tomasz Wasilczyk
2017-07-28 10:08:46 -07:00
parent 5be4c2b6e3
commit efadc19b6b
6 changed files with 95 additions and 38 deletions

View File

@@ -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);

View File

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

View File

@@ -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

View File

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

View File

@@ -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

View File

@@ -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