Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 34a479eb authored by Hongguang's avatar Hongguang Committed by Hongguang Chen
Browse files

Add SharedFilter to tuner service.

Bug: 196124225
Test: atest android.media.tv.tuner.cts on both AIDL and HIDL HAL.
Change-Id: I91b1f9ef09b0bda868b7817be4d946d11629b16c
parent 2245fb2c
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -84,10 +84,12 @@ TunerDemux::~TunerDemux() {
    }

    shared_ptr<IFilter> filter;
    shared_ptr<IFilterCallback> cb = ::ndk::SharedRefBase::make<TunerFilter::FilterCallback>(in_cb);
    shared_ptr<TunerFilter::FilterCallback> filterCb =
            ::ndk::SharedRefBase::make<TunerFilter::FilterCallback>(in_cb);
    shared_ptr<IFilterCallback> cb = filterCb;
    auto status = mDemux->openFilter(in_type, in_bufferSize, cb, &filter);
    if (status.isOk()) {
        *_aidl_return = ::ndk::SharedRefBase::make<TunerFilter>(filter, in_type);
        *_aidl_return = ::ndk::SharedRefBase::make<TunerFilter>(filter, filterCb, in_type);
    }

    return status;
+1 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@

#include <aidl/android/hardware/tv/tuner/IFilter.h>
#include <aidl/android/hardware/tv/tuner/Result.h>
#include <utils/Log.h>

#include "TunerDemux.h"
#include "TunerFilter.h"
+1 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include "TunerDvr.h"

#include <aidl/android/hardware/tv/tuner/Result.h>
#include <utils/Log.h>

#include "TunerFilter.h"

+237 −3
Original line number Diff line number Diff line
@@ -19,6 +19,10 @@
#include "TunerFilter.h"

#include <aidl/android/hardware/tv/tuner/Result.h>
#include <binder/IPCThreadState.h>

#include "TunerHelper.h"
#include "TunerService.h"

using ::aidl::android::hardware::tv::tuner::Result;

@@ -28,32 +32,54 @@ namespace media {
namespace tv {
namespace tuner {

using ::android::IPCThreadState;

using namespace std;

TunerFilter::TunerFilter(shared_ptr<IFilter> filter, DemuxFilterType type)
      : mFilter(filter), mType(type) {}
TunerFilter::TunerFilter(shared_ptr<IFilter> filter, shared_ptr<FilterCallback> cb,
                         DemuxFilterType type)
      : mFilter(filter), mType(type), mStarted(false), mShared(false), mFilterCallback(cb) {}

TunerFilter::~TunerFilter() {
    Mutex::Autolock _l(mLock);
    mFilter = nullptr;
}

::ndk::ScopedAStatus TunerFilter::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));
        }
    }

    return mFilter->getQueueDesc(_aidl_return);
}

::ndk::ScopedAStatus TunerFilter::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));
    }

    auto status = mFilter->getId(&mId);
    if (status.isOk()) {
        *_aidl_return = mId;
@@ -62,12 +88,19 @@ TunerFilter::~TunerFilter() {
}

::ndk::ScopedAStatus TunerFilter::getId64Bit(int64_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));
    }

    auto status = mFilter->getId64Bit(&mId64Bit);
    if (status.isOk()) {
        *_aidl_return = mId64Bit;
@@ -76,46 +109,75 @@ TunerFilter::~TunerFilter() {
}

::ndk::ScopedAStatus TunerFilter::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));
    }

    return mFilter->configure(in_settings);
}

::ndk::ScopedAStatus TunerFilter::configureMonitorEvent(int32_t monitorEventType) {
    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));
    }

    return mFilter->configureMonitorEvent(monitorEventType);
}

::ndk::ScopedAStatus TunerFilter::configureIpFilterContextId(int32_t cid) {
    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));
    }

    return mFilter->configureIpCid(cid);
}

::ndk::ScopedAStatus TunerFilter::configureAvStreamType(const AvStreamType& in_avStreamType) {
    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));
    }

    return mFilter->configureAvStreamType(in_avStreamType);
}

