blob: 73a2cf29d50e218136bbfca6ebccbe15839795be [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);
69 if (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) {
99 // TODO: handle error code
100 shared_ptr<ITunerFrontend> tunerFrontend;
101 mTunerService->openFrontend(frontendHandle, &tunerFrontend);
Amy Zhangb9f3cab2021-01-13 15:24:14 -0800102 if (tunerFrontend == NULL) {
103 return NULL;
104 }
105 int id;
106 // TODO: handle error code
107 tunerFrontend->getFrontendId(&id);
Amy Zhangd1fd5ac2021-01-13 16:30:24 -0800108 TunerFrontendInfo aidlFrontendInfo;
Amy Zhangb9f3cab2021-01-13 15:24:14 -0800109 // TODO: handle error code
110 mTunerService->getFrontendInfo(id, &aidlFrontendInfo);
111 return new FrontendClient(tunerFrontend, frontendHandle, aidlFrontendInfo.type);
Amy Zhangbf68a162020-11-23 17:42:40 -0800112 }
113
114 if (mTuner != NULL) {
Amy Zhang210c26a2021-01-12 11:25:27 -0800115 int id = getResourceIdFromHandle(frontendHandle, FRONTEND);
116 sp<IFrontend> hidlFrontend = openHidlFrontendById(id);
Amy Zhangbf68a162020-11-23 17:42:40 -0800117 if (hidlFrontend != NULL) {
Amy Zhangb9f3cab2021-01-13 15:24:14 -0800118 FrontendInfo hidlInfo;
119 Result res = getHidlFrontendInfo(id, hidlInfo);
120 if (res != Result::SUCCESS) {
121 return NULL;
122 }
123 sp<FrontendClient> frontendClient = new FrontendClient(NULL, id, (int)hidlInfo.type);
Amy Zhangbf68a162020-11-23 17:42:40 -0800124 frontendClient->setHidlFrontend(hidlFrontend);
125 return frontendClient;
126 }
127 }
128
129 return NULL;
130}
131
132shared_ptr<FrontendInfo> TunerClient::getFrontendInfo(int id) {
133 if (mTunerService != NULL) {
Amy Zhangd1fd5ac2021-01-13 16:30:24 -0800134 TunerFrontendInfo aidlFrontendInfo;
Amy Zhangbf68a162020-11-23 17:42:40 -0800135 // TODO: handle error code
136 mTunerService->getFrontendInfo(id, &aidlFrontendInfo);
137 return make_shared<FrontendInfo>(FrontendInfoAidlToHidl(aidlFrontendInfo));
138 }
139
140 if (mTuner != NULL) {
141 FrontendInfo hidlInfo;
142 Result res = getHidlFrontendInfo(id, hidlInfo);
143 if (res != Result::SUCCESS) {
144 return NULL;
145 }
146 return make_shared<FrontendInfo>(hidlInfo);
147 }
148
149 return NULL;
150}
151
152shared_ptr<FrontendDtmbCapabilities> TunerClient::getFrontendDtmbCapabilities(int id) {
153 // pending aidl interface
154
155 if (mTuner_1_1 != NULL) {
156 Result result;
157 FrontendDtmbCapabilities dtmbCaps;
158 mTuner_1_1->getFrontendDtmbCapabilities(id,
159 [&](Result r, const FrontendDtmbCapabilities& caps) {
160 dtmbCaps = caps;
161 result = r;
162 });
163 if (result == Result::SUCCESS) {
164 return make_shared<FrontendDtmbCapabilities>(dtmbCaps);
165 }
166 }
167
168 return NULL;
169}
170
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800171sp<DemuxClient> TunerClient::openDemux(int /*demuxHandle*/) {
172 if (mTunerService != NULL) {
173 // TODO: handle error code
174 /*shared_ptr<ITunerDemux> tunerDemux;
175 mTunerService->openDemux(demuxHandle, &tunerDemux);
176 return new DemuxClient(tunerDemux);*/
177 }
178
179 if (mTuner != NULL) {
180 // TODO: pending aidl interface
181 sp<DemuxClient> demuxClient = new DemuxClient();
Amy Zhang921fd432021-01-07 13:18:27 -0800182 int demuxId;
183 sp<IDemux> hidlDemux = openHidlDemux(demuxId);
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800184 if (hidlDemux != NULL) {
185 demuxClient->setHidlDemux(hidlDemux);
Amy Zhang921fd432021-01-07 13:18:27 -0800186 demuxClient->setId(demuxId);
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800187 return demuxClient;
188 }
189 }
190
191 return NULL;
192}
193
Amy Zhang90a50b42021-01-11 16:58:59 -0800194shared_ptr<DemuxCapabilities> TunerClient::getDemuxCaps() {
195 // pending aidl interface
196
197 if (mTuner != NULL) {
198 Result res;
199 DemuxCapabilities caps;
200 mTuner->getDemuxCaps([&](Result r, const DemuxCapabilities& demuxCaps) {
201 caps = demuxCaps;
202 res = r;
203 });
204 if (res == Result::SUCCESS) {
205 return make_shared<DemuxCapabilities>(caps);
206 }
207 }
208
209 return NULL;
Amy Zhangb0f63ab2021-01-06 17:19:27 -0800210}
211
212sp<DescramblerClient> TunerClient::openDescrambler(int /*descramblerHandle*/) {
Amy Zhang921fd432021-01-07 13:18:27 -0800213 if (mTunerService != NULL) {
214 // TODO: handle error code
215 /*shared_ptr<ITunerDescrambler> tunerDescrambler;
216 mTunerService->openDescrambler(demuxHandle, &tunerDescrambler);
217 return new DescramblerClient(tunerDescrambler);*/
218 }
219
220 if (mTuner != NULL) {
221 // TODO: pending aidl interface
222 sp<DescramblerClient> descramblerClient = new DescramblerClient();
223 sp<IDescrambler> hidlDescrambler = openHidlDescrambler();
224 if (hidlDescrambler != NULL) {
225 descramblerClient->setHidlDescrambler(hidlDescrambler);
226 return descramblerClient;
227 }
228 }
229
230 return NULL;}
Amy Zhangb0f63ab2021-01-06 17:19:27 -0800231
Amy Zhangd3d57b42021-01-07 11:14:43 -0800232sp<LnbClient> TunerClient::openLnb(int lnbHandle) {
233 if (mTunerService != NULL) {
234 // TODO: handle error code
Amy Zhang3ac0a3e2021-01-14 18:55:10 -0800235 shared_ptr<ITunerLnb> tunerLnb;
236 mTunerService->openLnb(lnbHandle, &tunerLnb);
237 return new LnbClient(tunerLnb);
Amy Zhangd3d57b42021-01-07 11:14:43 -0800238 }
239
240 if (mTuner != NULL) {
241 int id = getResourceIdFromHandle(lnbHandle, LNB);
242 // TODO: pending aidl interface
Amy Zhang3ac0a3e2021-01-14 18:55:10 -0800243 sp<LnbClient> lnbClient = new LnbClient(NULL);
Amy Zhangd3d57b42021-01-07 11:14:43 -0800244 sp<ILnb> hidlLnb = openHidlLnbById(id);
245 if (hidlLnb != NULL) {
246 lnbClient->setHidlLnb(hidlLnb);
247 lnbClient->setId(id);
248 return lnbClient;
249 }
250 }
251
Amy Zhangb0f63ab2021-01-06 17:19:27 -0800252 return NULL;
253}
254
Amy Zhangd3d57b42021-01-07 11:14:43 -0800255sp<LnbClient> TunerClient::openLnbByName(string lnbName) {
256 if (mTunerService != NULL) {
257 // TODO: handle error code
Amy Zhang3ac0a3e2021-01-14 18:55:10 -0800258 shared_ptr<ITunerLnb> tunerLnb;
Amy Zhangd3d57b42021-01-07 11:14:43 -0800259 mTunerService->openLnbByName(lnbName, &tunerLnb);
Amy Zhang3ac0a3e2021-01-14 18:55:10 -0800260 return new LnbClient(tunerLnb);
Amy Zhangd3d57b42021-01-07 11:14:43 -0800261 }
262
263 if (mTuner != NULL) {
264 // TODO: pending aidl interface
Amy Zhang3ac0a3e2021-01-14 18:55:10 -0800265 sp<LnbClient> lnbClient = new LnbClient(NULL);
Amy Zhangd3d57b42021-01-07 11:14:43 -0800266 LnbId id;
267 sp<ILnb> hidlLnb = openHidlLnbByName(lnbName, id);
268 if (hidlLnb != NULL) {
269 lnbClient->setHidlLnb(hidlLnb);
270 lnbClient->setId(id);
271 return lnbClient;
272 }
273 }
274
Amy Zhangb0f63ab2021-01-06 17:19:27 -0800275 return NULL;
276}
277
Amy Zhangbf68a162020-11-23 17:42:40 -0800278/////////////// TunerClient Helper Methods ///////////////////////
279
Amy Zhang39a3fa42020-12-21 16:56:03 -0800280void TunerClient::updateTunerResources() {
281 if (mTuner == NULL) {
282 return;
283 }
284
285 // Connect with Tuner Resource Manager.
286 ::ndk::SpAIBinder binder(AServiceManager_getService("tv_tuner_resource_mgr"));
287 mTunerResourceManager = ITunerResourceManager::fromBinder(binder);
288
289 updateFrontendResources();
290 updateLnbResources();
291 // TODO: update Demux, Descrambler.
292}
293
294void TunerClient::updateFrontendResources() {
295 vector<FrontendId> ids = getFrontendIds();
296 if (ids.size() == 0) {
297 return;
298 }
299 vector<TunerFrontendInfo> infos;
300 for (int i = 0; i < ids.size(); i++) {
301 shared_ptr<FrontendInfo> frontendInfo = getFrontendInfo((int)ids[i]);
302 if (frontendInfo == NULL) {
303 continue;
304 }
305 TunerFrontendInfo tunerFrontendInfo{
306 .handle = getResourceHandleFromId((int)ids[i], FRONTEND),
Amy Zhangd1fd5ac2021-01-13 16:30:24 -0800307 .type = static_cast<int>(frontendInfo->type),
Amy Zhang39a3fa42020-12-21 16:56:03 -0800308 .exclusiveGroupId = static_cast<int>(frontendInfo->exclusiveGroupId),
309 };
310 infos.push_back(tunerFrontendInfo);
311 }
312 mTunerResourceManager->setFrontendInfoList(infos);
313}
314
315void TunerClient::updateLnbResources() {
316 vector<int> handles = getLnbHandles();
317 if (handles.size() == 0) {
318 return;
319 }
320 mTunerResourceManager->setLnbInfoList(handles);
321}
322
Amy Zhangbf68a162020-11-23 17:42:40 -0800323sp<ITuner> TunerClient::getHidlTuner() {
324 if (mTuner == NULL) {
325 mTunerVersion = 0;
326 mTuner_1_1 = ::android::hardware::tv::tuner::V1_1::ITuner::getService();
327
328 if (mTuner_1_1 == NULL) {
329 ALOGW("Failed to get tuner 1.1 service.");
330 mTuner = ITuner::getService();
331 if (mTuner == NULL) {
332 ALOGW("Failed to get tuner 1.0 service.");
333 } else {
334 mTunerVersion = 1 << 16;
335 }
336 } else {
337 mTuner = static_cast<sp<ITuner>>(mTuner_1_1);
338 mTunerVersion = ((1 << 16) | 1);
339 }
340 }
341 return mTuner;
342}
343
Amy Zhang210c26a2021-01-12 11:25:27 -0800344sp<IFrontend> TunerClient::openHidlFrontendById(int id) {
Amy Zhangbf68a162020-11-23 17:42:40 -0800345 sp<IFrontend> fe;
346 Result res;
Amy Zhangbf68a162020-11-23 17:42:40 -0800347 mTuner->openFrontendById(id, [&](Result r, const sp<IFrontend>& frontend) {
348 fe = frontend;
349 res = r;
350 });
351 if (res != Result::SUCCESS || fe == nullptr) {
352 ALOGE("Failed to open frontend");
353 return NULL;
354 }
355 return fe;
356}
357
358Result TunerClient::getHidlFrontendInfo(int id, FrontendInfo& feInfo) {
359 Result res;
360 mTuner->getFrontendInfo(id, [&](Result r, const FrontendInfo& info) {
361 feInfo = info;
362 res = r;
363 });
364 return res;
365}
366
Amy Zhang921fd432021-01-07 13:18:27 -0800367sp<IDemux> TunerClient::openHidlDemux(int& demuxId) {
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800368 sp<IDemux> demux;
369 Result res;
370
Amy Zhang921fd432021-01-07 13:18:27 -0800371 mTuner->openDemux([&](Result result, uint32_t id, const sp<IDemux>& demuxSp) {
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800372 demux = demuxSp;
Amy Zhang921fd432021-01-07 13:18:27 -0800373 demuxId = id;
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800374 res = result;
375 });
376 if (res != Result::SUCCESS || demux == nullptr) {
377 ALOGE("Failed to open demux");
378 return NULL;
379 }
380 return demux;
381}
382
Amy Zhangd3d57b42021-01-07 11:14:43 -0800383sp<ILnb> TunerClient::openHidlLnbById(int id) {
384 sp<ILnb> lnb;
385 Result res;
386
387 mTuner->openLnbById(id, [&](Result r, const sp<ILnb>& lnbSp) {
388 res = r;
389 lnb = lnbSp;
390 });
391 if (res != Result::SUCCESS || lnb == nullptr) {
392 ALOGE("Failed to open lnb by id");
393 return NULL;
394 }
395 return lnb;
396}
397
398sp<ILnb> TunerClient::openHidlLnbByName(string name, LnbId& lnbId) {
399 sp<ILnb> lnb;
400 Result res;
401
402 mTuner->openLnbByName(name, [&](Result r, LnbId id, const sp<ILnb>& lnbSp) {
403 res = r;
404 lnb = lnbSp;
405 lnbId = id;
406 });
407 if (res != Result::SUCCESS || lnb == nullptr) {
408 ALOGE("Failed to open lnb by name");
409 return NULL;
410 }
411 return lnb;
412}
413
Amy Zhang921fd432021-01-07 13:18:27 -0800414sp<IDescrambler> TunerClient::openHidlDescrambler() {
415 sp<IDescrambler> descrambler;
416 Result res;
417
418 mTuner->openDescrambler([&](Result r, const sp<IDescrambler>& descramblerSp) {
419 res = r;
420 descrambler = descramblerSp;
421 });
422
423 if (res != Result::SUCCESS || descrambler == NULL) {
424 return NULL;
425 }
426
427 return descrambler;
428}
429
Amy Zhang39a3fa42020-12-21 16:56:03 -0800430vector<int> TunerClient::getLnbHandles() {
431 vector<int> lnbHandles;
432
433 if (mTunerService != NULL) {
434 // TODO: pending hidl interface
435 }
436
437 if (mTuner != NULL) {
438 Result res;
439 vector<LnbId> lnbIds;
440 mTuner->getLnbIds([&](Result r, const hardware::hidl_vec<LnbId>& ids) {
441 lnbIds = ids;
442 res = r;
443 });
444 if (res != Result::SUCCESS || lnbIds.size() == 0) {
445 ALOGW("Lnb isn't available");
446 } else {
447 for (int i = 0; i < lnbIds.size(); i++) {
448 lnbHandles.push_back(getResourceHandleFromId((int)lnbIds[i], LNB));
449 }
450 }
451 }
452
453 return lnbHandles;
454}
455
Amy Zhangd1fd5ac2021-01-13 16:30:24 -0800456FrontendInfo TunerClient::FrontendInfoAidlToHidl(TunerFrontendInfo aidlFrontendInfo) {
Amy Zhangbf68a162020-11-23 17:42:40 -0800457 FrontendInfo hidlFrontendInfo {
458 .type = static_cast<FrontendType>(aidlFrontendInfo.type),
459 .minFrequency = static_cast<uint32_t>(aidlFrontendInfo.minFrequency),
460 .maxFrequency = static_cast<uint32_t>(aidlFrontendInfo.maxFrequency),
461 .minSymbolRate = static_cast<uint32_t>(aidlFrontendInfo.minSymbolRate),
462 .maxSymbolRate = static_cast<uint32_t>(aidlFrontendInfo.maxSymbolRate),
463 .acquireRange = static_cast<uint32_t>(aidlFrontendInfo.acquireRange),
464 .exclusiveGroupId = static_cast<uint32_t>(aidlFrontendInfo.exclusiveGroupId),
465 };
466 // TODO: handle Frontend caps
467
468 return hidlFrontendInfo;
469}
Amy Zhang210c26a2021-01-12 11:25:27 -0800470
471int TunerClient::getResourceIdFromHandle(int handle, int /*resourceType*/) {
472 return (handle & 0x00ff0000) >> 16;
473}
474
475int TunerClient::getResourceHandleFromId(int id, int resourceType) {
476 // TODO: build up randomly generated id to handle mapping
477 return (resourceType & 0x000000ff) << 24
478 | (id << 16)
479 | (mResourceRequestCount++ & 0xffff);
480}
Amy Zhangbf68a162020-11-23 17:42:40 -0800481} // namespace android