Merge "DVR API: class, methods, JNI"
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user