::ndk::ScopedAStatus TunerFilter::setDataSource(const shared_ptr<ITunerFilter>& filter) {
    Mutex::Autolock _l(mLock);
    if (mFilter == nullptr) {
        ALOGE("IFilter is not initialized");
        return ::ndk::ScopedAStatus::fromServiceSpecificError(
@@ -127,80 +189,231 @@ TunerFilter::~TunerFilter() {
                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));
    }

    shared_ptr<IFilter> halFilter = static_cast<TunerFilter*>(filter.get())->getHalFilter();
    return mFilter->setDataSource(halFilter);
}

::ndk::ScopedAStatus TunerFilter::getAvSharedHandle(NativeHandle* out_avMemory,
                                                    int64_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));
    }

    return mFilter->getAvSharedHandle(out_avMemory, _aidl_return);
}

::ndk::ScopedAStatus TunerFilter::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));
    }

    return mFilter->releaseAvHandle(in_handle, in_avDataId);
}

::ndk::ScopedAStatus TunerFilter::start() {
    Mutex::Autolock _l(mLock);
    if (mFilter == nullptr) {
        ALOGE("IFilter is not initialized");
        return ::ndk::ScopedAStatus::fromServiceSpecificError(
                static_cast<int32_t>(Result::UNAVAILABLE));
    }

    return mFilter->start();
    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));
        }
    }

    auto res = mFilter->start();
    if (res.isOk()) {
        mStarted = true;
    }
    return res;
}

::ndk::ScopedAStatus TunerFilter::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));
        }
    }

    mStarted = false;
    return mFilter->stop();
}

::ndk::ScopedAStatus TunerFilter::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));
        }
    }

    return mFilter->flush();
}

::ndk::ScopedAStatus TunerFilter::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();
            }
            TunerService::getTunerService()->removeSharedFilter(this->ref<TunerFilter>());
        } else {
            // Calling from shared process, do not really close this filter.
            if (mFilterCallback != nullptr) {
                mFilterCallback->detachSharedFilterCallback();
            }
            mStarted = false;
            return ::ndk::ScopedAStatus::ok();
        }
    }

    auto res = mFilter->close();
    mFilter = nullptr;
    mStarted = false;
    mShared = false;

    return res;
}

::ndk::ScopedAStatus TunerFilter::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 = TunerService::getTunerService()->addFilterToShared(this->ref<TunerFilter>());
    _aidl_return->assign(token);
    mShared = true;

    return ::ndk::ScopedAStatus::ok();
}

::ndk::ScopedAStatus TunerFilter::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();
    }

    TunerService::getTunerService()->removeSharedFilter(this->ref<TunerFilter>());
    mShared = false;

    return ::ndk::ScopedAStatus::ok();
}

::ndk::ScopedAStatus TunerFilter::getFilterType(DemuxFilterType* _aidl_return) {
    Mutex::Autolock _l(mLock);
    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 TunerFilter::isSharedFilterAllowed(int callingPid) {
    return mClientPid != callingPid;
}

void TunerFilter::attachSharedFilterCallback(const shared_ptr<ITunerFilterCallback>& in_cb) {
    if (mFilterCallback != nullptr) {
        mFilterCallback->attachSharedFilterCallback(in_cb);
    }
}

shared_ptr<IFilter> TunerFilter::getHalFilter() {
    return mFilter;
}

/////////////// FilterCallback ///////////////////////
::ndk::ScopedAStatus TunerFilter::FilterCallback::onFilterStatus(DemuxFilterStatus status) {
    Mutex::Autolock _l(mCallbackLock);
    if (mTunerFilterCallback != nullptr) {
        mTunerFilterCallback->onFilterStatus(status);
    }
@@ -209,12 +422,33 @@ shared_ptr<IFilter> TunerFilter::getHalFilter() {

::ndk::ScopedAStatus TunerFilter::FilterCallback::onFilterEvent(
        const vector<DemuxFilterEvent>& events) {
    Mutex::Autolock _l(mCallbackLock);
    if (mTunerFilterCallback != nullptr) {
        mTunerFilterCallback->onFilterEvent(events);
    }
    return ::ndk::ScopedAStatus::ok();
}

void TunerFilter::FilterCallback::sendSharedFilterStatus(int32_t status) {
    Mutex::Autolock _l(mCallbackLock);
    if (mTunerFilterCallback != nullptr && mOriginalCallback != nullptr) {
        mTunerFilterCallback->onFilterStatus(static_cast<DemuxFilterStatus>(status));
    }
}

void TunerFilter::FilterCallback::attachSharedFilterCallback(
        const shared_ptr<ITunerFilterCallback>& in_cb) {
    Mutex::Autolock _l(mCallbackLock);
    mOriginalCallback = mTunerFilterCallback;
    mTunerFilterCallback = in_cb;
}

void TunerFilter::FilterCallback::detachSharedFilterCallback() {
    Mutex::Autolock _l(mCallbackLock);
    mTunerFilterCallback = mOriginalCallback;
    mOriginalCallback = nullptr;
}

}  // namespace tuner
}  // namespace tv
}  // namespace media
+31 −14
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@
#include <aidl/android/hardware/tv/tuner/IFilter.h>
#include <aidl/android/media/tv/tuner/BnTunerFilter.h>
#include <aidl/android/media/tv/tuner/ITunerFilterCallback.h>
#include <media/stagefright/foundation/ADebug.h>
#include <utils/Mutex.h>

