From 5f08816ca7b77b328bec7b2d013a5661e0e0457e Mon Sep 17 00:00:00 2001 From: hiar Date: Mon, 29 Sep 2025 14:07:48 +0200 Subject: [PATCH] Added wrapper for API data with mapper and updated usage --- .../channelSounding/ChannelSoundingManager.kt | 3 +- .../channelSounding/ChannelSoundingScreen.kt | 11 ++--- .../ChannelSoundingUiMapper.kt | 40 +++++++++++++++++++ .../data/ChannelSoundingServiceData.kt | 22 ++++++++-- 4 files changed, 64 insertions(+), 12 deletions(-) diff --git a/profile/src/main/java/no/nordicsemi/android/toolbox/profile/repository/channelSounding/ChannelSoundingManager.kt b/profile/src/main/java/no/nordicsemi/android/toolbox/profile/repository/channelSounding/ChannelSoundingManager.kt index 707f9fea..ec9139a8 100644 --- a/profile/src/main/java/no/nordicsemi/android/toolbox/profile/repository/channelSounding/ChannelSoundingManager.kt +++ b/profile/src/main/java/no/nordicsemi/android/toolbox/profile/repository/channelSounding/ChannelSoundingManager.kt @@ -29,6 +29,7 @@ import no.nordicsemi.android.toolbox.profile.data.RangingSessionAction import no.nordicsemi.android.toolbox.profile.data.RangingSessionFailedReason import no.nordicsemi.android.toolbox.profile.data.SessionClosedReason import no.nordicsemi.android.toolbox.profile.data.UpdateRate +import no.nordicsemi.android.toolbox.profile.view.channelSounding.toCsRangingData import timber.log.Timber import java.util.UUID import javax.inject.Inject @@ -83,7 +84,7 @@ class ChannelSoundingManager @Inject constructor( } _previousRangingDataList.value = updatedList _rangingData.value = RangingSessionAction.OnResult( - data = data, + data = data.toCsRangingData(), previousData = _previousRangingDataList.value ) } 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 4c0115d1..62500187 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 @@ -1,8 +1,6 @@ package no.nordicsemi.android.toolbox.profile.view.channelSounding import android.os.Build -import android.ranging.RangingData -import androidx.annotation.RequiresApi import androidx.compose.foundation.background import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Arrangement @@ -41,6 +39,7 @@ import no.nordicsemi.android.common.theme.NordicTheme import no.nordicsemi.android.toolbox.profile.R 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.RangingTechnology import no.nordicsemi.android.toolbox.profile.data.SessionClosedReason @@ -90,7 +89,6 @@ private fun ChannelSoundingNotSupportedView() { } } -@RequiresApi(Build.VERSION_CODES.BAKLAVA) @Composable private fun ChannelSoundingView( channelSoundingState: ChannelSoundingServiceData, @@ -237,16 +235,15 @@ private fun SessionError( } } -@RequiresApi(Build.VERSION_CODES.BAKLAVA) @Composable private fun RangingContent( updateRate: UpdateRate, - rangingData: RangingData, + rangingData: CsRangingData, previousMeasurements: List = emptyList(), onClickEvent: (ChannelSoundingEvent) -> Unit, ) { val distanceMeasurement = rangingData.distance?.measurement - val confidence = rangingData.distance?.confidence + val confidence = rangingData.distance?.confidenceLevel?.value Column( modifier = Modifier @@ -259,7 +256,7 @@ private fun RangingContent( DetailsCard( updateRate = updateRate, - rangingTechnology = rangingData.rangingTechnology, + rangingTechnology = rangingData.technology.value, confidenceLevel = confidence ) { onClickEvent(ChannelSoundingEvent.RangingUpdateRate(it)) } diff --git a/profile/src/main/java/no/nordicsemi/android/toolbox/profile/view/channelSounding/ChannelSoundingUiMapper.kt b/profile/src/main/java/no/nordicsemi/android/toolbox/profile/view/channelSounding/ChannelSoundingUiMapper.kt index 3fc7cea0..009bdf8b 100644 --- a/profile/src/main/java/no/nordicsemi/android/toolbox/profile/view/channelSounding/ChannelSoundingUiMapper.kt +++ b/profile/src/main/java/no/nordicsemi/android/toolbox/profile/view/channelSounding/ChannelSoundingUiMapper.kt @@ -1,7 +1,13 @@ package no.nordicsemi.android.toolbox.profile.view.channelSounding +import android.os.Build +import android.ranging.RangingData +import androidx.annotation.RequiresApi import androidx.annotation.StringRes import no.nordicsemi.android.toolbox.profile.R +import no.nordicsemi.android.toolbox.profile.data.CSRangingMeasurement +import no.nordicsemi.android.toolbox.profile.data.ConfidenceLevel +import no.nordicsemi.android.toolbox.profile.data.CsRangingData import no.nordicsemi.android.toolbox.profile.data.RangingSessionFailedReason import no.nordicsemi.android.toolbox.profile.data.RangingTechnology import no.nordicsemi.android.toolbox.profile.data.SessionCloseReasonProvider @@ -58,3 +64,37 @@ internal fun SessionCloseReasonProvider.toUiString(): Int { } } +// Mapper function which maps RangingData to CsRangingData +@RequiresApi(Build.VERSION_CODES.BAKLAVA) +internal fun RangingData.toCsRangingData(): CsRangingData { + return CsRangingData( + distance = this.distance?.let { + CSRangingMeasurement( + measurement = it.measurement, + confidenceLevel = ConfidenceLevel.from(it.confidence) + ) + }, + azimuth = this.azimuth?.let { + CSRangingMeasurement( + measurement = it.measurement, + confidenceLevel = ConfidenceLevel.from(it.confidence) + ) + }, + elevation = this.elevation?.let { + CSRangingMeasurement( + measurement = it.measurement, + confidenceLevel = ConfidenceLevel.from(it.confidence) + ) + }, + technology = RangingTechnology.from(this.rangingTechnology) + ?: throw IllegalArgumentException("Unknown ranging technology: ${this.rangingTechnology}"), + timeStamp = this.timestampMillis, + hasRssi = this.hasRssi(), + rssi = if (this.hasRssi()) { + this.rssi + } else { + null + } + ) +} + 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 7713b006..e1e47d3b 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 @@ -1,6 +1,5 @@ package no.nordicsemi.android.toolbox.profile.data -import android.ranging.RangingData import no.nordicsemi.android.toolbox.lib.utils.Profile data class ChannelSoundingServiceData( @@ -13,7 +12,7 @@ data class ChannelSoundingServiceData( sealed interface RangingSessionAction { object OnStart : RangingSessionAction data class OnResult( - val data: RangingData, + val data: CsRangingData, val previousData: List = emptyList() ) : RangingSessionAction @@ -21,6 +20,21 @@ sealed interface RangingSessionAction { object OnClosed : RangingSessionAction } +data class CsRangingData( + val distance: CSRangingMeasurement? = null, + val azimuth: CSRangingMeasurement? = null, + val elevation: CSRangingMeasurement? = null, + val technology: RangingTechnology, + val timeStamp: Long, + val hasRssi: Boolean = false, + val rssi: Int? = null, +) + +data class CSRangingMeasurement( + val measurement: Double, + val confidenceLevel: ConfidenceLevel, +) + enum class UpdateRate { NORMAL, FREQUENT, @@ -33,7 +47,7 @@ enum class ConfidenceLevel(val value: Int) { CONFIDENCE_LOW(0); companion object { - fun from(value: Int): ConfidenceLevel? = entries.find { it.value == value } + fun from(value: Int): ConfidenceLevel = entries.find { it.value == value } ?: CONFIDENCE_LOW } } @@ -59,7 +73,7 @@ enum class SessionClosedReason : SessionCloseReasonProvider { sealed interface SessionCloseReasonProvider -enum class RangingSessionFailedReason(val reason: Int):SessionCloseReasonProvider { +enum class RangingSessionFailedReason(val reason: Int) : SessionCloseReasonProvider { UNKNOWN(0), LOCAL_REQUEST(1), REMOTE_REQUEST(2),