From 4f0cdc08c965ac9813866ae082a161080b6c2f93 Mon Sep 17 00:00:00 2001 From: Sylwester Zielinski Date: Wed, 22 Mar 2023 10:56:50 +0100 Subject: [PATCH] Add alarm to PRX --- .../android/prx/data/PRXServiceData.kt | 9 +++++- .../android/prx/repository/AlarmHandler.kt | 4 +++ .../android/prx/repository/PRXRepository.kt | 29 +++---------------- .../android/prx/repository/PRXService.kt | 7 +++-- .../android/prx/viewmodel/PRXViewModel.kt | 19 +++++++++++- 5 files changed, 38 insertions(+), 30 deletions(-) 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 2c520815..47893a30 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 @@ -1,5 +1,6 @@ package no.nordicsemi.android.prx.data +import no.nordicsemi.android.kotlin.ble.core.data.BleGattConnectionStatus import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState import no.nordicsemi.android.kotlin.ble.profile.prx.AlarmLevel @@ -8,6 +9,12 @@ data class PRXServiceData( val linkLossAlarmLevel: AlarmLevel = AlarmLevel.HIGH, val batteryLevel: Int? = null, val connectionState: GattConnectionState? = null, + val connectionStatus: BleGattConnectionStatus? = null, val isRemoteAlarm: Boolean = false, val deviceName: String? = null -) +) { + + val isLinkLossDisconnected = connectionState?.let { + connectionStatus == BleGattConnectionStatus.LINK_LOSS + } ?: false +} diff --git a/profile_prx/src/main/java/no/nordicsemi/android/prx/repository/AlarmHandler.kt b/profile_prx/src/main/java/no/nordicsemi/android/prx/repository/AlarmHandler.kt index eccef2ee..cb909807 100644 --- a/profile_prx/src/main/java/no/nordicsemi/android/prx/repository/AlarmHandler.kt +++ b/profile_prx/src/main/java/no/nordicsemi/android/prx/repository/AlarmHandler.kt @@ -60,6 +60,10 @@ internal class AlarmHandler @Inject constructor( } fun playAlarm(alarmLevel: AlarmLevel) { + if (alarmLevel == AlarmLevel.NONE) { + pauseAlarm() + return + } val ringtone = when (alarmLevel) { AlarmLevel.NONE -> null AlarmLevel.MEDIUM -> mediumLevelRingtone 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 58acccbb..4fa5bd42 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 @@ -38,19 +38,13 @@ import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.map import no.nordicsemi.android.common.core.simpleSharedFlow -import no.nordicsemi.android.common.logger.NordicLogger -import no.nordicsemi.android.common.logger.NordicLoggerFactory import no.nordicsemi.android.kotlin.ble.core.ServerDevice +import no.nordicsemi.android.kotlin.ble.core.data.BleGattConnectionStatus import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState import no.nordicsemi.android.kotlin.ble.profile.prx.AlarmLevel -import no.nordicsemi.android.kotlin.ble.profile.prx.PRXData import no.nordicsemi.android.prx.data.PRXServiceData -import no.nordicsemi.android.service.BleManagerResult import no.nordicsemi.android.service.DisconnectAndStopEvent -import no.nordicsemi.android.service.LinkLossResult import no.nordicsemi.android.service.ServiceManager -import no.nordicsemi.android.service.SuccessResult -import no.nordicsemi.android.ui.view.StringConst import javax.inject.Inject import javax.inject.Singleton @@ -58,8 +52,7 @@ import javax.inject.Singleton class PRXRepository @Inject internal constructor( @ApplicationContext private val context: Context, - private val serviceManager: ServiceManager, - private val alarmHandler: AlarmHandler, + private val serviceManager: ServiceManager ) { private val _data = MutableStateFlow(PRXServiceData()) @@ -81,8 +74,8 @@ class PRXRepository @Inject internal constructor( _data.value = _data.value.copy(deviceName = device.name) } - fun onConnectionStateChanged(connectionState: GattConnectionState?) { - _data.value = _data.value.copy(connectionState = connectionState) + fun onConnectionStateChanged(connection: Pair) { + _data.value = _data.value.copy(connectionState = connection.first, connectionStatus = connection.second) } fun setLocalAlarmLevel(alarmLevel: AlarmLevel) { @@ -93,20 +86,6 @@ class PRXRepository @Inject internal constructor( _data.value = _data.value.copy(linkLossAlarmLevel = alarmLevel) } - private fun handleLocalAlarm(result: BleManagerResult) { - (result as? SuccessResult)?.let { - if (it.data.localAlarmLevel != AlarmLevel.NONE) { - alarmHandler.playAlarm(it.data.localAlarmLevel) - } else { - alarmHandler.pauseAlarm() - } - } - (result as? LinkLossResult)?.let { - val alarmLevel = it.data?.linkLossAlarmLevel ?: AlarmLevel.HIGH - alarmHandler.playAlarm(alarmLevel) - } - } - fun onBatteryLevelChanged(batteryLevel: Int) { _data.value = _data.value.copy(batteryLevel = batteryLevel) } 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 707b0207..5991a39e 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 @@ -149,17 +149,18 @@ internal class PRXService : NotificationService() { linkLossCharacteristic.value .mapNotNull { AlarmLevelParser.parse(it) } - .onEach { repository.setLocalAlarmLevel(it) } + .onEach { repository.setLinkLossAlarmLevel(it) } .launchIn(lifecycleScope) } private fun startGattClient(device: ServerDevice) = lifecycleScope.launch { client = device.connect(this@PRXService) - client.connectionState + client.connectionStateWithStatus + .filterNotNull() .onEach { repository.onConnectionStateChanged(it) } .filterNotNull() - .onEach { stopIfDisconnected(it) } + .onEach { stopIfDisconnected(it.first) } .launchIn(lifecycleScope) client.services diff --git a/profile_prx/src/main/java/no/nordicsemi/android/prx/viewmodel/PRXViewModel.kt b/profile_prx/src/main/java/no/nordicsemi/android/prx/viewmodel/PRXViewModel.kt index 080a86aa..588202dc 100644 --- a/profile_prx/src/main/java/no/nordicsemi/android/prx/viewmodel/PRXViewModel.kt +++ b/profile_prx/src/main/java/no/nordicsemi/android/prx/viewmodel/PRXViewModel.kt @@ -32,11 +32,14 @@ package no.nordicsemi.android.prx.viewmodel import android.os.ParcelUuid +import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import no.nordicsemi.android.analytics.AppAnalytics @@ -47,6 +50,7 @@ import no.nordicsemi.android.common.navigation.Navigator import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState import no.nordicsemi.android.kotlin.ble.profile.prx.AlarmLevel +import no.nordicsemi.android.prx.repository.AlarmHandler import no.nordicsemi.android.prx.repository.PRXRepository import no.nordicsemi.android.prx.repository.PRX_SERVICE_UUID import no.nordicsemi.android.prx.view.DisconnectEvent @@ -62,7 +66,8 @@ import javax.inject.Inject internal class PRXViewModel @Inject constructor( private val repository: PRXRepository, private val navigationManager: Navigator, - private val analytics: AppAnalytics + private val analytics: AppAnalytics, + private val alarmHandler: AlarmHandler ) : ViewModel() { val state = repository.data @@ -75,10 +80,21 @@ internal class PRXViewModel @Inject constructor( } repository.data.onEach { + Log.d("AAATESTAAA", "Data $it") + if (it.isLinkLossDisconnected) { + alarmHandler.playAlarm(it.linkLossAlarmLevel) + } + if (it.connectionState == GattConnectionState.STATE_CONNECTED) { analytics.logEvent(ProfileConnectedEvent(Profile.PRX)) } }.launchIn(viewModelScope) + + repository.data + .map { it.localAlarmLevel } + .distinctUntilChanged() + .onEach { alarmHandler.playAlarm(it) } + .launchIn(viewModelScope) } private fun requestBluetoothDevice() { @@ -108,6 +124,7 @@ internal class PRXViewModel @Inject constructor( private fun disconnect() { repository.release() + alarmHandler.pauseAlarm() navigationManager.navigateUp() } }