Tuner JNI: setLnb and close()

Bug: 139308734
Test: mmm
Change-Id: I48ead59a638d83d2bfd9d8edabb0858715f0d473
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index d331126..50af60a 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -353,13 +353,16 @@
     @Override
     public void close() {
         if (mFrontendHandle != null) {
-            nativeCloseFrontendByHandle(mFrontendHandle);
+            int res = nativeCloseFrontend(mFrontendHandle);
+            if (res != Tuner.RESULT_SUCCESS) {
+                TunerUtils.throwExceptionForResult(res, "failed to close frontend");
+            }
             mTunerResourceManager.releaseFrontend(mFrontendHandle, mClientId);
             mFrontendHandle = null;
             mFrontend = null;
         }
         if (mLnb != null) {
-            releaseLnb();
+            mLnb.close();
         }
         if (!mDescramblers.isEmpty()) {
             for (Map.Entry<Integer, Descrambler> d : mDescramblers.entrySet()) {
@@ -374,6 +377,14 @@
             }
             mFilters.clear();
         }
+        if (mDemuxHandle != null) {
+            int res = nativeCloseDemux(mDemuxHandle);
+            if (res != Tuner.RESULT_SUCCESS) {
+                TunerUtils.throwExceptionForResult(res, "failed to close demux");
+            }
+            mTunerResourceManager.releaseDemux(mDemuxHandle, mClientId);
+            mFrontendHandle = null;
+        }
         TunerUtils.throwExceptionForResult(nativeClose(), "failed to close tuner");
     }
 
@@ -425,6 +436,8 @@
 
     private static native DemuxCapabilities nativeGetDemuxCapabilities();
 
+    private native int nativeCloseDemux(int handle);
+    private native int nativeCloseFrontend(int handle);
     private native int nativeClose();
 
 
@@ -545,10 +558,11 @@
     @Result
     public int tune(@NonNull FrontendSettings settings) {
         mFrontendType = settings.getType();
-        checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND);
-
-        mFrontendInfo = null;
-        return nativeTune(settings.getType(), settings);
+        if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND)) {
+            mFrontendInfo = null;
+            return nativeTune(settings.getType(), settings);
+        }
+        return RESULT_UNAVAILABLE;
     }
 
     /**
@@ -584,11 +598,13 @@
                             + "started.");
         }
         mFrontendType = settings.getType();
-        checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND);
-        mScanCallback = scanCallback;
-        mScanCallbackExecutor = executor;
-        mFrontendInfo = null;
-        return nativeScan(settings.getType(), settings, scanType);
+        if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND)) {
+            mScanCallback = scanCallback;
+            mScanCallbackExecutor = executor;
+            mFrontendInfo = null;
+            return nativeScan(settings.getType(), settings, scanType);
+        }
+        return RESULT_UNAVAILABLE;
     }
 
     /**
@@ -671,7 +687,9 @@
      * @return the id of hardware A/V sync.
      */
     public int getAvSyncHwId(@NonNull Filter filter) {
-        checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX);
+        if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+            return INVALID_AV_SYNC_ID;
+        }
         Integer id = nativeGetAvSyncHwId(filter);
         return id == null ? INVALID_AV_SYNC_ID : id;
     }
@@ -686,7 +704,9 @@
      * @return the current timestamp of hardware A/V sync.
      */
     public long getAvSyncTime(int avSyncHwId) {
-        checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX);
+        if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+            return INVALID_TIMESTAMP;
+        }
         Long time = nativeGetAvSyncTime(avSyncHwId);
         return time == null ? INVALID_TIMESTAMP : time;
     }
@@ -702,8 +722,10 @@
      */
     @Result
     public int connectCiCam(int ciCamId) {
-        checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX);
-        return nativeConnectCiCam(ciCamId);
+        if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+            return nativeConnectCiCam(ciCamId);
+        }
+        return RESULT_UNAVAILABLE;
     }
 
     /**
@@ -715,8 +737,10 @@
      */
     @Result
     public int disconnectCiCam() {
-        checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX);
-        return nativeDisconnectCiCam();
+        if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+            return nativeDisconnectCiCam();
+        }
+        return RESULT_UNAVAILABLE;
     }
 
     /**
@@ -726,7 +750,9 @@
      */
     @Nullable
     public FrontendInfo getFrontendInfo() {
-        checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND);
+        if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND)) {
+            return null;
+        }
         if (mFrontend == null) {
             throw new IllegalStateException("frontend is not initialized");
         }
