Merge "Handle frontend callbacks"
This commit is contained in:
committed by
Android (Google) Code Review
commit
6f382b7061
@@ -16,6 +16,11 @@
|
||||
|
||||
package android.media.tv.tuner;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -34,8 +39,9 @@ public final class Tuner implements AutoCloseable {
|
||||
nativeInit();
|
||||
}
|
||||
|
||||
private FrontendCallback mFrontendCallback;
|
||||
private List<Integer> mFrontendIds;
|
||||
private Frontend mFrontend;
|
||||
private EventHandler mHandler;
|
||||
|
||||
public Tuner() {
|
||||
nativeSetup();
|
||||
@@ -80,11 +86,66 @@ public final class Tuner implements AutoCloseable {
|
||||
void onEvent(int frontendEventType);
|
||||
}
|
||||
|
||||
protected static class Frontend {
|
||||
int mId;
|
||||
@Nullable
|
||||
private EventHandler createEventHandler() {
|
||||
Looper looper;
|
||||
if ((looper = Looper.myLooper()) != null) {
|
||||
return new EventHandler(looper);
|
||||
} else if ((looper = Looper.getMainLooper()) != null) {
|
||||
return new EventHandler(looper);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private class EventHandler extends Handler {
|
||||
private EventHandler(Looper looper) {
|
||||
super(looper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case MSG_ON_FRONTEND_EVENT:
|
||||
if (mFrontend != null && mFrontend.mCallback != null) {
|
||||
mFrontend.mCallback.onEvent(msg.arg1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// fall through
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected class Frontend {
|
||||
private int mId;
|
||||
private FrontendCallback mCallback;
|
||||
|
||||
private Frontend(int id) {
|
||||
mId = id;
|
||||
}
|
||||
|
||||
public void setCallback(@Nullable FrontendCallback callback, @Nullable Handler handler) {
|
||||
mCallback = callback;
|
||||
|
||||
if (mCallback == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (handler == null) {
|
||||
// use default looper if handler is null
|
||||
if (mHandler == null) {
|
||||
mHandler = createEventHandler();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Looper looper = handler.getLooper();
|
||||
if (mHandler != null && mHandler.getLooper() == looper) {
|
||||
// the same looper. reuse mHandler
|
||||
return;
|
||||
}
|
||||
mHandler = new EventHandler(looper);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Integer> getFrontendIds() {
|
||||
@@ -94,12 +155,19 @@ public final class Tuner implements AutoCloseable {
|
||||
|
||||
private Frontend openFrontendById(int id) {
|
||||
if (mFrontendIds == null) {
|
||||
getFrontendIds();
|
||||
mFrontendIds = getFrontendIds();
|
||||
}
|
||||
if (!mFrontendIds.contains(id)) {
|
||||
return null;
|
||||
}
|
||||
return nativeOpenFrontendById(id);
|
||||
mFrontend = nativeOpenFrontendById(id);
|
||||
return mFrontend;
|
||||
}
|
||||
|
||||
private void onFrontendEvent(int eventType) {
|
||||
if (mHandler != null) {
|
||||
mHandler.sendMessage(mHandler.obtainMessage(MSG_ON_FRONTEND_EVENT, eventType, 0));
|
||||
}
|
||||
}
|
||||
|
||||
protected class Filter {
|
||||
|
||||
@@ -36,6 +36,7 @@ struct fields_t {
|
||||
jfieldID context;
|
||||
jmethodID frontendInitID;
|
||||
jmethodID filterInitID;
|
||||
jmethodID onFrontendEventID;
|
||||
};
|
||||
|
||||
static fields_t gFields;
|
||||
@@ -52,7 +53,32 @@ Return<void> FilterCallback::onFilterStatus(const DemuxFilterStatus /*status*/)
|
||||
return Void();
|
||||
}
|
||||
|
||||
/////////////// FrontendCallback ///////////////////////
|
||||
|
||||
FrontendCallback::FrontendCallback(jweak tunerObj, FrontendId id) : mObject(tunerObj), mId(id) {}
|
||||
|
||||
Return<void> FrontendCallback::onEvent(FrontendEventType frontendEventType) {
|
||||
ALOGD("FrontendCallback::onEvent, type=%d", frontendEventType);
|
||||
JNIEnv *env = AndroidRuntime::getJNIEnv();
|
||||
env->CallVoidMethod(
|
||||
mObject,
|
||||
gFields.onFrontendEventID,
|
||||
(jint)frontendEventType);
|
||||
return Void();
|
||||
}
|
||||
Return<void> FrontendCallback::onDiseqcMessage(const hidl_vec<uint8_t>& /*diseqcMessage*/) {
|
||||
ALOGD("FrontendCallback::onDiseqcMessage");
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> FrontendCallback::onScanMessage(
|
||||
FrontendScanMessageType type, const FrontendScanMessage& /*message*/) {
|
||||
ALOGD("FrontendCallback::onScanMessage, type=%d", type);
|
||||
return Void();
|
||||
}
|
||||
|
||||
/////////////// Tuner ///////////////////////
|
||||
|
||||
sp<ITuner> JTuner::mTuner;
|
||||
|
||||
JTuner::JTuner(JNIEnv *env, jobject thiz)
|
||||
@@ -89,11 +115,10 @@ sp<ITuner> JTuner::getTunerService() {
|
||||
|
||||
jobject JTuner::getFrontendIds() {
|
||||
ALOGD("JTuner::getFrontendIds()");
|
||||
hidl_vec<FrontendId> feIds;
|
||||
mTuner->getFrontendIds([&](Result, const hidl_vec<FrontendId>& frontendIds) {
|
||||
feIds = frontendIds;
|
||||
mFeIds = frontendIds;
|
||||
});
|
||||
if (feIds.size() == 0) {
|
||||
if (mFeIds.size() == 0) {
|
||||
ALOGW("Frontend isn't available");
|
||||
return NULL;
|
||||
}
|
||||
@@ -106,21 +131,25 @@ jobject JTuner::getFrontendIds() {
|
||||
jclass integerClazz = env->FindClass("java/lang/Integer");
|
||||
jmethodID intInit = env->GetMethodID(integerClazz, "<init>", "(I)V");
|
||||
|
||||
for (int i=0; i < feIds.size(); i++) {
|
||||
jobject idObj = env->NewObject(integerClazz, intInit, feIds[i]);
|
||||
for (int i=0; i < mFeIds.size(); i++) {
|
||||
jobject idObj = env->NewObject(integerClazz, intInit, mFeIds[i]);
|
||||
env->CallBooleanMethod(obj, arrayListAdd, idObj);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
jobject JTuner::openFrontendById(int id) {
|
||||
sp<IFrontend> fe;
|
||||
mTuner->openFrontendById(id, [&](Result, const sp<IFrontend>& frontend) {
|
||||
mFe = frontend;
|
||||
fe = frontend;
|
||||
});
|
||||
if (mFe == nullptr) {
|
||||
if (fe == nullptr) {
|
||||
ALOGE("Failed to open frontend");
|
||||
return NULL;
|
||||
}
|
||||
mFe = fe;
|
||||
sp<FrontendCallback> feCb = new FrontendCallback(mObject, id);
|
||||
fe->setCallback(feCb);
|
||||
|
||||
jint jId = (jint) id;
|
||||
JNIEnv *env = AndroidRuntime::getJNIEnv();
|
||||
@@ -128,6 +157,7 @@ jobject JTuner::openFrontendById(int id) {
|
||||
return env->NewObject(
|
||||
env->FindClass("android/media/tv/tuner/Tuner$Frontend"),
|
||||
gFields.frontendInitID,
|
||||
mObject,
|
||||
(jint) jId);
|
||||
}
|
||||
|
||||
@@ -210,8 +240,11 @@ static void android_media_tv_Tuner_native_init(JNIEnv *env) {
|
||||
gFields.context = env->GetFieldID(clazz, "mNativeContext", "J");
|
||||
CHECK(gFields.context != NULL);
|
||||
|
||||
gFields.onFrontendEventID = env->GetMethodID(clazz, "onFrontendEvent", "(I)V");
|
||||
|
||||
jclass frontendClazz = env->FindClass("android/media/tv/tuner/Tuner$Frontend");
|
||||
gFields.frontendInitID = env->GetMethodID(frontendClazz, "<init>", "(I)V");
|
||||
gFields.frontendInitID =
|
||||
env->GetMethodID(frontendClazz, "<init>", "(Landroid/media/tv/tuner/Tuner;I)V");
|
||||
|
||||
jclass filterClazz = env->FindClass("android/media/tv/tuner/Tuner$Filter");
|
||||
gFields.filterInitID =
|
||||
|
||||
@@ -24,14 +24,19 @@
|
||||
#include "jni.h"
|
||||
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::hidl_vec;
|
||||
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::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::IFilter;
|
||||
using ::android::hardware::tv::tuner::V1_0::IFilterCallback;
|
||||
using ::android::hardware::tv::tuner::V1_0::IFrontend;
|
||||
using ::android::hardware::tv::tuner::V1_0::IFrontendCallback;
|
||||
using ::android::hardware::tv::tuner::V1_0::ITuner;
|
||||
|
||||
namespace android {
|
||||
@@ -41,6 +46,18 @@ struct FilterCallback : public IFilterCallback {
|
||||
virtual Return<void> onFilterStatus(const DemuxFilterStatus status);
|
||||
};
|
||||
|
||||
struct FrontendCallback : public IFrontendCallback {
|
||||
FrontendCallback(jweak tunerObj, FrontendId id);
|
||||
|
||||
virtual Return<void> onEvent(FrontendEventType frontendEventType);
|
||||
virtual Return<void> onDiseqcMessage(const hidl_vec<uint8_t>& diseqcMessage);
|
||||
virtual Return<void> onScanMessage(
|
||||
FrontendScanMessageType type, const FrontendScanMessage& message);
|
||||
|
||||
jweak mObject;
|
||||
FrontendId mId;
|
||||
};
|
||||
|
||||
struct JTuner : public RefBase {
|
||||
JTuner(JNIEnv *env, jobject thiz);
|
||||
sp<ITuner> getTunerService();
|
||||
@@ -55,6 +72,7 @@ private:
|
||||
jclass mClass;
|
||||
jweak mObject;
|
||||
static sp<ITuner> mTuner;
|
||||
hidl_vec<FrontendId> mFeIds;
|
||||
sp<IFrontend> mFe;
|
||||
sp<IDemux> mDemux;
|
||||
int mDemuxId;
|
||||
|
||||
Reference in New Issue
Block a user