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 {