Add SharedFilter to tuner service.
Bug: 196124225
Test: atest android.media.tv.tuner.cts on both AIDL and HIDL HAL.
Change-Id: I91b1f9ef09b0bda868b7817be4d946d11629b16c
diff --git a/services/tuner/hidl/TunerHidlDemux.cpp b/services/tuner/hidl/TunerHidlDemux.cpp
index 5a921b9..a8151d2 100644
--- a/services/tuner/hidl/TunerHidlDemux.cpp
+++ b/services/tuner/hidl/TunerHidlDemux.cpp
@@ -121,8 +121,8 @@
}
HidlResult status;
sp<HidlIFilter> filterSp;
- sp<::android::hardware::tv::tuner::V1_0::IFilterCallback> cbSp =
- new TunerHidlFilter::FilterCallback(in_cb);
+ sp<TunerHidlFilter::FilterCallback> filterCb = new TunerHidlFilter::FilterCallback(in_cb);
+ sp<::android::hardware::tv::tuner::V1_0::IFilterCallback> cbSp = filterCb;
mDemux->openFilter(filterType, static_cast<uint32_t>(in_bufferSize), cbSp,
[&](HidlResult r, const sp<HidlIFilter>& filter) {
filterSp = filter;
@@ -132,7 +132,7 @@
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(status));
}
- *_aidl_return = ::ndk::SharedRefBase::make<TunerHidlFilter>(filterSp, in_type);
+ *_aidl_return = ::ndk::SharedRefBase::make<TunerHidlFilter>(filterSp, filterCb, in_type);
return ::ndk::ScopedAStatus::ok();
}
diff --git a/services/tuner/hidl/TunerHidlFilter.cpp b/services/tuner/hidl/TunerHidlFilter.cpp
index de82855..a3393bb 100644
--- a/services/tuner/hidl/TunerHidlFilter.cpp
+++ b/services/tuner/hidl/TunerHidlFilter.cpp
@@ -21,8 +21,12 @@
#include <aidl/android/hardware/tv/tuner/Constant.h>
#include <aidl/android/hardware/tv/tuner/Result.h>
#include <aidlcommonsupport/NativeHandle.h>
+#include <binder/IPCThreadState.h>
#include <fmq/ConvertMQDescriptors.h>
+#include "TunerHelper.h"
+#include "TunerHidlService.h"
+
using ::aidl::android::hardware::tv::tuner::AudioExtraMetaData;
using ::aidl::android::hardware::tv::tuner::Constant;
using ::aidl::android::hardware::tv::tuner::DemuxAlpFilterSettings;
@@ -59,6 +63,7 @@
using ::aidl::android::hardware::tv::tuner::Result;
using ::aidl::android::hardware::tv::tuner::ScramblingStatus;
using ::android::dupToAidl;
+using ::android::IPCThreadState;
using ::android::makeFromAidl;
using ::android::unsafeHidlToAidlMQDescriptor;
using ::android::hardware::hidl_handle;
@@ -84,23 +89,36 @@
namespace tv {
namespace tuner {
-TunerHidlFilter::TunerHidlFilter(sp<HidlIFilter> filter, DemuxFilterType type)
- : mFilter(filter), mType(type) {
+TunerHidlFilter::TunerHidlFilter(sp<HidlIFilter> filter, sp<FilterCallback> cb,
+ DemuxFilterType type)
+ : mFilter(filter), mType(type), mStarted(false), mShared(false), mFilterCallback(cb) {
mFilter_1_1 = ::android::hardware::tv::tuner::V1_1::IFilter::castFrom(filter);
}
TunerHidlFilter::~TunerHidlFilter() {
+ Mutex::Autolock _l(mLock);
mFilter = nullptr;
mFilter_1_1 = nullptr;
}
::ndk::ScopedAStatus TunerHidlFilter::getQueueDesc(AidlMQDesc* _aidl_return) {
+ Mutex::Autolock _l(mLock);
if (mFilter == nullptr) {
ALOGE("IFilter is not initialized");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::UNAVAILABLE));
}
+ if (mShared) {
+ IPCThreadState* ipc = IPCThreadState::self();
+ int32_t callingPid = ipc->getCallingPid();
+ if (callingPid == mClientPid) {
+ ALOGD("%s is called in wrong process", __FUNCTION__);
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::INVALID_STATE));
+ }
+ }
+
MQDesc filterMQDesc;
HidlResult res;
mFilter->getQueueDesc([&](HidlResult r, const MQDesc& desc) {
@@ -119,12 +137,19 @@
}
::ndk::ScopedAStatus TunerHidlFilter::getId(int32_t* _aidl_return) {
+ Mutex::Autolock _l(mLock);
if (mFilter == nullptr) {
ALOGE("IFilter is not initialized");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::UNAVAILABLE));
}
+ if (mShared) {
+ ALOGD("%s is called on a shared filter", __FUNCTION__);
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::INVALID_STATE));
+ }
+
HidlResult res;
mFilter->getId([&](HidlResult r, uint32_t filterId) {
res = r;
@@ -139,12 +164,19 @@
}
::ndk::ScopedAStatus TunerHidlFilter::getId64Bit(int64_t* _aidl_return) {
+ Mutex::Autolock _l(mLock);
if (mFilter_1_1 == nullptr) {
ALOGE("IFilter_1_1 is not initialized");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::UNAVAILABLE));
}
+ if (mShared) {
+ ALOGD("%s is called on a shared filter", __FUNCTION__);
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::INVALID_STATE));
+ }
+
HidlResult res;
mFilter_1_1->getId64Bit([&](HidlResult r, uint64_t filterId) {
res = r;
@@ -159,12 +191,19 @@
}
::ndk::ScopedAStatus TunerHidlFilter::configure(const DemuxFilterSettings& in_settings) {
+ Mutex::Autolock _l(mLock);
if (mFilter == nullptr) {
ALOGE("IFilter is not initialized");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::UNAVAILABLE));
}
+ if (mShared) {
+ ALOGD("%s is called on a shared filter", __FUNCTION__);
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::INVALID_STATE));
+ }
+
HidlDemuxFilterSettings settings;
switch (in_settings.getTag()) {
case DemuxFilterSettings::ts: {
@@ -198,12 +237,19 @@
}
::ndk::ScopedAStatus TunerHidlFilter::configureMonitorEvent(int32_t monitorEventType) {
+ Mutex::Autolock _l(mLock);
if (mFilter_1_1 == nullptr) {
ALOGE("IFilter_1_1 is not initialized");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::UNAVAILABLE));
}
+ if (mShared) {
+ ALOGD("%s is called on a shared filter", __FUNCTION__);
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::INVALID_STATE));
+ }
+
HidlResult res = mFilter_1_1->configureMonitorEvent(monitorEventType);
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
@@ -213,12 +259,19 @@
}
::ndk::ScopedAStatus TunerHidlFilter::configureIpFilterContextId(int32_t cid) {
+ Mutex::Autolock _l(mLock);
if (mFilter_1_1 == nullptr) {
ALOGE("IFilter_1_1 is not initialized");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::UNAVAILABLE));
}
+ if (mShared) {
+ ALOGD("%s is called on a shared filter", __FUNCTION__);
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::INVALID_STATE));
+ }
+
HidlResult res = mFilter_1_1->configureIpCid(cid);
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
@@ -228,12 +281,19 @@
}
::ndk::ScopedAStatus TunerHidlFilter::configureAvStreamType(const AvStreamType& in_avStreamType) {
+ Mutex::Autolock _l(mLock);
if (mFilter_1_1 == nullptr) {
ALOGE("IFilter_1_1 is not initialized");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::UNAVAILABLE));
}
+ if (mShared) {
+ ALOGD("%s is called on a shared filter", __FUNCTION__);
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::INVALID_STATE));
+ }
+
HidlAvStreamType type;
if (!getHidlAvStreamType(in_avStreamType, type)) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(
@@ -249,6 +309,7 @@
}
::ndk::ScopedAStatus TunerHidlFilter::setDataSource(const shared_ptr<ITunerFilter>& filter) {
+ Mutex::Autolock _l(mLock);
if (mFilter == nullptr) {
ALOGE("IFilter is not initialized");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
@@ -260,6 +321,12 @@
static_cast<int32_t>(Result::INVALID_ARGUMENT));
}
+ if (mShared) {
+ ALOGD("%s is called on a shared filter", __FUNCTION__);
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::INVALID_STATE));
+ }
+
sp<HidlIFilter> hidlFilter = static_cast<TunerHidlFilter*>(filter.get())->getHalFilter();
HidlResult res = mFilter->setDataSource(hidlFilter);
if (res != HidlResult::SUCCESS) {
@@ -271,12 +338,19 @@
::ndk::ScopedAStatus TunerHidlFilter::getAvSharedHandle(NativeHandle* out_avMemory,
int64_t* _aidl_return) {
+ Mutex::Autolock _l(mLock);
if (mFilter_1_1 == nullptr) {
ALOGE("IFilter_1_1 is not initialized");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::UNAVAILABLE));
}
+ if (mShared) {
+ ALOGD("%s is called on a shared filter", __FUNCTION__);
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::INVALID_STATE));
+ }
+
HidlResult res;
mFilter_1_1->getAvSharedHandle([&](HidlResult r, hidl_handle avMemory, uint64_t avMemSize) {
res = r;
@@ -295,12 +369,19 @@
::ndk::ScopedAStatus TunerHidlFilter::releaseAvHandle(const NativeHandle& in_handle,
int64_t in_avDataId) {
+ Mutex::Autolock _l(mLock);
if (mFilter == nullptr) {
ALOGE("IFilter is not initialized");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::UNAVAILABLE));
}
+ if (mShared) {
+ ALOGD("%s is called on a shared filter", __FUNCTION__);
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::INVALID_STATE));
+ }
+
HidlResult res = mFilter->releaseAvHandle(hidl_handle(makeFromAidl(in_handle)), in_avDataId);
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
@@ -315,42 +396,77 @@
}
::ndk::ScopedAStatus TunerHidlFilter::start() {
+ Mutex::Autolock _l(mLock);
if (mFilter == nullptr) {
ALOGE("IFilter is not initialized");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::UNAVAILABLE));
}
+ if (mShared) {
+ IPCThreadState* ipc = IPCThreadState::self();
+ int32_t callingPid = ipc->getCallingPid();
+ if (callingPid == mClientPid) {
+ ALOGD("%s is called in wrong process", __FUNCTION__);
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::INVALID_STATE));
+ }
+ }
+
HidlResult res = mFilter->start();
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
}
+ mStarted = true;
return ::ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus TunerHidlFilter::stop() {
+ Mutex::Autolock _l(mLock);
if (mFilter == nullptr) {
ALOGE("IFilter is not initialized");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::UNAVAILABLE));
}
+ if (mShared) {
+ IPCThreadState* ipc = IPCThreadState::self();
+ int32_t callingPid = ipc->getCallingPid();
+ if (callingPid == mClientPid) {
+ ALOGD("%s is called in wrong process", __FUNCTION__);
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::INVALID_STATE));
+ }
+ }
+
HidlResult res = mFilter->stop();
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
}
+ mStarted = false;
return ::ndk::ScopedAStatus::ok();
}
::ndk::ScopedAStatus TunerHidlFilter::flush() {
+ Mutex::Autolock _l(mLock);
if (mFilter == nullptr) {
ALOGE("IFilter is not initialized");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::UNAVAILABLE));
}
+ if (mShared) {
+ IPCThreadState* ipc = IPCThreadState::self();
+ int32_t callingPid = ipc->getCallingPid();
+ if (callingPid == mClientPid) {
+ ALOGD("%s is called in wrong process", __FUNCTION__);
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::INVALID_STATE));
+ }
+ }
+
HidlResult res = mFilter->flush();
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
@@ -360,15 +476,37 @@
}
::ndk::ScopedAStatus TunerHidlFilter::close() {
+ Mutex::Autolock _l(mLock);
if (mFilter == nullptr) {
ALOGE("IFilter is not initialized");
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::UNAVAILABLE));
}
+ if (mShared) {
+ IPCThreadState* ipc = IPCThreadState::self();
+ int32_t callingPid = ipc->getCallingPid();
+ if (callingPid == mClientPid) {
+ if (mFilterCallback != nullptr) {
+ mFilterCallback->sendSharedFilterStatus(STATUS_INACCESSIBLE);
+ mFilterCallback->detachSharedFilterCallback();
+ }
+ TunerHidlService::getTunerService()->removeSharedFilter(this->ref<TunerHidlFilter>());
+ } else {
+ // Calling from shared process, do not really close this filter.
+ if (mFilterCallback != nullptr) {
+ mFilterCallback->detachSharedFilterCallback();
+ }
+ mStarted = false;
+ return ::ndk::ScopedAStatus::ok();
+ }
+ }
+
HidlResult res = mFilter->close();
mFilter = nullptr;
mFilter_1_1 = nullptr;
+ mStarted = false;
+ mShared = false;
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
@@ -377,6 +515,75 @@
return ::ndk::ScopedAStatus::ok();
}
+::ndk::ScopedAStatus TunerHidlFilter::createSharedFilter(string* _aidl_return) {
+ Mutex::Autolock _l(mLock);
+ if (mFilter == nullptr) {
+ ALOGE("IFilter is not initialized");
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ if (mShared || mStarted) {
+ ALOGD("create SharedFilter in wrong state");
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::INVALID_STATE));
+ }
+
+ IPCThreadState* ipc = IPCThreadState::self();
+ mClientPid = ipc->getCallingPid();
+ string token =
+ TunerHidlService::getTunerService()->addFilterToShared(this->ref<TunerHidlFilter>());
+ _aidl_return->assign(token);
+ mShared = true;
+
+ return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus TunerHidlFilter::releaseSharedFilter(const string& /* in_filterToken */) {
+ Mutex::Autolock _l(mLock);
+ if (mFilter == nullptr) {
+ ALOGE("IFilter is not initialized");
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ if (!mShared) {
+ // The filter is not shared or the shared filter has been closed.
+ return ::ndk::ScopedAStatus::ok();
+ }
+
+ if (mFilterCallback != nullptr) {
+ mFilterCallback->sendSharedFilterStatus(STATUS_INACCESSIBLE);
+ mFilterCallback->detachSharedFilterCallback();
+ }
+
+ TunerHidlService::getTunerService()->removeSharedFilter(this->ref<TunerHidlFilter>());
+ mShared = false;
+
+ return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus TunerHidlFilter::getFilterType(DemuxFilterType* _aidl_return) {
+ if (mFilter == nullptr) {
+ ALOGE("IFilter is not initialized");
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ *_aidl_return = mType;
+ return ::ndk::ScopedAStatus::ok();
+}
+
+bool TunerHidlFilter::isSharedFilterAllowed(int callingPid) {
+ return mClientPid != callingPid;
+}
+
+void TunerHidlFilter::attachSharedFilterCallback(const shared_ptr<ITunerFilterCallback>& in_cb) {
+ if (mFilterCallback != nullptr) {
+ mFilterCallback->attachSharedFilterCallback(in_cb);
+ }
+}
+
sp<HidlIFilter> TunerHidlFilter::getHalFilter() {
return mFilter;
}
@@ -681,7 +888,8 @@
/////////////// FilterCallback ///////////////////////
Return<void> TunerHidlFilter::FilterCallback::onFilterStatus(HidlDemuxFilterStatus status) {
- if (mTunerFilterCallback != NULL) {
+ Mutex::Autolock _l(mCallbackLock);
+ if (mTunerFilterCallback != nullptr) {
mTunerFilterCallback->onFilterStatus(static_cast<DemuxFilterStatus>(status));
}
return Void();
@@ -699,7 +907,8 @@
Return<void> TunerHidlFilter::FilterCallback::onFilterEvent_1_1(
const HidlDemuxFilterEvent& filterEvent, const HidlDemuxFilterEventExt& filterEventExt) {
- if (mTunerFilterCallback != NULL) {
+ Mutex::Autolock _l(mCallbackLock);
+ if (mTunerFilterCallback != nullptr) {
vector<HidlDemuxFilterEvent::Event> events = filterEvent.events;
vector<HidlDemuxFilterEventExt::Event> eventsExt = filterEventExt.events;
vector<DemuxFilterEvent> tunerEvents;
@@ -710,6 +919,26 @@
return Void();
}
+void TunerHidlFilter::FilterCallback::sendSharedFilterStatus(int32_t status) {
+ Mutex::Autolock _l(mCallbackLock);
+ if (mTunerFilterCallback != nullptr && mOriginalCallback != nullptr) {
+ mTunerFilterCallback->onFilterStatus(static_cast<DemuxFilterStatus>(status));
+ }
+}
+
+void TunerHidlFilter::FilterCallback::attachSharedFilterCallback(
+ const shared_ptr<ITunerFilterCallback>& in_cb) {
+ Mutex::Autolock _l(mCallbackLock);
+ mOriginalCallback = mTunerFilterCallback;
+ mTunerFilterCallback = in_cb;
+}
+
+void TunerHidlFilter::FilterCallback::detachSharedFilterCallback() {
+ Mutex::Autolock _l(mCallbackLock);
+ mTunerFilterCallback = mOriginalCallback;
+ mOriginalCallback = nullptr;
+}
+
/////////////// FilterCallback Helper Methods ///////////////////////
void TunerHidlFilter::FilterCallback::getAidlFilterEvent(
const vector<HidlDemuxFilterEvent::Event>& events,
diff --git a/services/tuner/hidl/TunerHidlFilter.h b/services/tuner/hidl/TunerHidlFilter.h
index 0111e00..548b753 100644
--- a/services/tuner/hidl/TunerHidlFilter.h
+++ b/services/tuner/hidl/TunerHidlFilter.h
@@ -34,7 +34,9 @@
#include <android/hardware/tv/tuner/1.1/IFilterCallback.h>
#include <android/hardware/tv/tuner/1.1/types.h>
#include <fmq/MessageQueue.h>
-#include <media/stagefright/foundation/ADebug.h>
+#include <utils/Mutex.h>
+
+#include <map>
using ::aidl::android::hardware::common::NativeHandle;
using ::aidl::android::hardware::common::fmq::MQDescriptor;
@@ -52,12 +54,14 @@
using ::aidl::android::hardware::tv::tuner::DemuxIpAddressIpAddress;
using ::aidl::android::media::tv::tuner::BnTunerFilter;
using ::aidl::android::media::tv::tuner::ITunerFilterCallback;
+using ::android::Mutex;
using ::android::sp;
using ::android::hardware::hidl_array;
using ::android::hardware::MQDescriptorSync;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::std::shared_ptr;
+using ::std::string;
using ::std::vector;
using HidlAvStreamType = ::android::hardware::tv::tuner::V1_1::AvStreamType;
@@ -111,29 +115,8 @@
class TunerHidlFilter : public BnTunerFilter {
public:
- TunerHidlFilter(sp<HidlIFilter> filter, DemuxFilterType type);
- virtual ~TunerHidlFilter();
-
- ::ndk::ScopedAStatus getId(int32_t* _aidl_return) override;
- ::ndk::ScopedAStatus getId64Bit(int64_t* _aidl_return) override;
- ::ndk::ScopedAStatus getQueueDesc(AidlMQDesc* _aidl_return) override;
- ::ndk::ScopedAStatus configure(const DemuxFilterSettings& in_settings) override;
- ::ndk::ScopedAStatus configureMonitorEvent(int32_t in_monitorEventTypes) override;
- ::ndk::ScopedAStatus configureIpFilterContextId(int32_t in_cid) override;
- ::ndk::ScopedAStatus configureAvStreamType(const AvStreamType& in_avStreamType) override;
- ::ndk::ScopedAStatus getAvSharedHandle(NativeHandle* out_avMemory,
- int64_t* _aidl_return) override;
- ::ndk::ScopedAStatus releaseAvHandle(const NativeHandle& in_handle,
- int64_t in_avDataId) override;
- ::ndk::ScopedAStatus setDataSource(const shared_ptr<ITunerFilter>& in_filter) override;
- ::ndk::ScopedAStatus start() override;
- ::ndk::ScopedAStatus stop() override;
- ::ndk::ScopedAStatus flush() override;
- ::ndk::ScopedAStatus close() override;
-
- sp<HidlIFilter> getHalFilter();
-
- struct FilterCallback : public HidlIFilterCallback {
+ class FilterCallback : public HidlIFilterCallback {
+ public:
FilterCallback(const shared_ptr<ITunerFilterCallback> tunerFilterCallback)
: mTunerFilterCallback(tunerFilterCallback){};
@@ -142,6 +125,11 @@
const HidlDemuxFilterEventExt& filterEventExt);
virtual Return<void> onFilterStatus(HidlDemuxFilterStatus status);
+ void sendSharedFilterStatus(int32_t status);
+ void attachSharedFilterCallback(const shared_ptr<ITunerFilterCallback>& in_cb);
+ void detachSharedFilterCallback();
+
+ private:
void getAidlFilterEvent(const vector<HidlDemuxFilterEvent::Event>& events,
const vector<HidlDemuxFilterEventExt::Event>& eventsExt,
vector<DemuxFilterEvent>& aidlEvents);
@@ -169,9 +157,39 @@
void getRestartEvent(const vector<HidlDemuxFilterEventExt::Event>& eventsExt,
vector<DemuxFilterEvent>& res);
+ private:
shared_ptr<ITunerFilterCallback> mTunerFilterCallback;
+ shared_ptr<ITunerFilterCallback> mOriginalCallback;
+ Mutex mCallbackLock;
};
+ TunerHidlFilter(sp<HidlIFilter> filter, sp<FilterCallback> cb, DemuxFilterType type);
+ virtual ~TunerHidlFilter();
+
+ ::ndk::ScopedAStatus getId(int32_t* _aidl_return) override;
+ ::ndk::ScopedAStatus getId64Bit(int64_t* _aidl_return) override;
+ ::ndk::ScopedAStatus getQueueDesc(AidlMQDesc* _aidl_return) override;
+ ::ndk::ScopedAStatus configure(const DemuxFilterSettings& in_settings) override;
+ ::ndk::ScopedAStatus configureMonitorEvent(int32_t in_monitorEventTypes) override;
+ ::ndk::ScopedAStatus configureIpFilterContextId(int32_t in_cid) override;
+ ::ndk::ScopedAStatus configureAvStreamType(const AvStreamType& in_avStreamType) override;
+ ::ndk::ScopedAStatus getAvSharedHandle(NativeHandle* out_avMemory,
+ int64_t* _aidl_return) override;
+ ::ndk::ScopedAStatus releaseAvHandle(const NativeHandle& in_handle,
+ int64_t in_avDataId) override;
+ ::ndk::ScopedAStatus setDataSource(const shared_ptr<ITunerFilter>& in_filter) override;
+ ::ndk::ScopedAStatus start() override;
+ ::ndk::ScopedAStatus stop() override;
+ ::ndk::ScopedAStatus flush() override;
+ ::ndk::ScopedAStatus close() override;
+ ::ndk::ScopedAStatus createSharedFilter(string* _aidl_return) override;
+ ::ndk::ScopedAStatus releaseSharedFilter(const string& in_filterToken) override;
+ ::ndk::ScopedAStatus getFilterType(DemuxFilterType* _aidl_return) override;
+
+ bool isSharedFilterAllowed(int32_t pid);
+ void attachSharedFilterCallback(const shared_ptr<ITunerFilterCallback>& in_cb);
+ sp<HidlIFilter> getHalFilter();
+
private:
bool isAudioFilter();
bool isVideoFilter();
@@ -204,6 +222,11 @@
int32_t mId;
int64_t mId64Bit;
DemuxFilterType mType;
+ bool mStarted;
+ bool mShared;
+ int32_t mClientPid;
+ sp<FilterCallback> mFilterCallback;
+ Mutex mLock;
};
} // namespace tuner
diff --git a/services/tuner/hidl/TunerHidlFrontend.h b/services/tuner/hidl/TunerHidlFrontend.h
index 0abd80b..6a3a04a 100644
--- a/services/tuner/hidl/TunerHidlFrontend.h
+++ b/services/tuner/hidl/TunerHidlFrontend.h
@@ -22,7 +22,6 @@
#include <android/hardware/tv/tuner/1.0/ITuner.h>
#include <android/hardware/tv/tuner/1.1/IFrontend.h>
#include <android/hardware/tv/tuner/1.1/IFrontendCallback.h>
-#include <media/stagefright/foundation/ADebug.h>
#include <utils/Log.h>
using ::aidl::android::hardware::tv::tuner::FrontendAtsc3Settings;
diff --git a/services/tuner/hidl/TunerHidlLnb.h b/services/tuner/hidl/TunerHidlLnb.h
index c496f48..becf848 100644
--- a/services/tuner/hidl/TunerHidlLnb.h
+++ b/services/tuner/hidl/TunerHidlLnb.h
@@ -21,7 +21,6 @@
#include <aidl/android/media/tv/tuner/BnTunerLnb.h>
#include <android/hardware/tv/tuner/1.0/ILnb.h>
#include <android/hardware/tv/tuner/1.0/ILnbCallback.h>
-#include <media/stagefright/foundation/ADebug.h>
#include <utils/Log.h>
using ::aidl::android::hardware::tv::tuner::LnbEventType;
diff --git a/services/tuner/hidl/TunerHidlService.cpp b/services/tuner/hidl/TunerHidlService.cpp
index 9d9bc7e..8d4053a 100644
--- a/services/tuner/hidl/TunerHidlService.cpp
+++ b/services/tuner/hidl/TunerHidlService.cpp
@@ -21,6 +21,8 @@
#include <aidl/android/hardware/tv/tuner/Result.h>
#include <android/binder_manager.h>
+#include <binder/IPCThreadState.h>
+#include <binder/PermissionCache.h>
#include <utils/Log.h>
#include "TunerHelper.h"
@@ -43,6 +45,8 @@
using ::aidl::android::hardware::tv::tuner::FrontendType;
using ::aidl::android::hardware::tv::tuner::Result;
using ::aidl::android::media::tv::tunerresourcemanager::TunerFrontendInfo;
+using ::android::IPCThreadState;
+using ::android::PermissionCache;
using ::android::hardware::hidl_vec;
using HidlFrontendId = ::android::hardware::tv::tuner::V1_0::FrontendId;
@@ -57,6 +61,8 @@
namespace tv {
namespace tuner {
+shared_ptr<TunerHidlService> TunerHidlService::sTunerService = nullptr;
+
TunerHidlService::TunerHidlService() {
if (!TunerHelper::checkTunerFeature()) {
ALOGD("Device doesn't have tuner hardware.");
@@ -74,8 +80,12 @@
return STATUS_NAME_NOT_FOUND;
}
- shared_ptr<TunerHidlService> service = ::ndk::SharedRefBase::make<TunerHidlService>();
- return AServiceManager_addService(service->asBinder().get(), getServiceName());
+ sTunerService = ::ndk::SharedRefBase::make<TunerHidlService>();
+ return AServiceManager_addService(sTunerService->asBinder().get(), getServiceName());
+}
+
+shared_ptr<TunerHidlService> TunerHidlService::getTunerService() {
+ return sTunerService;
}
bool TunerHidlService::hasITuner() {
@@ -304,6 +314,62 @@
return ::ndk::ScopedAStatus::ok();
}
+::ndk::ScopedAStatus TunerHidlService::openSharedFilter(
+ const string& in_filterToken, const shared_ptr<ITunerFilterCallback>& in_cb,
+ shared_ptr<ITunerFilter>* _aidl_return) {
+ if (!hasITuner()) {
+ ALOGE("get ITuner failed");
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ if (!PermissionCache::checkCallingPermission(sSharedFilterPermission)) {
+ ALOGE("Request requires android.permission.ACCESS_TV_SHARED_FILTER");
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ Mutex::Autolock _l(mSharedFiltersLock);
+ if (mSharedFilters.find(in_filterToken) == mSharedFilters.end()) {
+ *_aidl_return = nullptr;
+ ALOGD("fail to find %s", in_filterToken.c_str());
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::INVALID_STATE));
+ }
+
+ shared_ptr<TunerHidlFilter> filter = mSharedFilters.at(in_filterToken);
+ IPCThreadState* ipc = IPCThreadState::self();
+ const int pid = ipc->getCallingPid();
+ if (!filter->isSharedFilterAllowed(pid)) {
+ *_aidl_return = nullptr;
+ ALOGD("shared filter %s is opened in the same process", in_filterToken.c_str());
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::INVALID_STATE));
+ }
+
+ filter->attachSharedFilterCallback(in_cb);
+
+ *_aidl_return = filter;
+ return ::ndk::ScopedAStatus::ok();
+}
+
+string TunerHidlService::addFilterToShared(const shared_ptr<TunerHidlFilter>& sharedFilter) {
+ Mutex::Autolock _l(mSharedFiltersLock);
+
+ // Use sharedFilter address as token.
+ string token = to_string(reinterpret_cast<std::uintptr_t>(sharedFilter.get()));
+ mSharedFilters[token] = sharedFilter;
+
+ return token;
+}
+
+void TunerHidlService::removeSharedFilter(const shared_ptr<TunerHidlFilter>& sharedFilter) {
+ Mutex::Autolock _l(mSharedFiltersLock);
+
+ // Use sharedFilter address as token.
+ mSharedFilters.erase(to_string(reinterpret_cast<std::uintptr_t>(sharedFilter.get())));
+}
+
void TunerHidlService::updateTunerResources() {
if (!hasITuner()) {
ALOGE("Failed to updateTunerResources");
diff --git a/services/tuner/hidl/TunerHidlService.h b/services/tuner/hidl/TunerHidlService.h
index 9f5f371..2b8750e 100644
--- a/services/tuner/hidl/TunerHidlService.h
+++ b/services/tuner/hidl/TunerHidlService.h
@@ -22,8 +22,10 @@
#include <aidl/android/media/tv/tuner/BnTunerService.h>
#include <aidl/android/media/tv/tunerresourcemanager/TunerFrontendInfo.h>
#include <android/hardware/tv/tuner/1.1/ITuner.h>
+#include <utils/Mutex.h>
#include "TunerHelper.h"
+#include "TunerHidlFilter.h"
using ::aidl::android::hardware::tv::tuner::DemuxCapabilities;
using ::aidl::android::hardware::tv::tuner::DemuxFilterEvent;
@@ -34,11 +36,13 @@
using ::aidl::android::media::tv::tuner::ITunerFrontend;
using ::aidl::android::media::tv::tuner::ITunerLnb;
using ::aidl::android::media::tv::tunerresourcemanager::TunerFrontendInfo;
+using ::android::Mutex;
using ::android::sp;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::std::shared_ptr;
+using ::std::string;
using ::std::vector;
using HidlFrontendDtmbCapabilities = ::android::hardware::tv::tuner::V1_1::FrontendDtmbCapabilities;
@@ -78,6 +82,14 @@
::ndk::ScopedAStatus openDescrambler(int32_t in_descramblerHandle,
shared_ptr<ITunerDescrambler>* _aidl_return) override;
::ndk::ScopedAStatus getTunerHalVersion(int32_t* _aidl_return) override;
+ ::ndk::ScopedAStatus openSharedFilter(const string& in_filterToken,
+ const shared_ptr<ITunerFilterCallback>& in_cb,
+ shared_ptr<ITunerFilter>* _aidl_return) override;
+
+ string addFilterToShared(const shared_ptr<TunerHidlFilter>& sharedFilter);
+ void removeSharedFilter(const shared_ptr<TunerHidlFilter>& sharedFilter);
+
+ static shared_ptr<TunerHidlService> getTunerService();
private:
bool hasITuner();
@@ -94,6 +106,10 @@
sp<HidlITuner> mTuner;
sp<::android::hardware::tv::tuner::V1_1::ITuner> mTuner_1_1;
int mTunerVersion = TUNER_HAL_VERSION_UNKNOWN;
+ Mutex mSharedFiltersLock;
+ map<string, shared_ptr<TunerHidlFilter>> mSharedFilters;
+
+ static shared_ptr<TunerHidlService> sTunerService;
};
} // namespace tuner
diff --git a/services/tuner/hidl/TunerHidlTimeFilter.h b/services/tuner/hidl/TunerHidlTimeFilter.h
index 97d59dc..78f9c5e 100644
--- a/services/tuner/hidl/TunerHidlTimeFilter.h
+++ b/services/tuner/hidl/TunerHidlTimeFilter.h
@@ -19,7 +19,6 @@
#include <aidl/android/media/tv/tuner/BnTunerTimeFilter.h>
#include <android/hardware/tv/tuner/1.0/ITimeFilter.h>
-#include <media/stagefright/foundation/ADebug.h>
#include <utils/Log.h>
using ::android::sp;