Merge "Check if the weak reference of java object is alive before using it" into sc-dev

This commit is contained in:
Amy Zhang
2021-02-23 23:55:12 +00:00
committed by Android (Google) Code Review
2 changed files with 130 additions and 50 deletions

View File

@@ -217,23 +217,36 @@ namespace android {
void LnbClientCallbackImpl::onEvent(const LnbEventType lnbEventType) { void LnbClientCallbackImpl::onEvent(const LnbEventType lnbEventType) {
ALOGD("LnbClientCallbackImpl::onEvent, type=%d", lnbEventType); ALOGD("LnbClientCallbackImpl::onEvent, type=%d", lnbEventType);
JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = AndroidRuntime::getJNIEnv();
jobject lnb(env->NewLocalRef(mLnbObj));
if (!env->IsSameObject(lnb, nullptr)) {
env->CallVoidMethod( env->CallVoidMethod(
mLnbObj, lnb,
gFields.onLnbEventID, gFields.onLnbEventID,
(jint)lnbEventType); (jint)lnbEventType);
} else {
ALOGE("LnbClientCallbackImpl::onEvent:"
"Lnb object has been freed. Ignoring callback.");
env->DeleteWeakGlobalRef(mLnbObj);
}
} }
void LnbClientCallbackImpl::onDiseqcMessage(const hidl_vec<uint8_t>& diseqcMessage) { void LnbClientCallbackImpl::onDiseqcMessage(const hidl_vec<uint8_t>& diseqcMessage) {
ALOGD("LnbClientCallbackImpl::onDiseqcMessage"); ALOGD("LnbClientCallbackImpl::onDiseqcMessage");
JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = AndroidRuntime::getJNIEnv();
jobject lnb(env->NewLocalRef(mLnbObj));
if (!env->IsSameObject(lnb, nullptr)) {
jbyteArray array = env->NewByteArray(diseqcMessage.size()); jbyteArray array = env->NewByteArray(diseqcMessage.size());
env->SetByteArrayRegion( env->SetByteArrayRegion(
array, 0, diseqcMessage.size(), reinterpret_cast<jbyte*>(diseqcMessage[0])); array, 0, diseqcMessage.size(), reinterpret_cast<jbyte*>(diseqcMessage[0]));
env->CallVoidMethod( env->CallVoidMethod(
mLnbObj, lnb,
gFields.onLnbDiseqcMessageID, gFields.onLnbDiseqcMessageID,
array); array);
} else {
ALOGE("LnbClientCallbackImpl::onDiseqcMessage:"
"Lnb object has been freed. Ignoring callback.");
env->DeleteWeakGlobalRef(mLnbObj);
}
} }
void LnbClientCallbackImpl::setLnb(jweak lnbObj) { void LnbClientCallbackImpl::setLnb(jweak lnbObj) {
@@ -254,19 +267,33 @@ LnbClientCallbackImpl::~LnbClientCallbackImpl() {
void DvrClientCallbackImpl::onRecordStatus(RecordStatus status) { void DvrClientCallbackImpl::onRecordStatus(RecordStatus status) {
ALOGD("DvrClientCallbackImpl::onRecordStatus"); ALOGD("DvrClientCallbackImpl::onRecordStatus");
JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = AndroidRuntime::getJNIEnv();
jobject dvr(env->NewLocalRef(mDvrObj));
if (!env->IsSameObject(dvr, nullptr)) {
env->CallVoidMethod( env->CallVoidMethod(
mDvrObj, dvr,
gFields.onDvrRecordStatusID, gFields.onDvrRecordStatusID,
(jint) status); (jint) status);
} else {
ALOGE("DvrClientCallbackImpl::onRecordStatus:"
"Dvr object has been freed. Ignoring callback.");
env->DeleteWeakGlobalRef(mDvrObj);
}
} }
void DvrClientCallbackImpl::onPlaybackStatus(PlaybackStatus status) { void DvrClientCallbackImpl::onPlaybackStatus(PlaybackStatus status) {
ALOGD("DvrClientCallbackImpl::onPlaybackStatus"); ALOGD("DvrClientCallbackImpl::onPlaybackStatus");
JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = AndroidRuntime::getJNIEnv();
jobject dvr(env->NewLocalRef(mDvrObj));
if (!env->IsSameObject(dvr, nullptr)) {
env->CallVoidMethod( env->CallVoidMethod(
mDvrObj, dvr,
gFields.onDvrPlaybackStatusID, gFields.onDvrPlaybackStatusID,
(jint) status); (jint) status);
} else {
ALOGE("DvrClientCallbackImpl::onPlaybackStatus:"
"Dvr object has been freed. Ignoring callback.");
env->DeleteWeakGlobalRef(mDvrObj);
}
} }
void DvrClientCallbackImpl::setDvr(jweak dvrObj) { void DvrClientCallbackImpl::setDvr(jweak dvrObj) {
@@ -810,10 +837,17 @@ void FilterClientCallbackImpl::onFilterEvent_1_1(const DemuxFilterEvent& filterE
} }
} }
} }
jobject filter(env->NewLocalRef(mFilterObj));
if (!env->IsSameObject(filter, nullptr)) {
env->CallVoidMethod( env->CallVoidMethod(
mFilterObj, filter,
gFields.onFilterEventID, gFields.onFilterEventID,
array); array);
} else {
ALOGE("FilterClientCallbackImpl::onFilterEvent_1_1:"
"Filter object has been freed. Ignoring callback.");
env->DeleteWeakGlobalRef(mFilterObj);
}
} }
void FilterClientCallbackImpl::onFilterEvent(const DemuxFilterEvent& filterEvent) { void FilterClientCallbackImpl::onFilterEvent(const DemuxFilterEvent& filterEvent) {
@@ -828,10 +862,17 @@ void FilterClientCallbackImpl::onFilterEvent(const DemuxFilterEvent& filterEvent
void FilterClientCallbackImpl::onFilterStatus(const DemuxFilterStatus status) { void FilterClientCallbackImpl::onFilterStatus(const DemuxFilterStatus status) {
ALOGD("FilterClientCallbackImpl::onFilterStatus"); ALOGD("FilterClientCallbackImpl::onFilterStatus");
JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = AndroidRuntime::getJNIEnv();
jobject filter(env->NewLocalRef(mFilterObj));
if (!env->IsSameObject(filter, nullptr)) {
env->CallVoidMethod( env->CallVoidMethod(
mFilterObj, filter,
gFields.onFilterStatusID, gFields.onFilterStatusID,
(jint)status); (jint)status);
} else {
ALOGE("FilterClientCallbackImpl::onFilterStatus:"
"Filter object has been freed. Ignoring callback.");
env->DeleteWeakGlobalRef(mFilterObj);
}
} }
void FilterClientCallbackImpl::setFilter(jweak filterObj, sp<FilterClient> filterClient) { void FilterClientCallbackImpl::setFilter(jweak filterObj, sp<FilterClient> filterClient) {
@@ -841,6 +882,15 @@ void FilterClientCallbackImpl::setFilter(jweak filterObj, sp<FilterClient> filte
mFilterClient = filterClient; mFilterClient = filterClient;
} }
FilterClientCallbackImpl::~FilterClientCallbackImpl() {
JNIEnv *env = AndroidRuntime::getJNIEnv();
if (mFilterObj != NULL) {
env->DeleteWeakGlobalRef(mFilterObj);
mFilterObj = NULL;
}
mFilterClient = NULL;
}
/////////////// FrontendClientCallbackImpl /////////////////////// /////////////// FrontendClientCallbackImpl ///////////////////////
FrontendClientCallbackImpl::FrontendClientCallbackImpl(jweak tunerObj) : mObject(tunerObj) {} FrontendClientCallbackImpl::FrontendClientCallbackImpl(jweak tunerObj) : mObject(tunerObj) {}
@@ -848,10 +898,17 @@ FrontendClientCallbackImpl::FrontendClientCallbackImpl(jweak tunerObj) : mObject
void FrontendClientCallbackImpl::onEvent(FrontendEventType frontendEventType) { void FrontendClientCallbackImpl::onEvent(FrontendEventType frontendEventType) {
ALOGD("FrontendClientCallbackImpl::onEvent, type=%d", frontendEventType); ALOGD("FrontendClientCallbackImpl::onEvent, type=%d", frontendEventType);
JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = AndroidRuntime::getJNIEnv();
jobject frontend(env->NewLocalRef(mObject));
if (!env->IsSameObject(frontend, nullptr)) {
env->CallVoidMethod( env->CallVoidMethod(
mObject, frontend,
gFields.onFrontendEventID, gFields.onFrontendEventID,
(jint)frontendEventType); (jint)frontendEventType);
} else {
ALOGE("FrontendClientCallbackImpl::onEvent:"
"Frontend object has been freed. Ignoring callback.");
env->DeleteWeakGlobalRef(mObject);
}
} }
void FrontendClientCallbackImpl::onScanMessage( void FrontendClientCallbackImpl::onScanMessage(
@@ -859,11 +916,18 @@ void FrontendClientCallbackImpl::onScanMessage(
ALOGD("FrontendClientCallbackImpl::onScanMessage, type=%d", type); ALOGD("FrontendClientCallbackImpl::onScanMessage, type=%d", type);
JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = AndroidRuntime::getJNIEnv();
jclass clazz = env->FindClass("android/media/tv/tuner/Tuner"); 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.");
env->DeleteWeakGlobalRef(mObject);
return;
}
switch(type) { switch(type) {
case FrontendScanMessageType::LOCKED: { case FrontendScanMessageType::LOCKED: {
if (message.isLocked()) { if (message.isLocked()) {
env->CallVoidMethod( env->CallVoidMethod(
mObject, frontend,
env->GetMethodID(clazz, "onLocked", "()V")); env->GetMethodID(clazz, "onLocked", "()V"));
} }
break; break;
@@ -871,14 +935,14 @@ void FrontendClientCallbackImpl::onScanMessage(
case FrontendScanMessageType::END: { case FrontendScanMessageType::END: {
if (message.isEnd()) { if (message.isEnd()) {
env->CallVoidMethod( env->CallVoidMethod(
mObject, frontend,
env->GetMethodID(clazz, "onScanStopped", "()V")); env->GetMethodID(clazz, "onScanStopped", "()V"));
} }
break; break;
} }
case FrontendScanMessageType::PROGRESS_PERCENT: { case FrontendScanMessageType::PROGRESS_PERCENT: {
env->CallVoidMethod( env->CallVoidMethod(
mObject, frontend,
env->GetMethodID(clazz, "onProgress", "(I)V"), env->GetMethodID(clazz, "onProgress", "(I)V"),
(jint) message.progressPercent()); (jint) message.progressPercent());
break; break;
@@ -889,7 +953,7 @@ void FrontendClientCallbackImpl::onScanMessage(
env->SetIntArrayRegion(freqs, 0, v.size(), reinterpret_cast<jint*>(&v[0])); env->SetIntArrayRegion(freqs, 0, v.size(), reinterpret_cast<jint*>(&v[0]));
env->CallVoidMethod( env->CallVoidMethod(
mObject, frontend,
env->GetMethodID(clazz, "onFrequenciesReport", "([I)V"), env->GetMethodID(clazz, "onFrequenciesReport", "([I)V"),
freqs); freqs);
break; break;
@@ -900,21 +964,21 @@ void FrontendClientCallbackImpl::onScanMessage(
env->SetIntArrayRegion(symbolRates, 0, v.size(), reinterpret_cast<jint*>(&v[0])); env->SetIntArrayRegion(symbolRates, 0, v.size(), reinterpret_cast<jint*>(&v[0]));
env->CallVoidMethod( env->CallVoidMethod(
mObject, frontend,
env->GetMethodID(clazz, "onSymbolRates", "([I)V"), env->GetMethodID(clazz, "onSymbolRates", "([I)V"),
symbolRates); symbolRates);
break; break;
} }
case FrontendScanMessageType::HIERARCHY: { case FrontendScanMessageType::HIERARCHY: {
env->CallVoidMethod( env->CallVoidMethod(
mObject, frontend,
env->GetMethodID(clazz, "onHierarchy", "(I)V"), env->GetMethodID(clazz, "onHierarchy", "(I)V"),
(jint) message.hierarchy()); (jint) message.hierarchy());
break; break;
} }
case FrontendScanMessageType::ANALOG_TYPE: { case FrontendScanMessageType::ANALOG_TYPE: {
env->CallVoidMethod( env->CallVoidMethod(
mObject, frontend,
env->GetMethodID(clazz, "onSignalType", "(I)V"), env->GetMethodID(clazz, "onSignalType", "(I)V"),
(jint) message.analogType()); (jint) message.analogType());
break; break;
@@ -926,7 +990,7 @@ void FrontendClientCallbackImpl::onScanMessage(
env->SetIntArrayRegion(plpIds, 0, jintV.size(), &jintV[0]); env->SetIntArrayRegion(plpIds, 0, jintV.size(), &jintV[0]);
env->CallVoidMethod( env->CallVoidMethod(
mObject, frontend,
env->GetMethodID(clazz, "onPlpIds", "([I)V"), env->GetMethodID(clazz, "onPlpIds", "([I)V"),
plpIds); plpIds);
break; break;
@@ -938,7 +1002,7 @@ void FrontendClientCallbackImpl::onScanMessage(
env->SetIntArrayRegion(groupIds, 0, jintV.size(), &jintV[0]); env->SetIntArrayRegion(groupIds, 0, jintV.size(), &jintV[0]);
env->CallVoidMethod( env->CallVoidMethod(
mObject, frontend,
env->GetMethodID(clazz, "onGroupIds", "([I)V"), env->GetMethodID(clazz, "onGroupIds", "([I)V"),
groupIds); groupIds);
break; break;
@@ -950,7 +1014,7 @@ void FrontendClientCallbackImpl::onScanMessage(
env->SetIntArrayRegion(streamIds, 0, jintV.size(), &jintV[0]); env->SetIntArrayRegion(streamIds, 0, jintV.size(), &jintV[0]);
env->CallVoidMethod( env->CallVoidMethod(
mObject, frontend,
env->GetMethodID(clazz, "onInputStreamIds", "([I)V"), env->GetMethodID(clazz, "onInputStreamIds", "([I)V"),
streamIds); streamIds);
break; break;
@@ -961,21 +1025,21 @@ void FrontendClientCallbackImpl::onScanMessage(
if (std.getDiscriminator() == FrontendScanMessage::Standard::hidl_discriminator::sStd) { if (std.getDiscriminator() == FrontendScanMessage::Standard::hidl_discriminator::sStd) {
standard = (jint) std.sStd(); standard = (jint) std.sStd();
env->CallVoidMethod( env->CallVoidMethod(
mObject, frontend,
env->GetMethodID(clazz, "onDvbsStandard", "(I)V"), env->GetMethodID(clazz, "onDvbsStandard", "(I)V"),
standard); standard);
} else if (std.getDiscriminator() == } else if (std.getDiscriminator() ==
FrontendScanMessage::Standard::hidl_discriminator::tStd) { FrontendScanMessage::Standard::hidl_discriminator::tStd) {
standard = (jint) std.tStd(); standard = (jint) std.tStd();
env->CallVoidMethod( env->CallVoidMethod(
mObject, frontend,
env->GetMethodID(clazz, "onDvbtStandard", "(I)V"), env->GetMethodID(clazz, "onDvbtStandard", "(I)V"),
standard); standard);
} else if (std.getDiscriminator() == } else if (std.getDiscriminator() ==
FrontendScanMessage::Standard::hidl_discriminator::sifStd) { FrontendScanMessage::Standard::hidl_discriminator::sifStd) {
standard = (jint) std.sifStd(); standard = (jint) std.sifStd();
env->CallVoidMethod( env->CallVoidMethod(
mObject, frontend,
env->GetMethodID(clazz, "onAnalogSifStandard", "(I)V"), env->GetMethodID(clazz, "onAnalogSifStandard", "(I)V"),
standard); standard);
} }
@@ -996,7 +1060,7 @@ void FrontendClientCallbackImpl::onScanMessage(
env->SetObjectArrayElement(array, i, obj); env->SetObjectArrayElement(array, i, obj);
} }
env->CallVoidMethod( env->CallVoidMethod(
mObject, frontend,
env->GetMethodID(clazz, "onAtsc3PlpInfos", env->GetMethodID(clazz, "onAtsc3PlpInfos",
"([Landroid/media/tv/tuner/frontend/Atsc3PlpInfo;)V"), "([Landroid/media/tv/tuner/frontend/Atsc3PlpInfo;)V"),
array); array);
@@ -1010,6 +1074,13 @@ void FrontendClientCallbackImpl::onScanMessageExt1_1(FrontendScanMessageTypeExt1
ALOGD("FrontendClientCallbackImpl::onScanMessageExt1_1, type=%d", type); ALOGD("FrontendClientCallbackImpl::onScanMessageExt1_1, type=%d", type);
JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = AndroidRuntime::getJNIEnv();
jclass clazz = env->FindClass("android/media/tv/tuner/Tuner"); jclass clazz = env->FindClass("android/media/tv/tuner/Tuner");
jobject frontend(env->NewLocalRef(mObject));
if (env->IsSameObject(frontend, nullptr)) {
ALOGE("FrontendClientCallbackImpl::onScanMessageExt1_1:"
"Frontend object has been freed. Ignoring callback.");
env->DeleteWeakGlobalRef(mObject);
return;
}
switch(type) { switch(type) {
case FrontendScanMessageTypeExt1_1::MODULATION: { case FrontendScanMessageTypeExt1_1::MODULATION: {
jint modulation = -1; jint modulation = -1;
@@ -1056,7 +1127,7 @@ void FrontendClientCallbackImpl::onScanMessageExt1_1(FrontendScanMessageTypeExt1
} }
if (modulation > 0) { if (modulation > 0) {
env->CallVoidMethod( env->CallVoidMethod(
mObject, frontend,
env->GetMethodID(clazz, "onModulationReported", "(I)V"), env->GetMethodID(clazz, "onModulationReported", "(I)V"),
modulation); modulation);
} }
@@ -1065,7 +1136,7 @@ void FrontendClientCallbackImpl::onScanMessageExt1_1(FrontendScanMessageTypeExt1
case FrontendScanMessageTypeExt1_1::HIGH_PRIORITY: { case FrontendScanMessageTypeExt1_1::HIGH_PRIORITY: {
bool isHighPriority = message.isHighPriority(); bool isHighPriority = message.isHighPriority();
env->CallVoidMethod( env->CallVoidMethod(
mObject, frontend,
env->GetMethodID(clazz, "onPriorityReported", "(B)V"), env->GetMethodID(clazz, "onPriorityReported", "(B)V"),
isHighPriority); isHighPriority);
break; break;
@@ -1073,7 +1144,7 @@ void FrontendClientCallbackImpl::onScanMessageExt1_1(FrontendScanMessageTypeExt1
case FrontendScanMessageTypeExt1_1::DVBC_ANNEX: { case FrontendScanMessageTypeExt1_1::DVBC_ANNEX: {
jint dvbcAnnex = (jint) message.annex(); jint dvbcAnnex = (jint) message.annex();
env->CallVoidMethod( env->CallVoidMethod(
mObject, frontend,
env->GetMethodID(clazz, "onDvbcAnnexReported", "(I)V"), env->GetMethodID(clazz, "onDvbcAnnexReported", "(I)V"),
dvbcAnnex); dvbcAnnex);
break; break;
@@ -1083,6 +1154,14 @@ void FrontendClientCallbackImpl::onScanMessageExt1_1(FrontendScanMessageTypeExt1
} }
} }
FrontendClientCallbackImpl::~FrontendClientCallbackImpl() {
JNIEnv *env = AndroidRuntime::getJNIEnv();
if (mObject != NULL) {
env->DeleteWeakGlobalRef(mObject);
mObject = NULL;
}
}
/////////////// Tuner /////////////////////// /////////////// Tuner ///////////////////////
sp<TunerClient> JTuner::mTunerClient; sp<TunerClient> JTuner::mTunerClient;

View File

@@ -118,6 +118,7 @@ struct MediaEvent : public RefBase {
}; };
struct FilterClientCallbackImpl : public FilterClientCallback { struct FilterClientCallbackImpl : public FilterClientCallback {
~FilterClientCallbackImpl();
virtual void onFilterEvent_1_1(const DemuxFilterEvent& filterEvent, virtual void onFilterEvent_1_1(const DemuxFilterEvent& filterEvent,
const DemuxFilterEventExt& filterEventExt); const DemuxFilterEventExt& filterEventExt);
virtual void onFilterEvent(const DemuxFilterEvent& filterEvent); virtual void onFilterEvent(const DemuxFilterEvent& filterEvent);
@@ -155,7 +156,7 @@ private:
struct FrontendClientCallbackImpl : public FrontendClientCallback { struct FrontendClientCallbackImpl : public FrontendClientCallback {
FrontendClientCallbackImpl(jweak tunerObj); FrontendClientCallbackImpl(jweak tunerObj);
~FrontendClientCallbackImpl();
virtual void onEvent(FrontendEventType frontendEventType); virtual void onEvent(FrontendEventType frontendEventType);
virtual void onScanMessage( virtual void onScanMessage(
FrontendScanMessageType type, const FrontendScanMessage& message); FrontendScanMessageType type, const FrontendScanMessage& message);