blob: 335578d0afbec89c5d4e46f1d6fc5daeaba7c410 [file] [log] [blame]
shubang23aa3ac2020-09-07 18:56:28 -07001/**
Hongguangeae68392021-07-27 20:56:23 -07002 * Copyright (c) 2021, The Android Open Source Project
shubang23aa3ac2020-09-07 18:56:28 -07003 *
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
Hongguangeae68392021-07-27 20:56:23 -070017//#define LOG_NDEBUG 0
shubang23aa3ac2020-09-07 18:56:28 -070018#define LOG_TAG "TunerService"
19
Hongguangeae68392021-07-27 20:56:23 -070020#include "TunerService.h"
21
22#include <aidl/android/hardware/tv/tuner/IDemux.h>
23#include <aidl/android/hardware/tv/tuner/IDescrambler.h>
24#include <aidl/android/hardware/tv/tuner/IFrontend.h>
25#include <aidl/android/hardware/tv/tuner/ILnb.h>
26#include <aidl/android/hardware/tv/tuner/Result.h>
shubang23aa3ac2020-09-07 18:56:28 -070027#include <android/binder_manager.h>
Hongguang34a479e2021-10-04 16:14:47 -070028#include <binder/IPCThreadState.h>
29#include <binder/PermissionCache.h>
shubang23aa3ac2020-09-07 18:56:28 -070030#include <utils/Log.h>
Hongguangeae68392021-07-27 20:56:23 -070031
Hongguang34a479e2021-10-04 16:14:47 -070032#include <string>
33
shubangae56a2e2021-01-21 07:29:55 -080034#include "TunerDemux.h"
Amy Zhangb2989b52021-02-05 12:27:25 -080035#include "TunerDescrambler.h"
Hongguangeae68392021-07-27 20:56:23 -070036#include "TunerFrontend.h"
Hongguang093c5f32021-08-09 19:46:34 -070037#include "TunerHelper.h"
Hongguangeae68392021-07-27 20:56:23 -070038#include "TunerLnb.h"
shubang23aa3ac2020-09-07 18:56:28 -070039
Hongguangeae68392021-07-27 20:56:23 -070040using ::aidl::android::hardware::tv::tuner::IDemux;
41using ::aidl::android::hardware::tv::tuner::IDescrambler;
42using ::aidl::android::hardware::tv::tuner::IFrontend;
43using ::aidl::android::hardware::tv::tuner::Result;
Hongguang34a479e2021-10-04 16:14:47 -070044using ::android::IPCThreadState;
45using ::android::PermissionCache;
Hongguangeae68392021-07-27 20:56:23 -070046using ::android::sp;
shubang23aa3ac2020-09-07 18:56:28 -070047
Hongguangeae68392021-07-27 20:56:23 -070048namespace aidl {
shubang23aa3ac2020-09-07 18:56:28 -070049namespace android {
Hongguangeae68392021-07-27 20:56:23 -070050namespace media {
51namespace tv {
52namespace tuner {
shubang23aa3ac2020-09-07 18:56:28 -070053
Hongguang34a479e2021-10-04 16:14:47 -070054shared_ptr<TunerService> TunerService::sTunerService = nullptr;
55
Amy Zhangfb1b4962021-02-18 19:34:52 -080056TunerService::TunerService() {
Hongguang093c5f32021-08-09 19:46:34 -070057 if (!TunerHelper::checkTunerFeature()) {
58 ALOGD("Device doesn't have tuner hardware.");
Amy Zhangc5eb8272021-03-01 16:19:39 -080059 return;
60 }
61
Amy Zhangfb1b4962021-02-18 19:34:52 -080062 updateTunerResources();
63}
64
shubang23aa3ac2020-09-07 18:56:28 -070065TunerService::~TunerService() {}
66
Amy Zhangb1baabb2021-02-08 19:54:28 -080067binder_status_t TunerService::instantiate() {
Hongguang34a479e2021-10-04 16:14:47 -070068 sTunerService = ::ndk::SharedRefBase::make<TunerService>();
69 return AServiceManager_addService(sTunerService->asBinder().get(), getServiceName());
70}
71
72shared_ptr<TunerService> TunerService::getTunerService() {
73 return sTunerService;
shubang6d266262020-10-09 00:15:04 -070074}
75
Amy Zhang5af84142021-02-04 18:36:54 -080076bool TunerService::hasITuner() {
Hongguangeae68392021-07-27 20:56:23 -070077 ALOGV("hasITuner");
shubang6d266262020-10-09 00:15:04 -070078 if (mTuner != nullptr) {
79 return true;
80 }
Hongguangeae68392021-07-27 20:56:23 -070081 const string statsServiceName = string() + ITuner::descriptor + "/default";
82 if (AServiceManager_isDeclared(statsServiceName.c_str())) {
83 ::ndk::SpAIBinder binder(AServiceManager_waitForService(statsServiceName.c_str()));
84 mTuner = ITuner::fromBinder(binder);
85 } else {
86 mTuner = nullptr;
87 ALOGE("Failed to get Tuner HAL Service");
shubang6d266262020-10-09 00:15:04 -070088 return false;
Amy Zhang0f04c452020-10-30 13:36:44 -070089 }
Hongguangeae68392021-07-27 20:56:23 -070090
91 mTunerVersion = TUNER_HAL_VERSION_2_0;
92 // TODO: Enable this after Tuner HAL is frozen.
93 // if (mTuner->getInterfaceVersion(&mTunerVersion).isOk()) {
94 // // Tuner AIDL HAL version 1 will be Tuner HAL 2.0
95 // mTunerVersion = (mTunerVersion + 1) << 16;
96 //}
97
shubang6d266262020-10-09 00:15:04 -070098 return true;
99}
100
Hongguangeae68392021-07-27 20:56:23 -0700101::ndk::ScopedAStatus TunerService::openDemux(int32_t /* in_demuxHandle */,
102 shared_ptr<ITunerDemux>* _aidl_return) {
103 ALOGV("openDemux");
Amy Zhang5af84142021-02-04 18:36:54 -0800104 if (!hasITuner()) {
Hongguangeae68392021-07-27 20:56:23 -0700105 return ::ndk::ScopedAStatus::fromServiceSpecificError(
106 static_cast<int32_t>(Result::UNAVAILABLE));
shubang6d266262020-10-09 00:15:04 -0700107 }
Hongguangeae68392021-07-27 20:56:23 -0700108 vector<int32_t> id;
109 shared_ptr<IDemux> demux;
110 auto status = mTuner->openDemux(&id, &demux);
111 if (status.isOk()) {
112 *_aidl_return = ::ndk::SharedRefBase::make<TunerDemux>(demux, id[0]);
shubang6d266262020-10-09 00:15:04 -0700113 }
114
Hongguangeae68392021-07-27 20:56:23 -0700115 return status;
Amy Zhang07428dc2021-02-04 15:58:02 -0800116}
117
Hongguangeae68392021-07-27 20:56:23 -0700118::ndk::ScopedAStatus TunerService::getDemuxCaps(DemuxCapabilities* _aidl_return) {
119 ALOGV("getDemuxCaps");
Amy Zhang5af84142021-02-04 18:36:54 -0800120 if (!hasITuner()) {
Hongguangeae68392021-07-27 20:56:23 -0700121 return ::ndk::ScopedAStatus::fromServiceSpecificError(
122 static_cast<int32_t>(Result::UNAVAILABLE));
Amy Zhang07428dc2021-02-04 15:58:02 -0800123 }
124
Hongguangeae68392021-07-27 20:56:23 -0700125 return mTuner->getDemuxCaps(_aidl_return);
shubang6d266262020-10-09 00:15:04 -0700126}
127
Hongguangeae68392021-07-27 20:56:23 -0700128::ndk::ScopedAStatus TunerService::getFrontendIds(vector<int32_t>* ids) {
Amy Zhang5af84142021-02-04 18:36:54 -0800129 if (!hasITuner()) {
Hongguangeae68392021-07-27 20:56:23 -0700130 return ::ndk::ScopedAStatus::fromServiceSpecificError(
131 static_cast<int32_t>(Result::UNAVAILABLE));
shubang23aa3ac2020-09-07 18:56:28 -0700132 }
shubang23aa3ac2020-09-07 18:56:28 -0700133
Hongguangeae68392021-07-27 20:56:23 -0700134 return mTuner->getFrontendIds(ids);
shubang23aa3ac2020-09-07 18:56:28 -0700135}
136
Hongguangeae68392021-07-27 20:56:23 -0700137::ndk::ScopedAStatus TunerService::getFrontendInfo(int32_t id, FrontendInfo* _aidl_return) {
Amy Zhang5af84142021-02-04 18:36:54 -0800138 if (!hasITuner()) {
Amy Zhang0f04c452020-10-30 13:36:44 -0700139 ALOGE("ITuner service is not init.");
140 return ::ndk::ScopedAStatus::fromServiceSpecificError(
141 static_cast<int32_t>(Result::UNAVAILABLE));
Amy Zhang70de35a2020-10-12 20:13:16 -0700142 }
143
Hongguangeae68392021-07-27 20:56:23 -0700144 return mTuner->getFrontendInfo(id, _aidl_return);
Amy Zhang0f04c452020-10-30 13:36:44 -0700145}
146
Hongguangeae68392021-07-27 20:56:23 -0700147::ndk::ScopedAStatus TunerService::openFrontend(int32_t frontendHandle,
148 shared_ptr<ITunerFrontend>* _aidl_return) {
149 if (!hasITuner()) {
150 ALOGE("ITuner service is not init.");
Amy Zhang5af84142021-02-04 18:36:54 -0800151 return ::ndk::ScopedAStatus::fromServiceSpecificError(
152 static_cast<int32_t>(Result::UNAVAILABLE));
153 }
154
Hongguang093c5f32021-08-09 19:46:34 -0700155 int id = TunerHelper::getResourceIdFromHandle(frontendHandle, FRONTEND);
Hongguangeae68392021-07-27 20:56:23 -0700156 shared_ptr<IFrontend> frontend;
157 auto status = mTuner->openFrontendById(id, &frontend);
158 if (status.isOk()) {
159 *_aidl_return = ::ndk::SharedRefBase::make<TunerFrontend>(frontend, id);
Amy Zhanga046eee2021-01-12 14:44:58 -0800160 }
Hongguangeae68392021-07-27 20:56:23 -0700161
162 return status;
Amy Zhanga046eee2021-01-12 14:44:58 -0800163}
164
Hongguangeae68392021-07-27 20:56:23 -0700165::ndk::ScopedAStatus TunerService::openLnb(int lnbHandle, shared_ptr<ITunerLnb>* _aidl_return) {
Amy Zhang5af84142021-02-04 18:36:54 -0800166 if (!hasITuner()) {
Amy Zhangce2cb402021-01-21 12:50:47 -0800167 ALOGD("get ITuner failed");
Hongguangeae68392021-07-27 20:56:23 -0700168 return ::ndk::ScopedAStatus::fromServiceSpecificError(
169 static_cast<int32_t>(Result::UNAVAILABLE));
Amy Zhanga046eee2021-01-12 14:44:58 -0800170 }
171
Hongguangeae68392021-07-27 20:56:23 -0700172 shared_ptr<ILnb> lnb;
Hongguang093c5f32021-08-09 19:46:34 -0700173 int id = TunerHelper::getResourceIdFromHandle(lnbHandle, LNB);
Hongguangeae68392021-07-27 20:56:23 -0700174 auto status = mTuner->openLnbById(id, &lnb);
175 if (status.isOk()) {
176 *_aidl_return = ::ndk::SharedRefBase::make<TunerLnb>(lnb, id);
Amy Zhanga046eee2021-01-12 14:44:58 -0800177 }
178
Hongguangeae68392021-07-27 20:56:23 -0700179 return status;
Amy Zhanga046eee2021-01-12 14:44:58 -0800180}
181
Hongguangeae68392021-07-27 20:56:23 -0700182::ndk::ScopedAStatus TunerService::openLnbByName(const string& lnbName,
183 shared_ptr<ITunerLnb>* _aidl_return) {
Amy Zhang5af84142021-02-04 18:36:54 -0800184 if (!hasITuner()) {
Amy Zhangce2cb402021-01-21 12:50:47 -0800185 ALOGE("get ITuner failed");
Hongguangeae68392021-07-27 20:56:23 -0700186 return ::ndk::ScopedAStatus::fromServiceSpecificError(
187 static_cast<int32_t>(Result::UNAVAILABLE));
Amy Zhanga046eee2021-01-12 14:44:58 -0800188 }
189
Hongguangeae68392021-07-27 20:56:23 -0700190 vector<int32_t> id;
191 shared_ptr<ILnb> lnb;
192 auto status = mTuner->openLnbByName(lnbName, &id, &lnb);
193 if (status.isOk()) {
194 *_aidl_return = ::ndk::SharedRefBase::make<TunerLnb>(lnb, id[0]);
Amy Zhanga046eee2021-01-12 14:44:58 -0800195 }
196
Hongguangeae68392021-07-27 20:56:23 -0700197 return ::ndk::ScopedAStatus::ok();
Amy Zhang70de35a2020-10-12 20:13:16 -0700198}
199
Hongguangeae68392021-07-27 20:56:23 -0700200::ndk::ScopedAStatus TunerService::openDescrambler(int32_t /*descramblerHandle*/,
201 shared_ptr<ITunerDescrambler>* _aidl_return) {
Amy Zhang5af84142021-02-04 18:36:54 -0800202 if (!hasITuner()) {
Amy Zhangb2989b52021-02-05 12:27:25 -0800203 ALOGD("get ITuner failed");
Hongguangeae68392021-07-27 20:56:23 -0700204 return ::ndk::ScopedAStatus::fromServiceSpecificError(
205 static_cast<int32_t>(Result::UNAVAILABLE));
Amy Zhangb2989b52021-02-05 12:27:25 -0800206 }
207
Hongguangeae68392021-07-27 20:56:23 -0700208 shared_ptr<IDescrambler> descrambler;
Hongguang093c5f32021-08-09 19:46:34 -0700209 // int id = TunerHelper::getResourceIdFromHandle(descramblerHandle, DESCRAMBLER);
Hongguangeae68392021-07-27 20:56:23 -0700210 auto status = mTuner->openDescrambler(&descrambler);
211 if (status.isOk()) {
212 *_aidl_return = ::ndk::SharedRefBase::make<TunerDescrambler>(descrambler);
Amy Zhangb2989b52021-02-05 12:27:25 -0800213 }
214
Hongguangeae68392021-07-27 20:56:23 -0700215 return status;
Amy Zhangb2989b52021-02-05 12:27:25 -0800216}
217
Hongguangeae68392021-07-27 20:56:23 -0700218::ndk::ScopedAStatus TunerService::getTunerHalVersion(int* _aidl_return) {
Amy Zhangb1baabb2021-02-08 19:54:28 -0800219 hasITuner();
220 *_aidl_return = mTunerVersion;
Hongguangeae68392021-07-27 20:56:23 -0700221 return ::ndk::ScopedAStatus::ok();
Amy Zhangb1baabb2021-02-08 19:54:28 -0800222}
223
Hongguang34a479e2021-10-04 16:14:47 -0700224::ndk::ScopedAStatus TunerService::openSharedFilter(const string& in_filterToken,
225 const shared_ptr<ITunerFilterCallback>& in_cb,
226 shared_ptr<ITunerFilter>* _aidl_return) {
227 if (!hasITuner()) {
228 ALOGE("get ITuner failed");
229 return ::ndk::ScopedAStatus::fromServiceSpecificError(
230 static_cast<int32_t>(Result::UNAVAILABLE));
231 }
232
233 if (!PermissionCache::checkCallingPermission(sSharedFilterPermission)) {
234 ALOGE("Request requires android.permission.ACCESS_TV_SHARED_FILTER");
235 return ::ndk::ScopedAStatus::fromServiceSpecificError(
236 static_cast<int32_t>(Result::UNAVAILABLE));
237 }
238
239 Mutex::Autolock _l(mSharedFiltersLock);
240 if (mSharedFilters.find(in_filterToken) == mSharedFilters.end()) {
241 *_aidl_return = nullptr;
242 ALOGD("fail to find %s", in_filterToken.c_str());
243 return ::ndk::ScopedAStatus::fromServiceSpecificError(
244 static_cast<int32_t>(Result::INVALID_STATE));
245 }
246
247 shared_ptr<TunerFilter> filter = mSharedFilters.at(in_filterToken);
248 IPCThreadState* ipc = IPCThreadState::self();
249 const int pid = ipc->getCallingPid();
250 if (!filter->isSharedFilterAllowed(pid)) {
251 *_aidl_return = nullptr;
252 ALOGD("shared filter %s is opened in the same process", in_filterToken.c_str());
253 return ::ndk::ScopedAStatus::fromServiceSpecificError(
254 static_cast<int32_t>(Result::INVALID_STATE));
255 }
256
257 filter->attachSharedFilterCallback(in_cb);
258
259 *_aidl_return = filter;
260 return ::ndk::ScopedAStatus::ok();
261}
262
Hongguangd8ccaae2021-12-13 18:07:10 -0800263::ndk::ScopedAStatus TunerService::setLna(bool bEnable) {
264 if (!hasITuner()) {
265 ALOGD("get ITuner failed");
266 return ::ndk::ScopedAStatus::fromServiceSpecificError(
267 static_cast<int32_t>(Result::UNAVAILABLE));
268 }
269
270 return mTuner->setLna(bEnable);
271}
272
Hongguang34a479e2021-10-04 16:14:47 -0700273string TunerService::addFilterToShared(const shared_ptr<TunerFilter>& sharedFilter) {
274 Mutex::Autolock _l(mSharedFiltersLock);
275
276 // Use sharedFilter address as token.
277 string token = to_string(reinterpret_cast<std::uintptr_t>(sharedFilter.get()));
278 mSharedFilters[token] = sharedFilter;
279 return token;
280}
281
282void TunerService::removeSharedFilter(const shared_ptr<TunerFilter>& sharedFilter) {
283 Mutex::Autolock _l(mSharedFiltersLock);
284
285 // Use sharedFilter address as token.
286 mSharedFilters.erase(to_string(reinterpret_cast<std::uintptr_t>(sharedFilter.get())));
287}
288
Hongguang093c5f32021-08-09 19:46:34 -0700289void TunerService::updateTunerResources() {
290 if (!hasITuner()) {
291 ALOGE("Failed to updateTunerResources");
Amy Zhangce2cb402021-01-21 12:50:47 -0800292 return;
293 }
Hongguangeae68392021-07-27 20:56:23 -0700294
Hongguang093c5f32021-08-09 19:46:34 -0700295 TunerHelper::updateTunerResources(getTRMFrontendInfos(), getTRMLnbHandles());
296}
297
298vector<TunerFrontendInfo> TunerService::getTRMFrontendInfos() {
Amy Zhangce2cb402021-01-21 12:50:47 -0800299 vector<TunerFrontendInfo> infos;
Hongguang093c5f32021-08-09 19:46:34 -0700300 vector<int32_t> ids;
301 auto status = mTuner->getFrontendIds(&ids);
302 if (!status.isOk()) {
303 return infos;
304 }
305
Amy Zhangce2cb402021-01-21 12:50:47 -0800306 for (int i = 0; i < ids.size(); i++) {
307 FrontendInfo frontendInfo;
Hongguangeae68392021-07-27 20:56:23 -0700308 auto res = mTuner->getFrontendInfo(ids[i], &frontendInfo);
309 if (!res.isOk()) {
Amy Zhangce2cb402021-01-21 12:50:47 -0800310 continue;
311 }
312 TunerFrontendInfo tunerFrontendInfo{
Hongguang093c5f32021-08-09 19:46:34 -0700313 .handle = TunerHelper::getResourceHandleFromId((int)ids[i], FRONTEND),
Hongguangeae68392021-07-27 20:56:23 -0700314 .type = static_cast<int>(frontendInfo.type),
315 .exclusiveGroupId = frontendInfo.exclusiveGroupId,
Amy Zhangce2cb402021-01-21 12:50:47 -0800316 };
317 infos.push_back(tunerFrontendInfo);
318 }
Hongguang093c5f32021-08-09 19:46:34 -0700319
320 return infos;
Amy Zhangce2cb402021-01-21 12:50:47 -0800321}
322
Hongguang093c5f32021-08-09 19:46:34 -0700323vector<int32_t> TunerService::getTRMLnbHandles() {
Hongguangeae68392021-07-27 20:56:23 -0700324 vector<int32_t> lnbHandles;
325 if (mTuner != nullptr) {
326 vector<int32_t> lnbIds;
327 auto res = mTuner->getLnbIds(&lnbIds);
328 if (res.isOk()) {
Amy Zhangce2cb402021-01-21 12:50:47 -0800329 for (int i = 0; i < lnbIds.size(); i++) {
Hongguang093c5f32021-08-09 19:46:34 -0700330 lnbHandles.push_back(TunerHelper::getResourceHandleFromId(lnbIds[i], LNB));
Amy Zhangce2cb402021-01-21 12:50:47 -0800331 }
332 }
333 }
334
335 return lnbHandles;
336}
337
Hongguangeae68392021-07-27 20:56:23 -0700338} // namespace tuner
339} // namespace tv
340} // namespace media
341} // namespace android
342} // namespace aidl