summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Vlad Popa <pvlad@google.com> 2024-01-23 16:09:49 -0800
committer Vlad Popa <pvlad@google.com> 2024-01-23 16:12:40 -0800
commitc0682eaa0a85f722858be4767f5452afc26efb04 (patch)
tree97202d1e8bab63fdb9f42925b83ec31ca6036f74
parentc121002af86ffb7a24489268da05b35dd647d1df (diff)
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
-rw-r--r--media/java/android/media/LoudnessCodecController.java10
-rw-r--r--media/java/android/media/LoudnessCodecDispatcher.java10
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<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);
+ }
}
}
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<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;
});