From b8b1e1da73c5dfb924b36af7a3b071c56cf991f1 Mon Sep 17 00:00:00 2001 From: Hongguang Date: Thu, 28 Oct 2021 21:25:51 -0700 Subject: [PATCH] Add ISDB-T Multi-Layer Support. Because ISDB-T has up to three layers (1) It is necessary to be able to obtain the hierarchical structure and information of each hierarchy by getFrontendStatus. Various transmission parameters, partial reception flags, error states at each level, etc. (2) It is necessary to be able to set the transmission parameters of each layer at the time of request. Various transmission parameters and partial reception flags. android.Manifest.permission.ACCESS_TV_TUNER is the overall control to the tuner resources, it's already checked before querying frontend status. Bug: 171537116 Test: atest android.media.tv.tuner.cts on AIDL and HAL HALs. Change-Id: I0d5a6056a09de5509be0a45cac435da4a43ab55f --- core/api/system-current.txt | 52 ++- media/java/android/media/tv/tuner/Tuner.java | 12 + .../tv/tuner/frontend/FrontendStatus.java | 66 +++- .../frontend/IsdbtFrontendCapabilities.java | 41 +- .../tuner/frontend/IsdbtFrontendSettings.java | 374 +++++++++++++++++- media/jni/android_media_tv_Tuner.cpp | 78 +++- 6 files changed, 587 insertions(+), 36 deletions(-) diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 0fb8bf4c50c6d..624fe0df40926 100755 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -7261,6 +7261,8 @@ package android.media.tv.tuner.frontend { method public int getHierarchy(); method public long getInnerFec(); method @NonNull public int[] getInterleaving(); + method public int getIsdbtMode(); + method public int getIsdbtPartialReceptionFlag(); method @IntRange(from=0, to=255) @NonNull public int[] getIsdbtSegment(); method @NonNull public boolean[] getLayerErrors(); method public int getLnbVoltage(); @@ -7299,6 +7301,8 @@ package android.media.tv.tuner.frontend { field public static final int FRONTEND_STATUS_TYPE_GUARD_INTERVAL = 26; // 0x1a field public static final int FRONTEND_STATUS_TYPE_HIERARCHY = 19; // 0x13 field public static final int FRONTEND_STATUS_TYPE_INTERLEAVINGS = 30; // 0x1e + field public static final int FRONTEND_STATUS_TYPE_ISDBT_MODE = 37; // 0x25 + field public static final int FRONTEND_STATUS_TYPE_ISDBT_PARTIAL_RECEPTION_FLAG = 38; // 0x26 field public static final int FRONTEND_STATUS_TYPE_ISDBT_SEGMENTS = 31; // 0x1f field public static final int FRONTEND_STATUS_TYPE_IS_LINEAR = 35; // 0x23 field public static final int FRONTEND_STATUS_TYPE_IS_MISO_ENABLED = 34; // 0x22 @@ -7431,15 +7435,20 @@ package android.media.tv.tuner.frontend { method public int getGuardIntervalCapability(); method public int getModeCapability(); method public int getModulationCapability(); + method public int getTimeInterleaveModeCapability(); + method public boolean isFullSegmentSupported(); + method public boolean isSegmentAutoSupported(); } public class IsdbtFrontendSettings extends android.media.tv.tuner.frontend.FrontendSettings { method @NonNull public static android.media.tv.tuner.frontend.IsdbtFrontendSettings.Builder builder(); method public int getBandwidth(); - method public int getCodeRate(); + method @Deprecated public int getCodeRate(); method public int getGuardInterval(); + method @NonNull public android.media.tv.tuner.frontend.IsdbtFrontendSettings.IsdbtLayerSettings[] getLayerSettings(); method public int getMode(); - method public int getModulation(); + method @Deprecated public int getModulation(); + method public int getPartialReceptionFlag(); method public int getServiceAreaId(); method public int getType(); field public static final int BANDWIDTH_6MHZ = 8; // 0x8 @@ -7458,20 +7467,55 @@ package android.media.tv.tuner.frontend { field public static final int MODULATION_MOD_DQPSK = 2; // 0x2 field public static final int MODULATION_MOD_QPSK = 4; // 0x4 field public static final int MODULATION_UNDEFINED = 0; // 0x0 + field public static final int PARTIAL_RECEPTION_FLAG_FALSE = 2; // 0x2 + field public static final int PARTIAL_RECEPTION_FLAG_TRUE = 4; // 0x4 + field public static final int PARTIAL_RECEPTION_FLAG_UNDEFINED = 0; // 0x0 + field public static final int TIME_INTERLEAVE_MODE_1_0 = 2; // 0x2 + field public static final int TIME_INTERLEAVE_MODE_1_16 = 16; // 0x10 + field public static final int TIME_INTERLEAVE_MODE_1_4 = 4; // 0x4 + field public static final int TIME_INTERLEAVE_MODE_1_8 = 8; // 0x8 + field public static final int TIME_INTERLEAVE_MODE_2_0 = 32; // 0x20 + field public static final int TIME_INTERLEAVE_MODE_2_2 = 64; // 0x40 + field public static final int TIME_INTERLEAVE_MODE_2_4 = 128; // 0x80 + field public static final int TIME_INTERLEAVE_MODE_2_8 = 256; // 0x100 + field public static final int TIME_INTERLEAVE_MODE_3_0 = 512; // 0x200 + field public static final int TIME_INTERLEAVE_MODE_3_1 = 1024; // 0x400 + field public static final int TIME_INTERLEAVE_MODE_3_2 = 2048; // 0x800 + field public static final int TIME_INTERLEAVE_MODE_3_4 = 4096; // 0x1000 + field public static final int TIME_INTERLEAVE_MODE_AUTO = 1; // 0x1 + field public static final int TIME_INTERLEAVE_MODE_UNDEFINED = 0; // 0x0 } public static class IsdbtFrontendSettings.Builder { method @NonNull public android.media.tv.tuner.frontend.IsdbtFrontendSettings build(); method @NonNull public android.media.tv.tuner.frontend.IsdbtFrontendSettings.Builder setBandwidth(int); - method @NonNull public android.media.tv.tuner.frontend.IsdbtFrontendSettings.Builder setCodeRate(int); + method @Deprecated @NonNull public android.media.tv.tuner.frontend.IsdbtFrontendSettings.Builder setCodeRate(int); method @Deprecated @IntRange(from=1) @NonNull public android.media.tv.tuner.frontend.IsdbtFrontendSettings.Builder setFrequency(int); method @IntRange(from=1) @NonNull public android.media.tv.tuner.frontend.IsdbtFrontendSettings.Builder setFrequencyLong(long); method @NonNull public android.media.tv.tuner.frontend.IsdbtFrontendSettings.Builder setGuardInterval(int); + method @NonNull public android.media.tv.tuner.frontend.IsdbtFrontendSettings.Builder setLayerSettings(@NonNull android.media.tv.tuner.frontend.IsdbtFrontendSettings.IsdbtLayerSettings[]); method @NonNull public android.media.tv.tuner.frontend.IsdbtFrontendSettings.Builder setMode(int); - method @NonNull public android.media.tv.tuner.frontend.IsdbtFrontendSettings.Builder setModulation(int); + method @Deprecated @NonNull public android.media.tv.tuner.frontend.IsdbtFrontendSettings.Builder setModulation(int); + method @NonNull public android.media.tv.tuner.frontend.IsdbtFrontendSettings.Builder setPartialReceptionFlag(int); method @NonNull public android.media.tv.tuner.frontend.IsdbtFrontendSettings.Builder setServiceAreaId(int); } + public static final class IsdbtFrontendSettings.IsdbtLayerSettings { + method @NonNull public static android.media.tv.tuner.frontend.IsdbtFrontendSettings.IsdbtLayerSettings.Builder builder(); + method public int getCodeRate(); + method public int getModulation(); + method @IntRange(from=0, to=255) public int getNumOfSegment(); + method public int getTimeInterleaveMode(); + } + + public static final class IsdbtFrontendSettings.IsdbtLayerSettings.Builder { + method @NonNull public android.media.tv.tuner.frontend.IsdbtFrontendSettings.IsdbtLayerSettings build(); + method @NonNull public android.media.tv.tuner.frontend.IsdbtFrontendSettings.IsdbtLayerSettings.Builder setCodeRate(int); + method @NonNull public android.media.tv.tuner.frontend.IsdbtFrontendSettings.IsdbtLayerSettings.Builder setModulation(int); + method @IntRange(from=0, to=255) @NonNull public android.media.tv.tuner.frontend.IsdbtFrontendSettings.IsdbtLayerSettings.Builder setNumOfSegment(int); + method @NonNull public android.media.tv.tuner.frontend.IsdbtFrontendSettings.IsdbtLayerSettings.Builder setTimeInterleaveMode(int); + } + public interface OnTuneEventListener { method public void onTuneEvent(int); field public static final int SIGNAL_LOCKED = 0; // 0x0 diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java index c484309f63fca..c666255c749a3 100644 --- a/media/java/android/media/tv/tuner/Tuner.java +++ b/media/java/android/media/tv/tuner/Tuner.java @@ -749,6 +749,12 @@ public class Tuner implements AutoCloseable { * supported in Tuner 1.1 or higher version. Unsupported version will cause no-op. Use {@link * TunerVersionChecker#getTunerVersion()} to get the version information. * + *