using ::aidl::android::hardware::common::NativeHandle;
using ::aidl::android::hardware::common::fmq::MQDescriptor;
@@ -39,6 +39,7 @@ using ::aidl::android::hardware::tv::tuner::DemuxFilterStatus;
using ::aidl::android::hardware::tv::tuner::DemuxFilterType;
using ::aidl::android::hardware::tv::tuner::IFilter;
using ::aidl::android::media::tv::tuner::BnTunerFilter;
using ::android::Mutex;

using namespace std;

@@ -53,7 +54,25 @@ using AidlMQDesc = MQDescriptor<int8_t, SynchronizedReadWrite>;
class TunerFilter : public BnTunerFilter {

public:
    TunerFilter(shared_ptr<IFilter> filter, DemuxFilterType type);
    class FilterCallback : public BnFilterCallback {
    public:
        FilterCallback(const shared_ptr<ITunerFilterCallback>& tunerFilterCallback)
              : mTunerFilterCallback(tunerFilterCallback), mOriginalCallback(nullptr){};

        ::ndk::ScopedAStatus onFilterEvent(const vector<DemuxFilterEvent>& events) override;
        ::ndk::ScopedAStatus onFilterStatus(DemuxFilterStatus status) override;

        void sendSharedFilterStatus(int32_t status);
        void attachSharedFilterCallback(const shared_ptr<ITunerFilterCallback>& in_cb);
        void detachSharedFilterCallback();

    private:
        shared_ptr<ITunerFilterCallback> mTunerFilterCallback;
        shared_ptr<ITunerFilterCallback> mOriginalCallback;
        Mutex mCallbackLock;
    };

    TunerFilter(shared_ptr<IFilter> filter, shared_ptr<FilterCallback> cb, DemuxFilterType type);
    virtual ~TunerFilter();

    ::ndk::ScopedAStatus getId(int32_t* _aidl_return) override;
@@ -72,26 +91,24 @@ public:
    ::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);
    shared_ptr<IFilter> getHalFilter();

    class FilterCallback : public BnFilterCallback {
    public:
        FilterCallback(const shared_ptr<ITunerFilterCallback> tunerFilterCallback)
              : mTunerFilterCallback(tunerFilterCallback){};

        ::ndk::ScopedAStatus onFilterEvent(const vector<DemuxFilterEvent>& events) override;
        ::ndk::ScopedAStatus onFilterStatus(DemuxFilterStatus status) override;

    private:
        shared_ptr<ITunerFilterCallback> mTunerFilterCallback;
    };

private:
    shared_ptr<IFilter> mFilter;
    int32_t mId;
    int64_t mId64Bit;
    DemuxFilterType mType;
    bool mStarted;
    bool mShared;
    int32_t mClientPid;
    shared_ptr<FilterCallback> mFilterCallback;
    Mutex mLock;
};

}  // namespace tuner
Loading