blob: 14a428970acde8b9af7e4bbd1d4b18b1a9d6e84a [file] [log] [blame]
Amy126ee922019-08-09 16:25:12 -07001/*
2 * Copyright (C) 2019 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 */
16
17#define LOG_TAG "android.hardware.tv.tuner@1.0-Tuner"
18
19#include "Tuner.h"
20#include <android/hardware/tv/tuner/1.0/IFrontendCallback.h>
21#include <utils/Log.h>
Amyfd4243a2019-08-16 16:01:27 -070022#include "Demux.h"
23#include "Descrambler.h"
Amy126ee922019-08-09 16:25:12 -070024#include "Frontend.h"
Amy016b7312019-09-16 15:51:28 -070025#include "Lnb.h"
Amy126ee922019-08-09 16:25:12 -070026
27namespace android {
28namespace hardware {
29namespace tv {
30namespace tuner {
31namespace V1_0 {
32namespace implementation {
33
Henry Fangf3eec032019-08-15 18:57:08 -070034using ::android::hardware::tv::tuner::V1_0::DemuxId;
35
Amy126ee922019-08-09 16:25:12 -070036Tuner::Tuner() {
37 // Static Frontends array to maintain local frontends information
38 // Array index matches their FrontendId in the default impl
39 mFrontendSize = 8;
40 mFrontends.resize(mFrontendSize);
Amy5094ae12019-10-04 18:43:21 -070041 mFrontends[0] = new Frontend(FrontendType::DVBT, 0, this);
42 mFrontends[1] = new Frontend(FrontendType::ATSC, 1, this);
43 mFrontends[2] = new Frontend(FrontendType::DVBC, 2, this);
44 mFrontends[3] = new Frontend(FrontendType::DVBS, 3, this);
45 mFrontends[4] = new Frontend(FrontendType::DVBT, 4, this);
46 mFrontends[5] = new Frontend(FrontendType::ISDBT, 5, this);
47 mFrontends[6] = new Frontend(FrontendType::ANALOG, 6, this);
48 mFrontends[7] = new Frontend(FrontendType::ATSC, 7, this);
shubangb0c1bbb2020-04-06 22:41:33 -070049
50 FrontendInfo::FrontendCapabilities caps;
51 mFrontendCaps.resize(mFrontendSize);
52 caps = FrontendInfo::FrontendCapabilities();
53 caps.dvbtCaps(FrontendDvbtCapabilities());
54 mFrontendCaps[0] = caps;
55
56 caps = FrontendInfo::FrontendCapabilities();
57 caps.atscCaps(FrontendAtscCapabilities());
58 mFrontendCaps[1] = caps;
59
60 caps = FrontendInfo::FrontendCapabilities();
61 caps.dvbcCaps(FrontendDvbcCapabilities());
62 mFrontendCaps[2] = caps;
63
64 caps = FrontendInfo::FrontendCapabilities();
65 caps.dvbsCaps(FrontendDvbsCapabilities());
66 mFrontendCaps[3] = caps;
67
68 caps = FrontendInfo::FrontendCapabilities();
69 caps.dvbtCaps(FrontendDvbtCapabilities());
70 mFrontendCaps[4] = caps;
71
72 caps = FrontendInfo::FrontendCapabilities();
73 FrontendIsdbtCapabilities isdbtCaps{
74 .modeCap = FrontendIsdbtMode::MODE_1 | FrontendIsdbtMode::MODE_2,
75 .bandwidthCap = (unsigned int)FrontendIsdbtBandwidth::BANDWIDTH_6MHZ,
76 .modulationCap = (unsigned int)FrontendIsdbtModulation::MOD_16QAM,
77 // ISDBT shares coderate and guard interval with DVBT
78 .coderateCap = FrontendDvbtCoderate::CODERATE_4_5 | FrontendDvbtCoderate::CODERATE_6_7,
79 .guardIntervalCap = (unsigned int)FrontendDvbtGuardInterval::INTERVAL_1_128,
80 };
81 caps.isdbtCaps(isdbtCaps);
82 mFrontendCaps[5] = caps;
83
84 caps = FrontendInfo::FrontendCapabilities();
85 caps.analogCaps(FrontendAnalogCapabilities());
86 mFrontendCaps[6] = caps;
87
88 caps = FrontendInfo::FrontendCapabilities();
89 caps.atscCaps(FrontendAtscCapabilities());
90 mFrontendCaps[7] = caps;
Amy126ee922019-08-09 16:25:12 -070091}
92
93Tuner::~Tuner() {}
94
95Return<void> Tuner::getFrontendIds(getFrontendIds_cb _hidl_cb) {
96 ALOGV("%s", __FUNCTION__);
97
98 vector<FrontendId> frontendIds;
99 frontendIds.resize(mFrontendSize);
100 for (int i = 0; i < mFrontendSize; i++) {
101 frontendIds[i] = mFrontends[i]->getFrontendId();
102 }
103
104 _hidl_cb(Result::SUCCESS, frontendIds);
105 return Void();
106}
107
108Return<void> Tuner::openFrontendById(uint32_t frontendId, openFrontendById_cb _hidl_cb) {
109 ALOGV("%s", __FUNCTION__);
110
111 if (frontendId >= mFrontendSize || frontendId < 0) {
112 ALOGW("[ WARN ] Frontend with id %d isn't available", frontendId);
113 _hidl_cb(Result::UNAVAILABLE, nullptr);
114 return Void();
115 }
116
117 _hidl_cb(Result::SUCCESS, mFrontends[frontendId]);
118 return Void();
119}
120
Henry Fangf3eec032019-08-15 18:57:08 -0700121Return<void> Tuner::openDemux(openDemux_cb _hidl_cb) {
122 ALOGV("%s", __FUNCTION__);
123
Amyfd4243a2019-08-16 16:01:27 -0700124 DemuxId demuxId = mLastUsedId + 1;
125 mLastUsedId += 1;
Amy5094ae12019-10-04 18:43:21 -0700126 sp<Demux> demux = new Demux(demuxId, this);
127 mDemuxes[demuxId] = demux;
Henry Fangf3eec032019-08-15 18:57:08 -0700128
129 _hidl_cb(Result::SUCCESS, demuxId, demux);
130 return Void();
131}
132
Amy42a5b4b2019-10-03 16:49:48 -0700133Return<void> Tuner::getDemuxCaps(getDemuxCaps_cb _hidl_cb) {
134 ALOGV("%s", __FUNCTION__);
135
136 DemuxCapabilities caps;
137
138 _hidl_cb(Result::SUCCESS, caps);
139 return Void();
140}
141
Henry Fangf3eec032019-08-15 18:57:08 -0700142Return<void> Tuner::openDescrambler(openDescrambler_cb _hidl_cb) {
143 ALOGV("%s", __FUNCTION__);
144
Amyfd4243a2019-08-16 16:01:27 -0700145 sp<IDescrambler> descrambler = new Descrambler();
Henry Fangf3eec032019-08-15 18:57:08 -0700146
147 _hidl_cb(Result::SUCCESS, descrambler);
148 return Void();
149}
150
Amy Zhang050bf782020-03-27 14:54:48 -0700151Return<void> Tuner::getFrontendInfo(FrontendId frontendId, getFrontendInfo_cb _hidl_cb) {
Amy016b7312019-09-16 15:51:28 -0700152 ALOGV("%s", __FUNCTION__);
153
Amy Zhang050bf782020-03-27 14:54:48 -0700154 FrontendInfo info;
155 if (frontendId >= mFrontendSize) {
156 _hidl_cb(Result::INVALID_ARGUMENT, info);
157 return Void();
158 }
159
160 switch (mFrontends[frontendId]->getFrontendType()) {
161 case FrontendType::DVBT:
162 info.type = FrontendType::DVBT;
163 break;
164 default:
165 vector<FrontendStatusType> statusCaps = {
166 FrontendStatusType::DEMOD_LOCK,
167 FrontendStatusType::SNR,
168 FrontendStatusType::FEC,
169 FrontendStatusType::MODULATION,
170 FrontendStatusType::PLP_ID,
171 FrontendStatusType::LAYER_ERROR,
172 FrontendStatusType::ATSC3_PLP_INFO,
173 };
Amy Zhang050bf782020-03-27 14:54:48 -0700174 // assign randomly selected values for testing.
175 info = {
shubangb0c1bbb2020-04-06 22:41:33 -0700176 .type = mFrontends[frontendId]->getFrontendType(),
Amy Zhang050bf782020-03-27 14:54:48 -0700177 .minFrequency = 139,
178 .maxFrequency = 1139,
179 .minSymbolRate = 45,
180 .maxSymbolRate = 1145,
181 .acquireRange = 30,
182 .exclusiveGroupId = 57,
183 .statusCaps = statusCaps,
shubangb0c1bbb2020-04-06 22:41:33 -0700184 .frontendCaps = mFrontendCaps[frontendId],
Amy Zhang050bf782020-03-27 14:54:48 -0700185 };
186 break;
187 }
Amy016b7312019-09-16 15:51:28 -0700188
189 _hidl_cb(Result::SUCCESS, info);
190 return Void();
191}
192
193Return<void> Tuner::getLnbIds(getLnbIds_cb _hidl_cb) {
194 ALOGV("%s", __FUNCTION__);
195
196 vector<LnbId> lnbIds;
197
198 _hidl_cb(Result::SUCCESS, lnbIds);
199 return Void();
200}
201
202Return<void> Tuner::openLnbById(LnbId /* lnbId */, openLnbById_cb _hidl_cb) {
203 ALOGV("%s", __FUNCTION__);
204
205 sp<ILnb> lnb = new Lnb();
206
207 _hidl_cb(Result::SUCCESS, lnb);
208 return Void();
209}
210
Amy5094ae12019-10-04 18:43:21 -0700211sp<Frontend> Tuner::getFrontendById(uint32_t frontendId) {
212 ALOGV("%s", __FUNCTION__);
213
214 return mFrontends[frontendId];
215}
216
Henry Fangfe019ac2019-12-23 18:13:43 -0800217Return<void> Tuner::openLnbByName(const hidl_string& /*lnbName*/, openLnbByName_cb _hidl_cb) {
218 ALOGV("%s", __FUNCTION__);
219
220 sp<ILnb> lnb = new Lnb();
221
222 _hidl_cb(Result::SUCCESS, 1234, lnb);
223 return Void();
224}
225
Amy5094ae12019-10-04 18:43:21 -0700226void Tuner::setFrontendAsDemuxSource(uint32_t frontendId, uint32_t demuxId) {
227 mFrontendToDemux[frontendId] = demuxId;
228}
229
230void Tuner::frontendStopTune(uint32_t frontendId) {
231 map<uint32_t, uint32_t>::iterator it = mFrontendToDemux.find(frontendId);
232 uint32_t demuxId;
233 if (it != mFrontendToDemux.end()) {
234 demuxId = it->second;
Amy5ed13572019-12-11 15:33:51 -0800235 mDemuxes[demuxId]->stopFrontendInput();
Amy5094ae12019-10-04 18:43:21 -0700236 }
237}
238
Amy Zhang0fe25be2020-04-08 17:30:52 -0700239void Tuner::frontendStartTune(uint32_t frontendId) {
240 map<uint32_t, uint32_t>::iterator it = mFrontendToDemux.find(frontendId);
241 uint32_t demuxId;
242 if (it != mFrontendToDemux.end()) {
243 demuxId = it->second;
244 mDemuxes[demuxId]->startFrontendInputLoop();
245 }
246}
247
Amy126ee922019-08-09 16:25:12 -0700248} // namespace implementation
249} // namespace V1_0
250} // namespace tuner
251} // namespace tv
252} // namespace hardware
253} // namespace android