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

Commit c0682eaa authored by Vlad Popa's avatar Vlad Popa
Browse files

CTA2075: Fix possible race condition

When accessing the MediaCodecs from the audio service callback the
client can still change the codecs which are tracked for receiving
updates. Hence, lock the parameterupdate when iterating over the
loudness controller codecs.

Test: atest "CtsMediaAudioTestCases:android.media.audio.cts.LoudnessCodecControllerTest#multipleLcc_withRegisteredCodecs_triggerUpdate" --iterations 100
Bug: 321868864
Change-Id: I7aedc85d9d143497d089ae7f613f9fb5897f916d
parent c121002a
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -32,12 +32,13 @@ import androidx.annotation.Nullable;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;

/**
 * Class for getting recommended loudness parameter updates for audio decoders as they are used
@@ -339,9 +340,12 @@ public class LoudnessCodecController implements SafeCloseable {
    }

    /** @hide */
    /*package*/ Map<LoudnessCodecInfo, Set<MediaCodec>> getRegisteredMediaCodecs() {
    /*package*/ void mediaCodecsConsume(
            Consumer<Entry<LoudnessCodecInfo, Set<MediaCodec>>> consumer) {
        synchronized (mControllerLock) {
            return mMediaCodecs;
            for (Entry<LoudnessCodecInfo, Set<MediaCodec>> entry : mMediaCodecs.entrySet()) {
                consumer.accept(entry);
            }
        }
    }

+4 −6
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@ import androidx.annotation.NonNull;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
@@ -81,16 +80,15 @@ public class LoudnessCodecDispatcher implements CallbackUtil.DispatcherStub {
                    mConfiguratorListener.computeIfPresent(listener, (l, lcConfig) -> {
                        // send the appropriate bundle for the user to update
                        if (lcConfig.getSessionId() == sessionId) {
                            final Map<LoudnessCodecInfo, Set<MediaCodec>> mediaCodecsMap =
                                    lcConfig.getRegisteredMediaCodecs();
                            for (LoudnessCodecInfo codecInfo : mediaCodecsMap.keySet()) {
                            lcConfig.mediaCodecsConsume(mcEntry -> {
                                final LoudnessCodecInfo codecInfo = mcEntry.getKey();
                                final String infoKey = Integer.toString(codecInfo.hashCode());
                                Bundle bundle = null;
                                if (params.containsKey(infoKey)) {
                                    bundle = new Bundle(params.getPersistableBundle(infoKey));
                                }

                                final Set<MediaCodec> mediaCodecs = mediaCodecsMap.get(codecInfo);
                                final Set<MediaCodec> mediaCodecs = mcEntry.getValue();
                                for (MediaCodec mediaCodec : mediaCodecs) {
                                    final String mediaCodecKey = Integer.toString(
                                            mediaCodec.hashCode());
@@ -121,7 +119,7 @@ public class LoudnessCodecDispatcher implements CallbackUtil.DispatcherStub {
                                        break;
                                    }
                                }
                            }
                            });
                        }
                        return lcConfig;
                    });