mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
Implement broadcast radio HAL 2.0 default implementation.
Also, split internal common utils library to 1.x and 2.x. Test: VTS Bug: 69958777 Change-Id: I21244c74270a07cc350e8a2b974dafcdae02a0e8
This commit is contained in:
@@ -22,7 +22,7 @@ cc_test {
|
||||
"android.hardware.broadcastradio@1.0",
|
||||
"android.hardware.broadcastradio@1.1",
|
||||
"android.hardware.broadcastradio@1.2", // common-utils-lib dependency
|
||||
"android.hardware.broadcastradio@common-utils-lib",
|
||||
"android.hardware.broadcastradio@common-utils-1x-lib",
|
||||
"android.hardware.broadcastradio@vts-utils-lib",
|
||||
"libgmock",
|
||||
],
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
#define LOG_TAG "broadcastradio.vts"
|
||||
|
||||
#include <VtsHalHidlTargetTestBase.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android/hardware/broadcastradio/1.1/IBroadcastRadio.h>
|
||||
#include <android/hardware/broadcastradio/1.1/IBroadcastRadioFactory.h>
|
||||
#include <android/hardware/broadcastradio/1.1/ITuner.h>
|
||||
#include <android/hardware/broadcastradio/1.1/ITunerCallback.h>
|
||||
#include <android/hardware/broadcastradio/1.1/types.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <broadcastradio-utils/Utils.h>
|
||||
#include <broadcastradio-utils-1x/Utils.h>
|
||||
#include <broadcastradio-vts-utils/call-barrier.h>
|
||||
#include <broadcastradio-vts-utils/mock-timeout.h>
|
||||
#include <cutils/native_handle.h>
|
||||
|
||||
@@ -33,6 +33,7 @@ cc_binary {
|
||||
"service.cpp"
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.broadcastradio@common-utils-1x-lib",
|
||||
"android.hardware.broadcastradio@common-utils-lib",
|
||||
],
|
||||
shared_libs: [
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include "BroadcastRadio.h"
|
||||
#include "Tuner.h"
|
||||
|
||||
#include <broadcastradio-utils/Utils.h>
|
||||
#include <broadcastradio-utils-1x/Utils.h>
|
||||
#include <log/log.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
#include "VirtualProgram.h"
|
||||
|
||||
#include <broadcastradio-utils/Utils.h>
|
||||
#include <broadcastradio-utils-1x/Utils.h>
|
||||
|
||||
#include "resources.h"
|
||||
|
||||
@@ -83,13 +83,6 @@ bool operator<(const VirtualProgram& lhs, const VirtualProgram& rhs) {
|
||||
if (l.primaryId.type != r.primaryId.type) return l.primaryId.type < r.primaryId.type;
|
||||
if (l.primaryId.value != r.primaryId.value) return l.primaryId.value < r.primaryId.value;
|
||||
|
||||
// A little exception for HD Radio subchannel - we check secondary ID too.
|
||||
if (utils::hasId(l, IdentifierType::HD_SUBCHANNEL) &&
|
||||
utils::hasId(r, IdentifierType::HD_SUBCHANNEL)) {
|
||||
return utils::getId(l, IdentifierType::HD_SUBCHANNEL) <
|
||||
utils::getId(r, IdentifierType::HD_SUBCHANNEL);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#define ANDROID_HARDWARE_BROADCASTRADIO_V1_2_VIRTUALPROGRAM_H
|
||||
|
||||
#include <android/hardware/broadcastradio/1.2/types.h>
|
||||
#include <broadcastradio-utils/Utils.h>
|
||||
#include <broadcastradio-utils-1x/Utils.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#include "VirtualRadio.h"
|
||||
|
||||
#include <broadcastradio-utils/Utils.h>
|
||||
#include <broadcastradio-utils-1x/Utils.h>
|
||||
#include <log/log.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
@@ -22,7 +22,6 @@ cc_test {
|
||||
"android.hardware.broadcastradio@1.0",
|
||||
"android.hardware.broadcastradio@1.1",
|
||||
"android.hardware.broadcastradio@1.2",
|
||||
"android.hardware.broadcastradio@common-utils-lib",
|
||||
"android.hardware.broadcastradio@vts-utils-lib",
|
||||
"libgmock",
|
||||
],
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include <android/hardware/broadcastradio/1.2/ITunerCallback.h>
|
||||
#include <android/hardware/broadcastradio/1.2/types.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <broadcastradio-utils/Utils.h>
|
||||
#include <broadcastradio-vts-utils/call-barrier.h>
|
||||
#include <broadcastradio-vts-utils/mock-timeout.h>
|
||||
#include <cutils/native_handle.h>
|
||||
|
||||
46
broadcastradio/2.0/default/Android.bp
Normal file
46
broadcastradio/2.0/default/Android.bp
Normal file
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// Copyright (C) 2017 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
cc_binary {
|
||||
name: "android.hardware.broadcastradio@2.0-service",
|
||||
init_rc: ["android.hardware.broadcastradio@2.0-service.rc"],
|
||||
vendor: true,
|
||||
relative_install_path: "hw",
|
||||
cflags: [
|
||||
"-Wall",
|
||||
"-Wextra",
|
||||
"-Werror",
|
||||
],
|
||||
srcs: [
|
||||
"BroadcastRadio.cpp",
|
||||
"TunerSession.cpp",
|
||||
"VirtualProgram.cpp",
|
||||
"VirtualRadio.cpp",
|
||||
"service.cpp"
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.broadcastradio@common-utils-2x-lib",
|
||||
"android.hardware.broadcastradio@common-utils-lib",
|
||||
],
|
||||
shared_libs: [
|
||||
"android.hardware.broadcastradio@2.0",
|
||||
"libbase",
|
||||
"libhidlbase",
|
||||
"libhidltransport",
|
||||
"liblog",
|
||||
"libutils",
|
||||
],
|
||||
}
|
||||
98
broadcastradio/2.0/default/BroadcastRadio.cpp
Normal file
98
broadcastradio/2.0/default/BroadcastRadio.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#define LOG_TAG "BcRadioDef.module"
|
||||
#define LOG_NDEBUG 0
|
||||
|
||||
#include "BroadcastRadio.h"
|
||||
|
||||
#include <log/log.h>
|
||||
|
||||
#include "resources.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace broadcastradio {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
using std::lock_guard;
|
||||
using std::map;
|
||||
using std::mutex;
|
||||
using std::vector;
|
||||
|
||||
static Properties initProperties(const VirtualRadio& virtualRadio) {
|
||||
Properties prop = {};
|
||||
|
||||
prop.maker = "Google";
|
||||
prop.product = virtualRadio.getName();
|
||||
prop.supportedIdentifierTypes = hidl_vec<uint32_t>({
|
||||
static_cast<uint32_t>(IdentifierType::AMFM_FREQUENCY),
|
||||
static_cast<uint32_t>(IdentifierType::RDS_PI),
|
||||
static_cast<uint32_t>(IdentifierType::HD_STATION_ID_EXT),
|
||||
});
|
||||
prop.vendorInfo = hidl_vec<VendorKeyValue>({
|
||||
{"com.google.dummy", "dummy"},
|
||||
});
|
||||
|
||||
return prop;
|
||||
}
|
||||
|
||||
BroadcastRadio::BroadcastRadio(const VirtualRadio& virtualRadio)
|
||||
: mVirtualRadio(virtualRadio), mProperties(initProperties(virtualRadio)) {}
|
||||
|
||||
Return<void> BroadcastRadio::getProperties(getProperties_cb _hidl_cb) {
|
||||
ALOGV("%s", __func__);
|
||||
_hidl_cb(mProperties);
|
||||
return {};
|
||||
}
|
||||
|
||||
Return<void> BroadcastRadio::openSession(const sp<ITunerCallback>& callback,
|
||||
openSession_cb _hidl_cb) {
|
||||
ALOGV("%s", __func__);
|
||||
lock_guard<mutex> lk(mMut);
|
||||
|
||||
auto oldSession = mSession.promote();
|
||||
if (oldSession != nullptr) {
|
||||
ALOGI("Closing previously opened tuner");
|
||||
oldSession->close();
|
||||
mSession = nullptr;
|
||||
}
|
||||
|
||||
sp<TunerSession> newSession = new TunerSession(*this, callback);
|
||||
mSession = newSession;
|
||||
|
||||
_hidl_cb(Result::OK, newSession);
|
||||
return {};
|
||||
}
|
||||
|
||||
Return<void> BroadcastRadio::getImage(uint32_t id, getImage_cb _hidl_cb) {
|
||||
ALOGV("%s(%x)", __func__, id);
|
||||
|
||||
if (id == resources::demoPngId) {
|
||||
_hidl_cb(std::vector<uint8_t>(resources::demoPng, std::end(resources::demoPng)));
|
||||
return {};
|
||||
}
|
||||
|
||||
ALOGI("Image %x doesn't exists", id);
|
||||
_hidl_cb({});
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace broadcastradio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
52
broadcastradio/2.0/default/BroadcastRadio.h
Normal file
52
broadcastradio/2.0/default/BroadcastRadio.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef ANDROID_HARDWARE_BROADCASTRADIO_V2_0_BROADCASTRADIO_H
|
||||
#define ANDROID_HARDWARE_BROADCASTRADIO_V2_0_BROADCASTRADIO_H
|
||||
|
||||
#include "TunerSession.h"
|
||||
|
||||
#include <android/hardware/broadcastradio/2.0/IBroadcastRadio.h>
|
||||
#include <android/hardware/broadcastradio/2.0/types.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace broadcastradio {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
struct BroadcastRadio : public IBroadcastRadio {
|
||||
BroadcastRadio(const VirtualRadio& virtualRadio);
|
||||
|
||||
// V2_0::IBroadcastRadio methods
|
||||
Return<void> getProperties(getProperties_cb _hidl_cb) override;
|
||||
Return<void> openSession(const sp<ITunerCallback>& callback, openSession_cb _hidl_cb) override;
|
||||
Return<void> getImage(uint32_t id, getImage_cb _hidl_cb);
|
||||
|
||||
std::reference_wrapper<const VirtualRadio> mVirtualRadio;
|
||||
Properties mProperties;
|
||||
|
||||
private:
|
||||
std::mutex mMut;
|
||||
wp<TunerSession> mSession;
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace broadcastradio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_HARDWARE_BROADCASTRADIO_V2_0_BROADCASTRADIO_H
|
||||
238
broadcastradio/2.0/default/TunerSession.cpp
Normal file
238
broadcastradio/2.0/default/TunerSession.cpp
Normal file
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "BcRadioDef.tuner"
|
||||
#define LOG_NDEBUG 0
|
||||
|
||||
#include "TunerSession.h"
|
||||
|
||||
#include "BroadcastRadio.h"
|
||||
|
||||
#include <broadcastradio-utils-2x/Utils.h>
|
||||
#include <log/log.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace broadcastradio {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
using utils::tunesTo;
|
||||
|
||||
using std::lock_guard;
|
||||
using std::move;
|
||||
using std::mutex;
|
||||
using std::sort;
|
||||
using std::vector;
|
||||
|
||||
namespace delay {
|
||||
|
||||
static constexpr auto scan = 200ms;
|
||||
static constexpr auto step = 100ms;
|
||||
static constexpr auto tune = 150ms;
|
||||
|
||||
} // namespace delay
|
||||
|
||||
TunerSession::TunerSession(BroadcastRadio& module, const sp<ITunerCallback>& callback)
|
||||
: mCallback(callback), mModule(module) {}
|
||||
|
||||
// makes ProgramInfo that points to no program
|
||||
static ProgramInfo makeDummyProgramInfo(const ProgramSelector& selector) {
|
||||
ProgramInfo info = {};
|
||||
info.selector = selector;
|
||||
return info;
|
||||
}
|
||||
|
||||
void TunerSession::tuneInternalLocked(const ProgramSelector& sel) {
|
||||
VirtualProgram virtualProgram;
|
||||
ProgramInfo programInfo;
|
||||
if (virtualRadio().getProgram(sel, virtualProgram)) {
|
||||
mCurrentProgram = virtualProgram.selector;
|
||||
programInfo = virtualProgram;
|
||||
} else {
|
||||
mCurrentProgram = sel;
|
||||
programInfo = makeDummyProgramInfo(sel);
|
||||
}
|
||||
mIsTuneCompleted = true;
|
||||
|
||||
mCallback->onCurrentProgramInfoChanged(programInfo);
|
||||
}
|
||||
|
||||
const VirtualRadio& TunerSession::virtualRadio() const {
|
||||
return mModule.get().mVirtualRadio;
|
||||
}
|
||||
|
||||
Return<Result> TunerSession::tune(const ProgramSelector& sel) {
|
||||
ALOGV("%s(%s)", __func__, toString(sel).c_str());
|
||||
lock_guard<mutex> lk(mMut);
|
||||
if (mIsClosed) return Result::INVALID_STATE;
|
||||
|
||||
if (!utils::isSupported(mModule.get().mProperties, sel)) {
|
||||
ALOGW("Selector not supported");
|
||||
return Result::NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (!utils::isValid(sel)) {
|
||||
ALOGE("ProgramSelector is not valid");
|
||||
return Result::INVALID_ARGUMENTS;
|
||||
}
|
||||
|
||||
mIsTuneCompleted = false;
|
||||
auto task = [this, sel]() {
|
||||
lock_guard<mutex> lk(mMut);
|
||||
tuneInternalLocked(sel);
|
||||
};
|
||||
mThread.schedule(task, delay::tune);
|
||||
|
||||
return Result::OK;
|
||||
}
|
||||
|
||||
Return<Result> TunerSession::scan(bool directionUp, bool /* skipSubChannel */) {
|
||||
ALOGV("%s", __func__);
|
||||
lock_guard<mutex> lk(mMut);
|
||||
if (mIsClosed) return Result::INVALID_STATE;
|
||||
|
||||
auto list = virtualRadio().getProgramList();
|
||||
|
||||
if (list.empty()) {
|
||||
mIsTuneCompleted = false;
|
||||
auto task = [this, directionUp]() {
|
||||
ALOGI("Performing failed scan up=%d", directionUp);
|
||||
|
||||
mCallback->onTuneFailed(Result::TIMEOUT, {});
|
||||
};
|
||||
mThread.schedule(task, delay::scan);
|
||||
|
||||
return Result::OK;
|
||||
}
|
||||
|
||||
// Not optimal (O(sort) instead of O(n)), but not a big deal here;
|
||||
// also, it's likely that list is already sorted (so O(n) anyway).
|
||||
sort(list.begin(), list.end());
|
||||
auto current = mCurrentProgram;
|
||||
auto found = lower_bound(list.begin(), list.end(), VirtualProgram({current}));
|
||||
if (directionUp) {
|
||||
if (found < list.end() - 1) {
|
||||
if (tunesTo(current, found->selector)) found++;
|
||||
} else {
|
||||
found = list.begin();
|
||||
}
|
||||
} else {
|
||||
if (found > list.begin() && found != list.end()) {
|
||||
found--;
|
||||
} else {
|
||||
found = list.end() - 1;
|
||||
}
|
||||
}
|
||||
auto tuneTo = found->selector;
|
||||
|
||||
mIsTuneCompleted = false;
|
||||
auto task = [this, tuneTo, directionUp]() {
|
||||
ALOGI("Performing scan up=%d", directionUp);
|
||||
|
||||
lock_guard<mutex> lk(mMut);
|
||||
tuneInternalLocked(tuneTo);
|
||||
};
|
||||
mThread.schedule(task, delay::scan);
|
||||
|
||||
return Result::OK;
|
||||
}
|
||||
|
||||
Return<Result> TunerSession::step(bool directionUp) {
|
||||
ALOGV("%s", __func__);
|
||||
lock_guard<mutex> lk(mMut);
|
||||
if (mIsClosed) return Result::INVALID_STATE;
|
||||
|
||||
if (!utils::hasId(mCurrentProgram, IdentifierType::AMFM_FREQUENCY)) {
|
||||
ALOGE("Can't step in anything else than AM/FM");
|
||||
return Result::NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
mIsTuneCompleted = false;
|
||||
|
||||
auto stepTo = utils::getId(mCurrentProgram, IdentifierType::AMFM_FREQUENCY);
|
||||
#if 0
|
||||
// TODO(b/69958423): handle regions
|
||||
if (directionUp) {
|
||||
stepTo += mAmfmConfig.spacings[0];
|
||||
} else {
|
||||
stepTo -= mAmfmConfig.spacings[0];
|
||||
}
|
||||
|
||||
if (stepTo > mAmfmConfig.upperLimit) stepTo = mAmfmConfig.lowerLimit;
|
||||
if (stepTo < mAmfmConfig.lowerLimit) stepTo = mAmfmConfig.upperLimit;
|
||||
#else
|
||||
if (directionUp) {
|
||||
stepTo += 100;
|
||||
} else {
|
||||
stepTo -= 100;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto task = [this, stepTo]() {
|
||||
ALOGI("Performing step to %lu", stepTo);
|
||||
|
||||
lock_guard<mutex> lk(mMut);
|
||||
|
||||
tuneInternalLocked(utils::make_selector_amfm(stepTo));
|
||||
};
|
||||
mThread.schedule(task, delay::step);
|
||||
|
||||
return Result::OK;
|
||||
}
|
||||
|
||||
Return<void> TunerSession::cancel() {
|
||||
ALOGV("%s", __func__);
|
||||
lock_guard<mutex> lk(mMut);
|
||||
if (mIsClosed) return {};
|
||||
|
||||
mThread.cancelAll();
|
||||
return {};
|
||||
}
|
||||
|
||||
Return<void> TunerSession::setParameters(const hidl_vec<VendorKeyValue>& /* parameters */,
|
||||
setParameters_cb _hidl_cb) {
|
||||
ALOGV("%s", __func__);
|
||||
|
||||
_hidl_cb({});
|
||||
return {};
|
||||
}
|
||||
|
||||
Return<void> TunerSession::getParameters(const hidl_vec<hidl_string>& /* keys */,
|
||||
getParameters_cb _hidl_cb) {
|
||||
ALOGV("%s", __func__);
|
||||
|
||||
_hidl_cb({});
|
||||
return {};
|
||||
}
|
||||
|
||||
Return<void> TunerSession::close() {
|
||||
ALOGV("%s", __func__);
|
||||
lock_guard<mutex> lk(mMut);
|
||||
if (mIsClosed) return {};
|
||||
|
||||
mIsClosed = true;
|
||||
mThread.cancelAll();
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace broadcastradio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
68
broadcastradio/2.0/default/TunerSession.h
Normal file
68
broadcastradio/2.0/default/TunerSession.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef ANDROID_HARDWARE_BROADCASTRADIO_V2_0_TUNER_H
|
||||
#define ANDROID_HARDWARE_BROADCASTRADIO_V2_0_TUNER_H
|
||||
|
||||
#include "VirtualRadio.h"
|
||||
|
||||
#include <android/hardware/broadcastradio/2.0/ITunerCallback.h>
|
||||
#include <android/hardware/broadcastradio/2.0/ITunerSession.h>
|
||||
#include <broadcastradio-utils/WorkerThread.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace broadcastradio {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
struct BroadcastRadio;
|
||||
|
||||
struct TunerSession : public ITunerSession {
|
||||
TunerSession(BroadcastRadio& module, const sp<ITunerCallback>& callback);
|
||||
|
||||
// V2_0::ITunerSession methods
|
||||
virtual Return<Result> tune(const ProgramSelector& program) override;
|
||||
virtual Return<Result> scan(bool directionUp, bool skipSubChannel) override;
|
||||
virtual Return<Result> step(bool directionUp) override;
|
||||
virtual Return<void> cancel() override;
|
||||
virtual Return<void> setParameters(const hidl_vec<VendorKeyValue>& parameters,
|
||||
setParameters_cb _hidl_cb) override;
|
||||
virtual Return<void> getParameters(const hidl_vec<hidl_string>& keys,
|
||||
getParameters_cb _hidl_cb) override;
|
||||
virtual Return<void> close() override;
|
||||
|
||||
private:
|
||||
std::mutex mMut;
|
||||
WorkerThread mThread;
|
||||
bool mIsClosed = false;
|
||||
|
||||
const sp<ITunerCallback> mCallback;
|
||||
|
||||
std::reference_wrapper<BroadcastRadio> mModule;
|
||||
bool mIsTuneCompleted = false;
|
||||
ProgramSelector mCurrentProgram = {};
|
||||
|
||||
void tuneInternalLocked(const ProgramSelector& sel);
|
||||
const VirtualRadio& virtualRadio() const;
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace broadcastradio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_HARDWARE_BROADCASTRADIO_V2_0_TUNER_H
|
||||
76
broadcastradio/2.0/default/VirtualProgram.cpp
Normal file
76
broadcastradio/2.0/default/VirtualProgram.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "VirtualProgram.h"
|
||||
|
||||
#include "resources.h"
|
||||
|
||||
#include <broadcastradio-utils-2x/Utils.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace broadcastradio {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
using utils::getType;
|
||||
using utils::make_metadata;
|
||||
|
||||
using std::vector;
|
||||
|
||||
VirtualProgram::operator ProgramInfo() const {
|
||||
ProgramInfo info = {};
|
||||
|
||||
info.selector = selector;
|
||||
|
||||
auto pType = getType(selector.primaryId);
|
||||
auto isDigital = (pType != IdentifierType::AMFM_FREQUENCY && pType != IdentifierType::RDS_PI);
|
||||
|
||||
info.infoFlags |= ProgramInfoFlags::TUNED;
|
||||
info.infoFlags |= ProgramInfoFlags::STEREO;
|
||||
info.signalQuality = isDigital ? 100 : 80;
|
||||
|
||||
info.metadata = hidl_vec<Metadata>({
|
||||
make_metadata(MetadataKey::RDS_PS, programName),
|
||||
make_metadata(MetadataKey::SONG_TITLE, songTitle),
|
||||
make_metadata(MetadataKey::SONG_ARTIST, songArtist),
|
||||
make_metadata(MetadataKey::STATION_ICON, resources::demoPngId),
|
||||
make_metadata(MetadataKey::ALBUM_ART, resources::demoPngId),
|
||||
});
|
||||
|
||||
info.vendorInfo = hidl_vec<VendorKeyValue>({
|
||||
{"com.google.dummy", "dummy"},
|
||||
{"com.google.dummy.VirtualProgram", std::to_string(reinterpret_cast<uintptr_t>(this))},
|
||||
});
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
bool operator<(const VirtualProgram& lhs, const VirtualProgram& rhs) {
|
||||
auto& l = lhs.selector;
|
||||
auto& r = rhs.selector;
|
||||
|
||||
// Two programs with the same primaryId are considered the same.
|
||||
if (l.primaryId.type != r.primaryId.type) return l.primaryId.type < r.primaryId.type;
|
||||
if (l.primaryId.value != r.primaryId.value) return l.primaryId.value < r.primaryId.value;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace broadcastradio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
57
broadcastradio/2.0/default/VirtualProgram.h
Normal file
57
broadcastradio/2.0/default/VirtualProgram.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef ANDROID_HARDWARE_BROADCASTRADIO_V2_0_VIRTUALPROGRAM_H
|
||||
#define ANDROID_HARDWARE_BROADCASTRADIO_V2_0_VIRTUALPROGRAM_H
|
||||
|
||||
#include <android/hardware/broadcastradio/2.0/types.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace broadcastradio {
|
||||
namespace V2_0 {
|
||||
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;
|
||||
|
||||
std::string programName = "";
|
||||
std::string songArtist = "";
|
||||
std::string songTitle = "";
|
||||
|
||||
operator ProgramInfo() const;
|
||||
|
||||
/**
|
||||
* Defines order on how virtual programs appear on the "air" with
|
||||
* ITunerSession::scan operation.
|
||||
*
|
||||
* It's for default implementation purposes, may not be complete or correct.
|
||||
*/
|
||||
friend bool operator<(const VirtualProgram& lhs, const VirtualProgram& rhs);
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace broadcastradio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_HARDWARE_BROADCASTRADIO_V2_0_VIRTUALPROGRAM_H
|
||||
75
broadcastradio/2.0/default/VirtualRadio.cpp
Normal file
75
broadcastradio/2.0/default/VirtualRadio.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#define LOG_TAG "BcRadioDef.VirtualRadio"
|
||||
//#define LOG_NDEBUG 0
|
||||
|
||||
#include "VirtualRadio.h"
|
||||
|
||||
#include <broadcastradio-utils-2x/Utils.h>
|
||||
#include <log/log.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace broadcastradio {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
using std::lock_guard;
|
||||
using std::move;
|
||||
using std::mutex;
|
||||
using std::vector;
|
||||
using utils::make_selector_amfm;
|
||||
|
||||
VirtualRadio gAmFmRadio(
|
||||
"AM/FM radio mock",
|
||||
{
|
||||
{make_selector_amfm(94900), "Wild 94.9", "Drake ft. Rihanna", "Too Good"},
|
||||
{make_selector_amfm(96500), "KOIT", "Celine Dion", "All By Myself"},
|
||||
{make_selector_amfm(97300), "Alice@97.3", "Drops of Jupiter", "Train"},
|
||||
{make_selector_amfm(99700), "99.7 Now!", "The Chainsmokers", "Closer"},
|
||||
{make_selector_amfm(101300), "101-3 KISS-FM", "Justin Timberlake", "Rock Your Body"},
|
||||
{make_selector_amfm(103700), "iHeart80s @ 103.7", "Michael Jackson", "Billie Jean"},
|
||||
{make_selector_amfm(106100), "106 KMEL", "Drake", "Marvins Room"},
|
||||
});
|
||||
|
||||
VirtualRadio::VirtualRadio(const std::string& name, const vector<VirtualProgram>& initialList)
|
||||
: mName(name), mPrograms(initialList) {}
|
||||
|
||||
std::string VirtualRadio::getName() const {
|
||||
return mName;
|
||||
}
|
||||
|
||||
vector<VirtualProgram> VirtualRadio::getProgramList() const {
|
||||
lock_guard<mutex> lk(mMut);
|
||||
return mPrograms;
|
||||
}
|
||||
|
||||
bool VirtualRadio::getProgram(const ProgramSelector& selector, VirtualProgram& programOut) const {
|
||||
lock_guard<mutex> lk(mMut);
|
||||
for (auto&& program : mPrograms) {
|
||||
if (utils::tunesTo(selector, program.selector)) {
|
||||
programOut = program;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace broadcastradio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
61
broadcastradio/2.0/default/VirtualRadio.h
Normal file
61
broadcastradio/2.0/default/VirtualRadio.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef ANDROID_HARDWARE_BROADCASTRADIO_V2_0_VIRTUALRADIO_H
|
||||
#define ANDROID_HARDWARE_BROADCASTRADIO_V2_0_VIRTUALRADIO_H
|
||||
|
||||
#include "VirtualProgram.h"
|
||||
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace broadcastradio {
|
||||
namespace V2_0 {
|
||||
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(const std::string& name, const std::vector<VirtualProgram>& initialList);
|
||||
|
||||
std::string getName() const;
|
||||
std::vector<VirtualProgram> getProgramList() const;
|
||||
bool getProgram(const ProgramSelector& selector, VirtualProgram& program) const;
|
||||
|
||||
private:
|
||||
mutable std::mutex mMut;
|
||||
std::string mName;
|
||||
std::vector<VirtualProgram> mPrograms;
|
||||
};
|
||||
|
||||
/** AM/FM virtual radio space. */
|
||||
extern VirtualRadio gAmFmRadio;
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace broadcastradio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_HARDWARE_BROADCASTRADIO_V2_0_VIRTUALRADIO_H
|
||||
@@ -0,0 +1,4 @@
|
||||
service broadcastradio-hal2 /vendor/bin/hw/android.hardware.broadcastradio@2.0-service
|
||||
class hal
|
||||
user audioserver
|
||||
group audio
|
||||
46
broadcastradio/2.0/default/resources.h
Normal file
46
broadcastradio/2.0/default/resources.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef ANDROID_HARDWARE_BROADCASTRADIO_V2_0_RESOURCES_H
|
||||
#define ANDROID_HARDWARE_BROADCASTRADIO_V2_0_RESOURCES_H
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace broadcastradio {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
namespace resources {
|
||||
|
||||
constexpr int32_t demoPngId = 123456;
|
||||
constexpr uint8_t demoPng[] = {
|
||||
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44,
|
||||
0x52, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x02, 0x00, 0x00, 0x00, 0x25,
|
||||
0x0b, 0xe6, 0x89, 0x00, 0x00, 0x00, 0x5d, 0x49, 0x44, 0x41, 0x54, 0x68, 0xde, 0xed, 0xd9,
|
||||
0xc1, 0x09, 0x00, 0x30, 0x08, 0x04, 0xc1, 0x33, 0xfd, 0xf7, 0x6c, 0x6a, 0xc8, 0x23, 0x04,
|
||||
0xc9, 0x6c, 0x01, 0xc2, 0x20, 0xbe, 0x4c, 0x86, 0x57, 0x49, 0xba, 0xfb, 0xd6, 0xf4, 0xba,
|
||||
0x3e, 0x7f, 0x4d, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x8f, 0x00, 0xbd, 0xce, 0x7f,
|
||||
0xc0, 0x11, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xb8, 0x0d, 0x32, 0xd4, 0x0c, 0x77, 0xbd,
|
||||
0xfb, 0xc1, 0xce, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82};
|
||||
|
||||
} // namespace resources
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace broadcastradio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_HARDWARE_BROADCASTRADIO_V2_0_RESOURCES_H
|
||||
38
broadcastradio/2.0/default/service.cpp
Normal file
38
broadcastradio/2.0/default/service.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#define LOG_TAG "BcRadioDef.service"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <hidl/HidlTransportSupport.h>
|
||||
|
||||
#include "BroadcastRadio.h"
|
||||
#include "VirtualRadio.h"
|
||||
|
||||
using android::hardware::configureRpcThreadpool;
|
||||
using android::hardware::joinRpcThreadpool;
|
||||
using android::hardware::broadcastradio::V2_0::implementation::BroadcastRadio;
|
||||
using android::hardware::broadcastradio::V2_0::implementation::gAmFmRadio;
|
||||
|
||||
int main(int /* argc */, char** /* argv */) {
|
||||
configureRpcThreadpool(4, true);
|
||||
|
||||
BroadcastRadio broadcastRadio(gAmFmRadio);
|
||||
auto status = broadcastRadio.registerAsService();
|
||||
CHECK_EQ(status, android::OK) << "Failed to register Broadcast Radio HAL implementation";
|
||||
|
||||
joinRpcThreadpool();
|
||||
return 1; // joinRpcThreadpool shouldn't exit
|
||||
}
|
||||
@@ -1,7 +1,3 @@
|
||||
# Automotive team
|
||||
egranata@google.com
|
||||
twasilczyk@google.com
|
||||
|
||||
# VTS team
|
||||
yuexima@google.com
|
||||
yim@google.com
|
||||
@@ -26,4 +26,25 @@ cc_test {
|
||||
"WorkerThread_test.cpp",
|
||||
],
|
||||
static_libs: ["android.hardware.broadcastradio@common-utils-lib"],
|
||||
}
|
||||
}
|
||||
|
||||
cc_test {
|
||||
name: "android.hardware.broadcastradio@common-utils-xx-tests",
|
||||
vendor: true,
|
||||
cflags: [
|
||||
"-Wall",
|
||||
"-Wextra",
|
||||
"-Werror",
|
||||
],
|
||||
srcs: [
|
||||
"CommonXX_test.cpp",
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.broadcastradio@common-utils-1x-lib",
|
||||
"android.hardware.broadcastradio@common-utils-2x-lib",
|
||||
],
|
||||
shared_libs: [
|
||||
"android.hardware.broadcastradio@1.2",
|
||||
"android.hardware.broadcastradio@2.0",
|
||||
],
|
||||
}
|
||||
|
||||
18
broadcastradio/common/tests/CommonXX_test.cpp
Normal file
18
broadcastradio/common/tests/CommonXX_test.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <broadcastradio-utils-1x/Utils.h>
|
||||
#include <broadcastradio-utils-2x/Utils.h>
|
||||
@@ -24,11 +24,7 @@ cc_library_static {
|
||||
"-Werror",
|
||||
],
|
||||
srcs: [
|
||||
"Utils.cpp",
|
||||
"WorkerThread.cpp",
|
||||
],
|
||||
export_include_dirs: ["include"],
|
||||
shared_libs: [
|
||||
"android.hardware.broadcastradio@1.2",
|
||||
],
|
||||
}
|
||||
|
||||
33
broadcastradio/common/utils1x/Android.bp
Normal file
33
broadcastradio/common/utils1x/Android.bp
Normal file
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// Copyright (C) 2017 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
cc_library_static {
|
||||
name: "android.hardware.broadcastradio@common-utils-1x-lib",
|
||||
vendor_available: true,
|
||||
relative_install_path: "hw",
|
||||
cflags: [
|
||||
"-Wall",
|
||||
"-Wextra",
|
||||
"-Werror",
|
||||
],
|
||||
srcs: [
|
||||
"Utils.cpp",
|
||||
],
|
||||
export_include_dirs: ["include"],
|
||||
shared_libs: [
|
||||
"android.hardware.broadcastradio@1.2",
|
||||
],
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
#define LOG_TAG "BroadcastRadioDefault.utils"
|
||||
//#define LOG_NDEBUG 0
|
||||
|
||||
#include <broadcastradio-utils/Utils.h>
|
||||
#include <broadcastradio-utils-1x/Utils.h>
|
||||
|
||||
#include <log/log.h>
|
||||
|
||||
@@ -59,9 +59,7 @@ static bool haveEqualIds(const ProgramSelector& a, const ProgramSelector& b,
|
||||
/* We should check all Ids of a given type (ie. other AF),
|
||||
* but it doesn't matter for default implementation.
|
||||
*/
|
||||
auto aId = getId(a, type);
|
||||
auto bId = getId(b, type);
|
||||
return aId == bId;
|
||||
return getId(a, type) == getId(b, type);
|
||||
}
|
||||
|
||||
bool tunesTo(const ProgramSelector& a, const ProgramSelector& b) {
|
||||
@@ -242,14 +240,16 @@ bool isDigital(const ProgramSelector& sel) {
|
||||
namespace V1_0 {
|
||||
|
||||
bool operator==(const BandConfig& l, const BandConfig& r) {
|
||||
using namespace utils;
|
||||
|
||||
if (l.type != r.type) return false;
|
||||
if (l.antennaConnected != r.antennaConnected) return false;
|
||||
if (l.lowerLimit != r.lowerLimit) return false;
|
||||
if (l.upperLimit != r.upperLimit) return false;
|
||||
if (l.spacings != r.spacings) return false;
|
||||
if (utils::isAm(l.type)) {
|
||||
if (isAm(l.type)) {
|
||||
return l.ext.am == r.ext.am;
|
||||
} else if (utils::isFm(l.type)) {
|
||||
} else if (isFm(l.type)) {
|
||||
return l.ext.fm == r.ext.fm;
|
||||
} else {
|
||||
ALOGW("Unsupported band config type: %s", toString(l.type).c_str());
|
||||
@@ -13,8 +13,8 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef ANDROID_HARDWARE_BROADCASTRADIO_COMMON_UTILS_H
|
||||
#define ANDROID_HARDWARE_BROADCASTRADIO_COMMON_UTILS_H
|
||||
#ifndef ANDROID_HARDWARE_BROADCASTRADIO_COMMON_UTILS_1X_H
|
||||
#define ANDROID_HARDWARE_BROADCASTRADIO_COMMON_UTILS_1X_H
|
||||
|
||||
#include <android/hardware/broadcastradio/1.2/types.h>
|
||||
#include <chrono>
|
||||
@@ -68,8 +68,8 @@ uint64_t getId(const V1_1::ProgramSelector& sel, const V1_2::IdentifierType type
|
||||
|
||||
V1_1::ProgramSelector make_selector(V1_0::Band band, uint32_t channel, uint32_t subChannel = 0);
|
||||
|
||||
bool getLegacyChannel(const V1_1::ProgramSelector& sel,
|
||||
uint32_t* channelOut, uint32_t* subChannelOut);
|
||||
bool getLegacyChannel(const V1_1::ProgramSelector& sel, uint32_t* channelOut,
|
||||
uint32_t* subChannelOut);
|
||||
|
||||
bool isDigital(const V1_1::ProgramSelector& sel);
|
||||
|
||||
@@ -85,4 +85,4 @@ bool operator==(const BandConfig& l, const BandConfig& r);
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_HARDWARE_BROADCASTRADIO_COMMON_UTILS_H
|
||||
#endif // ANDROID_HARDWARE_BROADCASTRADIO_COMMON_UTILS_1X_H
|
||||
33
broadcastradio/common/utils2x/Android.bp
Normal file
33
broadcastradio/common/utils2x/Android.bp
Normal file
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// Copyright (C) 2017 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
cc_library_static {
|
||||
name: "android.hardware.broadcastradio@common-utils-2x-lib",
|
||||
vendor_available: true,
|
||||
relative_install_path: "hw",
|
||||
cflags: [
|
||||
"-Wall",
|
||||
"-Wextra",
|
||||
"-Werror",
|
||||
],
|
||||
srcs: [
|
||||
"Utils.cpp",
|
||||
],
|
||||
export_include_dirs: ["include"],
|
||||
shared_libs: [
|
||||
"android.hardware.broadcastradio@2.0",
|
||||
],
|
||||
}
|
||||
235
broadcastradio/common/utils2x/Utils.cpp
Normal file
235
broadcastradio/common/utils2x/Utils.cpp
Normal file
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#define LOG_TAG "BcRadioDef.utils"
|
||||
//#define LOG_NDEBUG 0
|
||||
|
||||
#include <broadcastradio-utils-2x/Utils.h>
|
||||
|
||||
#include <log/log.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace broadcastradio {
|
||||
namespace utils {
|
||||
|
||||
using V2_0::IdentifierType;
|
||||
using V2_0::Metadata;
|
||||
using V2_0::MetadataKey;
|
||||
using V2_0::ProgramIdentifier;
|
||||
using V2_0::ProgramSelector;
|
||||
|
||||
using std::string;
|
||||
|
||||
IdentifierType getType(const ProgramIdentifier& id) {
|
||||
return static_cast<IdentifierType>(id.type);
|
||||
}
|
||||
|
||||
static bool bothHaveId(const ProgramSelector& a, const ProgramSelector& b,
|
||||
const IdentifierType type) {
|
||||
return hasId(a, type) && hasId(b, type);
|
||||
}
|
||||
|
||||
static bool haveEqualIds(const ProgramSelector& a, const ProgramSelector& b,
|
||||
const IdentifierType type) {
|
||||
if (!bothHaveId(a, b, type)) return false;
|
||||
/* We should check all Ids of a given type (ie. other AF),
|
||||
* but it doesn't matter for default implementation.
|
||||
*/
|
||||
return getId(a, type) == getId(b, type);
|
||||
}
|
||||
|
||||
static int getHdSubchannel(const ProgramSelector& sel) {
|
||||
auto hdsidext = getId(sel, IdentifierType::HD_STATION_ID_EXT, 0);
|
||||
hdsidext >>= 32; // Station ID number
|
||||
return hdsidext & 0xF; // HD Radio subchannel
|
||||
}
|
||||
|
||||
bool tunesTo(const ProgramSelector& a, const ProgramSelector& b) {
|
||||
auto type = getType(b.primaryId);
|
||||
|
||||
switch (type) {
|
||||
case IdentifierType::HD_STATION_ID_EXT:
|
||||
case IdentifierType::RDS_PI:
|
||||
case IdentifierType::AMFM_FREQUENCY:
|
||||
if (haveEqualIds(a, b, IdentifierType::HD_STATION_ID_EXT)) return true;
|
||||
if (haveEqualIds(a, b, IdentifierType::RDS_PI)) return true;
|
||||
return getHdSubchannel(b) == 0 && haveEqualIds(a, b, IdentifierType::AMFM_FREQUENCY);
|
||||
case IdentifierType::DAB_SID_EXT:
|
||||
return haveEqualIds(a, b, IdentifierType::DAB_SID_EXT);
|
||||
case IdentifierType::DRMO_SERVICE_ID:
|
||||
return haveEqualIds(a, b, IdentifierType::DRMO_SERVICE_ID);
|
||||
case IdentifierType::SXM_SERVICE_ID:
|
||||
return haveEqualIds(a, b, IdentifierType::SXM_SERVICE_ID);
|
||||
default: // includes all vendor types
|
||||
ALOGW("Unsupported program type: %s", toString(type).c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool maybeGetId(const ProgramSelector& sel, const IdentifierType type, uint64_t* val) {
|
||||
auto itype = static_cast<uint32_t>(type);
|
||||
|
||||
if (sel.primaryId.type == itype) {
|
||||
if (val) *val = sel.primaryId.value;
|
||||
return true;
|
||||
}
|
||||
|
||||
// not optimal, but we don't care in default impl
|
||||
for (auto&& id : sel.secondaryIds) {
|
||||
if (id.type == itype) {
|
||||
if (val) *val = id.value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hasId(const ProgramSelector& sel, const IdentifierType type) {
|
||||
return maybeGetId(sel, type, nullptr);
|
||||
}
|
||||
|
||||
uint64_t getId(const ProgramSelector& sel, const IdentifierType type) {
|
||||
uint64_t val;
|
||||
|
||||
if (maybeGetId(sel, type, &val)) {
|
||||
return val;
|
||||
}
|
||||
|
||||
ALOGW("Identifier %s not found", toString(type).c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t getId(const ProgramSelector& sel, const IdentifierType type, uint64_t defval) {
|
||||
if (!hasId(sel, type)) return defval;
|
||||
return getId(sel, type);
|
||||
}
|
||||
|
||||
bool isSupported(const V2_0::Properties& prop, const V2_0::ProgramSelector& sel) {
|
||||
// Not optimal, but it doesn't matter for default impl nor VTS tests.
|
||||
for (auto&& idTypeI : prop.supportedIdentifierTypes) {
|
||||
auto idType = static_cast<IdentifierType>(idTypeI);
|
||||
if (hasId(sel, idType)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool isValid(const ProgramIdentifier& id) {
|
||||
auto val = id.value;
|
||||
bool valid = true;
|
||||
|
||||
auto expect = [&valid](bool condition, std::string message) {
|
||||
if (!condition) {
|
||||
valid = false;
|
||||
ALOGE("Identifier not valid, expected %s", message.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
switch (static_cast<IdentifierType>(id.type)) {
|
||||
case IdentifierType::AMFM_FREQUENCY:
|
||||
case IdentifierType::DAB_FREQUENCY:
|
||||
case IdentifierType::DRMO_FREQUENCY:
|
||||
expect(val > 100u, "f > 100kHz");
|
||||
expect(val < 10000000u, "f < 10GHz");
|
||||
break;
|
||||
case IdentifierType::RDS_PI:
|
||||
expect(val != 0u, "RDS PI != 0");
|
||||
expect(val <= 0xFFFFu, "16bit id");
|
||||
break;
|
||||
case IdentifierType::HD_STATION_ID_EXT: {
|
||||
auto stationId = val & 0xFFFFFFFF; // 32bit
|
||||
val >>= 32;
|
||||
auto subchannel = val & 0xF; // 4bit
|
||||
val >>= 4;
|
||||
auto freq = val & 0x3FFFF; // 18bit
|
||||
expect(stationId != 0u, "HD station id != 0");
|
||||
expect(subchannel < 8u, "HD subch < 8");
|
||||
expect(freq > 100u, "f > 100kHz");
|
||||
expect(freq < 10000000u, "f < 10GHz");
|
||||
break;
|
||||
}
|
||||
case IdentifierType::DAB_SID_EXT: {
|
||||
auto sid = val & 0xFFFF; // 16bit
|
||||
val >>= 16;
|
||||
auto ecc = val & 0xFF; // 8bit
|
||||
expect(sid != 0u, "DAB SId != 0");
|
||||
expect(ecc >= 0xA0u && ecc <= 0xF6u, "Invalid ECC, see ETSI TS 101 756 V2.1.1");
|
||||
break;
|
||||
}
|
||||
case IdentifierType::DAB_ENSEMBLE:
|
||||
expect(val != 0u, "DAB ensemble != 0");
|
||||
expect(val <= 0xFFFFu, "16bit id");
|
||||
break;
|
||||
case IdentifierType::DAB_SCID:
|
||||
expect(val > 0xFu, "12bit SCId (not 4bit SCIdS)");
|
||||
expect(val <= 0xFFFu, "12bit id");
|
||||
break;
|
||||
case IdentifierType::DRMO_SERVICE_ID:
|
||||
expect(val != 0u, "DRM SId != 0");
|
||||
expect(val <= 0xFFFFFFu, "24bit id");
|
||||
break;
|
||||
case IdentifierType::SXM_SERVICE_ID:
|
||||
expect(val != 0u, "SXM SId != 0");
|
||||
expect(val <= 0xFFFFFFFFu, "32bit id");
|
||||
break;
|
||||
case IdentifierType::SXM_CHANNEL:
|
||||
expect(val < 1000u, "SXM channel < 1000");
|
||||
break;
|
||||
case IdentifierType::VENDOR_START:
|
||||
case IdentifierType::VENDOR_END:
|
||||
// skip
|
||||
break;
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
bool isValid(const V2_0::ProgramSelector& sel) {
|
||||
if (!isValid(sel.primaryId)) return false;
|
||||
for (auto&& id : sel.secondaryIds) {
|
||||
if (!isValid(id)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ProgramIdentifier make_identifier(IdentifierType type, uint64_t value) {
|
||||
return {static_cast<uint32_t>(type), value};
|
||||
}
|
||||
|
||||
ProgramSelector make_selector_amfm(uint32_t frequency) {
|
||||
ProgramSelector sel = {};
|
||||
sel.primaryId = make_identifier(IdentifierType::AMFM_FREQUENCY, frequency);
|
||||
return sel;
|
||||
}
|
||||
|
||||
Metadata make_metadata(MetadataKey key, int64_t value) {
|
||||
Metadata meta = {};
|
||||
meta.key = static_cast<uint32_t>(key);
|
||||
meta.intValue = value;
|
||||
return meta;
|
||||
}
|
||||
|
||||
Metadata make_metadata(MetadataKey key, string value) {
|
||||
Metadata meta = {};
|
||||
meta.key = static_cast<uint32_t>(key);
|
||||
meta.stringValue = value;
|
||||
return meta;
|
||||
}
|
||||
|
||||
} // namespace utils
|
||||
} // namespace broadcastradio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef ANDROID_HARDWARE_BROADCASTRADIO_COMMON_UTILS_2X_H
|
||||
#define ANDROID_HARDWARE_BROADCASTRADIO_COMMON_UTILS_2X_H
|
||||
|
||||
#include <android/hardware/broadcastradio/2.0/types.h>
|
||||
#include <chrono>
|
||||
#include <queue>
|
||||
#include <thread>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace broadcastradio {
|
||||
namespace utils {
|
||||
|
||||
V2_0::IdentifierType getType(const V2_0::ProgramIdentifier& id);
|
||||
|
||||
/**
|
||||
* Checks, if {@code pointer} tunes to {@channel}.
|
||||
*
|
||||
* For example, having a channel {AMFM_FREQUENCY = 103.3}:
|
||||
* - selector {AMFM_FREQUENCY = 103.3, HD_SUBCHANNEL = 0} can tune to this channel;
|
||||
* - selector {AMFM_FREQUENCY = 103.3, HD_SUBCHANNEL = 1} can't.
|
||||
*
|
||||
* @param pointer selector we're trying to match against channel.
|
||||
* @param channel existing channel.
|
||||
*/
|
||||
bool tunesTo(const V2_0::ProgramSelector& pointer, const V2_0::ProgramSelector& channel);
|
||||
|
||||
bool hasId(const V2_0::ProgramSelector& sel, const V2_0::IdentifierType type);
|
||||
|
||||
/**
|
||||
* Returns ID (either primary or secondary) for a given program selector.
|
||||
*
|
||||
* If the selector does not contain given type, returns 0 and emits a warning.
|
||||
*/
|
||||
uint64_t getId(const V2_0::ProgramSelector& sel, const V2_0::IdentifierType type);
|
||||
|
||||
/**
|
||||
* Returns ID (either primary or secondary) for a given program selector.
|
||||
*
|
||||
* If the selector does not contain given type, returns default value.
|
||||
*/
|
||||
uint64_t getId(const V2_0::ProgramSelector& sel, const V2_0::IdentifierType type, uint64_t defval);
|
||||
|
||||
/**
|
||||
* Checks, if a given selector is supported by the radio module.
|
||||
*
|
||||
* @param prop Module description.
|
||||
* @param sel The selector to check.
|
||||
* @return True, if the selector is supported, false otherwise.
|
||||
*/
|
||||
bool isSupported(const V2_0::Properties& prop, const V2_0::ProgramSelector& sel);
|
||||
|
||||
bool isValid(const V2_0::ProgramSelector& sel);
|
||||
|
||||
V2_0::ProgramIdentifier make_identifier(V2_0::IdentifierType type, uint64_t value);
|
||||
V2_0::ProgramSelector make_selector_amfm(uint32_t frequency);
|
||||
V2_0::Metadata make_metadata(V2_0::MetadataKey key, int64_t value);
|
||||
V2_0::Metadata make_metadata(V2_0::MetadataKey key, std::string value);
|
||||
|
||||
} // namespace utils
|
||||
} // namespace broadcastradio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_HARDWARE_BROADCASTRADIO_COMMON_UTILS_2X_H
|
||||
@@ -1,7 +0,0 @@
|
||||
# Automotive team
|
||||
egranata@google.com
|
||||
twasilczyk@google.com
|
||||
|
||||
# VTS team
|
||||
yuexima@google.com
|
||||
yim@google.com
|
||||
Reference in New Issue
Block a user