blob: 39e6ba27e56f2f6ec064927ecccc5cabb45edadf [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 Zhang6bfeaa02020-11-30 15:16:39 -0800101 return new FrontendClient(tunerFrontend, frontendHandle);
Amy Zhangbf68a162020-11-23 17:42:40 -0800102 }
103
104 if (mTuner != NULL) {
Amy Zhang210c26a2021-01-12 11:25:27 -0800105 int id = getResourceIdFromHandle(frontendHandle, FRONTEND);
106 sp<IFrontend> hidlFrontend = openHidlFrontendById(id);
Amy Zhangbf68a162020-11-23 17:42:40 -0800107 if (hidlFrontend != NULL) {
Amy Zhang210c26a2021-01-12 11:25:27 -0800108 sp<FrontendClient> frontendClient = new FrontendClient(NULL, id);
Amy Zhangbf68a162020-11-23 17:42:40 -0800109 frontendClient->setHidlFrontend(hidlFrontend);
110 return frontendClient;
111 }
112 }
113
114 return NULL;
115}
116
117shared_ptr<FrontendInfo> TunerClient::getFrontendInfo(int id) {
118 if (mTunerService != NULL) {
119 TunerServiceFrontendInfo aidlFrontendInfo;
120 // TODO: handle error code
121 mTunerService->getFrontendInfo(id, &aidlFrontendInfo);
122 return make_shared<FrontendInfo>(FrontendInfoAidlToHidl(aidlFrontendInfo));
123 }
124
125 if (mTuner != NULL) {
126 FrontendInfo hidlInfo;
127 Result res = getHidlFrontendInfo(id, hidlInfo);
128 if (res != Result::SUCCESS) {
129 return NULL;
130 }
131 return make_shared<FrontendInfo>(hidlInfo);
132 }
133
134 return NULL;
135}
136
137shared_ptr<FrontendDtmbCapabilities> TunerClient::getFrontendDtmbCapabilities(int id) {
138 // pending aidl interface
139
140 if (mTuner_1_1 != NULL) {
141 Result result;
142 FrontendDtmbCapabilities dtmbCaps;
143 mTuner_1_1->getFrontendDtmbCapabilities(id,
144 [&](Result r, const FrontendDtmbCapabilities& caps) {
145 dtmbCaps = caps;
146 result = r;
147 });
148 if (result == Result::SUCCESS) {
149 return make_shared<FrontendDtmbCapabilities>(dtmbCaps);
150 }
151 }
152
153 return NULL;
154}
155
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800156sp<DemuxClient> TunerClient::openDemux(int /*demuxHandle*/) {
157 if (mTunerService != NULL) {
158 // TODO: handle error code
159 /*shared_ptr<ITunerDemux> tunerDemux;
160 mTunerService->openDemux(demuxHandle, &tunerDemux);
161 return new DemuxClient(tunerDemux);*/
162 }
163
164 if (mTuner != NULL) {
165 // TODO: pending aidl interface
166 sp<DemuxClient> demuxClient = new DemuxClient();
Amy Zhang921fd432021-01-07 13:18:27 -0800167 int demuxId;
168 sp<IDemux> hidlDemux = openHidlDemux(demuxId);
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800169 if (hidlDemux != NULL) {
170 demuxClient->setHidlDemux(hidlDemux);
Amy Zhang921fd432021-01-07 13:18:27 -0800171 demuxClient->setId(demuxId);
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800172 return demuxClient;
173 }
174 }
175
176 return NULL;
177}
178
Amy Zhang90a50b42021-01-11 16:58:59 -0800179shared_ptr<DemuxCapabilities> TunerClient::getDemuxCaps() {
180 // pending aidl interface
181
182 if (mTuner != NULL) {
183 Result res;
184 DemuxCapabilities caps;
185 mTuner->getDemuxCaps([&](Result r, const DemuxCapabilities& demuxCaps) {
186 caps = demuxCaps;
187 res = r;
188 });
189 if (res == Result::SUCCESS) {
190 return make_shared<DemuxCapabilities>(caps);
191 }
192 }
193
194 return NULL;
Amy Zhangb0f63ab2021-01-06 17:19:27 -0800195}
196
197sp<DescramblerClient> TunerClient::openDescrambler(int /*descramblerHandle*/) {
Amy Zhang921fd432021-01-07 13:18:27 -0800198 if (mTunerService != NULL) {
199 // TODO: handle error code
200 /*shared_ptr<ITunerDescrambler> tunerDescrambler;
201 mTunerService->openDescrambler(demuxHandle, &tunerDescrambler);
202 return new DescramblerClient(tunerDescrambler);*/
203 }
204
205 if (mTuner != NULL) {
206 // TODO: pending aidl interface
207 sp<DescramblerClient> descramblerClient = new DescramblerClient();
208 sp<IDescrambler> hidlDescrambler = openHidlDescrambler();
209 if (hidlDescrambler != NULL) {
210 descramblerClient->setHidlDescrambler(hidlDescrambler);
211 return descramblerClient;
212 }
213 }
214
215 return NULL;}
Amy Zhangb0f63ab2021-01-06 17:19:27 -0800216
Amy Zhangd3d57b42021-01-07 11:14:43 -0800217sp<LnbClient> TunerClient::openLnb(int lnbHandle) {
218 if (mTunerService != NULL) {
219 // TODO: handle error code
220 /*shared_ptr<ITunerLnb> tunerLnb;
221 mTunerService->openLnb(demuxHandle, &tunerLnb);
222 return new LnbClient(tunerLnb);*/
223 }
224
225 if (mTuner != NULL) {
226 int id = getResourceIdFromHandle(lnbHandle, LNB);
227 // TODO: pending aidl interface
228 sp<LnbClient> lnbClient = new LnbClient();
229 sp<ILnb> hidlLnb = openHidlLnbById(id);
230 if (hidlLnb != NULL) {
231 lnbClient->setHidlLnb(hidlLnb);
232 lnbClient->setId(id);
233 return lnbClient;
234 }
235 }
236
Amy Zhangb0f63ab2021-01-06 17:19:27 -0800237 return NULL;
238}
239
Amy Zhangd3d57b42021-01-07 11:14:43 -0800240sp<LnbClient> TunerClient::openLnbByName(string lnbName) {
241 if (mTunerService != NULL) {
242 // TODO: handle error code
243 /*shared_ptr<ITunerLnb> tunerLnb;
244 mTunerService->openLnbByName(lnbName, &tunerLnb);
245 return new LnbClient(tunerLnb);*/
246 }
247
248 if (mTuner != NULL) {
249 // TODO: pending aidl interface
250 sp<LnbClient> lnbClient = new LnbClient();
251 LnbId id;
252 sp<ILnb> hidlLnb = openHidlLnbByName(lnbName, id);
253 if (hidlLnb != NULL) {
254 lnbClient->setHidlLnb(hidlLnb);
255 lnbClient->setId(id);
256 return lnbClient;
257 }
258 }
259
Amy Zhangb0f63ab2021-01-06 17:19:27 -0800260 return NULL;
261}
262
Amy Zhangbf68a162020-11-23 17:42:40 -0800263/////////////// TunerClient Helper Methods ///////////////////////
264
Amy Zhang39a3fa42020-12-21 16:56:03 -0800265void TunerClient::updateTunerResources() {
266 if (mTuner == NULL) {
267 return;
268 }
269
270 // Connect with Tuner Resource Manager.
271 ::ndk::SpAIBinder binder(AServiceManager_getService("tv_tuner_resource_mgr"));
272 mTunerResourceManager = ITunerResourceManager::fromBinder(binder);
273
274 updateFrontendResources();
275 updateLnbResources();
276 // TODO: update Demux, Descrambler.
277}
278
279void TunerClient::updateFrontendResources() {
280 vector<FrontendId> ids = getFrontendIds();
281 if (ids.size() == 0) {
282 return;
283 }
284 vector<TunerFrontendInfo> infos;
285 for (int i = 0; i < ids.size(); i++) {
286 shared_ptr<FrontendInfo> frontendInfo = getFrontendInfo((int)ids[i]);
287 if (frontendInfo == NULL) {
288 continue;
289 }
290 TunerFrontendInfo tunerFrontendInfo{
291 .handle = getResourceHandleFromId((int)ids[i], FRONTEND),
292 .frontendType = static_cast<int>(frontendInfo->type),
293 .exclusiveGroupId = static_cast<int>(frontendInfo->exclusiveGroupId),
294 };
295 infos.push_back(tunerFrontendInfo);
296 }
297 mTunerResourceManager->setFrontendInfoList(infos);
298}
299
300void TunerClient::updateLnbResources() {
301 vector<int> handles = getLnbHandles();
302 if (handles.size() == 0) {
303 return;
304 }
305 mTunerResourceManager->setLnbInfoList(handles);
306}
307
Amy Zhangbf68a162020-11-23 17:42:40 -0800308sp<ITuner> TunerClient::getHidlTuner() {
309 if (mTuner == NULL) {
310 mTunerVersion = 0;
311 mTuner_1_1 = ::android::hardware::tv::tuner::V1_1::ITuner::getService();
312
313 if (mTuner_1_1 == NULL) {
314 ALOGW("Failed to get tuner 1.1 service.");
315 mTuner = ITuner::getService();
316 if (mTuner == NULL) {
317 ALOGW("Failed to get tuner 1.0 service.");
318 } else {
319 mTunerVersion = 1 << 16;
320 }
321 } else {
322 mTuner = static_cast<sp<ITuner>>(mTuner_1_1);
323 mTunerVersion = ((1 << 16) | 1);
324 }
325 }
326 return mTuner;
327}
328
Amy Zhang210c26a2021-01-12 11:25:27 -0800329sp<IFrontend> TunerClient::openHidlFrontendById(int id) {
Amy Zhangbf68a162020-11-23 17:42:40 -0800330 sp<IFrontend> fe;
331 Result res;
Amy Zhangbf68a162020-11-23 17:42:40 -0800332 mTuner->openFrontendById(id, [&](Result r, const sp<IFrontend>& frontend) {
333 fe = frontend;
334 res = r;
335 });
336 if (res != Result::SUCCESS || fe == nullptr) {
337 ALOGE("Failed to open frontend");
338 return NULL;
339 }
340 return fe;
341}
342
343Result TunerClient::getHidlFrontendInfo(int id, FrontendInfo& feInfo) {
344 Result res;
345 mTuner->getFrontendInfo(id, [&](Result r, const FrontendInfo& info) {
346 feInfo = info;
347 res = r;
348 });
349 return res;
350}
351
Amy Zhang921fd432021-01-07 13:18:27 -0800352sp<IDemux> TunerClient::openHidlDemux(int& demuxId) {
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800353 sp<IDemux> demux;
354 Result res;
355
Amy Zhang921fd432021-01-07 13:18:27 -0800356 mTuner->openDemux([&](Result result, uint32_t id, const sp<IDemux>& demuxSp) {
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800357 demux = demuxSp;
Amy Zhang921fd432021-01-07 13:18:27 -0800358 demuxId = id;
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800359 res = result;
360 });
361 if (res != Result::SUCCESS || demux == nullptr) {
362 ALOGE("Failed to open demux");
363 return NULL;
364 }
365 return demux;
366}
367
Amy Zhangd3d57b42021-01-07 11:14:43 -0800368sp<ILnb> TunerClient::openHidlLnbById(int id) {
369 sp<ILnb> lnb;
370 Result res;
371
372 mTuner->openLnbById(id, [&](Result r, const sp<ILnb>& lnbSp) {
373 res = r;
374 lnb = lnbSp;
375 });
376 if (res != Result::SUCCESS || lnb == nullptr) {
377 ALOGE("Failed to open lnb by id");
378 return NULL;
379 }
380 return lnb;
381}
382
383sp<ILnb> TunerClient::openHidlLnbByName(string name, LnbId& lnbId) {
384 sp<ILnb> lnb;
385 Result res;
386
387 mTuner->openLnbByName(name, [&](Result r, LnbId id, const sp<ILnb>& lnbSp) {
388 res = r;
389 lnb = lnbSp;
390 lnbId = id;
391 });
392 if (res != Result::SUCCESS || lnb == nullptr) {
393 ALOGE("Failed to open lnb by name");
394 return NULL;
395 }
396 return lnb;
397}
398
Amy Zhang921fd432021-01-07 13:18:27 -0800399sp<IDescrambler> TunerClient::openHidlDescrambler() {
400 sp<IDescrambler> descrambler;
401 Result res;
402
403 mTuner->openDescrambler([&](Result r, const sp<IDescrambler>& descramblerSp) {
404 res = r;
405 descrambler = descramblerSp;
406 });
407
408 if (res != Result::SUCCESS || descrambler == NULL) {
409 return NULL;
410 }
411
412 return descrambler;
413}
414
Amy Zhang39a3fa42020-12-21 16:56:03 -0800415vector<int> TunerClient::getLnbHandles() {
416 vector<int> lnbHandles;
417
418 if (mTunerService != NULL) {
419 // TODO: pending hidl interface
420 }
421
422 if (mTuner != NULL) {
423 Result res;
424 vector<LnbId> lnbIds;
425 mTuner->getLnbIds([&](Result r, const hardware::hidl_vec<LnbId>& ids) {
426 lnbIds = ids;
427 res = r;
428 });
429 if (res != Result::SUCCESS || lnbIds.size() == 0) {
430 ALOGW("Lnb isn't available");
431 } else {
432 for (int i = 0; i < lnbIds.size(); i++) {
433 lnbHandles.push_back(getResourceHandleFromId((int)lnbIds[i], LNB));
434 }
435 }
436 }
437
438 return lnbHandles;
439}
440
Amy Zhangbf68a162020-11-23 17:42:40 -0800441FrontendInfo TunerClient::FrontendInfoAidlToHidl(TunerServiceFrontendInfo aidlFrontendInfo) {
442 FrontendInfo hidlFrontendInfo {
443 .type = static_cast<FrontendType>(aidlFrontendInfo.type),
444 .minFrequency = static_cast<uint32_t>(aidlFrontendInfo.minFrequency),
445 .maxFrequency = static_cast<uint32_t>(aidlFrontendInfo.maxFrequency),
446 .minSymbolRate = static_cast<uint32_t>(aidlFrontendInfo.minSymbolRate),
447 .maxSymbolRate = static_cast<uint32_t>(aidlFrontendInfo.maxSymbolRate),
448 .acquireRange = static_cast<uint32_t>(aidlFrontendInfo.acquireRange),
449 .exclusiveGroupId = static_cast<uint32_t>(aidlFrontendInfo.exclusiveGroupId),
450 };
451 // TODO: handle Frontend caps
452
453 return hidlFrontendInfo;
454}
Amy Zhang210c26a2021-01-12 11:25:27 -0800455
456int TunerClient::getResourceIdFromHandle(int handle, int /*resourceType*/) {
457 return (handle & 0x00ff0000) >> 16;
458}
459
460int TunerClient::getResourceHandleFromId(int id, int resourceType) {
461 // TODO: build up randomly generated id to handle mapping
462 return (resourceType & 0x000000ff) << 24
463 | (id << 16)
464 | (mResourceRequestCount++ & 0xffff);
465}
Amy Zhangbf68a162020-11-23 17:42:40 -0800466} // namespace android