From b3536d3b4f0c33c92614c8faf5d74c8e07e258da Mon Sep 17 00:00:00 2001 From: Constantine Date: Fri, 9 Jan 2026 16:04:38 -0800 Subject: [PATCH] Improve deep acknowledgement --- .idea/vcs.xml | 2 +- app/build.gradle.kts | 4 +- .../software/data/repo/SettingsRepository.kt | 9 ++-- .../software/ui/settings/SettingsScreen.kt | 34 +++++++++++- .../utils/graphic/ComposeFunctions.kt | 53 ++++++++++++++++--- app/src/main/res/values/strings.xml | 9 +++- 6 files changed, 95 insertions(+), 16 deletions(-) diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 94a25f7f..35eb1ddf 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 562ce30b..47521a80 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -26,8 +26,8 @@ android { minSdk = 29 targetSdk = 36 - versionCode = 1708536380 - versionName = "0.32.0-beta" + versionCode = 1708536381 + versionName = "0.32.1-beta" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/java/f/cking/software/data/repo/SettingsRepository.kt b/app/src/main/java/f/cking/software/data/repo/SettingsRepository.kt index 9108d417..3b5febe9 100644 --- a/app/src/main/java/f/cking/software/data/repo/SettingsRepository.kt +++ b/app/src/main/java/f/cking/software/data/repo/SettingsRepository.kt @@ -13,6 +13,7 @@ class SettingsRepository( private val silentModeState = MutableStateFlow(getSilentMode()) private val hideBackgroundLocationWarning = MutableStateFlow(getHideBackgroundLocationWarning()) + private val enableDeepAnalysisState = MutableStateFlow(false) fun setGarbagingTime(time: Long) { sharedPreferences.edit().putLong(KEY_GARBAGING_TIME, time).apply() @@ -105,11 +106,13 @@ class SettingsRepository( } fun setEnableDeepAnalysis(value: Boolean) { - sharedPreferences.edit { putBoolean(KEY_ENABLE_DEEP_ANALYSIS, value) } + enableDeepAnalysisState.value = value + //sharedPreferences.edit { putBoolean(KEY_ENABLE_DEEP_ANALYSIS, value) } } fun getEnableDeepAnalysis(): Boolean { - return sharedPreferences.getBoolean(KEY_ENABLE_DEEP_ANALYSIS, false) + return enableDeepAnalysisState.value + //return sharedPreferences.getBoolean(KEY_ENABLE_DEEP_ANALYSIS, false) } fun setDisclaimerWasAccepted(value: Boolean) { @@ -147,7 +150,7 @@ class SettingsRepository( private const val KEY_SILENT_NETWORK_MODE = "silent_network_mode" private const val KEY_CURRENT_BATCH_SORTING_STRATEGY_ID = "key_current_batch_sorting_strategy_id" private const val KEY_HIDE_BACKGROUND_LOCATION_WARNING = "key_hide_background_location_warning" - private const val KEY_ENABLE_DEEP_ANALYSIS = "key_enable_deep_analysis" + private const val KEY_ENABLE_DEEP_ANALYSIS = "key_enable_deep_analysis_v2" private const val KEY_DISCLAIMER_WAS_ACCEPTED = "key_disclaimer_was_accepted" private const val KEY_WHAT_IS_THIS_APP_FOR_WAS_SHOWN = "what_is_this_app_for_was_shown" private const val KEY_WAKE_UP_SCREEN_WHILE_SCANNING = "key_wake_up_screen_while_scanning" diff --git a/app/src/main/java/f/cking/software/ui/settings/SettingsScreen.kt b/app/src/main/java/f/cking/software/ui/settings/SettingsScreen.kt index eae0155b..71a62889 100644 --- a/app/src/main/java/f/cking/software/ui/settings/SettingsScreen.kt +++ b/app/src/main/java/f/cking/software/ui/settings/SettingsScreen.kt @@ -38,6 +38,7 @@ import f.cking.software.utils.graphic.FABSpacer import f.cking.software.utils.graphic.RoundedBox import f.cking.software.utils.graphic.Switcher import f.cking.software.utils.graphic.ThemedDialog +import f.cking.software.utils.graphic.agreementDialog import org.koin.androidx.compose.koinViewModel object SettingsScreen { @@ -288,17 +289,46 @@ object SettingsScreen { subtitle = null, onClick = { viewModel.setRunOnStartup() } ) + + val deepAnalysisDialog = agreementDialog( + title = stringResource(R.string.deep_analysis_warning_title), + content = stringResource(R.string.deep_analysis_warning_text), + agreement = stringResource(R.string.deep_analysis_agreement_text), + buttons = { state -> + { + negativeButton( + stringResource(R.string.deep_analysis_decline), + textStyle = TextStyle(color = MaterialTheme.colorScheme.onSurface) + ) { state.hide() } + positiveButton( + stringResource(R.string.deep_analysis_enable), + textStyle = TextStyle(color = MaterialTheme.colorScheme.onSurface) + ) { + state.hide() + viewModel.onEnableDeepAnalysisClick() + } + } + } + ) Switcher( value = viewModel.deepAnalysisEnabled, title = stringResource(R.string.enable_deep_analysis), subtitle = stringResource(R.string.enable_deep_analysis_description), - onClick = { viewModel.onEnableDeepAnalysisClick() } + onClick = { + if (viewModel.deepAnalysisEnabled) { + viewModel.onEnableDeepAnalysisClick() + } else { + deepAnalysisDialog.show() + } + } ) Switcher( value = viewModel.wakeUpWhileScanning, title = stringResource(R.string.settings_keep_screen_on_while_scanning_title), subtitle = stringResource(R.string.settings_keep_screen_on_while_scanning_description), - onClick = { viewModel.toggleWakeUpOnScreen() } + onClick = { + viewModel.toggleWakeUpOnScreen() + } ) } } diff --git a/app/src/main/java/f/cking/software/utils/graphic/ComposeFunctions.kt b/app/src/main/java/f/cking/software/utils/graphic/ComposeFunctions.kt index bf3996e8..33d54e3c 100644 --- a/app/src/main/java/f/cking/software/utils/graphic/ComposeFunctions.kt +++ b/app/src/main/java/f/cking/software/utils/graphic/ComposeFunctions.kt @@ -30,6 +30,7 @@ import androidx.compose.material.icons.filled.Star import androidx.compose.material.icons.outlined.Info import androidx.compose.material3.AssistChip import androidx.compose.material3.AssistChipDefaults +import androidx.compose.material3.Checkbox import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ColorScheme import androidx.compose.material3.Icon @@ -214,6 +215,41 @@ fun infoDialog( return dialogState } +@Composable +fun agreementDialog( + title: String, + content: String, + agreement: String, + buttons: ((state: MaterialDialogState) -> (@Composable MaterialDialogButtons.() -> Unit)), +): MaterialDialogState { + val dialogState = rememberMaterialDialogState() + ThemedDialog( + dialogState = dialogState, + buttons = buttons.invoke(dialogState), + ) { + var agreed: Boolean by remember { mutableStateOf(false) } + positiveButtonEnabled[0] = agreed + Column(modifier = Modifier.padding(16.dp)) { + Text(text = title, fontWeight = FontWeight.Bold) + Spacer(modifier = Modifier.height(8.dp)) + Text(text = content) + Spacer(modifier = Modifier.height(8.dp)) + val agreedClick = { + agreed = !agreed + positiveButtonEnabled[0] = agreed + } + Row(Modifier.clickable(onClick = agreedClick), verticalAlignment = Alignment.CenterVertically) { + Checkbox( + checked = agreed, + onCheckedChange = { agreedClick.invoke() } + ) + Text(text = agreement) + } + } + } + return dialogState +} + @Composable fun ThemedDialog( dialogState: MaterialDialogState = rememberMaterialDialogState(), @@ -286,7 +322,9 @@ fun DeviceListItem( .clickable { onClick.invoke() }, ) { Row( - modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 8.dp) + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 8.dp) ) { DeviceTypeIcon( modifier = Modifier.size(64.dp), @@ -374,7 +412,8 @@ fun DevicePairedIcon(isPaired: Boolean, extended: Boolean = false) { content = null, ) Row( - modifier = Modifier.background(color.copy(0.2f), RoundedCornerShape(20.dp)) + modifier = Modifier + .background(color.copy(0.2f), RoundedCornerShape(20.dp)) .clickable { infoDialog.show() }, verticalAlignment = Alignment.CenterVertically, ) { @@ -407,7 +446,8 @@ fun DeviceTypeIcon( val icon = remember(device) { GetIconForDeviceClass.getIcon(device) } val color = colorByHash(device.address.hashCode()) Icon( - modifier = modifier.background(color.copy(0.2f), CircleShape) + modifier = modifier + .background(color.copy(0.2f), CircleShape) .padding(paddingDp), painter = painterResource(icon), contentDescription = stringResource(R.string.device_type), @@ -696,9 +736,10 @@ fun Switcher( subtitle: String?, onClick: () -> Unit, ) { - Box(modifier = modifier - .fillMaxWidth() - .clickable { onClick.invoke() } + Box( + modifier = modifier + .fillMaxWidth() + .clickable { onClick.invoke() } ) { Row( modifier = Modifier diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9969115a..e3b993d5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -106,8 +106,13 @@ Location records: %s App settings Offline mode is turned off. You can change it in the settings. - Deep analysis - Enabling deep analysis for all found devices will provide more data for each scan, but increase scan time and power consumption. + Deep analysis (Experimental) + If Deep Analysis is enabled, the app will request more information from all found devices. It will provide more data for each scan, but will also increase scan time and power consumption and may disclose your presence. + Enable Deep Analysis? (EXPERIMENTAL) + Deep Analysis does not only scan for BLE devices. It also actively requests data from their accessible GATT services.\n\nSome devices may require authentication or encryption to access certain services. In such cases, this may trigger a pairing request.\n\nThis mode may also make your device more visible to nearby devices.\n\nOnly enable this feature if you understand how it works and accept these side effects. + I know what I\'m doing + Cancel + Enable Search manufacturer