Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 03c3d6bc authored by Ray Chin's avatar Ray Chin
Browse files

Fix FilterClientCallbackImpl race condition

When changing the tuner source (e.g. recording playback to live
viewing), the FilterClientCallbackImpl will be recreated. When releasing
it, the thread sending filter events may still be running depend on the
HAL implementation. We should synchronous the filter event thread and
release thread to avoid the crash in Tuner framework.

Bug: 365688825
Test: test on cf_x86_tv
Flag: EXEMPT bugfix
Change-Id: I84e1d315730fc904b1083a8291c074f0d9d50195
parent 9d3450ca
Loading
Loading
Loading
Loading
+19 −7
Original line number Diff line number Diff line
@@ -701,6 +701,9 @@ void FilterClientCallbackImpl::getMediaEvent(const jobjectArray& arr, const int

    // Protect mFilterClient from being set to null.
    android::Mutex::Autolock autoLock(mLock);
    if (mFilterClient == nullptr) {
        return;
    }
    uint64_t avSharedMemSize = mFilterClient->getAvSharedHandleInfo().size;
    if (mediaEvent.avMemory.fds.size() > 0 || mediaEvent.avDataId != 0 ||
        (dataLength > 0 && (dataLength + offset) < avSharedMemSize)) {
@@ -868,10 +871,18 @@ void FilterClientCallbackImpl::getRestartEvent(const jobjectArray& arr, const in
void FilterClientCallbackImpl::onFilterEvent(const vector<DemuxFilterEvent> &events) {
    ALOGV("FilterClientCallbackImpl::onFilterEvent");
    JNIEnv *env = AndroidRuntime::getJNIEnv();

    ScopedLocalRef<jobjectArray> array(env);

    if (!events.empty()) {
        array.reset(env->NewObjectArray(events.size(), mEventClass, nullptr));
        if (env->IsSameObject(array.get(), nullptr)) {
            // It can happen when FilterClientCallbackImpl release the resource
            // in another thread.
            ALOGE("FilterClientCallbackImpl::onFilterEvent:"
                  "Unable to create object array of filter events. Ignoring callback.");
            return;
        }
    }

    for (int i = 0, arraySize = 0; i < events.size(); i++) {
@@ -1070,14 +1081,15 @@ FilterClientCallbackImpl::FilterClientCallbackImpl() {

FilterClientCallbackImpl::~FilterClientCallbackImpl() {
    JNIEnv *env = AndroidRuntime::getJNIEnv();
    {

    android::Mutex::Autolock autoLock(mLock);

    if (mFilterObj != nullptr) {
        env->DeleteWeakGlobalRef(mFilterObj);
        mFilterObj = nullptr;
    }
    mFilterClient = nullptr;
    }

    env->DeleteGlobalRef(mEventClass);
    env->DeleteGlobalRef(mSectionEventClass);
    env->DeleteGlobalRef(mMediaEventClass);