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