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