diff options
| author | 2019-11-08 17:10:18 -0800 | |
|---|---|---|
| committer | 2019-11-14 10:47:29 -0800 | |
| commit | 4a0eddf4b8ed9473efb54aea27c1022ba267ec9d (patch) | |
| tree | 5e85abf463839d1e0b8151e7dc7be87942819cc8 | |
| parent | 4056b743f8496606c57326b516ce370dbfc50353 (diff) | |
DVR API: class, methods, JNI
Test: make; alcoud;
Change-Id: Iddcffef436dc520c969a3dc4f854e3d4c902c2b8
| -rw-r--r-- | media/java/android/media/tv/tuner/Tuner.java | 50 | ||||
| -rw-r--r-- | media/jni/android_media_tv_Tuner.cpp | 131 | ||||
| -rw-r--r-- | media/jni/android_media_tv_Tuner.h | 15 |
3 files changed, 196 insertions, 0 deletions
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java index 3d89909b87aa..c91325aa9a09 100644 --- a/media/java/android/media/tv/tuner/Tuner.java +++ b/media/java/android/media/tv/tuner/Tuner.java @@ -86,6 +86,7 @@ public final class Tuner implements AutoCloseable { private native Descrambler nativeOpenDescrambler(); + private native Dvr nativeOpenDvr(int type, int bufferSize); /** * Frontend Callback. @@ -118,6 +119,20 @@ public final class Tuner implements AutoCloseable { void onFilterStatus(int status); } + /** + * DVR Callback. + */ + public interface DvrCallback { + /** + * Invoked when record status changed. + */ + void onRecordStatus(int status); + /** + * Invoked when playback status changed. + */ + void onPlaybackStatus(int status); + } + @Nullable private EventHandler createEventHandler() { Looper looper; @@ -321,4 +336,39 @@ public final class Tuner implements AutoCloseable { Descrambler descrambler = nativeOpenDescrambler(); return descrambler; } + + // TODO: consider splitting Dvr to Playback and Recording + protected class Dvr { + private long mNativeContext; + private DvrCallback mCallback; + + private native boolean nativeAttachFilter(Filter filter); + private native boolean nativeDetachFilter(Filter filter); + private native boolean nativeStartDvr(); + private native boolean nativeStopDvr(); + private native boolean nativeFlushDvr(); + + private Dvr() {} + + public boolean attachFilter(Filter filter) { + return nativeAttachFilter(filter); + } + public boolean detachFilter(Filter filter) { + return nativeDetachFilter(filter); + } + public boolean start() { + return nativeStartDvr(); + } + public boolean stop() { + return nativeStopDvr(); + } + public boolean flush() { + return nativeFlushDvr(); + } + } + + private Dvr openDvr(int type, int bufferSize) { + Dvr dvr = nativeOpenDvr(type, bufferSize); + return dvr; + } } diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp index efdd333f97f2..f5202fc17f71 100644 --- a/media/jni/android_media_tv_Tuner.cpp +++ b/media/jni/android_media_tv_Tuner.cpp @@ -38,8 +38,10 @@ struct fields_t { jfieldID tunerContext; jfieldID filterContext; jfieldID descramblerContext; + jfieldID dvrContext; jmethodID frontendInitID; jmethodID filterInitID; + jmethodID dvrInitID; jmethodID onFrontendEventID; jmethodID onFilterStatusID; jmethodID lnbInitID; @@ -67,6 +69,23 @@ Return<void> LnbCallback::onDiseqcMessage(const hidl_vec<uint8_t>& /*diseqcMessa return Void(); } +/////////////// DvrCallback /////////////////////// +Return<void> DvrCallback::onRecordStatus(RecordStatus /*status*/) { + ALOGD("DvrCallback::onRecordStatus"); + return Void(); +} + +Return<void> DvrCallback::onPlaybackStatus(PlaybackStatus /*status*/) { + ALOGD("DvrCallback::onPlaybackStatus"); + return Void(); +} + +void DvrCallback::setDvr(const jobject dvr) { + ALOGD("FilterCallback::setDvr"); + JNIEnv *env = AndroidRuntime::getJNIEnv(); + mDvr = env->NewWeakGlobalRef(dvr); +} + /////////////// FilterCallback /////////////////////// //TODO: implement filter callback Return<void> FilterCallback::onFilterEvent(const DemuxFilterEvent& /*filterEvent*/) { @@ -327,6 +346,39 @@ jobject JTuner::openFilter(DemuxFilterType type, int bufferSize) { return filterObj; } +jobject JTuner::openDvr(DvrType type, int bufferSize) { + ALOGD("JTuner::openDvr"); + if (mDemux == NULL) { + if (!openDemux()) { + return NULL; + } + } + sp<IDvr> dvrSp; + sp<DvrCallback> callback = new DvrCallback(); + mDemux->openDvr(type, bufferSize, callback, + [&](Result, const sp<IDvr>& dvr) { + dvrSp = dvr; + }); + + if (dvrSp == NULL) { + return NULL; + } + + JNIEnv *env = AndroidRuntime::getJNIEnv(); + jobject dvrObj = + env->NewObject( + env->FindClass("android/media/tv/tuner/Tuner$Dvr"), + gFields.dvrInitID, + mObject); + + dvrSp->incStrong(dvrObj); + env->SetLongField(dvrObj, gFields.dvrContext, (jlong)dvrSp.get()); + + callback->setDvr(dvrObj); + + return dvrObj; +} + } // namespace android //////////////////////////////////////////////////////////////////////////////// @@ -369,6 +421,10 @@ static sp<IFilter> getFilter(JNIEnv *env, jobject filter) { return (IFilter *)env->GetLongField(filter, gFields.filterContext); } +static sp<IDvr> getDvr(JNIEnv *env, jobject dvr) { + return (IDvr *)env->GetLongField(dvr, gFields.dvrContext); +} + static void android_media_tv_Tuner_native_init(JNIEnv *env) { jclass clazz = env->FindClass("android/media/tv/tuner/Tuner"); CHECK(clazz != NULL); @@ -399,6 +455,10 @@ static void android_media_tv_Tuner_native_init(JNIEnv *env) { gFields.descramblerContext = env->GetFieldID(descramblerClazz, "mNativeContext", "J"); gFields.descramblerInitID = env->GetMethodID(descramblerClazz, "<init>", "(Landroid/media/tv/tuner/Tuner;)V"); + + jclass dvrClazz = env->FindClass("android/media/tv/tuner/Tuner$Dvr"); + gFields.dvrContext = env->GetFieldID(dvrClazz, "mNativeContext", "J"); + gFields.dvrInitID = env->GetMethodID(dvrClazz, "<init>", "(Landroid/media/tv/tuner/Tuner;)V"); } static void android_media_tv_Tuner_native_setup(JNIEnv *env, jobject thiz) { @@ -493,6 +553,58 @@ static bool android_media_tv_Tuner_remove_pid( return result == Result::SUCCESS; } +static jobject android_media_tv_Tuner_open_dvr(JNIEnv *env, jobject thiz, jint type, jint bufferSize) { + sp<JTuner> tuner = getTuner(env, thiz); + return tuner->openDvr(static_cast<DvrType>(type), bufferSize); +} + +static bool android_media_tv_Tuner_attach_filter(JNIEnv *env, jobject dvr, jobject filter) { + sp<IDvr> dvrSp = getDvr(env, dvr); + sp<IFilter> filterSp = getFilter(env, filter); + if (dvrSp == NULL || filterSp == NULL) { + return false; + } + Result result = dvrSp->attachFilter(filterSp); + return result == Result::SUCCESS; +} + +static bool android_media_tv_Tuner_detach_filter(JNIEnv *env, jobject dvr, jobject filter) { + sp<IDvr> dvrSp = getDvr(env, dvr); + sp<IFilter> filterSp = getFilter(env, filter); + if (dvrSp == NULL || filterSp == NULL) { + return false; + } + Result result = dvrSp->detachFilter(filterSp); + return result == Result::SUCCESS; +} + +static bool android_media_tv_Tuner_start_dvr(JNIEnv *env, jobject dvr) { + sp<IDvr> dvrSp = getDvr(env, dvr); + if (dvrSp == NULL) { + ALOGD("Failed to start dvr: dvr not found"); + return false; + } + return dvrSp->start() == Result::SUCCESS; +} + +static bool android_media_tv_Tuner_stop_dvr(JNIEnv *env, jobject dvr) { + sp<IDvr> dvrSp = getDvr(env, dvr); + if (dvrSp == NULL) { + ALOGD("Failed to stop dvr: dvr not found"); + return false; + } + return dvrSp->stop() == Result::SUCCESS; +} + +static bool android_media_tv_Tuner_flush_dvr(JNIEnv *env, jobject dvr) { + sp<IDvr> dvrSp = getDvr(env, dvr); + if (dvrSp == NULL) { + ALOGD("Failed to flush dvr: dvr not found"); + return false; + } + return dvrSp->flush() == Result::SUCCESS; +} + static const JNINativeMethod gTunerMethods[] = { { "nativeInit", "()V", (void *)android_media_tv_Tuner_native_init }, { "nativeSetup", "()V", (void *)android_media_tv_Tuner_native_setup }, @@ -508,6 +620,8 @@ static const JNINativeMethod gTunerMethods[] = { (void *)android_media_tv_Tuner_open_lnb_by_id }, { "nativeOpenDescrambler", "()Landroid/media/tv/tuner/Tuner$Descrambler;", (void *)android_media_tv_Tuner_open_descrambler }, + { "nativeOpenDvr", "(II)Landroid/media/tv/tuner/Tuner$Dvr;", + (void *)android_media_tv_Tuner_open_dvr }, }; static const JNINativeMethod gFilterMethods[] = { @@ -523,6 +637,16 @@ static const JNINativeMethod gDescramblerMethods[] = { (void *)android_media_tv_Tuner_remove_pid }, }; +static const JNINativeMethod gDvrMethods[] = { + { "nativeAttachFilter", "(Landroid/media/tv/tuner/Tuner$Filter;)Z", + (void *)android_media_tv_Tuner_attach_filter }, + { "nativeDetachFilter", "(Landroid/media/tv/tuner/Tuner$Filter;)Z", + (void *)android_media_tv_Tuner_detach_filter }, + { "nativeStartDvr", "()Z", (void *)android_media_tv_Tuner_start_dvr }, + { "nativeStopDvr", "()Z", (void *)android_media_tv_Tuner_stop_dvr }, + { "nativeFlushDvr", "()Z", (void *)android_media_tv_Tuner_flush_dvr }, +}; + static bool register_android_media_tv_Tuner(JNIEnv *env) { if (AndroidRuntime::registerNativeMethods( env, "android/media/tv/tuner/Tuner", gTunerMethods, NELEM(gTunerMethods)) != JNI_OK) { @@ -543,6 +667,13 @@ static bool register_android_media_tv_Tuner(JNIEnv *env) { ALOGE("Failed to register descrambler native methods"); return false; } + if (AndroidRuntime::registerNativeMethods( + env, "android/media/tv/tuner/Tuner$Dvr", + gDvrMethods, + NELEM(gDvrMethods)) != JNI_OK) { + ALOGE("Failed to register dvr native methods"); + return false; + } return true; } diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h index d3aec64c075e..3bf6ec84c8f7 100644 --- a/media/jni/android_media_tv_Tuner.h +++ b/media/jni/android_media_tv_Tuner.h @@ -29,12 +29,15 @@ using ::android::hardware::tv::tuner::V1_0::DemuxFilterEvent; using ::android::hardware::tv::tuner::V1_0::DemuxFilterStatus; using ::android::hardware::tv::tuner::V1_0::DemuxFilterType; using ::android::hardware::tv::tuner::V1_0::DemuxPid; +using ::android::hardware::tv::tuner::V1_0::DvrType; using ::android::hardware::tv::tuner::V1_0::FrontendEventType; using ::android::hardware::tv::tuner::V1_0::FrontendId; using ::android::hardware::tv::tuner::V1_0::FrontendScanMessage; using ::android::hardware::tv::tuner::V1_0::FrontendScanMessageType; using ::android::hardware::tv::tuner::V1_0::IDemux; using ::android::hardware::tv::tuner::V1_0::IDescrambler; +using ::android::hardware::tv::tuner::V1_0::IDvr; +using ::android::hardware::tv::tuner::V1_0::IDvrCallback; using ::android::hardware::tv::tuner::V1_0::IFilter; using ::android::hardware::tv::tuner::V1_0::IFilterCallback; using ::android::hardware::tv::tuner::V1_0::IFrontend; @@ -44,6 +47,8 @@ using ::android::hardware::tv::tuner::V1_0::ILnbCallback; using ::android::hardware::tv::tuner::V1_0::ITuner; using ::android::hardware::tv::tuner::V1_0::LnbEventType; using ::android::hardware::tv::tuner::V1_0::LnbId; +using ::android::hardware::tv::tuner::V1_0::PlaybackStatus; +using ::android::hardware::tv::tuner::V1_0::RecordStatus; namespace android { @@ -55,6 +60,15 @@ struct LnbCallback : public ILnbCallback { LnbId mId; }; +struct DvrCallback : public IDvrCallback { + virtual Return<void> onRecordStatus(RecordStatus status); + virtual Return<void> onPlaybackStatus(PlaybackStatus status); + + void setDvr(const jobject dvr); +private: + jweak mDvr; +}; + struct FilterCallback : public IFilterCallback { virtual Return<void> onFilterEvent(const DemuxFilterEvent& filterEvent); virtual Return<void> onFilterStatus(const DemuxFilterStatus status); @@ -85,6 +99,7 @@ struct JTuner : public RefBase { jobject openLnbById(int id); jobject openFilter(DemuxFilterType type, int bufferSize); jobject openDescrambler(); + jobject openDvr(DvrType type, int bufferSize); protected: bool openDemux(); |