blob: 2933aa7dd5d50c17efcb569783081a47d946825d [file] [log] [blame]
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -08001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Tomasz Wasilczyk48377552017-06-22 10:45:33 -070016#define LOG_TAG "BroadcastRadioDefault.module"
17#define LOG_NDEBUG 0
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -080018
19#include "BroadcastRadio.h"
Tomasz Wasilczyk48377552017-06-22 10:45:33 -070020
21#include <log/log.h>
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -080022
Tomasz Wasilczykba3e2542017-07-17 13:59:21 -070023#include "resources.h"
24
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -080025namespace android {
26namespace hardware {
27namespace broadcastradio {
Tomasz Wasilczyk8c34c812018-02-08 13:42:31 -080028namespace V1_1 {
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -080029namespace implementation {
30
Tomasz Wasilczyk48377552017-06-22 10:45:33 -070031using V1_0::Band;
32using V1_0::BandConfig;
33using V1_0::Class;
34using V1_0::Deemphasis;
35using V1_0::Rds;
Tomasz Wasilczykf679e8b2017-09-14 09:43:35 -070036using V1_1::IdentifierType;
37using V1_1::ProgramSelector;
38using V1_1::ProgramType;
39using V1_1::Properties;
40using V1_1::VendorKeyValue;
Tomasz Wasilczyk48377552017-06-22 10:45:33 -070041
42using std::lock_guard;
43using std::map;
44using std::mutex;
45using std::vector;
46
47// clang-format off
48static const map<Class, ModuleConfig> gModuleConfigs{
49 {Class::AM_FM, ModuleConfig({
50 "Digital radio mock",
51 { // amFmBands
52 AmFmBandConfig({
Tomasz Wasilczyk701a5bd2017-08-10 12:32:45 -070053 Band::AM,
54 153, // lowerLimit
55 26100, // upperLimit
56 {5, 9, 10}, // spacings
57 }),
58 AmFmBandConfig({
59 Band::FM,
60 65800, // lowerLimit
61 108000, // upperLimit
62 {10, 100, 200}, // spacings
63 }),
64 AmFmBandConfig({
Tomasz Wasilczyk48377552017-06-22 10:45:33 -070065 Band::AM_HD,
Tomasz Wasilczyk701a5bd2017-08-10 12:32:45 -070066 153, // lowerLimit
67 26100, // upperLimit
68 {5, 9, 10}, // spacings
Tomasz Wasilczyk48377552017-06-22 10:45:33 -070069 }),
70 AmFmBandConfig({
71 Band::FM_HD,
Tomasz Wasilczykab70ddf2017-09-12 11:36:06 -070072 87700, // lowerLimit
Tomasz Wasilczyk48377552017-06-22 10:45:33 -070073 107900, // upperLimit
Tomasz Wasilczyk701a5bd2017-08-10 12:32:45 -070074 {200}, // spacings
Tomasz Wasilczyk48377552017-06-22 10:45:33 -070075 }),
76 },
77 })},
78
79 {Class::SAT, ModuleConfig({
80 "Satellite radio mock",
81 {}, // amFmBands
82 })},
83};
84// clang-format on
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -080085
86BroadcastRadio::BroadcastRadio(Class classId)
Tomasz Wasilczyk48377552017-06-22 10:45:33 -070087 : mClassId(classId), mConfig(gModuleConfigs.at(classId)) {}
88
89bool BroadcastRadio::isSupported(Class classId) {
90 return gModuleConfigs.find(classId) != gModuleConfigs.end();
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -080091}
92
Tomasz Wasilczyk48377552017-06-22 10:45:33 -070093Return<void> BroadcastRadio::getProperties(getProperties_cb _hidl_cb) {
94 ALOGV("%s", __func__);
95 return getProperties_1_1(
96 [&](const Properties& properties) { _hidl_cb(Result::OK, properties.base); });
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -080097}
98
Tomasz Wasilczyk02b9cba2017-06-13 09:34:30 -070099Return<void> BroadcastRadio::getProperties_1_1(getProperties_1_1_cb _hidl_cb) {
Tomasz Wasilczyk48377552017-06-22 10:45:33 -0700100 ALOGV("%s", __func__);
101 Properties prop11 = {};
102 auto& prop10 = prop11.base;
Tomasz Wasilczyk02b9cba2017-06-13 09:34:30 -0700103
Tomasz Wasilczyk48377552017-06-22 10:45:33 -0700104 prop10.classId = mClassId;
105 prop10.implementor = "Google";
106 prop10.product = mConfig.productName;
107 prop10.numTuners = 1;
108 prop10.numAudioSources = 1;
109 prop10.supportsCapture = false;
Tomasz Wasilczyk653f7662018-01-09 21:11:38 -0800110 prop11.supportsBackgroundScanning = true;
Tomasz Wasilczykfa3a5592017-08-03 11:06:09 -0700111 prop11.supportedProgramTypes = hidl_vec<uint32_t>({
Tomasz Wasilczyke192c392017-07-16 15:14:34 -0700112 static_cast<uint32_t>(ProgramType::AM), static_cast<uint32_t>(ProgramType::FM),
113 static_cast<uint32_t>(ProgramType::AM_HD), static_cast<uint32_t>(ProgramType::FM_HD),
114 });
Tomasz Wasilczykfa3a5592017-08-03 11:06:09 -0700115 prop11.supportedIdentifierTypes = hidl_vec<uint32_t>({
Tomasz Wasilczyke192c392017-07-16 15:14:34 -0700116 static_cast<uint32_t>(IdentifierType::AMFM_FREQUENCY),
117 static_cast<uint32_t>(IdentifierType::RDS_PI),
118 static_cast<uint32_t>(IdentifierType::HD_STATION_ID_EXT),
119 static_cast<uint32_t>(IdentifierType::HD_SUBCHANNEL),
120 });
Tomasz Wasilczykfa3a5592017-08-03 11:06:09 -0700121 prop11.vendorInfo = hidl_vec<VendorKeyValue>({
122 {"com.google.dummy", "dummy"},
123 });
Tomasz Wasilczyk02b9cba2017-06-13 09:34:30 -0700124
Tomasz Wasilczyk48377552017-06-22 10:45:33 -0700125 prop10.bands.resize(mConfig.amFmBands.size());
126 for (size_t i = 0; i < mConfig.amFmBands.size(); i++) {
127 auto& src = mConfig.amFmBands[i];
128 auto& dst = prop10.bands[i];
Tomasz Wasilczyk803301a2017-03-13 14:30:15 -0700129
Tomasz Wasilczyk48377552017-06-22 10:45:33 -0700130 dst.type = src.type;
131 dst.antennaConnected = true;
132 dst.lowerLimit = src.lowerLimit;
133 dst.upperLimit = src.upperLimit;
Tomasz Wasilczyk701a5bd2017-08-10 12:32:45 -0700134 dst.spacings = src.spacings;
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -0800135
Tomasz Wasilczyk701a5bd2017-08-10 12:32:45 -0700136 if (utils::isAm(src.type)) {
Tomasz Wasilczyk48377552017-06-22 10:45:33 -0700137 dst.ext.am.stereo = true;
Tomasz Wasilczyk701a5bd2017-08-10 12:32:45 -0700138 } else if (utils::isFm(src.type)) {
139 dst.ext.fm.deemphasis = static_cast<Deemphasis>(Deemphasis::D50 | Deemphasis::D75);
Tomasz Wasilczyk48377552017-06-22 10:45:33 -0700140 dst.ext.fm.stereo = true;
Tomasz Wasilczyk701a5bd2017-08-10 12:32:45 -0700141 dst.ext.fm.rds = static_cast<Rds>(Rds::WORLD | Rds::US);
Tomasz Wasilczyk48377552017-06-22 10:45:33 -0700142 dst.ext.fm.ta = true;
143 dst.ext.fm.af = true;
144 dst.ext.fm.ea = true;
145 }
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -0800146 }
147
Tomasz Wasilczyk48377552017-06-22 10:45:33 -0700148 _hidl_cb(prop11);
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -0800149 return Void();
150}
151
Tomasz Wasilczyk48377552017-06-22 10:45:33 -0700152Return<void> BroadcastRadio::openTuner(const BandConfig& config, bool audio __unused,
153 const sp<V1_0::ITunerCallback>& callback,
154 openTuner_cb _hidl_cb) {
Tomasz Wasilczykc9ba6462017-07-07 13:28:00 -0700155 ALOGV("%s(%s)", __func__, toString(config.type).c_str());
Tomasz Wasilczyk48377552017-06-22 10:45:33 -0700156 lock_guard<mutex> lk(mMut);
157
158 auto oldTuner = mTuner.promote();
159 if (oldTuner != nullptr) {
160 ALOGI("Force-closing previously opened tuner");
161 oldTuner->forceClose();
162 mTuner = nullptr;
163 }
164
Tomasz Wasilczykefadc192017-07-28 10:08:46 -0700165 sp<Tuner> newTuner = new Tuner(mClassId, callback);
Tomasz Wasilczyk48377552017-06-22 10:45:33 -0700166 mTuner = newTuner;
167 if (mClassId == Class::AM_FM) {
168 auto ret = newTuner->setConfiguration(config);
169 if (ret != Result::OK) {
170 _hidl_cb(Result::INVALID_ARGUMENTS, {});
171 return Void();
172 }
173 }
174
175 _hidl_cb(Result::OK, newTuner);
176 return Void();
177}
178
Tomasz Wasilczykba3e2542017-07-17 13:59:21 -0700179Return<void> BroadcastRadio::getImage(int32_t id, getImage_cb _hidl_cb) {
180 ALOGV("%s(%x)", __func__, id);
181
182 if (id == resources::demoPngId) {
183 _hidl_cb(std::vector<uint8_t>(resources::demoPng, std::end(resources::demoPng)));
184 return {};
185 }
186
187 ALOGI("Image %x doesn't exists", id);
188 _hidl_cb({});
189 return Void();
190}
191
Tomasz Wasilczyk48377552017-06-22 10:45:33 -0700192} // namespace implementation
Tomasz Wasilczyk8c34c812018-02-08 13:42:31 -0800193} // namespace V1_1
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -0800194} // namespace broadcastradio
195} // namespace hardware
196} // namespace android