From c0682eaa0a85f722858be4767f5452afc26efb04 Mon Sep 17 00:00:00 2001 From: Vlad Popa Date: Tue, 23 Jan 2024 16:09:49 -0800 Subject: 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 --- media/java/android/media/LoudnessCodecController.java | 10 +++++++--- media/java/android/media/LoudnessCodecDispatcher.java | 10 ++++------ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/media/java/android/media/LoudnessCodecController.java b/media/java/android/media/LoudnessCodecController.java index b3e5c52b27b3..836b228cb6f9 100644 --- a/media/java/android/media/LoudnessCodecController.java +++ b/media/java/android/media/LoudnessCodecController.java @@ -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> getRegisteredMediaCodecs() { + /*package*/ void mediaCodecsConsume( + Consumer>> consumer) { synchronized (mControllerLock) { - return mMediaCodecs; + for (Entry> entry : mMediaCodecs.entrySet()) { + consumer.accept(entry); + } } } diff --git a/media/java/android/media/LoudnessCodecDispatcher.java b/media/java/android/media/LoudnessCodecDispatcher.java index 46be54be55ec..fa08658a214f 100644 --- a/media/java/android/media/LoudnessCodecDispatcher.java +++ b/media/java/android/media/LoudnessCodecDispatcher.java @@ -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> 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 mediaCodecs = mediaCodecsMap.get(codecInfo); + final Set 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; }); -- cgit v1.2.3-59-g8ed1b