@@ -861,7 +887,9 @@
     public Filter openFilter(@Type int mainType, @Subtype int subType,
             @BytesLong long bufferSize, @CallbackExecutor @Nullable Executor executor,
             @Nullable FilterCallback cb) {
-        checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX);
+        if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+            return null;
+        }
         Filter filter = nativeOpenFilter(
                 mainType, TunerUtils.getFilterSubtype(mainType, subType), bufferSize);
         if (filter != null) {
@@ -891,12 +919,15 @@
         Objects.requireNonNull(executor, "executor must not be null");
         Objects.requireNonNull(cb, "LnbCallback must not be null");
         if (mLnb != null) {
+            mLnb.setCallback(executor, cb, this);
             return mLnb;
         }
         if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_LNB) && mLnb != null) {
             mLnb.setCallback(executor, cb, this);
+            setLnb(mLnb);
+            return mLnb;
         }
-        return mLnb;
+        return null;
     }
 
     /**
@@ -922,6 +953,7 @@
             }
             mLnb = newLnb;
             mLnb.setCallback(executor, cb, this);
+            setLnb(mLnb);
         }
         return mLnb;
     }
@@ -944,7 +976,9 @@
      */
     @Nullable
     public TimeFilter openTimeFilter() {
-        checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX);
+        if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+            return null;
+        }
         return nativeOpenTimeFilter();
     }
 
@@ -956,6 +990,9 @@
     @RequiresPermission(android.Manifest.permission.ACCESS_TV_DESCRAMBLER)
     @Nullable
     public Descrambler openDescrambler() {
+        if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+            return null;
+        }
         return requestDescrambler();
     }
 
@@ -976,7 +1013,9 @@
             @NonNull OnRecordStatusChangedListener l) {
         Objects.requireNonNull(executor, "executor must not be null");
         Objects.requireNonNull(l, "OnRecordStatusChangedListener must not be null");
-        checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX);
+        if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+            return null;
+        }
         DvrRecorder dvr = nativeOpenDvrRecorder(bufferSize);
         dvr.setListener(executor, l);
         return dvr;
@@ -999,7 +1038,9 @@
             @NonNull OnPlaybackStatusChangedListener l) {
         Objects.requireNonNull(executor, "executor must not be null");
         Objects.requireNonNull(l, "OnPlaybackStatusChangedListener must not be null");
-        checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX);
+        if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+            return null;
+        }
         DvrPlayback dvr = nativeOpenDvrPlayback(bufferSize);
         dvr.setListener(executor, l);
         return dvr;
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index 614fe73..ab311c0e 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -1130,7 +1130,7 @@
         lnbIds = ids;
         res = r;
     });
-    if (res != Result::SUCCESS || mLnbIds.size() == 0) {
+    if (res != Result::SUCCESS || lnbIds.size() == 0) {
         ALOGW("Lnb isn't available");
         return NULL;
     }
@@ -1797,6 +1797,22 @@
     return statusObj;
 }
 
+jint JTuner::closeFrontend() {
+    Result r = Result::SUCCESS;
+    if (mFe != NULL) {
+        r = mFe->close();
+    }
+    return (jint) r;
+}
+
+jint JTuner::closeDemux() {
+    Result r = Result::SUCCESS;
+    if (mDemux != NULL) {
+        r = mDemux->close();
+    }
+    return (jint) r;
+}
+
 }  // namespace android
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -3199,6 +3215,16 @@
     return (jint) tuner->close();
 }
 
+static jint android_media_tv_Tuner_close_demux(JNIEnv* env, jobject thiz, jint /* handle */) {
+    sp<JTuner> tuner = getTuner(env, thiz);
+    return tuner->closeDemux();
+}
+
+static jint android_media_tv_Tuner_close_frontend(JNIEnv* env, jobject thiz, jint /* handle */) {
+    sp<JTuner> tuner = getTuner(env, thiz);
+    return tuner->closeFrontend();
+}
+
 static jint android_media_tv_Tuner_attach_filter(JNIEnv *env, jobject dvr, jobject filter) {
     sp<Dvr> dvrSp = getDvr(env, dvr);
     if (dvrSp == NULL) {
@@ -3526,7 +3552,9 @@
     { "nativeGetDemuxCapabilities", "()Landroid/media/tv/tuner/DemuxCapabilities;",
             (void *)android_media_tv_Tuner_get_demux_caps },
     { "nativeOpenDemuxByhandle", "(I)I", (void *)android_media_tv_Tuner_open_demux },
-    {"nativeClose", "()I", (void *)android_media_tv_Tuner_close_tuner },
+    { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_tuner },
+    { "nativeCloseFrontend", "(I)I", (void *)android_media_tv_Tuner_close_frontend },
+    { "nativeCloseDemux", "(I)I", (void *)android_media_tv_Tuner_close_demux },
 };
 
 static const JNINativeMethod gFilterMethods[] = {
diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h
index 750b146..3da78ac 100644
--- a/media/jni/android_media_tv_Tuner.h
+++ b/media/jni/android_media_tv_Tuner.h
@@ -191,6 +191,8 @@
     jobject getFrontendStatus(jintArray types);
     Result openDemux();
     jint close();
+    jint closeFrontend();
+    jint closeDemux();
 
 protected:
     virtual ~JTuner();