blob: f5e35248fcfdc4debfca83c024b2bd2858394990 [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 Zhang39a3fa42020-12-21 16:56:03 -080040 updateTunerResources();
Amy Zhangbf68a162020-11-23 17:42:40 -080041 // Connect with Tuner Service.
42 ::ndk::SpAIBinder binder(AServiceManager_getService("media.tuner"));
43 mTunerService = ITunerService::fromBinder(binder);
Amy Zhang9a9ed602020-12-07 16:37:33 -080044 // TODO: Remove after JNI migration is done.
45 mTunerService = NULL;
Amy Zhangbf68a162020-11-23 17:42:40 -080046 if (mTunerService == NULL) {
47 ALOGE("Failed to get tuner service");
48 }
49}
50
51TunerClient::~TunerClient() {
52 mTuner = NULL;
53 mTuner_1_1 = NULL;
54 mTunerVersion = 0;
55 mTunerService = NULL;
56}
57
58vector<FrontendId> TunerClient::getFrontendIds() {
59 vector<FrontendId> ids;
shubang68f32a32020-12-29 00:34:24 -080060
61 if (mTunerService != NULL) {
62 vector<int32_t> v;
63 int aidl_return;
64 Status s = mTunerService->getFrontendIds(&v, &aidl_return);
65 if (!s.isOk() || aidl_return != (int) Result::SUCCESS
66 || v.size() == 0) {
67 ids.clear();
68 return ids;
69 }
70 for (int32_t id : v) {
71 ids.push_back(static_cast<FrontendId>(id));
72 }
73 return ids;
74 }
Amy Zhangbf68a162020-11-23 17:42:40 -080075
76 if (mTuner != NULL) {
77 Result res;
78 mTuner->getFrontendIds([&](Result r, const hardware::hidl_vec<FrontendId>& frontendIds) {
79 res = r;
80 ids = frontendIds;
81 });
82 if (res != Result::SUCCESS || ids.size() == 0) {
83 ALOGW("Frontend ids not available");
84 ids.clear();
85 return ids;
86 }
87 return ids;
88 }
89
90 return ids;
91}
92
93
94sp<FrontendClient> TunerClient::openFrontend(int frontendHandle) {
95 if (mTunerService != NULL) {
96 // TODO: handle error code
97 shared_ptr<ITunerFrontend> tunerFrontend;
98 mTunerService->openFrontend(frontendHandle, &tunerFrontend);
Amy Zhangb9f3cab2021-01-13 15:24:14 -080099 if (tunerFrontend == NULL) {
100 return NULL;
101 }
102 int id;
103 // TODO: handle error code
104 tunerFrontend->getFrontendId(&id);
Amy Zhangd1fd5ac2021-01-13 16:30:24 -0800105 TunerFrontendInfo aidlFrontendInfo;
Amy Zhangb9f3cab2021-01-13 15:24:14 -0800106 // TODO: handle error code
107 mTunerService->getFrontendInfo(id, &aidlFrontendInfo);
108 return new FrontendClient(tunerFrontend, frontendHandle, aidlFrontendInfo.type);
Amy Zhangbf68a162020-11-23 17:42:40 -0800109 }
110
111 if (mTuner != NULL) {
Amy Zhang210c26a2021-01-12 11:25:27 -0800112 int id = getResourceIdFromHandle(frontendHandle, FRONTEND);
113 sp<IFrontend> hidlFrontend = openHidlFrontendById(id);
Amy Zhangbf68a162020-11-23 17:42:40 -0800114 if (hidlFrontend != NULL) {
Amy Zhangb9f3cab2021-01-13 15:24:14 -0800115 FrontendInfo hidlInfo;
116 Result res = getHidlFrontendInfo(id, hidlInfo);
117 if (res != Result::SUCCESS) {
118 return NULL;
119 }
120 sp<FrontendClient> frontendClient = new FrontendClient(NULL, id, (int)hidlInfo.type);
Amy Zhangbf68a162020-11-23 17:42:40 -0800121 frontendClient->setHidlFrontend(hidlFrontend);
122 return frontendClient;
123 }
124 }
125
126 return NULL;
127}
128
129shared_ptr<FrontendInfo> TunerClient::getFrontendInfo(int id) {
130 if (mTunerService != NULL) {
Amy Zhangd1fd5ac2021-01-13 16:30:24 -0800131 TunerFrontendInfo aidlFrontendInfo;
Amy Zhangbf68a162020-11-23 17:42:40 -0800132 // TODO: handle error code
133 mTunerService->getFrontendInfo(id, &aidlFrontendInfo);
134 return make_shared<FrontendInfo>(FrontendInfoAidlToHidl(aidlFrontendInfo));
135 }
136
137 if (mTuner != NULL) {
138 FrontendInfo hidlInfo;
139 Result res = getHidlFrontendInfo(id, hidlInfo);
140 if (res != Result::SUCCESS) {
141 return NULL;
142 }
143 return make_shared<FrontendInfo>(hidlInfo);
144 }
145
146 return NULL;
147}
148
149shared_ptr<FrontendDtmbCapabilities> TunerClient::getFrontendDtmbCapabilities(int id) {
150 // pending aidl interface
151
152 if (mTuner_1_1 != NULL) {
153 Result result;
154 FrontendDtmbCapabilities dtmbCaps;
155 mTuner_1_1->getFrontendDtmbCapabilities(id,
156 [&](Result r, const FrontendDtmbCapabilities& caps) {
157 dtmbCaps = caps;
158 result = r;
159 });
160 if (result == Result::SUCCESS) {
161 return make_shared<FrontendDtmbCapabilities>(dtmbCaps);
162 }
163 }
164
165 return NULL;
166}
167
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800168sp<DemuxClient> TunerClient::openDemux(int /*demuxHandle*/) {
169 if (mTunerService != NULL) {
170 // TODO: handle error code
171 /*shared_ptr<ITunerDemux> tunerDemux;
172 mTunerService->openDemux(demuxHandle, &tunerDemux);
173 return new DemuxClient(tunerDemux);*/
174 }
175
176 if (mTuner != NULL) {
177 // TODO: pending aidl interface
178 sp<DemuxClient> demuxClient = new DemuxClient();
Amy Zhang921fd432021-01-07 13:18:27 -0800179 int demuxId;
180 sp<IDemux> hidlDemux = openHidlDemux(demuxId);
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800181 if (hidlDemux != NULL) {
182 demuxClient->setHidlDemux(hidlDemux);
Amy Zhang921fd432021-01-07 13:18:27 -0800183 demuxClient->setId(demuxId);
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800184 return demuxClient;
185 }
186 }
187
188 return NULL;
189}
190
Amy Zhang90a50b42021-01-11 16:58:59 -0800191shared_ptr<DemuxCapabilities> TunerClient::getDemuxCaps() {
192 // pending aidl interface
193
194 if (mTuner != NULL) {
195 Result res;
196 DemuxCapabilities caps;
197 mTuner->getDemuxCaps([&](Result r, const DemuxCapabilities& demuxCaps) {
198 caps = demuxCaps;
199 res = r;
200 });
201 if (res == Result::SUCCESS) {
202 return make_shared<DemuxCapabilities>(caps);
203 }
204 }
205
206 return NULL;
Amy Zhangb0f63ab2021-01-06 17:19:27 -0800207}
208
209sp<DescramblerClient> TunerClient::openDescrambler(int /*descramblerHandle*/) {
Amy Zhang921fd432021-01-07 13:18:27 -0800210 if (mTunerService != NULL) {
211 // TODO: handle error code
212 /*shared_ptr<ITunerDescrambler> tunerDescrambler;
213 mTunerService->openDescrambler(demuxHandle, &tunerDescrambler);
214 return new DescramblerClient(tunerDescrambler);*/
215 }
216
217 if (mTuner != NULL) {
218 // TODO: pending aidl interface
219 sp<DescramblerClient> descramblerClient = new DescramblerClient();
220 sp<IDescrambler> hidlDescrambler = openHidlDescrambler();
221 if (hidlDescrambler != NULL) {
222 descramblerClient->setHidlDescrambler(hidlDescrambler);
223 return descramblerClient;
224 }
225 }
226
227 return NULL;}
Amy Zhangb0f63ab2021-01-06 17:19:27 -0800228
Amy Zhangd3d57b42021-01-07 11:14:43 -0800229sp<LnbClient> TunerClient::openLnb(int lnbHandle) {
230 if (mTunerService != NULL) {
231 // TODO: handle error code
232 /*shared_ptr<ITunerLnb> tunerLnb;
233 mTunerService->openLnb(demuxHandle, &tunerLnb);
234 return new LnbClient(tunerLnb);*/
235 }
236
237 if (mTuner != NULL) {
238 int id = getResourceIdFromHandle(lnbHandle, LNB);
239 // TODO: pending aidl interface
240 sp<LnbClient> lnbClient = new LnbClient();
241 sp<ILnb> hidlLnb = openHidlLnbById(id);
242 if (hidlLnb != NULL) {
243 lnbClient->setHidlLnb(hidlLnb);
244 lnbClient->setId(id);
245 return lnbClient;
246 }
247 }
248
Amy Zhangb0f63ab2021-01-06 17:19:27 -0800249 return NULL;
250}
251
Amy Zhangd3d57b42021-01-07 11:14:43 -0800252sp<LnbClient> TunerClient::openLnbByName(string lnbName) {
253 if (mTunerService != NULL) {
254 // TODO: handle error code
255 /*shared_ptr<ITunerLnb> tunerLnb;
256 mTunerService->openLnbByName(lnbName, &tunerLnb);
257 return new LnbClient(tunerLnb);*/
258 }
259
260 if (mTuner != NULL) {
261 // TODO: pending aidl interface
262 sp<LnbClient> lnbClient = new LnbClient();
263 LnbId id;
264 sp<ILnb> hidlLnb = openHidlLnbByName(lnbName, id);
265 if (hidlLnb != NULL) {
266 lnbClient->setHidlLnb(hidlLnb);
267 lnbClient->setId(id);
268 return lnbClient;
269 }
270 }
271
Amy Zhangb0f63ab2021-01-06 17:19:27 -0800272 return NULL;
273}
274
Amy Zhangbf68a162020-11-23 17:42:40 -0800275/////////////// TunerClient Helper Methods ///////////////////////
276
Amy Zhang39a3fa42020-12-21 16:56:03 -0800277void TunerClient::updateTunerResources() {
278 if (mTuner == NULL) {
279 return;
280 }
281
282 // Connect with Tuner Resource Manager.
283 ::ndk::SpAIBinder binder(AServiceManager_getService("tv_tuner_resource_mgr"));
284 mTunerResourceManager = ITunerResourceManager::fromBinder(binder);
285
286 updateFrontendResources();
287 updateLnbResources();
288 // TODO: update Demux, Descrambler.
289}
290
291void TunerClient::updateFrontendResources() {
292 vector<FrontendId> ids = getFrontendIds();
293 if (ids.size() == 0) {
294 return;
295 }
296 vector<TunerFrontendInfo> infos;
297 for (int i = 0; i < ids.size(); i++) {
298 shared_ptr<FrontendInfo> frontendInfo = getFrontendInfo((int)ids[i]);
299 if (frontendInfo == NULL) {
300 continue;
301 }
302 TunerFrontendInfo tunerFrontendInfo{
303 .handle = getResourceHandleFromId((int)ids[i], FRONTEND),
Amy Zhangd1fd5ac2021-01-13 16:30:24 -0800304 .type = static_cast<int>(frontendInfo->type),
Amy Zhang39a3fa42020-12-21 16:56:03 -0800305 .exclusiveGroupId = static_cast<int>(frontendInfo->exclusiveGroupId),
306 };
307 infos.push_back(tunerFrontendInfo);
308 }
309 mTunerResourceManager->setFrontendInfoList(infos);
310}
311
312void TunerClient::updateLnbResources() {
313 vector<int> handles = getLnbHandles();
314 if (handles.size() == 0) {
315 return;
316 }
317 mTunerResourceManager->setLnbInfoList(handles);
318}
319
Amy Zhangbf68a162020-11-23 17:42:40 -0800320sp<ITuner> TunerClient::getHidlTuner() {
321 if (mTuner == NULL) {
322 mTunerVersion = 0;
323 mTuner_1_1 = ::android::hardware::tv::tuner::V1_1::ITuner::getService();
324
325 if (mTuner_1_1 == NULL) {
326 ALOGW("Failed to get tuner 1.1 service.");
327 mTuner = ITuner::getService();
328 if (mTuner == NULL) {
329 ALOGW("Failed to get tuner 1.0 service.");
330 } else {
331 mTunerVersion = 1 << 16;
332 }
333 } else {
334 mTuner = static_cast<sp<ITuner>>(mTuner_1_1);
335 mTunerVersion = ((1 << 16) | 1);
336 }
337 }
338 return mTuner;
339}
340
Amy Zhang210c26a2021-01-12 11:25:27 -0800341sp<IFrontend> TunerClient::openHidlFrontendById(int id) {
Amy Zhangbf68a162020-11-23 17:42:40 -0800342 sp<IFrontend> fe;
343 Result res;
Amy Zhangbf68a162020-11-23 17:42:40 -0800344 mTuner->openFrontendById(id, [&](Result r, const sp<IFrontend>& frontend) {
345 fe = frontend;
346 res = r;
347 });
348 if (res != Result::SUCCESS || fe == nullptr) {
349 ALOGE("Failed to open frontend");
350 return NULL;
351 }
352 return fe;
353}
354
355Result TunerClient::getHidlFrontendInfo(int id, FrontendInfo& feInfo) {
356 Result res;
357 mTuner->getFrontendInfo(id, [&](Result r, const FrontendInfo& info) {
358 feInfo = info;
359 res = r;
360 });
361 return res;
362}
363
Amy Zhang921fd432021-01-07 13:18:27 -0800364sp<IDemux> TunerClient::openHidlDemux(int& demuxId) {
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800365 sp<IDemux> demux;
366 Result res;
367
Amy Zhang921fd432021-01-07 13:18:27 -0800368 mTuner->openDemux([&](Result result, uint32_t id, const sp<IDemux>& demuxSp) {
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800369 demux = demuxSp;
Amy Zhang921fd432021-01-07 13:18:27 -0800370 demuxId = id;
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800371 res = result;
372 });
373 if (res != Result::SUCCESS || demux == nullptr) {
374 ALOGE("Failed to open demux");
375 return NULL;
376 }
377 return demux;
378}
379
Amy Zhangd3d57b42021-01-07 11:14:43 -0800380sp<ILnb> TunerClient::openHidlLnbById(int id) {
381 sp<ILnb> lnb;
382 Result res;
383
384 mTuner->openLnbById(id, [&](Result r, const sp<ILnb>& lnbSp) {
385 res = r;
386 lnb = lnbSp;
387 });
388 if (res != Result::SUCCESS || lnb == nullptr) {
389 ALOGE("Failed to open lnb by id");
390 return NULL;
391 }
392 return lnb;
393}
394
395sp<ILnb> TunerClient::openHidlLnbByName(string name, LnbId& lnbId) {
396 sp<ILnb> lnb;
397 Result res;
398
399 mTuner->openLnbByName(name, [&](Result r, LnbId id, const sp<ILnb>& lnbSp) {
400 res = r;
401 lnb = lnbSp;
402 lnbId = id;
403 });
404 if (res != Result::SUCCESS || lnb == nullptr) {
405 ALOGE("Failed to open lnb by name");
406 return NULL;
407 }
408 return lnb;
409}
410
Amy Zhang921fd432021-01-07 13:18:27 -0800411sp<IDescrambler> TunerClient::openHidlDescrambler() {
412 sp<IDescrambler> descrambler;
413 Result res;
414
415 mTuner->openDescrambler([&](Result r, const sp<IDescrambler>& descramblerSp) {
416 res = r;
417 descrambler = descramblerSp;
418 });
419
420 if (res != Result::SUCCESS || descrambler == NULL) {
421 return NULL;
422 }
423
424 return descrambler;
425}
426
Amy Zhang39a3fa42020-12-21 16:56:03 -0800427vector<int> TunerClient::getLnbHandles() {
428 vector<int> lnbHandles;
429
430 if (mTunerService != NULL) {
431 // TODO: pending hidl interface
432 }
433
434 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 Zhangd1fd5ac2021-01-13 16:30:24 -0800453FrontendInfo TunerClient::FrontendInfoAidlToHidl(TunerFrontendInfo aidlFrontendInfo) {
Amy Zhangbf68a162020-11-23 17:42:40 -0800454 FrontendInfo hidlFrontendInfo {
455 .type = static_cast<FrontendType>(aidlFrontendInfo.type),
456 .minFrequency = static_cast<uint32_t>(aidlFrontendInfo.minFrequency),
457 .maxFrequency = static_cast<uint32_t>(aidlFrontendInfo.maxFrequency),
458 .minSymbolRate = static_cast<uint32_t>(aidlFrontendInfo.minSymbolRate),
459 .maxSymbolRate = static_cast<uint32_t>(aidlFrontendInfo.maxSymbolRate),
460 .acquireRange = static_cast<uint32_t>(aidlFrontendInfo.acquireRange),
461 .exclusiveGroupId = static_cast<uint32_t>(aidlFrontendInfo.exclusiveGroupId),
462 };
463 // TODO: handle Frontend caps
464
465 return hidlFrontendInfo;
466}
Amy Zhang210c26a2021-01-12 11:25:27 -0800467
468int TunerClient::getResourceIdFromHandle(int handle, int /*resourceType*/) {
469 return (handle & 0x00ff0000) >> 16;
470}
471
472int TunerClient::getResourceHandleFromId(int id, int resourceType) {
473 // TODO: build up randomly generated id to handle mapping
474 return (resourceType & 0x000000ff) << 24
475 | (id << 16)
476 | (mResourceRequestCount++ & 0xffff);
477}
Amy Zhangbf68a162020-11-23 17:42:40 -0800478} // namespace android