diff --git a/profile/src/main/java/no/nordicsemi/android/toolbox/profile/view/channelSounding/ChannelSoundingScreen.kt b/profile/src/main/java/no/nordicsemi/android/toolbox/profile/view/channelSounding/ChannelSoundingScreen.kt
index e01d2bb0..fcce6690 100644
--- a/profile/src/main/java/no/nordicsemi/android/toolbox/profile/view/channelSounding/ChannelSoundingScreen.kt
+++ b/profile/src/main/java/no/nordicsemi/android/toolbox/profile/view/channelSounding/ChannelSoundingScreen.kt
@@ -24,6 +24,9 @@ import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
@@ -41,6 +44,7 @@ import no.nordicsemi.android.toolbox.profile.data.ChannelSoundingServiceData
import no.nordicsemi.android.toolbox.profile.data.ConfidenceLevel
import no.nordicsemi.android.toolbox.profile.data.CsRangingData
import no.nordicsemi.android.toolbox.profile.data.RangingSessionAction
+import no.nordicsemi.android.toolbox.profile.data.RangingSessionFailedReason
import no.nordicsemi.android.toolbox.profile.data.RangingTechnology
import no.nordicsemi.android.toolbox.profile.data.SessionClosedReason
import no.nordicsemi.android.toolbox.profile.data.UpdateRate
@@ -95,13 +99,14 @@ private fun ChannelSoundingView(
channelSoundingState: ChannelSoundingServiceData,
onClickEvent: (ChannelSoundingEvent) -> Unit,
) {
+ var isRestartingSession by rememberSaveable { mutableStateOf(false) }
Column(
verticalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier.fillMaxWidth()
) {
when (val sessionData = channelSoundingState.rangingSessionAction) {
is RangingSessionAction.OnError -> {
- SessionError(sessionData) { onClickEvent(it) }
+ SessionError(sessionData, isRestartingSession) { onClickEvent(it) }
}
is RangingSessionAction.OnResult -> {
@@ -109,18 +114,26 @@ private fun ChannelSoundingView(
channelSoundingState.updateRate,
sessionData.data,
sessionData.previousData,
- onClickEvent
- )
+ ) {
+ isRestartingSession = true
+ onClickEvent(it)
+ }
}
RangingSessionAction.OnClosed -> {
- SessionClosed(onClickEvent)
+ SessionClosed(isRestartingSession, onClickEvent)
}
RangingSessionAction.OnStart -> {
+ isRestartingSession = false
InitiatingSession()
}
+ RangingSessionAction.OnRestarting -> {
+ isRestartingSession = true
+ RestartingSession()
+ }
+
null -> LoadingView()
}
@@ -149,8 +162,31 @@ private fun InitiatingSession() {
}
}
+@Composable
+private fun RestartingSession() {
+ ScreenSection(modifier = Modifier.padding(0.dp) /* No padding */) {
+ Column(modifier = Modifier.padding(top = 16.dp, start = 16.dp, end = 16.dp)) {
+ SectionTitle(
+ icon = Icons.Default.SocialDistance,
+ title = stringResource(R.string.channel_sounding),
+ )
+ }
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(16.dp),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ ) {
+ TextWithAnimatedDots(
+ text = stringResource(R.string.ranging_session_restarting),
+ )
+ }
+ }
+}
+
@Composable
private fun SessionClosed(
+ isRestartingSession: Boolean,
onClickEvent: (ChannelSoundingEvent) -> Unit,
) {
Column(
@@ -177,10 +213,17 @@ private fun SessionClosed(
)
}
}
- Button(
- onClick = { onClickEvent(ChannelSoundingEvent.RestartRangingSession) },
- ) {
- Text(text = stringResource(id = R.string.reconnect))
+
+ if (isRestartingSession) {
+ Button(onClick = { /* No action */ }) {
+ Text(text = stringResource(id = R.string.ranging_session_reconnecting))
+ }
+ } else {
+ Button(
+ onClick = { onClickEvent(ChannelSoundingEvent.RestartRangingSession) },
+ ) {
+ Text(text = stringResource(id = R.string.reconnect))
+ }
}
}
}
@@ -189,13 +232,14 @@ private fun SessionClosed(
@Composable
private fun SessionClosed_Preview() {
NordicTheme {
- SessionClosed(onClickEvent = {})
+ SessionClosed(false, onClickEvent = {})
}
}
@Composable
private fun SessionError(
sessionData: RangingSessionAction.OnError,
+ isRestartingSession: Boolean,
onClickEvent: (ChannelSoundingEvent) -> Unit,
) {
Column(
@@ -222,7 +266,12 @@ private fun SessionError(
)
}
}
- if (sessionData.reason != SessionClosedReason.NOT_SUPPORTED ||
+
+ if (isRestartingSession && sessionData.reason == RangingSessionFailedReason.LOCAL_REQUEST) {
+ Button(onClick = { /* No action */ }) {
+ Text(text = stringResource(id = R.string.ranging_session_reconnecting))
+ }
+ } else if (sessionData.reason != SessionClosedReason.NOT_SUPPORTED ||
sessionData.reason != SessionClosedReason.RANGING_NOT_AVAILABLE
) {
Button(
diff --git a/profile/src/main/res/values/channelSoundingStrings.xml b/profile/src/main/res/values/channelSoundingStrings.xml
index 2f35347d..36341407 100644
--- a/profile/src/main/res/values/channelSoundingStrings.xml
+++ b/profile/src/main/res/values/channelSoundingStrings.xml
@@ -4,7 +4,9 @@
Channel Sounding is not supported on this Android version.
Initiating ranging
+ Reconnecting session
Ranging session stopped
+ Reconnecting…
Distance
Current measurement
diff --git a/profile_data/src/main/java/no/nordicsemi/android/toolbox/profile/data/ChannelSoundingServiceData.kt b/profile_data/src/main/java/no/nordicsemi/android/toolbox/profile/data/ChannelSoundingServiceData.kt
index e1e47d3b..65712bbc 100644
--- a/profile_data/src/main/java/no/nordicsemi/android/toolbox/profile/data/ChannelSoundingServiceData.kt
+++ b/profile_data/src/main/java/no/nordicsemi/android/toolbox/profile/data/ChannelSoundingServiceData.kt
@@ -10,7 +10,7 @@ data class ChannelSoundingServiceData(
) : ProfileServiceData()
sealed interface RangingSessionAction {
- object OnStart : RangingSessionAction
+ data object OnStart : RangingSessionAction
data class OnResult(
val data: CsRangingData,
val previousData: List = emptyList()
@@ -18,6 +18,7 @@ sealed interface RangingSessionAction {
data class OnError(val reason: SessionCloseReasonProvider) : RangingSessionAction
object OnClosed : RangingSessionAction
+ data object OnRestarting : RangingSessionAction
}
data class CsRangingData(