mirror of
https://github.com/aljazceru/Android-nRF-Toolbox.git
synced 2025-12-19 23:44:24 +01:00
Fixed disconnection reason
This commit is contained in:
@@ -12,6 +12,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
import kotlinx.coroutines.flow.onCompletion
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -94,26 +95,17 @@ internal class ProfileService : NotificationService() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val job = lifecycleScope.launch {
|
val job = lifecycleScope.launch {
|
||||||
// Launch the initial connection attempt.
|
|
||||||
launch {
|
|
||||||
try {
|
try {
|
||||||
centralManager.connect(peripheral, options = ConnectionOptions.Direct())
|
centralManager.connect(peripheral, options = ConnectionOptions.Direct())
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Timber.e(e, "Failed to connect to $address")
|
Timber.e(e, "Failed to connect to $address")
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Observe connection state changes and react accordingly.
|
// Observe connection state changes and react accordingly.
|
||||||
observeConnectionState(peripheral)
|
observeConnectionState(peripheral)
|
||||||
}
|
}
|
||||||
|
|
||||||
managedConnections[address] = job
|
managedConnections[address] = job
|
||||||
job.invokeOnCompletion {
|
|
||||||
// Clean up when the management coroutine is cancelled.
|
|
||||||
handleDisconnection(address, "Job cancelled")
|
|
||||||
managedConnections.remove(address)
|
|
||||||
stopServiceIfNoDevices()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
@@ -136,7 +128,6 @@ internal class ProfileService : NotificationService() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
is ConnectionState.Disconnected -> {
|
is ConnectionState.Disconnected -> {
|
||||||
Timber.tag("AAAA").d("Disconnected State: ${peripheral.address}")
|
|
||||||
val reason = state.reason ?: DisconnectReason.UNKNOWN
|
val reason = state.reason ?: DisconnectReason.UNKNOWN
|
||||||
_disconnectionEvent.value =
|
_disconnectionEvent.value =
|
||||||
ServiceApi.DisconnectionEvent(
|
ServiceApi.DisconnectionEvent(
|
||||||
@@ -144,14 +135,17 @@ internal class ProfileService : NotificationService() {
|
|||||||
StateReason(reason as ConnectionState.Disconnected.Reason)
|
StateReason(reason as ConnectionState.Disconnected.Reason)
|
||||||
)
|
)
|
||||||
_devices.update { it - peripheral.address }
|
_devices.update { it - peripheral.address }
|
||||||
Timber.tag("AAA").d("Devices after disconnection: ${_devices.value.keys}")
|
|
||||||
handleDisconnection(peripheral.address, reason.toString())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
// Handle connecting/disconnecting states if needed
|
// Handle connecting/disconnecting states if needed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}.onCompletion {
|
||||||
|
handleDisconnection(peripheral.address)
|
||||||
|
managedConnections[peripheral.address]?.cancel()
|
||||||
|
managedConnections.remove(peripheral.address)
|
||||||
|
stopServiceIfNoDevices()
|
||||||
}.launchIn(this)
|
}.launchIn(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,8 +162,6 @@ internal class ProfileService : NotificationService() {
|
|||||||
ServiceManagerFactory
|
ServiceManagerFactory
|
||||||
.createServiceManager(removeService.uuid)
|
.createServiceManager(removeService.uuid)
|
||||||
?.also { manager ->
|
?.also { manager ->
|
||||||
Timber.tag("AAA")
|
|
||||||
.d("Found ServiceManager for service ${removeService.uuid}")
|
|
||||||
isMissing = false
|
isMissing = false
|
||||||
_devices.update {
|
_devices.update {
|
||||||
it + (peripheral.address to it[peripheral.address]!!.copy(
|
it + (peripheral.address to it[peripheral.address]!!.copy(
|
||||||
@@ -178,20 +170,15 @@ internal class ProfileService : NotificationService() {
|
|||||||
) ?: listOf(manager)
|
) ?: listOf(manager)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
// _isMissingServices.update { it - peripheral.address }
|
// Launch observation for each service.
|
||||||
scope.launch { // Launch observation for each service.
|
|
||||||
observeService(peripheral, removeService, manager)
|
observeService(peripheral, removeService, manager)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (isMissing != false) {
|
if (isMissing != false) {
|
||||||
Timber.tag("AAA").w("Peripheral ${peripheral.address} is missing services")
|
|
||||||
_isMissingServices.update { it + (peripheral.address to true) }
|
_isMissingServices.update { it + (peripheral.address to true) }
|
||||||
} else {
|
} else {
|
||||||
_isMissingServices.update { it - peripheral.address }
|
_isMissingServices.update { it - peripheral.address }
|
||||||
// If all required services are found, log it.
|
// If all required services are found, log it.
|
||||||
Timber.tag("AAA")
|
|
||||||
.d("Peripheral ${peripheral.address} has all required services")
|
|
||||||
}
|
}
|
||||||
}.launchIn(scope)
|
}.launchIn(scope)
|
||||||
|
|
||||||
@@ -218,19 +205,15 @@ internal class ProfileService : NotificationService() {
|
|||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
try {
|
try {
|
||||||
peripheral.disconnect()
|
peripheral.disconnect()
|
||||||
handleDisconnection(address, "Disconnected by user")
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Timber.e(e, "Failed to disconnect from $address")
|
Timber.e(e, "Failed to disconnect from $address")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
managedConnections[address]?.cancel()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleDisconnection(address: String, reason: String) {
|
private fun handleDisconnection(address: String) {
|
||||||
Timber.d("Handling disconnection for $address, reason: $reason")
|
|
||||||
_devices.update { it - address }
|
_devices.update { it - address }
|
||||||
Timber.tag("AAA").d("Devices after disconnection: ${_devices.value.keys}")
|
|
||||||
_isMissingServices.update { it - address }
|
_isMissingServices.update { it - address }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ internal class ProfileViewModel @Inject constructor(
|
|||||||
val uiState: StateFlow<ProfileUiState> = _uiState.asStateFlow()
|
val uiState: StateFlow<ProfileUiState> = _uiState.asStateFlow()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
Timber.tag("AAA PVM").d("Initializing ViewModel for device: $address")
|
|
||||||
connectToPeripheral()
|
connectToPeripheral()
|
||||||
observeConnectedDevices()
|
observeConnectedDevices()
|
||||||
Timber.plant(logger)
|
Timber.plant(logger)
|
||||||
@@ -72,9 +71,6 @@ internal class ProfileViewModel @Inject constructor(
|
|||||||
) { devices, missingServicesMap, disconnection ->
|
) { devices, missingServicesMap, disconnection ->
|
||||||
val deviceData = devices[address]
|
val deviceData = devices[address]
|
||||||
val isMissingServices = missingServicesMap[address] ?: false
|
val isMissingServices = missingServicesMap[address] ?: false
|
||||||
Timber.tag("AAA PVM")
|
|
||||||
.d("DeviceData for $address: $deviceData, MissingServices: $isMissingServices, $deviceData")
|
|
||||||
|
|
||||||
// Determine the UI state based on the service's state
|
// Determine the UI state based on the service's state
|
||||||
if (deviceData != null) {
|
if (deviceData != null) {
|
||||||
// Update connected device info in the repository
|
// Update connected device info in the repository
|
||||||
@@ -89,8 +85,6 @@ internal class ProfileViewModel @Inject constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
deviceRepository.updateConnectedDevices(devices)
|
deviceRepository.updateConnectedDevices(devices)
|
||||||
|
|
||||||
// // Create the Connected state
|
|
||||||
val currentMaxVal =
|
val currentMaxVal =
|
||||||
(_uiState.value as? ProfileUiState.Connected)?.maxValueLength
|
(_uiState.value as? ProfileUiState.Connected)?.maxValueLength
|
||||||
ProfileUiState.Connected(deviceData, isMissingServices, currentMaxVal)
|
ProfileUiState.Connected(deviceData, isMissingServices, currentMaxVal)
|
||||||
@@ -134,7 +128,6 @@ internal class ProfileViewModel @Inject constructor(
|
|||||||
ConnectionEvent.NavigateUp -> {
|
ConnectionEvent.NavigateUp -> {
|
||||||
// Disconnect only if services are missing, otherwise leave connected
|
// Disconnect only if services are missing, otherwise leave connected
|
||||||
if ((_uiState.value as? ProfileUiState.Connected)?.isMissingServices == true) {
|
if ((_uiState.value as? ProfileUiState.Connected)?.isMissingServices == true) {
|
||||||
Timber.tag("BBB").d("Disconnecting due to missing services")
|
|
||||||
serviceApi?.disconnect(address)
|
serviceApi?.disconnect(address)
|
||||||
}
|
}
|
||||||
navigator.navigateUp()
|
navigator.navigateUp()
|
||||||
|
|||||||
Reference in New Issue
Block a user