blob: a8b24a03b794d62450c6b3356a01a6eacd4ed2d1 [file] [log] [blame]
Hongguang4092f2f2021-07-08 18:49:12 -07001/*
2 * Copyright 2021 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_NDEBUG 0
18#define LOG_TAG "android.hardware.tv.tuner-service.example-Tuner"
19
Hongguange423acd2021-07-27 16:56:47 -070020#include <aidl/android/hardware/tv/tuner/Result.h>
Hongguang4092f2f2021-07-08 18:49:12 -070021#include <utils/Log.h>
Hongguange423acd2021-07-27 16:56:47 -070022
Hongguang4092f2f2021-07-08 18:49:12 -070023#include "Demux.h"
24#include "Descrambler.h"
25#include "Frontend.h"
26#include "Lnb.h"
Hongguange423acd2021-07-27 16:56:47 -070027#include "Tuner.h"
Hongguang4092f2f2021-07-08 18:49:12 -070028
29namespace aidl {
30namespace android {
31namespace hardware {
32namespace tv {
33namespace tuner {
34
Hongguang Chenff2c6b02021-08-07 00:12:26 +000035Tuner::Tuner() {}
36
37void Tuner::init() {
Hongguang4092f2f2021-07-08 18:49:12 -070038 // Static Frontends array to maintain local frontends information
39 // Array index matches their FrontendId in the default impl
sadiqsada8441c0d2022-12-12 12:16:33 -080040 mFrontendSize = 11;
Hongguang4a8ac292022-08-09 14:02:03 -070041 mFrontends[0] = ndk::SharedRefBase::make<Frontend>(FrontendType::ISDBS, 0);
42 mFrontends[1] = ndk::SharedRefBase::make<Frontend>(FrontendType::ATSC3, 1);
43 mFrontends[2] = ndk::SharedRefBase::make<Frontend>(FrontendType::DVBC, 2);
44 mFrontends[3] = ndk::SharedRefBase::make<Frontend>(FrontendType::DVBS, 3);
45 mFrontends[4] = ndk::SharedRefBase::make<Frontend>(FrontendType::DVBT, 4);
46 mFrontends[5] = ndk::SharedRefBase::make<Frontend>(FrontendType::ISDBT, 5);
47 mFrontends[6] = ndk::SharedRefBase::make<Frontend>(FrontendType::ANALOG, 6);
48 mFrontends[7] = ndk::SharedRefBase::make<Frontend>(FrontendType::ATSC, 7);
49 mFrontends[8] = ndk::SharedRefBase::make<Frontend>(FrontendType::ISDBS3, 8);
50 mFrontends[9] = ndk::SharedRefBase::make<Frontend>(FrontendType::DTMB, 9);
sadiqsada8441c0d2022-12-12 12:16:33 -080051 mFrontends[10] = ndk::SharedRefBase::make<Frontend>(FrontendType::IPTV, 10);
Hongguang4092f2f2021-07-08 18:49:12 -070052
Hongguang5766ddf2021-12-23 11:40:37 -080053 mMaxUsableFrontends[FrontendType::ISDBS] = 1;
Hongguang5766ddf2021-12-23 11:40:37 -080054 mMaxUsableFrontends[FrontendType::ATSC3] = 1;
Hongguang5766ddf2021-12-23 11:40:37 -080055 mMaxUsableFrontends[FrontendType::DVBC] = 1;
Hongguang5766ddf2021-12-23 11:40:37 -080056 mMaxUsableFrontends[FrontendType::DVBS] = 1;
Hongguang5766ddf2021-12-23 11:40:37 -080057 mMaxUsableFrontends[FrontendType::DVBT] = 1;
Hongguang5766ddf2021-12-23 11:40:37 -080058 mMaxUsableFrontends[FrontendType::ISDBT] = 1;
Hongguang5766ddf2021-12-23 11:40:37 -080059 mMaxUsableFrontends[FrontendType::ANALOG] = 1;
Hongguang5766ddf2021-12-23 11:40:37 -080060 mMaxUsableFrontends[FrontendType::ATSC] = 1;
Hongguang5766ddf2021-12-23 11:40:37 -080061 mMaxUsableFrontends[FrontendType::ISDBS3] = 1;
Hongguang5766ddf2021-12-23 11:40:37 -080062 mMaxUsableFrontends[FrontendType::DTMB] = 1;
sadiqsada8441c0d2022-12-12 12:16:33 -080063 mMaxUsableFrontends[FrontendType::IPTV] = 1;
Hongguang4092f2f2021-07-08 18:49:12 -070064
65 mLnbs.resize(2);
66 mLnbs[0] = ndk::SharedRefBase::make<Lnb>(0);
67 mLnbs[1] = ndk::SharedRefBase::make<Lnb>(1);
68}
69
70Tuner::~Tuner() {}
71
72::ndk::ScopedAStatus Tuner::getFrontendIds(std::vector<int32_t>* _aidl_return) {
73 ALOGV("%s", __FUNCTION__);
74
75 _aidl_return->resize(mFrontendSize);
76 for (int i = 0; i < mFrontendSize; i++) {
77 (*_aidl_return)[i] = mFrontends[i]->getFrontendId();
78 }
79
80 return ::ndk::ScopedAStatus::ok();
81}
82
83::ndk::ScopedAStatus Tuner::openFrontendById(int32_t in_frontendId,
84 std::shared_ptr<IFrontend>* _aidl_return) {
85 ALOGV("%s", __FUNCTION__);
86
87 if (in_frontendId >= mFrontendSize || in_frontendId < 0) {
88 ALOGW("[ WARN ] Frontend with id %d isn't available", in_frontendId);
89 *_aidl_return = nullptr;
Hongguange423acd2021-07-27 16:56:47 -070090 return ::ndk::ScopedAStatus::fromServiceSpecificError(
91 static_cast<int32_t>(Result::INVALID_ARGUMENT));
Hongguang4092f2f2021-07-08 18:49:12 -070092 }
93
Hongguang4a8ac292022-08-09 14:02:03 -070094 mFrontends[in_frontendId]->setTunerService(this->ref<Tuner>());
Hongguang4092f2f2021-07-08 18:49:12 -070095 *_aidl_return = mFrontends[in_frontendId];
96 return ::ndk::ScopedAStatus::ok();
97}
98
99::ndk::ScopedAStatus Tuner::openDemux(std::vector<int32_t>* out_demuxId,
100 std::shared_ptr<IDemux>* _aidl_return) {
101 ALOGV("%s", __FUNCTION__);
102
103 mLastUsedId += 1;
Hongguang Chenff2c6b02021-08-07 00:12:26 +0000104 mDemuxes[mLastUsedId] = ndk::SharedRefBase::make<Demux>(mLastUsedId, this->ref<Tuner>());
Hongguang4092f2f2021-07-08 18:49:12 -0700105
106 out_demuxId->push_back(mLastUsedId);
107 *_aidl_return = mDemuxes[mLastUsedId];
108
109 return ::ndk::ScopedAStatus::ok();
110}
111
112::ndk::ScopedAStatus Tuner::getDemuxCaps(DemuxCapabilities* _aidl_return) {
113 ALOGV("%s", __FUNCTION__);
114
115 // IP filter can be an MMTP filter's data source.
116 _aidl_return->linkCaps = {0x00, 0x00, 0x02, 0x00, 0x00};
117 // Support time filter testing
118 _aidl_return->bTimeFilter = true;
119
120 return ::ndk::ScopedAStatus::ok();
121}
122
123::ndk::ScopedAStatus Tuner::openDescrambler(std::shared_ptr<IDescrambler>* _aidl_return) {
124 ALOGV("%s", __FUNCTION__);
125
126 *_aidl_return = ndk::SharedRefBase::make<Descrambler>();
127
128 return ndk::ScopedAStatus::ok();
129}
130
131::ndk::ScopedAStatus Tuner::getFrontendInfo(int32_t in_frontendId, FrontendInfo* _aidl_return) {
132 ALOGV("%s", __FUNCTION__);
133
Hongguang881190f2022-01-14 13:23:37 -0800134 if (in_frontendId < 0 || in_frontendId >= mFrontendSize) {
Hongguange423acd2021-07-27 16:56:47 -0700135 return ::ndk::ScopedAStatus::fromServiceSpecificError(
136 static_cast<int32_t>(Result::INVALID_ARGUMENT));
Hongguang4092f2f2021-07-08 18:49:12 -0700137 }
138
Hongguang881190f2022-01-14 13:23:37 -0800139 mFrontends[in_frontendId]->getFrontendInfo(_aidl_return);
Hongguang4092f2f2021-07-08 18:49:12 -0700140 return ::ndk::ScopedAStatus::ok();
141}
142
143::ndk::ScopedAStatus Tuner::getLnbIds(std::vector<int32_t>* _aidl_return) {
144 ALOGV("%s", __FUNCTION__);
145
146 _aidl_return->resize(mLnbs.size());
147 for (int i = 0; i < mLnbs.size(); i++) {
148 (*_aidl_return)[i] = mLnbs[i]->getId();
149 }
150
151 return ::ndk::ScopedAStatus::ok();
152}
153
154::ndk::ScopedAStatus Tuner::openLnbById(int32_t in_lnbId, std::shared_ptr<ILnb>* _aidl_return) {
155 ALOGV("%s", __FUNCTION__);
156
157 if (in_lnbId >= mLnbs.size()) {
158 *_aidl_return = nullptr;
Hongguange423acd2021-07-27 16:56:47 -0700159 return ::ndk::ScopedAStatus::fromServiceSpecificError(
160 static_cast<int32_t>(Result::INVALID_ARGUMENT));
Hongguang4092f2f2021-07-08 18:49:12 -0700161 }
162
163 *_aidl_return = mLnbs[in_lnbId];
164 return ::ndk::ScopedAStatus::ok();
165}
166
167std::shared_ptr<Frontend> Tuner::getFrontendById(int32_t frontendId) {
168 ALOGV("%s", __FUNCTION__);
169
170 return mFrontends[frontendId];
171}
172
173::ndk::ScopedAStatus Tuner::openLnbByName(const std::string& /* in_lnbName */,
174 std::vector<int32_t>* out_lnbId,
175 std::shared_ptr<ILnb>* _aidl_return) {
176 ALOGV("%s", __FUNCTION__);
177
178 out_lnbId->push_back(1234);
179 *_aidl_return = ndk::SharedRefBase::make<Lnb>();
180
181 return ::ndk::ScopedAStatus::ok();
182}
183
Hongguangfcedda02021-12-13 17:08:02 -0800184::ndk::ScopedAStatus Tuner::setLna(bool /* in_bEnable */) {
185 ALOGV("%s", __FUNCTION__);
186
187 return ::ndk::ScopedAStatus::ok();
188}
189
Hongguang5766ddf2021-12-23 11:40:37 -0800190::ndk::ScopedAStatus Tuner::setMaxNumberOfFrontends(FrontendType in_frontendType,
191 int32_t in_maxNumber) {
192 ALOGV("%s", __FUNCTION__);
193
194 // In the default implementation, every type only has one frontend.
195 if (in_maxNumber < 0 || in_maxNumber > 1) {
196 return ::ndk::ScopedAStatus::fromServiceSpecificError(
197 static_cast<int32_t>(Result::INVALID_ARGUMENT));
198 }
199 mMaxUsableFrontends[in_frontendType] = in_maxNumber;
200 return ::ndk::ScopedAStatus::ok();
201}
202
203::ndk::ScopedAStatus Tuner::getMaxNumberOfFrontends(FrontendType in_frontendType,
204 int32_t* _aidl_return) {
205 *_aidl_return = mMaxUsableFrontends[in_frontendType];
206 return ::ndk::ScopedAStatus::ok();
207}
208
Ray Chin8fe32b22022-11-01 11:51:23 +0800209::ndk::ScopedAStatus Tuner::isLnaSupported(bool* _aidl_return) {
210 ALOGV("%s", __FUNCTION__);
211
212 *_aidl_return = true;
213 return ::ndk::ScopedAStatus::ok();
214}
215
Hongguang2ecfc392021-11-23 10:29:15 -0800216binder_status_t Tuner::dump(int fd, const char** args, uint32_t numArgs) {
217 ALOGV("%s", __FUNCTION__);
218 {
219 dprintf(fd, "Frontends:\n");
220 for (int i = 0; i < mFrontendSize; i++) {
221 mFrontends[i]->dump(fd, args, numArgs);
Hongguang2ecfc392021-11-23 10:29:15 -0800222 }
223 }
224 {
225 dprintf(fd, "Demuxs:\n");
226 map<int32_t, std::shared_ptr<Demux>>::iterator it;
227 for (it = mDemuxes.begin(); it != mDemuxes.end(); it++) {
228 it->second->dump(fd, args, numArgs);
229 }
230 }
231 {
232 dprintf(fd, "Lnbs:\n");
233 for (int i = 0; i < mLnbs.size(); i++) {
234 mLnbs[i]->dump(fd, args, numArgs);
235 }
236 }
237 return STATUS_OK;
238}
239
Hongguang4092f2f2021-07-08 18:49:12 -0700240void Tuner::setFrontendAsDemuxSource(int32_t frontendId, int32_t demuxId) {
241 mFrontendToDemux[frontendId] = demuxId;
242 if (mFrontends[frontendId] != nullptr && mFrontends[frontendId]->isLocked()) {
243 mDemuxes[demuxId]->startFrontendInputLoop();
244 }
245}
246
247void Tuner::removeDemux(int32_t demuxId) {
248 map<int32_t, int32_t>::iterator it;
249 for (it = mFrontendToDemux.begin(); it != mFrontendToDemux.end(); it++) {
250 if (it->second == demuxId) {
251 it = mFrontendToDemux.erase(it);
252 break;
253 }
254 }
255 mDemuxes.erase(demuxId);
256}
257
258void Tuner::removeFrontend(int32_t frontendId) {
Hongguang2ecfc392021-11-23 10:29:15 -0800259 map<int32_t, int32_t>::iterator it = mFrontendToDemux.find(frontendId);
260 if (it != mFrontendToDemux.end()) {
261 mDemuxes.erase(it->second);
262 }
Hongguang4092f2f2021-07-08 18:49:12 -0700263 mFrontendToDemux.erase(frontendId);
264}
265
266void Tuner::frontendStopTune(int32_t frontendId) {
267 map<int32_t, int32_t>::iterator it = mFrontendToDemux.find(frontendId);
268 int32_t demuxId;
269 if (it != mFrontendToDemux.end()) {
270 demuxId = it->second;
271 mDemuxes[demuxId]->stopFrontendInput();
272 }
273}
274
275void Tuner::frontendStartTune(int32_t frontendId) {
276 map<int32_t, int32_t>::iterator it = mFrontendToDemux.find(frontendId);
277 int32_t demuxId;
278 if (it != mFrontendToDemux.end()) {
279 demuxId = it->second;
280 mDemuxes[demuxId]->startFrontendInputLoop();
281 }
282}
283
284} // namespace tuner
285} // namespace tv
286} // namespace hardware
287} // namespace android
288} // namespace aidl