• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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