diff --git a/app/src/main/kotlin/org/fdroid/repo/RepoUpdateManager.kt b/app/src/main/kotlin/org/fdroid/repo/RepoUpdateManager.kt
index d03434b15..6ed95fc5b 100644
--- a/app/src/main/kotlin/org/fdroid/repo/RepoUpdateManager.kt
+++ b/app/src/main/kotlin/org/fdroid/repo/RepoUpdateManager.kt
@@ -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.
*
diff --git a/app/src/main/kotlin/org/fdroid/repo/RepoUpdateWorker.kt b/app/src/main/kotlin/org/fdroid/repo/RepoUpdateWorker.kt
index 792dd4fa8..b56f1c757 100644
--- a/app/src/main/kotlin/org/fdroid/repo/RepoUpdateWorker.kt
+++ b/app/src/main/kotlin/org/fdroid/repo/RepoUpdateWorker.kt
@@ -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) {
diff --git a/app/src/main/kotlin/org/fdroid/settings/SettingsConstants.kt b/app/src/main/kotlin/org/fdroid/settings/SettingsConstants.kt
index 51e4a0ee0..a38fd0cfe 100644
--- a/app/src/main/kotlin/org/fdroid/settings/SettingsConstants.kt
+++ b/app/src/main/kotlin/org/fdroid/settings/SettingsConstants.kt
@@ -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"
diff --git a/app/src/main/kotlin/org/fdroid/ui/settings/Settings.kt b/app/src/main/kotlin/org/fdroid/ui/settings/Settings.kt
index b0297444f..20ec99e3b 100644
--- a/app/src/main/kotlin/org/fdroid/ui/settings/Settings.kt
+++ b/app/src/main/kotlin/org/fdroid/ui/settings/Settings.kt
@@ -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)
}
)
diff --git a/app/src/main/kotlin/org/fdroid/updates/AppUpdateWorker.kt b/app/src/main/kotlin/org/fdroid/updates/AppUpdateWorker.kt
index ae34db7ae..42892c5f0 100644
--- a/app/src/main/kotlin/org/fdroid/updates/AppUpdateWorker.kt
+++ b/app/src/main/kotlin/org/fdroid/updates/AppUpdateWorker.kt
@@ -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) {
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 0570b9a1e..d97d5379b 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -182,6 +182,7 @@
Open system language settings
Only on Wi-Fi
Always (even on mobile data)
+ Only when opening the app
Never
Download and update apps daily when on Wi-Fi and the device isn\'t being used
Download and update apps daily even on mobile data when the device isn\'t being used
@@ -189,6 +190,7 @@
Check for updates
Periodically fetch app updates from repositories only when on Wi-Fi
Periodically fetch app updates from repositories even when on mobile data
+ Check for updates only when opened • Apps will become outdated
Don\'t check for updates • Apps will become outdated
Network
Download mirror selection
diff --git a/app/src/test/java/org/fdroid/repo/RepoUpdateManagerTest.kt b/app/src/test/java/org/fdroid/repo/RepoUpdateManagerTest.kt
index b59469dbe..ca40f229b 100644
--- a/app/src/test/java/org/fdroid/repo/RepoUpdateManagerTest.kt
+++ b/app/src/test/java/org/fdroid/repo/RepoUpdateManagerTest.kt
@@ -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].