diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 93f6b20bee2a2..fc35905875c22 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -6467,6 +6467,7 @@ package android.media.tv.tuner { method public int getAvSyncHwId(@NonNull android.media.tv.tuner.filter.Filter); method public long getAvSyncTime(int); method @Nullable public java.util.List getAvailableFrontendInfos(); + method @Nullable public String getCurrentFrontendHardwardInfo(); method @Nullable public android.media.tv.tuner.DemuxCapabilities getDemuxCapabilities(); method @Nullable public android.media.tv.tuner.frontend.FrontendInfo getFrontendInfo(); method @Nullable public android.media.tv.tuner.frontend.FrontendStatus getFrontendStatus(@NonNull int[]); @@ -6631,6 +6632,10 @@ package android.media.tv.tuner.filter { method public boolean isPassthrough(); method public boolean useSecureMemory(); field public static final int AUDIO_STREAM_TYPE_AAC = 6; // 0x6 + field public static final int AUDIO_STREAM_TYPE_AAC_ADTS = 16; // 0x10 + field public static final int AUDIO_STREAM_TYPE_AAC_HE_ADTS = 18; // 0x12 + field public static final int AUDIO_STREAM_TYPE_AAC_HE_LATM = 19; // 0x13 + field public static final int AUDIO_STREAM_TYPE_AAC_LATM = 17; // 0x11 field public static final int AUDIO_STREAM_TYPE_AC3 = 7; // 0x7 field public static final int AUDIO_STREAM_TYPE_AC4 = 9; // 0x9 field public static final int AUDIO_STREAM_TYPE_DRA = 15; // 0xf @@ -6792,6 +6797,7 @@ package android.media.tv.tuner.filter { method @IntRange(from=0) public int getMpuSequenceNumber(); method public long getOffset(); method public long getPts(); + method public int getScIndexMask(); method public int getStreamId(); method public boolean isDtsPresent(); method public boolean isPrivateData(); @@ -7907,6 +7913,7 @@ package android.media.tv.tuner.frontend { method public void onScanStopped(); method public void onSignalTypeReported(int); method public void onSymbolRatesReported(@NonNull int[]); + method public default void onUnLocked(); } } diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java index 41f926520a13d..7c08913c82cdd 100644 --- a/media/java/android/media/tv/tuner/Tuner.java +++ b/media/java/android/media/tv/tuner/Tuner.java @@ -687,6 +687,7 @@ public class Tuner implements AutoCloseable { private native FrontendInfo nativeGetFrontendInfo(int id); private native Filter nativeOpenFilter(int type, int subType, long bufferSize); private native TimeFilter nativeOpenTimeFilter(); + private native String nativeGetFrontendHardwareInfo(); private native Lnb nativeOpenLnbByHandle(int handle); private native Lnb nativeOpenLnbByName(String name); @@ -1278,6 +1279,34 @@ public class Tuner implements AutoCloseable { return Arrays.asList(feInfoList); } + /** + * Gets the currently initialized and activated frontend hardware information. The return values + * would differ per device makers. E.g. RF chip version, Demod chip version, detailed status of + * dvbs blind scan, etc + * + *

This API is only supported by Tuner HAL 2.0 or higher. Unsupported version would return + * {@code null}. Use {@link TunerVersionChecker#getTunerVersion()} to check the version. + * + * @return The active frontend hardware information. {@code null} if the operation failed. + * @throws IllegalStateException if there is no active frontend currently. + */ + @Nullable + public String getCurrentFrontendHardwardInfo() { + mFrontendLock.lock(); + try { + if (!TunerVersionChecker.checkHigherOrEqualVersionTo( + TunerVersionChecker.TUNER_VERSION_2_0, "Get Frontend hardware info")) { + return null; + } + if (mFrontend == null) { + throw new IllegalStateException("frontend is not initialized"); + } + return nativeGetFrontendHardwareInfo(); + } finally { + mFrontendLock.unlock(); + } + } + /** @hide */ public FrontendInfo getFrontendInfoById(int id) { mFrontendLock.lock(); @@ -1353,6 +1382,24 @@ public class Tuner implements AutoCloseable { } } + private void onUnLocked() { + Log.d(TAG, "Wrote Stats Log for unlocked event from scanning."); + FrameworkStatsLog.write(FrameworkStatsLog.TV_TUNER_STATE_CHANGED, mUserId, + FrameworkStatsLog.TV_TUNER_STATE_CHANGED__STATE__LOCKED); + + synchronized (mScanCallbackLock) { + if (mScanCallbackExecutor != null && mScanCallback != null) { + mScanCallbackExecutor.execute(() -> { + synchronized (mScanCallbackLock) { + if (mScanCallback != null) { + mScanCallback.onUnLocked(); + } + } + }); + } + } + } + private void onScanStopped() { synchronized (mScanCallbackLock) { if (mScanCallbackExecutor != null && mScanCallback != null) { diff --git a/media/java/android/media/tv/tuner/filter/AvSettings.java b/media/java/android/media/tv/tuner/filter/AvSettings.java index ed04754365041..15811d2c4f115 100644 --- a/media/java/android/media/tv/tuner/filter/AvSettings.java +++ b/media/java/android/media/tv/tuner/filter/AvSettings.java @@ -107,7 +107,8 @@ public class AvSettings extends Settings { AUDIO_STREAM_TYPE_AAC, AUDIO_STREAM_TYPE_AC3, AUDIO_STREAM_TYPE_EAC3, AUDIO_STREAM_TYPE_AC4, AUDIO_STREAM_TYPE_DTS, AUDIO_STREAM_TYPE_DTS_HD, AUDIO_STREAM_TYPE_WMA, AUDIO_STREAM_TYPE_OPUS, AUDIO_STREAM_TYPE_VORBIS, - AUDIO_STREAM_TYPE_DRA}) + AUDIO_STREAM_TYPE_DRA, AUDIO_STREAM_TYPE_AAC_ADTS, AUDIO_STREAM_TYPE_AAC_LATM, + AUDIO_STREAM_TYPE_AAC_HE_ADTS, AUDIO_STREAM_TYPE_AAC_HE_LATM}) @Retention(RetentionPolicy.SOURCE) public @interface AudioStreamType {} @@ -182,6 +183,41 @@ public class AvSettings extends Settings { */ public static final int AUDIO_STREAM_TYPE_DRA = android.hardware.tv.tuner.AudioStreamType.DRA; + /* + * AAC with ADTS (Audio Data Transport Format). + * + * This API is only supported by Tuner HAL 2.0 or higher. Use + * {@link TunerVersionChecker#getTunerVersion()} to check the version. + */ + public static final int AUDIO_STREAM_TYPE_AAC_ADTS = + android.hardware.tv.tuner.AudioStreamType.AAC_ADTS; + + /* + * AAC with ADTS with LATM (Low-overhead MPEG-4 Audio Transport Multiplex). + * + * This API is only supported by Tuner HAL 2.0 or higher. Use + * {@link TunerVersionChecker#getTunerVersion()} to check the version. + */ + public static final int AUDIO_STREAM_TYPE_AAC_LATM = + android.hardware.tv.tuner.AudioStreamType.AAC_LATM; + + /* + * High-Efficiency AAC (HE-AAC) with ADTS (Audio Data Transport Format). + * + * This API is only supported by Tuner HAL 2.0 or higher. Use + * {@link TunerVersionChecker#getTunerVersion()} to check the version. + */ + public static final int AUDIO_STREAM_TYPE_AAC_HE_ADTS = + android.hardware.tv.tuner.AudioStreamType.AAC_HE_ADTS; + + /* + * High-Efficiency AAC (HE-AAC) with LATM (Low-overhead MPEG-4 Audio Transport Multiplex). + * + * This API is only supported by Tuner HAL 2.0 or higher. Use + * {@link TunerVersionChecker#getTunerVersion()} to check the version. + */ + public static final int AUDIO_STREAM_TYPE_AAC_HE_LATM = + android.hardware.tv.tuner.AudioStreamType.AAC_HE_LATM; private final boolean mIsPassthrough; private int mAudioStreamType = AUDIO_STREAM_TYPE_UNDEFINED; diff --git a/media/java/android/media/tv/tuner/filter/MediaEvent.java b/media/java/android/media/tv/tuner/filter/MediaEvent.java index 79d4062cfbbfa..d958db102f190 100644 --- a/media/java/android/media/tv/tuner/filter/MediaEvent.java +++ b/media/java/android/media/tv/tuner/filter/MediaEvent.java @@ -49,12 +49,14 @@ public class MediaEvent extends FilterEvent { private final long mDataId; private final int mMpuSequenceNumber; private final boolean mIsPrivateData; + private final int mScIndexMask; private final AudioDescriptor mExtraMetaData; // This constructor is used by JNI code only private MediaEvent(int streamId, boolean isPtsPresent, long pts, boolean isDtsPresent, long dts, long dataLength, long offset, LinearBlock buffer, boolean isSecureMemory, long dataId, - int mpuSequenceNumber, boolean isPrivateData, AudioDescriptor extraMetaData) { + int mpuSequenceNumber, boolean isPrivateData, int scIndexMask, + AudioDescriptor extraMetaData) { mStreamId = streamId; mIsPtsPresent = isPtsPresent; mPts = pts; @@ -67,6 +69,7 @@ public class MediaEvent extends FilterEvent { mDataId = dataId; mMpuSequenceNumber = mpuSequenceNumber; mIsPrivateData = isPrivateData; + mScIndexMask = scIndexMask; mExtraMetaData = extraMetaData; } @@ -193,6 +196,17 @@ public class MediaEvent extends FilterEvent { return mIsPrivateData; } + /** + * Gets SC (Start Code) index mask. + * + *

This API is only supported by Tuner HAL 2.0 or higher. Unsupported version would return + * {@code 0}. Use {@link TunerVersionChecker#getTunerVersion()} to check the version. + */ + @RecordSettings.ScIndexMask + public int getScIndexMask() { + return mScIndexMask; + } + /** * Gets audio extra metadata. */ diff --git a/media/java/android/media/tv/tuner/frontend/ScanCallback.java b/media/java/android/media/tv/tuner/frontend/ScanCallback.java index 8917050fcd241..6bbc13fe66f4b 100644 --- a/media/java/android/media/tv/tuner/frontend/ScanCallback.java +++ b/media/java/android/media/tv/tuner/frontend/ScanCallback.java @@ -36,6 +36,9 @@ public interface ScanCallback { */ void onLocked(); + /** Scan unlocked the signal. */ + default void onUnLocked() {} + /** Scan stopped. */ void onScanStopped(); diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp index 712add4ffc3c6..64eede5ef88fd 100644 --- a/media/jni/android_media_tv_Tuner.cpp +++ b/media/jni/android_media_tv_Tuner.cpp @@ -604,9 +604,11 @@ void FilterClientCallbackImpl::getMediaEvent(jobjectArray &arr, const int size, const DemuxFilterEvent &event) { JNIEnv *env = AndroidRuntime::getJNIEnv(); jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/MediaEvent"); - jmethodID eventInit = env->GetMethodID(eventClazz, "", - "(IZJZJJJLandroid/media/MediaCodec$LinearBlock;" - "ZJIZLandroid/media/tv/tuner/filter/AudioDescriptor;)V"); + jmethodID eventInit = env->GetMethodID( + eventClazz, + "", + "(IZJZJJJLandroid/media/MediaCodec$LinearBlock;" + "ZJIZILandroid/media/tv/tuner/filter/AudioDescriptor;)V"); jfieldID eventContext = env->GetFieldID(eventClazz, "mNativeContext", "J"); const DemuxFilterMediaEvent &mediaEvent = event.get(); @@ -639,10 +641,20 @@ void FilterClientCallbackImpl::getMediaEvent(jobjectArray &arr, const int size, jlong avDataId = mediaEvent.avDataId; jint mpuSequenceNumber = mediaEvent.mpuSequenceNumber; jboolean isPesPrivateData = mediaEvent.isPesPrivateData; + jint sc = 0; + if (mediaEvent.scIndexMask.getTag() == DemuxFilterScIndexMask::Tag::scIndex) { + sc = mediaEvent.scIndexMask.get(); + } else if (mediaEvent.scIndexMask.getTag() == DemuxFilterScIndexMask::Tag::scHevc) { + sc = mediaEvent.scIndexMask.get(); + } else if (mediaEvent.scIndexMask.getTag() == DemuxFilterScIndexMask::Tag::scAvc) { + sc = mediaEvent.scIndexMask.get(); + // Java uses the values defined by HIDL HAL. Left shift 4 bits. + sc = sc << 4; + } jobject obj = env->NewObject(eventClazz, eventInit, streamId, isPtsPresent, pts, isDtsPresent, dts, dataLength, offset, nullptr, isSecureMemory, avDataId, - mpuSequenceNumber, isPesPrivateData, audioDescriptor); + mpuSequenceNumber, isPesPrivateData, sc, audioDescriptor); uint64_t avSharedMemSize = mFilterClient->getAvSharedHandleInfo().size; if (mediaEvent.avMemory.fds.size() > 0 || mediaEvent.avDataId != 0 || @@ -1025,6 +1037,10 @@ void FrontendClientCallbackImpl::executeOnScanMessage( env->CallVoidMethod( frontend, env->GetMethodID(clazz, "onLocked", "()V")); + } else { + env->CallVoidMethod( + frontend, + env->GetMethodID(clazz, "onUnLocked", "()V")); } break; } @@ -1548,6 +1564,15 @@ jobject JTuner::getFrontendInfo(int id) { maxSymbolRate, acquireRange, exclusiveGroupId, statusCaps, jcaps); } +Result JTuner::getFrontendHardwareInfo(string &info) { + if (mFeClient == nullptr) { + ALOGE("frontend is not initialized"); + return Result::INVALID_STATE; + } + + return mFeClient->getHardwareInfo(info); +} + jobject JTuner::openLnbByHandle(int handle) { if (mTunerClient == nullptr) { return nullptr; @@ -1657,11 +1682,10 @@ int JTuner::setLnb(sp lnbClient) { } int JTuner::setLna(bool enable) { - if (mFeClient == nullptr) { - ALOGE("frontend client is not initialized"); - return (int)Result::INVALID_STATE; + if (mTunerClient == nullptr) { + return (int)Result::NOT_INITIALIZED; } - Result result = mFeClient->setLna(enable); + Result result = mTunerClient->setLna(enable); return (int)result; } @@ -4213,6 +4237,16 @@ static jobject android_media_tv_Tuner_open_shared_filter( return filterObj; } +static jstring android_media_tv_Tuner_get_frontend_hardware_info(JNIEnv *env, jobject thiz) { + sp tuner = getTuner(env, thiz); + string info; + Result r = tuner->getFrontendHardwareInfo(info); + if (r != Result::SUCCESS) { + return nullptr; + } + return env->NewStringUTF(info.data()); +} + static jint android_media_tv_Tuner_close_frontend(JNIEnv* env, jobject thiz, jint /* handle */) { sp tuner = getTuner(env, thiz); return tuner->closeFrontend(); @@ -4522,6 +4556,8 @@ static const JNINativeMethod gTunerMethods[] = { { "nativeOpenSharedFilter", "(Ljava/lang/String;)Landroid/media/tv/tuner/filter/SharedFilter;", (void *)android_media_tv_Tuner_open_shared_filter}, + { "nativeGetFrontendHardwareInfo","()Ljava/lang/String;", + (void *)android_media_tv_Tuner_get_frontend_hardware_info }, }; static const JNINativeMethod gFilterMethods[] = { diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h index 06e249212444d..4cad92b7d0f8a 100644 --- a/media/jni/android_media_tv_Tuner.h +++ b/media/jni/android_media_tv_Tuner.h @@ -200,6 +200,7 @@ struct JTuner : public RefBase { jint close(); jint closeFrontend(); jint closeDemux(); + Result getFrontendHardwareInfo(string& info); jweak getObject(); diff --git a/media/jni/tuner/FrontendClient.cpp b/media/jni/tuner/FrontendClient.cpp index 70309a0871633..0fdd8d8773f40 100644 --- a/media/jni/tuner/FrontendClient.cpp +++ b/media/jni/tuner/FrontendClient.cpp @@ -102,15 +102,6 @@ Result FrontendClient::setLnb(sp lnbClient) { return Result::INVALID_STATE; } -Result FrontendClient::setLna(bool bEnable) { - if (mTunerFrontend != nullptr) { - Status s = mTunerFrontend->setLna(bEnable); - return ClientHelper::getServiceSpecificErrorCode(s); - } - - return Result::INVALID_STATE; -} - int32_t FrontendClient::linkCiCamToFrontend(int32_t ciCamId) { int32_t ltsId = static_cast(Constant::INVALID_LTS_ID); @@ -143,6 +134,15 @@ Result FrontendClient::close() { return Result::INVALID_STATE; } +Result FrontendClient::getHardwareInfo(string& info) { + if (mTunerFrontend != nullptr) { + Status s = mTunerFrontend->getHardwareInfo(&info); + return ClientHelper::getServiceSpecificErrorCode(s); + } + + return Result::INVALID_STATE; +} + shared_ptr FrontendClient::getAidlFrontend() { return mTunerFrontend; } diff --git a/media/jni/tuner/FrontendClient.h b/media/jni/tuner/FrontendClient.h index 08c0b20d18ed9..77d909804cf05 100644 --- a/media/jni/tuner/FrontendClient.h +++ b/media/jni/tuner/FrontendClient.h @@ -98,11 +98,6 @@ public: */ Result setLnb(sp lnbClient); - /** - * Enable or Disable Low Noise Amplifier (LNA). - */ - Result setLna(bool bEnable); - /** * Link Frontend to the cicam with given id. * @@ -120,7 +115,13 @@ public: */ Result close(); + /** + * Get Frontend hardware info. + */ + Result getHardwareInfo(string& info); + int32_t getId(); + shared_ptr getAidlFrontend(); private: /** diff --git a/media/jni/tuner/TunerClient.cpp b/media/jni/tuner/TunerClient.cpp index 861d78d6c3eca..f917f016939ae 100644 --- a/media/jni/tuner/TunerClient.cpp +++ b/media/jni/tuner/TunerClient.cpp @@ -185,4 +185,13 @@ sp TunerClient::openSharedFilter(const string& filterToken, return nullptr; } +Result TunerClient::setLna(bool bEnable) { + if (mTunerService != nullptr) { + Status s = mTunerService->setLna(bEnable); + return ClientHelper::getServiceSpecificErrorCode(s); + } + + return Result::INVALID_STATE; +} + } // namespace android diff --git a/media/jni/tuner/TunerClient.h b/media/jni/tuner/TunerClient.h index 3e59e26dea818..37b8ee1526a59 100644 --- a/media/jni/tuner/TunerClient.h +++ b/media/jni/tuner/TunerClient.h @@ -127,6 +127,11 @@ public: */ sp openSharedFilter(const string& filterToken, sp cb); + /** + * Enable or Disable Low Noise Amplifier (LNA). + */ + Result setLna(bool bEnable); + private: /** * An AIDL Tuner Service Singleton assigned at the first time the Tuner Client