Skip to content

Commit c7a9fd5

Browse files
committed
fix: wait for Android camera session state
1 parent e226a61 commit c7a9fd5

1 file changed

Lines changed: 45 additions & 0 deletions

File tree

  • packages/react-native-vision-camera/android/src/main/java/com/margelo/nitro/camera/hybrids

packages/react-native-vision-camera/android/src/main/java/com/margelo/nitro/camera/hybrids/HybridCameraSession.kt

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import com.margelo.nitro.camera.session.toConfig
2828
import com.margelo.nitro.camera.utils.CustomLifecycle
2929
import com.margelo.nitro.camera.utils.DirectByteBufferPool
3030
import com.margelo.nitro.core.Promise
31+
import kotlinx.coroutines.CompletableDeferred
3132
import kotlinx.coroutines.CoroutineScope
3233
import kotlinx.coroutines.Dispatchers
3334

@@ -50,6 +51,8 @@ class HybridCameraSession(
5051
private var onErrorListeners = arrayListOf<(Throwable) -> Unit>()
5152
private var onInterruptionStartedListeners = arrayListOf<(InterruptionReason) -> Unit>()
5253
private var onInterruptionEndedListeners = arrayListOf<() -> Unit>()
54+
private var startWaiters = arrayListOf<CompletableDeferred<Unit>>()
55+
private var stopWaiters = arrayListOf<CompletableDeferred<Unit>>()
5356
private var currentCameraState = CameraState.Type.CLOSED
5457

5558
@SuppressLint("RestrictedApi")
@@ -139,13 +142,47 @@ class HybridCameraSession(
139142

140143
override fun start(): Promise<Unit> {
141144
return Promise.async(uiScope) {
145+
val startWaiter =
146+
if (activeSession?.isRunning == false) {
147+
CompletableDeferred<Unit>().also { startWaiters.add(it) }
148+
} else {
149+
null
150+
}
151+
142152
lifecycleOwner.setActive(true)
153+
154+
if (activeSession?.isRunning == true) {
155+
startWaiter?.complete(Unit)
156+
}
157+
158+
try {
159+
startWaiter?.await()
160+
} finally {
161+
startWaiter?.let { startWaiters.remove(it) }
162+
}
143163
}
144164
}
145165

146166
override fun stop(): Promise<Unit> {
147167
return Promise.async(uiScope) {
168+
val stopWaiter =
169+
if (activeSession?.isRunning == true) {
170+
CompletableDeferred<Unit>().also { stopWaiters.add(it) }
171+
} else {
172+
null
173+
}
174+
148175
lifecycleOwner.setActive(false)
176+
177+
if (activeSession?.isRunning == false) {
178+
stopWaiter?.complete(Unit)
179+
}
180+
181+
try {
182+
stopWaiter?.await()
183+
} finally {
184+
stopWaiter?.let { stopWaiters.remove(it) }
185+
}
149186
}
150187
}
151188

@@ -177,14 +214,22 @@ class HybridCameraSession(
177214
// pragma MARK: Lifecycle Changed Callbacks
178215

179216
override fun onStarted() {
217+
startWaiters.forEach { waiter -> waiter.complete(Unit) }
218+
startWaiters.clear()
180219
onStartedListeners.forEach { listener -> listener() }
181220
}
182221

183222
override fun onStopped() {
223+
stopWaiters.forEach { waiter -> waiter.complete(Unit) }
224+
stopWaiters.clear()
184225
onStoppedListeners.forEach { listener -> listener() }
185226
}
186227

187228
override fun onError(error: Throwable) {
229+
startWaiters.forEach { waiter -> waiter.completeExceptionally(error) }
230+
startWaiters.clear()
231+
stopWaiters.forEach { waiter -> waiter.completeExceptionally(error) }
232+
stopWaiters.clear()
188233
onErrorListeners.forEach { listener -> listener(error) }
189234
}
190235

0 commit comments

Comments
 (0)