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

Commit dd393028 authored by Amy Zhang's avatar Amy Zhang Committed by Android (Google) Code Review
Browse files

Merge "Add ITunerDvr/ITunerDvrCallback aidl interface and implementation"

parents 5eb59bd7 ada92d7a
Loading
Loading
Loading
Loading
+25 −1
Original line number Diff line number Diff line
@@ -16,8 +16,8 @@

#define LOG_TAG "TunerDemux"

#include "TunerDvr.h"
#include "TunerDemux.h"
#include "TunerFilter.h"

using ::android::hardware::tv::tuner::V1_0::DemuxAlpFilterType;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
@@ -26,6 +26,7 @@ using ::android::hardware::tv::tuner::V1_0::DemuxIpFilterType;
using ::android::hardware::tv::tuner::V1_0::DemuxMmtpFilterType;
using ::android::hardware::tv::tuner::V1_0::DemuxTlvFilterType;
using ::android::hardware::tv::tuner::V1_0::DemuxTsFilterType;
using ::android::hardware::tv::tuner::V1_0::DvrType;
using ::android::hardware::tv::tuner::V1_0::Result;

namespace android {
@@ -100,4 +101,27 @@ Status TunerDemux::openFilter(
    return Status::ok();
}

Status TunerDemux::openDvr(int dvrType, int bufferSize, const shared_ptr<ITunerDvrCallback>& cb,
        shared_ptr<ITunerDvr>* _aidl_return) {
    if (mDemux == nullptr) {
        ALOGE("IDemux is not initialized.");
        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
    }

    Result res;
    sp<IDvrCallback> callback = new TunerDvr::DvrCallback(cb);
    sp<IDvr> hidlDvr;
    mDemux->openDvr(static_cast<DvrType>(dvrType), bufferSize, callback,
            [&](Result r, const sp<IDvr>& dvr) {
                hidlDvr = dvr;
                res = r;
            });
    if (res != Result::SUCCESS) {
        *_aidl_return = NULL;
        return Status::fromServiceSpecificError(static_cast<int32_t>(res));
    }

    *_aidl_return = ::ndk::SharedRefBase::make<TunerDvr>(hidlDvr, dvrType);
    return Status::ok();
}
}  // namespace android
+11 −3
Original line number Diff line number Diff line
@@ -22,11 +22,16 @@

using Status = ::ndk::ScopedAStatus;
using ::aidl::android::media::tv::tuner::BnTunerDemux;
using ::aidl::android::media::tv::tuner::ITunerDvr;
using ::aidl::android::media::tv::tuner::ITunerDvrCallback;
using ::aidl::android::media::tv::tuner::ITunerFilter;
using ::aidl::android::media::tv::tuner::ITunerFilterCallback;
using ::aidl::android::media::tv::tuner::ITunerFrontend;
using ::android::hardware::tv::tuner::V1_0::IDemux;
using ::android::hardware::tv::tuner::V1_0::IDvr;
using ::android::hardware::tv::tuner::V1_0::IDvrCallback;

using namespace std;

