Add setting to only update repos when app is opened

if enabled, this auto updates repos, when user opens app and if last check was more than 12h ago
This commit is contained in:
Torsten Grote
2026-05-15 15:06:13 -03:00
parent 7b59f28fbf
commit 9ccc81b96d
7 changed files with 62 additions and 14 deletions

View File

@@ -23,10 +23,12 @@ import org.fdroid.download.DownloaderFactory
import org.fdroid.index.IndexUpdateResult
import org.fdroid.index.RepoManager
import org.fdroid.index.RepoUpdater
import org.fdroid.settings.SettingsConstants
import org.fdroid.settings.SettingsManager
import org.fdroid.updates.UpdatesManager
private const val MIN_UPDATE_INTERVAL_MILLIS = 15_000
private const val MAX_UPDATE_INTERVAL_MILLIS = 12 * 60 * 60 * 1000L // 12 hours
@Singleton
class RepoUpdateManager
@@ -87,6 +89,17 @@ internal constructor(
workInfo?.nextScheduleTimeMillis ?: Long.MAX_VALUE
}
init {
log.info { "RepoUpdateManager initialized" }
if (settingsManager.repoUpdates == SettingsConstants.AutoUpdateValues.OnlyWhenOpenApp) {
val now = System.currentTimeMillis()
if (now - settingsManager.lastRepoUpdate > MAX_UPDATE_INTERVAL_MILLIS) {
log.info { "Last repo update was more than 12h ago, triggering update..." }
RepoUpdateWorker.updateNow(context)
}
}
}
/**
* Updates all enabled repositories.
*

View File

@@ -74,7 +74,7 @@ constructor(
@JvmStatic
fun scheduleOrCancel(context: Context, autoUpdate: AutoUpdateValues) {
val workManager = WorkManager.getInstance(context)
if (autoUpdate != AutoUpdateValues.Never) {
if (autoUpdate.workerEnabled) {
Log.i(TAG, "scheduleOrCancel: enqueueUniquePeriodicWork")
val networkType =
if (autoUpdate == AutoUpdateValues.Always) {

View File

@@ -17,10 +17,11 @@ object SettingsConstants {
const val PREF_KEY_DYNAMIC_COLORS = "dynamicColors"
const val PREF_DEFAULT_DYNAMIC_COLORS = false
enum class AutoUpdateValues {
OnlyWifi,
Always,
Never,
enum class AutoUpdateValues(val workerEnabled: Boolean) {
OnlyWifi(true),
Always(true),
OnlyWhenOpenApp(false),
Never(false),
}
const val PREF_KEY_REPO_UPDATES = "repoAutoUpdates"

View File

@@ -59,6 +59,7 @@ import org.fdroid.R
import org.fdroid.settings.SettingsConstants.AutoUpdateValues
import org.fdroid.settings.SettingsConstants.AutoUpdateValues.Always
import org.fdroid.settings.SettingsConstants.AutoUpdateValues.Never
import org.fdroid.settings.SettingsConstants.AutoUpdateValues.OnlyWhenOpenApp
import org.fdroid.settings.SettingsConstants.AutoUpdateValues.OnlyWifi
import org.fdroid.settings.SettingsConstants.MirrorChooserValues
import org.fdroid.settings.SettingsConstants.PREF_DEFAULT_AUTO_UPDATES
@@ -214,7 +215,8 @@ fun Settings(model: SettingsModel, onSaveLogcat: (Uri?) -> Unit, onBackClicked:
)
},
summary = { strValue ->
if (strValue != Never.name) {
val value = strValue.toAutoUpdateValue()
if (value.workerEnabled) {
val nextUpdate = model.nextRepoUpdateFlow.collectAsState(Long.MAX_VALUE).value
val nextUpdateStr =
if (nextUpdate == Long.MAX_VALUE) {
@@ -228,17 +230,20 @@ fun Settings(model: SettingsModel, onSaveLogcat: (Uri?) -> Unit, onBackClicked:
stringResource(R.string.auto_update_time, nextUpdate.asRelativeTimeString())
}
val s =
if (strValue == OnlyWifi.name) {
if (value == OnlyWifi) {
stringResource(R.string.pref_repo_updates_summary_only_wifi)
} else if (strValue == Always.name) {
} else if (value == Always) {
stringResource(R.string.pref_repo_updates_summary_always)
} else error("Unknown value: $strValue")
Text(s + "\n" + nextUpdateStr)
} else {
Text(
text = stringResource(R.string.pref_repo_updates_summary_never),
color = MaterialTheme.colorScheme.error,
)
val s =
if (value == OnlyWhenOpenApp) {
stringResource(R.string.pref_repo_updates_summary_only_when_open_app)
} else {
stringResource(R.string.pref_repo_updates_summary_never)
}
Text(text = s, color = MaterialTheme.colorScheme.error)
}
},
values = AutoUpdateValues.entries.map { it.name },
@@ -247,6 +252,7 @@ fun Settings(model: SettingsModel, onSaveLogcat: (Uri?) -> Unit, onBackClicked:
when (value.toAutoUpdateValue()) {
OnlyWifi -> res.getString(R.string.pref_auto_updates_only_wifi)
Always -> res.getString(R.string.pref_auto_updates_only_always)
OnlyWhenOpenApp -> res.getString(R.string.pref_auto_updates_only_only_when_open_app)
Never -> res.getString(R.string.pref_auto_updates_only_never)
}
)
@@ -295,12 +301,15 @@ fun Settings(model: SettingsModel, onSaveLogcat: (Uri?) -> Unit, onBackClicked:
}
Text(s)
},
values = AutoUpdateValues.entries.map { it.name },
// Exclude the OnlyWhenOpenApp option here
values =
AutoUpdateValues.entries.mapNotNull { if (it == OnlyWhenOpenApp) null else it.name },
valueToText = { value: String ->
AnnotatedString(
when (value.toAutoUpdateValue()) {
OnlyWifi -> res.getString(R.string.pref_auto_updates_only_wifi)
Always -> res.getString(R.string.pref_auto_updates_only_always)
OnlyWhenOpenApp -> res.getString(R.string.pref_auto_updates_only_only_when_open_app)
Never -> res.getString(R.string.pref_auto_updates_only_never)
}
)

View File

@@ -49,7 +49,7 @@ constructor(
@JvmStatic
fun scheduleOrCancel(context: Context, autoUpdate: AutoUpdateValues) {
val workManager = WorkManager.getInstance(context)
if (autoUpdate != AutoUpdateValues.Never) {
if (autoUpdate.workerEnabled) {
Log.i(TAG, "scheduleOrCancel: enqueueUniquePeriodicWork")
val networkType =
if (autoUpdate == AutoUpdateValues.Always) {

View File

@@ -182,6 +182,7 @@
<string name="pref_language_summary">Open system language settings</string>
<string name="pref_auto_updates_only_wifi">Only on Wi-Fi</string>
<string name="pref_auto_updates_only_always">Always (even on mobile data)</string>
<string name="pref_auto_updates_only_only_when_open_app">Only when opening the app</string>
<string name="pref_auto_updates_only_never">Never</string>
<string name="pref_auto_updates_summary_only_wifi">Download and update apps daily when on Wi-Fi and the device isn\'t being used</string>
<string name="pref_auto_updates_summary_always">Download and update apps daily even on mobile data when the device isn\'t being used</string>
@@ -189,6 +190,7 @@
<string name="pref_repo_updates_title">Check for updates</string>
<string name="pref_repo_updates_summary_only_wifi">Periodically fetch app updates from repositories only when on Wi-Fi</string>
<string name="pref_repo_updates_summary_always">Periodically fetch app updates from repositories even when on mobile data</string>
<string name="pref_repo_updates_summary_only_when_open_app">Check for updates only when opened • Apps will become outdated</string>
<string name="pref_repo_updates_summary_never">Don\'t check for updates • Apps will become outdated</string>
<string name="pref_category_network">Network</string>
<string name="pref_mirror_chooser_title">Download mirror selection</string>

View File

@@ -29,6 +29,7 @@ import org.fdroid.index.IndexUpdateResult
import org.fdroid.index.RepoManager
import org.fdroid.index.RepoUpdater
import org.fdroid.install.InstalledAppsCache
import org.fdroid.settings.SettingsConstants
import org.fdroid.settings.SettingsManager
import org.fdroid.updates.AppUpdateWorker
import org.fdroid.updates.UpdatesManager
@@ -57,6 +58,7 @@ internal class RepoUpdateManagerTest {
every { db.getRepositoryDao() } returns repositoryDao
every { context.getString(any(), any()) } returns "repo update"
every { settingsManager.isFirstStart } returns false
every { settingsManager.repoUpdates } returns SettingsConstants.AutoUpdateValues.OnlyWifi
every { installedAppsCache.installedApps } returns MutableStateFlow(emptyMap())
}
@@ -324,6 +326,27 @@ internal class RepoUpdateManagerTest {
}
}
@Test
fun `triggers updateNow on init when OnlyWhenOpenApp and last update is stale`() {
every { settingsManager.repoUpdates } returns SettingsConstants.AutoUpdateValues.OnlyWhenOpenApp
every { settingsManager.lastRepoUpdate } returns 0L
every { RepoUpdateWorker.updateNow(any()) } just runs
RepoUpdateManager(
context = context,
db = db,
repoManager = repoManager,
updatesManager = updatesManager,
settingsManager = settingsManager,
downloaderFactory = mockk(relaxed = true),
notificationManager = notificationManager,
compatibilityChecker = compatibilityChecker,
repoUpdater = repoUpdater,
)
verify(exactly = 1) { RepoUpdateWorker.updateNow(context) }
}
/**
* Workaround for [verify] calls trying to take installedAppsCache into account for
* [UpdatesManager.loadUpdates].