Handle filter status callback
Test: make; acloud
Change-Id: Ibff3e6e7fd834b2cbb1ceb75028151af575c27eb
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index 4ed8f42..7d68d02 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -33,6 +33,8 @@
private static final boolean DEBUG = false;
private static final int MSG_ON_FRONTEND_EVENT = 1;
+ private static final int MSG_ON_FILTER_EVENT = 2;
+ private static final int MSG_ON_FILTER_STATUS = 3;
static {
System.loadLibrary("media_tv_tuner");
@@ -86,6 +88,16 @@
void onEvent(int frontendEventType);
}
+ /**
+ * Frontend Callback.
+ */
+ public interface FilterCallback {
+ /**
+ * Invoked when filter status changed.
+ */
+ void onFilterStatus(int status);
+ }
+
@Nullable
private EventHandler createEventHandler() {
Looper looper;
@@ -110,6 +122,13 @@
mFrontend.mCallback.onEvent(msg.arg1);
}
break;
+ case MSG_ON_FILTER_STATUS: {
+ Filter filter = (Filter) msg.obj;
+ if (filter.mCallback != null) {
+ filter.mCallback.onFilterStatus(msg.arg1);
+ }
+ break;
+ }
default:
// fall through
}
@@ -171,13 +190,29 @@
}
protected class Filter {
+ private long mNativeContext;
+ private FilterCallback mCallback;
int mId;
private Filter(int id) {
mId = id;
}
+
+ private void onFilterStatus(int status) {
+ if (mHandler != null) {
+ mHandler.sendMessage(
+ mHandler.obtainMessage(MSG_ON_FILTER_STATUS, status, 0, this));
+ }
+ }
}
- private Filter openFilter(int type, int subType, int bufferSize) {
- return nativeOpenFilter(type, subType, bufferSize);
+ private Filter openFilter(int type, int subType, int bufferSize, FilterCallback cb) {
+ Filter filter = nativeOpenFilter(type, subType, bufferSize);
+ if (filter != null) {
+ filter.mCallback = cb;
+ if (mHandler == null) {
+ mHandler = createEventHandler();
+ }
+ }
+ return filter;
}
}
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index f815097..2640572 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -34,9 +34,11 @@
struct fields_t {
jfieldID context;
+ jfieldID filterContext;
jmethodID frontendInitID;
jmethodID filterInitID;
jmethodID onFrontendEventID;
+ jmethodID onFilterStatusID;
};
static fields_t gFields;
@@ -44,15 +46,27 @@
namespace android {
/////////////// FilterCallback ///////////////////////
//TODO: implement filter callback
-Return<void> FilterCallback::onFilterEvent(const DemuxFilterEvent& /* filterEvent */) {
+Return<void> FilterCallback::onFilterEvent(const DemuxFilterEvent& /*filterEvent*/) {
ALOGD("FilterCallback::onFilterEvent");
return Void();
}
-Return<void> FilterCallback::onFilterStatus(const DemuxFilterStatus /*status*/) {
- ALOGD("FilterCallback::onFilterStatu");
+
+Return<void> FilterCallback::onFilterStatus(const DemuxFilterStatus status) {
+ ALOGD("FilterCallback::onFilterStatus");
+ JNIEnv *env = AndroidRuntime::getJNIEnv();
+ env->CallVoidMethod(
+ mFilter,
+ gFields.onFilterStatusID,
+ (jint)status);
return Void();
}
+void FilterCallback::setFilter(const jobject filter) {
+ ALOGD("FilterCallback::setFilter");
+ JNIEnv *env = AndroidRuntime::getJNIEnv();
+ mFilter = env->NewWeakGlobalRef(filter);
+}
+
/////////////// FrontendCallback ///////////////////////
FrontendCallback::FrontendCallback(jweak tunerObj, FrontendId id) : mObject(tunerObj), mId(id) {}
@@ -186,27 +200,35 @@
}
}
- sp<IFilter> f;
- mDemux->openFilter(type, bufferSize, new FilterCallback,
+ sp<IFilter> filterSp;
+ sp<FilterCallback> callback = new FilterCallback();
+ mDemux->openFilter(type, bufferSize, callback,
[&](Result, const sp<IFilter>& filter) {
- f = filter;
+ filterSp = filter;
});
- if (f == NULL) {
+ if (filterSp == NULL) {
ALOGD("Failed to open filter, type = %d", type.mainType);
return NULL;
}
int fId;
- f->getId([&](Result, uint32_t filterId) {
+ filterSp->getId([&](Result, uint32_t filterId) {
fId = filterId;
});
- mFilters[fId] = f;
JNIEnv *env = AndroidRuntime::getJNIEnv();
- return env->NewObject(
- env->FindClass("android/media/tv/tuner/Tuner$Filter"),
- gFields.filterInitID,
- mObject,
- (jint) fId);
+ jobject filterObj =
+ env->NewObject(
+ env->FindClass("android/media/tv/tuner/Tuner$Filter"),
+ gFields.filterInitID,
+ mObject,
+ (jint) fId);
+
+ filterSp->incStrong(filterObj);
+ env->SetLongField(filterObj, gFields.filterContext, (jlong)filterSp.get());
+
+ callback->setFilter(filterObj);
+
+ return filterObj;
}
} // namespace android
@@ -233,6 +255,10 @@
return (JTuner *)env->GetLongField(thiz, gFields.context);
}
+static sp<IFilter> getFilter(JNIEnv *env, jobject filter) {
+ return (IFilter *)env->GetLongField(filter, gFields.filterContext);
+}
+
static void android_media_tv_Tuner_native_init(JNIEnv *env) {
jclass clazz = env->FindClass("android/media/tv/tuner/Tuner");
CHECK(clazz != NULL);
@@ -247,8 +273,11 @@
env->GetMethodID(frontendClazz, "<init>", "(Landroid/media/tv/tuner/Tuner;I)V");
jclass filterClazz = env->FindClass("android/media/tv/tuner/Tuner$Filter");
+ gFields.filterContext = env->GetFieldID(filterClazz, "mNativeContext", "J");
gFields.filterInitID =
env->GetMethodID(filterClazz, "<init>", "(Landroid/media/tv/tuner/Tuner;I)V");
+ gFields.onFilterStatusID =
+ env->GetMethodID(filterClazz, "onFilterStatus", "(I)V");
}
static void android_media_tv_Tuner_native_setup(JNIEnv *env, jobject thiz) {
diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h
index 7a889c3..ab48761 100644
--- a/media/jni/android_media_tv_Tuner.h
+++ b/media/jni/android_media_tv_Tuner.h
@@ -44,6 +44,10 @@
struct FilterCallback : public IFilterCallback {
virtual Return<void> onFilterEvent(const DemuxFilterEvent& filterEvent);
virtual Return<void> onFilterStatus(const DemuxFilterStatus status);
+
+ void setFilter(const jobject filter);
+private:
+ jweak mFilter;
};
struct FrontendCallback : public IFrontendCallback {
@@ -76,7 +80,6 @@
sp<IFrontend> mFe;
sp<IDemux> mDemux;
int mDemuxId;
- std::unordered_map<int, sp<IFilter>> mFilters;
};
} // namespace android