Add error support

This commit is contained in:
Sylwester Zielinski
2023-05-02 12:21:52 +02:00
parent 5145266bdc
commit 6c58901c12
2 changed files with 38 additions and 18 deletions

View File

@@ -40,6 +40,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.mapNotNull
@@ -128,7 +129,6 @@ internal class BPSViewModel @Inject constructor(
client.connectionStateWithStatus client.connectionStateWithStatus
.filterNotNull() .filterNotNull()
.onEach { onDataUpdate(it) } .onEach { onDataUpdate(it) }
.onEach { stopIfDisconnected(it.state) }
.onEach { logAnalytics(it.state) } .onEach { logAnalytics(it.state) }
.launchIn(viewModelScope) .launchIn(viewModelScope)
@@ -152,16 +152,19 @@ internal class BPSViewModel @Inject constructor(
batteryLevelCharacteristic.getNotifications() batteryLevelCharacteristic.getNotifications()
.mapNotNull { BatteryLevelParser.parse(it) } .mapNotNull { BatteryLevelParser.parse(it) }
.onEach { onDataUpdate(it) } .onEach { onDataUpdate(it) }
.catch { it.printStackTrace() }
.launchIn(viewModelScope) .launchIn(viewModelScope)
bpmCharacteristic.getNotifications() bpmCharacteristic.getNotifications()
.mapNotNull { BloodPressureMeasurementParser.parse(it) } .mapNotNull { BloodPressureMeasurementParser.parse(it) }
.onEach { onDataUpdate(it) } .onEach { onDataUpdate(it) }
.catch { it.printStackTrace() }
.launchIn(viewModelScope) .launchIn(viewModelScope)
icpCharacteristic?.getNotifications() icpCharacteristic?.getNotifications()
?.mapNotNull { IntermediateCuffPressureParser.parse(it) } ?.mapNotNull { IntermediateCuffPressureParser.parse(it) }
?.onEach { onDataUpdate(it) } ?.onEach { onDataUpdate(it) }
?.catch { it.printStackTrace() }
?.launchIn(viewModelScope) ?.launchIn(viewModelScope)
} }
@@ -185,12 +188,6 @@ internal class BPSViewModel @Inject constructor(
_state.value = _state.value.copy(result = newResult) _state.value = _state.value.copy(result = newResult)
} }
private fun stopIfDisconnected(connectionState: GattConnectionState) {
if (connectionState == GattConnectionState.STATE_DISCONNECTED) {
navigationManager.navigateUp()
}
}
private fun logAnalytics(connectionState: GattConnectionState) { private fun logAnalytics(connectionState: GattConnectionState) {
if (connectionState == GattConnectionState.STATE_CONNECTED) { if (connectionState == GattConnectionState.STATE_CONNECTED) {
analytics.logEvent(ProfileConnectedEvent(Profile.BPS)) analytics.logEvent(ProfileConnectedEvent(Profile.BPS))

View File

@@ -40,6 +40,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.mapNotNull
@@ -61,6 +62,7 @@ import no.nordicsemi.android.gls.main.view.OnWorkingModeSelected
import no.nordicsemi.android.gls.main.view.OpenLoggerEvent import no.nordicsemi.android.gls.main.view.OpenLoggerEvent
import no.nordicsemi.android.kotlin.ble.client.main.callback.BleGattClient 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.connect
import no.nordicsemi.android.kotlin.ble.client.main.errors.GattOperationException
import no.nordicsemi.android.kotlin.ble.client.main.service.BleGattCharacteristic import no.nordicsemi.android.kotlin.ble.client.main.service.BleGattCharacteristic
import no.nordicsemi.android.kotlin.ble.client.main.service.BleGattServices 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.ServerDevice
@@ -178,6 +180,7 @@ internal class GLSViewModel @Inject constructor(
client.discoverServices() client.discoverServices()
.filterNotNull() .filterNotNull()
.onEach { configureGatt(it) } .onEach { configureGatt(it) }
.catch { it.printStackTrace() }
.launchIn(viewModelScope) .launchIn(viewModelScope)
} }
@@ -197,21 +200,25 @@ internal class GLSViewModel @Inject constructor(
batteryLevelCharacteristic.getNotifications() batteryLevelCharacteristic.getNotifications()
.mapNotNull { BatteryLevelParser.parse(it) } .mapNotNull { BatteryLevelParser.parse(it) }
.onEach { _state.value = _state.value.copyWithNewBatteryLevel(it) } .onEach { _state.value = _state.value.copyWithNewBatteryLevel(it) }
.catch { it.printStackTrace() }
.launchIn(viewModelScope) .launchIn(viewModelScope)
glucoseMeasurementCharacteristic.getNotifications() glucoseMeasurementCharacteristic.getNotifications()
.mapNotNull { GlucoseMeasurementParser.parse(it) } .mapNotNull { GlucoseMeasurementParser.parse(it) }
.onEach { _state.value = _state.value.copyWithNewRecord(it) } .onEach { _state.value = _state.value.copyWithNewRecord(it) }
.catch { it.printStackTrace() }
.launchIn(viewModelScope) .launchIn(viewModelScope)
glsService.findCharacteristic(GM_CONTEXT_CHARACTERISTIC)?.getNotifications() glsService.findCharacteristic(GM_CONTEXT_CHARACTERISTIC)?.getNotifications()
?.mapNotNull { GlucoseMeasurementContextParser.parse(it) } ?.mapNotNull { GlucoseMeasurementContextParser.parse(it) }
?.onEach { _state.value = _state.value.copyWithNewContext(it) } ?.onEach { _state.value = _state.value.copyWithNewContext(it) }
?.catch { it.printStackTrace() }
?.launchIn(viewModelScope) ?.launchIn(viewModelScope)
recordAccessControlPointCharacteristic.getNotifications() recordAccessControlPointCharacteristic.getNotifications()
.mapNotNull { RecordAccessControlPointParser.parse(it) } .mapNotNull { RecordAccessControlPointParser.parse(it) }
.onEach { onAccessControlPointDataReceived(it) } .onEach { onAccessControlPointDataReceived(it) }
.catch { it.printStackTrace() }
.launchIn(viewModelScope) .launchIn(viewModelScope)
} }
@@ -246,14 +253,18 @@ internal class GLSViewModel @Inject constructor(
private suspend fun onNumberOfRecordsReceived(numberOfRecords: Int) { private suspend fun onNumberOfRecordsReceived(numberOfRecords: Int) {
if (numberOfRecords > 0) { if (numberOfRecords > 0) {
if (state.value.glsServiceData.records.isNotEmpty()) { try {
recordAccessControlPointCharacteristic.write( if (state.value.glsServiceData.records.isNotEmpty()) {
RecordAccessControlPointInputParser.reportStoredRecordsGreaterThenOrEqualTo(highestSequenceNumber).value recordAccessControlPointCharacteristic.write(
) RecordAccessControlPointInputParser.reportStoredRecordsGreaterThenOrEqualTo(highestSequenceNumber).value
} else { )
recordAccessControlPointCharacteristic.write( } else {
RecordAccessControlPointInputParser.reportAllStoredRecords().value recordAccessControlPointCharacteristic.write(
) RecordAccessControlPointInputParser.reportAllStoredRecords().value
)
}
} catch (e: GattOperationException) {
e.printStackTrace()
} }
} }
_state.value = _state.value.copyWithNewRequestStatus(RequestStatus.SUCCESS) _state.value = _state.value.copyWithNewRequestStatus(RequestStatus.SUCCESS)
@@ -274,18 +285,30 @@ internal class GLSViewModel @Inject constructor(
private suspend fun requestLastRecord() { private suspend fun requestLastRecord() {
clear() clear()
_state.value = _state.value.copyWithNewRequestStatus(RequestStatus.PENDING) _state.value = _state.value.copyWithNewRequestStatus(RequestStatus.PENDING)
recordAccessControlPointCharacteristic.write(RecordAccessControlPointInputParser.reportLastStoredRecord().value) try {
recordAccessControlPointCharacteristic.write(RecordAccessControlPointInputParser.reportLastStoredRecord().value)
} catch (e: Exception) {
_state.value = _state.value.copyWithNewRequestStatus(RequestStatus.FAILED)
}
} }
private suspend fun requestFirstRecord() { private suspend fun requestFirstRecord() {
clear() clear()
_state.value = _state.value.copyWithNewRequestStatus(RequestStatus.PENDING) _state.value = _state.value.copyWithNewRequestStatus(RequestStatus.PENDING)
recordAccessControlPointCharacteristic.write(RecordAccessControlPointInputParser.reportFirstStoredRecord().value) try {
recordAccessControlPointCharacteristic.write(RecordAccessControlPointInputParser.reportFirstStoredRecord().value)
} catch (e: Exception) {
_state.value = _state.value.copyWithNewRequestStatus(RequestStatus.FAILED)
}
} }
private suspend fun requestAllRecords() { private suspend fun requestAllRecords() {
clear() clear()
_state.value = _state.value.copyWithNewRequestStatus(RequestStatus.PENDING) _state.value = _state.value.copyWithNewRequestStatus(RequestStatus.PENDING)
recordAccessControlPointCharacteristic.write(RecordAccessControlPointInputParser.reportNumberOfAllStoredRecords().value) try {
recordAccessControlPointCharacteristic.write(RecordAccessControlPointInputParser.reportNumberOfAllStoredRecords().value)
} catch (e: Exception) {
e.printStackTrace()
}
} }
} }