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

Commit 2a1a52ce authored by Dichen Zhang's avatar Dichen Zhang
Browse files

Fix addAudioDeviceCallback() memory leak bug

Store jobjects and JObjectHolders as backup, delete JObjectHolders after
usage

Bug: 128341809
Test: RoutingTest#test_MediaPlayer2_RoutingChangedCallback
Change-Id: I70b2312519ab0efef0ed40ce721ae8c26dc1aed2
parent d9c99eaf
Loading
Loading
Loading
Loading
+12 −11
Original line number Original line Diff line number Diff line
@@ -571,10 +571,9 @@ status_t JAudioTrack::removeAudioDeviceCallback(jobject listener) {
}
}


void JAudioTrack::registerRoutingDelegates(
void JAudioTrack::registerRoutingDelegates(
        Vector<std::pair<jobject, jobject>>& routingDelegates) {
        Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& routingDelegates) {
    for (Vector<std::pair<jobject, jobject>>::iterator it = routingDelegates.begin();
    for (auto it = routingDelegates.begin(); it != routingDelegates.end(); it++) {
            it != routingDelegates.end(); it++) {
        addAudioDeviceCallback(it->second->getJObject(), getHandler(it->second->getJObject()));
        addAudioDeviceCallback(it->second, getHandler(it->second));
    }
    }
}
}


@@ -597,20 +596,22 @@ jobject JAudioTrack::getHandler(const jobject routingDelegateObj) {
    return env->CallObjectMethod(routingDelegateObj, jGetHandler);
    return env->CallObjectMethod(routingDelegateObj, jGetHandler);
}
}


jobject JAudioTrack::findByKey(Vector<std::pair<jobject, jobject>>& mp, const jobject key) {
jobject JAudioTrack::findByKey(
        Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& mp, const jobject key) {
    JNIEnv *env = JavaVMHelper::getJNIEnv();
    JNIEnv *env = JavaVMHelper::getJNIEnv();
    for (Vector<std::pair<jobject, jobject>>::iterator it = mp.begin(); it != mp.end(); it++) {
    for (auto it = mp.begin(); it != mp.end(); it++) {
        if (env->IsSameObject(it->first, key)) {
        if (env->IsSameObject(it->first->getJObject(), key)) {
            return it->second;
            return it->second->getJObject();
        }
        }
    }
    }
    return nullptr;
    return nullptr;
}
}


void JAudioTrack::eraseByKey(Vector<std::pair<jobject, jobject>>& mp, const jobject key) {
void JAudioTrack::eraseByKey(
        Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& mp, const jobject key) {
    JNIEnv *env = JavaVMHelper::getJNIEnv();
    JNIEnv *env = JavaVMHelper::getJNIEnv();
    for (Vector<std::pair<jobject, jobject>>::iterator it = mp.begin(); it != mp.end(); it++) {
    for (auto it = mp.begin(); it != mp.end(); it++) {
        if (env->IsSameObject(it->first, key)) {
        if (env->IsSameObject(it->first->getJObject(), key)) {
            mp.erase(it);
            mp.erase(it);
            return;
            return;
        }
        }
+10 −7
Original line number Original line Diff line number Diff line
@@ -521,15 +521,18 @@ jobject MediaPlayer2AudioOutput::getRoutedDevice() {
status_t MediaPlayer2AudioOutput::addAudioDeviceCallback(jobject jRoutingDelegate) {
status_t MediaPlayer2AudioOutput::addAudioDeviceCallback(jobject jRoutingDelegate) {
    ALOGV("addAudioDeviceCallback");
    ALOGV("addAudioDeviceCallback");
    Mutex::Autolock lock(mLock);
    Mutex::Autolock lock(mLock);
    jobject listener = (new JObjectHolder(
    jobject listener = JAudioTrack::getListener(jRoutingDelegate);
            JAudioTrack::getListener(jRoutingDelegate)))->getJObject();
    if (JAudioTrack::findByKey(mRoutingDelegates, listener) == nullptr) {
    if (JAudioTrack::findByKey(mRoutingDelegates, listener) == nullptr) {
        jobject handler = (new JObjectHolder(
        sp<JObjectHolder> listenerHolder = new JObjectHolder(listener);
                JAudioTrack::getHandler(jRoutingDelegate)))->getJObject();
        jobject handler = JAudioTrack::getHandler(jRoutingDelegate);
        jobject routingDelegate = (new JObjectHolder(jRoutingDelegate))->getJObject();
        sp<JObjectHolder> routingDelegateHolder = new JObjectHolder(jRoutingDelegate);
        mRoutingDelegates.push_back(std::pair<jobject, jobject>(listener, routingDelegate));

        mRoutingDelegates.push_back(std::pair<sp<JObjectHolder>, sp<JObjectHolder>>(
                listenerHolder, routingDelegateHolder));

        if (mJAudioTrack != nullptr) {
        if (mJAudioTrack != nullptr) {
            return mJAudioTrack->addAudioDeviceCallback(routingDelegate, handler);
            return mJAudioTrack->addAudioDeviceCallback(
                    routingDelegateHolder->getJObject(), handler);
        }
        }
    }
    }
    return NO_ERROR;
    return NO_ERROR;
+6 −3
Original line number Original line Diff line number Diff line
@@ -405,7 +405,8 @@ public:
     * routingDelegates: backed-up routing delegates
     * routingDelegates: backed-up routing delegates
     *
     *
     */
     */
    void registerRoutingDelegates(Vector<std::pair<jobject, jobject>>& routingDelegates);
    void registerRoutingDelegates(
            Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& routingDelegates);


    /* get listener from RoutingDelegate object
    /* get listener from RoutingDelegate object
     */
     */
@@ -422,13 +423,15 @@ public:
     * Returns value if key is in the map
     * Returns value if key is in the map
     *         nullptr if key is not in the map
     *         nullptr if key is not in the map
     */
     */
    static jobject findByKey(Vector<std::pair<jobject, jobject>>& mp, const jobject key);
    static jobject findByKey(
            Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& mp, const jobject key);


    /*
    /*
     * Parameters:
     * Parameters:
     * map and key
     * map and key
     */
     */
    static void eraseByKey(Vector<std::pair<jobject, jobject>>& mp, const jobject key);
    static void eraseByKey(
            Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>>& mp, const jobject key);


private:
private:
    audio_output_flags_t mFlags;
    audio_output_flags_t mFlags;
+3 −1
Original line number Original line Diff line number Diff line
@@ -124,7 +124,9 @@ private:
    audio_output_flags_t    mFlags;
    audio_output_flags_t    mFlags;
    sp<JObjectHolder>       mPreferredDevice;
    sp<JObjectHolder>       mPreferredDevice;
    mutable Mutex           mLock;
    mutable Mutex           mLock;
    Vector<std::pair<jobject, jobject>> mRoutingDelegates; // <listener, routingDelegate>

    // <listener, routingDelegate>
    Vector<std::pair<sp<JObjectHolder>, sp<JObjectHolder>>> mRoutingDelegates;


    // static variables below not protected by mutex
    // static variables below not protected by mutex
    static bool             mIsOnEmulator;
    static bool             mIsOnEmulator;