Tuning with {@link + * android.media.tv.tuner.frontend.IsdbtFrontendSettings.PartialReceptionFlag} or {@link + * android.media.tv.tuner.frontend.IsdbtFrontendSettings.IsdbtLayerSettings} is only supported + * in Tuner 2.0 or higher version. Unsupported version will cause no-op. Use {@link + * TunerVersionChecker#getTunerVersion()} to get the version information. + * * @param settings Signal delivery information the frontend uses to * search and lock the signal. * @return result status of tune operation. @@ -803,6 +809,12 @@ public class Tuner implements AutoCloseable { * supported in Tuner 1.1 or higher version. Unsupported version will cause no-op. Use {@link * TunerVersionChecker#getTunerVersion()} to get the version information. * + * *

Scanning with {@link + * android.media.tv.tuner.frontend.IsdbtFrontendSettings.PartialReceptionFlag} or {@link + * android.media.tv.tuner.frontend.IsdbtFrontendSettings.IsdbtLayerSettings} is only supported + * in Tuner 2.0 or higher version. Unsupported version will cause no-op. Use {@link + * TunerVersionChecker#getTunerVersion()} to get the version information. + * * @param settings A {@link FrontendSettings} to configure the frontend. * @param scanType The scan type. * @throws SecurityException if the caller does not have appropriate permissions. diff --git a/media/java/android/media/tv/tuner/frontend/FrontendStatus.java b/media/java/android/media/tv/tuner/frontend/FrontendStatus.java index 53adc75696bb8..31f1a63e12ba6 100644 --- a/media/java/android/media/tv/tuner/frontend/FrontendStatus.java +++ b/media/java/android/media/tv/tuner/frontend/FrontendStatus.java @@ -52,7 +52,8 @@ public class FrontendStatus { FRONTEND_STATUS_TYPE_ISDBT_SEGMENTS, FRONTEND_STATUS_TYPE_TS_DATA_RATES, FRONTEND_STATUS_TYPE_MODULATIONS_EXT, FRONTEND_STATUS_TYPE_ROLL_OFF, FRONTEND_STATUS_TYPE_IS_MISO_ENABLED, FRONTEND_STATUS_TYPE_IS_LINEAR, - FRONTEND_STATUS_TYPE_IS_SHORT_FRAMES_ENABLED}) + FRONTEND_STATUS_TYPE_IS_SHORT_FRAMES_ENABLED, FRONTEND_STATUS_TYPE_ISDBT_MODE, + FRONTEND_STATUS_TYPE_ISDBT_PARTIAL_RECEPTION_FLAG}) @Retention(RetentionPolicy.SOURCE) public @interface FrontendStatusType {} @@ -242,6 +243,16 @@ public class FrontendStatus { */ public static final int FRONTEND_STATUS_TYPE_IS_SHORT_FRAMES_ENABLED = android.hardware.tv.tuner.FrontendStatusType.IS_SHORT_FRAMES; + /** + * ISDB-T mode. Only supported in Tuner HAL 2.0 or higher. + */ + public static final int FRONTEND_STATUS_TYPE_ISDBT_MODE = + android.hardware.tv.tuner.FrontendStatusType.ISDBT_MODE; + /** + * ISDB-T partial reception flag. Only supported in Tuner HAL 2.0 or higher. + */ + public static final int FRONTEND_STATUS_TYPE_ISDBT_PARTIAL_RECEPTION_FLAG = + android.hardware.tv.tuner.FrontendStatusType.ISDBT_PARTIAL_RECEPTION_FLAG; /** @hide */ @IntDef(value = { @@ -337,7 +348,21 @@ public class FrontendStatus { DvbcFrontendSettings.TIME_INTERLEAVE_MODE_8_16, DvbcFrontendSettings.TIME_INTERLEAVE_MODE_128_2, DvbcFrontendSettings.TIME_INTERLEAVE_MODE_128_3, - DvbcFrontendSettings.TIME_INTERLEAVE_MODE_128_4}) + DvbcFrontendSettings.TIME_INTERLEAVE_MODE_128_4, + IsdbtFrontendSettings.TIME_INTERLEAVE_MODE_UNDEFINED, + IsdbtFrontendSettings.TIME_INTERLEAVE_MODE_AUTO, + IsdbtFrontendSettings.TIME_INTERLEAVE_MODE_1_0, + IsdbtFrontendSettings.TIME_INTERLEAVE_MODE_1_4, + IsdbtFrontendSettings.TIME_INTERLEAVE_MODE_1_8, + IsdbtFrontendSettings.TIME_INTERLEAVE_MODE_1_16, + IsdbtFrontendSettings.TIME_INTERLEAVE_MODE_2_0, + IsdbtFrontendSettings.TIME_INTERLEAVE_MODE_2_2, + IsdbtFrontendSettings.TIME_INTERLEAVE_MODE_2_4, + IsdbtFrontendSettings.TIME_INTERLEAVE_MODE_2_8, + IsdbtFrontendSettings.TIME_INTERLEAVE_MODE_3_0, + IsdbtFrontendSettings.TIME_INTERLEAVE_MODE_3_1, + IsdbtFrontendSettings.TIME_INTERLEAVE_MODE_3_2, + IsdbtFrontendSettings.TIME_INTERLEAVE_MODE_3_4}) @Retention(RetentionPolicy.SOURCE) public @interface FrontendInterleaveMode {} @@ -466,7 +491,8 @@ public class FrontendStatus { private Boolean mIsMisoEnabled; private Boolean mIsLinear; private Boolean mIsShortFrames; - + private Integer mIsdbtMode; + private Integer mIsdbtPartialReceptionFlag; // Constructed and fields set by JNI code. private FrontendStatus() { @@ -940,6 +966,40 @@ public class FrontendStatus { return mIsShortFrames; } + /** + * Gets ISDB-T mode. + * + *

This query is only supported by Tuner HAL 2.0 or higher. Unsupported version or if HAL + * doesn't return ISDB-T mode status will throw IllegalStateException. Use + * {@link TunerVersionChecker#getTunerVersion()} to check the version. + */ + @IsdbtFrontendSettings.Mode + public int getIsdbtMode() { + TunerVersionChecker.checkHigherOrEqualVersionTo( + TunerVersionChecker.TUNER_VERSION_2_0, "IsdbtMode status"); + if (mIsdbtMode == null) { + throw new IllegalStateException("IsdbtMode status is empty"); + } + return mIsdbtMode; + } + + /** + * Gets ISDB-T partial reception flag. + * + *

This query is only supported by Tuner HAL 2.0 or higher. Unsupported version or if HAL + * doesn't return partial reception flag status will throw IllegalStateException. Use + * {@link TunerVersionChecker#getTunerVersion()} to check the version. + */ + @IsdbtFrontendSettings.PartialReceptionFlag + public int getIsdbtPartialReceptionFlag() { + TunerVersionChecker.checkHigherOrEqualVersionTo( + TunerVersionChecker.TUNER_VERSION_2_0, "IsdbtPartialReceptionFlag status"); + if (mIsdbtPartialReceptionFlag == null) { + throw new IllegalStateException("IsdbtPartialReceptionFlag status is empty"); + } + return mIsdbtPartialReceptionFlag; + } + /** * Information of each tuning Physical Layer Pipes. */ diff --git a/media/java/android/media/tv/tuner/frontend/IsdbtFrontendCapabilities.java b/media/java/android/media/tv/tuner/frontend/IsdbtFrontendCapabilities.java index ffebc5a668c54..768dedbcfcf6b 100644 --- a/media/java/android/media/tv/tuner/frontend/IsdbtFrontendCapabilities.java +++ b/media/java/android/media/tv/tuner/frontend/IsdbtFrontendCapabilities.java @@ -17,6 +17,7 @@ package android.media.tv.tuner.frontend; import android.annotation.SystemApi; +import android.media.tv.tuner.TunerVersionChecker; /** * ISDBT Capabilities. @@ -30,14 +31,21 @@ public class IsdbtFrontendCapabilities extends FrontendCapabilities { private final int mModulationCap; private final int mCodeRateCap; private final int mGuardIntervalCap; + private final int mTimeInterleaveCap; + private final boolean mIsSegmentAutoSupported; + private final boolean mIsFullSegmentSupported; private IsdbtFrontendCapabilities(int modeCap, int bandwidthCap, int modulationCap, - int codeRateCap, int guardIntervalCap) { + int codeRateCap, int guardIntervalCap, int timeInterleaveCap, + boolean isSegmentAutoSupported, boolean isFullSegmentSupported) { mModeCap = modeCap; mBandwidthCap = bandwidthCap; mModulationCap = modulationCap; mCodeRateCap = codeRateCap; mGuardIntervalCap = guardIntervalCap; + mTimeInterleaveCap = timeInterleaveCap; + mIsSegmentAutoSupported = isSegmentAutoSupported; + mIsFullSegmentSupported = isFullSegmentSupported; } /** @@ -75,4 +83,35 @@ public class IsdbtFrontendCapabilities extends FrontendCapabilities { public int getGuardIntervalCapability() { return mGuardIntervalCap; } + /** + * Gets time interleave mode capability. + * + *

This query is only supported by Tuner HAL 2.0 or higher. Unsupported version will + * return {@link IsdbtFrontendSettings#TIME_INTERLEAVE_MODE_UNDEFINED}. + * Use {@link TunerVersionChecker#getTunerVersion()} to check the version. + */ + @IsdbtFrontendSettings.TimeInterleaveMode + public int getTimeInterleaveModeCapability() { + return mTimeInterleaveCap; + } + /** + * If auto segment is supported or not. + * + *

This query is only supported by Tuner HAL 2.0 or higher. Unsupported version will + * return false. + * Use {@link TunerVersionChecker#getTunerVersion()} to check the version. + */ + public boolean isSegmentAutoSupported() { + return mIsSegmentAutoSupported; + } + /** + * If full segment is supported or not. + * + *

This query is only supported by Tuner HAL 2.0 or higher. Unsupported version will + * return false. + * Use {@link TunerVersionChecker#getTunerVersion()} to check the version. + */ + public boolean isFullSegmentSupported() { + return mIsFullSegmentSupported; + } } diff --git a/media/java/android/media/tv/tuner/frontend/IsdbtFrontendSettings.java b/media/java/android/media/tv/tuner/frontend/IsdbtFrontendSettings.java index d34b643b1890e..1090f33ff73e6 100644 --- a/media/java/android/media/tv/tuner/frontend/IsdbtFrontendSettings.java +++ b/media/java/android/media/tv/tuner/frontend/IsdbtFrontendSettings.java @@ -19,12 +19,16 @@ package android.media.tv.tuner.frontend; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; +import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.hardware.tv.tuner.FrontendIsdbtBandwidth; import android.hardware.tv.tuner.FrontendIsdbtMode; import android.hardware.tv.tuner.FrontendIsdbtModulation; +import android.hardware.tv.tuner.FrontendIsdbtPartialReceptionFlag; +import android.hardware.tv.tuner.FrontendIsdbtTimeInterleaveMode; +import android.media.tv.tuner.TunerVersionChecker; import android.media.tv.tuner.frontend.DvbtFrontendSettings.CodeRate; - +import android.util.Log; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -127,30 +131,145 @@ public class IsdbtFrontendSettings extends FrontendSettings { */ public static final int BANDWIDTH_6MHZ = FrontendIsdbtBandwidth.BANDWIDTH_6MHZ; - private final int mModulation; + /** @hide */ + @IntDef(flag = true, prefix = "PARTIAL_RECEPTION_FLAG_", + value = {PARTIAL_RECEPTION_FLAG_UNDEFINED, PARTIAL_RECEPTION_FLAG_FALSE, + PARTIAL_RECEPTION_FLAG_TRUE}) + @Retention(RetentionPolicy.SOURCE) + public @interface PartialReceptionFlag {} + + /** + * Partial Reception Flag undefined. + */ + public static final int PARTIAL_RECEPTION_FLAG_UNDEFINED = + FrontendIsdbtPartialReceptionFlag.UNDEFINED; + /** + * Partial Reception Flag false. + */ + public static final int PARTIAL_RECEPTION_FLAG_FALSE = FrontendIsdbtPartialReceptionFlag.FALSE; + /** + * Partial Reception Flag true. + */ + public static final int PARTIAL_RECEPTION_FLAG_TRUE = FrontendIsdbtPartialReceptionFlag.TRUE; + + /** @hide */ + @IntDef(flag = true, prefix = "TIME_INTERLEAVE_MODE_", + value = {TIME_INTERLEAVE_MODE_UNDEFINED, TIME_INTERLEAVE_MODE_AUTO, + TIME_INTERLEAVE_MODE_1_0, TIME_INTERLEAVE_MODE_1_4, TIME_INTERLEAVE_MODE_1_8, + TIME_INTERLEAVE_MODE_1_16, TIME_INTERLEAVE_MODE_2_0, TIME_INTERLEAVE_MODE_2_2, + TIME_INTERLEAVE_MODE_2_4, TIME_INTERLEAVE_MODE_2_8, TIME_INTERLEAVE_MODE_3_0, + TIME_INTERLEAVE_MODE_3_1, TIME_INTERLEAVE_MODE_3_2, TIME_INTERLEAVE_MODE_3_4}) + @Retention(RetentionPolicy.SOURCE) + public @interface TimeInterleaveMode {} + + /** + * Time Interleave Mode undefined. + */ + public static final int TIME_INTERLEAVE_MODE_UNDEFINED = + FrontendIsdbtTimeInterleaveMode.UNDEFINED; + /** + * Hardware is able to detect and set time interleave mode automatically + */ + public static final int TIME_INTERLEAVE_MODE_AUTO = FrontendIsdbtTimeInterleaveMode.AUTO; + /** + * Time Interleave Mode 1: 0. + */ + public static final int TIME_INTERLEAVE_MODE_1_0 = + FrontendIsdbtTimeInterleaveMode.INTERLEAVE_1_0; + /** + * Time Interleave Mode 1: 4. + */ + public static final int TIME_INTERLEAVE_MODE_1_4 = + FrontendIsdbtTimeInterleaveMode.INTERLEAVE_1_4; + /** + * Time Interleave Mode 1: 8. + */ + public static final int TIME_INTERLEAVE_MODE_1_8 = + FrontendIsdbtTimeInterleaveMode.INTERLEAVE_1_8; + /** + * Time Interleave Mode 1: 16. + */ + public static final int TIME_INTERLEAVE_MODE_1_16 = + FrontendIsdbtTimeInterleaveMode.INTERLEAVE_1_16; + /** + * Time Interleave Mode 2: 0. + */ + public static final int TIME_INTERLEAVE_MODE_2_0 = + FrontendIsdbtTimeInterleaveMode.INTERLEAVE_2_0; + /** + * Time Interleave Mode 2: 2. + */ + public static final int TIME_INTERLEAVE_MODE_2_2 = + FrontendIsdbtTimeInterleaveMode.INTERLEAVE_2_2; + /** + * Time Interleave Mode 2: 4. + */ + public static final int TIME_INTERLEAVE_MODE_2_4 = + FrontendIsdbtTimeInterleaveMode.INTERLEAVE_2_4; + /** + * Time Interleave Mode 2: 8. + */ + public static final int TIME_INTERLEAVE_MODE_2_8 = + FrontendIsdbtTimeInterleaveMode.INTERLEAVE_2_8; + /** + * Time Interleave Mode 3: 0. + */ + public static final int TIME_INTERLEAVE_MODE_3_0 = + FrontendIsdbtTimeInterleaveMode.INTERLEAVE_3_0; + /** + * Time Interleave Mode 3: 1. + */ + public static final int TIME_INTERLEAVE_MODE_3_1 = + FrontendIsdbtTimeInterleaveMode.INTERLEAVE_3_1; + /** + * Time Interleave Mode 3: 2. + */ + public static final int TIME_INTERLEAVE_MODE_3_2 = + FrontendIsdbtTimeInterleaveMode.INTERLEAVE_3_2; + /** + * Time Interleave Mode 3: 4. + */ + public static final int TIME_INTERLEAVE_MODE_3_4 = + FrontendIsdbtTimeInterleaveMode.INTERLEAVE_3_4; + private final int mBandwidth; private final int mMode; - private final int mCodeRate; private final int mGuardInterval; private final int mServiceAreaId; + private final IsdbtLayerSettings[] mLayerSettings; + private final int mPartialReceptionFlag; + private static final String TAG = "IsdbtFrontendSettings"; - private IsdbtFrontendSettings(long frequency, int modulation, int bandwidth, int mode, - int codeRate, int guardInterval, int serviceAreaId) { + private IsdbtFrontendSettings(long frequency, int bandwidth, int mode, int guardInterval, + int serviceAreaId, IsdbtLayerSettings[] layerSettings, int partialReceptionFlag) { super(frequency); - mModulation = modulation; mBandwidth = bandwidth; mMode = mode; - mCodeRate = codeRate; mGuardInterval = guardInterval; mServiceAreaId = serviceAreaId; + mLayerSettings = new IsdbtLayerSettings[layerSettings.length]; + for (int i = 0; i < layerSettings.length; i++) { + mLayerSettings[i] = layerSettings[i]; + } + mPartialReceptionFlag = partialReceptionFlag; } /** * Gets Modulation. + * + *

This query is only supported in Tuner 1.1 or lowner version. Unsupported version will + * return {@link MODULATION_UNDEFINED}. + * Use {@link TunerVersionChecker#getTunerVersion()} to get the version information. + * @deprecated Use {@link #getLayerSettings()} and {@link IsdbtLayerSettings#getModulation()} + * instead. */ + @Deprecated @Modulation public int getModulation() { - return mModulation; + if (TunerVersionChecker.isHigherOrEqualVersionTo(TunerVersionChecker.TUNER_VERSION_2_0)) { + return MODULATION_UNDEFINED; + } + return mLayerSettings.length > 0 ? mLayerSettings[0].getModulation() : MODULATION_UNDEFINED; } /** * Gets Bandwidth. @@ -168,10 +287,21 @@ public class IsdbtFrontendSettings extends FrontendSettings { } /** * Gets Code rate. + * + *

This query is only supported in Tuner 1.1 or lowner version. Unsupported version will + * return {@link DvbtFrontendSettings#CODERATE_UNDEFINED}. + * Use {@link TunerVersionChecker#getTunerVersion()} to get the version information. + * @deprecated Use {@link #getLayerSettings()} and {@link IsdbtLayerSettings#getCodeRate()} + * instead. */ + @Deprecated @CodeRate public int getCodeRate() { - return mCodeRate; + if (TunerVersionChecker.isHigherOrEqualVersionTo(TunerVersionChecker.TUNER_VERSION_2_0)) { + return DvbtFrontendSettings.CODERATE_UNDEFINED; + } + return mLayerSettings.length > 0 ? mLayerSettings[0].getCodeRate() + : DvbtFrontendSettings.CODERATE_UNDEFINED; } /** * Gets Guard Interval. @@ -186,6 +316,29 @@ public class IsdbtFrontendSettings extends FrontendSettings { public int getServiceAreaId() { return mServiceAreaId; } + /** + * Gets ISDB-T Layer Settings. + * + *

This query is only supported in Tuner 2.0 or higher version. Unsupported version will + * return an empty array. + * Use {@link TunerVersionChecker#getTunerVersion()} to get the version information. + */ + @SuppressLint("ArrayReturn") + @NonNull + public IsdbtLayerSettings[] getLayerSettings() { + return mLayerSettings; + } + /** + * Gets ISDB-T Partial Reception Flag. + * + *

This query is only supported in Tuner 2.0 or higher version. Unsupported version will + * return {@link PARTIALRECEPTIONFLAG_UNDEFINED}. + * Use {@link TunerVersionChecker#getTunerVersion()} to get the version information. + */ + @PartialReceptionFlag + public int getPartialReceptionFlag() { + return mPartialReceptionFlag; + } /** * Creates a builder for {@link IsdbtFrontendSettings}. @@ -200,12 +353,12 @@ public class IsdbtFrontendSettings extends FrontendSettings { */ public static class Builder { private long mFrequency = 0; - private int mModulation = MODULATION_UNDEFINED; private int mBandwidth = BANDWIDTH_UNDEFINED; private int mMode = MODE_UNDEFINED; - private int mCodeRate = DvbtFrontendSettings.CODERATE_UNDEFINED; private int mGuardInterval = DvbtFrontendSettings.GUARD_INTERVAL_UNDEFINED; private int mServiceAreaId = 0; + private IsdbtLayerSettings[] mLayerSettings = {}; + private int mPartialReceptionFlag = PARTIAL_RECEPTION_FLAG_UNDEFINED; private Builder() { } @@ -238,11 +391,28 @@ public class IsdbtFrontendSettings extends FrontendSettings { /** * Sets Modulation. * + *

This configuration is only supported in Tuner 1.1 or lowner version. Unsupported + * version will cause no-op. Use {@link TunerVersionChecker#getTunerVersion()} to get the + * version information. + * *

Default value is {@link #MODULATION_UNDEFINED}. */ + @Deprecated @NonNull public Builder setModulation(@Modulation int modulation) { - mModulation = modulation; + if (TunerVersionChecker.checkHigherOrEqualVersionTo( + TunerVersionChecker.TUNER_VERSION_2_0, "setModulation")) { + Log.d(TAG, "Use IsdbtLayerSettings on HAL 2.0 or higher"); + } else { + IsdbtLayerSettings.Builder layerBuilder = IsdbtLayerSettings.builder(); + layerBuilder.setModulation(modulation); + if (mLayerSettings.length == 0) { + mLayerSettings = new IsdbtLayerSettings[1]; + } else { + layerBuilder.setCodeRate(mLayerSettings[0].getCodeRate()); + } + mLayerSettings[0] = layerBuilder.build(); + } return this; } /** @@ -268,11 +438,28 @@ public class IsdbtFrontendSettings extends FrontendSettings { /** * Sets Code rate. * + *

This configuration is only supported in Tuner 1.1 or lowner version. Unsupported + * version will cause no-op. Use {@link TunerVersionChecker#getTunerVersion()} to get the + * version information. + * *

Default value is {@link DvbtFrontendSettings#CODERATE_UNDEFINED}. */ + @Deprecated @NonNull public Builder setCodeRate(@DvbtFrontendSettings.CodeRate int codeRate) { - mCodeRate = codeRate; + if (TunerVersionChecker.checkHigherOrEqualVersionTo( + TunerVersionChecker.TUNER_VERSION_2_0, "setModulation")) { + Log.d(TAG, "Use IsdbtLayerSettings on HAL 2.0 or higher"); + } else { + IsdbtLayerSettings.Builder layerBuilder = IsdbtLayerSettings.builder(); + layerBuilder.setCodeRate(codeRate); + if (mLayerSettings.length == 0) { + mLayerSettings = new IsdbtLayerSettings[1]; + } else { + layerBuilder.setModulation(mLayerSettings[0].getModulation()); + } + mLayerSettings[0] = layerBuilder.build(); + } return this; } /** @@ -295,14 +482,52 @@ public class IsdbtFrontendSettings extends FrontendSettings { mServiceAreaId = serviceAreaId; return this; } + /** + * Sets ISDB-T Layer Settings. + * + *

This configuration is only supported in Tuner 2.0 or higher version. Unsupported + * version will cause no-op. Use {@link TunerVersionChecker#getTunerVersion()} to get the + * version information. + * + *

Default value is an empty array. + */ + @NonNull + public Builder setLayerSettings( + @SuppressLint("ArrayReturn") @NonNull IsdbtLayerSettings[] layerSettings) { + if (TunerVersionChecker.checkHigherOrEqualVersionTo( + TunerVersionChecker.TUNER_VERSION_2_0, "setLayerSettings")) { + mLayerSettings = new IsdbtLayerSettings[layerSettings.length]; + for (int i = 0; i < layerSettings.length; i++) { + mLayerSettings[i] = layerSettings[i]; + } + } + return this; + } + /** + * Sets ISDB-T Partial Reception Flag. + * + *

This configuration is only supported in Tuner 2.0 or higher version. Unsupported + * version will cause no-op. Use {@link TunerVersionChecker#getTunerVersion()} to get the + * version information. + * + *

Default value is {@link PARTIALRECEPTIONFLAG_UNDEFINED}. + */ + @NonNull + public Builder setPartialReceptionFlag(@PartialReceptionFlag int flag) { + if (TunerVersionChecker.checkHigherOrEqualVersionTo( + TunerVersionChecker.TUNER_VERSION_2_0, "setPartialReceptionFlag")) { + mPartialReceptionFlag = flag; + } + return this; + } /** * Builds a {@link IsdbtFrontendSettings} object. */ @NonNull public IsdbtFrontendSettings build() { - return new IsdbtFrontendSettings(mFrequency, mModulation, mBandwidth, mMode, mCodeRate, - mGuardInterval, mServiceAreaId); + return new IsdbtFrontendSettings(mFrequency, mBandwidth, mMode, mGuardInterval, + mServiceAreaId, mLayerSettings, mPartialReceptionFlag); } } @@ -310,4 +535,123 @@ public class IsdbtFrontendSettings extends FrontendSettings { public int getType() { return FrontendSettings.TYPE_ISDBT; } + + /** + * Layer Settings for ISDB-T Frontend. + * + *

Layer Settings is only supported in Tuner 2.0 or higher version. Use + * {@link TunerVersionChecker#getTunerVersion()} to get the version information. + */ + public static final class IsdbtLayerSettings { + private final int mModulation; + private final int mTimeInterleaveMode; + private final int mCodeRate; + private final int mNumOfSegment; + + private IsdbtLayerSettings( + int modulation, int timeInterleaveMode, int codeRate, int numOfSegment) { + mModulation = modulation; + mTimeInterleaveMode = timeInterleaveMode; + mCodeRate = codeRate; + mNumOfSegment = numOfSegment; + } + + /** + * Gets Modulation. + */ + @Modulation + public int getModulation() { + return mModulation; + } + /** + * Gets Time Interleave Mode. + */ + @TimeInterleaveMode + public int getTimeInterleaveMode() { + return mTimeInterleaveMode; + } + /** + * Gets Code rate. + */ + @CodeRate + public int getCodeRate() { + return mCodeRate; + } + /** + * Gets Number of Segment. + */ + @IntRange(from = 0, to = 0xff) + public int getNumOfSegment() { + return mNumOfSegment; + } + + /** + * Creates a builder for {@link IsdbtLayerSettings}. + */ + @NonNull + public static Builder builder() { + return new Builder(); + } + + /** + * Builder for {@link IsdbtLayerSettings}. + */ + public static final class Builder { + private int mModulation = MODULATION_UNDEFINED; + private int mTimeInterleaveMode = TIME_INTERLEAVE_MODE_UNDEFINED; + private int mCodeRate = DvbtFrontendSettings.CODERATE_UNDEFINED; + private int mNumOfSegment = 0; + + private Builder() {} + + /** + * Sets modulation. + * + *

Default value is {@link #MODULATION_UNDEFINED}. + */ + @NonNull + public Builder setModulation(@Modulation int modulation) { + mModulation = modulation; + return this; + } + /** + * Sets time interleave mode. + * + *

Default value is {@link #TIME_INTERLEAVE_MODE_UNDEFINED}. + */ + @NonNull + public Builder setTimeInterleaveMode(@TimeInterleaveMode int mode) { + mTimeInterleaveMode = mode; + return this; + } + /** + * Sets code rate. + */ + @NonNull + public Builder setCodeRate(@DvbtFrontendSettings.CodeRate int codeRate) { + mCodeRate = codeRate; + return this; + } + /** + * Sets number of segment. + * + *

Default value is 0. + */ + @NonNull + @IntRange(from = 0, to = 0xff) + public Builder setNumOfSegment(int numOfSegment) { + mNumOfSegment = numOfSegment; + return this; + } + + /** + * Builds a {@link IsdbtLayerSettings} object. + */ + @NonNull + public IsdbtLayerSettings build() { + return new IsdbtLayerSettings( + mModulation, mTimeInterleaveMode, mCodeRate, mNumOfSegment); + } + } + } } diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp index 35f1875193abf..24eea30952779 100644 --- a/media/jni/android_media_tv_Tuner.cpp +++ b/media/jni/android_media_tv_Tuner.cpp @@ -123,9 +123,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -268,9 +271,12 @@ using ::aidl::android::hardware::tv::tuner::FrontendIsdbsStreamIdType; using ::aidl::android::hardware::tv::tuner::FrontendIsdbtBandwidth; using ::aidl::android::hardware::tv::tuner::FrontendIsdbtCoderate; using ::aidl::android::hardware::tv::tuner::FrontendIsdbtGuardInterval; +using ::aidl::android::hardware::tv::tuner::FrontendIsdbtLayerSettings; using ::aidl::android::hardware::tv::tuner::FrontendIsdbtMode; using ::aidl::android::hardware::tv::tuner::FrontendIsdbtModulation; +using ::aidl::android::hardware::tv::tuner::FrontendIsdbtPartialReceptionFlag; using ::aidl::android::hardware::tv::tuner::FrontendIsdbtSettings; +using ::aidl::android::hardware::tv::tuner::FrontendIsdbtTimeInterleaveMode; using ::aidl::android::hardware::tv::tuner::FrontendModulation; using ::aidl::android::hardware::tv::tuner::FrontendModulationStatus; using ::aidl::android::hardware::tv::tuner::FrontendRollOff; @@ -1355,16 +1361,19 @@ jobject JTuner::getIsdbsFrontendCaps(JNIEnv *env, FrontendCapabilities &caps) { jobject JTuner::getIsdbtFrontendCaps(JNIEnv *env, FrontendCapabilities &caps) { jclass clazz = env->FindClass("android/media/tv/tuner/frontend/IsdbtFrontendCapabilities"); - jmethodID capsInit = env->GetMethodID(clazz, "", "(IIIII)V"); + jmethodID capsInit = env->GetMethodID(clazz, "", "(IIIIIIZZ)V"); jint modeCap = caps.get().modeCap; jint bandwidthCap = caps.get().bandwidthCap; jint modulationCap = caps.get().modulationCap; jint coderateCap = caps.get().coderateCap; jint guardIntervalCap = caps.get().guardIntervalCap; + jint timeInterleaveCap = caps.get().timeInterleaveCap; + jboolean isSegmentAuto = caps.get().isSegmentAuto; + jboolean isFullSegment = caps.get().isFullSegment; return env->NewObject(clazz, capsInit, modeCap, bandwidthCap, modulationCap, coderateCap, - guardIntervalCap); + guardIntervalCap, timeInterleaveCap, isSegmentAuto, isFullSegment); } jobject JTuner::getDtmbFrontendCaps(JNIEnv *env, FrontendCapabilities &caps) { @@ -2336,6 +2345,13 @@ jobject JTuner::getFrontendStatus(jintArray types) { valid = true; break; } + case FrontendInterleaveMode::Tag::isdbt: { + in[0] = static_cast( + interleaving.get()); + env->SetIntArrayRegion(valObj, i, 1, in); + valid = true; + break; + } default: break; } @@ -2414,6 +2430,22 @@ jobject JTuner::getFrontendStatus(jintArray types) { env->SetObjectField(statusObj, field, newBooleanObj); break; } + case FrontendStatus::Tag::isdbtMode: { + jfieldID field = env->GetFieldID(clazz, "mIsdbtMode", "Ljava/lang/Integer;"); + jobject newIntegerObj = + env->NewObject(intClazz, initInt, s.get()); + env->SetObjectField(statusObj, field, newIntegerObj); + break; + } + case FrontendStatus::Tag::partialReceptionFlag: { + jfieldID field = + env->GetFieldID(clazz, "mIsdbtPartialReceptionFlag", "Ljava/lang/Integer;"); + jobject newIntegerObj = + env->NewObject(intClazz, initInt, + s.get()); + env->SetObjectField(statusObj, field, newIntegerObj); + break; + } default: { break; } @@ -2879,35 +2911,55 @@ static FrontendSettings getIsdbtFrontendSettings(JNIEnv *env, const jobject& set int64_t endFreq = getFrontendSettingsEndFreq(env, settings); FrontendSpectralInversion inversion = getFrontendSettingsSpectralInversion(env, settings); jclass clazz = env->FindClass("android/media/tv/tuner/frontend/IsdbtFrontendSettings"); - FrontendIsdbtModulation modulation = - static_cast( - env->GetIntField(settings, env->GetFieldID(clazz, "mModulation", "I"))); FrontendIsdbtBandwidth bandwidth = static_cast( env->GetIntField(settings, env->GetFieldID(clazz, "mBandwidth", "I"))); - FrontendIsdbtMode mode = - static_cast( - env->GetIntField(settings, env->GetFieldID(clazz, "mMode", "I"))); - FrontendIsdbtCoderate coderate = - static_cast( - env->GetIntField(settings, env->GetFieldID(clazz, "mCodeRate", "I"))); + FrontendIsdbtMode mode = static_cast( + env->GetIntField(settings, env->GetFieldID(clazz, "mMode", "I"))); FrontendIsdbtGuardInterval guardInterval = static_cast( env->GetIntField(settings, env->GetFieldID(clazz, "mGuardInterval", "I"))); int32_t serviceAreaId = env->GetIntField(settings, env->GetFieldID(clazz, "mServiceAreaId", "I")); + FrontendIsdbtPartialReceptionFlag partialReceptionFlag = + static_cast( + env->GetIntField(settings, + env->GetFieldID(clazz, "mPartialReceptionFlag", "I"))); FrontendIsdbtSettings frontendIsdbtSettings{ .frequency = freq, .endFrequency = endFreq, - .modulation = modulation, .bandwidth = bandwidth, .mode = mode, - .coderate = coderate, .guardInterval = guardInterval, .serviceAreaId = serviceAreaId, .inversion = inversion, + .partialReceptionFlag = partialReceptionFlag, }; + + jobjectArray layerSettings = reinterpret_cast( + env->GetObjectField(settings, + env->GetFieldID(clazz, "mLayerSettings", + "[Landroid/media/tv/tuner/frontend/" + "IsdbtFrontendSettings$IsdbtLayerSettings;"))); + int len = env->GetArrayLength(layerSettings); + jclass layerClazz = env->FindClass( + "android/media/tv/tuner/frontend/IsdbtFrontendSettings$IsdbtLayerSettings"); + frontendIsdbtSettings.layerSettings.resize(len); + for (int i = 0; i < len; i++) { + jobject layer = env->GetObjectArrayElement(layerSettings, i); + frontendIsdbtSettings.layerSettings[i].modulation = static_cast( + env->GetIntField(layer, env->GetFieldID(layerClazz, "mModulation", "I"))); + frontendIsdbtSettings.layerSettings[i].timeInterleave = + static_cast( + env->GetIntField(layer, + env->GetFieldID(layerClazz, "mTimeInterleaveMode", "I"))); + frontendIsdbtSettings.layerSettings[i].coderate = static_cast( + env->GetIntField(layer, env->GetFieldID(layerClazz, "mCodeRate", "I"))); + frontendIsdbtSettings.layerSettings[i].numOfSegment = + env->GetIntField(layer, env->GetFieldID(layerClazz, "mNumOfSegment", "I")); + } + frontendSettings.set(frontendIsdbtSettings); return frontendSettings; }