Merge "Implement region guessing." into oc-mr1-dev

This commit is contained in:
Tomasz Wasilczyk
2017-08-12 00:16:01 +00:00
committed by Android (Google) Code Review
5 changed files with 282 additions and 38 deletions

View File

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

View File

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

View File

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

View 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

View 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