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(const shared_ptr<IFilter> filter,const shared_ptr<FilterCallback> cb,const DemuxFilterType type,const shared_ptr<TunerService> tuner)39 TunerFilter::TunerFilter(const shared_ptr<IFilter> filter, const shared_ptr<FilterCallback> cb,
40                          const DemuxFilterType type, const shared_ptr<TunerService> tuner)
41       : mFilter(filter),
42         mType(type),
43         mStarted(false),
44         mShared(false),
45         mClientPid(-1),
46         mFilterCallback(cb),
47         mTunerService(tuner) {}
48 
~TunerFilter()49 TunerFilter::~TunerFilter() {
50     if (!isClosed) {
51         close();
52     }
53     freeSharedFilterToken("");
54     {
55         Mutex::Autolock _l(mLock);
56         mFilter = nullptr;
57         mTunerService = nullptr;
58     }
59 }
60 
getQueueDesc(AidlMQDesc * _aidl_return)61 ::ndk::ScopedAStatus TunerFilter::getQueueDesc(AidlMQDesc* _aidl_return) {
62     Mutex::Autolock _l(mLock);
63     if (mShared) {
64         IPCThreadState* ipc = IPCThreadState::self();
65         int32_t callingPid = ipc->getCallingPid();
66         if (callingPid == mClientPid) {
67             ALOGD("%s is called in wrong process", __FUNCTION__);
68             return ::ndk::ScopedAStatus::fromServiceSpecificError(
69                     static_cast<int32_t>(Result::INVALID_STATE));
70         }
71     }
72 
73     return mFilter->getQueueDesc(_aidl_return);
74 }
75 
getId(int32_t * _aidl_return)76 ::ndk::ScopedAStatus TunerFilter::getId(int32_t* _aidl_return) {
77     Mutex::Autolock _l(mLock);
78     if (mShared) {
79         ALOGD("%s is called on a shared filter", __FUNCTION__);
80         return ::ndk::ScopedAStatus::fromServiceSpecificError(
81                 static_cast<int32_t>(Result::INVALID_STATE));
82     }
83 
84     auto status = mFilter->getId(&mId);
85     if (status.isOk()) {
86         *_aidl_return = mId;
87     }
88     return status;
89 }
90 
getId64Bit(int64_t * _aidl_return)91 ::ndk::ScopedAStatus TunerFilter::getId64Bit(int64_t* _aidl_return) {
92     Mutex::Autolock _l(mLock);
93     if (mShared) {
94         ALOGD("%s is called on a shared filter", __FUNCTION__);
95         return ::ndk::ScopedAStatus::fromServiceSpecificError(
96                 static_cast<int32_t>(Result::INVALID_STATE));
97     }
98 
99     auto status = mFilter->getId64Bit(&mId64Bit);
100     if (status.isOk()) {
101         *_aidl_return = mId64Bit;
102     }
103     return status;
104 }
105 
configure(const DemuxFilterSettings & in_settings)106 ::ndk::ScopedAStatus TunerFilter::configure(const DemuxFilterSettings& in_settings) {
107     Mutex::Autolock _l(mLock);
108     if (mShared) {
109         ALOGD("%s is called on a shared filter", __FUNCTION__);
110         return ::ndk::ScopedAStatus::fromServiceSpecificError(
111                 static_cast<int32_t>(Result::INVALID_STATE));
112     }
113 
114     return mFilter->configure(in_settings);
115 }
116 
configureMonitorEvent(int32_t monitorEventType)117 ::ndk::ScopedAStatus TunerFilter::configureMonitorEvent(int32_t monitorEventType) {
118     Mutex::Autolock _l(mLock);
119     if (mShared) {
120         ALOGD("%s is called on a shared filter", __FUNCTION__);
121         return ::ndk::ScopedAStatus::fromServiceSpecificError(
122                 static_cast<int32_t>(Result::INVALID_STATE));
123     }
124 
125     return mFilter->configureMonitorEvent(monitorEventType);
126 }
127 
configureIpFilterContextId(int32_t cid)128 ::ndk::ScopedAStatus TunerFilter::configureIpFilterContextId(int32_t cid) {
129     Mutex::Autolock _l(mLock);
130     if (mShared) {
131         ALOGD("%s is called on a shared filter", __FUNCTION__);
132         return ::ndk::ScopedAStatus::fromServiceSpecificError(
133                 static_cast<int32_t>(Result::INVALID_STATE));
134     }
135 
136     return mFilter->configureIpCid(cid);
137 }
138 
configureAvStreamType(const AvStreamType & in_avStreamType)139 ::ndk::ScopedAStatus TunerFilter::configureAvStreamType(const AvStreamType& in_avStreamType) {
140     Mutex::Autolock _l(mLock);
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->configureAvStreamType(in_avStreamType);
148 }
149 
setDataSource(const shared_ptr<ITunerFilter> & filter)150 ::ndk::ScopedAStatus TunerFilter::setDataSource(const shared_ptr<ITunerFilter>& filter) {
151     Mutex::Autolock _l(mLock);
152     if (filter == nullptr) {
153         return ::ndk::ScopedAStatus::fromServiceSpecificError(
154                 static_cast<int32_t>(Result::INVALID_ARGUMENT));
155     }
156 
157     if (mShared) {
158         ALOGD("%s is called on a shared filter", __FUNCTION__);
159         return ::ndk::ScopedAStatus::fromServiceSpecificError(
160                 static_cast<int32_t>(Result::INVALID_STATE));
161     }
162 
163     shared_ptr<IFilter> halFilter = static_cast<TunerFilter*>(filter.get())->getHalFilter();
164     return mFilter->setDataSource(halFilter);
165 }
166 
getAvSharedHandle(NativeHandle * out_avMemory,int64_t * _aidl_return)167 ::ndk::ScopedAStatus TunerFilter::getAvSharedHandle(NativeHandle* out_avMemory,
168                                                     int64_t* _aidl_return) {
169     Mutex::Autolock _l(mLock);
170     if (mShared) {
171         ALOGD("%s is called on a shared filter", __FUNCTION__);
172         return ::ndk::ScopedAStatus::fromServiceSpecificError(
173                 static_cast<int32_t>(Result::INVALID_STATE));
174     }
175 
176     return mFilter->getAvSharedHandle(out_avMemory, _aidl_return);
177 }
178 
releaseAvHandle(const NativeHandle & in_handle,int64_t in_avDataId)179 ::ndk::ScopedAStatus TunerFilter::releaseAvHandle(const NativeHandle& in_handle,
180                                                   int64_t in_avDataId) {
181     Mutex::Autolock _l(mLock);
182     if (mShared) {
183         ALOGD("%s is called on a shared filter", __FUNCTION__);
184         return ::ndk::ScopedAStatus::fromServiceSpecificError(
185                 static_cast<int32_t>(Result::INVALID_STATE));
186     }
187 
188     return mFilter->releaseAvHandle(in_handle, in_avDataId);
189 }
190 
start()191 ::ndk::ScopedAStatus TunerFilter::start() {
192     Mutex::Autolock _l(mLock);
193     if (mShared) {
194         IPCThreadState* ipc = IPCThreadState::self();
195         int32_t callingPid = ipc->getCallingPid();
196         if (callingPid == mClientPid) {
197             ALOGD("%s is called in wrong process", __FUNCTION__);
198             return ::ndk::ScopedAStatus::fromServiceSpecificError(
199                     static_cast<int32_t>(Result::INVALID_STATE));
200         }
201     }
202 
203     auto res = mFilter->start();
204     if (res.isOk()) {
205         mStarted = true;
206     }
207     return res;
208 }
209 
stop()210 ::ndk::ScopedAStatus TunerFilter::stop() {
211     Mutex::Autolock _l(mLock);
212     if (mShared) {
213         IPCThreadState* ipc = IPCThreadState::self();
214         int32_t callingPid = ipc->getCallingPid();
215         if (callingPid == mClientPid) {
216             ALOGD("%s is called in wrong process", __FUNCTION__);
217             return ::ndk::ScopedAStatus::fromServiceSpecificError(
218                     static_cast<int32_t>(Result::INVALID_STATE));
219         }
220     }
221 
222     auto res = mFilter->stop();
223     mStarted = false;
224 
225     return res;
226 }
227 
flush()228 ::ndk::ScopedAStatus TunerFilter::flush() {
229     Mutex::Autolock _l(mLock);
230     if (mShared) {
231         IPCThreadState* ipc = IPCThreadState::self();
232         int32_t callingPid = ipc->getCallingPid();
233         if (callingPid == mClientPid) {
234             ALOGD("%s is called in wrong process", __FUNCTION__);
235             return ::ndk::ScopedAStatus::fromServiceSpecificError(
236                     static_cast<int32_t>(Result::INVALID_STATE));
237         }
238     }
239 
240     return mFilter->flush();
241 }
242 
close()243 ::ndk::ScopedAStatus TunerFilter::close() {
244     Mutex::Autolock _l(mLock);
245     if (mShared) {
246         IPCThreadState* ipc = IPCThreadState::self();
247         int32_t callingPid = ipc->getCallingPid();
248         if (callingPid == mClientPid) {
249             if (mFilterCallback != nullptr) {
250                 mFilterCallback->sendSharedFilterStatus(STATUS_INACCESSIBLE);
251                 mFilterCallback->detachSharedFilterCallback();
252             }
253             mTunerService->removeSharedFilter(this->ref<TunerFilter>());
254         } else {
255             // Calling from shared process, do not really close this filter.
256             if (mFilterCallback != nullptr) {
257                 mFilterCallback->detachSharedFilterCallback();
258             }
259             mStarted = false;
260             return ::ndk::ScopedAStatus::ok();
261         }
262     }
263 
264     if (mFilterCallback != nullptr) {
265         mFilterCallback->detachCallbacks();
266     }
267     auto res = mFilter->close();
268     mStarted = false;
269     mShared = false;
270     mClientPid = -1;
271     isClosed = true;
272 
273     return res;
274 }
275 
acquireSharedFilterToken(string * _aidl_return)276 ::ndk::ScopedAStatus TunerFilter::acquireSharedFilterToken(string* _aidl_return) {
277     Mutex::Autolock _l(mLock);
278     if (mShared || mStarted) {
279         ALOGD("create SharedFilter in wrong state");
280         return ::ndk::ScopedAStatus::fromServiceSpecificError(
281                 static_cast<int32_t>(Result::INVALID_STATE));
282     }
283 
284     IPCThreadState* ipc = IPCThreadState::self();
285     mClientPid = ipc->getCallingPid();
286     string token = mTunerService->addFilterToShared(this->ref<TunerFilter>());
287     _aidl_return->assign(token);
288     mShared = true;
289 
290     return ::ndk::ScopedAStatus::ok();
291 }
292 
freeSharedFilterToken(const string &)293 ::ndk::ScopedAStatus TunerFilter::freeSharedFilterToken(const string& /* in_filterToken */) {
294     Mutex::Autolock _l(mLock);
295     if (!mShared) {
296         // The filter is not shared or the shared filter has been closed.
297         return ::ndk::ScopedAStatus::ok();
298     }
299 
300     if (mFilterCallback != nullptr) {
301         mFilterCallback->sendSharedFilterStatus(STATUS_INACCESSIBLE);
302         mFilterCallback->detachSharedFilterCallback();
303     }
304 
305     mTunerService->removeSharedFilter(this->ref<TunerFilter>());
306     mShared = false;
307 
308     return ::ndk::ScopedAStatus::ok();
309 }
310 
getFilterType(DemuxFilterType * _aidl_return)311 ::ndk::ScopedAStatus TunerFilter::getFilterType(DemuxFilterType* _aidl_return) {
312     Mutex::Autolock _l(mLock);
313     *_aidl_return = mType;
314     return ::ndk::ScopedAStatus::ok();
315 }
316 
setDelayHint(const FilterDelayHint & in_hint)317 ::ndk::ScopedAStatus TunerFilter::setDelayHint(const FilterDelayHint& in_hint) {
318     Mutex::Autolock _l(mLock);
319     return mFilter->setDelayHint(in_hint);
320 }
321 
isSharedFilterAllowed(int callingPid)322 bool TunerFilter::isSharedFilterAllowed(int callingPid) {
323     return mShared && mClientPid != callingPid;
324 }
325 
attachSharedFilterCallback(const shared_ptr<ITunerFilterCallback> & in_cb)326 void TunerFilter::attachSharedFilterCallback(const shared_ptr<ITunerFilterCallback>& in_cb) {
327     if (mFilterCallback != nullptr) {
328         mFilterCallback->attachSharedFilterCallback(in_cb);
329     }
330 }
331 
getHalFilter()332 shared_ptr<IFilter> TunerFilter::getHalFilter() {
333     return mFilter;
334 }
335 
336 /////////////// FilterCallback ///////////////////////
onFilterStatus(DemuxFilterStatus status)337 ::ndk::ScopedAStatus TunerFilter::FilterCallback::onFilterStatus(DemuxFilterStatus status) {
338     Mutex::Autolock _l(mCallbackLock);
339     if (mTunerFilterCallback != nullptr) {
340         mTunerFilterCallback->onFilterStatus(status);
341     }
342     return ::ndk::ScopedAStatus::ok();
343 }
344 
onFilterEvent(const vector<DemuxFilterEvent> & events)345 ::ndk::ScopedAStatus TunerFilter::FilterCallback::onFilterEvent(
346         const vector<DemuxFilterEvent>& events) {
347     Mutex::Autolock _l(mCallbackLock);
348     if (mTunerFilterCallback != nullptr) {
349         mTunerFilterCallback->onFilterEvent(events);
350     }
351     return ::ndk::ScopedAStatus::ok();
352 }
353 
sendSharedFilterStatus(int32_t status)354 void TunerFilter::FilterCallback::sendSharedFilterStatus(int32_t status) {
355     Mutex::Autolock _l(mCallbackLock);
356     if (mTunerFilterCallback != nullptr && mOriginalCallback != nullptr) {
357         mTunerFilterCallback->onFilterStatus(static_cast<DemuxFilterStatus>(status));
358     }
359 }
360 
attachSharedFilterCallback(const shared_ptr<ITunerFilterCallback> & in_cb)361 void TunerFilter::FilterCallback::attachSharedFilterCallback(
362         const shared_ptr<ITunerFilterCallback>& in_cb) {
363     Mutex::Autolock _l(mCallbackLock);
364     mOriginalCallback = mTunerFilterCallback;
365     mTunerFilterCallback = in_cb;
366 }
367 
detachSharedFilterCallback()368 void TunerFilter::FilterCallback::detachSharedFilterCallback() {
369     Mutex::Autolock _l(mCallbackLock);
370     if (mTunerFilterCallback != nullptr && mOriginalCallback != nullptr) {
371         mTunerFilterCallback = mOriginalCallback;
372         mOriginalCallback = nullptr;
373     }
374 }
375 
detachCallbacks()376 void TunerFilter::FilterCallback::detachCallbacks() {
377     Mutex::Autolock _l(mCallbackLock);
378     mOriginalCallback = nullptr;
379     mTunerFilterCallback = nullptr;
380 }
381 
382 }  // namespace tuner
383 }  // namespace tv
384 }  // namespace media
385 }  // namespace android
386 }  // namespace aidl
387