Merge "Tuner JNI: demux" into rvc-dev
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index 7a684b3..c79e72d 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -216,8 +216,8 @@
     private native int nativeSetLnb(int lnbId);
     private native int nativeSetLna(boolean enable);
     private native FrontendStatus nativeGetFrontendStatus(int[] statusTypes);
-    private native int nativeGetAvSyncHwId(Filter filter);
-    private native long nativeGetAvSyncTime(int avSyncId);
+    private native Integer nativeGetAvSyncHwId(Filter filter);
+    private native Long nativeGetAvSyncTime(int avSyncId);
     private native int nativeConnectCiCam(int ciCamId);
     private native int nativeDisconnectCiCam();
     private native FrontendInfo nativeGetFrontendInfo(int id);
@@ -463,7 +463,8 @@
     @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER)
     public int getAvSyncHwId(@NonNull Filter filter) {
         TunerUtils.checkTunerPermission(mContext);
-        return nativeGetAvSyncHwId(filter);
+        Integer id = nativeGetAvSyncHwId(filter);
+        return id == null ? TunerConstants.INVALID_AV_SYNC_ID : id;
     }
 
     /**
@@ -478,7 +479,8 @@
     @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER)
     public long getAvSyncTime(int avSyncHwId) {
         TunerUtils.checkTunerPermission(mContext);
-        return nativeGetAvSyncTime(avSyncHwId);
+        Long time = nativeGetAvSyncTime(avSyncHwId);
+        return time == null ? TunerConstants.TIMESTAMP_UNAVAILABLE : time;
     }
 
     /**
diff --git a/media/java/android/media/tv/tuner/TunerConstants.java b/media/java/android/media/tv/tuner/TunerConstants.java
index 82af658..6d89962 100644
--- a/media/java/android/media/tv/tuner/TunerConstants.java
+++ b/media/java/android/media/tv/tuner/TunerConstants.java
@@ -46,6 +46,19 @@
      * Invalid AV Sync ID.
      */
     public static final int INVALID_AV_SYNC_ID = Constants.Constant.INVALID_AV_SYNC_ID;
+    /**
+     * Timestamp is unavailable.
+     *
+     * <p>Returned by {@link android.media.tv.tuner.filter.TimeFilter#getSourceTime()},
+     * {@link android.media.tv.tuner.filter.TimeFilter#getTimeStamp()}, or
+     * {@link Tuner#getAvSyncTime(int)} when the requested timestamp is not available.
+     *
+     * @see android.media.tv.tuner.filter.TimeFilter#getSourceTime()
+     * @see android.media.tv.tuner.filter.TimeFilter#getTimeStamp()
+     * @see Tuner#getAvSyncTime(int)
+     * @hide
+     */
+    public static final long TIMESTAMP_UNAVAILABLE = -1L;
 
     /** @hide */
     @IntDef(prefix = "SCAN_TYPE_", value = {SCAN_TYPE_UNDEFINED, SCAN_TYPE_AUTO, SCAN_TYPE_BLIND})
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index 5c39f29..e68ccfa 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -119,7 +119,6 @@
 using ::android::hardware::tv::tuner::V1_0::ITuner;
 using ::android::hardware::tv::tuner::V1_0::PlaybackSettings;
 using ::android::hardware::tv::tuner::V1_0::RecordSettings;
-using ::android::hardware::tv::tuner::V1_0::Result;
 
 struct fields_t {
     jfieldID tunerContext;
@@ -845,22 +844,85 @@
     return (int)result;
 }
 
