Support frontend status readiness query.
The caller could use it to check whether frontend status is ready to
read or not.
Bug: 171540820
Fix: 171540820
Test: atest android.media.tv.tuner.cts on AIDL and HILD HALs
Change-Id: I55610e02412d6043e7fab91d1a2bf187a8e5e3ba
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 94c5c9c..5b79fcc 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -6607,6 +6607,7 @@
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[]);
+ method @Nullable public android.media.tv.tuner.frontend.FrontendStatusReadiness[] getFrontendStatusReadiness(@NonNull int[]);
method @IntRange(from=0xffffffff) public int getMaxNumberOfFrontends(int);
method @RequiresPermission("android.permission.TUNER_RESOURCE_ACCESS") public boolean hasUnusedFrontend(int);
method public boolean isLowestPriority(int);
@@ -7851,6 +7852,16 @@
method public boolean isLocked();
}
+ public class FrontendStatusReadiness {
+ method public int getStatusReadiness();
+ method public int getStatusType();
+ field public static final int FRONTEND_STATUS_READINESS_STABLE = 3; // 0x3
+ field public static final int FRONTEND_STATUS_READINESS_UNAVAILABLE = 1; // 0x1
+ field public static final int FRONTEND_STATUS_READINESS_UNDEFINED = 0; // 0x0
+ field public static final int FRONTEND_STATUS_READINESS_UNSTABLE = 2; // 0x2
+ field public static final int FRONTEND_STATUS_READINESS_UNSUPPORTED = 4; // 0x4
+ }
+
public class Isdbs3FrontendCapabilities extends android.media.tv.tuner.frontend.FrontendCapabilities {
method public int getCodeRateCapability();
method public int getModulationCapability();
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index 3157375..be114d4 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -47,6 +47,7 @@
import android.media.tv.tuner.frontend.FrontendSettings;
import android.media.tv.tuner.frontend.FrontendStatus;
import android.media.tv.tuner.frontend.FrontendStatus.FrontendStatusType;
+import android.media.tv.tuner.frontend.FrontendStatusReadiness;
import android.media.tv.tuner.frontend.OnTuneEventListener;
import android.media.tv.tuner.frontend.ScanCallback;
import android.media.tv.tunerresourcemanager.ResourceClientProfile;
@@ -61,9 +62,7 @@
import android.os.Message;
import android.os.Process;
import android.util.Log;
-
import com.android.internal.util.FrameworkStatsLog;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;
@@ -1005,6 +1004,7 @@
private native int nativeRemoveOutputPid(int pid);
private native Lnb nativeOpenLnbByHandle(int handle);
private native Lnb nativeOpenLnbByName(String name);
+ private native FrontendStatusReadiness[] nativeGetFrontendStatusReadiness(int[] statusTypes);
private native Descrambler nativeOpenDescramblerByHandle(int handle);
private native int nativeOpenDemuxByhandle(int handle);
@@ -1595,6 +1595,38 @@
}
/**
+ * Gets Frontend Status Readiness statuses for given status types.
+ *
+ * <p>This API is only supported by Tuner HAL 2.0 or higher. Unsupported versions would cause
+ * no-op. Use {@link TunerVersionChecker#getTunerVersion()} to check the version.
+ *
+ * @param statusTypes an array of status types.
+ *
+ * @return an array of current readiness states. {@code null} if the operation failed or
+ * unsupported versions.
+ * @throws IllegalStateException if there is no active frontend currently.
+ */
+ @Nullable
+ @SuppressLint("ArrayReturn")
+ @SuppressWarnings("NullableCollection")
+ public FrontendStatusReadiness[] getFrontendStatusReadiness(
+ @NonNull @FrontendStatusType int[] statusTypes) {
+ mFrontendLock.lock();
+ try {
+ if (!TunerVersionChecker.checkHigherOrEqualVersionTo(
+ TunerVersionChecker.TUNER_VERSION_2_0, "Remove output PID")) {
+ return null;
+ }
+ if (mFrontend == null) {
+ throw new IllegalStateException("frontend is not initialized");
+ }
+ return nativeGetFrontendStatusReadiness(statusTypes);
+ } finally {
+ mFrontendLock.unlock();
+ }
+ }
+
+ /**
* Gets the currently initialized and activated frontend information. To get all the available
* frontend info on the device, use {@link getAvailableFrontendInfos()}.
*
diff --git a/media/java/android/media/tv/tuner/frontend/FrontendStatusReadiness.java b/media/java/android/media/tv/tuner/frontend/FrontendStatusReadiness.java
new file mode 100644
index 0000000..52527b3
--- /dev/null
+++ b/media/java/android/media/tv/tuner/frontend/FrontendStatusReadiness.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2022 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.frontend;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.media.tv.tuner.frontend.FrontendStatus.FrontendStatusType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * A class contains the Frontend Status Readiness of a given type.
+ *
+ * @hide
+ */
+@SystemApi
+public class FrontendStatusReadiness {
+ /** @hide */
+ @IntDef({FRONTEND_STATUS_READINESS_UNDEFINED, FRONTEND_STATUS_READINESS_UNAVAILABLE,
+ FRONTEND_STATUS_READINESS_UNSTABLE, FRONTEND_STATUS_READINESS_STABLE,
+ FRONTEND_STATUS_READINESS_UNSUPPORTED})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Readiness {}
+
+ /**
+ * The FrontendStatus readiness status for the given FrontendStatusType is undefined.
+ */
+ public static final int FRONTEND_STATUS_READINESS_UNDEFINED =
+ android.hardware.tv.tuner.FrontendStatusReadiness.UNDEFINED;
+
+ /**
+ * The FrontendStatus for the given FrontendStatusType is currently unavailable.
+ */
+ public static final int FRONTEND_STATUS_READINESS_UNAVAILABLE =
+ android.hardware.tv.tuner.FrontendStatusReadiness.UNAVAILABLE;
+
+ /**
+ * The FrontendStatus for the given FrontendStatusType is ready to read, but it’s unstable.
+ */
+ public static final int FRONTEND_STATUS_READINESS_UNSTABLE =
+ android.hardware.tv.tuner.FrontendStatusReadiness.UNSTABLE;
+
+ /**
+ * The FrontendStatus for the given FrontendStatusType is ready to read, and it’s stable.
+ */
+ public static final int FRONTEND_STATUS_READINESS_STABLE =
+ android.hardware.tv.tuner.FrontendStatusReadiness.STABLE;
+
+ /**
+ * The FrontendStatus for the given FrontendStatusType is not supported.
+ */
+ public static final int FRONTEND_STATUS_READINESS_UNSUPPORTED =
+ android.hardware.tv.tuner.FrontendStatusReadiness.UNSUPPORTED;
+
+ @FrontendStatusType private int mFrontendStatusType;
+ @Readiness private int mStatusReadiness;
+
+ private FrontendStatusReadiness(int type, int readiness) {
+ mFrontendStatusType = type;
+ mStatusReadiness = readiness;
+ }
+
+ /**
+ * Gets the frontend status type.
+ */
+ @FrontendStatusType
+ public int getStatusType() {
+ return mFrontendStatusType;
+ }
+ /**
+ * Gets the frontend status readiness.
+ */
+ @Readiness
+ public int getStatusReadiness() {
+ return mStatusReadiness;
+ }
+}
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index 41f3a67..68dd8d0 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -1631,6 +1631,36 @@
return (jint)mFeClient->removeOutputPid(pid);
}
+jobjectArray JTuner::getFrontendStatusReadiness(jintArray types) {
+ if (mFeClient == nullptr) {
+ ALOGE("frontend is not initialized");
+ return nullptr;
+ }
+
+ JNIEnv *env = AndroidRuntime::getJNIEnv();
+ jsize size = env->GetArrayLength(types);
+ jint intTypes[size];
+ env->GetIntArrayRegion(types, 0, size, intTypes);
+ std::vector<FrontendStatusType> v;
+ for (int i = 0; i < size; i++) {
+ v.push_back(static_cast<FrontendStatusType>(intTypes[i]));
+ }
+
+ vector<FrontendStatusReadiness> readiness = mFeClient->getStatusReadiness(v);
+ if (readiness.size() < size) {
+ return nullptr;
+ }
+
+ jclass clazz = env->FindClass("android/media/tv/tuner/frontend/FrontendStatusReadiness");
+ jmethodID init = env->GetMethodID(clazz, "<init>", "(II)V");
+ jobjectArray valObj = env->NewObjectArray(size, clazz, nullptr);
+ for (int i = 0; i < size; i++) {
+ jobject readinessObj = env->NewObject(clazz, init, intTypes[i], readiness[i]);
+ env->SetObjectArrayElement(valObj, i, readinessObj);
+ }
+ return valObj;
+}
+
jobject JTuner::openLnbByHandle(int handle) {
if (mTunerClient == nullptr) {
return nullptr;
@@ -4389,6 +4419,12 @@
return tuner->removeOutputPid(pid);
}
+static jobjectArray android_media_tv_Tuner_get_frontend_status_readiness(JNIEnv *env, jobject thiz,
+ jintArray types) {
+ sp<JTuner> tuner = getTuner(env, thiz);
+ return tuner->getFrontendStatusReadiness(types);
+}
+
static jint android_media_tv_Tuner_close_frontend(JNIEnv* env, jobject thiz, jint /* handle */) {
sp<JTuner> tuner = getTuner(env, thiz);
return tuner->closeFrontend();
@@ -4710,6 +4746,9 @@
(void *)android_media_tv_Tuner_get_maximum_frontends },
{ "nativeRemoveOutputPid", "(I)I",
(void *)android_media_tv_Tuner_remove_output_pid },
+ { "nativeGetFrontendStatusReadiness",
+ "([I)[Landroid/media/tv/tuner/frontend/FrontendStatusReadiness;",
+ (void *)android_media_tv_Tuner_get_frontend_status_readiness },
};
static const JNINativeMethod gFilterMethods[] = {
diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h
index e9475dc..03e7fa9 100644
--- a/media/jni/android_media_tv_Tuner.h
+++ b/media/jni/android_media_tv_Tuner.h
@@ -206,6 +206,7 @@
jint setMaxNumberOfFrontends(int32_t frontendType, int32_t maxNumber);
int32_t getMaxNumberOfFrontends(int32_t frontendType);
jint removeOutputPid(int32_t pid);
+ jobjectArray getFrontendStatusReadiness(jintArray types);
jweak getObject();
diff --git a/media/jni/tuner/FrontendClient.cpp b/media/jni/tuner/FrontendClient.cpp
index bea0342..c6337ec 100644
--- a/media/jni/tuner/FrontendClient.cpp
+++ b/media/jni/tuner/FrontendClient.cpp
@@ -152,6 +152,16 @@
return Result::INVALID_STATE;
}
+vector<FrontendStatusReadiness> FrontendClient::getStatusReadiness(
+ const std::vector<FrontendStatusType>& statusTypes) {
+ vector<FrontendStatusReadiness> readiness;
+ if (mTunerFrontend != nullptr) {
+ mTunerFrontend->getFrontendStatusReadiness(statusTypes, &readiness);
+ }
+
+ return readiness;
+}
+
shared_ptr<ITunerFrontend> FrontendClient::getAidlFrontend() {
return mTunerFrontend;
}
diff --git a/media/jni/tuner/FrontendClient.h b/media/jni/tuner/FrontendClient.h
index c6838c8..85f6d56 100644
--- a/media/jni/tuner/FrontendClient.h
+++ b/media/jni/tuner/FrontendClient.h
@@ -35,6 +35,7 @@
using ::aidl::android::hardware::tv::tuner::FrontendScanType;
using ::aidl::android::hardware::tv::tuner::FrontendSettings;
using ::aidl::android::hardware::tv::tuner::FrontendStatus;
+using ::aidl::android::hardware::tv::tuner::FrontendStatusReadiness;
using ::aidl::android::hardware::tv::tuner::FrontendStatusType;
using ::aidl::android::hardware::tv::tuner::FrontendType;
using ::aidl::android::hardware::tv::tuner::Result;
@@ -125,6 +126,12 @@
*/
Result removeOutputPid(int32_t pid);
+ /**
+ * Gets Frontend Status Readiness statuses for given status types.
+ */
+ vector<FrontendStatusReadiness> getStatusReadiness(
+ const std::vector<FrontendStatusType>& types);
+
int32_t getId();
shared_ptr<ITunerFrontend> getAidlFrontend();