blob: fa74288b093ab3c0d79adb44ae13fa445cd99f1a [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
40 mFrontendSize = 10;
Hongguang Chenff2c6b02021-08-07 00:12:26 +000041 mFrontends[0] = ndk::SharedRefBase::make<Frontend>(FrontendType::ISDBS, 0, this->ref<Tuner>());
42 mFrontends[1] = ndk::SharedRefBase::make<Frontend>(FrontendType::ATSC3, 1, this->ref<Tuner>());
43 mFrontends[2] = ndk::SharedRefBase::make<Frontend>(FrontendType::DVBC, 2, this->ref<Tuner>());
44 mFrontends[3] = ndk::SharedRefBase::make<Frontend>(FrontendType::DVBS, 3, this->ref<Tuner>());
45 mFrontends[4] = ndk::SharedRefBase::make<Frontend>(FrontendType::DVBT, 4, this->ref<Tuner>());
46 mFrontends[5] = ndk::SharedRefBase::make<Frontend>(FrontendType::ISDBT, 5, this->ref<Tuner>());
47 mFrontends[6] = ndk::SharedRefBase::make<Frontend>(FrontendType::ANALOG, 6, this->ref<Tuner>());
48 mFrontends[7] = ndk::SharedRefBase::make<Frontend>(FrontendType::ATSC, 7, this->ref<Tuner>());
49 mFrontends[8] = ndk::SharedRefBase::make<Frontend>(FrontendType::ISDBS3, 8, this->ref<Tuner>());
50 mFrontends[9] = ndk::SharedRefBase::make<Frontend>(FrontendType::DTMB, 9, this->ref<Tuner>());
Hongguang4092f2f2021-07-08 18:49:12 -070051
Hongguang5766ddf2021-12-23 11:40:37 -080052 mMaxUsableFrontends[FrontendType::ISDBS] = 1;
Hongguang5766ddf2021-12-23 11:40:37 -080053 mMaxUsableFrontends[FrontendType::ATSC3] = 1;
Hongguang5766ddf2021-12-23 11:40:37 -080054 mMaxUsableFrontends[FrontendType::DVBC] = 1;
Hongguang5766ddf2021-12-23 11:40:37 -080055 mMaxUsableFrontends[FrontendType::DVBS] = 1;
Hongguang5766ddf2021-12-23 11:40:37 -080056 mMaxUsableFrontends[FrontendType::DVBT] = 1;
Hongguang5766ddf2021-12-23 11:40:37 -080057 mMaxUsableFrontends[FrontendType::ISDBT] = 1;
Hongguang5766ddf2021-12-23 11:40:37 -080058 mMaxUsableFrontends[FrontendType::ANALOG] = 1;
Hongguang5766ddf2021-12-23 11:40:37 -080059 mMaxUsableFrontends[FrontendType::ATSC] = 1;
Hongguang5766ddf2021-12-23 11:40:37 -080060 mMaxUsableFrontends[FrontendType::ISDBS3] = 1;
Hongguang5766ddf2021-12-23 11:40:37 -080061 mMaxUsableFrontends[FrontendType::DTMB] = 1;
Hongguang4092f2f2021-07-08 18:49:12 -070062
63 mLnbs.resize(2);
64 mLnbs[0] = ndk::SharedRefBase::make<Lnb>(0);
65 mLnbs[1] = ndk::SharedRefBase::make<Lnb>(1);
66}
67
68Tuner::~Tuner() {}
69
70::ndk::ScopedAStatus Tuner::getFrontendIds(std::vector<int32_t>* _aidl_return) {
71 ALOGV("%s", __FUNCTION__);
72
73 _aidl_return->resize(mFrontendSize);
74 for (int i = 0; i < mFrontendSize; i++) {
75 (*_aidl_return)[i] = mFrontends[i]->getFrontendId();
76 }
77
78 return ::ndk::ScopedAStatus::ok();
79}
80
81::ndk::ScopedAStatus Tuner::openFrontendById(int32_t in_frontendId,
82 std::shared_ptr<IFrontend>* _aidl_return) {
83 ALOGV("%s", __FUNCTION__);
84
85 if (in_frontendId >= mFrontendSize || in_frontendId < 0) {
86 ALOGW("[ WARN ] Frontend with id %d isn't available", in_frontendId);
87 *_aidl_return = nullptr;
Hongguange423acd2021-07-27 16:56:47 -070088 return ::ndk::ScopedAStatus::fromServiceSpecificError(
89 static_cast<int32_t>(Result::INVALID_ARGUMENT));
Hongguang4092f2f2021-07-08 18:49:12 -070090 }
91
92 *_aidl_return = mFrontends[in_frontendId];
93 return ::ndk::ScopedAStatus::ok();
94}
95
96::ndk::ScopedAStatus Tuner::openDemux(std::vector<int32_t>* out_demuxId,
97 std::shared_ptr<IDemux>* _aidl_return) {
98 ALOGV("%s", __FUNCTION__);
99
100 mLastUsedId += 1;
Hongguang Chenff2c6b02021-08-07 00:12:26 +0000101 mDemuxes[mLastUsedId] = ndk::SharedRefBase::make<Demux>(mLastUsedId, this->ref<Tuner>());
Hongguang4092f2f2021-07-08 18:49:12 -0700102
103 out_demuxId->push_back(mLastUsedId);
104 *_aidl_return = mDemuxes[mLastUsedId];
105
106 return ::ndk::ScopedAStatus::ok();
107}
108
109::ndk::ScopedAStatus Tuner::getDemuxCaps(DemuxCapabilities* _aidl_return) {
110 ALOGV("%s", __FUNCTION__);
111
112 // IP filter can be an MMTP filter's data source.
113 _aidl_return->linkCaps = {0x00, 0x00, 0x02, 0x00, 0x00};
114 // Support time filter testing
115 _aidl_return->bTimeFilter = true;
116
117 return ::ndk::ScopedAStatus::ok();
118}
119
120::ndk::ScopedAStatus Tuner::openDescrambler(std::shared_ptr<IDescrambler>* _aidl_return) {
121 ALOGV("%s", __FUNCTION__);
122
123 *_aidl_return = ndk::SharedRefBase::make<Descrambler>();
124
125 return ndk::ScopedAStatus::ok();
126}
127
128::ndk::ScopedAStatus Tuner::getFrontendInfo(int32_t in_frontendId, FrontendInfo* _aidl_return) {
129 ALOGV("%s", __FUNCTION__);
130
Hongguang881190f2022-01-14 13:23:37 -0800131 if (in_frontendId < 0 || in_frontendId >= mFrontendSize) {
Hongguange423acd2021-07-27 16:56:47 -0700132 return ::ndk::ScopedAStatus::fromServiceSpecificError(
133 static_cast<int32_t>(Result::INVALID_ARGUMENT));
Hongguang4092f2f2021-07-08 18:49:12 -0700134 }
135
Hongguang881190f2022-01-14 13:23:37 -0800136 mFrontends[in_frontendId]->getFrontendInfo(_aidl_return);
Hongguang4092f2f2021-07-08 18:49:12 -0700137 return ::ndk::ScopedAStatus::ok();
138}
139
140::ndk::ScopedAStatus Tuner::getLnbIds(std::vector<int32_t>* _aidl_return) {
141 ALOGV("%s", __FUNCTION__);
142
143 _aidl_return->resize(mLnbs.size());
144 for (int i = 0; i < mLnbs.size(); i++) {
145 (*_aidl_return)[i] = mLnbs[i]->getId();
146 }
147
148 return ::ndk::ScopedAStatus::ok();
149}
150
151::ndk::ScopedAStatus Tuner::openLnbById(int32_t in_lnbId, std::shared_ptr<ILnb>* _aidl_return) {
152 ALOGV("%s", __FUNCTION__);
153
154 if (in_lnbId >= mLnbs.size()) {
155 *_aidl_return = nullptr;
Hongguange423acd2021-07-27 16:56:47 -0700156 return ::ndk::ScopedAStatus::fromServiceSpecificError(
157 static_cast<int32_t>(Result::INVALID_ARGUMENT));
Hongguang4092f2f2021-07-08 18:49:12 -0700158 }
159
160 *_aidl_return = mLnbs[in_lnbId];
161 return ::ndk::ScopedAStatus::ok();
162}
163
164std::shared_ptr<Frontend> Tuner::getFrontendById(int32_t frontendId) {
165 ALOGV("%s", __FUNCTION__);
166
167 return mFrontends[frontendId];
168}
169
170::ndk::ScopedAStatus Tuner::openLnbByName(const std::string& /* in_lnbName */,
171 std::vector<int32_t>* out_lnbId,
172 std::shared_ptr<ILnb>* _aidl_return) {
173 ALOGV("%s", __FUNCTION__);
174
175 out_lnbId->push_back(1234);
176 *_aidl_return = ndk::SharedRefBase::make<Lnb>();
177
178 return ::ndk::ScopedAStatus::ok();
179}
180
Hongguangfcedda02021-12-13 17:08:02 -0800181::ndk::ScopedAStatus Tuner::setLna(bool /* in_bEnable */) {
182 ALOGV("%s", __FUNCTION__);
183
184 return ::ndk::ScopedAStatus::ok();
185}
186
Hongguang5766ddf2021-12-23 11:40:37 -0800187::ndk::ScopedAStatus Tuner::setMaxNumberOfFrontends(FrontendType in_frontendType,
188 int32_t in_maxNumber) {
189 ALOGV("%s", __FUNCTION__);
190
191 // In the default implementation, every type only has one frontend.
192 if (in_maxNumber < 0 || in_maxNumber > 1) {
193 return ::ndk::ScopedAStatus::fromServiceSpecificError(
194 static_cast<int32_t>(Result::INVALID_ARGUMENT));
195 }
196 mMaxUsableFrontends[in_frontendType] = in_maxNumber;
197 return ::ndk::ScopedAStatus::ok();
198}
199
200::ndk::ScopedAStatus Tuner::getMaxNumberOfFrontends(FrontendType in_frontendType,
201 int32_t* _aidl_return) {
202 *_aidl_return = mMaxUsableFrontends[in_frontendType];
203 return ::ndk::ScopedAStatus::ok();
204}
205
Hongguang2ecfc392021-11-23 10:29:15 -0800206binder_status_t Tuner::dump(int fd, const char** args, uint32_t numArgs) {
207 ALOGV("%s", __FUNCTION__);
208 {
209 dprintf(fd, "Frontends:\n");
210 for (int i = 0; i < mFrontendSize; i++) {
211 mFrontends[i]->dump(fd, args, numArgs);
Hongguang2ecfc392021-11-23 10:29:15 -0800212 }
213 }
214 {
215 dprintf(fd, "Demuxs:\n");
216 map<int32_t, std::shared_ptr<Demux>>::iterator it;
217 for (it = mDemuxes.begin(); it != mDemuxes.end(); it++) {
218 it->second->dump(fd, args, numArgs);
219 }
220 }
221 {
222 dprintf(fd, "Lnbs:\n");
223 for (int i = 0; i < mLnbs.size(); i++) {
224 mLnbs[i]->dump(fd, args, numArgs);
225 }
226 }
227 return STATUS_OK;
228}
229
Hongguang4092f2f2021-07-08 18:49:12 -0700230void Tuner::setFrontendAsDemuxSource(int32_t frontendId, int32_t demuxId) {
231 mFrontendToDemux[frontendId] = demuxId;
232 if (mFrontends[frontendId] != nullptr && mFrontends[frontendId]->isLocked()) {
233 mDemuxes[demuxId]->startFrontendInputLoop();
234 }
235}
236
237void Tuner::removeDemux(int32_t demuxId) {
238 map<int32_t, int32_t>::iterator it;
239 for (it = mFrontendToDemux.begin(); it != mFrontendToDemux.end(); it++) {
240 if (it->second == demuxId) {
241 it = mFrontendToDemux.erase(it);
242 break;
243 }
244 }
245 mDemuxes.erase(demuxId);
246}
247
248void Tuner::removeFrontend(int32_t frontendId) {
Hongguang2ecfc392021-11-23 10:29:15 -0800249 map<int32_t, int32_t>::iterator it = mFrontendToDemux.find(frontendId);
250 if (it != mFrontendToDemux.end()) {
251 mDemuxes.erase(it->second);
252 }
Hongguang4092f2f2021-07-08 18:49:12 -0700253 mFrontendToDemux.erase(frontendId);
254}
255
256void Tuner::frontendStopTune(int32_t frontendId) {
257 map<int32_t, int32_t>::iterator it = mFrontendToDemux.find(frontendId);
258 int32_t demuxId;
259 if (it != mFrontendToDemux.end()) {
260 demuxId = it->second;
261 mDemuxes[demuxId]->stopFrontendInput();
262 }
263}
264
265void Tuner::frontendStartTune(int32_t frontendId) {
266 map<int32_t, int32_t>::iterator it = mFrontendToDemux.find(frontendId);
267 int32_t demuxId;
268 if (it != mFrontendToDemux.end()) {
269 demuxId = it->second;
270 mDemuxes[demuxId]->startFrontendInputLoop();
271 }
272}
273
274} // namespace tuner
275} // namespace tv
276} // namespace hardware
277} // namespace android
278} // namespace aidl