blob: 1119ffd8544f242ba71af01bad58dcd673291a23 [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
23namespace android {
24namespace hardware {
25namespace broadcastradio {
26namespace V1_1 {
27namespace implementation {
28
Tomasz Wasilczyk48377552017-06-22 10:45:33 -070029using V1_0::Band;
30using V1_0::BandConfig;
31using V1_0::Class;
32using V1_0::Deemphasis;
33using V1_0::Rds;
34
35using std::lock_guard;
36using std::map;
37using std::mutex;
38using std::vector;
39
40// clang-format off
41static const map<Class, ModuleConfig> gModuleConfigs{
42 {Class::AM_FM, ModuleConfig({
43 "Digital radio mock",
44 { // amFmBands
45 AmFmBandConfig({
46 Band::AM_HD,
47 540, // lowerLimit
48 1610, // upperLimit
49 10, // spacing
50 }),
51 AmFmBandConfig({
52 Band::FM_HD,
53 87900, // lowerLimit
54 107900, // upperLimit
55 200, // spacing
56 }),
57 },
58 })},
59
60 {Class::SAT, ModuleConfig({
61 "Satellite radio mock",
62 {}, // amFmBands
63 })},
64};
65// clang-format on
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -080066
67BroadcastRadio::BroadcastRadio(Class classId)
Tomasz Wasilczyk48377552017-06-22 10:45:33 -070068 : mClassId(classId), mConfig(gModuleConfigs.at(classId)) {}
69
70bool BroadcastRadio::isSupported(Class classId) {
71 return gModuleConfigs.find(classId) != gModuleConfigs.end();
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -080072}
73
Tomasz Wasilczyk48377552017-06-22 10:45:33 -070074Return<void> BroadcastRadio::getProperties(getProperties_cb _hidl_cb) {
75 ALOGV("%s", __func__);
76 return getProperties_1_1(
77 [&](const Properties& properties) { _hidl_cb(Result::OK, properties.base); });
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -080078}
79
Tomasz Wasilczyk02b9cba2017-06-13 09:34:30 -070080Return<void> BroadcastRadio::getProperties_1_1(getProperties_1_1_cb _hidl_cb) {
Tomasz Wasilczyk48377552017-06-22 10:45:33 -070081 ALOGV("%s", __func__);
82 Properties prop11 = {};
83 auto& prop10 = prop11.base;
Tomasz Wasilczyk02b9cba2017-06-13 09:34:30 -070084
Tomasz Wasilczyk48377552017-06-22 10:45:33 -070085 prop10.classId = mClassId;
86 prop10.implementor = "Google";
87 prop10.product = mConfig.productName;
88 prop10.numTuners = 1;
89 prop10.numAudioSources = 1;
90 prop10.supportsCapture = false;
91 prop11.supportsBackgroundScanning = false;
92 prop11.vendorExension = "dummy";
Tomasz Wasilczyk02b9cba2017-06-13 09:34:30 -070093
Tomasz Wasilczyk48377552017-06-22 10:45:33 -070094 prop10.bands.resize(mConfig.amFmBands.size());
95 for (size_t i = 0; i < mConfig.amFmBands.size(); i++) {
96 auto& src = mConfig.amFmBands[i];
97 auto& dst = prop10.bands[i];
Tomasz Wasilczyk803301a2017-03-13 14:30:15 -070098
Tomasz Wasilczyk48377552017-06-22 10:45:33 -070099 dst.type = src.type;
100 dst.antennaConnected = true;
101 dst.lowerLimit = src.lowerLimit;
102 dst.upperLimit = src.upperLimit;
103 dst.spacings = vector<uint32_t>({src.spacing});
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -0800104
Tomasz Wasilczyk48377552017-06-22 10:45:33 -0700105 if (src.type == Band::AM) {
106 dst.ext.am.stereo = true;
107 } else if (src.type == Band::FM) {
108 dst.ext.fm.deemphasis = Deemphasis::D75;
109 dst.ext.fm.stereo = true;
110 dst.ext.fm.rds = Rds::US;
111 dst.ext.fm.ta = true;
112 dst.ext.fm.af = true;
113 dst.ext.fm.ea = true;
114 }
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -0800115 }
116
Tomasz Wasilczyk48377552017-06-22 10:45:33 -0700117 _hidl_cb(prop11);
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -0800118 return Void();
119}
120
Tomasz Wasilczyk48377552017-06-22 10:45:33 -0700121Return<void> BroadcastRadio::openTuner(const BandConfig& config, bool audio __unused,
122 const sp<V1_0::ITunerCallback>& callback,
123 openTuner_cb _hidl_cb) {
Tomasz Wasilczykc9ba6462017-07-07 13:28:00 -0700124 ALOGV("%s(%s)", __func__, toString(config.type).c_str());
Tomasz Wasilczyk48377552017-06-22 10:45:33 -0700125 lock_guard<mutex> lk(mMut);
126
127 auto oldTuner = mTuner.promote();
128 if (oldTuner != nullptr) {
129 ALOGI("Force-closing previously opened tuner");
130 oldTuner->forceClose();
131 mTuner = nullptr;
132 }
133
134 sp<Tuner> newTuner = new Tuner(callback);
135 mTuner = newTuner;
136 if (mClassId == Class::AM_FM) {
137 auto ret = newTuner->setConfiguration(config);
138 if (ret != Result::OK) {
139 _hidl_cb(Result::INVALID_ARGUMENTS, {});
140 return Void();
141 }
142 }
143
144 _hidl_cb(Result::OK, newTuner);
145 return Void();
146}
147
148} // namespace implementation
Tomasz Wasilczyk213170b2017-02-07 17:38:21 -0800149} // namespace V1_1
150} // namespace broadcastradio
151} // namespace hardware
152} // namespace android