Merge "Enable Frontend callback for sharee."
This commit is contained in:
committed by
Android (Google) Code Review
commit
90413535d6
@@ -285,7 +285,7 @@ public class Tuner implements AutoCloseable {
|
||||
@Nullable
|
||||
private FrontendInfo mFrontendInfo;
|
||||
private Integer mFrontendHandle;
|
||||
private Boolean mIsSharedFrontend = false;
|
||||
private Tuner mFeOwnerTuner = null;
|
||||
private int mFrontendType = FrontendSettings.TYPE_UNDEFINED;
|
||||
private int mUserId;
|
||||
private Lnb mLnb;
|
||||
@@ -442,11 +442,10 @@ public class Tuner implements AutoCloseable {
|
||||
mFrontendLock.lock();
|
||||
try {
|
||||
mTunerResourceManager.shareFrontend(mClientId, tuner.mClientId);
|
||||
synchronized (mIsSharedFrontend) {
|
||||
mFrontendHandle = tuner.mFrontendHandle;
|
||||
mFrontend = tuner.mFrontend;
|
||||
mIsSharedFrontend = true;
|
||||
}
|
||||
mFeOwnerTuner = tuner;
|
||||
mFeOwnerTuner.registerFrontendCallbackListener(this);
|
||||
mFrontendHandle = mFeOwnerTuner.mFrontendHandle;
|
||||
mFrontend = mFeOwnerTuner.mFrontend;
|
||||
nativeShareFrontend(mFrontend.mId);
|
||||
} finally {
|
||||
releaseTRMSLock();
|
||||
@@ -512,6 +511,27 @@ public class Tuner implements AutoCloseable {
|
||||
|
||||
private long mNativeContext; // used by native jMediaTuner
|
||||
|
||||
/**
|
||||
* Registers a tuner as a listener for frontend callbacks.
|
||||
*/
|
||||
private void registerFrontendCallbackListener(Tuner tuner) {
|
||||
nativeRegisterFeCbListener(tuner.getNativeContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters a tuner as a listener for frontend callbacks.
|
||||
*/
|
||||
private void unregisterFrontendCallbackListener(Tuner tuner) {
|
||||
nativeUnregisterFeCbListener(tuner.getNativeContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pointer to the associated JTuner.
|
||||
*/
|
||||
long getNativeContext() {
|
||||
return mNativeContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases the Tuner instance.
|
||||
*/
|
||||
@@ -526,19 +546,21 @@ public class Tuner implements AutoCloseable {
|
||||
}
|
||||
}
|
||||
|
||||
private void releaseAll() {
|
||||
private void releaseFrontend() {
|
||||
mFrontendLock.lock();
|
||||
try {
|
||||
if (mFrontendHandle != null) {
|
||||
synchronized (mIsSharedFrontend) {
|
||||
if (!mIsSharedFrontend) {
|
||||
int res = nativeCloseFrontend(mFrontendHandle);
|
||||
if (res != Tuner.RESULT_SUCCESS) {
|
||||
TunerUtils.throwExceptionForResult(res, "failed to close frontend");
|
||||
}
|
||||
mTunerResourceManager.releaseFrontend(mFrontendHandle, mClientId);
|
||||
if (mFeOwnerTuner != null) {
|
||||
// unregister self from the Frontend callback
|
||||
mFeOwnerTuner.unregisterFrontendCallbackListener(this);
|
||||
mFeOwnerTuner = null;
|
||||
} else {
|
||||
// close resource as owner
|
||||
int res = nativeCloseFrontend(mFrontendHandle);
|
||||
if (res != Tuner.RESULT_SUCCESS) {
|
||||
TunerUtils.throwExceptionForResult(res, "failed to close frontend");
|
||||
}
|
||||
mIsSharedFrontend = false;
|
||||
mTunerResourceManager.releaseFrontend(mFrontendHandle, mClientId);
|
||||
}
|
||||
FrameworkStatsLog
|
||||
.write(FrameworkStatsLog.TV_TUNER_STATE_CHANGED, mUserId,
|
||||
@@ -549,9 +571,14 @@ public class Tuner implements AutoCloseable {
|
||||
} finally {
|
||||
mFrontendLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void releaseAll() {
|
||||
releaseFrontend();
|
||||
|
||||
mLnbLock.lock();
|
||||
try {
|
||||
// mLnb will be non-null only for owner tuner
|
||||
if (mLnb != null) {
|
||||
mLnb.close();
|
||||
}
|
||||
@@ -641,6 +668,8 @@ public class Tuner implements AutoCloseable {
|
||||
*/
|
||||
private native Frontend nativeOpenFrontendByHandle(int handle);
|
||||
private native int nativeShareFrontend(int id);
|
||||
private native void nativeRegisterFeCbListener(long nativeContext);
|
||||
private native void nativeUnregisterFeCbListener(long nativeContext);
|
||||
@Result
|
||||
private native int nativeTune(int type, FrontendSettings settings);
|
||||
private native int nativeStopTune();
|
||||
@@ -1276,7 +1305,7 @@ public class Tuner implements AutoCloseable {
|
||||
}
|
||||
|
||||
private void onFrontendEvent(int eventType) {
|
||||
Log.d(TAG, "Got event from tuning. Event type: " + eventType);
|
||||
Log.d(TAG, "Got event from tuning. Event type: " + eventType + " for " + this);
|
||||
synchronized (mOnTuneEventLock) {
|
||||
if (mOnTuneEventExecutor != null && mOnTuneEventListener != null) {
|
||||
mOnTuneEventExecutor.execute(() -> {
|
||||
|
||||
@@ -951,20 +951,45 @@ FilterClientCallbackImpl::~FilterClientCallbackImpl() {
|
||||
}
|
||||
|
||||
/////////////// FrontendClientCallbackImpl ///////////////////////
|
||||
FrontendClientCallbackImpl::FrontendClientCallbackImpl(jweak tunerObj) : mObject(tunerObj) {}
|
||||
FrontendClientCallbackImpl::FrontendClientCallbackImpl(JTuner* jtuner, jweak listener) {
|
||||
ALOGV("FrontendClientCallbackImpl() with listener:%p", listener);
|
||||
addCallbackListener(jtuner, listener);
|
||||
}
|
||||
|
||||
void FrontendClientCallbackImpl::addCallbackListener(JTuner* jtuner, jweak listener) {
|
||||
JNIEnv *env = AndroidRuntime::getJNIEnv();
|
||||
jweak listenerRef = env->NewWeakGlobalRef(listener);
|
||||
ALOGV("addCallbackListener() with listener:%p and ref:%p @%p", listener, listenerRef, this);
|
||||
std::scoped_lock<std::mutex> lock(mMutex);
|
||||
mListenersMap[jtuner] = listenerRef;
|
||||
}
|
||||
|
||||
void FrontendClientCallbackImpl::removeCallbackListener(JTuner* listener) {
|
||||
ALOGV("removeCallbackListener for listener:%p", listener);
|
||||
JNIEnv *env = AndroidRuntime::getJNIEnv();
|
||||
std::scoped_lock<std::mutex> lock(mMutex);
|
||||
if (mListenersMap.find(listener) != mListenersMap.end() && mListenersMap[listener]) {
|
||||
env->DeleteWeakGlobalRef(mListenersMap[listener]);
|
||||
mListenersMap.erase(listener);
|
||||
}
|
||||
}
|
||||
|
||||
void FrontendClientCallbackImpl::onEvent(FrontendEventType frontendEventType) {
|
||||
ALOGV("FrontendClientCallbackImpl::onEvent, type=%d", frontendEventType);
|
||||
JNIEnv *env = AndroidRuntime::getJNIEnv();
|
||||
jobject frontend(env->NewLocalRef(mObject));
|
||||
if (!env->IsSameObject(frontend, nullptr)) {
|
||||
env->CallVoidMethod(
|
||||
frontend,
|
||||
gFields.onFrontendEventID,
|
||||
(jint)frontendEventType);
|
||||
} else {
|
||||
ALOGE("FrontendClientCallbackImpl::onEvent:"
|
||||
"Frontend object has been freed. Ignoring callback.");
|
||||
std::scoped_lock<std::mutex> lock(mMutex);
|
||||
for (const auto& mapEntry : mListenersMap) {
|
||||
ALOGV("JTuner:%p, jweak:%p", mapEntry.first, mapEntry.second);
|
||||
jobject frontend(env->NewLocalRef(mapEntry.second));
|
||||
if (!env->IsSameObject(frontend, nullptr)) {
|
||||
env->CallVoidMethod(
|
||||
frontend,
|
||||
gFields.onFrontendEventID,
|
||||
(jint)frontendEventType);
|
||||
} else {
|
||||
ALOGW("FrontendClientCallbackImpl::onEvent:"
|
||||
"Frontend object has been freed. Ignoring callback.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -973,12 +998,25 @@ void FrontendClientCallbackImpl::onScanMessage(
|
||||
ALOGV("FrontendClientCallbackImpl::onScanMessage, type=%d", type);
|
||||
JNIEnv *env = AndroidRuntime::getJNIEnv();
|
||||
jclass clazz = env->FindClass("android/media/tv/tuner/Tuner");
|
||||
jobject frontend(env->NewLocalRef(mObject));
|
||||
if (env->IsSameObject(frontend, nullptr)) {
|
||||
ALOGE("FrontendClientCallbackImpl::onScanMessage:"
|
||||
"Frontend object has been freed. Ignoring callback.");
|
||||
return;
|
||||
|
||||
std::scoped_lock<std::mutex> lock(mMutex);
|
||||
for (const auto& mapEntry : mListenersMap) {
|
||||
jobject frontend(env->NewLocalRef(mapEntry.second));
|
||||
if (env->IsSameObject(frontend, nullptr)) {
|
||||
ALOGE("FrontendClientCallbackImpl::onScanMessage:"
|
||||
"Tuner object has been freed. Ignoring callback.");
|
||||
continue;
|
||||
}
|
||||
executeOnScanMessage(env, clazz, frontend, type, message);
|
||||
}
|
||||
}
|
||||
|
||||
void FrontendClientCallbackImpl::executeOnScanMessage(
|
||||
JNIEnv *env, const jclass& clazz, const jobject& frontend,
|
||||
FrontendScanMessageType type,
|
||||
const FrontendScanMessage& message) {
|
||||
ALOGV("FrontendClientCallbackImpl::executeOnScanMessage, type=%d", type);
|
||||
|
||||
switch(type) {
|
||||
case FrontendScanMessageType::LOCKED: {
|
||||
if (message.get<FrontendScanMessage::Tag::isLocked>()) {
|
||||
@@ -1157,11 +1195,14 @@ void FrontendClientCallbackImpl::onScanMessage(
|
||||
}
|
||||
|
||||
FrontendClientCallbackImpl::~FrontendClientCallbackImpl() {
|
||||
JNIEnv *env = AndroidRuntime::getJNIEnv();
|
||||
if (mObject != nullptr) {
|
||||
env->DeleteWeakGlobalRef(mObject);
|
||||
mObject = nullptr;
|
||||
JNIEnv *env = android::AndroidRuntime::getJNIEnv();
|
||||
ALOGV("~FrontendClientCallbackImpl()");
|
||||
std::scoped_lock<std::mutex> lock(mMutex);
|
||||
for (const auto& mapEntry : mListenersMap) {
|
||||
ALOGV("deleteRef :%p at @ %p", mapEntry.second, this);
|
||||
env->DeleteWeakGlobalRef(mapEntry.second);
|
||||
}
|
||||
mListenersMap.clear();
|
||||
}
|
||||
|
||||
/////////////// Tuner ///////////////////////
|
||||
@@ -1180,6 +1221,10 @@ JTuner::JTuner(JNIEnv *env, jobject thiz) : mClass(nullptr) {
|
||||
mSharedFeId = (int)Constant::INVALID_FRONTEND_ID;
|
||||
}
|
||||
|
||||
jweak JTuner::getObject() {
|
||||
return mObject;
|
||||
}
|
||||
|
||||
JTuner::~JTuner() {
|
||||
if (mFeClient != nullptr) {
|
||||
mFeClient->close();
|
||||
@@ -1192,6 +1237,7 @@ JTuner::~JTuner() {
|
||||
env->DeleteWeakGlobalRef(mObject);
|
||||
env->DeleteGlobalRef(mClass);
|
||||
mFeClient = nullptr;
|
||||
mFeClientCb = nullptr;
|
||||
mDemuxClient = nullptr;
|
||||
mClass = nullptr;
|
||||
mObject = nullptr;
|
||||
@@ -1247,9 +1293,8 @@ jobject JTuner::openFrontendByHandle(int feHandle) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sp<FrontendClientCallbackImpl> feClientCb =
|
||||
new FrontendClientCallbackImpl(env->NewWeakGlobalRef(mObject));
|
||||
mFeClient->setCallback(feClientCb);
|
||||
mFeClientCb = new FrontendClientCallbackImpl(this, mObject);
|
||||
mFeClient->setCallback(mFeClientCb);
|
||||
// TODO: add more fields to frontend
|
||||
return env->NewObject(
|
||||
env->FindClass("android/media/tv/tuner/Tuner$Frontend"),
|
||||
@@ -1269,6 +1314,18 @@ int JTuner::shareFrontend(int feId) {
|
||||
return (int)Result::SUCCESS;
|
||||
}
|
||||
|
||||
void JTuner::registerFeCbListener(JTuner* jtuner) {
|
||||
if (mFeClientCb != nullptr && jtuner != nullptr) {
|
||||
mFeClientCb->addCallbackListener(jtuner, jtuner->getObject());
|
||||
}
|
||||
}
|
||||
|
||||
void JTuner::unregisterFeCbListener(JTuner* jtuner) {
|
||||
if (mFeClientCb != nullptr && jtuner != nullptr) {
|
||||
mFeClientCb->removeCallbackListener(jtuner);
|
||||
}
|
||||
}
|
||||
|
||||
jobject JTuner::getAnalogFrontendCaps(JNIEnv *env, FrontendCapabilities &caps) {
|
||||
jclass clazz = env->FindClass("android/media/tv/tuner/frontend/AnalogFrontendCapabilities");
|
||||
jmethodID capsInit = env->GetMethodID(clazz, "<init>", "(II)V");
|
||||
@@ -3188,6 +3245,20 @@ static int android_media_tv_Tuner_share_frontend(
|
||||
return tuner->shareFrontend(id);
|
||||
}
|
||||
|
||||
static void android_media_tv_Tuner_register_fe_cb_listener(
|
||||
JNIEnv *env, jobject thiz, jlong shareeJTuner) {
|
||||
sp<JTuner> tuner = getTuner(env, thiz);
|
||||
JTuner *jtuner = (JTuner *)shareeJTuner;
|
||||
tuner->registerFeCbListener(jtuner);
|
||||
}
|
||||
|
||||
static void android_media_tv_Tuner_unregister_fe_cb_listener(
|
||||
JNIEnv *env, jobject thiz, jlong shareeJTuner) {
|
||||
sp<JTuner> tuner = getTuner(env, thiz);
|
||||
JTuner *jtuner = (JTuner *)shareeJTuner;
|
||||
tuner->unregisterFeCbListener(jtuner);
|
||||
}
|
||||
|
||||
static int android_media_tv_Tuner_tune(JNIEnv *env, jobject thiz, jint type, jobject settings) {
|
||||
sp<JTuner> tuner = getTuner(env, thiz);
|
||||
FrontendSettings setting = getFrontendSettings(env, type, settings);
|
||||
@@ -4361,6 +4432,10 @@ static const JNINativeMethod gTunerMethods[] = {
|
||||
(void *)android_media_tv_Tuner_open_frontend_by_handle },
|
||||
{ "nativeShareFrontend", "(I)I",
|
||||
(void *)android_media_tv_Tuner_share_frontend },
|
||||
{ "nativeRegisterFeCbListener", "(J)V",
|
||||
(void*)android_media_tv_Tuner_register_fe_cb_listener },
|
||||
{ "nativeUnregisterFeCbListener", "(J)V",
|
||||
(void*)android_media_tv_Tuner_unregister_fe_cb_listener },
|
||||
{ "nativeTune", "(ILandroid/media/tv/tuner/frontend/FrontendSettings;)I",
|
||||
(void *)android_media_tv_Tuner_tune },
|
||||
{ "nativeStopTune", "()I", (void *)android_media_tv_Tuner_stop_tune },
|
||||
|
||||
@@ -149,14 +149,21 @@ private:
|
||||
void getRestartEvent(jobjectArray& arr, const int size, const DemuxFilterEvent& event);
|
||||
};
|
||||
|
||||
struct JTuner;
|
||||
struct FrontendClientCallbackImpl : public FrontendClientCallback {
|
||||
FrontendClientCallbackImpl(jweak tunerObj);
|
||||
FrontendClientCallbackImpl(JTuner*, jweak);
|
||||
~FrontendClientCallbackImpl();
|
||||
virtual void onEvent(FrontendEventType frontendEventType);
|
||||
virtual void onScanMessage(
|
||||
FrontendScanMessageType type, const FrontendScanMessage& message);
|
||||
|
||||
jweak mObject;
|
||||
void executeOnScanMessage(JNIEnv *env, const jclass& clazz, const jobject& frontend,
|
||||
FrontendScanMessageType type,
|
||||
const FrontendScanMessage& message);
|
||||
void addCallbackListener(JTuner*, jweak obj);
|
||||
void removeCallbackListener(JTuner* jtuner);
|
||||
std::unordered_map<JTuner*, jweak> mListenersMap;
|
||||
std::mutex mMutex;
|
||||
};
|
||||
|
||||
struct JTuner : public RefBase {
|
||||
@@ -171,6 +178,8 @@ struct JTuner : public RefBase {
|
||||
jobject getFrontendIds();
|
||||
jobject openFrontendByHandle(int feHandle);
|
||||
int shareFrontend(int feId);
|
||||
void registerFeCbListener(JTuner* jtuner);
|
||||
void unregisterFeCbListener(JTuner* jtuner);
|
||||
jint closeFrontendById(int id);
|
||||
jobject getFrontendInfo(int id);
|
||||
int tune(const FrontendSettings& settings);
|
||||
@@ -192,6 +201,8 @@ struct JTuner : public RefBase {
|
||||
jint closeFrontend();
|
||||
jint closeDemux();
|
||||
|
||||
jweak getObject();
|
||||
|
||||
protected:
|
||||
virtual ~JTuner();
|
||||
|
||||
@@ -200,6 +211,7 @@ private:
|
||||
jweak mObject;
|
||||
static sp<TunerClient> mTunerClient;
|
||||
sp<FrontendClient> mFeClient;
|
||||
sp<FrontendClientCallbackImpl> mFeClientCb;
|
||||
int mFeId;
|
||||
int mSharedFeId;
|
||||
sp<LnbClient> mLnbClient;
|
||||
|
||||
Reference in New Issue
Block a user