Skip to content

Commit d846086

Browse files
Fixed data race in CameraEventsDispatchHandler (#822)
1 parent b538e56 commit d846086

2 files changed

Lines changed: 14 additions & 16 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"client-sdk-android": patch
3+
---
4+
5+
Fixed data race in `CameraEventsDispatchHandler` by using `CopyOnWriteArraySet` for thread-safe iteration.

livekit-android-sdk/src/main/java/io/livekit/android/room/track/video/CameraEventsDispatchHandler.kt

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023-2024 LiveKit, Inc.
2+
* Copyright 2023-2025 LiveKit, Inc.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,61 +17,54 @@
1717
package io.livekit.android.room.track.video
1818

1919
import livekit.org.webrtc.CameraVideoCapturer.CameraEventsHandler
20+
import java.util.concurrent.CopyOnWriteArraySet
2021

2122
/**
2223
* Dispatches CameraEventsHandler callbacks to registered handlers.
2324
*/
2425
class CameraEventsDispatchHandler : CameraEventsHandler {
25-
private val handlers = mutableSetOf<CameraEventsHandler>()
26+
private val handlers = CopyOnWriteArraySet<CameraEventsHandler>()
2627

27-
@Synchronized
2828
fun registerHandler(handler: CameraEventsHandler) {
2929
handlers.add(handler)
3030
}
3131

32-
@Synchronized
3332
fun unregisterHandler(handler: CameraEventsHandler) {
3433
handlers.remove(handler)
3534
}
3635

3736
override fun onCameraError(errorDescription: String) {
38-
val handlersCopy = handlers.toMutableSet()
39-
for (handler in handlersCopy) {
37+
for (handler in handlers) {
4038
handler.onCameraError(errorDescription)
4139
}
4240
}
4341

4442
override fun onCameraDisconnected() {
45-
val handlersCopy = handlers.toMutableSet()
46-
for (handler in handlersCopy) {
43+
for (handler in handlers) {
4744
handler.onCameraDisconnected()
4845
}
4946
}
5047

5148
override fun onCameraFreezed(errorDescription: String) {
52-
val handlersCopy = handlers.toMutableSet()
53-
for (handler in handlersCopy) {
49+
for (handler in handlers) {
5450
handler.onCameraFreezed(errorDescription)
5551
}
5652
}
5753

5854
override fun onCameraOpening(cameraName: String) {
59-
val handlersCopy = handlers.toMutableSet()
60-
for (handler in handlersCopy) {
55+
for (handler in handlers) {
6156
handler.onCameraOpening(cameraName)
6257
}
6358
}
6459

6560
override fun onFirstFrameAvailable() {
66-
val handlersCopy = handlers.toMutableSet()
67-
for (handler in handlersCopy) {
61+
for (handler in handlers) {
6862
handler.onFirstFrameAvailable()
6963
}
7064
}
7165

7266
override fun onCameraClosed() {
73-
val handlersCopy = handlers.toMutableSet()
74-
for (handler in handlersCopy) {
67+
for (handler in handlers) {
7568
handler.onCameraClosed()
7669
}
7770
}

0 commit comments

Comments
 (0)