Implement Tuner.openLnbByName()
Bug: 149786702
Test: mmm;
Change-Id: I37fd9dd6ebc15962db70f81887184135974268e1
diff --git a/media/java/android/media/tv/tuner/Lnb.java b/media/java/android/media/tv/tuner/Lnb.java
index 7932dcb..ea06632 100644
--- a/media/java/android/media/tv/tuner/Lnb.java
+++ b/media/java/android/media/tv/tuner/Lnb.java
@@ -156,7 +156,7 @@
private long mNativeContext;
- Lnb(int id) {
+ private Lnb(int id) {
mId = id;
}
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index bcbc12b..08a33f1 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -43,7 +43,11 @@
import android.media.tv.tuner.frontend.FrontendStatus.FrontendStatusType;
import android.media.tv.tuner.frontend.OnTuneEventListener;
import android.media.tv.tuner.frontend.ScanCallback;
+import android.media.tv.tunerresourcemanager.ResourceClientProfile;
+import android.media.tv.tunerresourcemanager.TunerLnbRequest;
+import android.media.tv.tunerresourcemanager.TunerResourceManager;
import android.os.Handler;
+import android.os.HandlerExecutor;
import android.os.Looper;
import android.os.Message;
@@ -67,6 +71,7 @@
private static final String TAG = "MediaTvTuner";
private static final boolean DEBUG = false;
+ private static final int MSG_RESOURCE_LOST = 1;
private static final int MSG_ON_FILTER_EVENT = 2;
private static final int MSG_ON_FILTER_STATUS = 3;
private static final int MSG_ON_LNB_EVENT = 4;
@@ -93,6 +98,8 @@
}
private final Context mContext;
+ private final TunerResourceManager mTunerResourceManager;
+ private final int mClientId;
private List<Integer> mFrontendIds;
private Frontend mFrontend;
@@ -102,6 +109,7 @@
private List<Integer> mLnbIds;
private Lnb mLnb;
+ private Integer mLnbId;
@Nullable
private OnTuneEventListener mOnTuneEventListener;
@Nullable
@@ -115,6 +123,15 @@
@Nullable
private Executor mOnResourceLostListenerExecutor;
+
+ private final TunerResourceManager.ResourcesReclaimListener mResourceListener =
+ new TunerResourceManager.ResourcesReclaimListener() {
+ @Override
+ public void onReclaimResources() {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_RESOURCE_LOST));
+ }
+ };
+
/**
* Constructs a Tuner instance.
*
@@ -127,6 +144,14 @@
@TvInputService.PriorityHintUseCaseType int useCase) {
nativeSetup();
mContext = context;
+ mTunerResourceManager = (TunerResourceManager)
+ context.getSystemService(Context.TV_TUNER_RESOURCE_MGR_SERVICE);
+
+ int[] clientId = new int[1];
+ ResourceClientProfile profile = new ResourceClientProfile(tvInputSessionId, useCase);
+ mTunerResourceManager.registerClientProfile(
+ profile, new HandlerExecutor(mHandler), mResourceListener, clientId);
+ mClientId = clientId[0];
}
/**
@@ -226,6 +251,7 @@
private native List<Integer> nativeGetLnbIds();
private native Lnb nativeOpenLnbById(int id);
+ private native Lnb nativeOpenLnbByName(String name);
private native Descrambler nativeOpenDescrambler();
@@ -275,6 +301,14 @@
}
break;
}
+ case MSG_RESOURCE_LOST: {
+ if (mOnResourceLostListener != null
+ && mOnResourceLostListenerExecutor != null) {
+ mOnResourceLostListenerExecutor.execute(
+ () -> mOnResourceLostListener.onResourceLost(Tuner.this));
+ }
+ break;
+ }
default:
// fall through
}
@@ -698,7 +732,10 @@
Objects.requireNonNull(executor, "executor must not be null");
Objects.requireNonNull(cb, "LnbCallback must not be null");
TunerUtils.checkTunerPermission(mContext);
- return openLnbByName(null, executor, cb);
+ if (mLnbId == null && !requestLnb()) {
+ return null;
+ }
+ return nativeOpenLnbById(mLnbId);
}
/**
@@ -714,11 +751,21 @@
@Nullable
public Lnb openLnbByName(@NonNull String name, @CallbackExecutor @NonNull Executor executor,
@NonNull LnbCallback cb) {
+ Objects.requireNonNull(name, "LNB name must not be null");
Objects.requireNonNull(executor, "executor must not be null");
Objects.requireNonNull(cb, "LnbCallback must not be null");
TunerUtils.checkTunerPermission(mContext);
- // TODO: use resource manager to get LNB ID.
- return new Lnb(0);
+ return nativeOpenLnbByName(name);
+ }
+
+ private boolean requestLnb() {
+ int[] lnbId = new int[1];
+ TunerLnbRequest request = new TunerLnbRequest(mClientId);
+ boolean granted = mTunerResourceManager.requestLnb(request, lnbId);
+ if (granted) {
+ mLnbId = lnbId[0];
+ }
+ return granted;
}
/**
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index 01f068a..679f18a 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -1072,6 +1072,37 @@
return lnbObj;
}
+jobject JTuner::openLnbByName(jstring name) {
+ JNIEnv *env = AndroidRuntime::getJNIEnv();
+ std::string lnbName(env->GetStringUTFChars(name, nullptr));
+ sp<ILnb> iLnbSp;
+ Result res;
+ LnbId id;
+ mTuner->openLnbByName(lnbName, [&](Result r, LnbId lnbId, const sp<ILnb>& lnb) {
+ res = r;
+ iLnbSp = lnb;
+ id = lnbId;
+ });
+ if (res != Result::SUCCESS || iLnbSp == nullptr) {
+ ALOGE("Failed to open lnb");
+ return NULL;
+ }
+ mLnb = iLnbSp;
+ sp<LnbCallback> lnbCb = new LnbCallback(mObject, id);
+ mLnb->setCallback(lnbCb);
+
+ jobject lnbObj = env->NewObject(
+ env->FindClass("android/media/tv/tuner/Lnb"),
+ gFields.lnbInitID,
+ id);
+
+ sp<Lnb> lnbSp = new Lnb(iLnbSp, lnbObj);
+ lnbSp->incStrong(lnbObj);
+ env->SetLongField(lnbObj, gFields.lnbContext, (jlong) lnbSp.get());
+
+ return lnbObj;
+}
+
int JTuner::tune(const FrontendSettings& settings) {
if (mFe == NULL) {
ALOGE("frontend is not initialized");
@@ -1872,8 +1903,7 @@
jclass lnbClazz = env->FindClass("android/media/tv/tuner/Lnb");
gFields.lnbContext = env->GetFieldID(lnbClazz, "mNativeContext", "J");
- gFields.lnbInitID =
- env->GetMethodID(lnbClazz, "<init>", "(I)V");
+ gFields.lnbInitID = env->GetMethodID(lnbClazz, "<init>", "(I)V");
jclass filterClazz = env->FindClass("android/media/tv/tuner/filter/Filter");
gFields.filterContext = env->GetFieldID(filterClazz, "mNativeContext", "J");
@@ -1996,6 +2026,12 @@
return tuner->openLnbById(id);
}
+static jobject android_media_tv_Tuner_open_lnb_by_name(JNIEnv *env, jobject thiz, jstring name) {
+ sp<JTuner> tuner = getTuner(env, thiz);
+ return tuner->openLnbByName(name);
+}
+
+
static jobject android_media_tv_Tuner_open_filter(
JNIEnv *env, jobject thiz, jint type, jint subType, jlong bufferSize) {
sp<JTuner> tuner = getTuner(env, thiz);
@@ -2888,6 +2924,8 @@
(void *)android_media_tv_Tuner_get_lnb_ids },
{ "nativeOpenLnbById", "(I)Landroid/media/tv/tuner/Lnb;",
(void *)android_media_tv_Tuner_open_lnb_by_id },
+ { "nativeOpenLnbByName", "(Ljava/lang/String;)Landroid/media/tv/tuner/Lnb;",
+ (void *)android_media_tv_Tuner_open_lnb_by_name },
{ "nativeOpenDescrambler", "()Landroid/media/tv/tuner/Descrambler;",
(void *)android_media_tv_Tuner_open_descrambler },
{ "nativeOpenDvrRecorder", "(J)Landroid/media/tv/tuner/dvr/DvrRecorder;",
diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h
index d3298a8..3b8682f 100644
--- a/media/jni/android_media_tv_Tuner.h
+++ b/media/jni/android_media_tv_Tuner.h
@@ -180,6 +180,7 @@
int setLna(bool enable);
jobject getLnbIds();
jobject openLnbById(int id);
+ jobject openLnbByName(jstring name);
jobject openFilter(DemuxFilterType type, int bufferSize);
jobject openTimeFilter();
jobject openDescrambler();