Merge pull request #108 from NordicSemiconductor/bug/logging

Bug/logging
This commit is contained in:
Sylwester Zieliński
2022-04-04 16:27:50 +02:00
committed by GitHub
46 changed files with 320 additions and 42 deletions

View File

@@ -14,6 +14,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.logger.LoggerAppRunner
import no.nordicsemi.android.nrftoolbox.BuildConfig
import no.nordicsemi.android.nrftoolbox.ProfileDestination
import no.nordicsemi.android.nrftoolbox.R
@@ -24,7 +25,6 @@ private const val DFU_PACKAGE_NAME = "no.nordicsemi.android.dfu"
private const val DFU_LINK = "https://play.google.com/store/apps/details?id=no.nordicsemi.android.dfu"
private const val LOGGER_PACKAGE_NAME = "no.nordicsemi.android.log"
private const val LOGGER_LINK = "https://play.google.com/store/apps/details?id=no.nordicsemi.android.log"
@Composable
fun HomeScreen() {
@@ -148,12 +148,7 @@ fun HomeScreen() {
} ?: R.string.dfu_module_install
FeatureButton(R.drawable.ic_logger, R.string.logger_module, R.string.logger_module_full, null, loggerDescription) {
val intent = packageManger.getLaunchIntentForPackage(LOGGER_PACKAGE_NAME)
if (intent != null) {
context.startActivity(intent)
} else {
uriHandler.openUri(LOGGER_LINK)
}
viewModel.openLogger()
}
Spacer(modifier = Modifier.height(16.dp))

View File

@@ -12,6 +12,7 @@ import no.nordicsemi.android.cgms.repository.CGMRepository
import no.nordicsemi.android.csc.repository.CSCRepository
import no.nordicsemi.android.hrs.service.HRSRepository
import no.nordicsemi.android.hts.repository.HTSRepository
import no.nordicsemi.android.logger.LoggerAppRunner
import no.nordicsemi.android.navigation.NavigationManager
import no.nordicsemi.android.nrftoolbox.ProfileDestination
import no.nordicsemi.android.nrftoolbox.repository.ActivitySignals
@@ -32,6 +33,7 @@ class HomeViewModel @Inject constructor(
prxRepository: PRXRepository,
rscsRepository: RSCSRepository,
uartRepository: UARTRepository,
private val loggerAppRunner: LoggerAppRunner
) : ViewModel() {
private val _state = MutableStateFlow(HomeViewState())
@@ -74,4 +76,8 @@ class HomeViewModel @Inject constructor(
fun openProfile(destination: ProfileDestination) {
navigationManager.navigateTo(destination.destination.id)
}
fun openLogger() {
loggerAppRunner.runLogger()
}
}

View File

@@ -0,0 +1,44 @@
package no.nordicsemi.android.logger
import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.compose.ui.platform.AndroidUriHandler
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
private const val LOGGER_PACKAGE_NAME = "no.nordicsemi.android.log"
private const val LOGGER_LINK = "https://play.google.com/store/apps/details?id=no.nordicsemi.android.log"
class LoggerAppRunner @Inject constructor(
@ApplicationContext
private val context: Context
) {
fun runLogger() {
val packageManger = context.packageManager
val uriHandler = AndroidUriHandler(context)
val intent = packageManger.getLaunchIntentForPackage(LOGGER_PACKAGE_NAME)
if (intent != null) {
context.startActivity(intent)
} else {
uriHandler.openUri(LOGGER_LINK)
}
}
fun runLogger(uri: Uri?) {
val packageManger = context.packageManager
val intent = packageManger.getLaunchIntentForPackage(LOGGER_PACKAGE_NAME)
val targetUri = if (intent != null && uri != null) {
uri
} else {
Uri.parse(LOGGER_LINK)
}
val launchIntent = Intent(Intent.ACTION_VIEW, targetUri)
launchIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
context.startActivity(launchIntent)
}
}

View File

@@ -2,6 +2,9 @@ package no.nordicsemi.android.logger
import android.content.Context
import android.util.Log
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import dagger.hilt.android.qualifiers.ApplicationContext
import no.nordicsemi.android.log.LogContract
import no.nordicsemi.android.log.LogSession
import no.nordicsemi.android.log.Logger
@@ -9,8 +12,13 @@ import no.nordicsemi.android.log.annotation.LogLevel
internal const val LOG_TAG = "nRF Toolbox"
class ToolboxLogger(
class ToolboxLogger @AssistedInject constructor(
@ApplicationContext
private val context: Context,
private val appRunner: LoggerAppRunner,
@Assisted("profile")
private val profile: String,
@Assisted("key")
private val key: String,
) {
@@ -21,11 +29,17 @@ class ToolboxLogger(
if (logSession != null) {
Logger.log(logSession, LogContract.Log.Level.fromPriority(level), message)
}
Log.println(level, LOG_TAG, message)
val logPriority = if (level <= Log.ASSERT) level else Log.INFO
Log.println(logPriority, LOG_TAG, message)
}
fun openLogger() {
appRunner.runLogger(logSession?.sessionUri)
}
private fun getLogger(): LogSession? {
logSession = logSession ?: Logger.newSession(context, key, LOG_TAG)
logSession = logSession ?: Logger.newSession(context, profile, key, LOG_TAG)
logSession?.sessionsUri
return logSession
}
}

View File

@@ -0,0 +1,10 @@
package no.nordicsemi.android.logger
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
@AssistedFactory
interface ToolboxLoggerFactory {
fun create(@Assisted("profile") profile: String, @Assisted("key") key: String): ToolboxLogger
}

View File

@@ -1,6 +1,6 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="1024dp"
android:height="1024dp"
android:width="80dp"
android:height="80dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path

View File

@@ -1,6 +1,8 @@
apply from: rootProject.file("library.gradle")
dependencies {
implementation project(":lib_log")
implementation libs.material
implementation libs.nordic.theme

View File

@@ -1,5 +1,6 @@
package no.nordicsemi.android.theme.view
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.Close
@@ -10,8 +11,13 @@ import androidx.compose.material3.SmallTopAppBar
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import no.nordicsemi.android.theme.R
@Composable
@@ -68,6 +74,48 @@ fun BackIconAppBar(text: String, onClick: () -> Unit) {
contentDescription = stringResource(id = R.string.back_screen),
)
}
},
actions = {
IconButton(onClick = { onClick() }) {
Icon(
painterResource(id = R.drawable.ic_logger),
contentDescription = stringResource(id = R.string.back_screen),
tint = MaterialTheme.colorScheme.onPrimary,
modifier = Modifier.size(24.dp)
)
}
}
)
}
@Composable
fun LoggerIconAppBar(text: String, onClick: () -> Unit, onLoggerClick: () -> Unit) {
SmallTopAppBar(
title = { Text(text) },
colors = TopAppBarDefaults.smallTopAppBarColors(
scrolledContainerColor = MaterialTheme.colorScheme.primary,
containerColor = colorResource(id = R.color.appBarColor),
titleContentColor = MaterialTheme.colorScheme.onPrimary,
actionIconContentColor = MaterialTheme.colorScheme.onPrimary,
navigationIconContentColor = MaterialTheme.colorScheme.onPrimary,
),
navigationIcon = {
IconButton(onClick = { onClick() }) {
Icon(
Icons.Default.ArrowBack,
contentDescription = stringResource(id = R.string.back_screen),
)
}
},
actions = {
IconButton(onClick = { onLoggerClick() }) {
Icon(
painterResource(id = R.drawable.ic_logger),
contentDescription = stringResource(id = R.string.back_screen),
tint = MaterialTheme.colorScheme.onPrimary,
modifier = Modifier.size(24.dp)
)
}
}
)
}

