1 /*
2 * Copyright 2021 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 "FilterClient"
18
19 #include "FilterClient.h"
20
21 #include <aidl/android/hardware/tv/tuner/DemuxFilterMainType.h>
22 #include <aidl/android/hardware/tv/tuner/DemuxQueueNotifyBits.h>
23 #include <aidlcommonsupport/NativeHandle.h>
24 #include <android-base/logging.h>
25 #include <utils/Log.h>
26
27 using ::aidl::android::hardware::common::NativeHandle;
28 using ::aidl::android::hardware::tv::tuner::DemuxFilterMainType;
29 using ::aidl::android::hardware::tv::tuner::DemuxFilterSubType;
30 using ::aidl::android::hardware::tv::tuner::DemuxMmtpFilterSettingsFilterSettings;
31 using ::aidl::android::hardware::tv::tuner::DemuxMmtpFilterType;
32 using ::aidl::android::hardware::tv::tuner::DemuxQueueNotifyBits;
33 using ::aidl::android::hardware::tv::tuner::DemuxTsFilterSettingsFilterSettings;
34 using ::aidl::android::hardware::tv::tuner::DemuxTsFilterType;
35 using ::aidl::android::hardware::tv::tuner::ScramblingStatus;
36
37 namespace android {
38 /////////////// FilterClient ///////////////////////
FilterClient(DemuxFilterType type,shared_ptr<ITunerFilter> tunerFilter)39 FilterClient::FilterClient(DemuxFilterType type, shared_ptr<ITunerFilter> tunerFilter) {
40 mTunerFilter = tunerFilter;
41 mAvSharedHandle = nullptr;
42 checkIsMediaFilter(type);
43 }
44
~FilterClient()45 FilterClient::~FilterClient() {
46 Mutex::Autolock _l(mLock);
47 mTunerFilter = nullptr;
48 mAvSharedHandle = nullptr;
49 mAvSharedMemSize = 0;
50 mIsMediaFilter = false;
51 mIsPassthroughFilter = false;
52 mFilterMQ = nullptr;
53 mFilterMQEventFlag = nullptr;
54 }
55
read(int8_t * buffer,int64_t size)56 int64_t FilterClient::read(int8_t* buffer, int64_t size) {
57 Result res = getFilterMq();
58 if (res != Result::SUCCESS) {
59 return -1;
60 }
61 return copyData(buffer, size);
62 }
63
getAvSharedHandleInfo()64 SharedHandleInfo FilterClient::getAvSharedHandleInfo() {
65 handleAvShareMemory();
66 SharedHandleInfo info{
67 .sharedHandle = (mIsMediaFilter && !mIsPassthroughFilter) ? mAvSharedHandle : nullptr,
68 .size = mAvSharedMemSize,
69 };
70
71 return info;
72 }
73
configure(DemuxFilterSettings configure)74 Result FilterClient::configure(DemuxFilterSettings configure) {
75 Result res;
76 checkIsPassthroughFilter(configure);
77
78 Mutex::Autolock _l(mLock);
79 if (mTunerFilter != nullptr) {
80 Status s = mTunerFilter->configure(configure);
81 res = ClientHelper::getServiceSpecificErrorCode(s);
82 if (res == Result::SUCCESS) {
83 getAvSharedHandleInfo();
84 }
85 return res;
86 }
87
88 return Result::INVALID_STATE;
89 }
90
configureMonitorEvent(int32_t monitorEventType)91 Result FilterClient::configureMonitorEvent(int32_t monitorEventType) {
92 Mutex::Autolock _l(mLock);
93 if (mTunerFilter != nullptr) {
94 Status s = mTunerFilter->configureMonitorEvent(monitorEventType);
95 return ClientHelper::getServiceSpecificErrorCode(s);
96 }
97
98 return Result::INVALID_STATE;
99 }
100
configureIpFilterContextId(int32_t cid)101 Result FilterClient::configureIpFilterContextId(int32_t cid) {
102 Mutex::Autolock _l(mLock);
103 if (mTunerFilter != nullptr) {
104 Status s = mTunerFilter->configureIpFilterContextId(cid);
105 return ClientHelper::getServiceSpecificErrorCode(s);
106 }
107
108 return Result::INVALID_STATE;
109 }
110
configureAvStreamType(AvStreamType avStreamType)111 Result FilterClient::configureAvStreamType(AvStreamType avStreamType) {
112 Mutex::Autolock _l(mLock);
113 if (mTunerFilter != nullptr) {
114 Status s = mTunerFilter->configureAvStreamType(avStreamType);
115 return ClientHelper::getServiceSpecificErrorCode(s);
116 }
117
118 return Result::INVALID_STATE;
119 }
120
start()121 Result FilterClient::start() {
122 Mutex::Autolock _l(mLock);
123 if (mTunerFilter != nullptr) {
124 Status s = mTunerFilter->start();
125 return ClientHelper::getServiceSpecificErrorCode(s);
126 }
127
128 return Result::INVALID_STATE;
129 }
130
stop()131 Result FilterClient::stop() {
132 Mutex::Autolock _l(mLock);
133 if (mTunerFilter != nullptr) {
134 Status s = mTunerFilter->stop();
135 return ClientHelper::getServiceSpecificErrorCode(s);
136 }
137
138 return Result::INVALID_STATE;
139 }
140
flush()141 Result FilterClient::flush() {
142 Mutex::Autolock _l(mLock);
143 if (mTunerFilter != nullptr) {
144 Status s = mTunerFilter->flush();
145 return ClientHelper::getServiceSpecificErrorCode(s);
146 }
147
148 return Result::INVALID_STATE;
149 }
150
getId(int32_t & id)151 Result FilterClient::getId(int32_t& id) {
152 Mutex::Autolock _l(mLock);
153 if (mTunerFilter != nullptr) {
154 Status s = mTunerFilter->getId(&id);
155 return ClientHelper::getServiceSpecificErrorCode(s);
156 }
157
158 return Result::INVALID_STATE;
159 }
160
getId64Bit(int64_t & id)161 Result FilterClient::getId64Bit(int64_t& id) {
162 Mutex::Autolock _l(mLock);
163 if (mTunerFilter != nullptr) {
164 Status s = mTunerFilter->getId64Bit(&id);
165 return ClientHelper::getServiceSpecificErrorCode(s);
166 }
167
168 return Result::INVALID_STATE;
169 }
170
releaseAvHandle(native_handle_t * handle,uint64_t avDataId)171 Result FilterClient::releaseAvHandle(native_handle_t* handle, uint64_t avDataId) {
172 Mutex::Autolock _l(mLock);
173 if (mTunerFilter != nullptr) {
174 Status s = mTunerFilter->releaseAvHandle(dupToAidl(handle), avDataId);
175 return ClientHelper::getServiceSpecificErrorCode(s);
176 }
177
178 return Result::INVALID_STATE;
179 }
180
setDataSource(sp<FilterClient> filterClient)181 Result FilterClient::setDataSource(sp<FilterClient> filterClient){
182 Mutex::Autolock _l(mLock);
183 if (mTunerFilter != nullptr) {
184 Status s = mTunerFilter->setDataSource(filterClient->getAidlFilter());
185 return ClientHelper::getServiceSpecificErrorCode(s);
186 }
187
188 return Result::INVALID_STATE;
189 }
190
close()191 Result FilterClient::close() {
192 Mutex::Autolock _l(mLock);
193 if (mFilterMQEventFlag != nullptr) {
194 EventFlag::deleteEventFlag(&mFilterMQEventFlag);
195 mFilterMQEventFlag = nullptr;
196 }
197 if (mFilterMQ != nullptr) {
198 delete mFilterMQ;
199 mFilterMQ = nullptr;
200 }
201
202 if (mTunerFilter != nullptr) {
203 Status s = mTunerFilter->close();
204 closeAvSharedMemory();
205 mTunerFilter = nullptr;
206 return ClientHelper::getServiceSpecificErrorCode(s);
207 }
208
209 return Result::INVALID_STATE;
210 }
211
acquireSharedFilterToken()212 string FilterClient::acquireSharedFilterToken() {
213 Mutex::Autolock _l(mLock);
214 if (mTunerFilter != nullptr) {
215 string filterToken;
216 if (mTunerFilter->acquireSharedFilterToken(&filterToken).isOk()) {
217 return filterToken;
218 }
219 }
220
221 return "";
222 }
223
freeSharedFilterToken(const string & filterToken)224 Result FilterClient::freeSharedFilterToken(const string& filterToken) {
225 Mutex::Autolock _l(mLock);
226 if (mTunerFilter != nullptr) {
227 Status s = mTunerFilter->freeSharedFilterToken(filterToken);
228 return ClientHelper::getServiceSpecificErrorCode(s);
229 }
230
231 return Result::INVALID_STATE;
232 }
233
234 /////////////// TunerFilterCallback ///////////////////////
TunerFilterCallback(sp<FilterClientCallback> filterClientCallback)235 TunerFilterCallback::TunerFilterCallback(sp<FilterClientCallback> filterClientCallback)
236 : mFilterClientCallback(filterClientCallback) {}
237
onFilterStatus(DemuxFilterStatus status)238 Status TunerFilterCallback::onFilterStatus(DemuxFilterStatus status) {
239 if (mFilterClientCallback != nullptr) {
240 mFilterClientCallback->onFilterStatus(status);
241 return Status::ok();
242 }
243 return Status::fromServiceSpecificError(static_cast<int32_t>(Result::INVALID_STATE));
244 }
245
onFilterEvent(const vector<DemuxFilterEvent> & filterEvents)246 Status TunerFilterCallback::onFilterEvent(const vector<DemuxFilterEvent>& filterEvents) {
247 if (mFilterClientCallback != nullptr) {
248 mFilterClientCallback->onFilterEvent(filterEvents);
249 return Status::ok();
250 }
251 return Status::fromServiceSpecificError(static_cast<int32_t>(Result::INVALID_STATE));
252 }
253
getFilterMq()254 Result FilterClient::getFilterMq() {
255 Mutex::Autolock _l(mLock);
256 if (mFilterMQ != nullptr) {
257 return Result::SUCCESS;
258 }
259
260 AidlMQDesc aidlMqDesc;
261 Result res = Result::UNAVAILABLE;
262
263 if (mTunerFilter != nullptr) {
264 Status s = mTunerFilter->getQueueDesc(&aidlMqDesc);
265 res = ClientHelper::getServiceSpecificErrorCode(s);
266 if (s.isOk()) {
267 mFilterMQ = new (nothrow) AidlMQ(aidlMqDesc, false/*resetPointer*/);
268 EventFlag::createEventFlag(mFilterMQ->getEventFlagWord(), &mFilterMQEventFlag);
269 }
270 }
271
272 return res;
273 }
274
copyData(int8_t * buffer,int64_t size)275 int64_t FilterClient::copyData(int8_t* buffer, int64_t size) {
276 if (mFilterMQ == nullptr || mFilterMQEventFlag == nullptr) {
277 return -1;
278 }
279
280 int64_t available = mFilterMQ->availableToRead();
281 size = min(size, available);
282
283 if (mFilterMQ->read(buffer, size)) {
284 mFilterMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED));
285 } else {
286 return -1;
287 }
288
289 return size;
290 }
291
checkIsMediaFilter(DemuxFilterType type)292 void FilterClient::checkIsMediaFilter(DemuxFilterType type) {
293 if (type.mainType == DemuxFilterMainType::MMTP) {
294 if (type.subType.get<DemuxFilterSubType::Tag::mmtpFilterType>() ==
295 DemuxMmtpFilterType::AUDIO ||
296 type.subType.get<DemuxFilterSubType::Tag::mmtpFilterType>() ==
297 DemuxMmtpFilterType::VIDEO) {
298 mIsMediaFilter = true;
299 return;
300 }
301 }
302
303 if (type.mainType == DemuxFilterMainType::TS) {
304 if (type.subType.get<DemuxFilterSubType::Tag::tsFilterType>() == DemuxTsFilterType::AUDIO ||
305 type.subType.get<DemuxFilterSubType::Tag::tsFilterType>() == DemuxTsFilterType::VIDEO) {
306 mIsMediaFilter = true;
307 return;
308 }
309 }
310
311 mIsMediaFilter = false;
312 }
313
checkIsPassthroughFilter(DemuxFilterSettings configure)314 void FilterClient::checkIsPassthroughFilter(DemuxFilterSettings configure) {
315 if (!mIsMediaFilter) {
316 mIsPassthroughFilter = false;
317 return;
318 }
319
320 if (configure.getTag() == DemuxFilterSettings::Tag::ts) {
321 if (configure.get<DemuxFilterSettings::Tag::ts>()
322 .filterSettings.get<DemuxTsFilterSettingsFilterSettings::Tag::av>()
323 .isPassthrough) {
324 mIsPassthroughFilter = true;
325 return;
326 }
327 }
328
329 if (configure.getTag() == DemuxFilterSettings::Tag::mmtp) {
330 if (configure.get<DemuxFilterSettings::Tag::mmtp>()
331 .filterSettings.get<DemuxMmtpFilterSettingsFilterSettings::Tag::av>()
332 .isPassthrough) {
333 mIsPassthroughFilter = true;
334 return;
335 }
336 }
337
338 mIsPassthroughFilter = false;
339 }
340
handleAvShareMemory()341 void FilterClient::handleAvShareMemory() {
342 if (mAvSharedHandle != nullptr) {
343 return;
344 }
345 if (mTunerFilter != nullptr && mIsMediaFilter && !mIsPassthroughFilter) {
346 int64_t size;
347 NativeHandle avMemory;
348 Status s = mTunerFilter->getAvSharedHandle(&avMemory, &size);
349 if (s.isOk()) {
350 mAvSharedHandle = dupFromAidl(avMemory);
351 mAvSharedMemSize = size;
352 }
353 }
354 }
355
closeAvSharedMemory()356 void FilterClient::closeAvSharedMemory() {
357 if (mAvSharedHandle == nullptr) {
358 mAvSharedMemSize = 0;
359 return;
360 }
361 native_handle_close(mAvSharedHandle);
362 native_handle_delete(mAvSharedHandle);
363 mAvSharedMemSize = 0;
364 mAvSharedHandle = nullptr;
365 }
366
setDelayHint(const FilterDelayHint & hint)367 Result FilterClient::setDelayHint(const FilterDelayHint& hint) {
368 if (mTunerFilter) {
369 Status s = mTunerFilter->setDelayHint(hint);
370 return ClientHelper::getServiceSpecificErrorCode(s);
371 }
372 return Result::INVALID_STATE;
373 }
374
375 } // namespace android
376