blob: a26753dd65a6b90a1160e5d4de9ec5f4bb515105 [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
Amy Zhang39a3fa42020-12-21 16:56:03 -080028using ::aidl::android::media::tv::tunerresourcemanager::TunerFrontendInfo;
29
Amy Zhangbf68a162020-11-23 17:42:40 -080030namespace android {
31
32sp<ITuner> TunerClient::mTuner;
33sp<::android::hardware::tv::tuner::V1_1::ITuner> TunerClient::mTuner_1_1;
34shared_ptr<ITunerService> TunerClient::mTunerService;
35int TunerClient::mTunerVersion;
36
37/////////////// TunerClient ///////////////////////
38
39TunerClient::TunerClient() {
40 // Get HIDL Tuner in migration stage.
41 getHidlTuner();
Amy Zhang39a3fa42020-12-21 16:56:03 -080042 updateTunerResources();
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");
50 }
51}
52
53TunerClient::~TunerClient() {
54 mTuner = NULL;
55 mTuner_1_1 = NULL;
56 mTunerVersion = 0;
57 mTunerService = NULL;
58}
59
60vector<FrontendId> TunerClient::getFrontendIds() {
61 vector<FrontendId> ids;
shubang68f32a32020-12-29 00:34:24 -080062
63 if (mTunerService != NULL) {
64 vector<int32_t> v;
65 int aidl_return;
66 Status s = mTunerService->getFrontendIds(&v, &aidl_return);
67 if (!s.isOk() || aidl_return != (int) Result::SUCCESS
68 || v.size() == 0) {
69 ids.clear();
70 return ids;
71 }
72 for (int32_t id : v) {
73 ids.push_back(static_cast<FrontendId>(id));
74 }
75 return ids;
76 }
Amy Zhangbf68a162020-11-23 17:42:40 -080077
78 if (mTuner != NULL) {
79 Result res;
80 mTuner->getFrontendIds([&](Result r, const hardware::hidl_vec<FrontendId>& frontendIds) {
81 res = r;
82 ids = frontendIds;
83 });
84 if (res != Result::SUCCESS || ids.size() == 0) {
85 ALOGW("Frontend ids not available");
86 ids.clear();
87 return ids;
88 }
89 return ids;
90 }
91
92 return ids;
93}
94
95
96sp<FrontendClient> TunerClient::openFrontend(int frontendHandle) {
97 if (mTunerService != NULL) {
98 // TODO: handle error code
99 shared_ptr<ITunerFrontend> tunerFrontend;
100 mTunerService->openFrontend(frontendHandle, &tunerFrontend);
Amy Zhangb9f3cab2021-01-13 15:24:14 -0800101 if (tunerFrontend == NULL) {
102 return NULL;
103 }
104 int id;
105 // TODO: handle error code
106 tunerFrontend->getFrontendId(&id);
107 TunerServiceFrontendInfo aidlFrontendInfo;
108 // TODO: handle error code
109 mTunerService->getFrontendInfo(id, &aidlFrontendInfo);
110 return new FrontendClient(tunerFrontend, frontendHandle, aidlFrontendInfo.type);
Amy Zhangbf68a162020-11-23 17:42:40 -0800111 }
112
113 if (mTuner != NULL) {
Amy Zhang210c26a2021-01-12 11:25:27 -0800114 int id = getResourceIdFromHandle(frontendHandle, FRONTEND);
115 sp<IFrontend> hidlFrontend = openHidlFrontendById(id);
Amy Zhangbf68a162020-11-23 17:42:40 -0800116 if (hidlFrontend != NULL) {
Amy Zhangb9f3cab2021-01-13 15:24:14 -0800117 FrontendInfo hidlInfo;
118 Result res = getHidlFrontendInfo(id, hidlInfo);
119 if (res != Result::SUCCESS) {
120 return NULL;
121 }
122 sp<FrontendClient> frontendClient = new FrontendClient(NULL, id, (int)hidlInfo.type);
Amy Zhangbf68a162020-11-23 17:42:40 -0800123 frontendClient->setHidlFrontend(hidlFrontend);
124 return frontendClient;
125 }
126 }
127
128 return NULL;
129}
130
131shared_ptr<FrontendInfo> TunerClient::getFrontendInfo(int id) {
132 if (mTunerService != NULL) {
133 TunerServiceFrontendInfo aidlFrontendInfo;
134 // TODO: handle error code
135 mTunerService->getFrontendInfo(id, &aidlFrontendInfo);
136 return make_shared<FrontendInfo>(FrontendInfoAidlToHidl(aidlFrontendInfo));
137 }
138
139 if (mTuner != NULL) {
140 FrontendInfo hidlInfo;
141 Result res = getHidlFrontendInfo(id, hidlInfo);
142 if (res != Result::SUCCESS) {
143 return NULL;
144 }
145 return make_shared<FrontendInfo>(hidlInfo);
146 }
147
148 return NULL;
149}
150
151shared_ptr<FrontendDtmbCapabilities> TunerClient::getFrontendDtmbCapabilities(int id) {
152 // pending aidl interface
153
154 if (mTuner_1_1 != NULL) {
155 Result result;
156 FrontendDtmbCapabilities dtmbCaps;
157 mTuner_1_1->getFrontendDtmbCapabilities(id,
158 [&](Result r, const FrontendDtmbCapabilities& caps) {
159 dtmbCaps = caps;
160 result = r;
161 });
162 if (result == Result::SUCCESS) {
163 return make_shared<FrontendDtmbCapabilities>(dtmbCaps);
164 }
165 }
166
167 return NULL;
168}
169
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800170sp<DemuxClient> TunerClient::openDemux(int /*demuxHandle*/) {
171 if (mTunerService != NULL) {
172 // TODO: handle error code
173 /*shared_ptr<ITunerDemux> tunerDemux;
174 mTunerService->openDemux(demuxHandle, &tunerDemux);
175 return new DemuxClient(tunerDemux);*/
176 }
177
178 if (mTuner != NULL) {
179 // TODO: pending aidl interface
180 sp<DemuxClient> demuxClient = new DemuxClient();
Amy Zhang921fd432021-01-07 13:18:27 -0800181 int demuxId;
182 sp<IDemux> hidlDemux = openHidlDemux(demuxId);
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800183 if (hidlDemux != NULL) {
184 demuxClient->setHidlDemux(hidlDemux);
Amy Zhang921fd432021-01-07 13:18:27 -0800185 demuxClient->setId(demuxId);
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800186 return demuxClient;
187 }
188 }
189
190 return NULL;
191}
192
Amy Zhang90a50b42021-01-11 16:58:59 -0800193shared_ptr<DemuxCapabilities> TunerClient::getDemuxCaps() {
194 // pending aidl interface
195
196 if (mTuner != NULL) {
197 Result res;
198 DemuxCapabilities caps;
199 mTuner->getDemuxCaps([&](Result r, const DemuxCapabilities& demuxCaps) {
200 caps = demuxCaps;
201 res = r;
202 });
203 if (res == Result::SUCCESS) {
204 return make_shared<DemuxCapabilities>(caps);
205 }
206 }
207
208 return NULL;
Amy Zhangb0f63ab2021-01-06 17:19:27 -0800209}
210
211sp<DescramblerClient> TunerClient::openDescrambler(int /*descramblerHandle*/) {
Amy Zhang921fd432021-01-07 13:18:27 -0800212 if (mTunerService != NULL) {
213 // TODO: handle error code
214 /*shared_ptr<ITunerDescrambler> tunerDescrambler;
215 mTunerService->openDescrambler(demuxHandle, &tunerDescrambler);
216 return new DescramblerClient(tunerDescrambler);*/
217 }
218
219 if (mTuner != NULL) {
220 // TODO: pending aidl interface
221 sp<DescramblerClient> descramblerClient = new DescramblerClient();
222 sp<IDescrambler> hidlDescrambler = openHidlDescrambler();
223 if (hidlDescrambler != NULL) {
224 descramblerClient->setHidlDescrambler(hidlDescrambler);
225 return descramblerClient;
226 }
227 }
228
229 return NULL;}
Amy Zhangb0f63ab2021-01-06 17:19:27 -0800230
Amy Zhangd3d57b42021-01-07 11:14:43 -0800231sp<LnbClient> TunerClient::openLnb(int lnbHandle) {
232 if (mTunerService != NULL) {
233 // TODO: handle error code
234 /*shared_ptr<ITunerLnb> tunerLnb;
235 mTunerService->openLnb(demuxHandle, &tunerLnb);
236 return new LnbClient(tunerLnb);*/
237 }
238
239 if (mTuner != NULL) {
240 int id = getResourceIdFromHandle(lnbHandle, LNB);
241 // TODO: pending aidl interface
242 sp<LnbClient> lnbClient = new LnbClient();
243 sp<ILnb> hidlLnb = openHidlLnbById(id);
244 if (hidlLnb != NULL) {
245 lnbClient->setHidlLnb(hidlLnb);
246 lnbClient->setId(id);
247 return lnbClient;
248 }
249 }
250
Amy Zhangb0f63ab2021-01-06 17:19:27 -0800251 return NULL;
252}
253
Amy Zhangd3d57b42021-01-07 11:14:43 -0800254sp<LnbClient> TunerClient::openLnbByName(string lnbName) {
255 if (mTunerService != NULL) {
256 // TODO: handle error code
257 /*shared_ptr<ITunerLnb> tunerLnb;
258 mTunerService->openLnbByName(lnbName, &tunerLnb);
259 return new LnbClient(tunerLnb);*/
260 }
261
262 if (mTuner != NULL) {
263 // TODO: pending aidl interface
264 sp<LnbClient> lnbClient = new LnbClient();
265 LnbId id;
266 sp<ILnb> hidlLnb = openHidlLnbByName(lnbName, id);
267 if (hidlLnb != NULL) {
268 lnbClient->setHidlLnb(hidlLnb);
269 lnbClient->setId(id);
270 return lnbClient;
271 }
272 }
273
Amy Zhangb0f63ab2021-01-06 17:19:27 -0800274 return NULL;
275}
276
Amy Zhangbf68a162020-11-23 17:42:40 -0800277/////////////// TunerClient Helper Methods ///////////////////////
278
Amy Zhang39a3fa42020-12-21 16:56:03 -0800279void TunerClient::updateTunerResources() {
280 if (mTuner == NULL) {
281 return;
282 }
283
284 // Connect with Tuner Resource Manager.
285 ::ndk::SpAIBinder binder(AServiceManager_getService("tv_tuner_resource_mgr"));
286 mTunerResourceManager = ITunerResourceManager::fromBinder(binder);
287
288 updateFrontendResources();
289 updateLnbResources();
290 // TODO: update Demux, Descrambler.
291}
292
293void TunerClient::updateFrontendResources() {
294 vector<FrontendId> ids = getFrontendIds();
295 if (ids.size() == 0) {
296 return;
297 }
298 vector<TunerFrontendInfo> infos;
299 for (int i = 0; i < ids.size(); i++) {
300 shared_ptr<FrontendInfo> frontendInfo = getFrontendInfo((int)ids[i]);
301 if (frontendInfo == NULL) {
302 continue;
303 }
304 TunerFrontendInfo tunerFrontendInfo{
305 .handle = getResourceHandleFromId((int)ids[i], FRONTEND),
306 .frontendType = static_cast<int>(frontendInfo->type),
307 .exclusiveGroupId = static_cast<int>(frontendInfo->exclusiveGroupId),
308 };
309 infos.push_back(tunerFrontendInfo);
310 }
311 mTunerResourceManager->setFrontendInfoList(infos);
312}
313
314void TunerClient::updateLnbResources() {
315 vector<int> handles = getLnbHandles();
316 if (handles.size() == 0) {
317 return;
318 }
319 mTunerResourceManager->setLnbInfoList(handles);
320}
321
Amy Zhangbf68a162020-11-23 17:42:40 -0800322sp<ITuner> TunerClient::getHidlTuner() {
323 if (mTuner == NULL) {
324 mTunerVersion = 0;
325 mTuner_1_1 = ::android::hardware::tv::tuner::V1_1::ITuner::getService();
326
327 if (mTuner_1_1 == NULL) {
328 ALOGW("Failed to get tuner 1.1 service.");
329 mTuner = ITuner::getService();
330 if (mTuner == NULL) {
331 ALOGW("Failed to get tuner 1.0 service.");
332 } else {
333 mTunerVersion = 1 << 16;
334 }
335 } else {
336 mTuner = static_cast<sp<ITuner>>(mTuner_1_1);
337 mTunerVersion = ((1 << 16) | 1);
338 }
339 }
340 return mTuner;
341}
342
Amy Zhang210c26a2021-01-12 11:25:27 -0800343sp<IFrontend> TunerClient::openHidlFrontendById(int id) {
Amy Zhangbf68a162020-11-23 17:42:40 -0800344 sp<IFrontend> fe;
345 Result res;
Amy Zhangbf68a162020-11-23 17:42:40 -0800346 mTuner->openFrontendById(id, [&](Result r, const sp<IFrontend>& frontend) {
347 fe = frontend;
348 res = r;
349 });
350 if (res != Result::SUCCESS || fe == nullptr) {
351 ALOGE("Failed to open frontend");
352 return NULL;
353 }
354 return fe;
355}
356
357Result TunerClient::getHidlFrontendInfo(int id, FrontendInfo& feInfo) {
358 Result res;
359 mTuner->getFrontendInfo(id, [&](Result r, const FrontendInfo& info) {
360 feInfo = info;
361 res = r;
362 });
363 return res;
364}
365
Amy Zhang921fd432021-01-07 13:18:27 -0800366sp<IDemux> TunerClient::openHidlDemux(int& demuxId) {
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800367 sp<IDemux> demux;
368 Result res;
369
Amy Zhang921fd432021-01-07 13:18:27 -0800370 mTuner->openDemux([&](Result result, uint32_t id, const sp<IDemux>& demuxSp) {
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800371 demux = demuxSp;
Amy Zhang921fd432021-01-07 13:18:27 -0800372 demuxId = id;
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800373 res = result;
374 });
375 if (res != Result::SUCCESS || demux == nullptr) {
376 ALOGE("Failed to open demux");
377 return NULL;
378 }
379 return demux;
380}
381
Amy Zhangd3d57b42021-01-07 11:14:43 -0800382sp<ILnb> TunerClient::openHidlLnbById(int id) {
383 sp<ILnb> lnb;
384 Result res;
385
386 mTuner->openLnbById(id, [&](Result r, const sp<ILnb>& lnbSp) {
387 res = r;
388 lnb = lnbSp;
389 });
390 if (res != Result::SUCCESS || lnb == nullptr) {
391 ALOGE("Failed to open lnb by id");
392 return NULL;
393 }
394 return lnb;
395}
396
397sp<ILnb> TunerClient::openHidlLnbByName(string name, LnbId& lnbId) {
398 sp<ILnb> lnb;
399 Result res;
400
401 mTuner->openLnbByName(name, [&](Result r, LnbId id, const sp<ILnb>& lnbSp) {
402 res = r;
403 lnb = lnbSp;
404 lnbId = id;
405 });
406 if (res != Result::SUCCESS || lnb == nullptr) {
407 ALOGE("Failed to open lnb by name");
408 return NULL;
409 }
410 return lnb;
411}
412
Amy Zhang921fd432021-01-07 13:18:27 -0800413sp<IDescrambler> TunerClient::openHidlDescrambler() {
414 sp<IDescrambler> descrambler;
415 Result res;
416
417 mTuner->openDescrambler([&](Result r, const sp<IDescrambler>& descramblerSp) {
418 res = r;
419 descrambler = descramblerSp;
420 });
421
422 if (res != Result::SUCCESS || descrambler == NULL) {
423 return NULL;
424 }
425
426 return descrambler;
427}
428
Amy Zhang39a3fa42020-12-21 16:56:03 -0800429vector<int> TunerClient::getLnbHandles() {
430 vector<int> lnbHandles;
431
432 if (mTunerService != NULL) {
433 // TODO: pending hidl interface
434 }
435
436 if (mTuner != NULL) {
437 Result res;
438 vector<LnbId> lnbIds;
439 mTuner->getLnbIds([&](Result r, const hardware::hidl_vec<LnbId>& ids) {
440 lnbIds = ids;
441 res = r;
442 });
443 if (res != Result::SUCCESS || lnbIds.size() == 0) {
444 ALOGW("Lnb isn't available");
445 } else {
446 for (int i = 0; i < lnbIds.size(); i++) {
447 lnbHandles.push_back(getResourceHandleFromId((int)lnbIds[i], LNB));
448 }
449 }
450 }
451
452 return lnbHandles;
453}
454
Amy Zhangbf68a162020-11-23 17:42:40 -0800455FrontendInfo TunerClient::FrontendInfoAidlToHidl(TunerServiceFrontendInfo aidlFrontendInfo) {
456 FrontendInfo hidlFrontendInfo {
457 .type = static_cast<FrontendType>(aidlFrontendInfo.type),
458 .minFrequency = static_cast<uint32_t>(aidlFrontendInfo.minFrequency),
459 .maxFrequency = static_cast<uint32_t>(aidlFrontendInfo.maxFrequency),
460 .minSymbolRate = static_cast<uint32_t>(aidlFrontendInfo.minSymbolRate),
461 .maxSymbolRate = static_cast<uint32_t>(aidlFrontendInfo.maxSymbolRate),
462 .acquireRange = static_cast<uint32_t>(aidlFrontendInfo.acquireRange),
463 .exclusiveGroupId = static_cast<uint32_t>(aidlFrontendInfo.exclusiveGroupId),
464 };
465 // TODO: handle Frontend caps
466
467 return hidlFrontendInfo;
468}
Amy Zhang210c26a2021-01-12 11:25:27 -0800469
470int TunerClient::getResourceIdFromHandle(int handle, int /*resourceType*/) {
471 return (handle & 0x00ff0000) >> 16;
472}
473
474int TunerClient::getResourceHandleFromId(int id, int resourceType) {
475 // TODO: build up randomly generated id to handle mapping
476 return (resourceType & 0x000000ff) << 24
477 | (id << 16)
478 | (mResourceRequestCount++ & 0xffff);
479}
Amy Zhangbf68a162020-11-23 17:42:40 -0800480} // namespace android