• 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 "TunerFilter"
18 
19 #include "TunerFilter.h"
20 
21 #include <aidl/android/hardware/tv/tuner/Result.h>
22 #include <binder/IPCThreadState.h>
23 
24 #include "TunerHelper.h"
25 #include "TunerService.h"
26 
27 using ::aidl::android::hardware::tv::tuner::Result;
28 
29 namespace aidl {
30 namespace android {
31 namespace media {
32 namespace tv {
33 namespace tuner {
34 
35 using ::android::IPCThreadState;
36 
37 using namespace std;
38 
TunerFilter(shared_ptr<IFilter> filter,shared_ptr<FilterCallback> cb,DemuxFilterType type)39 TunerFilter::TunerFilter(shared_ptr<IFilter> filter, shared_ptr<FilterCallback> cb,
40                          DemuxFilterType type)
41       : mFilter(filter),
42         mType(type),
43         mStarted(false),
44         mShared(false),
45         mClientPid(-1),
46         mFilterCallback(cb) {}
47 
~TunerFilter()48 TunerFilter::~TunerFilter() {
49     Mutex::Autolock _l(mLock);
50     mFilter = nullptr;
51 }
52 
getQueueDesc(AidlMQDesc * _aidl_return)53 ::ndk::ScopedAStatus TunerFilter::getQueueDesc(AidlMQDesc* _aidl_return) {
54     Mutex::Autolock _l(mLock);
55     if (mFilter == nullptr) {
56         ALOGE("IFilter is not initialized");
57         return ::ndk::ScopedAStatus::fromServiceSpecificError(
58                 static_cast<int32_t>(Result::UNAVAILABLE));
59     }
60 
61     if (mShared) {
62         IPCThreadState* ipc = IPCThreadState::self();
63         int32_t callingPid = ipc->getCallingPid();
64         if (callingPid == mClientPid) {
65             ALOGD("%s is called in wrong process", __FUNCTION__);
66             return ::ndk::ScopedAStatus::fromServiceSpecificError(
67                     static_cast<int32_t>(Result::INVALID_STATE));
68         }
69     }
70 
71     return mFilter->getQueueDesc(_aidl_return);
72 }
73 
getId(int32_t * _aidl_return)74 ::ndk::ScopedAStatus TunerFilter::getId(int32_t* _aidl_return) {
75     Mutex::Autolock _l(mLock);
76     if (mFilter == nullptr) {
77         ALOGE("IFilter is not initialized");
78         return ::ndk::ScopedAStatus::fromServiceSpecificError(
79                 static_cast<int32_t>(Result::UNAVAILABLE));
80     }
81 
82     if (mShared) {
83         ALOGD("%s is called on a shared filter", __FUNCTION__);
84         return ::ndk::ScopedAStatus::fromServiceSpecificError(
85                 static_cast<int32_t>(Result::INVALID_STATE));
86     }
87 
88     auto status = mFilter->getId(&mId);
89     if (status.isOk()) {
90         *_aidl_return = mId;
91     }
92     return status;
93 }
94 
getId64Bit(int64_t * _aidl_return)95 ::ndk::ScopedAStatus TunerFilter::getId64Bit(int64_t* _aidl_return) {
96     Mutex::Autolock _l(mLock);
97     if (mFilter == nullptr) {
98         ALOGE("IFilter is not initialized");
99         return ::ndk::ScopedAStatus::fromServiceSpecificError(
100                 static_cast<int32_t>(Result::UNAVAILABLE));
101     }
102 
103     if (mShared) {
104         ALOGD("%s is called on a shared filter", __FUNCTION__);
105         return ::ndk::ScopedAStatus::fromServiceSpecificError(
106                 static_cast<int32_t>(Result::INVALID_STATE));
107     }
108 
109     auto status = mFilter->getId64Bit(&mId64Bit);
110     if (status.isOk()) {
111         *_aidl_return = mId64Bit;
112     }
113     return status;
114 }
115 
configure(const DemuxFilterSettings & in_settings)116 ::ndk::ScopedAStatus TunerFilter::configure(const DemuxFilterSettings& in_settings) {
117     Mutex::Autolock _l(mLock);
118     if (mFilter == nullptr) {
119         ALOGE("IFilter is not initialized");
120         return ::ndk::ScopedAStatus::fromServiceSpecificError(
121                 static_cast<int32_t>(Result::UNAVAILABLE));
122     }
123 
124     if (mShared) {
125         ALOGD("%s is called on a shared filter", __FUNCTION__);
126         return ::ndk::ScopedAStatus::fromServiceSpecificError(
127                 static_cast<int32_t>(Result::INVALID_STATE));
128     }
129 
130     return mFilter->configure(in_settings);
131 }
132 
configureMonitorEvent(int32_t monitorEventType)133 ::ndk::ScopedAStatus TunerFilter::configureMonitorEvent(int32_t monitorEventType) {
134     Mutex::Autolock _l(mLock);
135     if (mFilter == nullptr) {
136         ALOGE("IFilter is not initialized");
137         return ::ndk::ScopedAStatus::fromServiceSpecificError(
138                 static_cast<int32_t>(Result::UNAVAILABLE));
139     }
140 
141     if (mShared) {
142         ALOGD("%s is called on a shared filter", __FUNCTION__);
143         return ::ndk::ScopedAStatus::fromServiceSpecificError(
144                 static_cast<int32_t>(Result::INVALID_STATE));
145     }
146 
147     return mFilter->configureMonitorEvent(monitorEventType);
148 }
149 
configureIpFilterContextId(int32_t cid)150 ::ndk::ScopedAStatus TunerFilter::configureIpFilterContextId(int32_t cid) {
151     Mutex::Autolock _l(mLock);
152     if (mFilter == nullptr) {
153         ALOGE("IFilter is not initialized");
154         return ::ndk::ScopedAStatus::fromServiceSpecificError(
155                 static_cast<int32_t>(Result::UNAVAILABLE));
156     }
157 
158     if (mShared) {
159         ALOGD("%s is called on a shared filter", __FUNCTION__);
160         return ::ndk::ScopedAStatus::fromServiceSpecificError(
161                 static_cast<int32_t>(Result::INVALID_STATE));
162     }
163 
164     return mFilter->configureIpCid(cid);
165 }
166 
configureAvStreamType(const AvStreamType & in_avStreamType)167 ::ndk::ScopedAStatus TunerFilter::configureAvStreamType(const AvStreamType& in_avStreamType) {
168     Mutex::Autolock _l(mLock);
169     if (mFilter == nullptr) {
170         ALOGE("IFilter is not initialized");
171         return ::ndk::ScopedAStatus::fromServiceSpecificError(
172                 static_cast<int32_t>(Result::UNAVAILABLE));
173     }
174 
175     if (mShared) {
176         ALOGD("%s is called on a shared filter", __FUNCTION__);
177         return ::ndk::ScopedAStatus::fromServiceSpecificError(
178                 static_cast<int32_t>(Result::INVALID_STATE));
179     }
180 
181     return mFilter->configureAvStreamType(in_avStreamType);
182 }
183 
setDataSource(const shared_ptr<ITunerFilter> & filter)184 ::ndk::ScopedAStatus TunerFilter::setDataSource(const shared_ptr<ITunerFilter>& filter) {
185     Mutex::Autolock _l(mLock);
186     if (mFilter == nullptr) {
187         ALOGE("IFilter is not initialized");
188         return ::ndk::ScopedAStatus::fromServiceSpecificError(
189                 static_cast<int32_t>(Result::UNAVAILABLE));
190     }
191 
192     if (filter == nullptr) {
193         return ::ndk::ScopedAStatus::fromServiceSpecificError(
194                 static_cast<int32_t>(Result::INVALID_ARGUMENT));
195     }
196 
197     if (mShared) {
198         ALOGD("%s is called on a shared filter", __FUNCTION__);
199         return ::ndk::ScopedAStatus::fromServiceSpecificError(
200                 static_cast<int32_t>(Result::INVALID_STATE));
201     }
202 
203     shared_ptr<IFilter> halFilter = static_cast<TunerFilter*>(filter.get())->getHalFilter();
204     return mFilter->setDataSource(halFilter);
205 }
206 
getAvSharedHandle(NativeHandle * out_avMemory,int64_t * _aidl_return)207 ::ndk::ScopedAStatus TunerFilter::getAvSharedHandle(NativeHandle* out_avMemory,
208                                                     int64_t* _aidl_return) {
209     Mutex::Autolock _l(mLock);
210     if (mFilter == nullptr) {
211         ALOGE("IFilter is not initialized");
212         return ::ndk::ScopedAStatus::fromServiceSpecificError(
213                 static_cast<int32_t>(Result::UNAVAILABLE));
214     }
215 
216     if (mShared) {
217         ALOGD("%s is called on a shared filter", __FUNCTION__);
218         return ::ndk::ScopedAStatus::fromServiceSpecificError(
219                 static_cast<int32_t>(Result::INVALID_STATE));
220     }
221 
222     return mFilter->getAvSharedHandle(out_avMemory, _aidl_return);
223 }
224 
releaseAvHandle(const NativeHandle & in_handle,int64_t in_avDataId)225 ::ndk::ScopedAStatus TunerFilter::releaseAvHandle(const NativeHandle& in_handle,
226                                                   int64_t in_avDataId) {
227     Mutex::Autolock _l(mLock);
228     if (mFilter == nullptr) {
229         ALOGE("IFilter is not initialized");
230         return ::ndk::ScopedAStatus::fromServiceSpecificError(
231                 static_cast<int32_t>(Result::UNAVAILABLE));
232     }
233 
234     if (mShared) {
235         ALOGD("%s is called on a shared filter", __FUNCTION__);
236         return ::ndk::ScopedAStatus::fromServiceSpecificError(
237                 static_cast<int32_t>(Result::INVALID_STATE));
238     }
239 
240     return mFilter->releaseAvHandle(in_handle, in_avDataId);
241 }
242 
start()243 ::ndk::ScopedAStatus TunerFilter::start() {
244     Mutex::Autolock _l(mLock);
245     if (mFilter == nullptr) {
246         ALOGE("IFilter is not initialized");
247         return ::ndk::ScopedAStatus::fromServiceSpecificError(
248                 static_cast<int32_t>(Result::UNAVAILABLE));
249     }
250 
251     if (mShared) {
252         IPCThreadState* ipc = IPCThreadState::self();
253         int32_t callingPid = ipc->getCallingPid();
254         if (callingPid == mClientPid) {
255             ALOGD("%s is called in wrong process", __FUNCTION__);
256             return ::ndk::ScopedAStatus::fromServiceSpecificError(
257                     static_cast<int32_t>(Result::INVALID_STATE));
258         }
259     }
260 
261     auto res = mFilter->start();
262     if (res.isOk()) {
263         mStarted = true;
264     }
265     return res;
266 }
267 
stop()268 ::ndk::ScopedAStatus TunerFilter::stop() {
269     Mutex::Autolock _l(mLock);
270     if (mFilter == nullptr) {
271         ALOGE("IFilter is not initialized");
272         return ::ndk::ScopedAStatus::fromServiceSpecificError(
273                 static_cast<int32_t>(Result::UNAVAILABLE));
274     }
275 
276     if (mShared) {
277         IPCThreadState* ipc = IPCThreadState::self();
278         int32_t callingPid = ipc->getCallingPid();
279         if (callingPid == mClientPid) {
280             ALOGD("%s is called in wrong process", __FUNCTION__);
281             return ::ndk::ScopedAStatus::fromServiceSpecificError(
282                     static_cast<int32_t>(Result::INVALID_STATE));
283         }
284     }
285 
286     auto res = mFilter->stop();
287     mStarted = false;
288 
289     return res;
290 }
291 
flush()292 ::ndk::ScopedAStatus TunerFilter::flush() {
293     Mutex::Autolock _l(mLock);
294     if (mFilter == nullptr) {
295         ALOGE("IFilter is not initialized");
296         return ::ndk::ScopedAStatus::fromServiceSpecificError(
297                 static_cast<int32_t>(Result::UNAVAILABLE));
298     }
299 
300     if (mShared) {
301         IPCThreadState* ipc = IPCThreadState::self();
302         int32_t callingPid = ipc->getCallingPid();
303         if (callingPid == mClientPid) {
304             ALOGD("%s is called in wrong process", __FUNCTION__);
305             return ::ndk::ScopedAStatus::fromServiceSpecificError(
306                     static_cast<int32_t>(Result::INVALID_STATE));
307         }
308     }
309 
310     return mFilter->flush();
311 }
312 
close()313 ::ndk::ScopedAStatus TunerFilter::close() {
314     Mutex::Autolock _l(mLock);
315     if (mFilter == nullptr) {
316         ALOGE("IFilter is not initialized");
317         return ::ndk::ScopedAStatus::fromServiceSpecificError(
318                 static_cast<int32_t>(Result::UNAVAILABLE));
319     }
320 
321     if (mShared) {
322         IPCThreadState* ipc = IPCThreadState::self();
323         int32_t callingPid = ipc->getCallingPid();
324         if (callingPid == mClientPid) {
325             if (mFilterCallback != nullptr) {
326                 mFilterCallback->sendSharedFilterStatus(STATUS_INACCESSIBLE);
327                 mFilterCallback->detachSharedFilterCallback();
328             }
329             TunerService::getTunerService()->removeSharedFilter(this->ref<TunerFilter>());
330         } else {
331             // Calling from shared process, do not really close this filter.
332             if (mFilterCallback != nullptr) {
333                 mFilterCallback->detachSharedFilterCallback();
334             }
335             mStarted = false;
336             return ::ndk::ScopedAStatus::ok();
337         }
338     }
339 
340     if (mFilterCallback != nullptr) {
341         mFilterCallback->detachCallbacks();
342     }
343     auto res = mFilter->close();
344     mFilter = nullptr;
345     mStarted = false;
346     mShared = false;
347     mClientPid = -1;
348 
349     return res;
350 }
351 
acquireSharedFilterToken(string * _aidl_return)352 ::ndk::ScopedAStatus TunerFilter::acquireSharedFilterToken(string* _aidl_return) {
353     Mutex::Autolock _l(mLock);
354     if (mFilter == nullptr) {
355         ALOGE("IFilter is not initialized");
356         return ::ndk::ScopedAStatus::fromServiceSpecificError(
357                 static_cast<int32_t>(Result::UNAVAILABLE));
358     }
359 
360     if (mShared || mStarted) {
361         ALOGD("create SharedFilter in wrong state");
362         return ::ndk::ScopedAStatus::fromServiceSpecificError(
363                 static_cast<int32_t>(Result::INVALID_STATE));
364     }
365 
366     IPCThreadState* ipc = IPCThreadState::self();
367     mClientPid = ipc->getCallingPid();
368     string token = TunerService::getTunerService()->addFilterToShared(this->ref<TunerFilter>());
369     _aidl_return->assign(token);
370     mShared = true;
371 
372     return ::ndk::ScopedAStatus::ok();
373 }
374 
freeSharedFilterToken(const string &)375 ::ndk::ScopedAStatus TunerFilter::freeSharedFilterToken(const string& /* in_filterToken */) {
376     Mutex::Autolock _l(mLock);
377     if (mFilter == nullptr) {
378         ALOGE("IFilter is not initialized");
379         return ::ndk::ScopedAStatus::fromServiceSpecificError(
380                 static_cast<int32_t>(Result::UNAVAILABLE));
381     }
382 
383     if (!mShared) {
384         // The filter is not shared or the shared filter has been closed.
385         return ::ndk::ScopedAStatus::ok();
386     }
387 
388     if (mFilterCallback != nullptr) {
389         mFilterCallback->sendSharedFilterStatus(STATUS_INACCESSIBLE);
390         mFilterCallback->detachSharedFilterCallback();
391     }
392 
393     TunerService::getTunerService()->removeSharedFilter(this->ref<TunerFilter>());
394     mShared = false;
395 
396     return ::ndk::ScopedAStatus::ok();
397 }
398 
getFilterType(DemuxFilterType * _aidl_return)399 ::ndk::ScopedAStatus TunerFilter::getFilterType(DemuxFilterType* _aidl_return) {
400     Mutex::Autolock _l(mLock);
401     if (mFilter == nullptr) {
402         ALOGE("IFilter is not initialized");
403         return ::ndk::ScopedAStatus::fromServiceSpecificError(
404                 static_cast<int32_t>(Result::UNAVAILABLE));
405     }
406 
407     *_aidl_return = mType;
408     return ::ndk::ScopedAStatus::ok();
409 }
410 
setDelayHint(const FilterDelayHint & in_hint)411 ::ndk::ScopedAStatus TunerFilter::setDelayHint(const FilterDelayHint& in_hint) {
412     Mutex::Autolock _l(mLock);
413     if (mFilter == nullptr) {
414         ALOGE("IFilter is not initialized");
415         return ::ndk::ScopedAStatus::fromServiceSpecificError(
416                 static_cast<int32_t>(Result::UNAVAILABLE));
417     }
418 
419     return mFilter->setDelayHint(in_hint);
420 }
421 
isSharedFilterAllowed(int callingPid)422 bool TunerFilter::isSharedFilterAllowed(int callingPid) {
423     return mShared && mClientPid != callingPid;
424 }
425 
attachSharedFilterCallback(const shared_ptr<ITunerFilterCallback> & in_cb)426 void TunerFilter::attachSharedFilterCallback(const shared_ptr<ITunerFilterCallback>& in_cb) {
427     if (mFilterCallback != nullptr) {
428         mFilterCallback->attachSharedFilterCallback(in_cb);
429     }
430 }
431 
getHalFilter()432 shared_ptr<IFilter> TunerFilter::getHalFilter() {
433     return mFilter;
434 }
435 
436 /////////////// FilterCallback ///////////////////////
onFilterStatus(DemuxFilterStatus status)437 ::ndk::ScopedAStatus TunerFilter::FilterCallback::onFilterStatus(DemuxFilterStatus status) {
438     Mutex::Autolock _l(mCallbackLock);
439     if (mTunerFilterCallback != nullptr) {
440         mTunerFilterCallback->onFilterStatus(status);
441     }
442     return ::ndk::ScopedAStatus::ok();
443 }
444 
onFilterEvent(const vector<DemuxFilterEvent> & events)445 ::ndk::ScopedAStatus TunerFilter::FilterCallback::onFilterEvent(
446         const vector<DemuxFilterEvent>& events) {
447     Mutex::Autolock _l(mCallbackLock);
448     if (mTunerFilterCallback != nullptr) {
449         mTunerFilterCallback->onFilterEvent(events);
450     }
451     return ::ndk::ScopedAStatus::ok();
452 }
453 
sendSharedFilterStatus(int32_t status)454 void TunerFilter::FilterCallback::sendSharedFilterStatus(int32_t status) {
455     Mutex::Autolock _l(mCallbackLock);
456     if (mTunerFilterCallback != nullptr && mOriginalCallback != nullptr) {
457         mTunerFilterCallback->onFilterStatus(static_cast<DemuxFilterStatus>(status));
458     }
459 }
460 
attachSharedFilterCallback(const shared_ptr<ITunerFilterCallback> & in_cb)461 void TunerFilter::FilterCallback::attachSharedFilterCallback(
462         const shared_ptr<ITunerFilterCallback>& in_cb) {
463     Mutex::Autolock _l(mCallbackLock);
464     mOriginalCallback = mTunerFilterCallback;
465     mTunerFilterCallback = in_cb;
466 }
467 
detachSharedFilterCallback()468 void TunerFilter::FilterCallback::detachSharedFilterCallback() {
469     Mutex::Autolock _l(mCallbackLock);
470     if (mTunerFilterCallback != nullptr && mOriginalCallback != nullptr) {
471         mTunerFilterCallback = mOriginalCallback;
472         mOriginalCallback = nullptr;
473     }
474 }
475 
detachCallbacks()476 void TunerFilter::FilterCallback::detachCallbacks() {
477     Mutex::Autolock _l(mCallbackLock);
478     mOriginalCallback = nullptr;
479     mTunerFilterCallback = nullptr;
480 }
481 
482 }  // namespace tuner
483 }  // namespace tv
484 }  // namespace media
485 }  // namespace android
486 }  // namespace aidl
487