combov2: Wait for coroutines to finish in onStop()
This commit is contained in:
parent
2cdc4c45ea
commit
fe1235dbe1
1 changed files with 53 additions and 31 deletions
|
@ -134,8 +134,8 @@ class ComboV2Plugin @Inject constructor (
|
||||||
|
|
||||||
// Coroutine scope and the associated job. All coroutines
|
// Coroutine scope and the associated job. All coroutines
|
||||||
// that are started in this plugin are part of this scope.
|
// that are started in this plugin are part of this scope.
|
||||||
private val pumpCoroutineMainJob = SupervisorJob()
|
private var pumpCoroutineScopeJob = SupervisorJob()
|
||||||
private val pumpCoroutineScope = CoroutineScope(Dispatchers.Default + pumpCoroutineMainJob)
|
private var pumpCoroutineScope = CoroutineScope(Dispatchers.Default + pumpCoroutineScopeJob)
|
||||||
|
|
||||||
private val _pumpDescription = PumpDescription()
|
private val _pumpDescription = PumpDescription()
|
||||||
|
|
||||||
|
@ -255,6 +255,8 @@ class ComboV2Plugin @Inject constructor (
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
|
aapsLogger.info(LTag.PUMP, "Starting combov2 driver")
|
||||||
|
|
||||||
super.onStart()
|
super.onStart()
|
||||||
|
|
||||||
updateComboCtlLogLevel()
|
updateComboCtlLogLevel()
|
||||||
|
@ -290,49 +292,63 @@ class ComboV2Plugin @Inject constructor (
|
||||||
aapsLogger.debug(LTag.PUMP, "Creating bluetooth interface")
|
aapsLogger.debug(LTag.PUMP, "Creating bluetooth interface")
|
||||||
bluetoothInterface = AndroidBluetoothInterface(context)
|
bluetoothInterface = AndroidBluetoothInterface(context)
|
||||||
|
|
||||||
|
aapsLogger.info(LTag.PUMP, "Continuing combov2 driver start in coroutine")
|
||||||
|
|
||||||
// Continue initialization in a separate coroutine. This allows us to call
|
// Continue initialization in a separate coroutine. This allows us to call
|
||||||
// runWithPermissionCheck(), which will keep trying to run the code block
|
// runWithPermissionCheck(), which will keep trying to run the code block
|
||||||
// until either the necessary Bluetooth permissions are granted, or the
|
// until either the necessary Bluetooth permissions are granted, or the
|
||||||
// coroutine is cancelled (see onStop() below).
|
// coroutine is cancelled (see onStop() below).
|
||||||
pumpCoroutineScope.launch {
|
pumpCoroutineScope.launch {
|
||||||
runWithPermissionCheck(
|
try {
|
||||||
context, config, aapsLogger, androidPermission,
|
runWithPermissionCheck(
|
||||||
permissionsToCheckFor = listOf("android.permission.BLUETOOTH_CONNECT")
|
context, config, aapsLogger, androidPermission,
|
||||||
) {
|
permissionsToCheckFor = listOf("android.permission.BLUETOOTH_CONNECT")
|
||||||
aapsLogger.debug(LTag.PUMP, "Setting up bluetooth interface")
|
) {
|
||||||
bluetoothInterface!!.setup()
|
aapsLogger.debug(LTag.PUMP, "Setting up bluetooth interface")
|
||||||
|
bluetoothInterface!!.setup()
|
||||||
|
|
||||||
aapsLogger.debug(LTag.PUMP, "Setting up pump manager")
|
aapsLogger.debug(LTag.PUMP, "Setting up pump manager")
|
||||||
pumpManager = ComboCtlPumpManager(bluetoothInterface!!, pumpStateStore)
|
pumpManager = ComboCtlPumpManager(bluetoothInterface!!, pumpStateStore)
|
||||||
pumpManager!!.setup {
|
pumpManager!!.setup {
|
||||||
_pairedStateUIFlow.value = false
|
_pairedStateUIFlow.value = false
|
||||||
unpairing = false
|
unpairing = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// UI flows that must have defined values right
|
||||||
|
// at start are initialized here.
|
||||||
|
|
||||||
|
// The paired state UI flow is special in that it is also
|
||||||
|
// used as the backing store for the isPaired() function,
|
||||||
|
// so setting up that UI state flow equals updating that
|
||||||
|
// paired state.
|
||||||
|
val paired = pumpManager!!.getPairedPumpAddresses().isNotEmpty()
|
||||||
|
_pairedStateUIFlow.value = paired
|
||||||
|
|
||||||
|
setDriverState(DriverState.Disconnected)
|
||||||
|
|
||||||
|
aapsLogger.info(LTag.PUMP, "combov2 driver start complete")
|
||||||
|
|
||||||
|
// NOTE: EventInitializationChanged is sent in getPumpStatus() .
|
||||||
}
|
}
|
||||||
|
} catch (e: CancellationException) {
|
||||||
// UI flows that must have defined values right
|
aapsLogger.info(LTag.PUMP, "combov2 driver start cancelled")
|
||||||
// at start are initialized here.
|
throw e
|
||||||
|
|
||||||
// The paired state UI flow is special in that it is also
|
|
||||||
// used as the backing store for the isPaired() function,
|
|
||||||
// so setting up that UI state flow equals updating that
|
|
||||||
// paired state.
|
|
||||||
val paired = pumpManager!!.getPairedPumpAddresses().isNotEmpty()
|
|
||||||
_pairedStateUIFlow.value = paired
|
|
||||||
|
|
||||||
setDriverState(DriverState.Disconnected)
|
|
||||||
|
|
||||||
// NOTE: EventInitializationChanged is sent in getPumpStatus() .
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStop() {
|
override fun onStop() {
|
||||||
// Cancel any ongoing background coroutines. This includes an ongoing
|
aapsLogger.info(LTag.PUMP, "Stopping combov2 driver")
|
||||||
// unfinished initialization that still waits for the user to grant
|
|
||||||
// Bluetooth permissions.
|
|
||||||
pumpCoroutineScope.cancel()
|
|
||||||
|
|
||||||
runBlocking {
|
runBlocking {
|
||||||
|
// Cancel any ongoing background coroutines. This includes an ongoing
|
||||||
|
// unfinished initialization that still waits for the user to grant
|
||||||
|
// Bluetooth permissions. Also join to wait for the coroutines to
|
||||||
|
// finish. Otherwise, race conditions can occur, for example, when
|
||||||
|
// a coroutine tries to access bluetoothInterface right after it
|
||||||
|
// was torn down below.
|
||||||
|
pumpCoroutineScopeJob.cancelAndJoin()
|
||||||
|
|
||||||
// Normally this should not happen, but to be safe,
|
// Normally this should not happen, but to be safe,
|
||||||
// make sure any running pump instance is disconnected.
|
// make sure any running pump instance is disconnected.
|
||||||
pump?.disconnect()
|
pump?.disconnect()
|
||||||
|
@ -353,7 +369,13 @@ class ComboV2Plugin @Inject constructor (
|
||||||
rxBus.send(EventInitializationChanged())
|
rxBus.send(EventInitializationChanged())
|
||||||
initializationChangedEventSent = false
|
initializationChangedEventSent = false
|
||||||
|
|
||||||
|
// The old job and scope were completed. We need new ones.
|
||||||
|
pumpCoroutineScopeJob = SupervisorJob()
|
||||||
|
pumpCoroutineScope = CoroutineScope(Dispatchers.Default + pumpCoroutineScopeJob)
|
||||||
|
|
||||||
super.onStop()
|
super.onStop()
|
||||||
|
|
||||||
|
aapsLogger.info(LTag.PUMP, "combov2 driver stopped")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun preprocessPreferences(preferenceFragment: PreferenceFragmentCompat) {
|
override fun preprocessPreferences(preferenceFragment: PreferenceFragmentCompat) {
|
||||||
|
|
Loading…
Reference in a new issue