From b13e3042f3e7e3ef972b8c7cffb398477e8b6f05 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Mon, 27 Jul 2020 14:50:10 -0700 Subject: [PATCH 1/2] Make Tuner java framework and Tuner JNI adopt Tuner HAL 1.1 Please see the Tuner HAL 1.1 design doc here: go/android_tuner_hal_1.1 In this CL, the Tuner framework and JNI start to use the @1.1::IFilter.getId64Bit() API and @1.1::IFilterCallback. Currently the 1.1 IFilterCallback passes two new 1.1 record filter events: DemuxFilterTsRecordEvent and DemuxFilterMmtpRecordEvent. Tuner Framework exposes a new API: getId64Bit() which calls the native getId64Bit. Also Filter java will be using long id instead of the previous int id. The FilterCallback interface remains unchanged but the TsRecordEvent and the MmtpRecordEvent carry more variables to pass the extra info in version 1.1. When the HAL implementation is on version 1.0 and calls onFilterEvent, it still uses the extended TsRecordEvent and MmtpRecordEvent but the 1.1 field will be set to invalid. Related HAL interface can be referred here: hardware/interfaces/tv/tuner/1.1 Test: make -j44 dist, atest android.media.tv.tuner.cts Bug: b/159058358 Bug: 158816517 Change-Id: I8d52c0b2031eed9c54909e5bf233137c56eeb78f --- Android.bp | 1 + api/system-current.txt | 6 + media/java/android/media/tv/tuner/Tuner.java | 27 ++++- .../android/media/tv/tuner/filter/Filter.java | 15 ++- .../tv/tuner/filter/MmtpRecordEvent.java | 22 +++- .../media/tv/tuner/filter/TsRecordEvent.java | 13 +- media/jni/Android.bp | 1 + media/jni/android_media_tv_Tuner.cpp | 113 ++++++++++++++---- media/jni/android_media_tv_Tuner.h | 18 ++- non-updatable-api/system-current.txt | 6 + 10 files changed, 187 insertions(+), 35 deletions(-) diff --git a/Android.bp b/Android.bp index afdd832718bbc..1f17932be895e 100644 --- a/Android.bp +++ b/Android.bp @@ -482,6 +482,7 @@ java_library { "android.hardware.thermal-V2.0-java", "android.hardware.tv.input-V1.0-java-constants", "android.hardware.tv.tuner-V1.0-java-constants", + "android.hardware.tv.tuner-V1.1-java-constants", "android.hardware.usb-V1.0-java-constants", "android.hardware.usb-V1.1-java-constants", "android.hardware.usb-V1.2-java-constants", diff --git a/api/system-current.txt b/api/system-current.txt index 1404f7e1c554b..dff171eb52c16 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -5052,6 +5052,8 @@ package android.media.tv.tuner { method public void updateResourcePriority(int, int); field public static final int INVALID_AV_SYNC_ID = -1; // 0xffffffff field public static final int INVALID_FILTER_ID = -1; // 0xffffffff + field public static final long INVALID_FILTER_ID_64BIT = -1L; // 0xffffffffffffffffL + field public static final int INVALID_MMTP_RECORD_EVENT_MPT_SEQUENCE_NUM = -1; // 0xffffffff field public static final int INVALID_STREAM_ID = 65535; // 0xffff field public static final long INVALID_TIMESTAMP = -1L; // 0xffffffffffffffffL field public static final int INVALID_TS_PID = 65535; // 0xffff @@ -5204,6 +5206,7 @@ package android.media.tv.tuner.filter { method public int configure(@NonNull android.media.tv.tuner.filter.FilterConfiguration); method public int flush(); method public int getId(); + method public long getId64Bit(); method public int read(@NonNull byte[], long, long); method public int setDataSource(@Nullable android.media.tv.tuner.filter.Filter); method public int start(); @@ -5304,6 +5307,8 @@ package android.media.tv.tuner.filter { public class MmtpRecordEvent extends android.media.tv.tuner.filter.FilterEvent { method public long getDataLength(); + method public int getMpuSequenceNumber(); + method public long getPts(); method public int getScHevcIndexMask(); } @@ -5466,6 +5471,7 @@ package android.media.tv.tuner.filter { public class TsRecordEvent extends android.media.tv.tuner.filter.FilterEvent { method public long getDataLength(); method public int getPacketId(); + method public long getPts(); method public int getScIndexMask(); method public int getTsIndexMask(); } diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java index e148d0e29b5a6..0f14134eea021 100644 --- a/media/java/android/media/tv/tuner/Tuner.java +++ b/media/java/android/media/tv/tuner/Tuner.java @@ -98,15 +98,34 @@ public class Tuner implements AutoCloseable { * Invalid timestamp. * *

Returned by {@link android.media.tv.tuner.filter.TimeFilter#getSourceTime()}, - * {@link android.media.tv.tuner.filter.TimeFilter#getTimeStamp()}, or - * {@link Tuner#getAvSyncTime(int)} when the requested timestamp is not available. + * {@link android.media.tv.tuner.filter.TimeFilter#getTimeStamp()}, + * {@link Tuner#getAvSyncTime(int)} or {@link TsRecordEvent#getPts()} and + * {@link MmtpRecordEvent#getPts()} when the requested timestamp is not available. * * @see android.media.tv.tuner.filter.TimeFilter#getSourceTime() * @see android.media.tv.tuner.filter.TimeFilter#getTimeStamp() * @see Tuner#getAvSyncTime(int) + * @see android.media.tv.tuner.filter.TsRecordEvent#getPts() + * @see android.media.tv.tuner.filter.MmtpRecordEvent#getPts() */ - public static final long INVALID_TIMESTAMP = -1L; - + public static final long INVALID_TIMESTAMP = + android.hardware.tv.tuner.V1_1.Constants.Constant64Bit.INVALID_PRESENTATION_TIME_STAMP; + /** + * Invalid mpu sequence number in MmtpRecordEvent. + * + *

Returned by {@link MmtpRecordEvent#getMpuSequenceNumber()} when the requested sequence + * number is not available. + * + * @see android.media.tv.tuner.filter.MmtpRecordEvent#getMpuSequenceNumber() + */ + public static final int INVALID_MMTP_RECORD_EVENT_MPT_SEQUENCE_NUM = + android.hardware.tv.tuner.V1_1.Constants.Constant + .INVALID_MMTP_RECORD_EVENT_MPT_SEQUENCE_NUM; + /** + * Invalid 64-bit filter ID. + */ + public static final long INVALID_FILTER_ID_64BIT = + android.hardware.tv.tuner.V1_1.Constants.Constant64Bit.INVALID_FILTER_ID_64BIT; /** @hide */ @IntDef(prefix = "SCAN_TYPE_", value = {SCAN_TYPE_UNDEFINED, SCAN_TYPE_AUTO, SCAN_TYPE_BLIND}) diff --git a/media/java/android/media/tv/tuner/filter/Filter.java b/media/java/android/media/tv/tuner/filter/Filter.java index f0015b723edbb..2f2d8f74c9083 100644 --- a/media/java/android/media/tv/tuner/filter/Filter.java +++ b/media/java/android/media/tv/tuner/filter/Filter.java @@ -185,7 +185,7 @@ public class Filter implements AutoCloseable { private long mNativeContext; private FilterCallback mCallback; private Executor mExecutor; - private final int mId; + private final long mId; private int mMainType; private int mSubtype; private Filter mSource; @@ -196,6 +196,7 @@ public class Filter implements AutoCloseable { private native int nativeConfigureFilter( int type, int subType, FilterConfiguration settings); private native int nativeGetId(); + private native long nativeGetId64Bit(); private native int nativeSetDataSource(Filter source); private native int nativeStartFilter(); private native int nativeStopFilter(); @@ -204,7 +205,7 @@ public class Filter implements AutoCloseable { private native int nativeClose(); // Called by JNI - private Filter(int id) { + private Filter(long id) { mId = id; } @@ -268,6 +269,16 @@ public class Filter implements AutoCloseable { } } + /** + * Gets the 64-bit filter Id. + */ + public long getId64Bit() { + synchronized (mLock) { + TunerUtils.checkResourceState(TAG, mIsClosed); + return nativeGetId64Bit(); + } + } + /** * Sets the filter's data source. * diff --git a/media/java/android/media/tv/tuner/filter/MmtpRecordEvent.java b/media/java/android/media/tv/tuner/filter/MmtpRecordEvent.java index 466fa3ecb6e7a..7060bd722d572 100644 --- a/media/java/android/media/tv/tuner/filter/MmtpRecordEvent.java +++ b/media/java/android/media/tv/tuner/filter/MmtpRecordEvent.java @@ -29,11 +29,15 @@ import android.media.tv.tuner.filter.RecordSettings.ScHevcIndex; public class MmtpRecordEvent extends FilterEvent { private final int mScHevcIndexMask; private final long mDataLength; + private final int mMpuSequenceNumber; + private final long mPts; // This constructor is used by JNI code only - private MmtpRecordEvent(int scHevcIndexMask, long dataLength) { + private MmtpRecordEvent(int scHevcIndexMask, long dataLength, int mpuSequenceNumber, long pts) { mScHevcIndexMask = scHevcIndexMask; mDataLength = dataLength; + mMpuSequenceNumber = mpuSequenceNumber; + mPts = pts; } /** @@ -51,4 +55,20 @@ public class MmtpRecordEvent extends FilterEvent { public long getDataLength() { return mDataLength; } + + /** + * Get the MPU sequence number of the filtered data. + */ + public int getMpuSequenceNumber() { + return mMpuSequenceNumber; + } + + /** + * Get the Presentation Time Stamp(PTS) for the audio or video frame. It is based on 90KHz + * and has the same format as the PTS in ISO/IEC 13818-1. It is used only for the SC and + * the SC_HEVC. + */ + public long getPts() { + return mPts; + } } diff --git a/media/java/android/media/tv/tuner/filter/TsRecordEvent.java b/media/java/android/media/tv/tuner/filter/TsRecordEvent.java index 7a14bb8637008..258e2f22427c6 100644 --- a/media/java/android/media/tv/tuner/filter/TsRecordEvent.java +++ b/media/java/android/media/tv/tuner/filter/TsRecordEvent.java @@ -32,13 +32,15 @@ public class TsRecordEvent extends FilterEvent { private final int mTsIndexMask; private final int mScIndexMask; private final long mDataLength; + private final long mPts; // This constructor is used by JNI code only - private TsRecordEvent(int pid, int tsIndexMask, int scIndexMask, long dataLength) { + private TsRecordEvent(int pid, int tsIndexMask, int scIndexMask, long dataLength, long pts) { mPid = pid; mTsIndexMask = tsIndexMask; mScIndexMask = scIndexMask; mDataLength = dataLength; + mPts = pts; } /** @@ -72,4 +74,13 @@ public class TsRecordEvent extends FilterEvent { public long getDataLength() { return mDataLength; } + + /** + * Gets the Presentation Time Stamp(PTS) for the audio or video frame. It is based on 90KHz + * and has the same format as the PTS in ISO/IEC 13818-1. It is used only for the SC and + * the SC_HEVC. + */ + public long getPts() { + return mPts; + } } diff --git a/media/jni/Android.bp b/media/jni/Android.bp index 4e27c8e2723d1..724965dac9471 100644 --- a/media/jni/Android.bp +++ b/media/jni/Android.bp @@ -142,6 +142,7 @@ cc_library_shared { shared_libs: [ "android.hardware.graphics.bufferqueue@2.0", "android.hardware.tv.tuner@1.0", + "android.hardware.tv.tuner@1.1", "libandroid_runtime", "libcutils", "libfmq", diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp index 5daf8b0f88f85..1c23eaf05b5f1 100644 --- a/media/jni/android_media_tv_Tuner.cpp +++ b/media/jni/android_media_tv_Tuner.cpp @@ -22,7 +22,6 @@ #include "android_runtime/AndroidRuntime.h" #include -#include #include #include #include @@ -34,7 +33,6 @@ 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; @@ -129,12 +127,13 @@ using ::android::hardware::tv::tuner::V1_0::FrontendStatus; using ::android::hardware::tv::tuner::V1_0::FrontendStatusAtsc3PlpInfo; using ::android::hardware::tv::tuner::V1_0::FrontendStatusType; using ::android::hardware::tv::tuner::V1_0::FrontendType; -using ::android::hardware::tv::tuner::V1_0::ITuner; using ::android::hardware::tv::tuner::V1_0::LnbPosition; using ::android::hardware::tv::tuner::V1_0::LnbTone; using ::android::hardware::tv::tuner::V1_0::LnbVoltage; using ::android::hardware::tv::tuner::V1_0::PlaybackSettings; using ::android::hardware::tv::tuner::V1_0::RecordSettings; +using ::android::hardware::tv::tuner::V1_1::Constant; +using ::android::hardware::tv::tuner::V1_1::Constant64Bit; struct fields_t { jfieldID tunerContext; @@ -505,10 +504,11 @@ jobjectArray FilterCallback::getPesEvent( } jobjectArray FilterCallback::getTsRecordEvent( - jobjectArray& arr, const std::vector& events) { + jobjectArray& arr, const std::vector& events, + const std::vector& eventsExt) { JNIEnv *env = AndroidRuntime::getJNIEnv(); jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/TsRecordEvent"); - jmethodID eventInit = env->GetMethodID(eventClazz, "", "(IIIJ)V"); + jmethodID eventInit = env->GetMethodID(eventClazz, "", "(IIIJJ)V"); for (int i = 0; i < events.size(); i++) { auto event = events[i]; @@ -537,28 +537,39 @@ jobjectArray FilterCallback::getTsRecordEvent( jlong byteNumber = static_cast(tsRecordEvent.byteNumber); + jlong pts = (eventsExt.size() > i) ? static_cast(eventsExt[i].tsRecord().pts) + : static_cast(Constant64Bit::INVALID_PRESENTATION_TIME_STAMP); + jobject obj = - env->NewObject(eventClazz, eventInit, jpid, ts, sc, byteNumber); + env->NewObject(eventClazz, eventInit, jpid, ts, sc, byteNumber, pts); env->SetObjectArrayElement(arr, i, obj); } return arr; } jobjectArray FilterCallback::getMmtpRecordEvent( - jobjectArray& arr, const std::vector& events) { + jobjectArray& arr, const std::vector& events, + const std::vector& eventsExt) { JNIEnv *env = AndroidRuntime::getJNIEnv(); jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/MmtpRecordEvent"); - jmethodID eventInit = env->GetMethodID(eventClazz, "", "(IJ)V"); + jmethodID eventInit = env->GetMethodID(eventClazz, "", "(IJIJ)V"); for (int i = 0; i < events.size(); i++) { auto event = events[i]; + DemuxFilterMmtpRecordEvent mmtpRecordEvent = event.mmtpRecord(); jint scHevcIndexMask = static_cast(mmtpRecordEvent.scHevcIndexMask); jlong byteNumber = static_cast(mmtpRecordEvent.byteNumber); + jint mpuSequenceNumber = (eventsExt.size() > i) + ? static_cast(eventsExt[i].mmtpRecord().mpuSequenceNumber) + : static_cast(Constant::INVALID_MMTP_RECORD_EVENT_MPT_SEQUENCE_NUM); + jlong pts = (eventsExt.size() > i) ? static_cast(eventsExt[i].mmtpRecord().pts) + : static_cast(Constant64Bit::INVALID_PRESENTATION_TIME_STAMP); jobject obj = - env->NewObject(eventClazz, eventInit, scHevcIndexMask, byteNumber); + env->NewObject(eventClazz, eventInit, scHevcIndexMask, byteNumber, + mpuSequenceNumber, pts); env->SetObjectArrayElement(arr, i, obj); } return arr; @@ -627,12 +638,14 @@ jobjectArray FilterCallback::getTemiEvent( return arr; } -Return FilterCallback::onFilterEvent(const DemuxFilterEvent& filterEvent) { - ALOGD("FilterCallback::onFilterEvent"); +Return FilterCallback::onFilterEvent_1_1(const DemuxFilterEvent& filterEvent, + const DemuxFilterEventExt& filterEventExt) { + ALOGD("FilterCallback::onFilterEvent_1_1"); JNIEnv *env = AndroidRuntime::getJNIEnv(); std::vector events = filterEvent.events; + std::vector eventsExt = filterEventExt.events; jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/FilterEvent"); jobjectArray array = env->NewObjectArray(events.size(), eventClazz, NULL); @@ -652,11 +665,11 @@ Return FilterCallback::onFilterEvent(const DemuxFilterEvent& filterEvent) break; } case DemuxFilterEvent::Event::hidl_discriminator::tsRecord: { - array = getTsRecordEvent(array, events); + array = getTsRecordEvent(array, events, eventsExt); break; } case DemuxFilterEvent::Event::hidl_discriminator::mmtpRecord: { - array = getMmtpRecordEvent(array, events); + array = getMmtpRecordEvent(array, events, eventsExt); break; } case DemuxFilterEvent::Event::hidl_discriminator::download: { @@ -683,6 +696,14 @@ Return FilterCallback::onFilterEvent(const DemuxFilterEvent& filterEvent) return Void(); } +Return FilterCallback::onFilterEvent(const DemuxFilterEvent& filterEvent) { + ALOGD("FilterCallback::onFilterEvent"); + std::vector emptyEventsExt; + DemuxFilterEventExt emptyFilterEventExt { + .events = emptyEventsExt, + }; + return onFilterEvent_1_1(filterEvent, emptyFilterEventExt); +} Return FilterCallback::onFilterStatus(const DemuxFilterStatus status) { ALOGD("FilterCallback::onFilterStatus"); @@ -919,6 +940,7 @@ Return FrontendCallback::onScanMessage(FrontendScanMessageType type, const /////////////// Tuner /////////////////////// sp JTuner::mTuner; +sp<::android::hardware::tv::tuner::V1_1::ITuner> JTuner::mTuner_1_1; JTuner::JTuner(JNIEnv *env, jobject thiz) : mClass(NULL) { @@ -949,14 +971,20 @@ JTuner::~JTuner() { } sp JTuner::getTunerService() { - if (mTuner == nullptr) { - mTuner = ITuner::getService(); + if (mTuner == nullptr && mTuner_1_1 == nullptr) { + mTuner_1_1 = ::android::hardware::tv::tuner::V1_1::ITuner::getService(); - if (mTuner == nullptr) { - ALOGW("Failed to get tuner service."); - } - } - return mTuner; + if (mTuner_1_1 == nullptr) { + ALOGW("Failed to get tuner 1.1 service."); + mTuner = ITuner::getService(); + if (mTuner == nullptr) { + ALOGW("Failed to get tuner 1.0 service."); + } + } else { + mTuner = static_cast>(mTuner_1_1); + } + } + return mTuner; } jobject JTuner::getFrontendIds() { @@ -1504,6 +1532,7 @@ jobject JTuner::openFilter(DemuxFilterType type, int bufferSize) { } sp iFilterSp; + sp<::android::hardware::tv::tuner::V1_1::IFilter> iFilterSp_1_1; sp callback = new FilterCallback(); Result res; mDemux->openFilter(type, bufferSize, callback, @@ -1515,17 +1544,23 @@ jobject JTuner::openFilter(DemuxFilterType type, int bufferSize) { ALOGD("Failed to open filter, type = %d", type.mainType); return NULL; } - int fId; + uint64_t fId; iFilterSp->getId([&](Result, uint32_t filterId) { fId = filterId; }); + iFilterSp_1_1 = ::android::hardware::tv::tuner::V1_1::IFilter::castFrom(iFilterSp); + if (iFilterSp_1_1 != NULL) { + iFilterSp_1_1->getId64Bit([&](Result, uint64_t filterId64Bit) { + fId = filterId64Bit; + }); + } JNIEnv *env = AndroidRuntime::getJNIEnv(); jobject filterObj = env->NewObject( env->FindClass("android/media/tv/tuner/filter/Filter"), gFields.filterInitID, - (jint) fId); + (jlong) fId); sp filterSp = new Filter(iFilterSp, filterObj); filterSp->incStrong(filterObj); @@ -2460,7 +2495,7 @@ static void android_media_tv_Tuner_native_init(JNIEnv *env) { jclass filterClazz = env->FindClass("android/media/tv/tuner/filter/Filter"); gFields.filterContext = env->GetFieldID(filterClazz, "mNativeContext", "J"); gFields.filterInitID = - env->GetMethodID(filterClazz, "", "(I)V"); + env->GetMethodID(filterClazz, "", "(J)V"); gFields.onFilterStatusID = env->GetMethodID(filterClazz, "onFilterStatus", "(I)V"); gFields.onFilterEventID = @@ -3071,6 +3106,36 @@ static jint android_media_tv_Tuner_get_filter_id(JNIEnv* env, jobject filter) { return (jint) id; } +static jlong android_media_tv_Tuner_get_filter_64bit_id(JNIEnv* env, jobject filter) { + sp iFilterSp = getFilter(env, filter)->getIFilter(); + if (iFilterSp == NULL) { + ALOGD("Failed to get filter ID: filter not found"); + return static_cast( + ::android::hardware::tv::tuner::V1_1::Constant64Bit::INVALID_FILTER_ID_64BIT); + } + + sp<::android::hardware::tv::tuner::V1_1::IFilter> iFilterSp_1_1; + iFilterSp_1_1 = ::android::hardware::tv::tuner::V1_1::IFilter::castFrom(iFilterSp); + Result res; + uint64_t id; + + if (iFilterSp_1_1 != NULL) { + iFilterSp_1_1->getId64Bit( + [&](Result r, uint64_t filterId64Bit) { + res = r; + id = filterId64Bit; + }); + } else { + ALOGW("getId64Bit is not supported with the current HAL implementation."); + return static_cast( + ::android::hardware::tv::tuner::V1_1::Constant64Bit::INVALID_FILTER_ID_64BIT); + } + + return (res == Result::SUCCESS) ? + static_cast(id) : static_cast( + ::android::hardware::tv::tuner::V1_1::Constant64Bit::INVALID_FILTER_ID_64BIT); +} + static jint android_media_tv_Tuner_set_filter_data_source( JNIEnv* env, jobject filter, jobject srcFilter) { sp iFilterSp = getFilter(env, filter)->getIFilter(); @@ -3735,6 +3800,8 @@ static const JNINativeMethod gFilterMethods[] = { { "nativeConfigureFilter", "(IILandroid/media/tv/tuner/filter/FilterConfiguration;)I", (void *)android_media_tv_Tuner_configure_filter }, { "nativeGetId", "()I", (void *)android_media_tv_Tuner_get_filter_id }, + { "nativeGetId64Bit", "()J", + (void *)android_media_tv_Tuner_get_filter_64bit_id }, { "nativeSetDataSource", "(Landroid/media/tv/tuner/filter/Filter;)I", (void *)android_media_tv_Tuner_set_filter_data_source }, { "nativeStartFilter", "()I", (void *)android_media_tv_Tuner_start_filter }, diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h index c4deeaf887bbd..0b145b4b3843f 100644 --- a/media/jni/android_media_tv_Tuner.h +++ b/media/jni/android_media_tv_Tuner.h @@ -17,7 +17,11 @@ #ifndef _ANDROID_MEDIA_TV_TUNER_H_ #define _ANDROID_MEDIA_TV_TUNER_H_ -#include +#include +#include +#include +#include + #include #include #include @@ -38,6 +42,7 @@ using ::android::hardware::hidl_handle; using ::android::hardware::hidl_vec; using ::android::hardware::kSynchronizedReadWrite; using ::android::hardware::tv::tuner::V1_0::DemuxFilterEvent; +using ::android::hardware::tv::tuner::V1_1::DemuxFilterEventExt; using ::android::hardware::tv::tuner::V1_0::DemuxFilterStatus; using ::android::hardware::tv::tuner::V1_0::DemuxFilterType; using ::android::hardware::tv::tuner::V1_0::DemuxPid; @@ -54,7 +59,7 @@ using ::android::hardware::tv::tuner::V1_0::IDescrambler; using ::android::hardware::tv::tuner::V1_0::IDvr; using ::android::hardware::tv::tuner::V1_0::IDvrCallback; using ::android::hardware::tv::tuner::V1_0::IFilter; -using ::android::hardware::tv::tuner::V1_0::IFilterCallback; +using ::android::hardware::tv::tuner::V1_1::IFilterCallback; using ::android::hardware::tv::tuner::V1_0::IFrontend; using ::android::hardware::tv::tuner::V1_0::IFrontendCallback; using ::android::hardware::tv::tuner::V1_0::ILnb; @@ -147,6 +152,8 @@ struct Filter : public RefBase { struct FilterCallback : public IFilterCallback { ~FilterCallback(); + virtual Return onFilterEvent_1_1(const DemuxFilterEvent& filterEvent, + const DemuxFilterEventExt& filterEventExt); virtual Return onFilterEvent(const DemuxFilterEvent& filterEvent); virtual Return onFilterStatus(const DemuxFilterStatus status); @@ -161,9 +168,11 @@ private: jobjectArray getPesEvent( jobjectArray& arr, const std::vector& events); jobjectArray getTsRecordEvent( - jobjectArray& arr, const std::vector& events); + jobjectArray& arr, const std::vector&events, + const std::vector& eventsExt); jobjectArray getMmtpRecordEvent( - jobjectArray& arr, const std::vector& events); + jobjectArray& arr, const std::vector&events, + const std::vector& eventsExt); jobjectArray getDownloadEvent( jobjectArray& arr, const std::vector& events); jobjectArray getIpPayloadEvent( @@ -229,6 +238,7 @@ private: jclass mClass; jweak mObject; static sp mTuner; + static sp<::android::hardware::tv::tuner::V1_1::ITuner> mTuner_1_1; hidl_vec mFeIds; sp mFe; int mFeId; diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt index 515c2737029c9..80e90432ae2bb 100644 --- a/non-updatable-api/system-current.txt +++ b/non-updatable-api/system-current.txt @@ -4992,6 +4992,8 @@ package android.media.tv.tuner { method public void updateResourcePriority(int, int); field public static final int INVALID_AV_SYNC_ID = -1; // 0xffffffff field public static final int INVALID_FILTER_ID = -1; // 0xffffffff + field public static final long INVALID_FILTER_ID_64BIT = -1L; // 0xffffffffffffffffL + field public static final int INVALID_MMTP_RECORD_EVENT_MPT_SEQUENCE_NUM = -1; // 0xffffffff field public static final int INVALID_STREAM_ID = 65535; // 0xffff field public static final long INVALID_TIMESTAMP = -1L; // 0xffffffffffffffffL field public static final int INVALID_TS_PID = 65535; // 0xffff @@ -5144,6 +5146,7 @@ package android.media.tv.tuner.filter { method public int configure(@NonNull android.media.tv.tuner.filter.FilterConfiguration); method public int flush(); method public int getId(); + method public long getId64Bit(); method public int read(@NonNull byte[], long, long); method public int setDataSource(@Nullable android.media.tv.tuner.filter.Filter); method public int start(); @@ -5244,6 +5247,8 @@ package android.media.tv.tuner.filter { public class MmtpRecordEvent extends android.media.tv.tuner.filter.FilterEvent { method public long getDataLength(); + method public int getMpuSequenceNumber(); + method public long getPts(); method public int getScHevcIndexMask(); } @@ -5406,6 +5411,7 @@ package android.media.tv.tuner.filter { public class TsRecordEvent extends android.media.tv.tuner.filter.FilterEvent { method public long getDataLength(); method public int getPacketId(); + method public long getPts(); method public int getScIndexMask(); method public int getTsIndexMask(); } From 7b3b578d50d624cc4cf736a8bc2b2a5da6c2e846 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Wed, 5 Aug 2020 20:15:31 -0700 Subject: [PATCH 2/2] Add TunerVersionChecker to expose the Tuner HAL implementation version This can help Tuner java/cts get the information of the Tuner HAL implementation version and notify the client on the availability of the APIs in different versions or test with different expected result. Users can all access getTunerVersion to get the information. Test: atest android.media.tv.tuner.cts Bug: 158816517 Bug: 164449999 Change-Id: I0b6e4c226e696ca7f94dff7d2c9a59f57af7e13a --- api/system-current.txt | 7 + api/test-current.txt | 15 ++ media/java/android/media/tv/tuner/Tuner.java | 19 +++ .../media/tv/tuner/TunerVersionChecker.java | 153 ++++++++++++++++++ media/jni/android_media_tv_Tuner.cpp | 18 ++- media/jni/android_media_tv_Tuner.h | 4 + non-updatable-api/system-current.txt | 7 + 7 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 media/java/android/media/tv/tuner/TunerVersionChecker.java diff --git a/api/system-current.txt b/api/system-current.txt index dff171eb52c16..db936bf1b8f26 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -5073,6 +5073,13 @@ package android.media.tv.tuner { method public void onResourceLost(@NonNull android.media.tv.tuner.Tuner); } + public final class TunerVersionChecker { + method public static int getTunerVersion(); + field public static final int TUNER_VERSION_1_0 = 65536; // 0x10000 + field public static final int TUNER_VERSION_1_1 = 65537; // 0x10001 + field public static final int TUNER_VERSION_UNKNOWN = 0; // 0x0 + } + } package android.media.tv.tuner.dvr { diff --git a/api/test-current.txt b/api/test-current.txt index 76663378caf13..42dc114bbbd2b 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -2132,6 +2132,21 @@ package android.media.tv { } +package android.media.tv.tuner { + + public final class TunerVersionChecker { + method public static int getMajorVersion(int); + method public static int getMinorVersion(int); + method public static int getTunerVersion(); + method public static boolean isHigherOrEqualVersionTo(int); + method public static boolean supportTunerVersion(int); + field public static final int TUNER_VERSION_1_0 = 65536; // 0x10000 + field public static final int TUNER_VERSION_1_1 = 65537; // 0x10001 + field public static final int TUNER_VERSION_UNKNOWN = 0; // 0x0 + } + +} + package android.metrics { public class LogMaker { diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java index 0f14134eea021..27a49a75c6d00 100644 --- a/media/java/android/media/tv/tuner/Tuner.java +++ b/media/java/android/media/tv/tuner/Tuner.java @@ -223,6 +223,7 @@ public class Tuner implements AutoCloseable { private final Context mContext; private final TunerResourceManager mTunerResourceManager; private final int mClientId; + private static int sTunerVersion = TunerVersionChecker.TUNER_VERSION_UNKNOWN; private Frontend mFrontend; private EventHandler mHandler; @@ -274,6 +275,14 @@ public class Tuner implements AutoCloseable { public Tuner(@NonNull Context context, @Nullable String tvInputSessionId, @TvInputService.PriorityHintUseCaseType int useCase) { nativeSetup(); + sTunerVersion = nativeGetTunerVersion(); + if (sTunerVersion == TunerVersionChecker.TUNER_VERSION_UNKNOWN) { + Log.e(TAG, "Unknown Tuner version!"); + } else { + Log.d(TAG, "Current Tuner version is " + + TunerVersionChecker.getMajorVersion(sTunerVersion) + "." + + TunerVersionChecker.getMinorVersion(sTunerVersion) + "."); + } mContext = context; mTunerResourceManager = (TunerResourceManager) context.getSystemService(Context.TV_TUNER_RESOURCE_MGR_SERVICE); @@ -313,6 +322,11 @@ public class Tuner implements AutoCloseable { mTunerResourceManager.setFrontendInfoList(infos); } + /** @hide */ + public static int getTunerVersion() { + return sTunerVersion; + } + /** @hide */ public List getFrontendIds() { return nativeGetFrontendIds(); @@ -435,6 +449,11 @@ public class Tuner implements AutoCloseable { */ private native void nativeSetup(); + /** + * Native method to get all frontend IDs. + */ + private native int nativeGetTunerVersion(); + /** * Native method to get all frontend IDs. */ diff --git a/media/java/android/media/tv/tuner/TunerVersionChecker.java b/media/java/android/media/tv/tuner/TunerVersionChecker.java new file mode 100644 index 0000000000000..739f87dd711d5 --- /dev/null +++ b/media/java/android/media/tv/tuner/TunerVersionChecker.java @@ -0,0 +1,153 @@ +/* + * Copyright 2020 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. + */ + +package android.media.tv.tuner; + +import android.annotation.IntDef; +import android.annotation.SystemApi; +import android.annotation.TestApi; +import android.util.Log; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Utility class to check the currently running Tuner Hal implementation version. + * + * APIs that are not supported by the HAL implementation version would be no-op. + * + * @hide + */ +@TestApi +@SystemApi +public final class TunerVersionChecker { + private static final String TAG = "TunerVersionChecker"; + + private TunerVersionChecker() {} + + /** @hide */ + @IntDef(prefix = "TUNER_VERSION_", value = {TUNER_VERSION_UNKNOWN, TUNER_VERSION_1_0, + TUNER_VERSION_1_1}) + @Retention(RetentionPolicy.SOURCE) + public @interface TunerVersion {} + /** + * Unknown Tuner version. + */ + public static final int TUNER_VERSION_UNKNOWN = 0; + /** + * Tuner version 1.0. + */ + public static final int TUNER_VERSION_1_0 = (1 << 16); + /** + * Tuner version 1.1. + */ + public static final int TUNER_VERSION_1_1 = ((1 << 16) | 1); + + /** + * Get the current running Tuner version. + * + * @return Tuner version. + */ + @TunerVersion + public static int getTunerVersion() { + return Tuner.getTunerVersion(); + } + + /** + * Check if the current running Tuner version supports the given version. + * + *

Note that we treat different major versions as unsupported among each other. If any + * feature could be supported across major versions, please use + * {@link #isHigherOrEqualVersionTo(int)} to check. + * + * @param version the version to support. + * + * @return true if the current version is under the same major version as the given version + * and has higher or the same minor version as the given version. + * @hide + */ + @TestApi + public static boolean supportTunerVersion(@TunerVersion int version) { + int currentVersion = Tuner.getTunerVersion(); + return isHigherOrEqualVersionTo(version) + && (getMajorVersion(version) == getMajorVersion(currentVersion)); + } + + /** + * Check if the current running Tuner version is higher than or equal to a given version. + * + * @param version the version to compare. + * + * @return true if the current version is higher or equal to the support version. + * @hide + */ + @TestApi + public static boolean isHigherOrEqualVersionTo(@TunerVersion int version) { + int currentVersion = Tuner.getTunerVersion(); + return currentVersion >= version; + } + + /** + * Get the major version from a version number. + * + * @param version the version to be checked. + * + * @return the major version number. + * @hide + */ + @TestApi + public static int getMajorVersion(@TunerVersion int version) { + return ((version & 0xFFFF0000) >>> 16); + } + + /** + * Get the major version from a version number. + * + * @param version the version to be checked. + * + * @return the minor version number. + * @hide + */ + @TestApi + public static int getMinorVersion(@TunerVersion int version) { + return (version & 0xFFFF); + } + + /** @hide */ + public static boolean checkHigherOrEqualVersionTo( + @TunerVersion int version, String methodName) { + if (!TunerVersionChecker.isHigherOrEqualVersionTo(version)) { + Log.e(TAG, "Current Tuner version " + + TunerVersionChecker.getMajorVersion(Tuner.getTunerVersion()) + "." + + TunerVersionChecker.getMinorVersion(Tuner.getTunerVersion()) + + " does not support " + methodName + "."); + return false; + } + return true; + } + + /** @hide */ + public static boolean checkSupportVersion(@TunerVersion int version, String methodName) { + if (!TunerVersionChecker.supportTunerVersion(version)) { + Log.e(TAG, "Current Tuner version " + + TunerVersionChecker.getMajorVersion(Tuner.getTunerVersion()) + "." + + TunerVersionChecker.getMinorVersion(Tuner.getTunerVersion()) + + " does not support " + methodName + "."); + return false; + } + return true; + } +} diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp index 1c23eaf05b5f1..e0afe29de7e69 100644 --- a/media/jni/android_media_tv_Tuner.cpp +++ b/media/jni/android_media_tv_Tuner.cpp @@ -941,6 +941,7 @@ Return FrontendCallback::onScanMessage(FrontendScanMessageType type, const sp JTuner::mTuner; sp<::android::hardware::tv::tuner::V1_1::ITuner> JTuner::mTuner_1_1; +int JTuner::mTunerVersion = 0; JTuner::JTuner(JNIEnv *env, jobject thiz) : mClass(NULL) { @@ -971,7 +972,8 @@ JTuner::~JTuner() { } sp JTuner::getTunerService() { - if (mTuner == nullptr && mTuner_1_1 == nullptr) { + if (mTuner == nullptr) { + mTunerVersion = 0; mTuner_1_1 = ::android::hardware::tv::tuner::V1_1::ITuner::getService(); if (mTuner_1_1 == nullptr) { @@ -979,14 +981,22 @@ sp JTuner::getTunerService() { mTuner = ITuner::getService(); if (mTuner == nullptr) { ALOGW("Failed to get tuner 1.0 service."); + } else { + mTunerVersion = 1 << 16; } } else { mTuner = static_cast>(mTuner_1_1); + mTunerVersion = ((1 << 16) | 1); } } return mTuner; } +jint JTuner::getTunerVersion() { + ALOGD("JTuner::getTunerVersion()"); + return (jint) mTunerVersion; +} + jobject JTuner::getFrontendIds() { ALOGD("JTuner::getFrontendIds()"); mTuner->getFrontendIds([&](Result, const hidl_vec& frontendIds) { @@ -2536,6 +2546,11 @@ static void android_media_tv_Tuner_native_setup(JNIEnv *env, jobject thiz) { setTuner(env,thiz, tuner); } +static jint android_media_tv_Tuner_native_get_tuner_version(JNIEnv *env, jobject thiz) { + sp tuner = getTuner(env, thiz); + return tuner->getTunerVersion(); +} + static jobject android_media_tv_Tuner_get_frontend_ids(JNIEnv *env, jobject thiz) { sp tuner = getTuner(env, thiz); return tuner->getFrontendIds(); @@ -3749,6 +3764,7 @@ static void android_media_tv_Tuner_media_event_finalize(JNIEnv* env, jobject med static const JNINativeMethod gTunerMethods[] = { { "nativeInit", "()V", (void *)android_media_tv_Tuner_native_init }, { "nativeSetup", "()V", (void *)android_media_tv_Tuner_native_setup }, + { "nativeGetTunerVersion", "()I", (void *)android_media_tv_Tuner_native_get_tuner_version }, { "nativeGetFrontendIds", "()Ljava/util/List;", (void *)android_media_tv_Tuner_get_frontend_ids }, { "nativeOpenFrontendByHandle", "(I)Landroid/media/tv/tuner/Tuner$Frontend;", diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h index 0b145b4b3843f..d7dc600a166b1 100644 --- a/media/jni/android_media_tv_Tuner.h +++ b/media/jni/android_media_tv_Tuner.h @@ -203,6 +203,7 @@ struct TimeFilter : public RefBase { struct JTuner : public RefBase { JTuner(JNIEnv *env, jobject thiz); sp getTunerService(); + int getTunerVersion(); jobject getAvSyncHwId(sp filter); jobject getAvSyncTime(jint id); int connectCiCam(jint id); @@ -239,6 +240,9 @@ private: jweak mObject; static sp mTuner; static sp<::android::hardware::tv::tuner::V1_1::ITuner> mTuner_1_1; + // An integer that carries the Tuner version. The high 16 bits are the major version number + // while the low 16 bits are the minor version. Default value is unknown version 0. + static int mTunerVersion; hidl_vec mFeIds; sp mFe; int mFeId; diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt index 80e90432ae2bb..3045e0a5595e6 100644 --- a/non-updatable-api/system-current.txt +++ b/non-updatable-api/system-current.txt @@ -5013,6 +5013,13 @@ package android.media.tv.tuner { method public void onResourceLost(@NonNull android.media.tv.tuner.Tuner); } + public final class TunerVersionChecker { + method public static int getTunerVersion(); + field public static final int TUNER_VERSION_1_0 = 65536; // 0x10000 + field public static final int TUNER_VERSION_1_1 = 65537; // 0x10001 + field public static final int TUNER_VERSION_UNKNOWN = 0; // 0x0 + } + } package android.media.tv.tuner.dvr {