From 1004a561fd39fe67a72fd8a2d38dac5bc68e72f7 Mon Sep 17 00:00:00 2001 From: Aleksander Nowakowski Date: Thu, 21 Dec 2023 22:55:47 +0100 Subject: [PATCH] Migration to latest BLEK (#132) * Migration to latest BLEK * Clean up --- app/build.gradle.kts | 16 ++--- lib_scanner/build.gradle.kts | 4 +- lib_service/build.gradle.kts | 5 +- .../android/service/NotificationService.kt | 8 +-- lib_ui/build.gradle.kts | 8 +-- lib_utils/build.gradle.kts | 2 + profile_bps/build.gradle.kts | 12 ++-- .../android/bps/viewmodel/BPSViewModel.kt | 2 +- profile_cgms/build.gradle.kts | 20 +++--- .../android/cgms/repository/CGMService.kt | 5 +- profile_csc/build.gradle.kts | 18 +++-- .../android/csc/repository/CSCService.kt | 2 +- profile_gls/build.gradle.kts | 15 ++-- .../no/nordicsemi/android/gls/GlsServer.kt | 72 +++++++++---------- .../gls/details/view/GLSDetailsContentView.kt | 8 +-- .../gls/main/viewmodel/GLSViewModel.kt | 14 ++-- profile_hrs/build.gradle.kts | 19 +++-- .../android/hrs/service/HRSService.kt | 2 +- profile_hts/build.gradle.kts | 14 ++-- .../android/hts/repository/HTSService.kt | 2 +- profile_prx/build.gradle.kts | 14 ++-- .../android/prx/repository/PRXService.kt | 3 +- profile_rscs/build.gradle.kts | 18 +++-- .../android/rscs/repository/RSCSService.kt | 2 +- profile_uart/build.gradle.kts | 21 +++--- .../no/nordicsemi/android/uart/UartServer.kt | 30 ++++---- .../android/uart/repository/UARTService.kt | 8 ++- settings.gradle.kts | 2 +- 28 files changed, 163 insertions(+), 183 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 23f9f20f..ef135bbe 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -33,7 +33,7 @@ plugins { alias(libs.plugins.nordic.hilt) } -if (getGradle().getStartParameter().getTaskRequests().toString().contains("Release")){ +if (getGradle().getStartParameter().getTaskRequests().toString().contains("Release")) { apply(plugin = "com.google.gms.google-services") apply(plugin = "com.google.firebase.crashlytics") } @@ -69,18 +69,14 @@ dependencies { implementation(libs.nordic.uilogger) implementation(libs.nordic.permissions.ble) implementation(libs.nordic.analytics) + + implementation(libs.nordic.blek.client) - implementation(libs.androidx.lifecycle.runtime.compose) - - implementation(libs.nordic.ble.common) - implementation(libs.nordic.ble.ktx) - - implementation(libs.androidx.hilt.navigation.compose) - - implementation(libs.androidx.compose.material.iconsExtended) implementation(libs.androidx.core.ktx) implementation(libs.androidx.compose.material3) + implementation(libs.androidx.compose.material.iconsExtended) implementation(libs.androidx.activity.compose) + implementation(libs.androidx.lifecycle.runtime.compose) - implementation(libs.nordic.blek.client) + implementation(libs.androidx.hilt.navigation.compose) } diff --git a/lib_scanner/build.gradle.kts b/lib_scanner/build.gradle.kts index 51a09721..9a3684ce 100644 --- a/lib_scanner/build.gradle.kts +++ b/lib_scanner/build.gradle.kts @@ -39,12 +39,12 @@ android { dependencies { implementation(libs.nordic.navigation) - implementation(libs.nordic.blek.uiscanner) + implementation(libs.nordic.blek.uiscanner) implementation(libs.nordic.blek.scanner) + implementation(libs.androidx.compose.material3) implementation(libs.androidx.compose.material.iconsExtended) implementation(libs.androidx.core.ktx) - implementation(libs.androidx.compose.material3) implementation(libs.androidx.activity.compose) } diff --git a/lib_service/build.gradle.kts b/lib_service/build.gradle.kts index c8c164b1..566cef72 100644 --- a/lib_service/build.gradle.kts +++ b/lib_service/build.gradle.kts @@ -40,11 +40,8 @@ android { dependencies { implementation(project(":lib_ui")) - - implementation(libs.nordic.ble.common) - implementation(libs.nordic.ble.ktx) + implementation(libs.nordic.blek.uiscanner) - implementation(libs.nordic.blek.core) implementation(libs.androidx.lifecycle.service) diff --git a/lib_service/src/main/java/no/nordicsemi/android/service/NotificationService.kt b/lib_service/src/main/java/no/nordicsemi/android/service/NotificationService.kt index e4f203aa..0b5c8515 100644 --- a/lib_service/src/main/java/no/nordicsemi/android/service/NotificationService.kt +++ b/lib_service/src/main/java/no/nordicsemi/android/service/NotificationService.kt @@ -65,7 +65,7 @@ abstract class NotificationService : LifecycleService() { private fun startForegroundService() { // when the activity closes we need to show the notification that user is connected to the peripheral sensor // We start the service as a foreground service as Android 8.0 (Oreo) onwards kills any running background services - val notification = createNotification(R.string.csc_notification_connected_message, 0) + val notification = createNotification(R.string.csc_notification_connected_message) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { startForeground(NOTIFICATION_ID, notification) } else { @@ -81,7 +81,7 @@ abstract class NotificationService : LifecycleService() { // when the activity rebinds to the service, remove the notification and stop the foreground service // on devices running Android 8.0 (Oreo) or above if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - stopForeground(true) + stopForeground(STOP_FOREGROUND_REMOVE) } else { cancelNotification() } @@ -92,9 +92,8 @@ abstract class NotificationService : LifecycleService() { * * @param messageResId the message resource id. The message must have one String parameter,

* f.e. `%s is connected` - * @param defaults */ - private fun createNotification(messageResId: Int, defaults: Int): Notification { + private fun createNotification(messageResId: Int): Notification { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { createNotificationChannel(CHANNEL_ID) } @@ -111,6 +110,7 @@ abstract class NotificationService : LifecycleService() { .build() } + @Suppress("SameParameterValue") @RequiresApi(Build.VERSION_CODES.O) private fun createNotificationChannel(channelName: String) { val channel = NotificationChannel( diff --git a/lib_ui/build.gradle.kts b/lib_ui/build.gradle.kts index 3d577f0f..41ca294f 100644 --- a/lib_ui/build.gradle.kts +++ b/lib_ui/build.gradle.kts @@ -43,13 +43,13 @@ android { dependencies { implementation(libs.nordic.uilogger) - implementation(libs.nordic.theme) + implementation(libs.nordic.logger) + implementation(libs.nordic.blek.client) + + implementation(libs.androidx.compose.material3) implementation(libs.androidx.compose.material.iconsExtended) implementation(libs.androidx.core.ktx) - implementation(libs.androidx.compose.material3) implementation(libs.androidx.activity.compose) - implementation(libs.nordic.blek.client) - implementation(libs.nordic.logger) } diff --git a/lib_utils/build.gradle.kts b/lib_utils/build.gradle.kts index 4be89537..6c2f2906 100644 --- a/lib_utils/build.gradle.kts +++ b/lib_utils/build.gradle.kts @@ -40,6 +40,8 @@ android { dependencies { implementation(libs.nordic.navigation) + implementation(libs.nordic.blek.uiscanner) + implementation(libs.kotlinx.coroutines.core) } diff --git a/profile_bps/build.gradle.kts b/profile_bps/build.gradle.kts index 5a8f75da..6932100e 100644 --- a/profile_bps/build.gradle.kts +++ b/profile_bps/build.gradle.kts @@ -47,19 +47,17 @@ dependencies { implementation(libs.nordic.blek.client) implementation(libs.nordic.blek.profile) + implementation(libs.nordic.blek.uiscanner) - implementation(libs.nordic.ble.common) - implementation(libs.nordic.ble.ktx) implementation(libs.nordic.navigation) implementation(libs.nordic.theme) implementation(libs.nordic.uilogger) - implementation(libs.nordic.blek.uiscanner) - - implementation(libs.androidx.compose.material.iconsExtended) - implementation(libs.androidx.hilt.navigation.compose) - implementation(libs.androidx.core.ktx) implementation(libs.androidx.compose.material3) + implementation(libs.androidx.compose.material.iconsExtended) + implementation(libs.androidx.core.ktx) implementation(libs.androidx.activity.compose) implementation(libs.androidx.lifecycle.service) + + implementation(libs.androidx.hilt.navigation.compose) } diff --git a/profile_bps/src/main/java/no/nordicsemi/android/bps/viewmodel/BPSViewModel.kt b/profile_bps/src/main/java/no/nordicsemi/android/bps/viewmodel/BPSViewModel.kt index c0867ce7..e44e6afb 100644 --- a/profile_bps/src/main/java/no/nordicsemi/android/bps/viewmodel/BPSViewModel.kt +++ b/profile_bps/src/main/java/no/nordicsemi/android/bps/viewmodel/BPSViewModel.kt @@ -127,7 +127,7 @@ internal class BPSViewModel @Inject constructor( logger = DefaultBleLogger.create(context, stringConst.APP_NAME, "BPS", device.address) - val client = ClientBleGatt.connect(context, device, logger = logger) + val client = ClientBleGatt.connect(context, device, viewModelScope, logger = logger) this@BPSViewModel.client = client client.connectionStateWithStatus diff --git a/profile_cgms/build.gradle.kts b/profile_cgms/build.gradle.kts index b7f82f0e..7fb0265c 100644 --- a/profile_cgms/build.gradle.kts +++ b/profile_cgms/build.gradle.kts @@ -45,22 +45,20 @@ dependencies { implementation(project(":lib_ui")) implementation(project(":lib_utils")) + implementation(libs.nordic.core) + implementation(libs.nordic.theme) + implementation(libs.nordic.uilogger) + implementation(libs.nordic.navigation) + + implementation(libs.nordic.blek.uiscanner) implementation(libs.nordic.blek.client) implementation(libs.nordic.blek.profile) - implementation(libs.nordic.ble.common) - implementation(libs.nordic.ble.ktx) - implementation(libs.nordic.uilogger) - - implementation(libs.nordic.theme) - implementation(libs.nordic.blek.uiscanner) - implementation(libs.nordic.navigation) - implementation(libs.nordic.core) - - implementation(libs.androidx.hilt.navigation.compose) + implementation(libs.androidx.compose.material3) implementation(libs.androidx.compose.material.iconsExtended) implementation(libs.androidx.core.ktx) - implementation(libs.androidx.compose.material3) implementation(libs.androidx.activity.compose) implementation(libs.androidx.lifecycle.service) + + implementation(libs.androidx.hilt.navigation.compose) } diff --git a/profile_cgms/src/main/java/no/nordicsemi/android/cgms/repository/CGMService.kt b/profile_cgms/src/main/java/no/nordicsemi/android/cgms/repository/CGMService.kt index 724527de..07479150 100644 --- a/profile_cgms/src/main/java/no/nordicsemi/android/cgms/repository/CGMService.kt +++ b/profile_cgms/src/main/java/no/nordicsemi/android/cgms/repository/CGMService.kt @@ -45,12 +45,12 @@ import kotlinx.coroutines.launch import no.nordicsemi.android.cgms.data.CGMRecordWithSequenceNumber import no.nordicsemi.android.cgms.data.CGMServiceCommand import no.nordicsemi.android.kotlin.ble.client.main.callback.ClientBleGatt -import no.nordicsemi.android.kotlin.ble.client.main.errors.GattOperationException import no.nordicsemi.android.kotlin.ble.client.main.service.ClientBleGattCharacteristic import no.nordicsemi.android.kotlin.ble.client.main.service.ClientBleGattServices import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionStateWithStatus +import no.nordicsemi.android.kotlin.ble.core.errors.GattOperationException import no.nordicsemi.android.kotlin.ble.profile.battery.BatteryLevelParser import no.nordicsemi.android.kotlin.ble.profile.cgm.CGMFeatureParser import no.nordicsemi.android.kotlin.ble.profile.cgm.CGMMeasurementParser @@ -58,7 +58,6 @@ import no.nordicsemi.android.kotlin.ble.profile.cgm.CGMSpecificOpsControlPointPa import no.nordicsemi.android.kotlin.ble.profile.cgm.CGMStatusParser import no.nordicsemi.android.kotlin.ble.profile.cgm.data.CGMErrorCode import no.nordicsemi.android.kotlin.ble.profile.cgm.data.CGMOpCode -import no.nordicsemi.android.kotlin.ble.profile.cgm.data.CGMSpecificOpsControlPointData import no.nordicsemi.android.kotlin.ble.profile.gls.CGMSpecificOpsControlPointDataParser import no.nordicsemi.android.kotlin.ble.profile.gls.RecordAccessControlPointInputParser import no.nordicsemi.android.kotlin.ble.profile.gls.RecordAccessControlPointParser @@ -133,7 +132,7 @@ internal class CGMService : NotificationService() { } private fun startGattClient(device: ServerDevice) = lifecycleScope.launch { - val client = ClientBleGatt.connect(this@CGMService, device, logger = { p, s -> repository.log(p, s) }) + val client = ClientBleGatt.connect(this@CGMService, device, lifecycleScope, logger = { p, s -> repository.log(p, s) }) this@CGMService.client = client client.connectionStateWithStatus diff --git a/profile_csc/build.gradle.kts b/profile_csc/build.gradle.kts index 1d66f68c..63c49608 100644 --- a/profile_csc/build.gradle.kts +++ b/profile_csc/build.gradle.kts @@ -45,22 +45,20 @@ dependencies { implementation(project(":lib_ui")) implementation(project(":lib_utils")) + implementation(libs.nordic.core) + implementation(libs.nordic.theme) + implementation(libs.nordic.uilogger) + implementation(libs.nordic.navigation) + implementation(libs.nordic.blek.client) implementation(libs.nordic.blek.profile) - - implementation(libs.nordic.ble.common) - implementation(libs.nordic.ble.ktx) - implementation(libs.nordic.uilogger) - - implementation(libs.nordic.theme) - implementation(libs.nordic.navigation) implementation(libs.nordic.blek.uiscanner) - implementation(libs.nordic.core) - implementation(libs.androidx.hilt.navigation.compose) + implementation(libs.androidx.compose.material3) implementation(libs.androidx.compose.material.iconsExtended) implementation(libs.androidx.core.ktx) - implementation(libs.androidx.compose.material3) implementation(libs.androidx.activity.compose) implementation(libs.androidx.lifecycle.service) + + implementation(libs.androidx.hilt.navigation.compose) } diff --git a/profile_csc/src/main/java/no/nordicsemi/android/csc/repository/CSCService.kt b/profile_csc/src/main/java/no/nordicsemi/android/csc/repository/CSCService.kt index 319b1674..da1be91b 100644 --- a/profile_csc/src/main/java/no/nordicsemi/android/csc/repository/CSCService.kt +++ b/profile_csc/src/main/java/no/nordicsemi/android/csc/repository/CSCService.kt @@ -86,7 +86,7 @@ internal class CSCService : NotificationService() { } private fun startGattClient(device: ServerDevice) = lifecycleScope.launch { - val client = ClientBleGatt.connect(this@CSCService, device, logger = { p, s -> repository.log(p, s) }) + val client = ClientBleGatt.connect(this@CSCService, device, lifecycleScope, logger = { p, s -> repository.log(p, s) }) this@CSCService.client = client client.connectionStateWithStatus diff --git a/profile_gls/build.gradle.kts b/profile_gls/build.gradle.kts index 882173b4..b684a5d1 100644 --- a/profile_gls/build.gradle.kts +++ b/profile_gls/build.gradle.kts @@ -45,27 +45,26 @@ dependencies { implementation(project(":lib_ui")) implementation(project(":lib_utils")) + implementation(libs.nordic.theme) + implementation(libs.nordic.navigation) + implementation(libs.nordic.uilogger) + implementation(libs.nordic.blek.client) implementation(libs.nordic.blek.profile) implementation(libs.nordic.blek.server) implementation(libs.nordic.blek.advertiser) + implementation(libs.nordic.blek.uiscanner) implementation(libs.chart) - implementation(libs.nordic.ble.common) - implementation(libs.nordic.ble.ktx) - implementation(libs.nordic.theme) - implementation(libs.nordic.blek.uiscanner) - implementation(libs.nordic.navigation) - implementation(libs.nordic.uilogger) - - implementation(libs.androidx.hilt.navigation.compose) implementation(libs.androidx.compose.material.iconsExtended) implementation(libs.androidx.core.ktx) implementation(libs.androidx.compose.material3) implementation(libs.androidx.activity.compose) implementation(libs.androidx.lifecycle.service) + implementation(libs.androidx.hilt.navigation.compose) + testImplementation(libs.hilt.android.testing) kaptTest(libs.hilt.compiler) testImplementation(libs.androidx.test.rules) diff --git a/profile_gls/src/main/java/no/nordicsemi/android/gls/GlsServer.kt b/profile_gls/src/main/java/no/nordicsemi/android/gls/GlsServer.kt index 9d9dbb3e..21360cf2 100644 --- a/profile_gls/src/main/java/no/nordicsemi/android/gls/GlsServer.kt +++ b/profile_gls/src/main/java/no/nordicsemi/android/gls/GlsServer.kt @@ -44,12 +44,12 @@ class GlsServer @Inject constructor( private val logger: BleLogger = DefaultConsoleLogger(context) ) { - lateinit var server: ServerBleGatt + private lateinit var server: ServerBleGatt - lateinit var glsCharacteristic: ServerBleGattCharacteristic - lateinit var glsContextCharacteristic: ServerBleGattCharacteristic - lateinit var racpCharacteristic: ServerBleGattCharacteristic - lateinit var batteryLevelCharacteristic: ServerBleGattCharacteristic + private lateinit var glsCharacteristic: ServerBleGattCharacteristic + private lateinit var glsContextCharacteristic: ServerBleGattCharacteristic + private lateinit var racpCharacteristic: ServerBleGattCharacteristic + private lateinit var batteryLevelCharacteristic: ServerBleGattCharacteristic private var lastRequest = DataByteArray() @@ -144,7 +144,7 @@ class GlsServer @Inject constructor( OLDEST_RECORD ) - val racp = DataByteArray.from(0x06, 0x00, 0x01, 0x01) + private val SUCCESS = DataByteArray.from(0x06, 0x00, 0x01, 0x01) fun start( context: Context, @@ -193,7 +193,8 @@ class GlsServer @Inject constructor( context = context, config = arrayOf(serviceConfig, batteryService), mock = device, - logger = { priority, log -> println(log) } + scope = scope, + logger = { _, log -> println(log) } ) val advertiser = BleAdvertiser.create(context) @@ -223,12 +224,11 @@ class GlsServer @Inject constructor( BATTERY_LEVEL_CHARACTERISTIC_UUID )!! - - startGlsService(connection) -// startBatteryService(connection) + startGlsService() +// startBatteryService() } - private fun startGlsService(connection: ServerBluetoothGattConnection) { + private fun startGlsService() { racpCharacteristic.value .onEach { lastRequest = it } .launchIn(scope) @@ -238,42 +238,38 @@ class GlsServer @Inject constructor( sendResponse(lastRequest) } - private fun sendResponse(request: DataByteArray) { - if (request == RecordAccessControlPointInputParser.reportNumberOfAllStoredRecords()) { - sendAll(glsCharacteristic) - racpCharacteristic.setValue(racp) - } else if (request == RecordAccessControlPointInputParser.reportLastStoredRecord()) { - sendLast(glsCharacteristic) - racpCharacteristic.setValue(racp) - } else if (request == RecordAccessControlPointInputParser.reportFirstStoredRecord()) { - sendFirst(glsCharacteristic) - racpCharacteristic.setValue(racp) + private fun sendResponse(request: DataByteArray) = scope.launch { + when (request) { + RecordAccessControlPointInputParser.reportNumberOfAllStoredRecords() -> { + records.forEach { + send(glsCharacteristic, it) + delay(100) + } + racpCharacteristic.setValueAndNotifyClient(SUCCESS) + } + RecordAccessControlPointInputParser.reportLastStoredRecord() -> { + send(glsCharacteristic, records.last()) + send(racpCharacteristic, SUCCESS) + } + RecordAccessControlPointInputParser.reportFirstStoredRecord() -> { + send(glsCharacteristic, records.first()) + send(racpCharacteristic, SUCCESS) + } } } - private fun sendFirst(characteristics: ServerBleGattCharacteristic) { - characteristics.setValue(records.first()) + private suspend fun send(characteristics: ServerBleGattCharacteristic, data: DataByteArray) { + characteristics.setValueAndNotifyClient(data) } - private fun sendLast(characteristics: ServerBleGattCharacteristic) { - characteristics.setValue(records.last()) - } - - private fun sendAll(characteristics: ServerBleGattCharacteristic) = scope.launch { - records.forEach { - characteristics.setValue(it) - delay(100) - } - } - - private fun startBatteryService(connection: ServerBluetoothGattConnection) { + private fun startBatteryService() { scope.launch { repeat(100) { - batteryLevelCharacteristic.setValue(DataByteArray.from(0x61)) + send(batteryLevelCharacteristic, DataByteArray.from(0x61)) delay(STANDARD_DELAY) - batteryLevelCharacteristic.setValue(DataByteArray.from(0x60)) + send(batteryLevelCharacteristic, DataByteArray.from(0x60)) delay(STANDARD_DELAY) - batteryLevelCharacteristic.setValue(DataByteArray.from(0x5F)) + send(batteryLevelCharacteristic, DataByteArray.from(0x5F)) delay(STANDARD_DELAY) } } diff --git a/profile_gls/src/main/java/no/nordicsemi/android/gls/details/view/GLSDetailsContentView.kt b/profile_gls/src/main/java/no/nordicsemi/android/gls/details/view/GLSDetailsContentView.kt index 6112db26..0162cad4 100644 --- a/profile_gls/src/main/java/no/nordicsemi/android/gls/details/view/GLSDetailsContentView.kt +++ b/profile_gls/src/main/java/no/nordicsemi/android/gls/details/view/GLSDetailsContentView.kt @@ -40,7 +40,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll -import androidx.compose.material3.Divider +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -71,7 +71,7 @@ internal fun GLSDetailsContentView(record: GLSRecord, context: GLSMeasurementCon ) } - Divider( + HorizontalDivider( color = MaterialTheme.colorScheme.secondary, thickness = 1.dp, modifier = Modifier.padding(vertical = 16.dp) @@ -112,7 +112,7 @@ internal fun GLSDetailsContentView(record: GLSRecord, context: GLSMeasurementCon } record.status?.let { - Divider( + HorizontalDivider( color = MaterialTheme.colorScheme.secondary, thickness = 1.dp, modifier = Modifier.padding(vertical = 16.dp) @@ -178,7 +178,7 @@ internal fun GLSDetailsContentView(record: GLSRecord, context: GLSMeasurementCon } context?.let { - Divider( + HorizontalDivider( color = MaterialTheme.colorScheme.secondary, thickness = 1.dp, modifier = Modifier.padding(vertical = 16.dp) diff --git a/profile_gls/src/main/java/no/nordicsemi/android/gls/main/viewmodel/GLSViewModel.kt b/profile_gls/src/main/java/no/nordicsemi/android/gls/main/viewmodel/GLSViewModel.kt index 56707b13..3c81aee2 100644 --- a/profile_gls/src/main/java/no/nordicsemi/android/gls/main/viewmodel/GLSViewModel.kt +++ b/profile_gls/src/main/java/no/nordicsemi/android/gls/main/viewmodel/GLSViewModel.kt @@ -32,9 +32,10 @@ package no.nordicsemi.android.gls.main.viewmodel import android.annotation.SuppressLint +import android.app.Application import android.content.Context import android.os.ParcelUuid -import androidx.lifecycle.ViewModel +import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.qualifiers.ApplicationContext @@ -61,12 +62,12 @@ import no.nordicsemi.android.gls.main.view.OnGLSRecordClick import no.nordicsemi.android.gls.main.view.OnWorkingModeSelected import no.nordicsemi.android.gls.main.view.OpenLoggerEvent import no.nordicsemi.android.kotlin.ble.client.main.callback.ClientBleGatt -import no.nordicsemi.android.kotlin.ble.client.main.errors.GattOperationException import no.nordicsemi.android.kotlin.ble.client.main.service.ClientBleGattCharacteristic import no.nordicsemi.android.kotlin.ble.client.main.service.ClientBleGattServices import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionStateWithStatus +import no.nordicsemi.android.kotlin.ble.core.errors.GattOperationException import no.nordicsemi.android.kotlin.ble.profile.battery.BatteryLevelParser import no.nordicsemi.android.kotlin.ble.profile.gls.GlucoseMeasurementContextParser import no.nordicsemi.android.kotlin.ble.profile.gls.GlucoseMeasurementParser @@ -99,13 +100,12 @@ val BATTERY_LEVEL_CHARACTERISTIC_UUID = UUID.fromString("00002A19-0000-1000-8000 @SuppressLint("MissingPermission") @HiltViewModel internal class GLSViewModel @Inject constructor( - @ApplicationContext - private val context: Context, + @ApplicationContext context: Context, private val navigationManager: Navigator, private val analytics: AppAnalytics, private val stringConst: StringConst, private val loggerFactory: NordicLoggerFactory -) : ViewModel() { +) : AndroidViewModel(context as Application) { private var client: ClientBleGatt? = null private lateinit var logger: BleLoggerAndLauncher @@ -168,9 +168,9 @@ internal class GLSViewModel @Inject constructor( private fun startGattClient(device: ServerDevice) = viewModelScope.launch { _state.value = _state.value.copy(deviceName = device.name) - logger = loggerFactory.createNordicLogger(context, stringConst.APP_NAME, "GLS", device.address) + logger = loggerFactory.createNordicLogger(getApplication(), stringConst.APP_NAME, "GLS", device.address) - val client = ClientBleGatt.connect(context, device, logger = logger) + val client = ClientBleGatt.connect(getApplication(), device, viewModelScope, logger = logger) this@GLSViewModel.client = client client.waitForBonding() diff --git a/profile_hrs/build.gradle.kts b/profile_hrs/build.gradle.kts index e03228fc..4a3c80a4 100644 --- a/profile_hrs/build.gradle.kts +++ b/profile_hrs/build.gradle.kts @@ -45,23 +45,22 @@ dependencies { implementation(project(":lib_ui")) implementation(project(":lib_utils")) + implementation(libs.nordic.core) + implementation(libs.nordic.theme) + implementation(libs.nordic.navigation) + implementation(libs.nordic.uilogger) + implementation(libs.nordic.blek.client) implementation(libs.nordic.blek.profile) + implementation(libs.nordic.blek.uiscanner) implementation(libs.chart) - implementation(libs.nordic.theme) - implementation(libs.nordic.ble.common) - implementation(libs.nordic.ble.ktx) - implementation(libs.nordic.navigation) - implementation(libs.nordic.blek.uiscanner) - implementation(libs.nordic.uilogger) - implementation(libs.nordic.core) - - implementation(libs.androidx.hilt.navigation.compose) + implementation(libs.androidx.compose.material3) implementation(libs.androidx.compose.material.iconsExtended) implementation(libs.androidx.core.ktx) - implementation(libs.androidx.compose.material3) implementation(libs.androidx.activity.compose) implementation(libs.androidx.lifecycle.service) + + implementation(libs.androidx.hilt.navigation.compose) } diff --git a/profile_hrs/src/main/java/no/nordicsemi/android/hrs/service/HRSService.kt b/profile_hrs/src/main/java/no/nordicsemi/android/hrs/service/HRSService.kt index 957b1819..de299496 100644 --- a/profile_hrs/src/main/java/no/nordicsemi/android/hrs/service/HRSService.kt +++ b/profile_hrs/src/main/java/no/nordicsemi/android/hrs/service/HRSService.kt @@ -88,7 +88,7 @@ internal class HRSService : NotificationService() { } private fun startGattClient(device: ServerDevice) = lifecycleScope.launch { - val client = ClientBleGatt.connect(this@HRSService, device, logger = { p, s -> repository.log(p, s) }) + val client = ClientBleGatt.connect(this@HRSService, device, lifecycleScope, logger = { p, s -> repository.log(p, s) }) this@HRSService.client = client client.waitForBonding() diff --git a/profile_hts/build.gradle.kts b/profile_hts/build.gradle.kts index 8355510b..1f4b79cf 100644 --- a/profile_hts/build.gradle.kts +++ b/profile_hts/build.gradle.kts @@ -47,20 +47,18 @@ dependencies { implementation(libs.nordic.blek.client) implementation(libs.nordic.blek.profile) - - implementation(libs.nordic.ble.common) - implementation(libs.nordic.ble.ktx) - - implementation(libs.nordic.theme) implementation(libs.nordic.blek.uiscanner) + + implementation(libs.nordic.core) + implementation(libs.nordic.theme) implementation(libs.nordic.navigation) implementation(libs.nordic.uilogger) - implementation(libs.nordic.core) - implementation(libs.androidx.hilt.navigation.compose) + implementation(libs.androidx.compose.material3) implementation(libs.androidx.compose.material.iconsExtended) implementation(libs.androidx.core.ktx) - implementation(libs.androidx.compose.material3) implementation(libs.androidx.activity.compose) implementation(libs.androidx.lifecycle.service) + + implementation(libs.androidx.hilt.navigation.compose) } diff --git a/profile_hts/src/main/java/no/nordicsemi/android/hts/repository/HTSService.kt b/profile_hts/src/main/java/no/nordicsemi/android/hts/repository/HTSService.kt index f28c476b..d241f13b 100644 --- a/profile_hts/src/main/java/no/nordicsemi/android/hts/repository/HTSService.kt +++ b/profile_hts/src/main/java/no/nordicsemi/android/hts/repository/HTSService.kt @@ -86,7 +86,7 @@ internal class HTSService : NotificationService() { } private fun startGattClient(device: ServerDevice) = lifecycleScope.launch { - val client = ClientBleGatt.connect(this@HTSService, device, logger = { p, s -> repository.log(p, s) }) + val client = ClientBleGatt.connect(this@HTSService, device, lifecycleScope, logger = { p, s -> repository.log(p, s) }) this@HTSService.client = client client.connectionStateWithStatus diff --git a/profile_prx/build.gradle.kts b/profile_prx/build.gradle.kts index a4583611..2b39270f 100644 --- a/profile_prx/build.gradle.kts +++ b/profile_prx/build.gradle.kts @@ -48,20 +48,18 @@ dependencies { implementation(libs.nordic.blek.client) implementation(libs.nordic.blek.profile) implementation(libs.nordic.blek.server) - - implementation(libs.nordic.ble.common) - implementation(libs.nordic.ble.ktx) - - implementation(libs.nordic.theme) implementation(libs.nordic.blek.uiscanner) + + implementation(libs.nordic.core) + implementation(libs.nordic.theme) implementation(libs.nordic.navigation) implementation(libs.nordic.uilogger) - implementation(libs.nordic.core) - implementation(libs.androidx.hilt.navigation.compose) + implementation(libs.androidx.compose.material3) implementation(libs.androidx.compose.material.iconsExtended) implementation(libs.androidx.core.ktx) - implementation(libs.androidx.compose.material3) implementation(libs.androidx.activity.compose) implementation(libs.androidx.lifecycle.service) + + implementation(libs.androidx.hilt.navigation.compose) } 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 55e9d4e9..1eb2c6b2 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 @@ -129,7 +129,7 @@ internal class PRXService : NotificationService() { characteristicConfigs = listOf(linkLossCharacteristic) ) - val server = ServerBleGatt.create(this@PRXService, prxServiceConfig, linkLossServiceConfig) + val server = ServerBleGatt.create(this@PRXService, lifecycleScope, prxServiceConfig, linkLossServiceConfig) this@PRXService.server = server //Order is important. We don't want to connect before services have been added to the server. @@ -163,6 +163,7 @@ internal class PRXService : NotificationService() { val client = ClientBleGatt.connect( this@PRXService, device, + lifecycleScope, logger = { p, s -> repository.log(p, s) }, options = BleGattConnectOptions(autoConnect = true) ) diff --git a/profile_rscs/build.gradle.kts b/profile_rscs/build.gradle.kts index e1452d04..03a73200 100644 --- a/profile_rscs/build.gradle.kts +++ b/profile_rscs/build.gradle.kts @@ -45,22 +45,20 @@ dependencies { implementation(project(":lib_ui")) implementation(project(":lib_utils")) - implementation(libs.nordic.blek.client) - implementation(libs.nordic.blek.profile) - - implementation(libs.nordic.ble.common) - implementation(libs.nordic.ble.ktx) - + implementation(libs.nordic.core) implementation(libs.nordic.theme) - implementation(libs.nordic.blek.uiscanner) implementation(libs.nordic.navigation) implementation(libs.nordic.uilogger) - implementation(libs.nordic.core) - implementation(libs.androidx.hilt.navigation.compose) + implementation(libs.nordic.blek.client) + implementation(libs.nordic.blek.profile) + implementation(libs.nordic.blek.uiscanner) + + implementation(libs.androidx.compose.material3) implementation(libs.androidx.compose.material.iconsExtended) implementation(libs.androidx.core.ktx) - implementation(libs.androidx.compose.material3) implementation(libs.androidx.activity.compose) implementation(libs.androidx.lifecycle.service) + + implementation(libs.androidx.hilt.navigation.compose) } diff --git a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/repository/RSCSService.kt b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/repository/RSCSService.kt index 28b64892..1b913109 100644 --- a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/repository/RSCSService.kt +++ b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/repository/RSCSService.kt @@ -86,7 +86,7 @@ internal class RSCSService : NotificationService() { } private fun startGattClient(device: ServerDevice) = lifecycleScope.launch { - val client = ClientBleGatt.connect(this@RSCSService, device, logger = { p, s -> repository.log(p, s) }) + val client = ClientBleGatt.connect(this@RSCSService, device, lifecycleScope, logger = { p, s -> repository.log(p, s) }) this@RSCSService.client = client client.connectionStateWithStatus diff --git a/profile_uart/build.gradle.kts b/profile_uart/build.gradle.kts index bca8be56..cf1bd033 100644 --- a/profile_uart/build.gradle.kts +++ b/profile_uart/build.gradle.kts @@ -50,11 +50,17 @@ dependencies { implementation(project(":lib_ui")) implementation(project(":lib_utils")) + implementation(libs.nordic.core) + implementation(libs.nordic.theme) + implementation(libs.nordic.navigation) + implementation(libs.nordic.uilogger) + implementation(libs.nordic.blek.client) implementation(libs.nordic.blek.profile) implementation(libs.nordic.blek.core) implementation(libs.nordic.blek.server) implementation(libs.nordic.blek.advertiser) + implementation(libs.nordic.blek.uiscanner) implementation(libs.room.runtime) implementation(libs.room.ktx) @@ -63,25 +69,16 @@ dependencies { implementation(libs.accompanist.pager) implementation(libs.accompanist.pagerindicators) - implementation(libs.nordic.ble.common) - implementation(libs.nordic.ble.ktx) - - implementation(libs.nordic.theme) - implementation(libs.nordic.navigation) - implementation(libs.nordic.uilogger) - implementation(libs.nordic.core) - implementation(libs.nordic.blek.uiscanner) - implementation(libs.androidx.dataStore.core) implementation(libs.androidx.dataStore.preferences) - - implementation(libs.androidx.hilt.navigation.compose) + implementation(libs.androidx.compose.material3) implementation(libs.androidx.compose.material.iconsExtended) implementation(libs.androidx.core.ktx) - implementation(libs.androidx.compose.material3) implementation(libs.androidx.activity.compose) implementation(libs.androidx.lifecycle.service) + implementation(libs.androidx.hilt.navigation.compose) + testImplementation(libs.hilt.android.testing) kaptTest(libs.hilt.compiler) testImplementation(libs.androidx.test.rules) diff --git a/profile_uart/src/main/java/no/nordicsemi/android/uart/UartServer.kt b/profile_uart/src/main/java/no/nordicsemi/android/uart/UartServer.kt index ba3a8a43..3f9e8f54 100644 --- a/profile_uart/src/main/java/no/nordicsemi/android/uart/UartServer.kt +++ b/profile_uart/src/main/java/no/nordicsemi/android/uart/UartServer.kt @@ -36,11 +36,11 @@ class UartServer @Inject constructor( private val scope: CoroutineScope ) { - lateinit var server: ServerBleGatt + private lateinit var server: ServerBleGatt - lateinit var rxCharacteristic: ServerBleGattCharacteristic - lateinit var txCharacteristic: ServerBleGattCharacteristic - lateinit var batteryLevelCharacteristic: ServerBleGattCharacteristic + private lateinit var rxCharacteristic: ServerBleGattCharacteristic + private lateinit var txCharacteristic: ServerBleGattCharacteristic + private lateinit var batteryLevelCharacteristic: ServerBleGattCharacteristic fun start( context: Context, @@ -81,6 +81,7 @@ class UartServer @Inject constructor( server = ServerBleGatt.create( context = context, + scope = scope, config = arrayOf(uartService, batteryService), mock = device ) @@ -105,27 +106,30 @@ class UartServer @Inject constructor( txCharacteristic = glsService.findCharacteristic(UART_TX_CHARACTERISTIC_UUID)!! rxCharacteristic.value.onEach { - txCharacteristic.setValue(it) + send(txCharacteristic, it) }.launchIn(scope) val batteryService = connection.services.findService(BATTERY_SERVICE_UUID)!! - batteryLevelCharacteristic = batteryService.findCharacteristic( - BATTERY_LEVEL_CHARACTERISTIC_UUID - )!! + batteryLevelCharacteristic = batteryService + .findCharacteristic(BATTERY_LEVEL_CHARACTERISTIC_UUID)!! - startBatteryService(connection) + startBatteryService() } - private fun startBatteryService(connection: ServerBluetoothGattConnection) { + private fun startBatteryService() { scope.launch { repeat(100) { - batteryLevelCharacteristic.setValue(DataByteArray.from(0x61)) + send(batteryLevelCharacteristic, DataByteArray.from(0x61)) delay(STANDARD_DELAY) - batteryLevelCharacteristic.setValue(DataByteArray.from(0x60)) + send(batteryLevelCharacteristic, DataByteArray.from(0x60)) delay(STANDARD_DELAY) - batteryLevelCharacteristic.setValue(DataByteArray.from(0x5F)) + send(batteryLevelCharacteristic, DataByteArray.from(0x5F)) delay(STANDARD_DELAY) } } } + + private suspend fun send(characteristics: ServerBleGattCharacteristic, data: DataByteArray) { + characteristics.setValueAndNotifyClient(data) + } } \ No newline at end of file diff --git a/profile_uart/src/main/java/no/nordicsemi/android/uart/repository/UARTService.kt b/profile_uart/src/main/java/no/nordicsemi/android/uart/repository/UARTService.kt index 56ff278b..c48be9c4 100644 --- a/profile_uart/src/main/java/no/nordicsemi/android/uart/repository/UARTService.kt +++ b/profile_uart/src/main/java/no/nordicsemi/android/uart/repository/UARTService.kt @@ -39,6 +39,7 @@ import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch @@ -91,7 +92,7 @@ internal class UARTService : NotificationService() { } private fun startGattClient(device: ServerDevice) = lifecycleScope.launch { - val client = ClientBleGatt.connect(this@UARTService, device, logger = { p, s -> repository.log(p, s) }) + val client = ClientBleGatt.connect(this@UARTService, device, lifecycleScope, logger = { p, s -> repository.log(p, s) }) this@UARTService.client = client if (!client.isConnected) { @@ -133,8 +134,9 @@ internal class UARTService : NotificationService() { ?.launchIn(lifecycleScope) txCharacteristic.getNotifications() - .onEach { repository.onNewMessageReceived(String(it.value)) } - .onEach { repository.log(10, "Received: ${String(it.value)}") } + .map { String(it.value) } + .onEach { repository.onNewMessageReceived(it) } + .onEach { repository.log(10, "Received: $it") } .catch { it.printStackTrace() } .launchIn(lifecycleScope) diff --git a/settings.gradle.kts b/settings.gradle.kts index 9f913ba3..9c175671 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -50,7 +50,7 @@ dependencyResolutionManagement { } versionCatalogs { create("libs") { - from("no.nordicsemi.android.gradle:version-catalog:1.9.13") + from("no.nordicsemi.android.gradle:version-catalog:1.10.6") } } }