namespace android {

@@ -35,10 +40,13 @@ class TunerDemux : public BnTunerDemux {
public:
    TunerDemux(sp<IDemux> demux, int demuxId);
    virtual ~TunerDemux();
    Status setFrontendDataSource(const std::shared_ptr<ITunerFrontend>& frontend) override;
    Status setFrontendDataSource(const shared_ptr<ITunerFrontend>& frontend) override;
    Status openFilter(
        int mainType, int subtype, int bufferSize, const std::shared_ptr<ITunerFilterCallback>& cb,
        std::shared_ptr<ITunerFilter>* _aidl_return);
        int mainType, int subtype, int bufferSize, const shared_ptr<ITunerFilterCallback>& cb,
        shared_ptr<ITunerFilter>* _aidl_return);
    Status openDvr(
        int dvbType, int bufferSize, const shared_ptr<ITunerDvrCallback>& cb,
        shared_ptr<ITunerDvr>* _aidl_return) override;

private:
    sp<IDemux> mDemux;
+207 −0
Original line number Diff line number Diff line
/**
 * Copyright 2021, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "TunerDvr"

#include <fmq/ConvertMQDescriptors.h>
#include "TunerDvr.h"
#include "TunerFilter.h"

using ::android::hardware::tv::tuner::V1_0::DataFormat;
using ::android::hardware::tv::tuner::V1_0::Result;

namespace android {

TunerDvr::TunerDvr(sp<IDvr> dvr, int type) {
    mDvr = dvr;
    mType = static_cast<DvrType>(type);
}

TunerDvr::~TunerDvr() {
    mDvr = NULL;
}

Status TunerDvr::getQueueDesc(AidlMQDesc* _aidl_return) {
    if (mDvr == NULL) {
        ALOGE("IDvr is not initialized");
        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
    }

    MQDesc dvrMQDesc;
    Result res;
    mDvr->getQueueDesc([&](Result r, const MQDesc& desc) {
        dvrMQDesc = desc;
        res = r;
    });
    if (res != Result::SUCCESS) {
        return Status::fromServiceSpecificError(static_cast<int32_t>(res));
    }

    AidlMQDesc aidlMQDesc;
    unsafeHidlToAidlMQDescriptor<uint8_t, int8_t, SynchronizedReadWrite>(
                dvrMQDesc,  &aidlMQDesc);
    *_aidl_return = move(aidlMQDesc);
    return Status::ok();
}

Status TunerDvr::configure(const TunerDvrSettings& settings) {
    if (mDvr == NULL) {
        ALOGE("IDvr is not initialized");
        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
    }

    Result res = mDvr->configure(getHidlDvrSettingsFromAidl(settings));
    if (res != Result::SUCCESS) {
        return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
    }
    return Status::ok();
}

Status TunerDvr::attachFilter(const shared_ptr<ITunerFilter>& filter) {
    if (mDvr == NULL) {
        ALOGE("IDvr is not initialized");
        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
    }

    ITunerFilter* tunerFilter = filter.get();
    sp<IFilter> hidlFilter = static_cast<TunerFilter*>(tunerFilter)->getHalFilter();
    if (hidlFilter == NULL) {
        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::INVALID_ARGUMENT));
    }

    Result res = mDvr->attachFilter(hidlFilter);
    if (res != Result::SUCCESS) {
        return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
    }
    return Status::ok();
}

Status TunerDvr::detachFilter(const shared_ptr<ITunerFilter>& filter) {
    if (mDvr == NULL) {
        ALOGE("IDvr is not initialized");
        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
    }

    ITunerFilter* tunerFilter = filter.get();
    sp<IFilter> hidlFilter = static_cast<TunerFilter*>(tunerFilter)->getHalFilter();
    if (hidlFilter == NULL) {
        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::INVALID_ARGUMENT));
    }

    Result res = mDvr->detachFilter(hidlFilter);
    if (res != Result::SUCCESS) {
        return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
    }
    return Status::ok();
}

Status TunerDvr::start() {
    if (mDvr == NULL) {
        ALOGE("IDvr is not initialized");
        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
    }

    Result res = mDvr->start();
    if (res != Result::SUCCESS) {
        return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
    }
    return Status::ok();
}

Status TunerDvr::stop() {
    if (mDvr == NULL) {
        ALOGE("IDvr is not initialized");
        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
    }

    Result res = mDvr->stop();
    if (res != Result::SUCCESS) {
        return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
    }
    return Status::ok();
}

Status TunerDvr::flush() {
    if (mDvr == NULL) {
        ALOGE("IDvr is not initialized");
        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
    }

    Result res = mDvr->flush();
    if (res != Result::SUCCESS) {
        return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
    }
    return Status::ok();
}

Status TunerDvr::close() {
    if (mDvr == NULL) {
        ALOGE("IDvr is not initialized");
        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
    }

    Result res = mDvr->close();
    if (res != Result::SUCCESS) {
        return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
    }
    return Status::ok();
}

DvrSettings TunerDvr::getHidlDvrSettingsFromAidl(TunerDvrSettings settings) {
    DvrSettings s;
    switch (mType) {
        case DvrType::PLAYBACK: {
            s.playback({
                .statusMask = static_cast<uint8_t>(settings.statusMask),
                .lowThreshold = static_cast<uint32_t>(settings.lowThreshold),
                .highThreshold = static_cast<uint32_t>(settings.highThreshold),
                .dataFormat = static_cast<DataFormat>(settings.dataFormat),
                .packetSize = static_cast<uint8_t>(settings.packetSize),
            });
            return s;
        }
        case DvrType::RECORD: {
            s.record({
                .statusMask = static_cast<uint8_t>(settings.statusMask),
                .lowThreshold = static_cast<uint32_t>(settings.lowThreshold),
                .highThreshold = static_cast<uint32_t>(settings.highThreshold),
                .dataFormat = static_cast<DataFormat>(settings.dataFormat),
                .packetSize = static_cast<uint8_t>(settings.packetSize),
            });
            return s;
        }
        default:
            break;
    }
    return s;
}

/////////////// IDvrCallback ///////////////////////

Return<void> TunerDvr::DvrCallback::onRecordStatus(const RecordStatus status) {
    if (mTunerDvrCallback != NULL) {
        mTunerDvrCallback->onRecordStatus(static_cast<int>(status));
    }
    return Void();
}

Return<void> TunerDvr::DvrCallback::onPlaybackStatus(const PlaybackStatus status) {
    if (mTunerDvrCallback != NULL) {
        mTunerDvrCallback->onPlaybackStatus(static_cast<int>(status));
    }
    return Void();
}
}  // namespace android
+97 −0
Original line number Diff line number Diff line
/**
 * Copyright 2021, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_MEDIA_TUNERDVR_H
#define ANDROID_MEDIA_TUNERDVR_H

#include <aidl/android/media/tv/tuner/BnTunerDvr.h>
#include <aidl/android/media/tv/tuner/ITunerDvrCallback.h>
#include <android/hardware/tv/tuner/1.0/ITuner.h>
#include <fmq/MessageQueue.h>

#include <TunerFilter.h>

using Status = ::ndk::ScopedAStatus;
using ::aidl::android::hardware::common::fmq::GrantorDescriptor;
using ::aidl::android::hardware::common::fmq::MQDescriptor;
using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
using ::aidl::android::media::tv::tuner::BnTunerDvr;
using ::aidl::android::media::tv::tuner::ITunerDvrCallback;
using ::aidl::android::media::tv::tuner::ITunerFilter;
using ::aidl::android::media::tv::tuner::TunerDvrSettings;

using ::android::hardware::MQDescriptorSync;
using ::android::hardware::MessageQueue;
using ::android::hardware::Return;
using ::android::hardware::Void;

using ::android::hardware::tv::tuner::V1_0::DvrSettings;
using ::android::hardware::tv::tuner::V1_0::DvrType;
using ::android::hardware::tv::tuner::V1_0::IDvr;
using ::android::hardware::tv::tuner::V1_0::IDvrCallback;
using ::android::hardware::tv::tuner::V1_0::PlaybackStatus;
using ::android::hardware::tv::tuner::V1_0::RecordStatus;

using namespace std;

namespace android {

using MQDesc = MQDescriptorSync<uint8_t>;
using AidlMQDesc = MQDescriptor<int8_t, SynchronizedReadWrite>;

class TunerDvr : public BnTunerDvr {

public:
    TunerDvr(sp<IDvr> dvr, int type);
    ~TunerDvr();

    Status getQueueDesc(AidlMQDesc* _aidl_return) override;

    Status configure(const TunerDvrSettings& settings) override;

    Status attachFilter(const shared_ptr<ITunerFilter>& filter) override;

    Status detachFilter(const shared_ptr<ITunerFilter>& filter) override;

    Status start() override;

    Status stop() override;

    Status flush() override;

    Status close() override;

    struct DvrCallback : public IDvrCallback {
        DvrCallback(const shared_ptr<ITunerDvrCallback> tunerDvrCallback)
                : mTunerDvrCallback(tunerDvrCallback) {};

        virtual Return<void> onRecordStatus(const RecordStatus status);
        virtual Return<void> onPlaybackStatus(const PlaybackStatus status);

        private:
            shared_ptr<ITunerDvrCallback> mTunerDvrCallback;
    };

private:
    DvrSettings getHidlDvrSettingsFromAidl(TunerDvrSettings settings);

    sp<IDvr> mDvr;
    DvrType mType;
};

} // namespace android

#endif // ANDROID_MEDIA_TUNERDVR_H
+4 −0
Original line number Diff line number Diff line
@@ -149,6 +149,10 @@ Status TunerFilter::flush() {
    return Status::ok();
}

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

/////////////// FilterCallback ///////////////////////

void TunerFilter::FilterCallback::getMediaEvent(
Loading