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

Commit 44a3dab3 authored by Hongguang Chen's avatar Hongguang Chen Committed by Android (Google) Code Review
Browse files

Merge "Add SharedFilter to tuner service."

parents 8a4d9cf1 34a479eb
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