-bool JTuner::openDemux() {
+Result JTuner::openDemux() {
     if (mTuner == nullptr) {
-        return false;
+        return Result::NOT_INITIALIZED;
     }
     if (mDemux != nullptr) {
-        return true;
+        return Result::SUCCESS;
     }
-    mTuner->openDemux([&](Result, uint32_t demuxId, const sp<IDemux>& demux) {
+    Result res;
+    mTuner->openDemux([&](Result r, uint32_t demuxId, const sp<IDemux>& demux) {
         mDemux = demux;
         mDemuxId = demuxId;
+        res = r;
         ALOGD("open demux, id = %d", demuxId);
     });
-    if (mDemux == nullptr) {
-        return false;
+    return res;
+}
+
+jobject JTuner::getAvSyncHwId(sp<Filter> filter) {
+    if (mDemux == NULL) {
+        return NULL;
     }
-    return true;
+
+    uint32_t avSyncHwId;
+    Result res;
+    sp<IFilter> iFilterSp = filter->getIFilter();
+    mDemux->getAvSyncHwId(iFilterSp,
+            [&](Result r, uint32_t id) {
+                res = r;
+                avSyncHwId = id;
+            });
+    if (res == Result::SUCCESS) {
+        JNIEnv *env = AndroidRuntime::getJNIEnv();
+        jclass integerClazz = env->FindClass("java/lang/Integer");
+        jmethodID intInit = env->GetMethodID(integerClazz, "<init>", "(I)V");
+        return env->NewObject(integerClazz, intInit, avSyncHwId);
+    }
+    return NULL;
+}
+
+jobject JTuner::getAvSyncTime(jint id) {
+    if (mDemux == NULL) {
+        return NULL;
+    }
+    uint64_t time;
+    Result res;
+    mDemux->getAvSyncTime(static_cast<uint32_t>(id),
+            [&](Result r, uint64_t ts) {
+                res = r;
+                time = ts;
+            });
+    if (res == Result::SUCCESS) {
+        JNIEnv *env = AndroidRuntime::getJNIEnv();
+        jclass longClazz = env->FindClass("java/lang/Long");
+        jmethodID longInit = env->GetMethodID(longClazz, "<init>", "(J)V");
+        return env->NewObject(longClazz, longInit, static_cast<jlong>(time));
+    }
+    return NULL;
+}
+
+int JTuner::connectCiCam(jint id) {
+    if (mDemux == NULL) {
+        Result r = openDemux();
+        if (r != Result::SUCCESS) {
+            return (int) r;
+        }
+    }
+    Result r = mDemux->connectCiCam(static_cast<uint32_t>(id));
+    return (int) r;
+}
+
+int JTuner::disconnectCiCam() {
+    if (mDemux == NULL) {
+        Result r = openDemux();
+        if (r != Result::SUCCESS) {
+            return (int) r;
+        }
+    }
+    Result r = mDemux->disconnectCiCam();
+    return (int) r;
 }
 
 jobject JTuner::openDescrambler() {
@@ -892,7 +954,7 @@
 
 jobject JTuner::openFilter(DemuxFilterType type, int bufferSize) {
     if (mDemux == NULL) {
-        if (!openDemux()) {
+        if (openDemux() != Result::SUCCESS) {
             return NULL;
         }
     }
@@ -917,7 +979,6 @@
             env->NewObject(
                     env->FindClass("android/media/tv/tuner/filter/Filter"),
                     gFields.filterInitID,
-                    mObject,
                     (jint) fId);
 
     sp<Filter> filterSp = new Filter(iFilterSp, filterObj);
@@ -931,7 +992,7 @@
 
 jobject JTuner::openTimeFilter() {
     if (mDemux == NULL) {
-        if (!openDemux()) {
+        if (openDemux() != Result::SUCCESS) {
             return NULL;
         }
     }
@@ -962,7 +1023,7 @@
 jobject JTuner::openDvr(DvrType type, int bufferSize) {
     ALOGD("JTuner::openDvr");
     if (mDemux == NULL) {
-        if (!openDemux()) {
+        if (openDemux() != Result::SUCCESS) {
             return NULL;
         }
     }
@@ -1608,20 +1669,30 @@
     return NULL;
 }
 
-static int android_media_tv_Tuner_gat_av_sync_hw_id(JNIEnv*, jobject, jobject) {
-    return 0;
+static jobject android_media_tv_Tuner_get_av_sync_hw_id(
+        JNIEnv *env, jobject thiz, jobject filter) {
+    sp<Filter> filterSp = getFilter(env, filter);
+    if (filterSp == NULL) {
+        ALOGD("Failed to get sync ID. Filter not found");
+        return NULL;
+    }
+    sp<JTuner> tuner = getTuner(env, thiz);
+    return tuner->getAvSyncHwId(filterSp);
 }
 
-static jlong android_media_tv_Tuner_gat_av_sync_time(JNIEnv*, jobject, jint) {
-    return 0;
+static jobject android_media_tv_Tuner_get_av_sync_time(JNIEnv *env, jobject thiz, jint id) {
+    sp<JTuner> tuner = getTuner(env, thiz);
+    return tuner->getAvSyncTime(id);
 }
 
-static int android_media_tv_Tuner_connect_cicam(JNIEnv*, jobject, jint) {
-    return 0;
+static int android_media_tv_Tuner_connect_cicam(JNIEnv *env, jobject thiz, jint id) {
+    sp<JTuner> tuner = getTuner(env, thiz);
+    return tuner->connectCiCam(id);
 }
 
-static int android_media_tv_Tuner_disconnect_cicam(JNIEnv*, jobject) {
-    return 0;
+static int android_media_tv_Tuner_disconnect_cicam(JNIEnv *env, jobject thiz) {
+    sp<JTuner> tuner = getTuner(env, thiz);
+    return tuner->disconnectCiCam();
 }
 
 static jobject android_media_tv_Tuner_get_frontend_info(JNIEnv *env, jobject thiz, jint id) {
@@ -2500,9 +2571,10 @@
     { "nativeSetLna", "(Z)I", (void *)android_media_tv_Tuner_set_lna },
     { "nativeGetFrontendStatus", "([I)Landroid/media/tv/tuner/frontend/FrontendStatus;",
             (void *)android_media_tv_Tuner_get_frontend_status },
-    { "nativeGetAvSyncHwId", "(Landroid/media/tv/tuner/filter/Filter;)I",
-            (void *)android_media_tv_Tuner_gat_av_sync_hw_id },
-    { "nativeGetAvSyncTime", "(I)J", (void *)android_media_tv_Tuner_gat_av_sync_time },
+    { "nativeGetAvSyncHwId", "(Landroid/media/tv/tuner/filter/Filter;)Ljava/lang/Integer;",
+            (void *)android_media_tv_Tuner_get_av_sync_hw_id },
+    { "nativeGetAvSyncTime", "(I)Ljava/lang/Long;",
+            (void *)android_media_tv_Tuner_get_av_sync_time },
     { "nativeConnectCiCam", "(I)I", (void *)android_media_tv_Tuner_connect_cicam },
     { "nativeDisconnectCiCam", "()I", (void *)android_media_tv_Tuner_disconnect_cicam },
     { "nativeGetFrontendInfo", "(I)Landroid/media/tv/tuner/frontend/FrontendInfo;",
diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h
index 32d4899..b786fc4 100644
--- a/media/jni/android_media_tv_Tuner.h
+++ b/media/jni/android_media_tv_Tuner.h
@@ -60,6 +60,7 @@
 using ::android::hardware::tv::tuner::V1_0::LnbId;
 using ::android::hardware::tv::tuner::V1_0::PlaybackStatus;
 using ::android::hardware::tv::tuner::V1_0::RecordStatus;
+using ::android::hardware::tv::tuner::V1_0::Result;
 
 using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
 using DvrMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
@@ -141,6 +142,10 @@
 struct JTuner : public RefBase {
     JTuner(JNIEnv *env, jobject thiz);
     sp<ITuner> getTunerService();
+    jobject getAvSyncHwId(sp<Filter> filter);
+    jobject getAvSyncTime(jint id);
+    int connectCiCam(jint id);
+    int disconnectCiCam();
     jobject getFrontendIds();
     jobject openFrontendById(int id);
     jobject getFrontendInfo(int id);
@@ -158,7 +163,7 @@
     jobject openDvr(DvrType type, int bufferSize);
 
 protected:
-    bool openDemux();
+    Result openDemux();
     virtual ~JTuner();
 
 private: