@@ -36,6 +36,7 @@ import kotlinx.coroutines.flow.asStateFlow
3636import kotlinx.coroutines.launch
3737import kotlinx.coroutines.sync.Mutex
3838import kotlinx.coroutines.sync.withLock
39+ import kotlinx.coroutines.withContext
3940
4041/* *
4142 * Encapsulates device controller and session controller.
@@ -49,7 +50,8 @@ internal class CameraController(
4950) {
5051 private val sessionCompat = CameraCaptureSessionCompatBuilder .build(dispatcherProvider)
5152
52- private val coroutineScope = CoroutineScope (dispatcherProvider.default)
53+ private val defaultDispatcher = dispatcherProvider.default
54+ private val coroutineScope = CoroutineScope (defaultDispatcher)
5355 private var isActiveJob: Job ? = null
5456
5557 private var deviceController: CameraDeviceController ? = null
@@ -70,26 +72,26 @@ internal class CameraController(
7072 /* *
7173 * Whether the current capture session has the given output.
7274 */
73- suspend fun hasOutput (output : CameraSurface ): Boolean {
74- return controllerMutex.withLock { outputs.values.contains(output) }
75+ suspend fun hasOutput (output : CameraSurface ) = withContext(defaultDispatcher) {
76+ controllerMutex.withLock { outputs.values.contains(output) }
7577 }
7678
7779 /* *
7880 * Whether the current capture session has the given output.
7981 *
8082 * @param name The name of the output to check
8183 */
82- suspend fun hasOutput (name : String ): Boolean {
83- return controllerMutex.withLock { outputs.keys.contains(name) }
84+ suspend fun hasOutput (name : String ) = withContext(defaultDispatcher) {
85+ controllerMutex.withLock { outputs.keys.contains(name) }
8486 }
8587
8688 /* *
8789 * Gets an output from the current capture session.
8890 *
8991 * @param name The name of the output to get
9092 */
91- suspend fun getOutput (name : String ): CameraSurface ? {
92- return controllerMutex.withLock { outputs[name] }
93+ suspend fun getOutput (name : String ) = withContext(defaultDispatcher) {
94+ controllerMutex.withLock { outputs[name] }
9395 }
9496
9597 /* *
@@ -101,13 +103,15 @@ internal class CameraController(
101103 @RequiresPermission(Manifest .permission.CAMERA )
102104 suspend fun addOutput (output : CameraSurface ) {
103105 require(output.surface.isValid) { " Output is invalid: $output " }
104- controllerMutex.withLock {
105- if (outputs.values.contains(output)) {
106- return
107- }
108- outputs[output.name] = output
109- if (isActiveFlow.value) {
110- restartSessionUnsafe()
106+ withContext(defaultDispatcher) {
107+ controllerMutex.withLock {
108+ if (outputs.values.contains(output)) {
109+ return @withContext
110+ }
111+ outputs[output.name] = output
112+ if (isActiveFlow.value) {
113+ restartSessionUnsafe()
114+ }
111115 }
112116 }
113117 }
@@ -119,11 +123,13 @@ internal class CameraController(
119123 */
120124 @RequiresPermission(Manifest .permission.CAMERA )
121125 suspend fun removeOutput (name : String ) {
122- controllerMutex.withLock {
123- val needRestart = outputs.containsKey(name) && isActiveFlow.value
124- outputs.remove(name) != null
125- if (needRestart) {
126- restartSessionUnsafe()
126+ withContext(defaultDispatcher) {
127+ controllerMutex.withLock {
128+ val needRestart = outputs.containsKey(name) && isActiveFlow.value
129+ outputs.remove(name) != null
130+ if (needRestart) {
131+ restartSessionUnsafe()
132+ }
127133 }
128134 }
129135 }
@@ -195,18 +201,6 @@ internal class CameraController(
195201 }
196202 }
197203
198- /* *
199- * Restarts the current capture session.
200- *
201- * The current capture session is closed and a new one is created with the same outputs.
202- */
203- @RequiresPermission(Manifest .permission.CAMERA )
204- private suspend fun restartSession () {
205- controllerMutex.withLock {
206- restartSessionUnsafe()
207- }
208- }
209-
210204 /* *
211205 * Restarts the current capture session.
212206 *
@@ -241,8 +235,8 @@ internal class CameraController(
241235 * @return true if the target has been added, false otherwise
242236 */
243237 @RequiresPermission(Manifest .permission.CAMERA )
244- suspend fun addTarget (name : String ): Boolean {
245- return controllerMutex.withLock {
238+ suspend fun addTarget (name : String ) = withContext(defaultDispatcher) {
239+ controllerMutex.withLock {
246240 val sessionController = getSessionController()
247241 sessionController.addTarget(name)
248242 }
@@ -255,8 +249,8 @@ internal class CameraController(
255249 * @return true if the target has been added, false otherwise
256250 */
257251 @RequiresPermission(Manifest .permission.CAMERA )
258- suspend fun addTarget (target : CameraSurface ): Boolean {
259- return controllerMutex.withLock {
252+ suspend fun addTarget (target : CameraSurface ) = withContext(defaultDispatcher) {
253+ controllerMutex.withLock {
260254 val sessionController = getSessionController()
261255 sessionController.addTarget(target)
262256 }
@@ -269,8 +263,8 @@ internal class CameraController(
269263 * @return true if the targets have been added, false otherwise
270264 */
271265 @RequiresPermission(Manifest .permission.CAMERA )
272- suspend fun addTargets (targets : List <CameraSurface >): Boolean {
273- return controllerMutex.withLock {
266+ suspend fun addTargets (targets : List <CameraSurface >) = withContext(defaultDispatcher) {
267+ controllerMutex.withLock {
274268 val sessionController = getSessionController()
275269 sessionController.addTargets(targets)
276270 }
@@ -283,11 +277,13 @@ internal class CameraController(
283277 */
284278 @RequiresPermission(Manifest .permission.CAMERA )
285279 suspend fun removeTarget (target : CameraSurface ) {
286- controllerMutex.withLock {
287- val sessionController = getSessionController()
288- sessionController.removeTarget(target)
289- if (sessionController.isEmpty()) {
290- closeControllers()
280+ withContext(defaultDispatcher) {
281+ controllerMutex.withLock {
282+ val sessionController = getSessionController()
283+ sessionController.removeTarget(target)
284+ if (sessionController.isEmpty()) {
285+ closeControllers()
286+ }
291287 }
292288 }
293289 }
@@ -299,11 +295,13 @@ internal class CameraController(
299295 */
300296 @RequiresPermission(Manifest .permission.CAMERA )
301297 suspend fun removeTarget (name : String ) {
302- controllerMutex.withLock {
303- val sessionController = getSessionController()
304- sessionController.removeTarget(name)
305- if (sessionController.isEmpty()) {
306- closeControllers()
298+ withContext(defaultDispatcher) {
299+ controllerMutex.withLock {
300+ val sessionController = getSessionController()
301+ sessionController.removeTarget(name)
302+ if (sessionController.isEmpty()) {
303+ closeControllers()
304+ }
307305 }
308306 }
309307 }
@@ -335,19 +333,21 @@ internal class CameraController(
335333 * @param fpsRange The fps range
336334 */
337335 suspend fun setFps (fps : Int ) {
338- controllerMutex.withLock {
339- if (this .fps == fps) {
340- return
341- }
336+ withContext(defaultDispatcher) {
337+ controllerMutex.withLock {
338+ if (this @CameraController.fps == fps) {
339+ return @withContext
340+ }
342341
343- this .fps = fps
342+ this @CameraController .fps = fps
344343
345- if (isActiveFlow.value) {
346- val range = fpsRange
347- val minFrameDuration = 1_000_000_000 / range.upper.toLong()
348- setSetting(CaptureRequest .CONTROL_AE_TARGET_FPS_RANGE , range)
349- setSetting(CaptureRequest .SENSOR_FRAME_DURATION , minFrameDuration)
350- setRepeatingSession()
344+ if (isActiveFlow.value) {
345+ val range = fpsRange
346+ val minFrameDuration = 1_000_000_000 / range.upper.toLong()
347+ setSetting(CaptureRequest .CONTROL_AE_TARGET_FPS_RANGE , range)
348+ setSetting(CaptureRequest .SENSOR_FRAME_DURATION , minFrameDuration)
349+ setRepeatingSession()
350+ }
351351 }
352352 }
353353 }
@@ -359,17 +359,19 @@ internal class CameraController(
359359 */
360360 @RequiresPermission(Manifest .permission.CAMERA )
361361 suspend fun setDynamicRangeProfile (dynamicRangeProfile : DynamicRangeProfile ) {
362- val needRestart = controllerMutex.withLock {
363- if (this .dynamicRangeProfile == dynamicRangeProfile) {
364- return
365- }
366- Logger .d(TAG , " Setting dynamic range profile to $dynamicRangeProfile " )
362+ withContext(defaultDispatcher) {
363+ controllerMutex.withLock {
364+ if (this @CameraController.dynamicRangeProfile == dynamicRangeProfile) {
365+ return @withContext
366+ }
367+ Logger .d(TAG , " Setting dynamic range profile to $dynamicRangeProfile " )
367368
368- this .dynamicRangeProfile = dynamicRangeProfile
369- isActiveFlow.value
370- }
371- if (needRestart) {
372- restartSession()
369+ this @CameraController.dynamicRangeProfile = dynamicRangeProfile
370+
371+ if (isActiveFlow.value) {
372+ restartSessionUnsafe()
373+ }
374+ }
373375 }
374376 }
375377
@@ -398,9 +400,11 @@ internal class CameraController(
398400 }
399401
400402 suspend fun release () {
401- controllerMutex.withLock {
402- closeControllers()
403- sessionController = null
403+ withContext(defaultDispatcher) {
404+ controllerMutex.withLock {
405+ closeControllers()
406+ sessionController = null
407+ }
404408 }
405409 outputs.clear()
406410 sessionCompat.release()
0 commit comments