Merge "Implement region guessing." into oc-mr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
d4446b79a3
@@ -131,7 +131,9 @@ public class RadioTunerTest {
|
||||
|
||||
// find FM band and build its config
|
||||
mModule = mModules.get(0);
|
||||
|
||||
for (RadioManager.BandDescriptor band : mModule.getBands()) {
|
||||
Log.d(TAG, "Band: " + band);
|
||||
int bandType = band.getType();
|
||||
if (bandType == RadioManager.BAND_AM || bandType == RadioManager.BAND_AM_HD) {
|
||||
mAmBandDescriptor = (RadioManager.AmBandDescriptor)band;
|
||||
|
||||
@@ -11,6 +11,7 @@ LOCAL_SRC_FILES += \
|
||||
$(LOCAL_REL_DIR)/BroadcastRadio/Tuner.cpp \
|
||||
$(LOCAL_REL_DIR)/BroadcastRadio/TunerCallback.cpp \
|
||||
$(LOCAL_REL_DIR)/BroadcastRadio/convert.cpp \
|
||||
$(LOCAL_REL_DIR)/BroadcastRadio/regions.cpp \
|
||||
$(LOCAL_REL_DIR)/com_android_server_AlarmManagerService.cpp \
|
||||
$(LOCAL_REL_DIR)/com_android_server_am_BatteryStatsService.cpp \
|
||||
$(LOCAL_REL_DIR)/com_android_server_connectivity_Vpn.cpp \
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
#include "convert.h"
|
||||
|
||||
#include "regions.h"
|
||||
|
||||
#include <broadcastradio-utils/Utils.h>
|
||||
#include <core_jni_helpers.h>
|
||||
#include <nativehelper/JNIHelp.h>
|
||||
@@ -29,8 +31,11 @@ namespace server {
|
||||
namespace BroadcastRadio {
|
||||
namespace convert {
|
||||
|
||||
namespace utils = V1_1::utils;
|
||||
|
||||
using hardware::Return;
|
||||
using hardware::hidl_vec;
|
||||
using regions::RegionalBandConfig;
|
||||
|
||||
using V1_0::Band;
|
||||
using V1_0::Deemphasis;
|
||||
@@ -43,6 +48,7 @@ using V1_1::ProgramListResult;
|
||||
using V1_1::ProgramSelector;
|
||||
using V1_1::VendorKeyValue;
|
||||
|
||||
static JavaRef<jobject> BandDescriptorFromHal(JNIEnv *env, const RegionalBandConfig &config);
|
||||
static JavaRef<jobject> BandDescriptorFromHal(JNIEnv *env, const V1_0::BandConfig &config, Region region);
|
||||
|
||||
static struct {
|
||||
@@ -334,9 +340,10 @@ static JavaRef<jobject> ModulePropertiesFromHal(JNIEnv *env, const V1_0::Propert
|
||||
auto jSerial = make_javastr(env, prop10.serial);
|
||||
bool isBgScanSupported = prop11 ? prop11->supportsBackgroundScanning : false;
|
||||
auto jVendorInfo = prop11 ? VendorInfoFromHal(env, prop11->vendorInfo) : nullptr;
|
||||
// ITU_1 is the default region just because its index is 0.
|
||||
auto jBands = ArrayFromHal<V1_0::BandConfig>(env, prop10.bands, gjni.BandDescriptor.clazz,
|
||||
std::bind(BandDescriptorFromHal, _1, _2, Region::ITU_1));
|
||||
|
||||
auto regionalBands = regions::mapRegions(prop10.bands);
|
||||
auto jBands = ArrayFromHal<RegionalBandConfig>(env, regionalBands,
|
||||
gjni.BandDescriptor.clazz, BandDescriptorFromHal);
|
||||
auto jSupportedProgramTypes =
|
||||
prop11 ? ArrayFromHal(env, prop11->supportedProgramTypes) : nullptr;
|
||||
auto jSupportedIdentifierTypes =
|
||||
@@ -359,32 +366,31 @@ JavaRef<jobject> ModulePropertiesFromHal(JNIEnv *env, const V1_1::Properties &pr
|
||||
return ModulePropertiesFromHal(env, properties.base, &properties, moduleId, serviceName);
|
||||
}
|
||||
|
||||
static JavaRef<jobject> BandDescriptorFromHal(JNIEnv *env, const RegionalBandConfig &config) {
|
||||
return BandDescriptorFromHal(env, config.bandConfig, config.region);
|
||||
}
|
||||
|
||||
static JavaRef<jobject> BandDescriptorFromHal(JNIEnv *env, const V1_0::BandConfig &config, Region region) {
|
||||
ALOGV("%s", __func__);
|
||||
|
||||
jint spacing = config.spacings.size() > 0 ? config.spacings[0] : 0;
|
||||
ALOGW_IF(config.spacings.size() > 1, "Multiple spacings - not a regional config");
|
||||
ALOGW_IF(config.spacings.size() == 0, "No channel spacing specified");
|
||||
|
||||
switch (config.type) {
|
||||
case Band::FM:
|
||||
case Band::FM_HD: {
|
||||
auto& fm = config.ext.fm;
|
||||
return make_javaref(env, env->NewObject(
|
||||
gjni.FmBandDescriptor.clazz, gjni.FmBandDescriptor.cstor,
|
||||
region, config.type, config.lowerLimit, config.upperLimit, spacing,
|
||||
fm.stereo, fm.rds != Rds::NONE, fm.ta, fm.af, fm.ea));
|
||||
}
|
||||
case Band::AM:
|
||||
case Band::AM_HD: {
|
||||
auto& am = config.ext.am;
|
||||
return make_javaref(env, env->NewObject(
|
||||
gjni.AmBandDescriptor.clazz, gjni.AmBandDescriptor.cstor,
|
||||
region, config.type, config.lowerLimit, config.upperLimit, spacing,
|
||||
am.stereo));
|
||||
}
|
||||
default:
|
||||
ALOGE("Unsupported band type: %d", config.type);
|
||||
return nullptr;
|
||||
if (utils::isFm(config.type)) {
|
||||
auto& fm = config.ext.fm;
|
||||
return make_javaref(env, env->NewObject(
|
||||
gjni.FmBandDescriptor.clazz, gjni.FmBandDescriptor.cstor,
|
||||
region, config.type, config.lowerLimit, config.upperLimit, spacing,
|
||||
fm.stereo, fm.rds != Rds::NONE, fm.ta, fm.af, fm.ea));
|
||||
} else if (utils::isAm(config.type)) {
|
||||
auto& am = config.ext.am;
|
||||
return make_javaref(env, env->NewObject(
|
||||
gjni.AmBandDescriptor.clazz, gjni.AmBandDescriptor.cstor,
|
||||
region, config.type, config.lowerLimit, config.upperLimit, spacing, am.stereo));
|
||||
} else {
|
||||
ALOGE("Unsupported band type: %d", config.type);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,20 +400,15 @@ JavaRef<jobject> BandConfigFromHal(JNIEnv *env, const V1_0::BandConfig &config,
|
||||
auto descriptor = BandDescriptorFromHal(env, config, region);
|
||||
if (descriptor == nullptr) return nullptr;
|
||||
|
||||
switch (config.type) {
|
||||
case Band::FM:
|
||||
case Band::FM_HD: {
|
||||
return make_javaref(env, env->NewObject(
|
||||
gjni.FmBandConfig.clazz, gjni.FmBandConfig.cstor, descriptor.get()));
|
||||
}
|
||||
case Band::AM:
|
||||
case Band::AM_HD: {
|
||||
return make_javaref(env, env->NewObject(
|
||||
gjni.AmBandConfig.clazz, gjni.AmBandConfig.cstor, descriptor.get()));
|
||||
}
|
||||
default:
|
||||
ALOGE("Unsupported band type: %d", config.type);
|
||||
return nullptr;
|
||||
if (utils::isFm(config.type)) {
|
||||
return make_javaref(env, env->NewObject(
|
||||
gjni.FmBandConfig.clazz, gjni.FmBandConfig.cstor, descriptor.get()));
|
||||
} else if (utils::isAm(config.type)) {
|
||||
return make_javaref(env, env->NewObject(
|
||||
gjni.AmBandConfig.clazz, gjni.AmBandConfig.cstor, descriptor.get()));
|
||||
} else {
|
||||
ALOGE("Unsupported band type: %d", config.type);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -583,7 +584,7 @@ static JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_0::ProgramInfo
|
||||
}
|
||||
|
||||
JavaRef<jobject> ProgramInfoFromHal(JNIEnv *env, const V1_0::ProgramInfo &info, V1_0::Band band) {
|
||||
auto selector = V1_1::utils::make_selector(band, info.channel, info.subChannel);
|
||||
auto selector = utils::make_selector(band, info.channel, info.subChannel);
|
||||
return ProgramInfoFromHal(env, info, nullptr, selector);
|
||||
}
|
||||
|
||||
|
||||
196
services/core/jni/BroadcastRadio/regions.cpp
Normal file
196
services/core/jni/BroadcastRadio/regions.cpp
Normal file
@@ -0,0 +1,196 @@
|
||||
/**
|
||||
* 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 "BroadcastRadioService.regions.jni"
|
||||
#define LOG_NDEBUG 0
|
||||
|
||||
#include "regions.h"
|
||||
|
||||
#include <broadcastradio-utils/Utils.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
namespace android {
|
||||
namespace server {
|
||||
namespace BroadcastRadio {
|
||||
namespace regions {
|
||||
|
||||
namespace utils = hardware::broadcastradio::V1_1::utils;
|
||||
|
||||
using hardware::hidl_vec;
|
||||
|
||||
using V1_0::Band;
|
||||
using V1_0::BandConfig;
|
||||
using V1_0::Deemphasis;
|
||||
using V1_0::Rds;
|
||||
|
||||
class RegionalBandDefinition {
|
||||
public:
|
||||
std::vector<Region> mRegions;
|
||||
std::vector<Band> mTypes;
|
||||
uint32_t mLowerLimit;
|
||||
uint32_t mUpperLimit;
|
||||
uint32_t mSpacing;
|
||||
|
||||
Deemphasis mFmDeemphasis = {};
|
||||
Rds mFmRds = Rds::NONE;
|
||||
|
||||
bool fitsInsideBand(const BandConfig &bandConfig) const;
|
||||
std::vector<RegionalBandConfig> withConfig(BandConfig bandConfig) const;
|
||||
};
|
||||
|
||||
static const RegionalBandDefinition kKnownRegionConfigs[] = {
|
||||
{
|
||||
{ Region::ITU_1 },
|
||||
{ Band::FM },
|
||||
87500,
|
||||
108000,
|
||||
100,
|
||||
Deemphasis::D50,
|
||||
Rds::WORLD,
|
||||
},
|
||||
{
|
||||
{ Region::ITU_2 },
|
||||
{ Band::FM, Band::FM_HD },
|
||||
87900,
|
||||
107900,
|
||||
200,
|
||||
Deemphasis::D75,
|
||||
Rds::US,
|
||||
},
|
||||
{
|
||||
{ Region::OIRT },
|
||||
{ Band::FM },
|
||||
65800,
|
||||
74000,
|
||||
10,
|
||||
Deemphasis::D50,
|
||||
Rds::WORLD,
|
||||
},
|
||||
{
|
||||
{ Region::JAPAN },
|
||||
{ Band::FM },
|
||||
76000,
|
||||
90000,
|
||||
100,
|
||||
Deemphasis::D50,
|
||||
Rds::WORLD,
|
||||
},
|
||||
{
|
||||
{ Region::KOREA },
|
||||
{ Band::FM },
|
||||
87500,
|
||||
108000,
|
||||
100,
|
||||
Deemphasis::D75,
|
||||
Rds::WORLD,
|
||||
},
|
||||
{ // AM LW
|
||||
{ Region::ITU_1, Region::OIRT, Region::JAPAN, Region::KOREA },
|
||||
{ Band::AM },
|
||||
153,
|
||||
279,
|
||||
9,
|
||||
},
|
||||
{ // AM MW
|
||||
{ Region::ITU_1, Region::OIRT, Region::JAPAN, Region::KOREA },
|
||||
{ Band::AM },
|
||||
531,
|
||||
1611,
|
||||
9,
|
||||
},
|
||||
{ // AM SW
|
||||
{ Region::ITU_1, Region::OIRT, Region::JAPAN, Region::KOREA },
|
||||
{ Band::AM },
|
||||
2300,
|
||||
26100,
|
||||
5,
|
||||
},
|
||||
{ // AM LW ITU2
|
||||
{ Region::ITU_2 },
|
||||
{ Band::AM, Band::AM_HD },
|
||||
153,
|
||||
279,
|
||||
9,
|
||||
},
|
||||
{ // AM MW ITU2
|
||||
{ Region::ITU_2 },
|
||||
{ Band::AM, Band::AM_HD },
|
||||
540,
|
||||
1610,
|
||||
10,
|
||||
},
|
||||
{ // AM SW ITU2
|
||||
{ Region::ITU_2 },
|
||||
{ Band::AM, Band::AM_HD },
|
||||
2300,
|
||||
26100,
|
||||
5,
|
||||
},
|
||||
};
|
||||
|
||||
bool RegionalBandDefinition::fitsInsideBand(const BandConfig &bandConfig) const {
|
||||
if (std::find(mTypes.begin(), mTypes.end(), bandConfig.type) == mTypes.end()) return false;
|
||||
if (mLowerLimit < bandConfig.lowerLimit) return false;
|
||||
if (mUpperLimit > bandConfig.upperLimit) return false;
|
||||
auto&& spacings = bandConfig.spacings;
|
||||
if (std::find(spacings.begin(), spacings.end(), mSpacing) == spacings.end()) return false;
|
||||
if (utils::isFm(bandConfig.type)) {
|
||||
if (0 == (mFmDeemphasis & bandConfig.ext.fm.deemphasis)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<RegionalBandConfig> RegionalBandDefinition::withConfig(BandConfig config) const {
|
||||
config.lowerLimit = mLowerLimit;
|
||||
config.upperLimit = mUpperLimit;
|
||||
config.spacings = hidl_vec<uint32_t>({ mSpacing });
|
||||
if (utils::isFm(config.type)) {
|
||||
auto&& fm = config.ext.fm;
|
||||
fm.deemphasis = mFmDeemphasis;
|
||||
fm.rds = static_cast<Rds>(mFmRds & fm.rds);
|
||||
}
|
||||
|
||||
std::vector<RegionalBandConfig> configs;
|
||||
for (auto region : mRegions) {
|
||||
configs.push_back({region, config});
|
||||
}
|
||||
|
||||
return configs;
|
||||
}
|
||||
|
||||
std::vector<RegionalBandConfig> mapRegions(const hidl_vec<BandConfig>& bands) {
|
||||
ALOGV("%s", __func__);
|
||||
|
||||
std::vector<RegionalBandConfig> out;
|
||||
|
||||
for (auto&& regionalBand : kKnownRegionConfigs) {
|
||||
for (auto&& tunerBand : bands) {
|
||||
if (regionalBand.fitsInsideBand(tunerBand)) {
|
||||
auto mapped = regionalBand.withConfig(tunerBand);
|
||||
out.insert(out.end(), mapped.begin(), mapped.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ALOGI("Mapped %zu tuner bands to %zu regional bands", bands.size(), out.size());
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace regions
|
||||
} // namespace BroadcastRadio
|
||||
} // namespace server
|
||||
} // namespace android
|
||||
44
services/core/jni/BroadcastRadio/regions.h
Normal file
44
services/core/jni/BroadcastRadio/regions.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* 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_SERVER_BROADCASTRADIO_REGIONS_H
|
||||
#define _ANDROID_SERVER_BROADCASTRADIO_REGIONS_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#include <android/hardware/broadcastradio/1.1/types.h>
|
||||
|
||||
namespace android {
|
||||
namespace server {
|
||||
namespace BroadcastRadio {
|
||||
namespace regions {
|
||||
|
||||
namespace V1_0 = hardware::broadcastradio::V1_0;
|
||||
|
||||
struct RegionalBandConfig {
|
||||
Region region;
|
||||
V1_0::BandConfig bandConfig;
|
||||
};
|
||||
|
||||
std::vector<RegionalBandConfig>
|
||||
mapRegions(const hardware::hidl_vec<V1_0::BandConfig>& bands);
|
||||
|
||||
} // namespace regions
|
||||
} // namespace BroadcastRadio
|
||||
} // namespace server
|
||||
} // namespace android
|
||||
|
||||
#endif // _ANDROID_SERVER_BROADCASTRADIO_REGIONS_H
|
||||
Reference in New Issue
Block a user