From fb5c2730af5616310ccbf6f3c409fb1863dc1589 Mon Sep 17 00:00:00 2001 From: Sylwester Zielinski Date: Thu, 4 May 2023 15:12:21 +0200 Subject: [PATCH] Add missing services message --- .../nordicsemi/android/bps/view/BPSScreen.kt | 2 +- .../android/bps/view/BPSViewState.kt | 13 ++++++++++-- .../android/bps/viewmodel/BPSViewModel.kt | 14 +++++++++++-- .../android/cgms/data/CGMServiceData.kt | 13 ++++++++++-- .../android/cgms/repository/CGMRepository.kt | 5 +++++ .../android/cgms/repository/CGMService.kt | 2 +- .../nordicsemi/android/cgms/view/CGMScreen.kt | 2 +- .../android/csc/data/CSCServiceData.kt | 13 ++++++++++-- .../android/csc/repository/CSCRepository.kt | 5 +++++ .../android/csc/repository/CSCService.kt | 2 +- .../nordicsemi/android/csc/view/CSCScreen.kt | 2 +- .../android/gls/main/view/GLSScreen.kt | 2 +- .../android/gls/main/view/GLSViewState.kt | 10 +++++++++- .../gls/main/viewmodel/GLSViewModel.kt | 14 +++++++++++-- .../android/hrs/data/HRSServiceData.kt | 11 +++++++++- .../android/hrs/service/HRSRepository.kt | 5 +++++ .../android/hrs/service/HRSService.kt | 2 +- .../nordicsemi/android/hrs/view/HRSScreen.kt | 2 +- .../android/hts/data/HTSServiceData.kt | 13 ++++++++++-- .../android/hts/repository/HTSRepository.kt | 20 +++++++++++++------ .../android/hts/repository/HTSService.kt | 15 ++------------ .../nordicsemi/android/hts/view/HTSScreen.kt | 2 +- .../android/prx/data/PRXServiceData.kt | 9 ++++++++- .../android/prx/repository/PRXRepository.kt | 5 +++++ .../android/prx/repository/PRXService.kt | 12 ++++++----- .../nordicsemi/android/prx/view/PRXScreen.kt | 2 +- .../android/rscs/data/RSCSServiceData.kt | 11 +++++++++- .../android/rscs/repository/RSCSRepository.kt | 5 +++++ .../android/rscs/repository/RSCSService.kt | 2 +- .../android/rscs/view/RSCSScreen.kt | 2 +- .../android/rscs/viewmodel/RSCSViewModel.kt | 7 +++++++ .../android/uart/data/UARTServiceData.kt | 10 +++++++++- .../android/uart/repository/UARTRepository.kt | 5 +++++ .../android/uart/repository/UARTService.kt | 11 +--------- .../android/uart/view/UARTScreen.kt | 2 +- 35 files changed, 188 insertions(+), 64 deletions(-) diff --git a/profile_bps/src/main/java/no/nordicsemi/android/bps/view/BPSScreen.kt b/profile_bps/src/main/java/no/nordicsemi/android/bps/view/BPSScreen.kt index 2abb728c..da253bdb 100644 --- a/profile_bps/src/main/java/no/nordicsemi/android/bps/view/BPSScreen.kt +++ b/profile_bps/src/main/java/no/nordicsemi/android/bps/view/BPSScreen.kt @@ -80,7 +80,7 @@ fun BPSScreen() { null, GattConnectionState.STATE_CONNECTING -> DeviceConnectingView { NavigateUpButton(navigateUp) } GattConnectionState.STATE_DISCONNECTED, - GattConnectionState.STATE_DISCONNECTING -> DeviceDisconnectedView(state.result.connectionState.status) { + GattConnectionState.STATE_DISCONNECTING -> DeviceDisconnectedView(state.disconnectStatus) { NavigateUpButton(navigateUp) } GattConnectionState.STATE_CONNECTED -> BPSContentView(state.result) { viewModel.onEvent(it) } diff --git a/profile_bps/src/main/java/no/nordicsemi/android/bps/view/BPSViewState.kt b/profile_bps/src/main/java/no/nordicsemi/android/bps/view/BPSViewState.kt index 23c10d02..4b9d617b 100644 --- a/profile_bps/src/main/java/no/nordicsemi/android/bps/view/BPSViewState.kt +++ b/profile_bps/src/main/java/no/nordicsemi/android/bps/view/BPSViewState.kt @@ -32,8 +32,17 @@ package no.nordicsemi.android.bps.view import no.nordicsemi.android.bps.data.BPSServiceData +import no.nordicsemi.android.kotlin.ble.core.data.BleGattConnectionStatus internal data class BPSViewState( val result: BPSServiceData = BPSServiceData(), - val deviceName: String? = null -) + val deviceName: String? = null, + val missingServices: Boolean = false +) { + + val disconnectStatus = if (missingServices) { + BleGattConnectionStatus.NOT_SUPPORTED + } else { + result.connectionState?.status ?: BleGattConnectionStatus.UNKNOWN + } +} diff --git a/profile_bps/src/main/java/no/nordicsemi/android/bps/viewmodel/BPSViewModel.kt b/profile_bps/src/main/java/no/nordicsemi/android/bps/viewmodel/BPSViewModel.kt index d6c38aa9..ccd99d4d 100644 --- a/profile_bps/src/main/java/no/nordicsemi/android/bps/viewmodel/BPSViewModel.kt +++ b/profile_bps/src/main/java/no/nordicsemi/android/bps/viewmodel/BPSViewModel.kt @@ -112,11 +112,16 @@ internal class BPSViewModel @Inject constructor( fun onEvent(event: BPSViewEvent) { when (event) { - DisconnectEvent -> navigationManager.navigateUp() + DisconnectEvent -> onDisconnectEvent() OpenLoggerEvent -> logger.launch() } } + private fun onDisconnectEvent() { + client.disconnect() + navigationManager.navigateUp() + } + private fun startGattClient(device: ServerDevice) = viewModelScope.launch { _state.value = _state.value.copy(deviceName = device.name) @@ -139,7 +144,7 @@ internal class BPSViewModel @Inject constructor( client.discoverServices() .filterNotNull() .onEach { configureGatt(it) } - .catch { it.printStackTrace() } + .catch { onMissingServices() } .launchIn(viewModelScope) } @@ -169,6 +174,11 @@ internal class BPSViewModel @Inject constructor( ?.launchIn(viewModelScope) } + private fun onMissingServices() { + _state.value = _state.value.copy(missingServices = true) + client.disconnect() + } + private fun onDataUpdate(connectionState: GattConnectionStateWithStatus) { val newResult = _state.value.result.copy(connectionState = connectionState) _state.value = _state.value.copy(result = newResult) diff --git a/profile_cgms/src/main/java/no/nordicsemi/android/cgms/data/CGMServiceData.kt b/profile_cgms/src/main/java/no/nordicsemi/android/cgms/data/CGMServiceData.kt index 2307c447..7c7133f1 100644 --- a/profile_cgms/src/main/java/no/nordicsemi/android/cgms/data/CGMServiceData.kt +++ b/profile_cgms/src/main/java/no/nordicsemi/android/cgms/data/CGMServiceData.kt @@ -1,5 +1,6 @@ package no.nordicsemi.android.cgms.data +import no.nordicsemi.android.kotlin.ble.core.data.BleGattConnectionStatus import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionStateWithStatus import no.nordicsemi.android.kotlin.ble.profile.cgm.data.CGMRecord import no.nordicsemi.android.kotlin.ble.profile.gls.data.RequestStatus @@ -9,8 +10,16 @@ internal data class CGMServiceData( val batteryLevel: Int? = null, val connectionState: GattConnectionStateWithStatus? = null, val requestStatus: RequestStatus = RequestStatus.IDLE, - val deviceName: String? = null -) + val deviceName: String? = null, + val missingServices: Boolean = false +) { + + val disconnectStatus = if (missingServices) { + BleGattConnectionStatus.NOT_SUPPORTED + } else { + connectionState?.status ?: BleGattConnectionStatus.UNKNOWN + } +} data class CGMRecordWithSequenceNumber( val sequenceNumber: Int, diff --git a/profile_cgms/src/main/java/no/nordicsemi/android/cgms/repository/CGMRepository.kt b/profile_cgms/src/main/java/no/nordicsemi/android/cgms/repository/CGMRepository.kt index 451c16fb..1320fce0 100644 --- a/profile_cgms/src/main/java/no/nordicsemi/android/cgms/repository/CGMRepository.kt +++ b/profile_cgms/src/main/java/no/nordicsemi/android/cgms/repository/CGMRepository.kt @@ -115,6 +115,11 @@ class CGMRepository @Inject constructor( _data.value = _data.value.copy(requestStatus = requestStatus) } + fun onMissingServices() { + _data.value = _data.value.copy(missingServices = true) + _stopEvent.tryEmit(DisconnectAndStopEvent()) + } + fun openLogger() { _loggerEvent.tryEmit(OpenLoggerEvent()) } diff --git a/profile_cgms/src/main/java/no/nordicsemi/android/cgms/repository/CGMService.kt b/profile_cgms/src/main/java/no/nordicsemi/android/cgms/repository/CGMService.kt index 781a729e..d52eedb5 100644 --- a/profile_cgms/src/main/java/no/nordicsemi/android/cgms/repository/CGMService.kt +++ b/profile_cgms/src/main/java/no/nordicsemi/android/cgms/repository/CGMService.kt @@ -157,7 +157,7 @@ internal class CGMService : NotificationService() { client.discoverServices() .filterNotNull() .onEach { configureGatt(it) } - .catch { it.printStackTrace() } + .catch { repository.onMissingServices() } .launchIn(lifecycleScope) } diff --git a/profile_cgms/src/main/java/no/nordicsemi/android/cgms/view/CGMScreen.kt b/profile_cgms/src/main/java/no/nordicsemi/android/cgms/view/CGMScreen.kt index 121759ae..8cbd1b8d 100644 --- a/profile_cgms/src/main/java/no/nordicsemi/android/cgms/view/CGMScreen.kt +++ b/profile_cgms/src/main/java/no/nordicsemi/android/cgms/view/CGMScreen.kt @@ -81,7 +81,7 @@ fun CGMScreen() { GattConnectionState.STATE_CONNECTING -> DeviceConnectingView { NavigateUpButton(navigateUp) } GattConnectionState.STATE_DISCONNECTED, - GattConnectionState.STATE_DISCONNECTING -> DeviceDisconnectedView(state.connectionState.status) { + GattConnectionState.STATE_DISCONNECTING -> DeviceDisconnectedView(state.disconnectStatus) { NavigateUpButton(navigateUp) } diff --git a/profile_csc/src/main/java/no/nordicsemi/android/csc/data/CSCServiceData.kt b/profile_csc/src/main/java/no/nordicsemi/android/csc/data/CSCServiceData.kt index 917c90df..1bb81d26 100644 --- a/profile_csc/src/main/java/no/nordicsemi/android/csc/data/CSCServiceData.kt +++ b/profile_csc/src/main/java/no/nordicsemi/android/csc/data/CSCServiceData.kt @@ -1,5 +1,6 @@ package no.nordicsemi.android.csc.data +import no.nordicsemi.android.kotlin.ble.core.data.BleGattConnectionStatus import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionStateWithStatus import no.nordicsemi.android.kotlin.ble.profile.csc.data.CSCData @@ -8,5 +9,13 @@ internal data class CSCServiceData( val batteryLevel: Int? = null, val connectionState: GattConnectionStateWithStatus? = null, val speedUnit: SpeedUnit = SpeedUnit.M_S, - val deviceName: String? = null -) + val deviceName: String? = null, + val missingServices: Boolean = false +) { + + val disconnectStatus = if (missingServices) { + BleGattConnectionStatus.NOT_SUPPORTED + } else { + connectionState?.status ?: BleGattConnectionStatus.UNKNOWN + } +} diff --git a/profile_csc/src/main/java/no/nordicsemi/android/csc/repository/CSCRepository.kt b/profile_csc/src/main/java/no/nordicsemi/android/csc/repository/CSCRepository.kt index 152b0eb9..f74f5e05 100644 --- a/profile_csc/src/main/java/no/nordicsemi/android/csc/repository/CSCRepository.kt +++ b/profile_csc/src/main/java/no/nordicsemi/android/csc/repository/CSCRepository.kt @@ -114,6 +114,11 @@ class CSCRepository @Inject constructor( _data.value = _data.value.copy(data = cscData) } + fun onMissingServices() { + _data.value = _data.value.copy(missingServices = true) + _stopEvent.tryEmit(DisconnectAndStopEvent()) + } + fun openLogger() { _loggerEvent.tryEmit(OpenLoggerEvent()) } diff --git a/profile_csc/src/main/java/no/nordicsemi/android/csc/repository/CSCService.kt b/profile_csc/src/main/java/no/nordicsemi/android/csc/repository/CSCService.kt index f50726ad..1a5878d6 100644 --- a/profile_csc/src/main/java/no/nordicsemi/android/csc/repository/CSCService.kt +++ b/profile_csc/src/main/java/no/nordicsemi/android/csc/repository/CSCService.kt @@ -112,7 +112,7 @@ internal class CSCService : NotificationService() { client.discoverServices() .filterNotNull() .onEach { configureGatt(it) } - .catch { it.printStackTrace() } + .catch { repository.onMissingServices() } .launchIn(lifecycleScope) } diff --git a/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCScreen.kt b/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCScreen.kt index 578b168b..7b6a9a9a 100644 --- a/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCScreen.kt +++ b/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCScreen.kt @@ -80,7 +80,7 @@ fun CSCScreen() { null, GattConnectionState.STATE_CONNECTING -> DeviceConnectingView { NavigateUpButton(navigateUp) } GattConnectionState.STATE_DISCONNECTED, - GattConnectionState.STATE_DISCONNECTING -> DeviceDisconnectedView(state.connectionState.status) { + GattConnectionState.STATE_DISCONNECTING -> DeviceDisconnectedView(state.disconnectStatus) { NavigateUpButton(navigateUp) } GattConnectionState.STATE_CONNECTED -> CSCContentView(state) { viewModel.onEvent(it) } diff --git a/profile_gls/src/main/java/no/nordicsemi/android/gls/main/view/GLSScreen.kt b/profile_gls/src/main/java/no/nordicsemi/android/gls/main/view/GLSScreen.kt index b8ecd090..cb5d84e9 100644 --- a/profile_gls/src/main/java/no/nordicsemi/android/gls/main/view/GLSScreen.kt +++ b/profile_gls/src/main/java/no/nordicsemi/android/gls/main/view/GLSScreen.kt @@ -80,7 +80,7 @@ fun GLSScreen() { null, GattConnectionState.STATE_CONNECTING -> DeviceConnectingView { NavigateUpButton(navigateUp) } GattConnectionState.STATE_DISCONNECTED, - GattConnectionState.STATE_DISCONNECTING -> DeviceDisconnectedView(state.glsServiceData.connectionState.status) { + GattConnectionState.STATE_DISCONNECTING -> DeviceDisconnectedView(state.disconnectStatus) { NavigateUpButton(navigateUp) } GattConnectionState.STATE_CONNECTED -> GLSContentView(state.glsServiceData) { viewModel.onEvent(it) } diff --git a/profile_gls/src/main/java/no/nordicsemi/android/gls/main/view/GLSViewState.kt b/profile_gls/src/main/java/no/nordicsemi/android/gls/main/view/GLSViewState.kt index fd157f73..9d5125c3 100644 --- a/profile_gls/src/main/java/no/nordicsemi/android/gls/main/view/GLSViewState.kt +++ b/profile_gls/src/main/java/no/nordicsemi/android/gls/main/view/GLSViewState.kt @@ -32,6 +32,7 @@ package no.nordicsemi.android.gls.main.view import no.nordicsemi.android.gls.data.GLSServiceData +import no.nordicsemi.android.kotlin.ble.core.data.BleGattConnectionStatus import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionStateWithStatus import no.nordicsemi.android.kotlin.ble.profile.gls.data.GLSMeasurementContext import no.nordicsemi.android.kotlin.ble.profile.gls.data.GLSRecord @@ -39,9 +40,16 @@ import no.nordicsemi.android.kotlin.ble.profile.gls.data.RequestStatus internal data class GLSViewState( val glsServiceData: GLSServiceData = GLSServiceData(), - val deviceName: String? = null + val deviceName: String? = null, + val missingServices: Boolean = false ) { + val disconnectStatus = if (missingServices) { + BleGattConnectionStatus.NOT_SUPPORTED + } else { + glsServiceData.connectionState?.status ?: BleGattConnectionStatus.UNKNOWN + } + fun copyWithNewConnectionState(connectionState: GattConnectionStateWithStatus): GLSViewState { return copy(glsServiceData = glsServiceData.copy(connectionState = connectionState)) } diff --git a/profile_gls/src/main/java/no/nordicsemi/android/gls/main/viewmodel/GLSViewModel.kt b/profile_gls/src/main/java/no/nordicsemi/android/gls/main/viewmodel/GLSViewModel.kt index 50917bff..8a34c0bd 100644 --- a/profile_gls/src/main/java/no/nordicsemi/android/gls/main/viewmodel/GLSViewModel.kt +++ b/profile_gls/src/main/java/no/nordicsemi/android/gls/main/viewmodel/GLSViewModel.kt @@ -137,10 +137,15 @@ internal class GLSViewModel @Inject constructor( OpenLoggerEvent -> logger.launch() is OnWorkingModeSelected -> onEvent(event) is OnGLSRecordClick -> navigateToDetails(event.record) - DisconnectEvent -> navigationManager.navigateUp() + DisconnectEvent -> onDisconnectEvent() } } + private fun onDisconnectEvent() { + client.disconnect() + navigationManager.navigateUp() + } + private fun navigateToDetails(record: GLSRecord) { val context = state.value.glsServiceData.records[record] navigationManager.navigateTo(GlsDetailsDestinationId, record to context) @@ -180,10 +185,15 @@ internal class GLSViewModel @Inject constructor( client.discoverServices() .filterNotNull() .onEach { configureGatt(it) } - .catch { it.printStackTrace() } + .catch { onMissingServices() } .launchIn(viewModelScope) } + private fun onMissingServices() { + _state.value = state.value.copy(missingServices = true) + client.disconnect() + } + private fun logAnalytics(connectionState: GattConnectionStateWithStatus) { if (connectionState.state == GattConnectionState.STATE_CONNECTED) { analytics.logEvent(ProfileConnectedEvent(Profile.GLS)) diff --git a/profile_hrs/src/main/java/no/nordicsemi/android/hrs/data/HRSServiceData.kt b/profile_hrs/src/main/java/no/nordicsemi/android/hrs/data/HRSServiceData.kt index 59043ad6..b86fce95 100644 --- a/profile_hrs/src/main/java/no/nordicsemi/android/hrs/data/HRSServiceData.kt +++ b/profile_hrs/src/main/java/no/nordicsemi/android/hrs/data/HRSServiceData.kt @@ -31,6 +31,7 @@ package no.nordicsemi.android.hrs.data +import no.nordicsemi.android.kotlin.ble.core.data.BleGattConnectionStatus import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionStateWithStatus import no.nordicsemi.android.kotlin.ble.profile.hrs.data.HRSData @@ -40,7 +41,15 @@ internal data class HRSServiceData( val batteryLevel: Int? = null, val connectionState: GattConnectionStateWithStatus? = null, val zoomIn: Boolean = false, - val deviceName: String? = null + val deviceName: String? = null, + val missingServices: Boolean = false ) { + + val disconnectStatus = if (missingServices) { + BleGattConnectionStatus.NOT_SUPPORTED + } else { + connectionState?.status ?: BleGattConnectionStatus.UNKNOWN + } + val heartRates = data.map { it.heartRate } } diff --git a/profile_hrs/src/main/java/no/nordicsemi/android/hrs/service/HRSRepository.kt b/profile_hrs/src/main/java/no/nordicsemi/android/hrs/service/HRSRepository.kt index e2df0947..c6f9b810 100644 --- a/profile_hrs/src/main/java/no/nordicsemi/android/hrs/service/HRSRepository.kt +++ b/profile_hrs/src/main/java/no/nordicsemi/android/hrs/service/HRSRepository.kt @@ -111,6 +111,11 @@ class HRSRepository @Inject constructor( _data.value = _data.value.copy(batteryLevel = batteryLevel) } + fun onMissingServices() { + _data.value = _data.value.copy(missingServices = true) + _stopEvent.tryEmit(DisconnectAndStopEvent()) + } + fun openLogger() { _loggerEvent.tryEmit(OpenLoggerEvent()) } diff --git a/profile_hrs/src/main/java/no/nordicsemi/android/hrs/service/HRSService.kt b/profile_hrs/src/main/java/no/nordicsemi/android/hrs/service/HRSService.kt index acdecd09..4d1f66a8 100644 --- a/profile_hrs/src/main/java/no/nordicsemi/android/hrs/service/HRSService.kt +++ b/profile_hrs/src/main/java/no/nordicsemi/android/hrs/service/HRSService.kt @@ -116,7 +116,7 @@ internal class HRSService : NotificationService() { client.discoverServices() .filterNotNull() .onEach { configureGatt(it) } - .catch { it.printStackTrace() } + .catch { repository.onMissingServices() } .launchIn(lifecycleScope) } diff --git a/profile_hrs/src/main/java/no/nordicsemi/android/hrs/view/HRSScreen.kt b/profile_hrs/src/main/java/no/nordicsemi/android/hrs/view/HRSScreen.kt index 2416e1ae..70b67d4a 100644 --- a/profile_hrs/src/main/java/no/nordicsemi/android/hrs/view/HRSScreen.kt +++ b/profile_hrs/src/main/java/no/nordicsemi/android/hrs/view/HRSScreen.kt @@ -80,7 +80,7 @@ fun HRSScreen() { null, GattConnectionState.STATE_CONNECTING -> DeviceConnectingView { NavigateUpButton(navigateUp) } GattConnectionState.STATE_DISCONNECTED, - GattConnectionState.STATE_DISCONNECTING -> DeviceDisconnectedView(state.connectionState.status) { + GattConnectionState.STATE_DISCONNECTING -> DeviceDisconnectedView(state.disconnectStatus) { NavigateUpButton(navigateUp) } GattConnectionState.STATE_CONNECTED -> HRSContentView(state) { viewModel.onEvent(it) } diff --git a/profile_hts/src/main/java/no/nordicsemi/android/hts/data/HTSServiceData.kt b/profile_hts/src/main/java/no/nordicsemi/android/hts/data/HTSServiceData.kt index e16453b7..d56e3f85 100644 --- a/profile_hts/src/main/java/no/nordicsemi/android/hts/data/HTSServiceData.kt +++ b/profile_hts/src/main/java/no/nordicsemi/android/hts/data/HTSServiceData.kt @@ -32,6 +32,7 @@ package no.nordicsemi.android.hts.data import no.nordicsemi.android.hts.view.TemperatureUnit +import no.nordicsemi.android.kotlin.ble.core.data.BleGattConnectionStatus import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionStateWithStatus import no.nordicsemi.android.kotlin.ble.profile.hts.data.HTSData @@ -40,5 +41,13 @@ internal data class HTSServiceData( val batteryLevel: Int? = null, val connectionState: GattConnectionStateWithStatus? = null, val temperatureUnit: TemperatureUnit = TemperatureUnit.CELSIUS, - val deviceName: String? = null -) + val deviceName: String? = null, + val missingServices: Boolean = false +) { + + val disconnectStatus = if (missingServices) { + BleGattConnectionStatus.NOT_SUPPORTED + } else { + connectionState?.status ?: BleGattConnectionStatus.UNKNOWN + } +} diff --git a/profile_hts/src/main/java/no/nordicsemi/android/hts/repository/HTSRepository.kt b/profile_hts/src/main/java/no/nordicsemi/android/hts/repository/HTSRepository.kt index 73b336f0..e1714b94 100644 --- a/profile_hts/src/main/java/no/nordicsemi/android/hts/repository/HTSRepository.kt +++ b/profile_hts/src/main/java/no/nordicsemi/android/hts/repository/HTSRepository.kt @@ -46,8 +46,8 @@ import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionStateWithStatus import no.nordicsemi.android.kotlin.ble.profile.hts.data.HTSData import no.nordicsemi.android.service.DisconnectAndStopEvent -import no.nordicsemi.android.service.OpenLoggerEvent import no.nordicsemi.android.service.ServiceManager +import no.nordicsemi.android.ui.view.StringConst import javax.inject.Inject import javax.inject.Singleton @@ -55,7 +55,8 @@ import javax.inject.Singleton class HTSRepository @Inject constructor( @ApplicationContext private val context: Context, - private val serviceManager: ServiceManager + private val serviceManager: ServiceManager, + private val stringConst: StringConst ) { private var logger: NordicBlekLogger? = null @@ -65,9 +66,6 @@ class HTSRepository @Inject constructor( private val _stopEvent = simpleSharedFlow() internal val stopEvent = _stopEvent.asSharedFlow() - private val _loggerEvent = simpleSharedFlow() - internal val loggerEvent = _loggerEvent.asSharedFlow() - val isRunning = data.map { it.connectionState?.state == GattConnectionState.STATE_CONNECTED } private var isOnScreen = false @@ -89,6 +87,7 @@ class HTSRepository @Inject constructor( fun launch(device: ServerDevice) { _data.value = _data.value.copy(deviceName = device.name) + logger = NordicBlekLogger(context, stringConst.APP_NAME, "HTS", device.address) serviceManager.startService(HTSService::class.java, device) } @@ -109,13 +108,22 @@ class HTSRepository @Inject constructor( } fun openLogger() { - _loggerEvent.tryEmit(OpenLoggerEvent()) + logger?.launch() + } + + fun log(priority: Int, message: String) { + logger?.log(priority, message) } fun disconnect() { _stopEvent.tryEmit(DisconnectAndStopEvent()) } + fun onMissingServices() { + _data.value = _data.value.copy(missingServices = true) + _stopEvent.tryEmit(DisconnectAndStopEvent()) + } + private fun clean() { logger = null _data.value = HTSServiceData() diff --git a/profile_hts/src/main/java/no/nordicsemi/android/hts/repository/HTSService.kt b/profile_hts/src/main/java/no/nordicsemi/android/hts/repository/HTSService.kt index 0abb94f8..9a0e9cf5 100644 --- a/profile_hts/src/main/java/no/nordicsemi/android/hts/repository/HTSService.kt +++ b/profile_hts/src/main/java/no/nordicsemi/android/hts/repository/HTSService.kt @@ -41,7 +41,6 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch -import no.nordicsemi.android.common.logger.NordicBlekLogger import no.nordicsemi.android.kotlin.ble.client.main.callback.BleGattClient import no.nordicsemi.android.kotlin.ble.client.main.connect import no.nordicsemi.android.kotlin.ble.client.main.service.BleGattServices @@ -52,7 +51,6 @@ import no.nordicsemi.android.kotlin.ble.profile.battery.BatteryLevelParser import no.nordicsemi.android.kotlin.ble.profile.hts.HTSDataParser import no.nordicsemi.android.service.DEVICE_DATA import no.nordicsemi.android.service.NotificationService -import no.nordicsemi.android.ui.view.StringConst import java.util.* import javax.inject.Inject @@ -69,9 +67,6 @@ internal class HTSService : NotificationService() { @Inject lateinit var repository: HTSRepository - @Inject - lateinit var stringConst: StringConst - private lateinit var client: BleGattClient override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { @@ -91,16 +86,10 @@ internal class HTSService : NotificationService() { } private fun startGattClient(device: ServerDevice) = lifecycleScope.launch { - val logger = NordicBlekLogger(this@HTSService, stringConst.APP_NAME, "HTS", device.address) - - client = device.connect(this@HTSService, logger = logger) + client = device.connect(this@HTSService, logger = { p, s -> repository.log(p, s) }) client.waitForBonding() - repository.loggerEvent - .onEach { logger.launch() } - .launchIn(lifecycleScope) - client.connectionStateWithStatus .onEach { repository.onConnectionStateChanged(it) } .filterNotNull() @@ -114,7 +103,7 @@ internal class HTSService : NotificationService() { client.discoverServices() .filterNotNull() .onEach { configureGatt(it) } - .catch { it.printStackTrace() } + .catch { repository.onMissingServices() } .launchIn(lifecycleScope) } diff --git a/profile_hts/src/main/java/no/nordicsemi/android/hts/view/HTSScreen.kt b/profile_hts/src/main/java/no/nordicsemi/android/hts/view/HTSScreen.kt index 1c259915..f1b7bcdf 100644 --- a/profile_hts/src/main/java/no/nordicsemi/android/hts/view/HTSScreen.kt +++ b/profile_hts/src/main/java/no/nordicsemi/android/hts/view/HTSScreen.kt @@ -80,7 +80,7 @@ fun HTSScreen() { null, GattConnectionState.STATE_CONNECTING -> DeviceConnectingView { NavigateUpButton(navigateUp) } GattConnectionState.STATE_DISCONNECTED, - GattConnectionState.STATE_DISCONNECTING -> DeviceDisconnectedView(state.connectionState.status) { + GattConnectionState.STATE_DISCONNECTING -> DeviceDisconnectedView(state.disconnectStatus) { NavigateUpButton(navigateUp) } GattConnectionState.STATE_CONNECTED -> HTSContentView(state) { viewModel.onEvent(it) } diff --git a/profile_prx/src/main/java/no/nordicsemi/android/prx/data/PRXServiceData.kt b/profile_prx/src/main/java/no/nordicsemi/android/prx/data/PRXServiceData.kt index 5d20f4b2..7787532f 100644 --- a/profile_prx/src/main/java/no/nordicsemi/android/prx/data/PRXServiceData.kt +++ b/profile_prx/src/main/java/no/nordicsemi/android/prx/data/PRXServiceData.kt @@ -11,8 +11,15 @@ data class PRXServiceData( val connectionState: GattConnectionStateWithStatus? = null, val connectionStatus: BleGattConnectionStatus? = null, val isRemoteAlarm: Boolean = false, - val deviceName: String? = null + val deviceName: String? = null, + val missingServices: Boolean = false ) { + val disconnectStatus = if (missingServices) { + BleGattConnectionStatus.NOT_SUPPORTED + } else { + connectionState?.status ?: BleGattConnectionStatus.UNKNOWN + } + val isLinkLossDisconnected = connectionStatus?.isLinkLoss ?: false } diff --git a/profile_prx/src/main/java/no/nordicsemi/android/prx/repository/PRXRepository.kt b/profile_prx/src/main/java/no/nordicsemi/android/prx/repository/PRXRepository.kt index 748f8c57..01421843 100644 --- a/profile_prx/src/main/java/no/nordicsemi/android/prx/repository/PRXRepository.kt +++ b/profile_prx/src/main/java/no/nordicsemi/android/prx/repository/PRXRepository.kt @@ -121,6 +121,11 @@ class PRXRepository @Inject internal constructor( _loggerEvent.tryEmit(OpenLoggerEvent()) } + fun onMissingServices() { + _data.value = _data.value.copy(missingServices = true) + _stopEvent.tryEmit(DisconnectAndStopEvent()) + } + fun disconnect() { _remoteAlarmLevel.tryEmit(AlarmLevel.NONE) _stopEvent.tryEmit(DisconnectAndStopEvent()) diff --git a/profile_prx/src/main/java/no/nordicsemi/android/prx/repository/PRXService.kt b/profile_prx/src/main/java/no/nordicsemi/android/prx/repository/PRXService.kt index 4753d277..e1226158 100644 --- a/profile_prx/src/main/java/no/nordicsemi/android/prx/repository/PRXService.kt +++ b/profile_prx/src/main/java/no/nordicsemi/android/prx/repository/PRXService.kt @@ -90,7 +90,7 @@ internal class PRXService : NotificationService() { private lateinit var client: BleGattClient private lateinit var server: BleGattServer - private lateinit var alertLevelCharacteristic: BleGattCharacteristic + private var alertLevelCharacteristic: BleGattCharacteristic? = null override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { super.onStartCommand(intent, flags, startId) @@ -185,7 +185,7 @@ internal class PRXService : NotificationService() { client.discoverServices() .filterNotNull() .onEach { configureGatt(it) } - .catch { it.printStackTrace() } + .catch { repository.onMissingServices() } .launchIn(lifecycleScope) repository.remoteAlarmLevel @@ -212,9 +212,11 @@ internal class PRXService : NotificationService() { private suspend fun writeAlertLevel(alarmLevel: AlarmLevel) { try { - alertLevelCharacteristic.write(AlertLevelInputParser.parse(alarmLevel), BleWriteType.NO_RESPONSE) - repository.onRemoteAlarmLevelSet(alarmLevel) - } catch (e: GattOperationException) { + alertLevelCharacteristic?.run { + write(AlertLevelInputParser.parse(alarmLevel), BleWriteType.NO_RESPONSE) + repository.onRemoteAlarmLevelSet(alarmLevel) + } + } catch (e: Exception) { e.printStackTrace() } } diff --git a/profile_prx/src/main/java/no/nordicsemi/android/prx/view/PRXScreen.kt b/profile_prx/src/main/java/no/nordicsemi/android/prx/view/PRXScreen.kt index aaa1faa7..7fb84f6d 100644 --- a/profile_prx/src/main/java/no/nordicsemi/android/prx/view/PRXScreen.kt +++ b/profile_prx/src/main/java/no/nordicsemi/android/prx/view/PRXScreen.kt @@ -80,7 +80,7 @@ fun PRXScreen() { null, GattConnectionState.STATE_CONNECTING -> DeviceConnectingView { NavigateUpButton(navigateUp) } GattConnectionState.STATE_DISCONNECTED, - GattConnectionState.STATE_DISCONNECTING -> DeviceDisconnectedView(state.connectionState.status) { + GattConnectionState.STATE_DISCONNECTING -> DeviceDisconnectedView(state.disconnectStatus) { NavigateUpButton(navigateUp) } GattConnectionState.STATE_CONNECTED -> ContentView(state) { viewModel.onEvent(it) } diff --git a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/data/RSCSServiceData.kt b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/data/RSCSServiceData.kt index 5ac52c91..6251a857 100644 --- a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/data/RSCSServiceData.kt +++ b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/data/RSCSServiceData.kt @@ -33,6 +33,7 @@ package no.nordicsemi.android.rscs.data import androidx.compose.runtime.Composable import androidx.compose.ui.res.stringResource +import no.nordicsemi.android.kotlin.ble.core.data.BleGattConnectionStatus import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionStateWithStatus import no.nordicsemi.android.kotlin.ble.profile.rscs.data.RSCSData import no.nordicsemi.android.rscs.R @@ -41,8 +42,16 @@ internal data class RSCSServiceData( val data: RSCSData = RSCSData(), val batteryLevel: Int? = null, val connectionState: GattConnectionStateWithStatus? = null, - val deviceName: String? = null + val deviceName: String? = null, + val missingServices: Boolean = false ) { + + val disconnectStatus = if (missingServices) { + BleGattConnectionStatus.NOT_SUPPORTED + } else { + connectionState?.status ?: BleGattConnectionStatus.UNKNOWN + } + @Composable fun displayActivity(): String { return if (data.running) { diff --git a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/repository/RSCSRepository.kt b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/repository/RSCSRepository.kt index ada36280..672c88ed 100644 --- a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/repository/RSCSRepository.kt +++ b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/repository/RSCSRepository.kt @@ -103,6 +103,11 @@ class RSCSRepository @Inject constructor( _data.value = _data.value.copy(batteryLevel = batteryLevel) } + fun onMissingServices() { + _data.value = _data.value.copy(missingServices = true) + _stopEvent.tryEmit(DisconnectAndStopEvent()) + } + fun openLogger() { _loggerEvent.tryEmit(OpenLoggerEvent()) } diff --git a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/repository/RSCSService.kt b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/repository/RSCSService.kt index c65e1058..fca9ef0f 100644 --- a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/repository/RSCSService.kt +++ b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/repository/RSCSService.kt @@ -112,7 +112,7 @@ internal class RSCSService : NotificationService() { client.discoverServices() .filterNotNull() .onEach { configureGatt(it) } - .catch { it.printStackTrace() } + .catch { repository.onMissingServices() } .launchIn(lifecycleScope) } diff --git a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/view/RSCSScreen.kt b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/view/RSCSScreen.kt index 4a5bb612..a99e4800 100644 --- a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/view/RSCSScreen.kt +++ b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/view/RSCSScreen.kt @@ -80,7 +80,7 @@ fun RSCSScreen() { null, GattConnectionState.STATE_CONNECTING -> DeviceConnectingView { NavigateUpButton(navigateUp) } GattConnectionState.STATE_DISCONNECTED, - GattConnectionState.STATE_DISCONNECTING -> DeviceDisconnectedView(state.connectionState.status) { + GattConnectionState.STATE_DISCONNECTING -> DeviceDisconnectedView(state.disconnectStatus) { NavigateUpButton(navigateUp) } GattConnectionState.STATE_CONNECTED -> RSCSContentView(state) { viewModel.onEvent(it) } diff --git a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/viewmodel/RSCSViewModel.kt b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/viewmodel/RSCSViewModel.kt index 88cb6543..74309784 100644 --- a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/viewmodel/RSCSViewModel.kt +++ b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/viewmodel/RSCSViewModel.kt @@ -65,6 +65,8 @@ internal class RSCSViewModel @Inject constructor( val state = repository.data init { + repository.setOnScreen(true) + viewModelScope.launch { if (repository.isRunning.firstOrNull() == false) { requestBluetoothDevice() @@ -109,4 +111,9 @@ internal class RSCSViewModel @Inject constructor( repository.disconnect() navigationManager.navigateUp() } + + override fun onCleared() { + super.onCleared() + repository.setOnScreen(false) + } } diff --git a/profile_uart/src/main/java/no/nordicsemi/android/uart/data/UARTServiceData.kt b/profile_uart/src/main/java/no/nordicsemi/android/uart/data/UARTServiceData.kt index 3896801f..ee7b0ac8 100644 --- a/profile_uart/src/main/java/no/nordicsemi/android/uart/data/UARTServiceData.kt +++ b/profile_uart/src/main/java/no/nordicsemi/android/uart/data/UARTServiceData.kt @@ -31,15 +31,23 @@ package no.nordicsemi.android.uart.data +import no.nordicsemi.android.kotlin.ble.core.data.BleGattConnectionStatus import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionStateWithStatus internal data class UARTServiceData( val messages: List = emptyList(), val connectionState: GattConnectionStateWithStatus? = null, val batteryLevel: Int? = null, - val deviceName: String? = null + val deviceName: String? = null, + val missingServices: Boolean = false ) { + val disconnectStatus = if (missingServices) { + BleGattConnectionStatus.NOT_SUPPORTED + } else { + connectionState?.status ?: BleGattConnectionStatus.UNKNOWN + } + val displayMessages = messages } diff --git a/profile_uart/src/main/java/no/nordicsemi/android/uart/repository/UARTRepository.kt b/profile_uart/src/main/java/no/nordicsemi/android/uart/repository/UARTRepository.kt index fda3ef5c..5e03d40e 100644 --- a/profile_uart/src/main/java/no/nordicsemi/android/uart/repository/UARTRepository.kt +++ b/profile_uart/src/main/java/no/nordicsemi/android/uart/repository/UARTRepository.kt @@ -134,6 +134,11 @@ class UARTRepository @Inject internal constructor( _loggerEvent.tryEmit(OpenLoggerEvent()) } + fun onMissingServices() { + _data.value = _data.value.copy(missingServices = true) + _stopEvent.tryEmit(DisconnectAndStopEvent()) + } + suspend fun saveConfigurationName(name: String) { configurationDataSource.saveConfigurationName(name) } diff --git a/profile_uart/src/main/java/no/nordicsemi/android/uart/repository/UARTService.kt b/profile_uart/src/main/java/no/nordicsemi/android/uart/repository/UARTService.kt index 0a0046ba..432e0554 100644 --- a/profile_uart/src/main/java/no/nordicsemi/android/uart/repository/UARTService.kt +++ b/profile_uart/src/main/java/no/nordicsemi/android/uart/repository/UARTService.kt @@ -49,8 +49,6 @@ import no.nordicsemi.android.kotlin.ble.client.main.service.BleGattServices import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.kotlin.ble.core.data.BleGattProperty import no.nordicsemi.android.kotlin.ble.core.data.BleWriteType -import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState -import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionStateWithStatus import no.nordicsemi.android.kotlin.ble.core.data.Mtu import no.nordicsemi.android.kotlin.ble.profile.battery.BatteryLevelParser import no.nordicsemi.android.service.DEVICE_DATA @@ -108,7 +106,6 @@ internal class UARTService : NotificationService() { client.connectionStateWithStatus .onEach { repository.onConnectionStateChanged(it) } .filterNotNull() - .onEach { stopIfDisconnected(it) } .launchIn(lifecycleScope) if (!client.isConnected) { @@ -118,7 +115,7 @@ internal class UARTService : NotificationService() { client.discoverServices() .filterNotNull() .onEach { configureGatt(it, logger) } - .catch { it.printStackTrace() } + .catch { repository.onMissingServices() } .launchIn(lifecycleScope) } @@ -156,12 +153,6 @@ internal class UARTService : NotificationService() { } } - private fun stopIfDisconnected(connectionState: GattConnectionStateWithStatus) { - if (connectionState.state == GattConnectionState.STATE_DISCONNECTED) { - stopSelf() - } - } - private fun disconnect() { client.disconnect() } diff --git a/profile_uart/src/main/java/no/nordicsemi/android/uart/view/UARTScreen.kt b/profile_uart/src/main/java/no/nordicsemi/android/uart/view/UARTScreen.kt index 7f426b20..71355fc3 100644 --- a/profile_uart/src/main/java/no/nordicsemi/android/uart/view/UARTScreen.kt +++ b/profile_uart/src/main/java/no/nordicsemi/android/uart/view/UARTScreen.kt @@ -85,7 +85,7 @@ fun UARTScreen() { GattConnectionState.STATE_CONNECTING -> PaddingBox { DeviceConnectingView { NavigateUpButton(navigateUp) } } GattConnectionState.STATE_DISCONNECTED, GattConnectionState.STATE_DISCONNECTING -> PaddingBox { - DeviceDisconnectedView(Reason.UNKNOWN) { NavigateUpButton(navigateUp) } + DeviceDisconnectedView(state.uartManagerState.disconnectStatus) { NavigateUpButton(navigateUp) } } GattConnectionState.STATE_CONNECTED -> SuccessScreen() }