Merge "Handle frontend callbacks"

This commit is contained in:
TreeHugger Robot
2019-11-06 01:28:11 +00:00
committed by Android (Google) Code Review
3 changed files with 132 additions and 13 deletions

View File

@@ -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 {

View File

@@ -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 =

View File

@@ -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;