Loading media/java/android/media/tv/tuner/Tuner.java +50 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ public final class Tuner implements AutoCloseable { private native Descrambler nativeOpenDescrambler(); private native Dvr nativeOpenDvr(int type, int bufferSize); /** * Frontend Callback. Loading Loading @@ -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; Loading Loading @@ -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; } } media/jni/android_media_tv_Tuner.cpp +131 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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*/) { Loading Loading @@ -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 //////////////////////////////////////////////////////////////////////////////// Loading Loading @@ -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); Loading Loading @@ -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) { Loading Loading @@ -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 }, Loading @@ -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[] = { Loading @@ -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) { Loading @@ -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; } Loading media/jni/android_media_tv_Tuner.h +15 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 { Loading @@ -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); Loading Loading @@ -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(); Loading Loading
media/java/android/media/tv/tuner/Tuner.java +50 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ public final class Tuner implements AutoCloseable { private native Descrambler nativeOpenDescrambler(); private native Dvr nativeOpenDvr(int type, int bufferSize); /** * Frontend Callback. Loading Loading @@ -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; Loading Loading @@ -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; } }
media/jni/android_media_tv_Tuner.cpp +131 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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*/) { Loading Loading @@ -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 //////////////////////////////////////////////////////////////////////////////// Loading Loading @@ -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); Loading Loading @@ -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) { Loading Loading @@ -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 }, Loading @@ -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[] = { Loading @@ -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) { Loading @@ -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; } Loading
media/jni/android_media_tv_Tuner.h +15 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 { Loading @@ -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); Loading Loading @@ -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(); Loading