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

Commit 0a3dfeb4 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Parse FilterConfiguration in JNI"

parents 1bc7be7f 87788c31
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -532,6 +532,8 @@ public class Tuner implements AutoCloseable {
        Filter filter = nativeOpenFilter(
                mainType, TunerUtils.getFilterSubtype(mainType, subType), bufferSize);
        if (filter != null) {
            filter.setMainType(mainType);
            filter.setSubtype(subType);
            filter.setCallback(cb);
            if (mHandler == null) {
                mHandler = createEventHandler();
+16 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.hardware.tv.tuner.V1_0.Constants;
import android.media.tv.tuner.TunerConstants.Result;
import android.media.tv.tuner.TunerUtils;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -177,6 +178,8 @@ public class Filter implements AutoCloseable {
    private long mNativeContext;
    private FilterCallback mCallback;
    private final int mId;
    private int mMainType;
    private int mSubtype;

    private native int nativeConfigureFilter(
            int type, int subType, FilterConfiguration settings);
@@ -196,6 +199,15 @@ public class Filter implements AutoCloseable {
    private void onFilterStatus(int status) {
    }

    /** @hide */
    public void setMainType(@Type int mainType) {
        mMainType = mainType;
    }
    /** @hide */
    public void setSubtype(@Subtype int subtype) {
        mSubtype = subtype;
    }

    /** @hide */
    public void setCallback(FilterCallback cb) {
        mCallback = cb;
@@ -213,10 +225,13 @@ public class Filter implements AutoCloseable {
     */
    @Result
    public int configure(@NonNull FilterConfiguration config) {
        int subType = -1;
        // TODO: validate main type, subtype, config, settings
        int subType;
        Settings s = config.getSettings();
        if (s != null) {
            subType = s.getType();
        } else {
            subType = TunerUtils.getFilterSubtype(mMainType, mSubtype);
        }
        return nativeConfigureFilter(config.getType(), subType, config);
    }
+6 −0
Original line number Diff line number Diff line
@@ -160,6 +160,12 @@ public class IpFilterConfiguration extends FilterConfiguration {
         */
        @NonNull
        public IpFilterConfiguration build() {
            int ipAddrLength = mSrcIpAddress.length;
            if (ipAddrLength != mDstIpAddress.length || (ipAddrLength != 4 && ipAddrLength != 16)) {
                throw new IllegalArgumentException(
                    "The lengths of src and dst IP address must be 4 or 16 and must be the same."
                            + "srcLength=" + ipAddrLength + ", dstLength=" + mDstIpAddress.length);
            }
            return new IpFilterConfiguration(
                    mSettings, mSrcIpAddress, mDstIpAddress, mSrcPort, mDstPort, mPassthrough);
        }
+120 −18
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ using ::android::hardware::hidl_vec;
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::DemuxFilterDownloadSettings;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
@@ -40,6 +41,7 @@ using ::android::hardware::tv::tuner::V1_0::DemuxFilterRecordSettings;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterSectionBits;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterSectionSettings;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterSettings;
using ::android::hardware::tv::tuner::V1_0::DemuxIpAddress;
using ::android::hardware::tv::tuner::V1_0::DemuxIpFilterSettings;
using ::android::hardware::tv::tuner::V1_0::DemuxIpFilterType;
using ::android::hardware::tv::tuner::V1_0::DemuxMmtpFilterSettings;
@@ -129,6 +131,9 @@ struct fields_t {

static fields_t gFields;

static int IP_V4_LENGTH = 4;
static int IP_V6_LENGTH = 16;

namespace android {
/////////////// LnbCallback ///////////////////////
LnbCallback::LnbCallback(jweak tunerObj, LnbId id) : mObject(tunerObj), mId(id) {}
@@ -1509,12 +1514,67 @@ static DemuxFilterDownloadSettings getFilterDownloadSettings(JNIEnv *env, const
    return filterDownloadSettings;
}

static DemuxIpAddress getDemuxIpAddress(JNIEnv *env, const jobject& config) {
    jclass clazz = env->FindClass("android/media/tv/tuner/filter/IpFilterConfiguration");

    jbyteArray jsrcIpAddress = static_cast<jbyteArray>(
            env->GetObjectField(config, env->GetFieldID(clazz, "mSrcIpAddress", "[B")));
    jsize srcSize = env->GetArrayLength(jsrcIpAddress);
    jbyteArray jdstIpAddress = static_cast<jbyteArray>(
            env->GetObjectField(config, env->GetFieldID(clazz, "mDstIpAddress", "[B")));
    jsize dstSize = env->GetArrayLength(jdstIpAddress);

    DemuxIpAddress res;

    if (srcSize != dstSize) {
        // should never happen. Validated on Java size.
        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
            "IP address lengths don't match. srcLength=%d, dstLength=%d", srcSize, dstSize);
        return res;
    }

    if (srcSize == IP_V4_LENGTH) {
        uint8_t srcAddr[IP_V4_LENGTH];
        uint8_t dstAddr[IP_V4_LENGTH];
        env->GetByteArrayRegion(
                jsrcIpAddress, 0, srcSize, reinterpret_cast<jbyte*>(srcAddr));
        env->GetByteArrayRegion(
                jdstIpAddress, 0, dstSize, reinterpret_cast<jbyte*>(dstAddr));
        res.srcIpAddress.v4(srcAddr);
        res.dstIpAddress.v4(dstAddr);
    } else if (srcSize == IP_V6_LENGTH) {
        uint8_t srcAddr[IP_V6_LENGTH];
        uint8_t dstAddr[IP_V6_LENGTH];
        env->GetByteArrayRegion(
                jsrcIpAddress, 0, srcSize, reinterpret_cast<jbyte*>(srcAddr));
        env->GetByteArrayRegion(
                jdstIpAddress, 0, dstSize, reinterpret_cast<jbyte*>(dstAddr));
        res.srcIpAddress.v6(srcAddr);
        res.dstIpAddress.v6(dstAddr);
    } else {
        // should never happen. Validated on Java size.
        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
            "Invalid IP address length %d", srcSize);
        return res;
    }

    uint16_t srcPort = static_cast<uint16_t>(
            env->GetIntField(config, env->GetFieldID(clazz, "mSrcPort", "I")));
    uint16_t dstPort = static_cast<uint16_t>(
            env->GetIntField(config, env->GetFieldID(clazz, "mDstPort", "I")));

    res.srcPort = srcPort;
    res.dstPort = dstPort;

    return res;
}

static DemuxFilterSettings getFilterConfiguration(
        JNIEnv *env, int type, int subtype, jobject filterSettingsObj) {
        JNIEnv *env, int type, int subtype, jobject filterConfigObj) {
    DemuxFilterSettings filterSettings;
    jobject settingsObj =
            env->GetObjectField(
                    filterSettingsObj,
                    filterConfigObj,
                    env->GetFieldID(
                            env->FindClass("android/media/tv/tuner/filter/FilterConfiguration"),
                            "mSettings",
@@ -1523,9 +1583,10 @@ static DemuxFilterSettings getFilterConfiguration(
    switch (mainType) {
        case DemuxFilterMainType::TS: {
            jclass clazz = env->FindClass("android/media/tv/tuner/filter/TsFilterConfiguration");
            int tpid = env->GetIntField(filterSettingsObj, env->GetFieldID(clazz, "mTpid", "I"));
            uint16_t tpid = static_cast<uint16_t>(
                    env->GetIntField(filterConfigObj, env->GetFieldID(clazz, "mTpid", "I")));
            DemuxTsFilterSettings tsFilterSettings {
                .tpid = static_cast<uint16_t>(tpid),
                .tpid = tpid,
            };

            DemuxTsFilterType tsType = static_cast<DemuxTsFilterType>(subtype);
@@ -1553,7 +1614,12 @@ static DemuxFilterSettings getFilterConfiguration(
            break;
        }
        case DemuxFilterMainType::MMTP: {
            DemuxMmtpFilterSettings mmtpFilterSettings;
            jclass clazz = env->FindClass("android/media/tv/tuner/filter/MmtpFilterConfiguration");
            uint16_t mmtpPid = static_cast<uint16_t>(
                    env->GetIntField(filterConfigObj, env->GetFieldID(clazz, "mMmtpPid", "I")));
            DemuxMmtpFilterSettings mmtpFilterSettings {
                .mmtpPid = mmtpPid,
            };
            DemuxMmtpFilterType mmtpType = static_cast<DemuxMmtpFilterType>(subtype);
            switch (mmtpType) {
                case DemuxMmtpFilterType::SECTION:
@@ -1583,43 +1649,79 @@ static DemuxFilterSettings getFilterConfiguration(
            break;
        }
        case DemuxFilterMainType::IP: {
            DemuxIpFilterSettings ipFilterSettings;
            DemuxIpAddress ipAddr = getDemuxIpAddress(env, filterConfigObj);

            DemuxIpFilterSettings ipFilterSettings {
                .ipAddr = ipAddr,
            };
            DemuxIpFilterType ipType = static_cast<DemuxIpFilterType>(subtype);
            switch (ipType) {
                case DemuxIpFilterType::SECTION:
                case DemuxIpFilterType::SECTION: {
                    ipFilterSettings.filterSettings.section(
                            getFilterSectionSettings(env, settingsObj));
                    break;
                case DemuxIpFilterType::IP:
                    // TODO: handle passthrough
                    ipFilterSettings.filterSettings.bPassthrough(false);
                }
                case DemuxIpFilterType::IP: {
                    jclass clazz = env->FindClass(
                            "android/media/tv/tuner/filter/IpFilterConfiguration");
                    bool bPassthrough = static_cast<bool>(
                            env->GetBooleanField(
                                    filterConfigObj, env->GetFieldID(
                                            clazz, "mPassthrough", "Z")));
                    ipFilterSettings.filterSettings.bPassthrough(bPassthrough);
                    break;
                default:
                }
                default: {
                    break;
                }
            }
            filterSettings.ip(ipFilterSettings);
            break;
        }
        case DemuxFilterMainType::TLV: {
            DemuxTlvFilterSettings tlvFilterSettings;
            jclass clazz = env->FindClass("android/media/tv/tuner/filter/TlvFilterConfiguration");
            uint8_t packetType = static_cast<uint8_t>(
                    env->GetIntField(filterConfigObj, env->GetFieldID(clazz, "mPacketType", "I")));
            bool isCompressedIpPacket = static_cast<bool>(
                    env->GetBooleanField(
                            filterConfigObj, env->GetFieldID(clazz, "mIsCompressedIpPacket", "Z")));

            DemuxTlvFilterSettings tlvFilterSettings {
                .packetType = packetType,
                .isCompressedIpPacket = isCompressedIpPacket,
            };
            DemuxTlvFilterType tlvType = static_cast<DemuxTlvFilterType>(subtype);
            switch (tlvType) {
                case DemuxTlvFilterType::SECTION:
                case DemuxTlvFilterType::SECTION: {
                    tlvFilterSettings.filterSettings.section(
                            getFilterSectionSettings(env, settingsObj));
                    break;
                case DemuxTlvFilterType::TLV:
                    // TODO: handle passthrough
                    tlvFilterSettings.filterSettings.bPassthrough(false);
                }
                case DemuxTlvFilterType::TLV: {
                    bool bPassthrough = static_cast<bool>(
                            env->GetBooleanField(
                                    filterConfigObj, env->GetFieldID(
                                            clazz, "mPassthrough", "Z")));
                    tlvFilterSettings.filterSettings.bPassthrough(bPassthrough);
                    break;
                default:
                }
                default: {
                    break;
                }
            }
            filterSettings.tlv(tlvFilterSettings);
            break;
        }
        case DemuxFilterMainType::ALP: {
            DemuxAlpFilterSettings alpFilterSettings;
            jclass clazz = env->FindClass("android/media/tv/tuner/filter/AlpFilterConfiguration");
            uint8_t packetType = static_cast<uint8_t>(
                    env->GetIntField(filterConfigObj, env->GetFieldID(clazz, "mPacketType", "I")));
            DemuxAlpLengthType lengthType = static_cast<DemuxAlpLengthType>(
                    env->GetIntField(filterConfigObj, env->GetFieldID(clazz, "mLengthType", "I")));
            DemuxAlpFilterSettings alpFilterSettings {
                .packetType = packetType,
                .lengthType = lengthType,
            };
            DemuxAlpFilterType alpType = static_cast<DemuxAlpFilterType>(subtype);
            switch (alpType) {
                case DemuxAlpFilterType::SECTION: