dfu redirection

This commit is contained in:
hiar
2025-10-01 16:36:26 +02:00
committed by Himali Aryal
parent 56db87dd5c
commit 900eaebdb1
6 changed files with 100 additions and 14 deletions

View File

@@ -29,7 +29,7 @@ import no.nordicsemi.android.common.permissions.ble.RequireLocation
import no.nordicsemi.android.common.permissions.notification.RequestNotificationPermission
import no.nordicsemi.android.toolbox.lib.utils.Profile
import no.nordicsemi.android.toolbox.profile.data.displayMessage
import no.nordicsemi.android.toolbox.profile.view.DFUScreen
import no.nordicsemi.android.toolbox.profile.view.dfu.DFUScreen
import no.nordicsemi.android.toolbox.profile.view.battery.BatteryScreen
import no.nordicsemi.android.toolbox.profile.view.bps.BPSScreen
import no.nordicsemi.android.toolbox.profile.view.cgms.CGMScreen

View File

@@ -1,12 +1,16 @@
package no.nordicsemi.android.toolbox.profile.view
package no.nordicsemi.android.toolbox.profile.view.dfu
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.widthIn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Download
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedCard
@@ -14,6 +18,8 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
@@ -29,7 +35,8 @@ internal fun DFUScreen(
modifier = Modifier
.fillMaxSize()
.then(modifier),
horizontalAlignment = Alignment.CenterHorizontally
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
OutlinedCard(
modifier = Modifier
@@ -55,13 +62,46 @@ internal fun DFUScreen(
)
Text(
text = "DFU service is not not available in the current version of the app." +
text = "DFU service is not available in the current version of the app. " +
"Please use the DFU app from Nordic Semiconductor to update your devices firmware.",
textAlign = TextAlign.Center,
style = MaterialTheme.typography.bodyMedium
)
}
}
val uriHandler = LocalUriHandler.current
val context = LocalContext.current
val packageManger = context.packageManager
val intent = packageManger.getLaunchIntentForPackage(DFU_PACKAGE_NAME)
val description = intent?.let {
"Open DFU"
} ?: "Download from Play Store"
Button(
onClick = {
if (intent != null) {
context.startActivity(intent)
} else {
uriHandler.openUri(DFU_APP_LINK)
}
},
) {
Row {
intent?.let {
Icon(
painter = painterResource(R.drawable.ic_dfu),
contentDescription = null,
modifier = Modifier
.size(24.dp)
.padding(end = 8.dp)
)
} ?: Icon(imageVector = Icons.Default.Download, contentDescription = null)
Text(text = description)
}
}
}
}

View File

@@ -0,0 +1,32 @@
package no.nordicsemi.android.toolbox.profile.view.dfu
import no.nordicsemi.android.toolbox.profile.data.DFUsAvailable
internal const val DFU_PACKAGE_NAME = "no.nordicsemi.android.dfu"
internal const val DFU_APP_LINK =
"https://play.google.com/store/apps/details?id=no.nordicsemi.android.dfu"
internal const val SMP_PACKAGE_NAME = "no.nordicsemi.android.nrfconnectdevicemanager"
internal const val SMP_APP_LINK =
"https://play.google.com/store/apps/details?id=no.nordicsemi.android.nrfconnectdevicemanager"
internal fun DFUsAvailable.getApp(): String {
return when (this) {
DFUsAvailable.DFU_SERVICE -> DFU_APP_LINK
DFUsAvailable.SMP_SERVICE -> SMP_APP_LINK
DFUsAvailable.MDS_SERVICE -> SMP_APP_LINK
DFUsAvailable.LEGACY_DFU_SERVICE -> DFU_APP_LINK
DFUsAvailable.EXPERIMENTAL_BUTTONLESS_DFU_SERVICE -> DFU_APP_LINK
}
}
internal fun DFUsAvailable.getPackageName(): String {
return when (this) {
DFUsAvailable.DFU_SERVICE -> DFU_PACKAGE_NAME
DFUsAvailable.SMP_SERVICE -> SMP_PACKAGE_NAME
DFUsAvailable.MDS_SERVICE -> SMP_PACKAGE_NAME
DFUsAvailable.LEGACY_DFU_SERVICE -> DFU_PACKAGE_NAME
DFUsAvailable.EXPERIMENTAL_BUTTONLESS_DFU_SERVICE -> DFU_PACKAGE_NAME
}
}

