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

Commit 7f6d545c authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge "Tuner JNI: FilterCallback" into rvc-dev am: f4d115b1 am: ed9493af...

Merge "Tuner JNI: FilterCallback" into rvc-dev am: f4d115b1 am: ed9493af am: 4dd8b6d9 am: 656c860a

Change-Id: Ia3f9f89383a504ab57296b43e82d9f50c1069d6c
parents 6ca49135 656c860a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -225,6 +225,7 @@ public class Filter implements AutoCloseable {
        mCallback = cb;
        mExecutor = executor;
    }

    /** @hide */
    public FilterCallback getCallback() {
        return mCallback;
+277 −18
Original line number Diff line number Diff line
@@ -34,19 +34,28 @@
using ::android::hardware::Void;
using ::android::hardware::hidl_bitfield;
using ::android::hardware::hidl_vec;
using ::android::hardware::tv::tuner::V1_0::AudioExtraMetaData;
using ::android::hardware::tv::tuner::V1_0::Constant;
using ::android::hardware::tv::tuner::V1_0::DataFormat;
using ::android::hardware::tv::tuner::V1_0::DemuxAlpFilterSettings;
using ::android::hardware::tv::tuner::V1_0::DemuxAlpFilterType;
using ::android::hardware::tv::tuner::V1_0::DemuxAlpLengthType;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterAvSettings;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterDownloadEvent;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterDownloadSettings;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterIpPayloadEvent;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterMediaEvent;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterMmtpRecordEvent;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterPesDataSettings;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterPesEvent;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterRecordSettings;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterSectionBits;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterSectionEvent;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterSectionSettings;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterSettings;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterTemiEvent;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterTsRecordEvent;
using ::android::hardware::tv::tuner::V1_0::DemuxIpAddress;
using ::android::hardware::tv::tuner::V1_0::DemuxIpFilterSettings;
using ::android::hardware::tv::tuner::V1_0::DemuxIpFilterType;
@@ -136,6 +145,7 @@ struct fields_t {
    jmethodID dvrInitID;
    jmethodID onFrontendEventID;
    jmethodID onFilterStatusID;
    jmethodID onFilterEventID;
    jmethodID lnbInitID;
    jmethodID onLnbEventID;
    jmethodID descramblerInitID;
@@ -248,48 +258,287 @@ jobject FilterCallback::handleToLinearBlock(const native_handle_t* handle, uint3
    return linearBlock;
}

jobject FilterCallback::getMediaEvent(const DemuxFilterEvent::Event& event) {
jobjectArray FilterCallback::getSectionEvent(
        jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) {
    JNIEnv *env = AndroidRuntime::getJNIEnv();
    jclass clazz = env->FindClass("android/media/tv/tuner/filter/MediaEvent");
    jmethodID eventInit = env->GetMethodID(clazz,
    jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/SectionEvent");
    jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(IIII)V");

    for (int i = 0; i < events.size(); i++) {
        auto event = events[i];
        DemuxFilterSectionEvent sectionEvent = event.section();

        jint tableId = static_cast<jint>(sectionEvent.tableId);
        jint version = static_cast<jint>(sectionEvent.version);
        jint sectionNum = static_cast<jint>(sectionEvent.sectionNum);
        jint dataLength = static_cast<jint>(sectionEvent.dataLength);

        jobject obj =
                env->NewObject(eventClazz, eventInit, tableId, version, sectionNum, dataLength);
        env->SetObjectArrayElement(arr, i, obj);
    }
    return arr;
}

jobjectArray FilterCallback::getMediaEvent(
        jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) {
    JNIEnv *env = AndroidRuntime::getJNIEnv();
    jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/MediaEvent");
    jmethodID eventInit = env->GetMethodID(eventClazz,
            "<init>",
            "(IZJJJLandroid/media/MediaCodec$LinearBlock;"
            "ZJIZLandroid/media/tv/tuner/filter/AudioDescriptor;)V");

    for (int i = 0; i < events.size(); i++) {
        auto event = events[i];
        DemuxFilterMediaEvent mediaEvent = event.media();
    uint32_t dataLength = mediaEvent.dataLength;
    const native_handle_t* h = mediaEvent.avMemory.getNativeHandle();
    jobject block = handleToLinearBlock(h, dataLength);
    // TODO: handle other fields

    return env->NewObject(clazz, eventInit, (jint) 0, (jboolean) 0, (jlong) 0, (jlong) 0, (jlong) 0,
            block, (jboolean) 0, (jlong) 0, (jint) 0, (jboolean) 0, NULL);
        jobject audioDescriptor = NULL;
        if (mediaEvent.extraMetaData.getDiscriminator()
                == DemuxFilterMediaEvent::ExtraMetaData::hidl_discriminator::audio) {
            jclass adClazz = env->FindClass("android/media/tv/tuner/filter/AudioDescriptor");
            jmethodID adInit = env->GetMethodID(adClazz, "<init>", "(BBCBBB)V");

            AudioExtraMetaData ad = mediaEvent.extraMetaData.audio();
            jbyte adFade = static_cast<jbyte>(ad.adFade);
            jbyte adPan = static_cast<jbyte>(ad.adPan);
            jchar versionTextTag = static_cast<jchar>(ad.versionTextTag);
            jbyte adGainCenter = static_cast<jbyte>(ad.adGainCenter);
            jbyte adGainFront = static_cast<jbyte>(ad.adGainFront);
            jbyte adGainSurround = static_cast<jbyte>(ad.adGainSurround);

            audioDescriptor =
                    env->NewObject(adClazz, adInit, adFade, adPan, versionTextTag, adGainCenter,
                            adGainFront, adGainSurround);
        }

        jlong dataLength = static_cast<jlong>(mediaEvent.dataLength);
        const native_handle_t* h = NULL;
        jobject block = NULL;
        if (mediaEvent.avMemory != NULL) {
            h = mediaEvent.avMemory.getNativeHandle();
            block = handleToLinearBlock(h, dataLength);
        }

        jint streamId = static_cast<jint>(mediaEvent.streamId);
        jboolean isPtsPresent = static_cast<jboolean>(mediaEvent.isPtsPresent);
        jlong pts = static_cast<jlong>(mediaEvent.pts);
        jlong offset = static_cast<jlong>(mediaEvent.offset);
        jboolean isSecureMemory = static_cast<jboolean>(mediaEvent.isSecureMemory);
        jlong avDataId = static_cast<jlong>(mediaEvent.avDataId);
        jint mpuSequenceNumber = static_cast<jint>(mediaEvent.mpuSequenceNumber);
        jboolean isPesPrivateData = static_cast<jboolean>(mediaEvent.isPesPrivateData);

        jobject obj =
                env->NewObject(eventClazz, eventInit, streamId, isPtsPresent, pts, dataLength,
                offset, block, isSecureMemory, avDataId, mpuSequenceNumber, isPesPrivateData,
                audioDescriptor);
        env->SetObjectArrayElement(arr, i, obj);
    }
    return arr;
}

jobjectArray FilterCallback::getPesEvent(
        jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) {
    JNIEnv *env = AndroidRuntime::getJNIEnv();
    jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/PesEvent");
    jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(III)V");

    for (int i = 0; i < events.size(); i++) {
        auto event = events[i];
        DemuxFilterPesEvent pesEvent = event.pes();

        jint streamId = static_cast<jint>(pesEvent.streamId);
        jint dataLength = static_cast<jint>(pesEvent.dataLength);
        jint mpuSequenceNumber = static_cast<jint>(pesEvent.mpuSequenceNumber);

        jobject obj =
                env->NewObject(eventClazz, eventInit, streamId, dataLength, mpuSequenceNumber);
        env->SetObjectArrayElement(arr, i, obj);
    }
    return arr;
}

jobjectArray FilterCallback::getTsRecordEvent(
        jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) {
    JNIEnv *env = AndroidRuntime::getJNIEnv();
    jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/TsRecordEvent");
    jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(IIIJ)V");

    for (int i = 0; i < events.size(); i++) {
        auto event = events[i];
        DemuxFilterTsRecordEvent tsRecordEvent = event.tsRecord();
        DemuxPid pid = tsRecordEvent.pid;

        jint jpid = static_cast<jint>(Constant::INVALID_TS_PID);

        if (pid.getDiscriminator() == DemuxPid::hidl_discriminator::tPid) {
            jpid = static_cast<jint>(pid.tPid());
        } else if (pid.getDiscriminator() == DemuxPid::hidl_discriminator::mmtpPid) {
            jpid = static_cast<jint>(pid.mmtpPid());
        }

        jint sc = 0;

        if (tsRecordEvent.scIndexMask.getDiscriminator()
                == DemuxFilterTsRecordEvent::ScIndexMask::hidl_discriminator::sc) {
            sc = static_cast<jint>(tsRecordEvent.scIndexMask.sc());
        } else if (tsRecordEvent.scIndexMask.getDiscriminator()
                == DemuxFilterTsRecordEvent::ScIndexMask::hidl_discriminator::scHevc) {
            sc = static_cast<jint>(tsRecordEvent.scIndexMask.scHevc());
        }

        jint ts = static_cast<jint>(tsRecordEvent.tsIndexMask);

        jlong byteNumber = static_cast<jlong>(tsRecordEvent.byteNumber);

        jobject obj =
                env->NewObject(eventClazz, eventInit, jpid, ts, sc, byteNumber);
        env->SetObjectArrayElement(arr, i, obj);
    }
    return arr;
}

jobjectArray FilterCallback::getMmtpRecordEvent(
        jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) {
    JNIEnv *env = AndroidRuntime::getJNIEnv();
    jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/MmtpRecordEvent");
    jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(IJ)V");

    for (int i = 0; i < events.size(); i++) {
        auto event = events[i];
        DemuxFilterMmtpRecordEvent mmtpRecordEvent = event.mmtpRecord();

        jint scHevcIndexMask = static_cast<jint>(mmtpRecordEvent.scHevcIndexMask);
        jlong byteNumber = static_cast<jlong>(mmtpRecordEvent.byteNumber);

        jobject obj =
                env->NewObject(eventClazz, eventInit, scHevcIndexMask, byteNumber);
        env->SetObjectArrayElement(arr, i, obj);
    }
    return arr;
}

jobjectArray FilterCallback::getDownloadEvent(
        jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) {
    JNIEnv *env = AndroidRuntime::getJNIEnv();
    jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/DownloadEvent");
    jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(IIIII)V");

    for (int i = 0; i < events.size(); i++) {
        auto event = events[i];
        DemuxFilterDownloadEvent downloadEvent = event.download();

        jint itemId = static_cast<jint>(downloadEvent.itemId);
        jint mpuSequenceNumber = static_cast<jint>(downloadEvent.mpuSequenceNumber);
        jint itemFragmentIndex = static_cast<jint>(downloadEvent.itemFragmentIndex);
        jint lastItemFragmentIndex = static_cast<jint>(downloadEvent.lastItemFragmentIndex);
        jint dataLength = static_cast<jint>(downloadEvent.dataLength);

        jobject obj =
                env->NewObject(eventClazz, eventInit, itemId, mpuSequenceNumber, itemFragmentIndex,
                        lastItemFragmentIndex, dataLength);
        env->SetObjectArrayElement(arr, i, obj);
    }
    return arr;
}

jobjectArray FilterCallback::getIpPayloadEvent(
        jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) {
    JNIEnv *env = AndroidRuntime::getJNIEnv();
    jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/IpPayloadEvent");
    jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(I)V");

    for (int i = 0; i < events.size(); i++) {
        auto event = events[i];
        DemuxFilterIpPayloadEvent ipPayloadEvent = event.ipPayload();
        jint dataLength = static_cast<jint>(ipPayloadEvent.dataLength);
        jobject obj = env->NewObject(eventClazz, eventInit, dataLength);
        env->SetObjectArrayElement(arr, i, obj);
    }
    return arr;
}

jobjectArray FilterCallback::getTemiEvent(
        jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events) {
    JNIEnv *env = AndroidRuntime::getJNIEnv();
    jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/TemiEvent");
    jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(JB[B)V");

    for (int i = 0; i < events.size(); i++) {
        auto event = events[i];
        DemuxFilterTemiEvent temiEvent = event.temi();
        jlong pts = static_cast<jlong>(temiEvent.pts);
        jbyte descrTag = static_cast<jbyte>(temiEvent.descrTag);
        std::vector<uint8_t> descrData = temiEvent.descrData;

        jbyteArray array = env->NewByteArray(descrData.size());
        env->SetByteArrayRegion(
                array, 0, descrData.size(), reinterpret_cast<jbyte*>(&descrData[0]));

        jobject obj = env->NewObject(eventClazz, eventInit, pts, descrTag, array);
        env->SetObjectArrayElement(arr, i, obj);
    }
    return arr;
}

Return<void> FilterCallback::onFilterEvent(const DemuxFilterEvent& filterEvent) {
    ALOGD("FilterCallback::onFilterEvent");

    JNIEnv *env = AndroidRuntime::getJNIEnv();
    jclass clazz = env->FindClass("android/media/tv/tuner/filter/Filter");

    std::vector<DemuxFilterEvent::Event> events = filterEvent.events;
    jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/FilterEvent");
    jobjectArray array = env->NewObjectArray(events.size(), eventClazz, NULL);

    for (int i = 0; i < events.size(); i++) {
        auto event = events[i];
        if (event.getDiscriminator() == DemuxFilterEvent::Event::hidl_discriminator::media) {
            env->SetObjectArrayElement(array, i, getMediaEvent(event));
    if (!events.empty()) {
        auto event = events[0];
        switch (event.getDiscriminator()) {
            case DemuxFilterEvent::Event::hidl_discriminator::media: {
                array = getMediaEvent(array, events);
                break;
            }
            case DemuxFilterEvent::Event::hidl_discriminator::section: {
                array = getSectionEvent(array, events);
                break;
            }
            case DemuxFilterEvent::Event::hidl_discriminator::pes: {
                array = getPesEvent(array, events);
                break;
            }
            case DemuxFilterEvent::Event::hidl_discriminator::tsRecord: {
                array = getTsRecordEvent(array, events);
                break;
            }
            case DemuxFilterEvent::Event::hidl_discriminator::mmtpRecord: {
                array = getMmtpRecordEvent(array, events);
                break;
            }
            case DemuxFilterEvent::Event::hidl_discriminator::download: {
                array = getDownloadEvent(array, events);
                break;
            }
            case DemuxFilterEvent::Event::hidl_discriminator::ipPayload: {
                array = getIpPayloadEvent(array, events);
                break;
            }
            case DemuxFilterEvent::Event::hidl_discriminator::temi: {
                array = getTemiEvent(array, events);
                break;
            }
            default: {
                break;
            }
        }
    }
    env->CallVoidMethod(
            mFilter,
            env->GetMethodID(clazz, "onFilterEvent",
                    "([Landroid/media/tv/tuner/filter/FilterEvent;)V"),
            gFields.onFilterEventID,
            array);
    return Void();
}


Return<void> FilterCallback::onFilterStatus(const DemuxFilterStatus status) {
    ALOGD("FilterCallback::onFilterStatus");
    JNIEnv *env = AndroidRuntime::getJNIEnv();
@@ -308,9 +557,16 @@ void FilterCallback::setFilter(const jobject filter) {

/////////////// Filter ///////////////////////

Filter::Filter(sp<IFilter> sp, jweak obj) : mFilterSp(sp), mFilterObj(obj) {}
Filter::Filter(sp<IFilter> sp, jobject obj) : mFilterSp(sp) {
    JNIEnv *env = AndroidRuntime::getJNIEnv();
    mFilterObj = env->NewWeakGlobalRef(obj);
}

Filter::~Filter() {
    JNIEnv *env = AndroidRuntime::getJNIEnv();

    env->DeleteWeakGlobalRef(mFilterObj);
    mFilterObj = NULL;
    EventFlag::deleteEventFlag(&mFilterMQEventFlag);
}

@@ -1625,6 +1881,9 @@ static void android_media_tv_Tuner_native_init(JNIEnv *env) {
            env->GetMethodID(filterClazz, "<init>", "(I)V");
    gFields.onFilterStatusID =
            env->GetMethodID(filterClazz, "onFilterStatus", "(I)V");
    gFields.onFilterEventID =
            env->GetMethodID(filterClazz, "onFilterEvent",
                    "([Landroid/media/tv/tuner/filter/FilterEvent;)V");

    jclass timeFilterClazz = env->FindClass("android/media/tv/tuner/filter/TimeFilter");
    gFields.timeFilterContext = env->GetFieldID(timeFilterClazz, "mNativeContext", "J");
+17 −2
Original line number Diff line number Diff line
@@ -114,7 +114,22 @@ struct FilterCallback : public IFilterCallback {
    jobject handleToLinearBlock(const native_handle_t* handle, uint32_t size);
private:
    jweak mFilter;
    jobject getMediaEvent(const DemuxFilterEvent::Event& event);
    jobjectArray getSectionEvent(
            jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events);
    jobjectArray getMediaEvent(
            jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events);
    jobjectArray getPesEvent(
            jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events);
    jobjectArray getTsRecordEvent(
            jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events);
    jobjectArray getMmtpRecordEvent(
            jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events);
    jobjectArray getDownloadEvent(
            jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events);
    jobjectArray getIpPayloadEvent(
            jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events);
    jobjectArray getTemiEvent(
            jobjectArray& arr, const std::vector<DemuxFilterEvent::Event>& events);
};

struct FrontendCallback : public IFrontendCallback {
@@ -129,7 +144,7 @@ struct FrontendCallback : public IFrontendCallback {
};

struct Filter : public RefBase {
    Filter(sp<IFilter> sp, jweak obj);
    Filter(sp<IFilter> sp, jobject obj);
    ~Filter();
    int close();
    sp<IFilter> getIFilter();