Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@
<string name="LoadingScreen_Runv2_Failure">Error</string>
<string name="LoadingScreen_Runv2_Canceled">Link installation cancelled</string>
<string name="DescriptorUpdate_Updates">UPDATES</string>
<string name="AddDescriptor_AutoRunDisabled">Auto-run is disabled. Please enable it to run tests automatically.</string>

<!-- Modals / Toasts / Snackbar -->

Expand Down Expand Up @@ -344,6 +345,7 @@
<string name="Common_Refresh">Refresh</string>
<string name="Common_Collapse">Collapse</string>
<string name="Common_Expand">Expand</string>
<string name="Common_Enable">Enable</string>
<string name="Common_Ago">%1$s ago</string>
<string name="Common_Minutes_One">%1$d minute</string>
<string name="Common_Minutes_Other">%1$d minutes</string>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.ooni.probe.domain

import androidx.annotation.VisibleForTesting
import co.touchlab.kermit.Logger
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
Expand Down Expand Up @@ -57,7 +58,8 @@ class CheckAutoRunConstraints(
}

companion object {
private const val NOT_UPLOADED_LIMIT = 10
@VisibleForTesting
const val NOT_UPLOADED_LIMIT = 50
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ class GetSettings(
WebConnectivityCategory.entries.count { preferences[it.settingsKey] == true }
buildSettings(
hasWebsitesDescriptor = OrganizationConfig.hasWebsitesDescriptor,
uploadResultsEnabled = preferences[SettingsKey.UPLOAD_RESULTS] == true,
autoRunEnabled = preferences[SettingsKey.AUTOMATED_TESTING_ENABLED] == true,
enabledCategoriesCount = enabledCategoriesCount,
maxRuntimeEnabled = preferences[SettingsKey.MAX_RUNTIME_ENABLED] == true,
Expand All @@ -105,7 +104,6 @@ class GetSettings(

private fun buildSettings(
hasWebsitesDescriptor: Boolean,
uploadResultsEnabled: Boolean,
autoRunEnabled: Boolean,
enabledCategoriesCount: Int,
maxRuntimeEnabled: Boolean,
Expand Down Expand Up @@ -134,7 +132,6 @@ class GetSettings(
title = Res.string.Settings_AutomatedTesting_RunAutomatically,
key = SettingsKey.AUTOMATED_TESTING_ENABLED,
type = PreferenceItemType.SWITCH,
enabled = uploadResultsEnabled,
supportingContent = {
Text(
stringResource(Res.string.Settings_AutomatedTesting_RunAutomatically_Description),
Expand All @@ -147,7 +144,7 @@ class GetSettings(
title = Res.string.Settings_AutomatedTesting_RunAutomatically_WiFiOnly,
key = SettingsKey.AUTOMATED_TESTING_WIFIONLY,
type = PreferenceItemType.SWITCH,
enabled = autoRunEnabled && uploadResultsEnabled,
enabled = autoRunEnabled,
indentation = 1,
)
} else {
Expand All @@ -158,7 +155,7 @@ class GetSettings(
title = Res.string.Settings_AutomatedTesting_RunAutomatically_ChargingOnly,
key = SettingsKey.AUTOMATED_TESTING_CHARGING,
type = PreferenceItemType.SWITCH,
enabled = autoRunEnabled && uploadResultsEnabled,
enabled = autoRunEnabled,
indentation = 1,
)
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,9 @@ expect object Instrumentation {
block: suspend () -> T,
): T
}

suspend fun Instrumentation.reportTransaction(
operation: String,
name: String? = null,
data: Map<String, Any> = emptyMap(),
) = withTransaction(operation, name, data) {}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.selection.toggleable
import androidx.compose.foundation.selection.triStateToggleable
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
Expand All @@ -25,6 +26,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TriStateCheckbox
import androidx.compose.material3.pulltorefresh.PullToRefreshDefaults
Expand All @@ -39,8 +41,10 @@ import androidx.compose.ui.semantics.Role
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import ooniprobe.composeapp.generated.resources.AddDescriptor_AutoRun
import ooniprobe.composeapp.generated.resources.AddDescriptor_AutoRunDisabled
import ooniprobe.composeapp.generated.resources.AddDescriptor_Settings
import ooniprobe.composeapp.generated.resources.Common_Back
import ooniprobe.composeapp.generated.resources.Common_Enable
import ooniprobe.composeapp.generated.resources.Dashboard_Overview_ChooseWebsites
import ooniprobe.composeapp.generated.resources.Dashboard_Overview_Estimated
import ooniprobe.composeapp.generated.resources.Dashboard_Overview_LastRun_Never
Expand Down Expand Up @@ -132,6 +136,7 @@ fun DescriptorScreen(
if (descriptor.source is Descriptor.Source.Installed) {
ConfigureUpdates(onEvent, descriptor.source.value.autoUpdate)
}

Text(
stringResource(Res.string.AddDescriptor_Settings),
style = MaterialTheme.typography.titleMedium,
Expand All @@ -140,6 +145,32 @@ fun DescriptorScreen(
.padding(bottom = 16.dp),
)

if (!state.isAutoRunEnabled) {
Surface(
color = MaterialTheme.colorScheme.surfaceVariant,
shape = RoundedCornerShape(4.dp),
modifier = Modifier.padding(horizontal = 16.dp).padding(bottom = 8.dp),
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp),
) {
Text(
text = stringResource(Res.string.AddDescriptor_AutoRunDisabled),
style = MaterialTheme.typography.labelLarge,
modifier = Modifier.weight(1f).padding(end = 8.dp),
)
TextButton(
onClick = { onEvent(DescriptorViewModel.Event.EnableAutoRunClicked) },
) {
Text(stringResource(Res.string.Common_Enable))
}
}
}
}

Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
Expand All @@ -148,19 +179,27 @@ fun DescriptorScreen(
state = state.allState,
onClick = { onEvent(DescriptorViewModel.Event.AllChecked) },
role = Role.Checkbox,
enabled = state.isAutoRunEnabled,
)
.padding(horizontal = 8.dp, vertical = 12.dp),
) {
TriStateCheckbox(
state = state.allState,
onClick = null,
modifier = Modifier.padding(start = 16.dp, end = 24.dp),
enabled = state.isAutoRunEnabled,
)
Text(stringResource(Res.string.AddDescriptor_AutoRun))
}

when (OrganizationConfig.testDisplayMode) {
TestDisplayMode.Regular -> TestItems(descriptor, state.tests, onEvent)
TestDisplayMode.Regular -> TestItems(
descriptor,
state.tests,
state.isAutoRunEnabled,
onEvent,
)

TestDisplayMode.WebsitesOnly -> WebsiteItems(state.tests)
}

Expand Down Expand Up @@ -286,6 +325,7 @@ private fun DescriptorDetails(
private fun TestItems(
descriptor: Descriptor,
tests: List<SelectableItem<NetTest>>,
enabled: Boolean,
onEvent: (DescriptorViewModel.Event) -> Unit,
) {
tests.forEach { netTestItem ->
Expand All @@ -299,13 +339,15 @@ private fun TestItems(
value = netTestItem.isSelected,
onValueChange = { onEvent(DescriptorViewModel.Event.TestChecked(test, it)) },
role = Role.Checkbox,
enabled = enabled,
)
.padding(horizontal = 16.dp)
.padding(vertical = 12.dp),
) {
Checkbox(
checked = netTestItem.isSelected,
onCheckedChange = null,
enabled = enabled,
)
Icon(
painterResource(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import org.ooni.probe.data.models.NetTest
import org.ooni.probe.data.models.ResultModel
import org.ooni.probe.data.models.SettingsKey
import org.ooni.probe.data.repositories.PreferenceRepository
import org.ooni.probe.shared.monitoring.Instrumentation
import org.ooni.probe.shared.monitoring.reportTransaction
import org.ooni.probe.ui.shared.SelectableItem
import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds
Expand Down Expand Up @@ -89,6 +91,15 @@ class DescriptorViewModel(
}
.launchIn(viewModelScope)

preferenceRepository
.getValueByKey(SettingsKey.AUTOMATED_TESTING_ENABLED)
.onEach { enabled ->
_state.update {
it.copy(isAutoRunEnabled = enabled == true)
}
}
.launchIn(viewModelScope)

getDescriptorLastResult(descriptorKey)
.onEach { lastResult ->
_state.update {
Expand Down Expand Up @@ -185,6 +196,13 @@ class DescriptorViewModel(
events.filterIsInstance<Event.ChooseWebsitesClicked>()
.onEach { goToChooseWebsites() }
.launchIn(viewModelScope)

events.filterIsInstance<Event.EnableAutoRunClicked>()
.onEach {
preferenceRepository.setValueByKey(SettingsKey.AUTOMATED_TESTING_ENABLED, true)
Instrumentation.reportTransaction("DescriptorEnableAutoRun")
}
.launchIn(viewModelScope)
}

fun onEvent(event: Event) {
Expand Down Expand Up @@ -218,6 +236,7 @@ class DescriptorViewModel(
val tests: List<SelectableItem<NetTest>> = emptyList(),
val lastResult: ResultModel? = null,
val updateOperationState: DescriptorUpdateOperationState = DescriptorUpdateOperationState.Idle,
val isAutoRunEnabled: Boolean = true,
) {
val isRefreshing: Boolean
get() = updateOperationState == DescriptorUpdateOperationState.FetchingUpdates
Expand Down Expand Up @@ -251,5 +270,7 @@ class DescriptorViewModel(
data object UpdateDescriptor : Event

data object ChooseWebsitesClicked : Event

data object EnableAutoRunClicked : Event
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ class CheckAutoRunConstraintsTest {
)
}

assertCheck(expected = false, count = 20)
assertCheck(expected = true, count = 5)
assertCheck(expected = false, count = CheckAutoRunConstraints.NOT_UPLOADED_LIMIT + 1L)
assertCheck(expected = true, count = CheckAutoRunConstraints.NOT_UPLOADED_LIMIT - 1L)
}

@Test
Expand Down
Loading