View File

@@ -4,5 +4,13 @@ import no.nordicsemi.android.toolbox.lib.utils.Profile
data class DFUServiceData(
override val profile: Profile = Profile.DFU,
val dfuAppName : String? = null,
): ProfileServiceData()
val dfuAppName : DFUsAvailable? = null,
): ProfileServiceData()
enum class DFUsAvailable {
DFU_SERVICE,
SMP_SERVICE,
MDS_SERVICE,
LEGACY_DFU_SERVICE,
EXPERIMENTAL_BUTTONLESS_DFU_SERVICE;
}

View File

@@ -5,12 +5,15 @@ import no.nordicsemi.android.toolbox.lib.utils.Profile
import no.nordicsemi.android.toolbox.lib.utils.spec.DFU_SERVICE_UUID
import no.nordicsemi.android.toolbox.lib.utils.spec.EXPERIMENTAL_BUTTONLESS_DFU_SERVICE_UUID
import no.nordicsemi.android.toolbox.lib.utils.spec.LEGACY_DFU_SERVICE_UUID
import no.nordicsemi.android.toolbox.lib.utils.spec.MDS_SERVICE_UUID
import no.nordicsemi.android.toolbox.lib.utils.spec.SMP_SERVICE_UUID
import no.nordicsemi.android.toolbox.profile.data.DFUsAvailable
import no.nordicsemi.android.toolbox.profile.manager.repository.DFURepository
import no.nordicsemi.kotlin.ble.client.RemoteService
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.toKotlinUuid
internal class DFUManager :ServiceManager{
internal class DFUManager : ServiceManager {
override val profile: Profile
get() = Profile.DFU
@@ -20,15 +23,17 @@ internal class DFUManager :ServiceManager{
remoteService: RemoteService,
scope: CoroutineScope
) {
when (remoteService.uuid) {
DFU_SERVICE_UUID.toKotlinUuid(),
SMP_SERVICE_UUID.toKotlinUuid(),
LEGACY_DFU_SERVICE_UUID.toKotlinUuid(),
EXPERIMENTAL_BUTTONLESS_DFU_SERVICE_UUID.toKotlinUuid() -> this
val appName = when (remoteService.uuid) {
DFU_SERVICE_UUID.toKotlinUuid() -> DFUsAvailable.DFU_SERVICE
SMP_SERVICE_UUID.toKotlinUuid() -> DFUsAvailable.SMP_SERVICE
LEGACY_DFU_SERVICE_UUID.toKotlinUuid() -> DFUsAvailable.LEGACY_DFU_SERVICE
EXPERIMENTAL_BUTTONLESS_DFU_SERVICE_UUID.toKotlinUuid() -> DFUsAvailable.EXPERIMENTAL_BUTTONLESS_DFU_SERVICE
MDS_SERVICE_UUID.toKotlinUuid() -> DFUsAvailable.MDS_SERVICE
else -> null
}
if (appName != null)
DFURepository.updateAppName(deviceId, appName)
}
}

View File

@@ -4,6 +4,7 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update
import no.nordicsemi.android.toolbox.profile.data.DFUServiceData
import no.nordicsemi.android.toolbox.profile.data.DFUsAvailable
object DFURepository {
private val _dataMap = mutableMapOf<String, MutableStateFlow<DFUServiceData>>()
@@ -12,7 +13,7 @@ object DFURepository {
return _dataMap.getOrPut(deviceId) { MutableStateFlow(DFUServiceData()) }
}
fun updateAppName(deviceId: String, appName: String) {
fun updateAppName(deviceId: String, appName: DFUsAvailable) {
_dataMap[deviceId]?.update { it.copy(dfuAppName = appName) }
}