blob: a604490daf58c81143f08457bf6fb98815e94185 [file] [log] [blame]
Amy Zhangbf68a162020-11-23 17:42:40 -08001/*
2 * Copyright 2020 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 "TunerClient"
18
19#include <android/binder_manager.h>
20#include <android-base/logging.h>
21#include <utils/Log.h>
22
23#include "TunerClient.h"
24
25using ::android::hardware::tv::tuner::V1_0::FrontendId;
26using ::android::hardware::tv::tuner::V1_0::FrontendType;
27
28namespace android {
29
30sp<ITuner> TunerClient::mTuner;
31sp<::android::hardware::tv::tuner::V1_1::ITuner> TunerClient::mTuner_1_1;
32shared_ptr<ITunerService> TunerClient::mTunerService;
33int TunerClient::mTunerVersion;
34
35/////////////// TunerClient ///////////////////////
36
37TunerClient::TunerClient() {
38 // Get HIDL Tuner in migration stage.
39 getHidlTuner();
Amy Zhang9eeba432021-01-21 12:52:05 -080040 if (mTuner != NULL) {
41 updateTunerResources();
42 }
Amy Zhangbf68a162020-11-23 17:42:40 -080043 // Connect with Tuner Service.
44 ::ndk::SpAIBinder binder(AServiceManager_getService("media.tuner"));
45 mTunerService = ITunerService::fromBinder(binder);
Amy Zhang9a9ed602020-12-07 16:37:33 -080046 // TODO: Remove after JNI migration is done.
47 mTunerService = NULL;
Amy Zhangbf68a162020-11-23 17:42:40 -080048 if (mTunerService == NULL) {
49 ALOGE("Failed to get tuner service");
Amy Zhang9eeba432021-01-21 12:52:05 -080050 } else {
51 // TODO: b/178124017 update TRM in TunerService independently.
52 mTunerService->updateTunerResources();
Amy Zhangbf68a162020-11-23 17:42:40 -080053 }
54}
55
56TunerClient::~TunerClient() {
57 mTuner = NULL;
58 mTuner_1_1 = NULL;
59 mTunerVersion = 0;
60 mTunerService = NULL;
61}
62
63vector<FrontendId> TunerClient::getFrontendIds() {
64 vector<FrontendId> ids;
shubang68f32a32020-12-29 00:34:24 -080065
66 if (mTunerService != NULL) {
67 vector<int32_t> v;
Amy Zhang9eeba432021-01-21 12:52:05 -080068 Status s = mTunerService->getFrontendIds(&v);
Amy Zhang4a07e802021-01-21 17:10:21 -080069 if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS || v.size() == 0) {
shubang68f32a32020-12-29 00:34:24 -080070 ids.clear();
71 return ids;
72 }
73 for (int32_t id : v) {
74 ids.push_back(static_cast<FrontendId>(id));
75 }
76 return ids;
77 }
Amy Zhangbf68a162020-11-23 17:42:40 -080078
79 if (mTuner != NULL) {
80 Result res;
81 mTuner->getFrontendIds([&](Result r, const hardware::hidl_vec<FrontendId>& frontendIds) {
82 res = r;
83 ids = frontendIds;
84 });
85 if (res != Result::SUCCESS || ids.size() == 0) {
86 ALOGW("Frontend ids not available");
87 ids.clear();
88 return ids;
89 }
90 return ids;
91 }
92
93 return ids;
94}
95
96
97sp<FrontendClient> TunerClient::openFrontend(int frontendHandle) {
98 if (mTunerService != NULL) {
Amy Zhangbf68a162020-11-23 17:42:40 -080099 shared_ptr<ITunerFrontend> tunerFrontend;
Amy Zhang4a07e802021-01-21 17:10:21 -0800100 Status s = mTunerService->openFrontend(frontendHandle, &tunerFrontend);
101 if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS
102 || tunerFrontend == NULL) {
Amy Zhangb9f3cab2021-01-13 15:24:14 -0800103 return NULL;
104 }
105 int id;
Amy Zhang4a07e802021-01-21 17:10:21 -0800106 s = tunerFrontend->getFrontendId(&id);
107 if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS) {
108 return NULL;
109 }
Amy Zhangd1fd5ac2021-01-13 16:30:24 -0800110 TunerFrontendInfo aidlFrontendInfo;
Amy Zhang4a07e802021-01-21 17:10:21 -0800111 s = mTunerService->getFrontendInfo(id, &aidlFrontendInfo);
112 if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS) {
113 return NULL;
114 }
Amy Zhangb9f3cab2021-01-13 15:24:14 -0800115 return new FrontendClient(tunerFrontend, frontendHandle, aidlFrontendInfo.type);
Amy Zhangbf68a162020-11-23 17:42:40 -0800116 }
117
118 if (mTuner != NULL) {
Amy Zhang210c26a2021-01-12 11:25:27 -0800119 int id = getResourceIdFromHandle(frontendHandle, FRONTEND);
120 sp<IFrontend> hidlFrontend = openHidlFrontendById(id);
Amy Zhangbf68a162020-11-23 17:42:40 -0800121 if (hidlFrontend != NULL) {
Amy Zhangb9f3cab2021-01-13 15:24:14 -0800122 FrontendInfo hidlInfo;
123 Result res = getHidlFrontendInfo(id, hidlInfo);
124 if (res != Result::SUCCESS) {
125 return NULL;
126 }
127 sp<FrontendClient> frontendClient = new FrontendClient(NULL, id, (int)hidlInfo.type);
Amy Zhangbf68a162020-11-23 17:42:40 -0800128 frontendClient->setHidlFrontend(hidlFrontend);
129 return frontendClient;
130 }
131 }
132
133 return NULL;
134}
135
136shared_ptr<FrontendInfo> TunerClient::getFrontendInfo(int id) {
137 if (mTunerService != NULL) {
Amy Zhangd1fd5ac2021-01-13 16:30:24 -0800138 TunerFrontendInfo aidlFrontendInfo;
Amy Zhangbf68a162020-11-23 17:42:40 -0800139 // TODO: handle error code
Amy Zhang4a07e802021-01-21 17:10:21 -0800140 Status s = mTunerService->getFrontendInfo(id, &aidlFrontendInfo);
141 if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS) {
142 return NULL;
143 }
Amy Zhangbf68a162020-11-23 17:42:40 -0800144 return make_shared<FrontendInfo>(FrontendInfoAidlToHidl(aidlFrontendInfo));
145 }
146
147 if (mTuner != NULL) {
148 FrontendInfo hidlInfo;
149 Result res = getHidlFrontendInfo(id, hidlInfo);
150 if (res != Result::SUCCESS) {
151 return NULL;
152 }
153 return make_shared<FrontendInfo>(hidlInfo);
154 }
155
156 return NULL;
157}
158
159shared_ptr<FrontendDtmbCapabilities> TunerClient::getFrontendDtmbCapabilities(int id) {
160 // pending aidl interface
161
162 if (mTuner_1_1 != NULL) {
163 Result result;
164 FrontendDtmbCapabilities dtmbCaps;
165 mTuner_1_1->getFrontendDtmbCapabilities(id,
166 [&](Result r, const FrontendDtmbCapabilities& caps) {
167 dtmbCaps = caps;
168 result = r;
169 });
170 if (result == Result::SUCCESS) {
171 return make_shared<FrontendDtmbCapabilities>(dtmbCaps);
172 }
173 }
174
175 return NULL;
176}
177
Amy Zhang4a07e802021-01-21 17:10:21 -0800178sp<DemuxClient> TunerClient::openDemux(int demuxHandle) {
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800179 if (mTunerService != NULL) {
Amy Zhang4a07e802021-01-21 17:10:21 -0800180 shared_ptr<ITunerDemux> tunerDemux;
181 Status s = mTunerService->openDemux(demuxHandle, &tunerDemux);
182 if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS) {
183 return NULL;
184 }
185 return new DemuxClient(tunerDemux);
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800186 }
187
188 if (mTuner != NULL) {
Amy Zhang4a07e802021-01-21 17:10:21 -0800189 sp<DemuxClient> demuxClient = new DemuxClient(NULL);
Amy Zhang921fd432021-01-07 13:18:27 -0800190 int demuxId;
191 sp<IDemux> hidlDemux = openHidlDemux(demuxId);
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800192 if (hidlDemux != NULL) {
193 demuxClient->setHidlDemux(hidlDemux);
Amy Zhang921fd432021-01-07 13:18:27 -0800194 demuxClient->setId(demuxId);
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800195 return demuxClient;
196 }
197 }
198
199 return NULL;
200}
201
Amy Zhang90a50b42021-01-11 16:58:59 -0800202shared_ptr<DemuxCapabilities> TunerClient::getDemuxCaps() {
Amy Zhang952794662021-02-04 15:56:22 -0800203 if (mTunerService != NULL) {
204 TunerDemuxCapabilities aidlCaps;
205 Status s = mTunerService->getDemuxCaps(&aidlCaps);
206 if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS) {
207 return NULL;
208 }
209 return make_shared<DemuxCapabilities>(getHidlDemuxCaps(aidlCaps));
210 }
Amy Zhang90a50b42021-01-11 16:58:59 -0800211
212 if (mTuner != NULL) {
213 Result res;
214 DemuxCapabilities caps;
215 mTuner->getDemuxCaps([&](Result r, const DemuxCapabilities& demuxCaps) {
216 caps = demuxCaps;
217 res = r;
218 });
219 if (res == Result::SUCCESS) {
220 return make_shared<DemuxCapabilities>(caps);
221 }
222 }
223
224 return NULL;
Amy Zhangb0f63ab2021-01-06 17:19:27 -0800225}
226
227sp<DescramblerClient> TunerClient::openDescrambler(int /*descramblerHandle*/) {
Amy Zhang921fd432021-01-07 13:18:27 -0800228 if (mTunerService != NULL) {
229 // TODO: handle error code
230 /*shared_ptr<ITunerDescrambler> tunerDescrambler;
231 mTunerService->openDescrambler(demuxHandle, &tunerDescrambler);
232 return new DescramblerClient(tunerDescrambler);*/
233 }
234
235 if (mTuner != NULL) {
236 // TODO: pending aidl interface
237 sp<DescramblerClient> descramblerClient = new DescramblerClient();
238 sp<IDescrambler> hidlDescrambler = openHidlDescrambler();
239 if (hidlDescrambler != NULL) {
240 descramblerClient->setHidlDescrambler(hidlDescrambler);
241 return descramblerClient;
242 }
243 }
244
Amy Zhangb5809be2021-01-26 16:27:23 -0800245 return NULL;
246}
Amy Zhangb0f63ab2021-01-06 17:19:27 -0800247
Amy Zhangd3d57b42021-01-07 11:14:43 -0800248sp<LnbClient> TunerClient::openLnb(int lnbHandle) {
249 if (mTunerService != NULL) {
Amy Zhang3ac0a3e2021-01-14 18:55:10 -0800250 shared_ptr<ITunerLnb> tunerLnb;
Amy Zhang4a07e802021-01-21 17:10:21 -0800251 Status s = mTunerService->openLnb(lnbHandle, &tunerLnb);
252 if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS) {
253 return NULL;
254 }
Amy Zhang3ac0a3e2021-01-14 18:55:10 -0800255 return new LnbClient(tunerLnb);
Amy Zhangd3d57b42021-01-07 11:14:43 -0800256 }
257
258 if (mTuner != NULL) {
259 int id = getResourceIdFromHandle(lnbHandle, LNB);
Amy Zhang3ac0a3e2021-01-14 18:55:10 -0800260 sp<LnbClient> lnbClient = new LnbClient(NULL);
Amy Zhangd3d57b42021-01-07 11:14:43 -0800261 sp<ILnb> hidlLnb = openHidlLnbById(id);
262 if (hidlLnb != NULL) {
263 lnbClient->setHidlLnb(hidlLnb);
264 lnbClient->setId(id);
265 return lnbClient;
266 }
267 }
268
Amy Zhangb0f63ab2021-01-06 17:19:27 -0800269 return NULL;
270}
271
Amy Zhangd3d57b42021-01-07 11:14:43 -0800272sp<LnbClient> TunerClient::openLnbByName(string lnbName) {
273 if (mTunerService != NULL) {
Amy Zhang3ac0a3e2021-01-14 18:55:10 -0800274 shared_ptr<ITunerLnb> tunerLnb;
Amy Zhang4a07e802021-01-21 17:10:21 -0800275 Status s = mTunerService->openLnbByName(lnbName, &tunerLnb);
276 if (ClientHelper::getServiceSpecificErrorCode(s) != Result::SUCCESS) {
277 return NULL;
278 }
Amy Zhang3ac0a3e2021-01-14 18:55:10 -0800279 return new LnbClient(tunerLnb);
Amy Zhangd3d57b42021-01-07 11:14:43 -0800280 }
281
282 if (mTuner != NULL) {
Amy Zhang3ac0a3e2021-01-14 18:55:10 -0800283 sp<LnbClient> lnbClient = new LnbClient(NULL);
Amy Zhangd3d57b42021-01-07 11:14:43 -0800284 LnbId id;
285 sp<ILnb> hidlLnb = openHidlLnbByName(lnbName, id);
286 if (hidlLnb != NULL) {
287 lnbClient->setHidlLnb(hidlLnb);
288 lnbClient->setId(id);
289 return lnbClient;
290 }
291 }
292
Amy Zhangb0f63ab2021-01-06 17:19:27 -0800293 return NULL;
294}
295
Amy Zhangbf68a162020-11-23 17:42:40 -0800296/////////////// TunerClient Helper Methods ///////////////////////
297
Amy Zhang39a3fa42020-12-21 16:56:03 -0800298void TunerClient::updateTunerResources() {
299 if (mTuner == NULL) {
300 return;
301 }
302
303 // Connect with Tuner Resource Manager.
304 ::ndk::SpAIBinder binder(AServiceManager_getService("tv_tuner_resource_mgr"));
305 mTunerResourceManager = ITunerResourceManager::fromBinder(binder);
306
307 updateFrontendResources();
308 updateLnbResources();
309 // TODO: update Demux, Descrambler.
310}
311
312void TunerClient::updateFrontendResources() {
313 vector<FrontendId> ids = getFrontendIds();
314 if (ids.size() == 0) {
315 return;
316 }
317 vector<TunerFrontendInfo> infos;
318 for (int i = 0; i < ids.size(); i++) {
319 shared_ptr<FrontendInfo> frontendInfo = getFrontendInfo((int)ids[i]);
320 if (frontendInfo == NULL) {
321 continue;
322 }
323 TunerFrontendInfo tunerFrontendInfo{
324 .handle = getResourceHandleFromId((int)ids[i], FRONTEND),
Amy Zhangd1fd5ac2021-01-13 16:30:24 -0800325 .type = static_cast<int>(frontendInfo->type),
Amy Zhang39a3fa42020-12-21 16:56:03 -0800326 .exclusiveGroupId = static_cast<int>(frontendInfo->exclusiveGroupId),
327 };
328 infos.push_back(tunerFrontendInfo);
329 }
330 mTunerResourceManager->setFrontendInfoList(infos);
331}
332
333void TunerClient::updateLnbResources() {
334 vector<int> handles = getLnbHandles();
335 if (handles.size() == 0) {
336 return;
337 }
338 mTunerResourceManager->setLnbInfoList(handles);
339}
340
Amy Zhangbf68a162020-11-23 17:42:40 -0800341sp<ITuner> TunerClient::getHidlTuner() {
342 if (mTuner == NULL) {
343 mTunerVersion = 0;
344 mTuner_1_1 = ::android::hardware::tv::tuner::V1_1::ITuner::getService();
345
346 if (mTuner_1_1 == NULL) {
347 ALOGW("Failed to get tuner 1.1 service.");
348 mTuner = ITuner::getService();
349 if (mTuner == NULL) {
350 ALOGW("Failed to get tuner 1.0 service.");
351 } else {
352 mTunerVersion = 1 << 16;
353 }
354 } else {
355 mTuner = static_cast<sp<ITuner>>(mTuner_1_1);
356 mTunerVersion = ((1 << 16) | 1);
357 }
358 }
359 return mTuner;
360}
361
Amy Zhang210c26a2021-01-12 11:25:27 -0800362sp<IFrontend> TunerClient::openHidlFrontendById(int id) {
Amy Zhangbf68a162020-11-23 17:42:40 -0800363 sp<IFrontend> fe;
364 Result res;
Amy Zhangbf68a162020-11-23 17:42:40 -0800365 mTuner->openFrontendById(id, [&](Result r, const sp<IFrontend>& frontend) {
366 fe = frontend;
367 res = r;
368 });
369 if (res != Result::SUCCESS || fe == nullptr) {
370 ALOGE("Failed to open frontend");
371 return NULL;
372 }
373 return fe;
374}
375
376Result TunerClient::getHidlFrontendInfo(int id, FrontendInfo& feInfo) {
377 Result res;
378 mTuner->getFrontendInfo(id, [&](Result r, const FrontendInfo& info) {
379 feInfo = info;
380 res = r;
381 });
382 return res;
383}
384
Amy Zhang921fd432021-01-07 13:18:27 -0800385sp<IDemux> TunerClient::openHidlDemux(int& demuxId) {
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800386 sp<IDemux> demux;
387 Result res;
388
Amy Zhang921fd432021-01-07 13:18:27 -0800389 mTuner->openDemux([&](Result result, uint32_t id, const sp<IDemux>& demuxSp) {
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800390 demux = demuxSp;
Amy Zhang921fd432021-01-07 13:18:27 -0800391 demuxId = id;
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800392 res = result;
393 });
394 if (res != Result::SUCCESS || demux == nullptr) {
395 ALOGE("Failed to open demux");
396 return NULL;
397 }
398 return demux;
399}
400
Amy Zhangd3d57b42021-01-07 11:14:43 -0800401sp<ILnb> TunerClient::openHidlLnbById(int id) {
402 sp<ILnb> lnb;
403 Result res;
404
405 mTuner->openLnbById(id, [&](Result r, const sp<ILnb>& lnbSp) {
406 res = r;
407 lnb = lnbSp;
408 });
409 if (res != Result::SUCCESS || lnb == nullptr) {
410 ALOGE("Failed to open lnb by id");
411 return NULL;
412 }
413 return lnb;
414}
415
416sp<ILnb> TunerClient::openHidlLnbByName(string name, LnbId& lnbId) {
417 sp<ILnb> lnb;
418 Result res;
419
420 mTuner->openLnbByName(name, [&](Result r, LnbId id, const sp<ILnb>& lnbSp) {
421 res = r;
422 lnb = lnbSp;
423 lnbId = id;
424 });
425 if (res != Result::SUCCESS || lnb == nullptr) {
426 ALOGE("Failed to open lnb by name");
427 return NULL;
428 }
429 return lnb;
430}
431
Amy Zhang39a3fa42020-12-21 16:56:03 -0800432vector<int> TunerClient::getLnbHandles() {
433 vector<int> lnbHandles;
Amy Zhang39a3fa42020-12-21 16:56:03 -0800434 if (mTuner != NULL) {
435 Result res;
436 vector<LnbId> lnbIds;
437 mTuner->getLnbIds([&](Result r, const hardware::hidl_vec<LnbId>& ids) {
438 lnbIds = ids;
439 res = r;
440 });
441 if (res != Result::SUCCESS || lnbIds.size() == 0) {
442 ALOGW("Lnb isn't available");
443 } else {
444 for (int i = 0; i < lnbIds.size(); i++) {
445 lnbHandles.push_back(getResourceHandleFromId((int)lnbIds[i], LNB));
446 }
447 }
448 }
449
450 return lnbHandles;
451}
452
Amy Zhang4a07e802021-01-21 17:10:21 -0800453sp<IDescrambler> TunerClient::openHidlDescrambler() {
454 sp<IDescrambler> descrambler;
455 Result res;
456
457 mTuner->openDescrambler([&](Result r, const sp<IDescrambler>& descramblerSp) {
458 res = r;
459 descrambler = descramblerSp;
460 });
461
462 if (res != Result::SUCCESS || descrambler == NULL) {
463 return NULL;
464 }
465
466 return descrambler;
467}
468
Amy Zhang952794662021-02-04 15:56:22 -0800469DemuxCapabilities TunerClient::getHidlDemuxCaps(TunerDemuxCapabilities& aidlCaps) {
470 DemuxCapabilities caps{
471 .numDemux = (uint32_t)aidlCaps.numDemux,
472 .numRecord = (uint32_t)aidlCaps.numRecord,
473 .numPlayback = (uint32_t)aidlCaps.numPlayback,
474 .numTsFilter = (uint32_t)aidlCaps.numTsFilter,
475 .numSectionFilter = (uint32_t)aidlCaps.numSectionFilter,
476 .numAudioFilter = (uint32_t)aidlCaps.numAudioFilter,
477 .numVideoFilter = (uint32_t)aidlCaps.numVideoFilter,
478 .numPesFilter = (uint32_t)aidlCaps.numPesFilter,
479 .numPcrFilter = (uint32_t)aidlCaps.numPcrFilter,
480 .numBytesInSectionFilter = (uint32_t)aidlCaps.numBytesInSectionFilter,
481 .filterCaps = (uint32_t)aidlCaps.filterCaps,
482 .bTimeFilter = aidlCaps.bTimeFilter,
483 };
484 caps.linkCaps.resize(aidlCaps.linkCaps.size());
485 copy(aidlCaps.linkCaps.begin(), aidlCaps.linkCaps.end(), caps.linkCaps.begin());
486 return caps;
487}
488
Amy Zhangd1fd5ac2021-01-13 16:30:24 -0800489FrontendInfo TunerClient::FrontendInfoAidlToHidl(TunerFrontendInfo aidlFrontendInfo) {
Amy Zhangbf68a162020-11-23 17:42:40 -0800490 FrontendInfo hidlFrontendInfo {
491 .type = static_cast<FrontendType>(aidlFrontendInfo.type),
492 .minFrequency = static_cast<uint32_t>(aidlFrontendInfo.minFrequency),
493 .maxFrequency = static_cast<uint32_t>(aidlFrontendInfo.maxFrequency),
494 .minSymbolRate = static_cast<uint32_t>(aidlFrontendInfo.minSymbolRate),
495 .maxSymbolRate = static_cast<uint32_t>(aidlFrontendInfo.maxSymbolRate),
496 .acquireRange = static_cast<uint32_t>(aidlFrontendInfo.acquireRange),
497 .exclusiveGroupId = static_cast<uint32_t>(aidlFrontendInfo.exclusiveGroupId),
498 };
499 // TODO: handle Frontend caps
500
501 return hidlFrontendInfo;
502}
Amy Zhang210c26a2021-01-12 11:25:27 -0800503
504int TunerClient::getResourceIdFromHandle(int handle, int /*resourceType*/) {
505 return (handle & 0x00ff0000) >> 16;
506}
507
508int TunerClient::getResourceHandleFromId(int id, int resourceType) {
509 // TODO: build up randomly generated id to handle mapping
510 return (resourceType & 0x000000ff) << 24
511 | (id << 16)
512 | (mResourceRequestCount++ & 0xffff);
513}
Amy Zhangbf68a162020-11-23 17:42:40 -0800514} // namespace android