View File

@@ -12,18 +12,25 @@ import kotlinx.coroutines.flow.onEach
import no.nordicsemi.android.bps.data.BPSData
import no.nordicsemi.android.bps.data.BPSManager
import no.nordicsemi.android.logger.ToolboxLogger
import no.nordicsemi.android.logger.ToolboxLoggerFactory
import no.nordicsemi.android.service.BleManagerResult
import javax.inject.Inject
@ViewModelScoped
internal class BPSRepository @Inject constructor(
@ApplicationContext
private val context: Context
private val context: Context,
private val toolboxLoggerFactory: ToolboxLoggerFactory
) {
private var logger: ToolboxLogger? = null
fun downloadData(device: BluetoothDevice): Flow<BleManagerResult<BPSData>> = callbackFlow {
val scope = this
val manager = BPSManager(context, scope, ToolboxLogger(context, "BPS"))
val createdLogger = toolboxLoggerFactory.create("BPS", device.address).also {
logger = it
}
val manager = BPSManager(context, scope, createdLogger)
manager.dataHolder.status.onEach {
trySend(it)
@@ -36,6 +43,12 @@ internal class BPSRepository @Inject constructor(
awaitClose {
manager.disconnect().enqueue()
logger = null
}
}
fun openLogger() {
logger?.openLogger()
}
}

View File

@@ -12,6 +12,7 @@ import no.nordicsemi.android.bps.R
import no.nordicsemi.android.bps.viewmodel.BPSViewModel
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.BackIconAppBar
import no.nordicsemi.android.theme.view.LoggerIconAppBar
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
import no.nordicsemi.ui.scanner.ui.NoDeviceView
import no.nordicsemi.android.utils.exhaustive
@@ -26,8 +27,10 @@ fun BPSScreen() {
Column {
val navigateUp = { viewModel.onEvent(DisconnectEvent) }
BackIconAppBar(stringResource(id = R.string.bps_title)) {
LoggerIconAppBar(stringResource(id = R.string.bps_title), {
viewModel.onEvent(DisconnectEvent)
}) {
viewModel.onEvent(OpenLoggerEvent)
}
Column(modifier = Modifier.verticalScroll(rememberScrollState())) {

View File

@@ -3,3 +3,5 @@ package no.nordicsemi.android.bps.view
internal sealed class BPSScreenViewEvent
internal object DisconnectEvent : BPSScreenViewEvent()
internal object OpenLoggerEvent : BPSScreenViewEvent()

View File

@@ -46,6 +46,7 @@ internal class BPSViewModel @Inject constructor(
fun onEvent(event: BPSScreenViewEvent) {
when (event) {
DisconnectEvent -> navigationManager.navigateUp()
OpenLoggerEvent -> repository.openLogger()
}.exhaustive
}

View File

@@ -10,6 +10,7 @@ import no.nordicsemi.android.ble.ktx.suspend
import no.nordicsemi.android.cgms.data.CGMData
import no.nordicsemi.android.cgms.data.CGMManager
import no.nordicsemi.android.logger.ToolboxLogger
import no.nordicsemi.android.logger.ToolboxLoggerFactory
import no.nordicsemi.android.service.BleManagerResult
import no.nordicsemi.android.service.ConnectingResult
import no.nordicsemi.android.service.ServiceManager
@@ -20,9 +21,11 @@ import javax.inject.Singleton
class CGMRepository @Inject constructor(
@ApplicationContext
private val context: Context,
private val serviceManager: ServiceManager
private val serviceManager: ServiceManager,
private val toolboxLoggerFactory: ToolboxLoggerFactory
) {
private var manager: CGMManager? = null
private var logger: ToolboxLogger? = null
private val _data = MutableStateFlow<BleManagerResult<CGMData>>(ConnectingResult())
internal val data = _data.asStateFlow()
@@ -35,7 +38,10 @@ class CGMRepository @Inject constructor(
}
fun start(device: BluetoothDevice, scope: CoroutineScope) {
val manager = CGMManager(context, scope, ToolboxLogger(context, "CGMS"))
val createdLogger = toolboxLoggerFactory.create("CGMS", device.address).also {
logger = it
}
val manager = CGMManager(context, scope, createdLogger)
this.manager = manager
manager.dataHolder.status.onEach {
@@ -70,8 +76,13 @@ class CGMRepository @Inject constructor(
manager?.requestFirstRecord()
}
fun openLogger() {
logger?.openLogger()
}
fun release() {
manager?.disconnect()?.enqueue()
logger = null
manager = null
}
}

View File

@@ -12,6 +12,7 @@ import no.nordicsemi.android.cgms.R
import no.nordicsemi.android.cgms.viewmodel.CGMScreenViewModel
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.BackIconAppBar
import no.nordicsemi.android.theme.view.LoggerIconAppBar
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
import no.nordicsemi.ui.scanner.ui.NoDeviceView
import no.nordicsemi.android.utils.exhaustive
@@ -26,7 +27,9 @@ fun CGMScreen() {
Column {
val navigateUp = { viewModel.onEvent(NavigateUp) }
BackIconAppBar(stringResource(id = R.string.cgms_title), navigateUp)
LoggerIconAppBar(stringResource(id = R.string.cgms_title), navigateUp) {
viewModel.onEvent(OpenLoggerEvent)
}
Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
when (state) {

View File

@@ -9,3 +9,5 @@ internal data class OnWorkingModeSelected(val workingMode: CGMServiceCommand) :
internal object NavigateUp : CGMViewEvent()
internal object DisconnectEvent : CGMViewEvent()
internal object OpenLoggerEvent : CGMViewEvent()

View File

@@ -41,6 +41,7 @@ internal class CGMScreenViewModel @Inject constructor(
DisconnectEvent -> disconnect()
is OnWorkingModeSelected -> onCommandReceived(event.workingMode)
NavigateUp -> navigationManager.navigateUp()
OpenLoggerEvent -> repository.openLogger()
}.exhaustive
}

View File

@@ -11,6 +11,7 @@ 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.logger.ToolboxLogger
import no.nordicsemi.android.logger.ToolboxLoggerFactory
import no.nordicsemi.android.service.BleManagerResult
import no.nordicsemi.android.service.ConnectingResult
import no.nordicsemi.android.service.ServiceManager
@@ -21,9 +22,11 @@ import javax.inject.Singleton
class CSCRepository @Inject constructor(
@ApplicationContext
private val context: Context,
private val serviceManager: ServiceManager
private val serviceManager: ServiceManager,
private val toolboxLoggerFactory: ToolboxLoggerFactory
) {
private var manager: CSCManager? = null
private var logger: ToolboxLogger? = null
private val _data = MutableStateFlow<BleManagerResult<CSCData>>(ConnectingResult())
internal val data = _data.asStateFlow()
@@ -36,7 +39,10 @@ class CSCRepository @Inject constructor(
}
fun start(device: BluetoothDevice, scope: CoroutineScope) {
val manager = CSCManager(context, scope, ToolboxLogger(context, "CSC"))
val createdLogger = toolboxLoggerFactory.create("CSC", device.address).also {
logger = it
}
val manager = CSCManager(context, scope, createdLogger)
this.manager = manager
manager.dataHolder.status.onEach {
@@ -63,8 +69,13 @@ class CSCRepository @Inject constructor(
}
}
fun openLogger() {
logger?.openLogger()
}
fun release() {
manager?.disconnect()?.enqueue()
logger = null
manager = null
}
}

View File

@@ -12,6 +12,7 @@ import no.nordicsemi.android.csc.R
import no.nordicsemi.android.csc.viewmodel.CSCViewModel
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.BackIconAppBar
import no.nordicsemi.android.theme.view.LoggerIconAppBar
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
import no.nordicsemi.ui.scanner.ui.NoDeviceView
import no.nordicsemi.android.utils.exhaustive
@@ -26,7 +27,9 @@ fun CSCScreen() {
Column {
val navigateUp = { viewModel.onEvent(NavigateUp) }
BackIconAppBar(stringResource(id = R.string.csc_title), navigateUp)
LoggerIconAppBar(stringResource(id = R.string.csc_title), navigateUp) {
viewModel.onEvent(OpenLogger)
}
Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
when (state.cscManagerState) {

View File

@@ -11,3 +11,5 @@ internal data class OnSelectedSpeedUnitSelected(val selectedSpeedUnit: SpeedUnit
internal object OnDisconnectButtonClick : CSCViewEvent()
internal object NavigateUp : CSCViewEvent()
internal object OpenLogger : CSCViewEvent()

View File

@@ -58,6 +58,7 @@ internal class CSCViewModel @Inject constructor(
is OnWheelSizeSelected -> repository.setWheelSize(event.wheelSize)
OnDisconnectButtonClick -> disconnect()
NavigateUp -> navigationManager.navigateUp()
OpenLogger -> repository.openLogger()
}.exhaustive
}

View File

@@ -56,8 +56,7 @@ private val BATTERY_SERVICE_UUID = UUID.fromString("0000180F-0000-1000-8000-0080
private val BATTERY_LEVEL_CHARACTERISTIC_UUID =
UUID.fromString("00002A19-0000-1000-8000-00805f9b34fb")
internal class GLSManager @Inject constructor(
@ApplicationContext
internal class GLSManager(
context: Context,
private val scope: CoroutineScope,
private val logger: ToolboxLogger

View File

@@ -12,6 +12,7 @@ import no.nordicsemi.android.gls.R
import no.nordicsemi.android.gls.main.viewmodel.GLSViewModel
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.BackIconAppBar
import no.nordicsemi.android.theme.view.LoggerIconAppBar
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
import no.nordicsemi.ui.scanner.ui.NoDeviceView
import no.nordicsemi.android.utils.exhaustive
@@ -26,8 +27,10 @@ fun GLSScreen() {
Column {
val navigateUp = { viewModel.onEvent(DisconnectEvent) }
BackIconAppBar(stringResource(id = R.string.gls_title)) {
LoggerIconAppBar(stringResource(id = R.string.gls_title), {
viewModel.onEvent(DisconnectEvent)
}) {
viewModel.onEvent(OpenLoggerEvent)
}
Column(modifier = Modifier.verticalScroll(rememberScrollState())) {

View File

@@ -10,3 +10,5 @@ internal data class OnWorkingModeSelected(val workingMode: WorkingMode) : GLSScr
internal data class OnGLSRecordClick(val record: GLSRecord) : GLSScreenViewEvent()
internal object DisconnectEvent : GLSScreenViewEvent()
internal object OpenLoggerEvent : GLSScreenViewEvent()

View File

@@ -43,6 +43,7 @@ internal class GLSViewModel @Inject constructor(
fun onEvent(event: GLSScreenViewEvent) {
when (event) {
OpenLoggerEvent -> repository.openLogger()
DisconnectEvent -> navigationManager.navigateUp()
is OnWorkingModeSelected -> repository.requestMode(event.workingMode)
is OnGLSRecordClick -> navigationManager.navigateTo(GlsDetailsDestinationId, AnyArgument(event.record))

View File

@@ -15,6 +15,7 @@ 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.logger.ToolboxLogger
import no.nordicsemi.android.logger.ToolboxLoggerFactory
import no.nordicsemi.android.service.BleManagerResult
import no.nordicsemi.android.utils.exhaustive
import javax.inject.Inject
@@ -22,14 +23,19 @@ import javax.inject.Inject
@ViewModelScoped
internal class GLSRepository @Inject constructor(
@ApplicationContext
private val context: Context
private val context: Context,
private val toolboxLoggerFactory: ToolboxLoggerFactory
) {
private var manager: GLSManager? = null
private var logger: ToolboxLogger? = null
fun downloadData(device: BluetoothDevice): Flow<BleManagerResult<GLSData>> = callbackFlow {
val scope = this
val managerInstance = manager ?: GLSManager(context, scope, ToolboxLogger(context, "GLS")).apply {
val createdLogger = toolboxLoggerFactory.create("GLS", device.address).also {
logger = it
}
val managerInstance = manager ?: GLSManager(context, scope, createdLogger).apply {
try {
connect(device)
.useAutoConnect(false)
@@ -48,11 +54,16 @@ internal class GLSRepository @Inject constructor(
awaitClose {
launch {
manager?.disconnect()?.suspend()
logger = null
manager = null
}
}
}
fun openLogger() {
logger?.openLogger()
}
fun requestMode(workingMode: WorkingMode) {
when (workingMode) {
WorkingMode.ALL -> manager?.requestAllRecords()

View File

@@ -10,6 +10,7 @@ import no.nordicsemi.android.ble.ktx.suspend
import no.nordicsemi.android.hrs.data.HRSData
import no.nordicsemi.android.hrs.data.HRSManager
import no.nordicsemi.android.logger.ToolboxLogger
import no.nordicsemi.android.logger.ToolboxLoggerFactory
import no.nordicsemi.android.service.BleManagerResult
import no.nordicsemi.android.service.ConnectingResult
import no.nordicsemi.android.service.ServiceManager
@@ -20,9 +21,11 @@ import javax.inject.Singleton
class HRSRepository @Inject constructor(
@ApplicationContext
private val context: Context,
private val serviceManager: ServiceManager
private val serviceManager: ServiceManager,
private val toolboxLoggerFactory: ToolboxLoggerFactory
) {
private var manager: HRSManager? = null
private var logger: ToolboxLogger? = null
private val _data = MutableStateFlow<BleManagerResult<HRSData>>(ConnectingResult())
internal val data = _data.asStateFlow()
@@ -35,7 +38,10 @@ class HRSRepository @Inject constructor(
}
fun start(device: BluetoothDevice, scope: CoroutineScope) {
val manager = HRSManager(context, scope, ToolboxLogger(context, "HRS"))
val createdLogger = toolboxLoggerFactory.create("HRS", device.address).also {
logger = it
}
val manager = HRSManager(context, scope, createdLogger)
this.manager = manager
manager.dataHolder.status.onEach {
@@ -47,6 +53,10 @@ class HRSRepository @Inject constructor(
}
}
fun openLogger() {
logger?.openLogger()
}
private suspend fun HRSManager.start(device: BluetoothDevice) {
try {
connect(device)
@@ -60,6 +70,7 @@ class HRSRepository @Inject constructor(
fun release() {
manager?.disconnect()?.enqueue()
logger = null
manager = null
}
}

View File

@@ -12,6 +12,7 @@ import no.nordicsemi.android.hrs.R
import no.nordicsemi.android.hrs.viewmodel.HRSViewModel
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.BackIconAppBar
import no.nordicsemi.android.theme.view.LoggerIconAppBar
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
import no.nordicsemi.ui.scanner.ui.NoDeviceView
import no.nordicsemi.android.utils.exhaustive
@@ -26,7 +27,9 @@ fun HRSScreen() {
Column {
val navigateUp = { viewModel.onEvent(NavigateUpEvent) }
BackIconAppBar(stringResource(id = R.string.hrs_title), navigateUp)
LoggerIconAppBar(stringResource(id = R.string.hrs_title), navigateUp) {
viewModel.onEvent(OpenLoggerEvent)
}
Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
when (state) {

View File

@@ -5,3 +5,5 @@ internal sealed class HRSScreenViewEvent
internal object DisconnectEvent : HRSScreenViewEvent()
internal object NavigateUpEvent : HRSScreenViewEvent()
internal object OpenLoggerEvent : HRSScreenViewEvent()

View File

@@ -56,6 +56,7 @@ internal class HRSViewModel @Inject constructor(
when (event) {
DisconnectEvent -> disconnect()
NavigateUpEvent -> navigationManager.navigateUp()
OpenLoggerEvent -> repository.openLogger()
}.exhaustive
}

View File

@@ -10,6 +10,7 @@ import no.nordicsemi.android.ble.ktx.suspend
import no.nordicsemi.android.hts.data.HTSData
import no.nordicsemi.android.hts.data.HTSManager
import no.nordicsemi.android.logger.ToolboxLogger
import no.nordicsemi.android.logger.ToolboxLoggerFactory
import no.nordicsemi.android.service.BleManagerResult
import no.nordicsemi.android.service.ConnectingResult
import no.nordicsemi.android.service.ServiceManager
@@ -20,9 +21,11 @@ import javax.inject.Singleton
class HTSRepository @Inject constructor(
@ApplicationContext
private val context: Context,
private val serviceManager: ServiceManager
private val serviceManager: ServiceManager,
private val toolboxLoggerFactory: ToolboxLoggerFactory
) {
private var manager: HTSManager? = null
private var logger: ToolboxLogger? = null
private val _data = MutableStateFlow<BleManagerResult<HTSData>>(ConnectingResult())
internal val data = _data.asStateFlow()
@@ -35,7 +38,10 @@ class HTSRepository @Inject constructor(
}
fun start(device: BluetoothDevice, scope: CoroutineScope) {
val manager = HTSManager(context, scope, ToolboxLogger(context, "HTS"))
val createdLogger = toolboxLoggerFactory.create("HTS", device.address).also {
logger = it
}
val manager = HTSManager(context, scope, createdLogger)
this.manager = manager
manager.dataHolder.status.onEach {
@@ -47,6 +53,10 @@ class HTSRepository @Inject constructor(
}
}
fun openLogger() {
logger?.openLogger()
}
private suspend fun HTSManager.start(device: BluetoothDevice) {
try {
connect(device)
@@ -60,6 +70,7 @@ class HTSRepository @Inject constructor(
fun release() {
manager?.disconnect()?.enqueue()
logger = null
manager = null
}
}

View File

@@ -12,6 +12,7 @@ import no.nordicsemi.android.hts.R
import no.nordicsemi.android.hts.viewmodel.HTSViewModel
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.BackIconAppBar
import no.nordicsemi.android.theme.view.LoggerIconAppBar
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
import no.nordicsemi.ui.scanner.ui.NoDeviceView
import no.nordicsemi.android.utils.exhaustive
@@ -26,7 +27,9 @@ fun HTSScreen() {
Column {
val navigateUp = { viewModel.onEvent(NavigateUp) }
BackIconAppBar(stringResource(id = R.string.hts_title), navigateUp)
LoggerIconAppBar(stringResource(id = R.string.hts_title), navigateUp) {
viewModel.onEvent(OpenLoggerEvent)
}
Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
when (state.htsManagerState) {

View File

@@ -7,3 +7,5 @@ internal data class OnTemperatureUnitSelected(val value: TemperatureUnit) : HTSS
internal object DisconnectEvent : HTSScreenViewEvent()
internal object NavigateUp : HTSScreenViewEvent()
internal object OpenLoggerEvent : HTSScreenViewEvent()

View File

@@ -57,6 +57,7 @@ internal class HTSViewModel @Inject constructor(
DisconnectEvent -> disconnect()
is OnTemperatureUnitSelected -> onTemperatureUnitSelected(event)
NavigateUp -> navigationManager.navigateUp()
OpenLoggerEvent -> repository.openLogger()
}.exhaustive
}

View File

@@ -6,6 +6,7 @@ import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.*
import no.nordicsemi.android.logger.ToolboxLogger
import no.nordicsemi.android.logger.ToolboxLoggerFactory
import no.nordicsemi.android.prx.data.AlarmLevel
import no.nordicsemi.android.prx.data.PRXData
import no.nordicsemi.android.prx.data.PRXManager
@@ -20,10 +21,12 @@ class PRXRepository @Inject internal constructor(
private val context: Context,
private val serviceManager: ServiceManager,
private val proximityServerManager: ProximityServerManager,
private val alarmHandler: AlarmHandler
private val alarmHandler: AlarmHandler,
private val toolboxLoggerFactory: ToolboxLoggerFactory
) {
private var manager: PRXManager? = null
private var logger: ToolboxLogger? = null
private val _data = MutableStateFlow<BleManagerResult<PRXData>>(ConnectingResult())
internal val data = _data.asStateFlow()
@@ -37,7 +40,10 @@ class PRXRepository @Inject internal constructor(
}
fun start(device: BluetoothDevice, scope: CoroutineScope) {
val manager = PRXManager(context, scope, ToolboxLogger(context, "PRX"))
val createdLogger = toolboxLoggerFactory.create("PRX", device.address).also {
logger = it
}
val manager = PRXManager(context, scope, createdLogger)
this.manager = manager
manager.useServer(proximityServerManager)
@@ -73,9 +79,14 @@ class PRXRepository @Inject internal constructor(
manager?.writeImmediateAlert(false)
}
fun openLogger() {
logger?.openLogger()
}
fun release() {
alarmHandler.releaseAlarm()
manager?.disconnect()?.enqueue()
manager = null
logger = null
}
}

View File

@@ -13,6 +13,7 @@ import no.nordicsemi.android.prx.R
import no.nordicsemi.android.prx.viewmodel.PRXViewModel
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.BackIconAppBar
import no.nordicsemi.android.theme.view.LoggerIconAppBar
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
import no.nordicsemi.ui.scanner.ui.NoDeviceView
import no.nordicsemi.android.utils.exhaustive
@@ -27,7 +28,9 @@ fun PRXScreen() {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
val navigateUp = { viewModel.onEvent(NavigateUpEvent) }
BackIconAppBar(stringResource(id = R.string.prx_title), navigateUp)
LoggerIconAppBar(stringResource(id = R.string.prx_title), navigateUp) {
viewModel.onEvent(OpenLoggerEvent)
}
Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
when (state) {

View File

@@ -9,3 +9,5 @@ internal object TurnOnAlert : PRXScreenViewEvent()
internal object TurnOffAlert : PRXScreenViewEvent()
internal object DisconnectEvent : PRXScreenViewEvent()
internal object OpenLoggerEvent : PRXScreenViewEvent()

View File

@@ -58,6 +58,7 @@ internal class PRXViewModel @Inject constructor(
TurnOffAlert -> repository.disableAlarm()
TurnOnAlert -> repository.enableAlarm()
NavigateUpEvent -> navigationManager.navigateUp()
OpenLoggerEvent -> repository.openLogger()
}.exhaustive
}

View File

@@ -8,6 +8,7 @@ import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import no.nordicsemi.android.ble.ktx.suspend
import no.nordicsemi.android.logger.ToolboxLogger
import no.nordicsemi.android.logger.ToolboxLoggerFactory
import no.nordicsemi.android.rscs.data.RSCSData
import no.nordicsemi.android.rscs.data.RSCSManager
import no.nordicsemi.android.service.BleManagerResult
@@ -20,9 +21,11 @@ import javax.inject.Singleton
class RSCSRepository @Inject constructor(
@ApplicationContext
private val context: Context,
private val serviceManager: ServiceManager
private val serviceManager: ServiceManager,
private val toolboxLoggerFactory: ToolboxLoggerFactory
) {
private var manager: RSCSManager? = null
private var logger: ToolboxLogger? = null
private val _data = MutableStateFlow<BleManagerResult<RSCSData>>(ConnectingResult())
internal val data = _data.asStateFlow()
@@ -35,7 +38,10 @@ class RSCSRepository @Inject constructor(
}
fun start(device: BluetoothDevice, scope: CoroutineScope) {
val manager = RSCSManager(context, scope, ToolboxLogger(context, "RSCS"))
val createdLogger = toolboxLoggerFactory.create("RSCS", device.address).also {
logger = it
}
val manager = RSCSManager(context, scope, createdLogger)
this.manager = manager
manager.dataHolder.status.onEach {
@@ -47,6 +53,10 @@ class RSCSRepository @Inject constructor(
}
}
fun openLogger() {
logger?.openLogger()
}
private suspend fun RSCSManager.start(device: BluetoothDevice) {
try {
connect(device)
@@ -61,5 +71,6 @@ class RSCSRepository @Inject constructor(
fun release() {
manager?.disconnect()?.enqueue()
manager = null
logger = null
}
}

View File

@@ -12,6 +12,7 @@ import no.nordicsemi.android.rscs.R
import no.nordicsemi.android.rscs.viewmodel.RSCSViewModel
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.BackIconAppBar
import no.nordicsemi.android.theme.view.LoggerIconAppBar
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
import no.nordicsemi.ui.scanner.ui.NoDeviceView
import no.nordicsemi.android.utils.exhaustive
@@ -26,7 +27,9 @@ fun RSCSScreen() {
Column {
val navigateUp = { viewModel.onEvent(NavigateUpEvent) }
BackIconAppBar(stringResource(id = R.string.rscs_title), navigateUp)
LoggerIconAppBar(stringResource(id = R.string.rscs_title), navigateUp) {
viewModel.onEvent(OpenLoggerEvent)
}
Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
when (state) {

View File

@@ -5,3 +5,5 @@ internal sealed class RSCScreenViewEvent
internal object NavigateUpEvent : RSCScreenViewEvent()
internal object DisconnectEvent : RSCScreenViewEvent()
internal object OpenLoggerEvent : RSCScreenViewEvent()

View File

@@ -56,6 +56,7 @@ internal class RSCSViewModel @Inject constructor(
when (event) {
DisconnectEvent -> disconnect()
NavigateUpEvent -> navigationManager.navigateUp()
OpenLoggerEvent -> repository.openLogger()
}.exhaustive
}

View File

@@ -21,6 +21,7 @@
*/
package no.nordicsemi.android.uart.data
import android.annotation.SuppressLint
import android.bluetooth.BluetoothGatt
import android.bluetooth.BluetoothGattCharacteristic
import android.bluetooth.BluetoothGattService
@@ -36,6 +37,7 @@ import no.nordicsemi.android.ble.WriteRequest
import no.nordicsemi.android.ble.common.callback.battery.BatteryLevelResponse
import no.nordicsemi.android.ble.ktx.asFlow
import no.nordicsemi.android.ble.ktx.asValidResponseFlow
import no.nordicsemi.android.ble.ktx.suspend
import no.nordicsemi.android.logger.ToolboxLogger
import no.nordicsemi.android.service.ConnectionObserverAdapter
import no.nordicsemi.android.utils.EMPTY
@@ -83,9 +85,11 @@ internal class UARTManager(
private inner class UARTManagerGattCallback : BleManagerGattCallback() {
@SuppressLint("WrongConstant")
override fun initialize() {
setNotificationCallback(txCharacteristic).asFlow().onEach {
val text: String = it.getStringValue(0) ?: String.EMPTY
log(10, "\"$text\" received")
data.value = data.value.copy(messages = data.value.messages + UARTOutputRecord(text))
}.launchIn(scope)
@@ -134,6 +138,7 @@ internal class UARTManager(
}
}
@SuppressLint("WrongConstant")
fun send(text: String) {
if (rxCharacteristic == null) return
if (!TextUtils.isEmpty(text)) {
@@ -147,7 +152,8 @@ internal class UARTManager(
if (!useLongWrite) {
request.split()
}
request.enqueue()
request.suspend()
log(10, "\"$text\" sent")
}
}
}

View File

@@ -8,6 +8,7 @@ import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import no.nordicsemi.android.ble.ktx.suspend
import no.nordicsemi.android.logger.ToolboxLogger
import no.nordicsemi.android.logger.ToolboxLoggerFactory
import no.nordicsemi.android.service.BleManagerResult
import no.nordicsemi.android.service.ConnectingResult
import no.nordicsemi.android.service.ServiceManager
@@ -20,9 +21,11 @@ class UARTRepository @Inject internal constructor(
@ApplicationContext
private val context: Context,
private val serviceManager: ServiceManager,
private val configurationDataSource: ConfigurationDataSource
private val configurationDataSource: ConfigurationDataSource,
private val toolboxLoggerFactory: ToolboxLoggerFactory
) {
private var manager: UARTManager? = null
private var logger: ToolboxLogger? = null
private val _data = MutableStateFlow<BleManagerResult<UARTData>>(ConnectingResult())
internal val data = _data.asStateFlow()
@@ -37,7 +40,10 @@ class UARTRepository @Inject internal constructor(
}
fun start(device: BluetoothDevice, scope: CoroutineScope) {
val manager = UARTManager(context, scope, ToolboxLogger(context, "UART"))
val createdLogger = toolboxLoggerFactory.create("UART", device.address).also {
logger = it
}
val manager = UARTManager(context, scope, createdLogger)
this.manager = manager
manager.dataHolder.status.onEach {
@@ -59,6 +65,10 @@ class UARTRepository @Inject internal constructor(
manager?.clearItems()
}
fun openLogger() {
logger?.openLogger()
}
suspend fun saveConfigurationName(name: String) {
configurationDataSource.saveConfigurationName(name)
}
@@ -77,5 +87,6 @@ class UARTRepository @Inject internal constructor(
fun release() {
manager?.disconnect()?.enqueue()
manager = null
logger = null
}
}

View File

@@ -10,6 +10,7 @@ import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.BackIconAppBar
import no.nordicsemi.android.theme.view.LoggerIconAppBar
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
import no.nordicsemi.ui.scanner.ui.NoDeviceView
import no.nordicsemi.android.uart.R
@@ -30,7 +31,9 @@ fun UARTScreen() {
Column {
val navigateUp = { viewModel.onEvent(NavigateUp) }
BackIconAppBar(stringResource(id = R.string.uart_title), navigateUp)
LoggerIconAppBar(stringResource(id = R.string.uart_title), navigateUp) {
viewModel.onEvent(OpenLogger)
}
Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
when (state.uartManagerState) {

View File

@@ -20,3 +20,4 @@ internal object ClearOutputItems : UARTViewEvent()
internal object DisconnectEvent : UARTViewEvent()
internal object NavigateUp : UARTViewEvent()
internal object OpenLogger : UARTViewEvent()

View File

@@ -81,6 +81,7 @@ internal class UARTViewModel @Inject constructor(
OnDeleteConfiguration -> deleteConfiguration()
OnEditConfiguration -> onEditConfiguration()
ClearOutputItems -> repository.clearItems()
OpenLogger -> repository.openLogger()
}.exhaustive
}