blob: ce7a10f5c93b70af6bf7bd0294caaf1d17257310 [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 {
28namespace V1_1 {
29namespace 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;
36
37using std::lock_guard;
38using std::map;
39using std::mutex;
40using std::vector;
41
42// clang-format off
43static const map<Class, ModuleConfig> gModuleConfigs{
44 {Class::AM_FM, ModuleConfig({
45 "Digital radio mock",
46 { // amFmBands
47 AmFmBandConfig({
48 Band::AM_HD,
49 540, // lowerLimit
50 1610, // upperLimit
51 10, // spacing
52 }),
53 AmFmBandConfig({
54 Band::FM_HD,
55 87900, // lowerLimit
56 107900, // upperLimit
57 200, // spacing
58 }),
59 },
60 })},
61
62 {Class::SAT, ModuleConfig({
63 "Satellite radio mock",
64 {}, // amFmBands
65 })},
66};
67// clang-format on
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -080068
69BroadcastRadio::BroadcastRadio(Class classId)
Tomasz Wasilczyk48377552017-06-22 10:45:33 -070070 : mClassId(classId), mConfig(gModuleConfigs.at(classId)) {}
71
72bool BroadcastRadio::isSupported(Class classId) {
73 return gModuleConfigs.find(classId) != gModuleConfigs.end();
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -080074}
75
Tomasz Wasilczyk48377552017-06-22 10:45:33 -070076Return<void> BroadcastRadio::getProperties(getProperties_cb _hidl_cb) {
77 ALOGV("%s", __func__);
78 return getProperties_1_1(
79 [&](const Properties& properties) { _hidl_cb(Result::OK, properties.base); });
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -080080}
81
Tomasz Wasilczyk02b9cba2017-06-13 09:34:30 -070082Return<void> BroadcastRadio::getProperties_1_1(getProperties_1_1_cb _hidl_cb) {
Tomasz Wasilczyk48377552017-06-22 10:45:33 -070083 ALOGV("%s", __func__);
84 Properties prop11 = {};
85 auto& prop10 = prop11.base;
Tomasz Wasilczyk02b9cba2017-06-13 09:34:30 -070086
Tomasz Wasilczyk48377552017-06-22 10:45:33 -070087 prop10.classId = mClassId;
88 prop10.implementor = "Google";
89 prop10.product = mConfig.productName;
90 prop10.numTuners = 1;
91 prop10.numAudioSources = 1;
92 prop10.supportsCapture = false;
93 prop11.supportsBackgroundScanning = false;
Tomasz Wasilczykfa3a5592017-08-03 11:06:09 -070094 prop11.supportedProgramTypes = hidl_vec<uint32_t>({
Tomasz Wasilczyke192c392017-07-16 15:14:34 -070095 static_cast<uint32_t>(ProgramType::AM), static_cast<uint32_t>(ProgramType::FM),
96 static_cast<uint32_t>(ProgramType::AM_HD), static_cast<uint32_t>(ProgramType::FM_HD),
97 });
Tomasz Wasilczykfa3a5592017-08-03 11:06:09 -070098 prop11.supportedIdentifierTypes = hidl_vec<uint32_t>({
Tomasz Wasilczyke192c392017-07-16 15:14:34 -070099 static_cast<uint32_t>(IdentifierType::AMFM_FREQUENCY),
100 static_cast<uint32_t>(IdentifierType::RDS_PI),
101 static_cast<uint32_t>(IdentifierType::HD_STATION_ID_EXT),
102 static_cast<uint32_t>(IdentifierType::HD_SUBCHANNEL),
103 });
Tomasz Wasilczykfa3a5592017-08-03 11:06:09 -0700104 prop11.vendorInfo = hidl_vec<VendorKeyValue>({
105 {"com.google.dummy", "dummy"},
106 });
Tomasz Wasilczyk02b9cba2017-06-13 09:34:30 -0700107
Tomasz Wasilczyk48377552017-06-22 10:45:33 -0700108 prop10.bands.resize(mConfig.amFmBands.size());
109 for (size_t i = 0; i < mConfig.amFmBands.size(); i++) {
110 auto& src = mConfig.amFmBands[i];
111 auto& dst = prop10.bands[i];
Tomasz Wasilczyk803301a2017-03-13 14:30:15 -0700112
Tomasz Wasilczyk48377552017-06-22 10:45:33 -0700113 dst.type = src.type;
114 dst.antennaConnected = true;
115 dst.lowerLimit = src.lowerLimit;
116 dst.upperLimit = src.upperLimit;
117 dst.spacings = vector<uint32_t>({src.spacing});
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -0800118
Tomasz Wasilczyk48377552017-06-22 10:45:33 -0700119 if (src.type == Band::AM) {
120 dst.ext.am.stereo = true;
121 } else if (src.type == Band::FM) {
122 dst.ext.fm.deemphasis = Deemphasis::D75;
123 dst.ext.fm.stereo = true;
124 dst.ext.fm.rds = Rds::US;
125 dst.ext.fm.ta = true;
126 dst.ext.fm.af = true;
127 dst.ext.fm.ea = true;
128 }
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -0800129 }
130
Tomasz Wasilczyk48377552017-06-22 10:45:33 -0700131 _hidl_cb(prop11);
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -0800132 return Void();
133}
134
Tomasz Wasilczyk48377552017-06-22 10:45:33 -0700135Return<void> BroadcastRadio::openTuner(const BandConfig& config, bool audio __unused,
136 const sp<V1_0::ITunerCallback>& callback,
137 openTuner_cb _hidl_cb) {
Tomasz Wasilczykc9ba6462017-07-07 13:28:00 -0700138 ALOGV("%s(%s)", __func__, toString(config.type).c_str());
Tomasz Wasilczyk48377552017-06-22 10:45:33 -0700139 lock_guard<mutex> lk(mMut);
140
141 auto oldTuner = mTuner.promote();
142 if (oldTuner != nullptr) {
143 ALOGI("Force-closing previously opened tuner");
144 oldTuner->forceClose();
145 mTuner = nullptr;
146 }
147
Tomasz Wasilczykefadc192017-07-28 10:08:46 -0700148 sp<Tuner> newTuner = new Tuner(mClassId, callback);
Tomasz Wasilczyk48377552017-06-22 10:45:33 -0700149 mTuner = newTuner;
150 if (mClassId == Class::AM_FM) {
151 auto ret = newTuner->setConfiguration(config);
152 if (ret != Result::OK) {
153 _hidl_cb(Result::INVALID_ARGUMENTS, {});
154 return Void();
155 }
156 }
157
158 _hidl_cb(Result::OK, newTuner);
159 return Void();
160}
161
Tomasz Wasilczykba3e2542017-07-17 13:59:21 -0700162Return<void> BroadcastRadio::getImage(int32_t id, getImage_cb _hidl_cb) {
163 ALOGV("%s(%x)", __func__, id);
164
165 if (id == resources::demoPngId) {
166 _hidl_cb(std::vector<uint8_t>(resources::demoPng, std::end(resources::demoPng)));
167 return {};
168 }
169
170 ALOGI("Image %x doesn't exists", id);
171 _hidl_cb({});
172 return Void();
173}
174
Tomasz Wasilczyk48377552017-06-22 10:45:33 -0700175} // namespace implementation
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -0800176} // namespace V1_1
177} // namespace broadcastradio
178} // namespace hardware
179} // namespace android