diff --git a/lib_scanner/src/main/java/no/nordicsemi/android/toolbox/scanner/ScannerDestination.kt b/lib_scanner/src/main/java/no/nordicsemi/android/toolbox/scanner/ScannerDestination.kt index da5cf239..8e86d360 100644 --- a/lib_scanner/src/main/java/no/nordicsemi/android/toolbox/scanner/ScannerDestination.kt +++ b/lib_scanner/src/main/java/no/nordicsemi/android/toolbox/scanner/ScannerDestination.kt @@ -8,9 +8,9 @@ import no.nordicsemi.android.common.navigation.viewmodel.SimpleNavigationViewMod import no.nordicsemi.android.common.ui.scanner.DeviceSelected import no.nordicsemi.android.common.ui.scanner.ScannerScreen import no.nordicsemi.android.common.ui.scanner.ScanningCancelled -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice +import no.nordicsemi.android.kotlin.ble.core.ServerDevice -val ScannerDestinationId = createDestination("uiscanner-destination") +val ScannerDestinationId = createDestination("uiscanner-destination") val ScannerDestination = defineDestination(ScannerDestinationId) { val navigationViewModel = hiltViewModel() diff --git a/lib_service/build.gradle.kts b/lib_service/build.gradle.kts index a58d8cce..784c1105 100644 --- a/lib_service/build.gradle.kts +++ b/lib_service/build.gradle.kts @@ -44,6 +44,8 @@ dependencies { implementation(libs.nordic.ble.ktx) implementation(libs.nordic.uiscanner) + implementation("no.nordicsemi.android.kotlin.ble:core:0.0.1") + implementation(libs.androidx.lifecycle.service) implementation(libs.androidx.localbroadcastmanager) implementation(libs.androidx.core) diff --git a/lib_service/src/main/java/no/nordicsemi/android/service/ServiceManager.kt b/lib_service/src/main/java/no/nordicsemi/android/service/ServiceManager.kt index f2753e6f..faf0c063 100644 --- a/lib_service/src/main/java/no/nordicsemi/android/service/ServiceManager.kt +++ b/lib_service/src/main/java/no/nordicsemi/android/service/ServiceManager.kt @@ -35,7 +35,7 @@ import android.bluetooth.BluetoothDevice import android.content.Context import android.content.Intent import dagger.hilt.android.qualifiers.ApplicationContext -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice +import no.nordicsemi.android.kotlin.ble.core.ServerDevice import javax.inject.Inject const val DEVICE_DATA = "device-data" @@ -45,7 +45,7 @@ class ServiceManager @Inject constructor( private val context: Context ) { - fun startService(service: Class, device: DiscoveredBluetoothDevice) { + fun startService(service: Class, device: ServerDevice) { val intent = Intent(context, service).apply { putExtra(DEVICE_DATA, device) } diff --git a/profile_bps/build.gradle.kts b/profile_bps/build.gradle.kts index a2d32398..39c04e70 100644 --- a/profile_bps/build.gradle.kts +++ b/profile_bps/build.gradle.kts @@ -46,6 +46,7 @@ dependencies { implementation(project(":lib_utils")) implementation("no.nordicsemi.android.kotlin.ble:core:0.0.1") + implementation("no.nordicsemi.android.kotlin.ble:profile:0.0.1") implementation(libs.nordic.ble.common) implementation(libs.nordic.ble.ktx) diff --git a/profile_bps/src/main/java/no/nordicsemi/android/bps/repository/BPSRepository.kt b/profile_bps/src/main/java/no/nordicsemi/android/bps/repository/BPSRepository.kt index 527a4db8..aeaaf140 100644 --- a/profile_bps/src/main/java/no/nordicsemi/android/bps/repository/BPSRepository.kt +++ b/profile_bps/src/main/java/no/nordicsemi/android/bps/repository/BPSRepository.kt @@ -41,12 +41,11 @@ import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch -import no.nordicsemi.android.ble.ktx.suspend import no.nordicsemi.android.bps.data.BPSData import no.nordicsemi.android.bps.data.BPSManager import no.nordicsemi.android.common.logger.NordicLogger import no.nordicsemi.android.common.logger.NordicLoggerFactory -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice +import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.service.BleManagerResult import no.nordicsemi.android.ui.view.StringConst import javax.inject.Inject @@ -61,7 +60,7 @@ internal class BPSRepository @Inject constructor( private var logger: NordicLogger? = null - fun downloadData(scope: CoroutineScope, device: DiscoveredBluetoothDevice): Flow> = callbackFlow { + fun downloadData(scope: CoroutineScope, device: ServerDevice): Flow> = callbackFlow { val createdLogger = loggerFactory.create(stringConst.APP_NAME, "BPS", device.address).also { logger = it } @@ -81,15 +80,15 @@ internal class BPSRepository @Inject constructor( } } - private suspend fun BPSManager.start(device: DiscoveredBluetoothDevice) { - try { - connect(device.device) - .useAutoConnect(false) - .retry(3, 100) - .suspend() - } catch (e: Exception) { - e.printStackTrace() - } + private suspend fun BPSManager.start(device: ServerDevice) { +// try { +// connect(device.device) +// .useAutoConnect(false) +// .retry(3, 100) +// .suspend() +// } catch (e: Exception) { +// e.printStackTrace() +// } } fun openLogger() { diff --git a/profile_bps/src/main/java/no/nordicsemi/android/bps/view/BPSContentView.kt b/profile_bps/src/main/java/no/nordicsemi/android/bps/view/BPSContentView.kt index baf2d1c2..da2621de 100644 --- a/profile_bps/src/main/java/no/nordicsemi/android/bps/view/BPSContentView.kt +++ b/profile_bps/src/main/java/no/nordicsemi/android/bps/view/BPSContentView.kt @@ -34,7 +34,6 @@ package no.nordicsemi.android.bps.view import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.runtime.Composable 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 3f79cd58..de180339 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 @@ -52,7 +52,7 @@ import no.nordicsemi.android.bps.view.OpenLoggerEvent import no.nordicsemi.android.bps.view.WorkingState import no.nordicsemi.android.common.navigation.NavigationResult import no.nordicsemi.android.common.navigation.Navigator -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice +import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.service.ConnectedResult import no.nordicsemi.android.toolbox.scanner.ScannerDestinationId import javax.inject.Inject @@ -75,7 +75,7 @@ internal class BPSViewModel @Inject constructor( .launchIn(viewModelScope) } - private fun handleArgs(result: NavigationResult) { + private fun handleArgs(result: NavigationResult) { when (result) { is NavigationResult.Cancelled -> navigationManager.navigateUp() is NavigationResult.Success -> connectDevice(result.value) @@ -89,7 +89,7 @@ internal class BPSViewModel @Inject constructor( } } - private fun connectDevice(device: DiscoveredBluetoothDevice) { + private fun connectDevice(device: ServerDevice) { repository.downloadData(viewModelScope, device).onEach { _state.value = WorkingState(it) diff --git a/profile_cgms/build.gradle.kts b/profile_cgms/build.gradle.kts index 4c107eff..f444d877 100644 --- a/profile_cgms/build.gradle.kts +++ b/profile_cgms/build.gradle.kts @@ -45,6 +45,9 @@ dependencies { implementation(project(":lib_ui")) implementation(project(":lib_utils")) + implementation("no.nordicsemi.android.kotlin.ble:core:0.0.1") + implementation("no.nordicsemi.android.kotlin.ble:profile:0.0.1") + implementation(libs.nordic.ble.common) implementation(libs.nordic.ble.ktx) implementation(libs.nordic.uilogger) diff --git a/profile_cgms/src/main/java/no/nordicsemi/android/cgms/repository/CGMRepository.kt b/profile_cgms/src/main/java/no/nordicsemi/android/cgms/repository/CGMRepository.kt index 43b179eb..f76367d9 100644 --- a/profile_cgms/src/main/java/no/nordicsemi/android/cgms/repository/CGMRepository.kt +++ b/profile_cgms/src/main/java/no/nordicsemi/android/cgms/repository/CGMRepository.kt @@ -45,7 +45,7 @@ import no.nordicsemi.android.cgms.data.CGMData import no.nordicsemi.android.cgms.data.CGMManager import no.nordicsemi.android.common.logger.NordicLogger import no.nordicsemi.android.common.logger.NordicLoggerFactory -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice +import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.service.BleManagerResult import no.nordicsemi.android.service.IdleResult import no.nordicsemi.android.service.ServiceManager @@ -70,11 +70,11 @@ class CGMRepository @Inject constructor( val isRunning = data.map { it.isRunning() } val hasBeenDisconnected = data.map { it.hasBeenDisconnected() } - fun launch(device: DiscoveredBluetoothDevice) { + fun launch(device: ServerDevice) { serviceManager.startService(CGMService::class.java, device) } - fun start(device: DiscoveredBluetoothDevice, scope: CoroutineScope) { + fun start(device: ServerDevice, scope: CoroutineScope) { val createdLogger = loggerFactory.create(stringConst.APP_NAME, "CGMS", device.address).also { logger = it } @@ -90,15 +90,15 @@ class CGMRepository @Inject constructor( } } - private suspend fun CGMManager.start(device: DiscoveredBluetoothDevice) { - try { - connect(device.device) - .useAutoConnect(false) - .retry(3, 100) - .suspend() - } catch (e: Exception) { - e.printStackTrace() - } + private suspend fun CGMManager.start(device: ServerDevice) { +// try { +// connect(device.device) +// .useAutoConnect(false) +// .retry(3, 100) +// .suspend() +// } catch (e: Exception) { +// e.printStackTrace() +// } } fun requestAllRecords() { 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 853516d3..9f53dc2d 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 @@ -36,7 +36,7 @@ import androidx.lifecycle.lifecycleScope import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice +import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.service.DEVICE_DATA import no.nordicsemi.android.service.NotificationService import javax.inject.Inject @@ -50,7 +50,7 @@ internal class CGMService : NotificationService() { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { super.onStartCommand(intent, flags, startId) - val device = intent!!.getParcelableExtra(DEVICE_DATA)!! + val device = intent!!.getParcelableExtra(DEVICE_DATA)!! repository.start(device, lifecycleScope) diff --git a/profile_cgms/src/main/java/no/nordicsemi/android/cgms/view/CGMContentView.kt b/profile_cgms/src/main/java/no/nordicsemi/android/cgms/view/CGMContentView.kt index 7e949d51..bdfacfc0 100644 --- a/profile_cgms/src/main/java/no/nordicsemi/android/cgms/view/CGMContentView.kt +++ b/profile_cgms/src/main/java/no/nordicsemi/android/cgms/view/CGMContentView.kt @@ -38,7 +38,6 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Search diff --git a/profile_cgms/src/main/java/no/nordicsemi/android/cgms/viewmodel/CGMViewModel.kt b/profile_cgms/src/main/java/no/nordicsemi/android/cgms/viewmodel/CGMViewModel.kt index 6cb09a35..afca2922 100644 --- a/profile_cgms/src/main/java/no/nordicsemi/android/cgms/viewmodel/CGMViewModel.kt +++ b/profile_cgms/src/main/java/no/nordicsemi/android/cgms/viewmodel/CGMViewModel.kt @@ -57,7 +57,7 @@ import no.nordicsemi.android.cgms.view.OpenLoggerEvent import no.nordicsemi.android.cgms.view.WorkingState import no.nordicsemi.android.common.navigation.NavigationResult import no.nordicsemi.android.common.navigation.Navigator -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice +import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.service.ConnectedResult import no.nordicsemi.android.toolbox.scanner.ScannerDestinationId import javax.inject.Inject @@ -105,7 +105,7 @@ internal class CGMViewModel @Inject constructor( .launchIn(viewModelScope) } - private fun handleResult(result: NavigationResult) { + private fun handleResult(result: NavigationResult) { when (result) { is NavigationResult.Cancelled -> navigationManager.navigateUp() is NavigationResult.Success -> repository.launch(result.value) diff --git a/profile_csc/build.gradle.kts b/profile_csc/build.gradle.kts index 3418458c..ac51882f 100644 --- a/profile_csc/build.gradle.kts +++ b/profile_csc/build.gradle.kts @@ -45,6 +45,9 @@ dependencies { implementation(project(":lib_ui")) implementation(project(":lib_utils")) + implementation("no.nordicsemi.android.kotlin.ble:core:0.0.1") + implementation("no.nordicsemi.android.kotlin.ble:profile:0.0.1") + implementation(libs.nordic.ble.common) implementation(libs.nordic.ble.ktx) implementation(libs.nordic.uilogger) diff --git a/profile_csc/src/main/java/no/nordicsemi/android/csc/data/CSCData.kt b/profile_csc/src/main/java/no/nordicsemi/android/csc/data/CSCData.kt deleted file mode 100644 index e9e54649..00000000 --- a/profile_csc/src/main/java/no/nordicsemi/android/csc/data/CSCData.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2022, Nordic Semiconductor - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package no.nordicsemi.android.csc.data - -internal data class CSCData( - val scanDevices: Boolean = false, - val speed: Float = 0f, - val cadence: Float = 0f, - val distance: Float = 0f, - val totalDistance: Float = 0f, - val gearRatio: Float = 0f, - val batteryLevel: Int? = null, - val wheelSize: WheelSize = WheelSize() -) diff --git a/profile_csc/src/main/java/no/nordicsemi/android/csc/data/CSCManager.kt b/profile_csc/src/main/java/no/nordicsemi/android/csc/data/CSCManager.kt deleted file mode 100644 index 5e44daf9..00000000 --- a/profile_csc/src/main/java/no/nordicsemi/android/csc/data/CSCManager.kt +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2022, Nordic Semiconductor - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package no.nordicsemi.android.csc.data - -import android.bluetooth.BluetoothGatt -import android.bluetooth.BluetoothGattCharacteristic -import android.content.Context -import android.util.Log -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import no.nordicsemi.android.ble.BleManager -import no.nordicsemi.android.ble.common.callback.battery.BatteryLevelResponse -import no.nordicsemi.android.ble.common.callback.csc.CyclingSpeedAndCadenceMeasurementResponse -import no.nordicsemi.android.ble.ktx.asValidResponseFlow -import no.nordicsemi.android.common.logger.NordicLogger -import no.nordicsemi.android.service.ConnectionObserverAdapter -import java.util.* - -val CSC_SERVICE_UUID: UUID = UUID.fromString("00001816-0000-1000-8000-00805f9b34fb") -private val CSC_MEASUREMENT_CHARACTERISTIC_UUID = UUID.fromString("00002A5B-0000-1000-8000-00805f9b34fb") - -private val BATTERY_SERVICE_UUID = UUID.fromString("0000180F-0000-1000-8000-00805f9b34fb") -private val BATTERY_LEVEL_CHARACTERISTIC_UUID = UUID.fromString("00002A19-0000-1000-8000-00805f9b34fb") - -internal class CSCManager( - context: Context, - private val scope: CoroutineScope, - private val logger: NordicLogger -) : BleManager(context) { - - private var batteryLevelCharacteristic: BluetoothGattCharacteristic? = null - private var cscMeasurementCharacteristic: BluetoothGattCharacteristic? = null - private var wheelSize: WheelSize = WheelSize() - - private var previousResponse: CyclingSpeedAndCadenceMeasurementResponse? = null - - private val data = MutableStateFlow(CSCData()) - val dataHolder = ConnectionObserverAdapter() - - init { - connectionObserver = dataHolder - - data.onEach { - dataHolder.setValue(it) - }.launchIn(scope) - } - - override fun log(priority: Int, message: String) { - logger.log(priority, message) - } - - override fun getMinLogPriority(): Int { - return Log.VERBOSE - } - - override fun getGattCallback(): BleManagerGattCallback { - return CSCManagerGattCallback() - } - - fun setWheelSize(value: WheelSize) { - wheelSize = value - } - - private inner class CSCManagerGattCallback : BleManagerGattCallback() { - override fun initialize() { - super.initialize() - - setNotificationCallback(cscMeasurementCharacteristic).asValidResponseFlow() - .onEach { - previousResponse?.let { previousResponse -> - val wheelCircumference = wheelSize.value.toFloat() - val totalDistance = it.getTotalDistance(wheelSize.value.toFloat()) - val distance = it.getDistance(wheelCircumference, previousResponse) - val speed = it.getSpeed(wheelCircumference, previousResponse) - val crankCadence = it.getCrankCadence(previousResponse) - val gearRatio = it.getGearRatio(previousResponse) - - data.tryEmit(data.value.copy( - totalDistance = totalDistance, - distance = distance, - speed = speed, - wheelSize = wheelSize, - cadence = crankCadence, - gearRatio = gearRatio, - )) - } - - previousResponse = it - }.launchIn(scope) - enableNotifications(cscMeasurementCharacteristic).enqueue() - - setNotificationCallback(batteryLevelCharacteristic).asValidResponseFlow().onEach { - data.value = data.value.copy(batteryLevel = it.batteryLevel) - }.launchIn(scope) - enableNotifications(batteryLevelCharacteristic).enqueue() - } - - public override fun isRequiredServiceSupported(gatt: BluetoothGatt): Boolean { - gatt.getService(CSC_SERVICE_UUID)?.run { - cscMeasurementCharacteristic = getCharacteristic(CSC_MEASUREMENT_CHARACTERISTIC_UUID) - } - gatt.getService(BATTERY_SERVICE_UUID)?.run { - batteryLevelCharacteristic = getCharacteristic(BATTERY_LEVEL_CHARACTERISTIC_UUID) - } - return cscMeasurementCharacteristic != null - } - - override fun onServicesInvalidated() { - cscMeasurementCharacteristic = null - batteryLevelCharacteristic = null - } - } -} diff --git a/profile_csc/src/main/java/no/nordicsemi/android/csc/data/CSCServicesData.kt b/profile_csc/src/main/java/no/nordicsemi/android/csc/data/CSCServicesData.kt new file mode 100644 index 00000000..cfc0f48f --- /dev/null +++ b/profile_csc/src/main/java/no/nordicsemi/android/csc/data/CSCServicesData.kt @@ -0,0 +1,10 @@ +package no.nordicsemi.android.csc.data + +import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState +import no.nordicsemi.android.kotlin.ble.profile.csc.CSCData + +data class CSCServicesData( + val data: CSCData = CSCData(), + val batteryLevel: Int? = null, + val connectionState: GattConnectionState = GattConnectionState.STATE_DISCONNECTED +) diff --git a/profile_csc/src/main/java/no/nordicsemi/android/csc/data/WheelSize.kt b/profile_csc/src/main/java/no/nordicsemi/android/csc/data/WheelSize.kt deleted file mode 100644 index bfeb2cfc..00000000 --- a/profile_csc/src/main/java/no/nordicsemi/android/csc/data/WheelSize.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2022, Nordic Semiconductor - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package no.nordicsemi.android.csc.data - -import no.nordicsemi.android.csc.view.CSCSettings - -data class WheelSize( - val value: Int = CSCSettings.DefaultWheelSize.VALUE, - val name: String = CSCSettings.DefaultWheelSize.NAME -) diff --git a/profile_csc/src/main/java/no/nordicsemi/android/csc/repository/CSCRepository.kt b/profile_csc/src/main/java/no/nordicsemi/android/csc/repository/CSCRepository.kt index 3d7bd006..a8a22517 100644 --- a/profile_csc/src/main/java/no/nordicsemi/android/csc/repository/CSCRepository.kt +++ b/profile_csc/src/main/java/no/nordicsemi/android/csc/repository/CSCRepository.kt @@ -33,22 +33,17 @@ package no.nordicsemi.android.csc.repository import android.content.Context import dagger.hilt.android.qualifiers.ApplicationContext -import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.launch -import no.nordicsemi.android.ble.ktx.suspend import no.nordicsemi.android.common.logger.NordicLogger import no.nordicsemi.android.common.logger.NordicLoggerFactory -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice -import no.nordicsemi.android.csc.data.CSCData -import no.nordicsemi.android.csc.data.CSCManager -import no.nordicsemi.android.csc.data.WheelSize -import no.nordicsemi.android.service.BleManagerResult -import no.nordicsemi.android.service.IdleResult +import no.nordicsemi.android.csc.data.CSCServicesData +import no.nordicsemi.android.kotlin.ble.core.ServerDevice +import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState +import no.nordicsemi.android.kotlin.ble.profile.csc.CSCData +import no.nordicsemi.android.kotlin.ble.profile.csc.WheelSize +import no.nordicsemi.android.kotlin.ble.profile.csc.WheelSizes import no.nordicsemi.android.service.ServiceManager import no.nordicsemi.android.ui.view.StringConst import javax.inject.Inject @@ -62,48 +57,36 @@ class CSCRepository @Inject constructor( private val loggerFactory: NordicLoggerFactory, private val stringConst: StringConst ) { - private var manager: CSCManager? = null private var logger: NordicLogger? = null - private val _data = MutableStateFlow>(IdleResult()) + private val _wheelSize = MutableStateFlow(WheelSizes.default) + internal val wheelSize = _wheelSize.asStateFlow() + + private val _data = MutableStateFlow(CSCServicesData()) internal val data = _data.asStateFlow() - val isRunning = data.map { it.isRunning() } - val hasBeenDisconnected = data.map { it.hasBeenDisconnected() } + val isRunning = data.map { it.connectionState == GattConnectionState.STATE_CONNECTED } + val hasBeenDisconnected = + data.map { it.connectionState != GattConnectionState.STATE_CONNECTED && it.connectionState != GattConnectionState.STATE_CONNECTING } - fun launch(device: DiscoveredBluetoothDevice) { + fun launch(device: ServerDevice) { serviceManager.startService(CSCService::class.java, device) } - fun start(device: DiscoveredBluetoothDevice, scope: CoroutineScope) { - val createdLogger = loggerFactory.create(stringConst.APP_NAME, "CSC", device.address).also { - logger = it - } - val manager = CSCManager(context, scope, createdLogger) - this.manager = manager - - manager.dataHolder.status.onEach { - _data.value = it - }.launchIn(scope) - - scope.launch { - manager.start(device) - } - } - fun setWheelSize(wheelSize: WheelSize) { - manager?.setWheelSize(wheelSize) + _wheelSize.value = wheelSize } - private suspend fun CSCManager.start(device: DiscoveredBluetoothDevice) { - try { - connect(device.device) - .useAutoConnect(false) - .retry(3, 100) - .suspend() - } catch (e: Exception) { - e.printStackTrace() - } + fun onConnectionStateChanged(connectionState: GattConnectionState) { + _data.value = _data.value.copy(connectionState = connectionState) + } + + fun onBatteryLevelChanged(batteryLevel: Int) { + _data.value = _data.value.copy(batteryLevel = batteryLevel) + } + + fun onCSCDataChanged(cscData: CSCData) { + _data.value = _data.value.copy(data = cscData) } fun openLogger() { @@ -111,8 +94,7 @@ class CSCRepository @Inject constructor( } fun release() { - manager?.disconnect()?.enqueue() logger = null - manager = null + serviceManager.stopService(CSCService::class.java) } } 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 7b9acf43..52e11ca8 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 @@ -31,16 +31,32 @@ package no.nordicsemi.android.csc.repository +import android.annotation.SuppressLint import android.content.Intent import androidx.lifecycle.lifecycleScope import dagger.hilt.android.AndroidEntryPoint +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 no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice +import kotlinx.coroutines.launch +import no.nordicsemi.android.kotlin.ble.core.ServerDevice +import no.nordicsemi.android.kotlin.ble.core.client.service.BleGattServices +import no.nordicsemi.android.kotlin.ble.profile.battery.BatteryLevelParser +import no.nordicsemi.android.kotlin.ble.profile.csc.CSCDataParser import no.nordicsemi.android.service.DEVICE_DATA import no.nordicsemi.android.service.NotificationService +import java.util.* import javax.inject.Inject +val CSC_SERVICE_UUID: UUID = UUID.fromString("00001816-0000-1000-8000-00805f9b34fb") +private val CSC_MEASUREMENT_CHARACTERISTIC_UUID = UUID.fromString("00002A5B-0000-1000-8000-00805f9b34fb") + +private val BATTERY_SERVICE_UUID = UUID.fromString("0000180F-0000-1000-8000-00805f9b34fb") +private val BATTERY_LEVEL_CHARACTERISTIC_UUID = UUID.fromString("00002A19-0000-1000-8000-00805f9b34fb") + +@SuppressLint("MissingPermission") @AndroidEntryPoint internal class CSCService : NotificationService() { @@ -50,14 +66,44 @@ internal class CSCService : NotificationService() { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { super.onStartCommand(intent, flags, startId) - val device = intent!!.getParcelableExtra(DEVICE_DATA)!! + val device = intent!!.getParcelableExtra(DEVICE_DATA)!! - repository.start(device, lifecycleScope) - - repository.hasBeenDisconnected.onEach { - if (it) stopSelf() - }.launchIn(lifecycleScope) + startGattClient(device) return START_REDELIVER_INTENT } + + private fun startGattClient(blinkyDevice: ServerDevice) = lifecycleScope.launch { + val client = blinkyDevice.connect(this@CSCService) + + client.connection + .onEach { repository.onConnectionStateChanged(it.connectionState) } + .map { it.services } + .filterNotNull() + .onEach { configureGatt(it) } + .launchIn(lifecycleScope) + } + + private suspend fun configureGatt(services: BleGattServices) { + val cscService = services.findService(CSC_SERVICE_UUID)!! + val cscMeasurementCharacteristic = cscService.findCharacteristic(CSC_MEASUREMENT_CHARACTERISTIC_UUID)!! + + cscMeasurementCharacteristic.enableNotifications() + + val cscDataParser = CSCDataParser() + cscMeasurementCharacteristic.notification + .mapNotNull { cscDataParser.parse(it, repository.wheelSize.value) } + .onEach { repository.onCSCDataChanged(it) } + .launchIn(lifecycleScope) + + val batteryService = services.findService(BATTERY_SERVICE_UUID)!! + val batteryLevelCharacteristic = batteryService.findCharacteristic(BATTERY_LEVEL_CHARACTERISTIC_UUID)!! + +// batteryLevelCharacteristic.enableNotifications() + + batteryLevelCharacteristic.notification + .mapNotNull { BatteryLevelParser.parse(it) } + .onEach { repository.onBatteryLevelChanged(it) } + .launchIn(lifecycleScope) + } } diff --git a/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCContentView.kt b/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCContentView.kt index 1bc80f35..e8133ab8 100644 --- a/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCContentView.kt +++ b/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCContentView.kt @@ -34,7 +34,6 @@ package no.nordicsemi.android.csc.view import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Settings import androidx.compose.material3.Button @@ -50,15 +49,16 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import no.nordicsemi.android.common.theme.view.RadioButtonGroup import no.nordicsemi.android.csc.R -import no.nordicsemi.android.csc.data.CSCData -import no.nordicsemi.android.csc.data.WheelSize +import no.nordicsemi.android.csc.data.CSCServicesData +import no.nordicsemi.android.kotlin.ble.profile.csc.CSCData +import no.nordicsemi.android.kotlin.ble.profile.csc.WheelSize import no.nordicsemi.android.ui.view.ScreenSection import no.nordicsemi.android.ui.view.SectionTitle import no.nordicsemi.android.ui.view.dialog.FlowCanceled import no.nordicsemi.android.ui.view.dialog.ItemSelectedResult @Composable -internal fun CSCContentView(state: CSCData, speedUnit: SpeedUnit, onEvent: (CSCViewEvent) -> Unit) { +internal fun CSCContentView(state: CSCServicesData, speedUnit: SpeedUnit, onEvent: (CSCViewEvent) -> Unit) { val showDialog = rememberSaveable { mutableStateOf(false) } if (showDialog.value) { @@ -69,8 +69,7 @@ internal fun CSCContentView(state: CSCData, speedUnit: SpeedUnit, onEvent: (CSCV when (it) { FlowCanceled -> showDialog.value = false is ItemSelectedResult -> { - onEvent(OnWheelSizeSelected(WheelSize(wheelValues[it.index].toInt(), - wheelEntries[it.index]))) + onEvent(OnWheelSizeSelected(WheelSize(wheelValues[it.index].toInt(), wheelEntries[it.index]))) showDialog.value = false } } @@ -80,7 +79,7 @@ internal fun CSCContentView(state: CSCData, speedUnit: SpeedUnit, onEvent: (CSCV Column( horizontalAlignment = Alignment.CenterHorizontally, ) { - SettingsSection(state, speedUnit, onEvent) { showDialog.value = true } + SettingsSection(state.data, speedUnit, onEvent) { showDialog.value = true } Spacer(modifier = Modifier.height(16.dp)) @@ -126,5 +125,5 @@ private fun SettingsSection( @Preview @Composable private fun ConnectedPreview() { - CSCContentView(CSCData(), SpeedUnit.KM_H) { } + CSCContentView(CSCServicesData(), SpeedUnit.KM_H) { } } diff --git a/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCMappers.kt b/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCMappers.kt index 43589f94..0a186798 100644 --- a/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCMappers.kt +++ b/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCMappers.kt @@ -33,7 +33,7 @@ package no.nordicsemi.android.csc.view import no.nordicsemi.android.common.theme.view.RadioButtonItem import no.nordicsemi.android.common.theme.view.RadioGroupViewEntity -import no.nordicsemi.android.csc.data.CSCData +import no.nordicsemi.android.kotlin.ble.profile.csc.CSCData import java.util.* private const val DISPLAY_M_S = "m/s" diff --git a/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCScreen.kt b/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCScreen.kt index e7980385..89443dc4 100644 --- a/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCScreen.kt +++ b/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCScreen.kt @@ -48,15 +48,8 @@ import no.nordicsemi.android.common.ui.scanner.view.DeviceDisconnectedView import no.nordicsemi.android.common.ui.scanner.view.Reason import no.nordicsemi.android.csc.R import no.nordicsemi.android.csc.viewmodel.CSCViewModel -import no.nordicsemi.android.service.ConnectedResult -import no.nordicsemi.android.service.ConnectingResult +import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState import no.nordicsemi.android.service.DeviceHolder -import no.nordicsemi.android.service.DisconnectedResult -import no.nordicsemi.android.service.IdleResult -import no.nordicsemi.android.service.LinkLossResult -import no.nordicsemi.android.service.MissingServiceResult -import no.nordicsemi.android.service.SuccessResult -import no.nordicsemi.android.service.UnknownErrorResult import no.nordicsemi.android.ui.view.BackIconAppBar import no.nordicsemi.android.ui.view.LoggerIconAppBar import no.nordicsemi.android.ui.view.NavigateUpButton @@ -80,20 +73,11 @@ fun CSCScreen() { ) { when (state.cscManagerState) { NoDeviceState -> DeviceConnectingView() - is WorkingState -> when (state.cscManagerState.result) { - is IdleResult, - is ConnectingResult -> DeviceConnectingView { NavigateUpButton(navigateUp) } - is ConnectedResult -> DeviceConnectingView { NavigateUpButton(navigateUp) } - is DisconnectedResult -> DeviceDisconnectedView(Reason.USER) { NavigateUpButton(navigateUp) } - is LinkLossResult -> DeviceDisconnectedView(Reason.LINK_LOSS) { NavigateUpButton(navigateUp) } - is MissingServiceResult -> DeviceDisconnectedView(Reason.MISSING_SERVICE) { - NavigateUpButton(navigateUp) - } - is UnknownErrorResult -> DeviceDisconnectedView(Reason.UNKNOWN) { NavigateUpButton(navigateUp) } - is SuccessResult -> CSCContentView( - state.cscManagerState.result.data, - state.speedUnit - ) { viewModel.onEvent(it) } + is WorkingState -> when (state.cscManagerState.result.connectionState) { + GattConnectionState.STATE_CONNECTING -> DeviceConnectingView { NavigateUpButton(navigateUp) } + GattConnectionState.STATE_DISCONNECTED, + GattConnectionState.STATE_DISCONNECTING -> DeviceDisconnectedView(Reason.UNKNOWN) { NavigateUpButton(navigateUp) } + GattConnectionState.STATE_CONNECTED -> CSCContentView(state.cscManagerState.result, state.speedUnit) { viewModel.onEvent(it) } } } } diff --git a/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCSettings.kt b/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCSettings.kt deleted file mode 100644 index 9b9a362c..00000000 --- a/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCSettings.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2022, Nordic Semiconductor - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package no.nordicsemi.android.csc.view - -internal object CSCSettings { - - object DefaultWheelSize { - const val NAME = "60-622" - const val VALUE = 2340 - } -} \ No newline at end of file diff --git a/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCState.kt b/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCState.kt index d6f2de13..dc2840aa 100644 --- a/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCState.kt +++ b/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCState.kt @@ -31,8 +31,7 @@ package no.nordicsemi.android.csc.view -import no.nordicsemi.android.csc.data.CSCData -import no.nordicsemi.android.service.BleManagerResult +import no.nordicsemi.android.csc.data.CSCServicesData internal data class CSCViewState( val speedUnit: SpeedUnit = SpeedUnit.M_S, @@ -41,6 +40,6 @@ internal data class CSCViewState( internal sealed class CSCMangerState -internal data class WorkingState(val result: BleManagerResult) : CSCMangerState() +internal data class WorkingState(val result: CSCServicesData) : CSCMangerState() internal object NoDeviceState : CSCMangerState() diff --git a/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCViewEvent.kt b/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCViewEvent.kt index 6cc033b7..b0ba0c84 100644 --- a/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCViewEvent.kt +++ b/profile_csc/src/main/java/no/nordicsemi/android/csc/view/CSCViewEvent.kt @@ -31,7 +31,7 @@ package no.nordicsemi.android.csc.view -import no.nordicsemi.android.csc.data.WheelSize +import no.nordicsemi.android.kotlin.ble.profile.csc.WheelSize internal sealed class CSCViewEvent diff --git a/profile_csc/src/main/java/no/nordicsemi/android/csc/view/SensorsReadingView.kt b/profile_csc/src/main/java/no/nordicsemi/android/csc/view/SensorsReadingView.kt index 123af1c8..cfa0c373 100644 --- a/profile_csc/src/main/java/no/nordicsemi/android/csc/view/SensorsReadingView.kt +++ b/profile_csc/src/main/java/no/nordicsemi/android/csc/view/SensorsReadingView.kt @@ -40,32 +40,33 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import no.nordicsemi.android.csc.R -import no.nordicsemi.android.csc.data.CSCData +import no.nordicsemi.android.csc.data.CSCServicesData import no.nordicsemi.android.ui.view.BatteryLevelView import no.nordicsemi.android.ui.view.KeyValueField import no.nordicsemi.android.ui.view.ScreenSection import no.nordicsemi.android.ui.view.SectionTitle @Composable -internal fun SensorsReadingView(state: CSCData, speedUnit: SpeedUnit) { +internal fun SensorsReadingView(state: CSCServicesData, speedUnit: SpeedUnit) { + val csc = state.data ScreenSection { SectionTitle(resId = R.drawable.ic_records, title = "Records") Spacer(modifier = Modifier.height(16.dp)) Column { - KeyValueField(stringResource(id = R.string.csc_field_speed), state.displaySpeed(speedUnit)) + KeyValueField(stringResource(id = R.string.csc_field_speed), csc.displaySpeed(speedUnit)) Spacer(modifier = Modifier.height(4.dp)) - KeyValueField(stringResource(id = R.string.csc_field_cadence), state.displayCadence()) + KeyValueField(stringResource(id = R.string.csc_field_cadence), csc.displayCadence()) Spacer(modifier = Modifier.height(4.dp)) - KeyValueField(stringResource(id = R.string.csc_field_distance), state.displayDistance(speedUnit)) + KeyValueField(stringResource(id = R.string.csc_field_distance), csc.displayDistance(speedUnit)) Spacer(modifier = Modifier.height(4.dp)) KeyValueField( stringResource(id = R.string.csc_field_total_distance), - state.displayTotalDistance(speedUnit) + csc.displayTotalDistance(speedUnit) ) Spacer(modifier = Modifier.height(4.dp)) - KeyValueField(stringResource(id = R.string.csc_field_gear_ratio), state.displayGearRatio()) + KeyValueField(stringResource(id = R.string.csc_field_gear_ratio), csc.displayGearRatio()) } } @@ -79,5 +80,5 @@ internal fun SensorsReadingView(state: CSCData, speedUnit: SpeedUnit) { @Preview @Composable private fun Preview() { - SensorsReadingView(CSCData(), SpeedUnit.KM_H) + SensorsReadingView(CSCServicesData(), SpeedUnit.KM_H) } diff --git a/profile_csc/src/main/java/no/nordicsemi/android/csc/view/WheelSizeView.kt b/profile_csc/src/main/java/no/nordicsemi/android/csc/view/WheelSizeView.kt index dd94c9a3..98393d66 100644 --- a/profile_csc/src/main/java/no/nordicsemi/android/csc/view/WheelSizeView.kt +++ b/profile_csc/src/main/java/no/nordicsemi/android/csc/view/WheelSizeView.kt @@ -47,7 +47,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import no.nordicsemi.android.csc.R -import no.nordicsemi.android.csc.data.CSCData +import no.nordicsemi.android.kotlin.ble.profile.csc.CSCData @Composable internal fun WheelSizeView(state: CSCData, onClick: () -> Unit) { diff --git a/profile_csc/src/main/java/no/nordicsemi/android/csc/viewmodel/CSCViewModel.kt b/profile_csc/src/main/java/no/nordicsemi/android/csc/viewmodel/CSCViewModel.kt index 8f5d333b..58f2afa9 100644 --- a/profile_csc/src/main/java/no/nordicsemi/android/csc/viewmodel/CSCViewModel.kt +++ b/profile_csc/src/main/java/no/nordicsemi/android/csc/viewmodel/CSCViewModel.kt @@ -46,9 +46,8 @@ import no.nordicsemi.android.analytics.Profile import no.nordicsemi.android.analytics.ProfileConnectedEvent import no.nordicsemi.android.common.navigation.NavigationResult import no.nordicsemi.android.common.navigation.Navigator -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice -import no.nordicsemi.android.csc.data.CSC_SERVICE_UUID import no.nordicsemi.android.csc.repository.CSCRepository +import no.nordicsemi.android.csc.repository.CSC_SERVICE_UUID import no.nordicsemi.android.csc.view.CSCViewEvent import no.nordicsemi.android.csc.view.CSCViewState import no.nordicsemi.android.csc.view.NavigateUp @@ -58,6 +57,8 @@ import no.nordicsemi.android.csc.view.OnWheelSizeSelected import no.nordicsemi.android.csc.view.OpenLogger import no.nordicsemi.android.csc.view.SpeedUnit import no.nordicsemi.android.csc.view.WorkingState +import no.nordicsemi.android.kotlin.ble.core.ServerDevice +import no.nordicsemi.android.kotlin.ble.core.data.GattConnectionState import no.nordicsemi.android.service.ConnectedResult import no.nordicsemi.android.toolbox.scanner.ScannerDestinationId import javax.inject.Inject @@ -82,7 +83,7 @@ internal class CSCViewModel @Inject constructor( repository.data.onEach { _state.value = _state.value.copy(cscManagerState = WorkingState(it)) - (it as? ConnectedResult)?.let { + if (it.connectionState == GattConnectionState.STATE_CONNECTED) { analytics.logEvent(ProfileConnectedEvent(Profile.CSC)) } }.launchIn(viewModelScope) @@ -96,7 +97,7 @@ internal class CSCViewModel @Inject constructor( .launchIn(viewModelScope) } - private fun handleResult(result: NavigationResult) { + private fun handleResult(result: NavigationResult) { when (result) { is NavigationResult.Cancelled -> navigationManager.navigateUp() is NavigationResult.Success -> repository.launch(result.value) diff --git a/profile_gls/build.gradle.kts b/profile_gls/build.gradle.kts index 5a2d4e70..ed4598d9 100644 --- a/profile_gls/build.gradle.kts +++ b/profile_gls/build.gradle.kts @@ -45,6 +45,9 @@ dependencies { implementation(project(":lib_ui")) implementation(project(":lib_utils")) + implementation("no.nordicsemi.android.kotlin.ble:core:0.0.1") + implementation("no.nordicsemi.android.kotlin.ble:profile:0.0.1") + implementation(libs.chart) implementation(libs.nordic.ble.common) 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 a789d575..7513f8c9 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,7 +32,6 @@ package no.nordicsemi.android.gls.main.viewmodel import android.os.ParcelUuid -import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel @@ -45,7 +44,6 @@ import no.nordicsemi.android.analytics.Profile import no.nordicsemi.android.analytics.ProfileConnectedEvent import no.nordicsemi.android.common.navigation.NavigationResult import no.nordicsemi.android.common.navigation.Navigator -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice import no.nordicsemi.android.gls.GlsDetailsDestinationId import no.nordicsemi.android.gls.data.GLS_SERVICE_UUID import no.nordicsemi.android.gls.main.view.DisconnectEvent @@ -57,6 +55,7 @@ import no.nordicsemi.android.gls.main.view.OnWorkingModeSelected import no.nordicsemi.android.gls.main.view.OpenLoggerEvent import no.nordicsemi.android.gls.main.view.WorkingState import no.nordicsemi.android.gls.repository.GLSRepository +import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.service.ConnectedResult import no.nordicsemi.android.toolbox.scanner.ScannerDestinationId import javax.inject.Inject @@ -79,7 +78,7 @@ internal class GLSViewModel @Inject constructor( .launchIn(viewModelScope) } - private fun handleResult(result: NavigationResult) { + private fun handleResult(result: NavigationResult) { when (result) { is NavigationResult.Cancelled -> navigationManager.navigateUp() is NavigationResult.Success -> connectDevice(result.value) @@ -96,7 +95,7 @@ internal class GLSViewModel @Inject constructor( } } - private fun connectDevice(device: DiscoveredBluetoothDevice) { + private fun connectDevice(device: ServerDevice) { repository.downloadData(viewModelScope, device).onEach { _state.value = WorkingState(it) diff --git a/profile_gls/src/main/java/no/nordicsemi/android/gls/repository/GLSRepository.kt b/profile_gls/src/main/java/no/nordicsemi/android/gls/repository/GLSRepository.kt index cbf5c576..86050cca 100644 --- a/profile_gls/src/main/java/no/nordicsemi/android/gls/repository/GLSRepository.kt +++ b/profile_gls/src/main/java/no/nordicsemi/android/gls/repository/GLSRepository.kt @@ -44,10 +44,10 @@ import kotlinx.coroutines.launch import no.nordicsemi.android.ble.ktx.suspend import no.nordicsemi.android.common.logger.NordicLogger import no.nordicsemi.android.common.logger.NordicLoggerFactory -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice import no.nordicsemi.android.gls.data.GLSData import no.nordicsemi.android.gls.data.GLSManager import no.nordicsemi.android.gls.data.WorkingMode +import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.service.BleManagerResult import no.nordicsemi.android.ui.view.StringConst import javax.inject.Inject @@ -63,7 +63,7 @@ internal class GLSRepository @Inject constructor( private var manager: GLSManager? = null private var logger: NordicLogger? = null - fun downloadData(scope: CoroutineScope, device: DiscoveredBluetoothDevice): Flow> = callbackFlow { + fun downloadData(scope: CoroutineScope, device: ServerDevice): Flow> = callbackFlow { val createdLogger = loggerFactory.create(stringConst.APP_NAME, "GLS", device.address).also { logger = it } @@ -87,15 +87,15 @@ internal class GLSRepository @Inject constructor( } } - private suspend fun GLSManager.start(device: DiscoveredBluetoothDevice) { - try { - connect(device.device) - .useAutoConnect(false) - .retry(3, 100) - .suspend() - } catch (e: Exception) { - e.printStackTrace() - } + private suspend fun GLSManager.start(device: ServerDevice) { +// try { +// connect(device.device) +// .useAutoConnect(false) +// .retry(3, 100) +// .suspend() +// } catch (e: Exception) { +// e.printStackTrace() +// } } fun openLogger() { diff --git a/profile_hrs/build.gradle.kts b/profile_hrs/build.gradle.kts index 5ebcb6f0..ea8177d8 100644 --- a/profile_hrs/build.gradle.kts +++ b/profile_hrs/build.gradle.kts @@ -45,6 +45,9 @@ dependencies { implementation(project(":lib_ui")) implementation(project(":lib_utils")) + implementation("no.nordicsemi.android.kotlin.ble:core:0.0.1") + implementation("no.nordicsemi.android.kotlin.ble:profile:0.0.1") + implementation(libs.chart) implementation(libs.nordic.theme) diff --git a/profile_hrs/src/main/java/no/nordicsemi/android/hrs/service/HRSRepository.kt b/profile_hrs/src/main/java/no/nordicsemi/android/hrs/service/HRSRepository.kt index b12efe66..85d0928f 100644 --- a/profile_hrs/src/main/java/no/nordicsemi/android/hrs/service/HRSRepository.kt +++ b/profile_hrs/src/main/java/no/nordicsemi/android/hrs/service/HRSRepository.kt @@ -40,12 +40,11 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch -import no.nordicsemi.android.ble.ktx.suspend import no.nordicsemi.android.common.logger.NordicLogger import no.nordicsemi.android.common.logger.NordicLoggerFactory -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice import no.nordicsemi.android.hrs.data.HRSData import no.nordicsemi.android.hrs.data.HRSManager +import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.service.BleManagerResult import no.nordicsemi.android.service.IdleResult import no.nordicsemi.android.service.ServiceManager @@ -70,11 +69,11 @@ class HRSRepository @Inject constructor( val isRunning = data.map { it.isRunning() } val hasBeenDisconnected = data.map { it.hasBeenDisconnected() } - fun launch(device: DiscoveredBluetoothDevice) { + fun launch(device: ServerDevice) { serviceManager.startService(HRSService::class.java, device) } - fun start(device: DiscoveredBluetoothDevice, scope: CoroutineScope) { + fun start(device: ServerDevice, scope: CoroutineScope) { val createdLogger = loggerFactory.create(stringConst.APP_NAME, "HRS", device.address).also { logger = it } @@ -94,15 +93,15 @@ class HRSRepository @Inject constructor( NordicLogger.launch(context, logger) } - private suspend fun HRSManager.start(device: DiscoveredBluetoothDevice) { - try { - connect(device.device) - .useAutoConnect(false) - .retry(3, 100) - .suspend() - } catch (e: Exception) { - e.printStackTrace() - } + private suspend fun HRSManager.start(device: ServerDevice) { +// try { +// connect(device.device) +// .useAutoConnect(false) +// .retry(3, 100) +// .suspend() +// } catch (e: Exception) { +// e.printStackTrace() +// } } fun release() { 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 fce7e486..a3d7675d 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 @@ -36,7 +36,7 @@ import androidx.lifecycle.lifecycleScope import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice +import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.service.DEVICE_DATA import no.nordicsemi.android.service.NotificationService import javax.inject.Inject @@ -50,7 +50,7 @@ internal class HRSService : NotificationService() { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { super.onStartCommand(intent, flags, startId) - val device = intent!!.getParcelableExtra(DEVICE_DATA)!! + val device = intent!!.getParcelableExtra(DEVICE_DATA)!! repository.start(device, lifecycleScope) diff --git a/profile_hrs/src/main/java/no/nordicsemi/android/hrs/view/HRSContentView.kt b/profile_hrs/src/main/java/no/nordicsemi/android/hrs/view/HRSContentView.kt index 4cd10842..d7e96190 100644 --- a/profile_hrs/src/main/java/no/nordicsemi/android/hrs/view/HRSContentView.kt +++ b/profile_hrs/src/main/java/no/nordicsemi/android/hrs/view/HRSContentView.kt @@ -34,7 +34,6 @@ package no.nordicsemi.android.hrs.view import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding import androidx.compose.material3.Button import androidx.compose.material3.Icon import androidx.compose.material3.IconButton diff --git a/profile_hrs/src/main/java/no/nordicsemi/android/hrs/viewmodel/HRSViewModel.kt b/profile_hrs/src/main/java/no/nordicsemi/android/hrs/viewmodel/HRSViewModel.kt index 5f276cd6..0ebe4367 100644 --- a/profile_hrs/src/main/java/no/nordicsemi/android/hrs/viewmodel/HRSViewModel.kt +++ b/profile_hrs/src/main/java/no/nordicsemi/android/hrs/viewmodel/HRSViewModel.kt @@ -46,7 +46,6 @@ import no.nordicsemi.android.analytics.Profile import no.nordicsemi.android.analytics.ProfileConnectedEvent import no.nordicsemi.android.common.navigation.NavigationResult import no.nordicsemi.android.common.navigation.Navigator -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice import no.nordicsemi.android.hrs.data.HRS_SERVICE_UUID import no.nordicsemi.android.hrs.service.HRSRepository import no.nordicsemi.android.hrs.view.DisconnectEvent @@ -57,6 +56,7 @@ import no.nordicsemi.android.hrs.view.NoDeviceState import no.nordicsemi.android.hrs.view.OpenLoggerEvent import no.nordicsemi.android.hrs.view.SwitchZoomEvent import no.nordicsemi.android.hrs.view.WorkingState +import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.service.ConnectedResult import no.nordicsemi.android.toolbox.scanner.ScannerDestinationId import javax.inject.Inject @@ -96,7 +96,7 @@ internal class HRSViewModel @Inject constructor( .launchIn(viewModelScope) } - private fun handleResult(result: NavigationResult) { + private fun handleResult(result: NavigationResult) { when (result) { is NavigationResult.Cancelled -> navigationManager.navigateUp() is NavigationResult.Success -> repository.launch(result.value) diff --git a/profile_hts/build.gradle.kts b/profile_hts/build.gradle.kts index 7bafc1e2..7b8423eb 100644 --- a/profile_hts/build.gradle.kts +++ b/profile_hts/build.gradle.kts @@ -45,6 +45,9 @@ dependencies { implementation(project(":lib_ui")) implementation(project(":lib_utils")) + implementation("no.nordicsemi.android.kotlin.ble:core:0.0.1") + implementation("no.nordicsemi.android.kotlin.ble:profile:0.0.1") + implementation(libs.nordic.ble.common) implementation(libs.nordic.ble.ktx) diff --git a/profile_hts/src/main/java/no/nordicsemi/android/hts/repository/HTSRepository.kt b/profile_hts/src/main/java/no/nordicsemi/android/hts/repository/HTSRepository.kt index 16e1f9f3..a6b88dd3 100644 --- a/profile_hts/src/main/java/no/nordicsemi/android/hts/repository/HTSRepository.kt +++ b/profile_hts/src/main/java/no/nordicsemi/android/hts/repository/HTSRepository.kt @@ -40,12 +40,11 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch -import no.nordicsemi.android.ble.ktx.suspend import no.nordicsemi.android.common.logger.NordicLogger import no.nordicsemi.android.common.logger.NordicLoggerFactory -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice import no.nordicsemi.android.hts.data.HTSData import no.nordicsemi.android.hts.data.HTSManager +import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.service.BleManagerResult import no.nordicsemi.android.service.IdleResult import no.nordicsemi.android.service.ServiceManager @@ -70,11 +69,11 @@ class HTSRepository @Inject constructor( val isRunning = data.map { it.isRunning() } val hasBeenDisconnected = data.map { it.hasBeenDisconnected() } - fun launch(device: DiscoveredBluetoothDevice) { + fun launch(device: ServerDevice) { serviceManager.startService(HTSService::class.java, device) } - fun start(device: DiscoveredBluetoothDevice, scope: CoroutineScope) { + fun start(device: ServerDevice, scope: CoroutineScope) { val createdLogger = loggerFactory.create(stringConst.APP_NAME, "HTS", device.address).also { logger = it } @@ -94,15 +93,15 @@ class HTSRepository @Inject constructor( NordicLogger.launch(context, logger) } - private suspend fun HTSManager.start(device: DiscoveredBluetoothDevice) { - try { - connect(device.device) - .useAutoConnect(false) - .retry(3, 100) - .suspend() - } catch (e: Exception) { - e.printStackTrace() - } + private suspend fun HTSManager.start(device: ServerDevice) { +// try { +// connect(device.device) +// .useAutoConnect(false) +// .retry(3, 100) +// .suspend() +// } catch (e: Exception) { +// e.printStackTrace() +// } } fun release() { 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 50bb962e..05ff5dbb 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 @@ -36,7 +36,7 @@ import androidx.lifecycle.lifecycleScope import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice +import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.service.DEVICE_DATA import no.nordicsemi.android.service.NotificationService import javax.inject.Inject @@ -50,7 +50,7 @@ internal class HTSService : NotificationService() { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { super.onStartCommand(intent, flags, startId) - val device = intent!!.getParcelableExtra(DEVICE_DATA)!! + val device = intent!!.getParcelableExtra(DEVICE_DATA)!! repository.start(device, lifecycleScope) diff --git a/profile_hts/src/main/java/no/nordicsemi/android/hts/view/HTSContentView.kt b/profile_hts/src/main/java/no/nordicsemi/android/hts/view/HTSContentView.kt index 8858ab9d..4c2242b6 100644 --- a/profile_hts/src/main/java/no/nordicsemi/android/hts/view/HTSContentView.kt +++ b/profile_hts/src/main/java/no/nordicsemi/android/hts/view/HTSContentView.kt @@ -35,7 +35,6 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.runtime.Composable diff --git a/profile_hts/src/main/java/no/nordicsemi/android/hts/viewmodel/HTSViewModel.kt b/profile_hts/src/main/java/no/nordicsemi/android/hts/viewmodel/HTSViewModel.kt index 1ffb4bd4..d11c8f85 100644 --- a/profile_hts/src/main/java/no/nordicsemi/android/hts/viewmodel/HTSViewModel.kt +++ b/profile_hts/src/main/java/no/nordicsemi/android/hts/viewmodel/HTSViewModel.kt @@ -46,7 +46,6 @@ import no.nordicsemi.android.analytics.Profile import no.nordicsemi.android.analytics.ProfileConnectedEvent import no.nordicsemi.android.common.navigation.NavigationResult import no.nordicsemi.android.common.navigation.Navigator -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice import no.nordicsemi.android.hts.data.HTS_SERVICE_UUID import no.nordicsemi.android.hts.repository.HTSRepository import no.nordicsemi.android.hts.view.DisconnectEvent @@ -56,6 +55,7 @@ import no.nordicsemi.android.hts.view.NavigateUp import no.nordicsemi.android.hts.view.OnTemperatureUnitSelected import no.nordicsemi.android.hts.view.OpenLoggerEvent import no.nordicsemi.android.hts.view.WorkingState +import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.service.ConnectedResult import no.nordicsemi.android.toolbox.scanner.ScannerDestinationId import javax.inject.Inject @@ -94,7 +94,7 @@ internal class HTSViewModel @Inject constructor( .launchIn(viewModelScope) } - private fun handleResult(result: NavigationResult) { + private fun handleResult(result: NavigationResult) { when (result) { is NavigationResult.Cancelled -> navigationManager.navigateUp() is NavigationResult.Success -> repository.launch(result.value) diff --git a/profile_prx/build.gradle.kts b/profile_prx/build.gradle.kts index f8585a6f..ade0bcee 100644 --- a/profile_prx/build.gradle.kts +++ b/profile_prx/build.gradle.kts @@ -45,6 +45,9 @@ dependencies { implementation(project(":lib_ui")) implementation(project(":lib_utils")) + implementation("no.nordicsemi.android.kotlin.ble:core:0.0.1") + implementation("no.nordicsemi.android.kotlin.ble:profile:0.0.1") + implementation(libs.nordic.ble.common) implementation(libs.nordic.ble.ktx) 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 9a9c42b6..20b4c13e 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 @@ -41,7 +41,7 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import no.nordicsemi.android.common.logger.NordicLogger import no.nordicsemi.android.common.logger.NordicLoggerFactory -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice +import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.prx.data.AlarmLevel import no.nordicsemi.android.prx.data.PRXData import no.nordicsemi.android.prx.data.PRXManager @@ -75,12 +75,12 @@ class PRXRepository @Inject internal constructor( val isRunning = data.map { it.isRunning() } val hasBeenDisconnectedWithoutLinkLoss = data.map { it.hasBeenDisconnectedWithoutLinkLoss() } - fun launch(device: DiscoveredBluetoothDevice) { + fun launch(device: ServerDevice) { serviceManager.startService(PRXService::class.java, device) proximityServerManager.open() } - fun start(device: DiscoveredBluetoothDevice, scope: CoroutineScope) { + fun start(device: ServerDevice, scope: CoroutineScope) { val createdLogger = loggerFactory.create(stringConst.APP_NAME, "PRX", device.address).also { logger = it } @@ -93,10 +93,10 @@ class PRXRepository @Inject internal constructor( handleLocalAlarm(it) }.launchIn(scope) - manager.connect(device.device) - .useAutoConnect(true) - .retry(3, 100) - .enqueue() +// manager.connect(device.device) +// .useAutoConnect(true) +// .retry(3, 100) +// .enqueue() } private fun handleLocalAlarm(result: BleManagerResult) { 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 1b19f49e..9925bf4b 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 @@ -36,7 +36,7 @@ import androidx.lifecycle.lifecycleScope import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice +import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.service.DEVICE_DATA import no.nordicsemi.android.service.NotificationService import javax.inject.Inject @@ -50,7 +50,7 @@ internal class PRXService : NotificationService() { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { super.onStartCommand(intent, flags, startId) - val device = intent!!.getParcelableExtra(DEVICE_DATA)!! + val device = intent!!.getParcelableExtra(DEVICE_DATA)!! repository.start(device, lifecycleScope) diff --git a/profile_prx/src/main/java/no/nordicsemi/android/prx/view/PRXContentView.kt b/profile_prx/src/main/java/no/nordicsemi/android/prx/view/PRXContentView.kt index d7da2a3b..e47fa8b1 100644 --- a/profile_prx/src/main/java/no/nordicsemi/android/prx/view/PRXContentView.kt +++ b/profile_prx/src/main/java/no/nordicsemi/android/prx/view/PRXContentView.kt @@ -34,7 +34,6 @@ package no.nordicsemi.android.prx.view import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Settings import androidx.compose.material3.Button diff --git a/profile_prx/src/main/java/no/nordicsemi/android/prx/view/PRXScreen.kt b/profile_prx/src/main/java/no/nordicsemi/android/prx/view/PRXScreen.kt index 933db8a7..b20d2f3c 100644 --- a/profile_prx/src/main/java/no/nordicsemi/android/prx/view/PRXScreen.kt +++ b/profile_prx/src/main/java/no/nordicsemi/android/prx/view/PRXScreen.kt @@ -39,7 +39,6 @@ import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp 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 2143bfee..6acfe572 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 @@ -46,7 +46,7 @@ import no.nordicsemi.android.analytics.Profile import no.nordicsemi.android.analytics.ProfileConnectedEvent import no.nordicsemi.android.common.navigation.NavigationResult import no.nordicsemi.android.common.navigation.Navigator -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice +import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.prx.data.PRX_SERVICE_UUID import no.nordicsemi.android.prx.repository.PRXRepository import no.nordicsemi.android.prx.view.DisconnectEvent @@ -96,7 +96,7 @@ internal class PRXViewModel @Inject constructor( .launchIn(viewModelScope) } - private fun handleResult(result: NavigationResult) { + private fun handleResult(result: NavigationResult) { when (result) { is NavigationResult.Cancelled -> navigationManager.navigateUp() is NavigationResult.Success -> repository.launch(result.value) diff --git a/profile_rscs/build.gradle.kts b/profile_rscs/build.gradle.kts index 92d50647..360d8826 100644 --- a/profile_rscs/build.gradle.kts +++ b/profile_rscs/build.gradle.kts @@ -45,6 +45,9 @@ dependencies { implementation(project(":lib_ui")) implementation(project(":lib_utils")) + implementation("no.nordicsemi.android.kotlin.ble:core:0.0.1") + implementation("no.nordicsemi.android.kotlin.ble:profile:0.0.1") + implementation(libs.nordic.ble.common) implementation(libs.nordic.ble.ktx) diff --git a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/repository/RSCSRepository.kt b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/repository/RSCSRepository.kt index fe7af444..1e270afb 100644 --- a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/repository/RSCSRepository.kt +++ b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/repository/RSCSRepository.kt @@ -40,10 +40,9 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch -import no.nordicsemi.android.ble.ktx.suspend import no.nordicsemi.android.common.logger.NordicLogger import no.nordicsemi.android.common.logger.NordicLoggerFactory -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice +import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.rscs.data.RSCSData import no.nordicsemi.android.rscs.data.RSCSManager import no.nordicsemi.android.service.BleManagerResult @@ -70,11 +69,11 @@ class RSCSRepository @Inject constructor( val isRunning = data.map { it.isRunning() } val hasBeenDisconnected = data.map { it.hasBeenDisconnected() } - fun launch(device: DiscoveredBluetoothDevice) { + fun launch(device: ServerDevice) { serviceManager.startService(RSCSService::class.java, device) } - fun start(device: DiscoveredBluetoothDevice, scope: CoroutineScope) { + fun start(device: ServerDevice, scope: CoroutineScope) { val createdLogger = loggerFactory.create(stringConst.APP_NAME, "RSCS", device.address).also { logger = it } @@ -94,15 +93,15 @@ class RSCSRepository @Inject constructor( NordicLogger.launch(context, logger) } - private suspend fun RSCSManager.start(device: DiscoveredBluetoothDevice) { - try { - connect(device.device) - .useAutoConnect(false) - .retry(3, 100) - .suspend() - } catch (e: Exception) { - e.printStackTrace() - } + private suspend fun RSCSManager.start(device: ServerDevice) { +// try { +// connect(device.device) +// .useAutoConnect(false) +// .retry(3, 100) +// .suspend() +// } catch (e: Exception) { +// e.printStackTrace() +// } } fun release() { 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 4359dab3..acdb6120 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 @@ -36,7 +36,7 @@ import androidx.lifecycle.lifecycleScope import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice +import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.service.DEVICE_DATA import no.nordicsemi.android.service.NotificationService import javax.inject.Inject @@ -50,7 +50,7 @@ internal class RSCSService : NotificationService() { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { super.onStartCommand(intent, flags, startId) - val device = intent!!.getParcelableExtra(DEVICE_DATA)!! + val device = intent!!.getParcelableExtra(DEVICE_DATA)!! repository.start(device, lifecycleScope) diff --git a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/view/SensorsReadingView.kt b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/view/SensorsReadingView.kt index 1c89e3f9..241c1c1e 100644 --- a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/view/SensorsReadingView.kt +++ b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/view/SensorsReadingView.kt @@ -33,7 +33,6 @@ package no.nordicsemi.android.rscs.view import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.height -import androidx.compose.material3.OutlinedCard import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource diff --git a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/viewmodel/RSCSViewModel.kt b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/viewmodel/RSCSViewModel.kt index 2dbbe12a..78360059 100644 --- a/profile_rscs/src/main/java/no/nordicsemi/android/rscs/viewmodel/RSCSViewModel.kt +++ b/profile_rscs/src/main/java/no/nordicsemi/android/rscs/viewmodel/RSCSViewModel.kt @@ -46,7 +46,7 @@ import no.nordicsemi.android.analytics.Profile import no.nordicsemi.android.analytics.ProfileConnectedEvent import no.nordicsemi.android.common.navigation.NavigationResult import no.nordicsemi.android.common.navigation.Navigator -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice +import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.rscs.data.RSCS_SERVICE_UUID import no.nordicsemi.android.rscs.repository.RSCSRepository import no.nordicsemi.android.rscs.view.DisconnectEvent @@ -94,7 +94,7 @@ internal class RSCSViewModel @Inject constructor( .launchIn(viewModelScope) } - private fun handleResult(result: NavigationResult) { + private fun handleResult(result: NavigationResult) { when (result) { is NavigationResult.Cancelled -> navigationManager.navigateUp() is NavigationResult.Success -> repository.launch(result.value) diff --git a/profile_uart/build.gradle.kts b/profile_uart/build.gradle.kts index eda73918..8890e92e 100644 --- a/profile_uart/build.gradle.kts +++ b/profile_uart/build.gradle.kts @@ -51,6 +51,9 @@ dependencies { implementation(project(":lib_ui")) implementation(project(":lib_utils")) + implementation("no.nordicsemi.android.kotlin.ble:core:0.0.1") + implementation("no.nordicsemi.android.kotlin.ble:profile:0.0.1") + implementation(libs.room.runtime) implementation(libs.room.ktx) kapt(libs.room.compiler) diff --git a/profile_uart/src/main/java/no/nordicsemi/android/uart/db/XmlMacro.java b/profile_uart/src/main/java/no/nordicsemi/android/uart/db/XmlMacro.java index 202097bd..726b9b34 100644 --- a/profile_uart/src/main/java/no/nordicsemi/android/uart/db/XmlMacro.java +++ b/profile_uart/src/main/java/no/nordicsemi/android/uart/db/XmlMacro.java @@ -35,9 +35,8 @@ import org.simpleframework.xml.Attribute; import org.simpleframework.xml.Root; import org.simpleframework.xml.Text; -//import no.nordicsemi.android.uart.data.MacroEol; -//import no.nordicsemi.android.uart.data.MacroIcon; -import no.nordicsemi.android.uart.data.*; +import no.nordicsemi.android.uart.data.MacroEol; +import no.nordicsemi.android.uart.data.MacroIcon; @Root public class XmlMacro { diff --git a/profile_uart/src/main/java/no/nordicsemi/android/uart/repository/UARTRepository.kt b/profile_uart/src/main/java/no/nordicsemi/android/uart/repository/UARTRepository.kt index a01b1bcf..47deff88 100644 --- a/profile_uart/src/main/java/no/nordicsemi/android/uart/repository/UARTRepository.kt +++ b/profile_uart/src/main/java/no/nordicsemi/android/uart/repository/UARTRepository.kt @@ -40,10 +40,9 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch -import no.nordicsemi.android.ble.ktx.suspend import no.nordicsemi.android.common.logger.NordicLogger import no.nordicsemi.android.common.logger.NordicLoggerFactory -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice +import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.service.BleManagerResult import no.nordicsemi.android.service.IdleResult import no.nordicsemi.android.service.ServiceManager @@ -78,11 +77,11 @@ class UARTRepository @Inject internal constructor( val lastConfigurationName = configurationDataSource.lastConfigurationName - fun launch(device: DiscoveredBluetoothDevice) { + fun launch(device: ServerDevice) { serviceManager.startService(UARTService::class.java, device) } - fun start(device: DiscoveredBluetoothDevice, scope: CoroutineScope) { + fun start(device: ServerDevice, scope: CoroutineScope) { val createdLogger = loggerFactory.create(stringConst.APP_NAME, "UART", device.address).also { logger = it } @@ -119,15 +118,15 @@ class UARTRepository @Inject internal constructor( configurationDataSource.saveConfigurationName(name) } - private suspend fun UARTManager.start(device: DiscoveredBluetoothDevice) { - try { - connect(device.device) - .useAutoConnect(false) - .retry(3, 100) - .suspend() - } catch (e: Exception) { - e.printStackTrace() - } + private suspend fun UARTManager.start(device: ServerDevice) { +// try { +// connect(device.device) +// .useAutoConnect(false) +// .retry(3, 100) +// .suspend() +// } catch (e: Exception) { +// e.printStackTrace() +// } } fun release() { 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 da4e4283..611fa329 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 @@ -36,7 +36,7 @@ import androidx.lifecycle.lifecycleScope import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice +import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.service.DEVICE_DATA import no.nordicsemi.android.service.NotificationService import javax.inject.Inject @@ -50,7 +50,7 @@ internal class UARTService : NotificationService() { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { super.onStartCommand(intent, flags, startId) - val device = intent!!.getParcelableExtra(DEVICE_DATA)!! + val device = intent!!.getParcelableExtra(DEVICE_DATA)!! repository.start(device, lifecycleScope) diff --git a/profile_uart/src/main/java/no/nordicsemi/android/uart/viewmodel/UARTViewModel.kt b/profile_uart/src/main/java/no/nordicsemi/android/uart/viewmodel/UARTViewModel.kt index 7d736e37..9e3a0409 100644 --- a/profile_uart/src/main/java/no/nordicsemi/android/uart/viewmodel/UARTViewModel.kt +++ b/profile_uart/src/main/java/no/nordicsemi/android/uart/viewmodel/UARTViewModel.kt @@ -51,7 +51,7 @@ import no.nordicsemi.android.analytics.UARTMode import no.nordicsemi.android.analytics.UARTSendAnalyticsEvent import no.nordicsemi.android.common.navigation.NavigationResult import no.nordicsemi.android.common.navigation.Navigator -import no.nordicsemi.android.common.ui.scanner.model.DiscoveredBluetoothDevice +import no.nordicsemi.android.kotlin.ble.core.ServerDevice import no.nordicsemi.android.service.ConnectedResult import no.nordicsemi.android.service.IdleResult import no.nordicsemi.android.toolbox.scanner.ScannerDestinationId @@ -129,7 +129,7 @@ internal class UARTViewModel @Inject constructor( .launchIn(viewModelScope) } - private fun handleResult(result: NavigationResult) { + private fun handleResult(result: NavigationResult) { when (result) { is NavigationResult.Cancelled -> navigationManager.navigateUp() is NavigationResult.Success -> repository.launch(result.value)