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