diff --git a/app/src/main/java/org/wikipedia/activity/BaseActivity.kt b/app/src/main/java/org/wikipedia/activity/BaseActivity.kt index a0dc35c0776..a91dbcfd684 100644 --- a/app/src/main/java/org/wikipedia/activity/BaseActivity.kt +++ b/app/src/main/java/org/wikipedia/activity/BaseActivity.kt @@ -97,7 +97,7 @@ abstract class BaseActivity : AppCompatActivity(), ConnectionStateMonitor.Callba supportActionBar?.setDisplayHomeAsUpEnabled(true) // Conditionally execute all recurring tasks - RecurringTasksExecutor().run() + RecurringTasksExecutor.schedule() if (Prefs.isReadingListsFirstTimeSync && AccountUtil.isLoggedIn) { Prefs.isReadingListsFirstTimeSync = false Prefs.isReadingListSyncEnabled = true diff --git a/app/src/main/java/org/wikipedia/alphaupdater/AlphaUpdateChecker.kt b/app/src/main/java/org/wikipedia/alphaupdater/AlphaUpdateChecker.kt deleted file mode 100644 index 1c8252d32d6..00000000000 --- a/app/src/main/java/org/wikipedia/alphaupdater/AlphaUpdateChecker.kt +++ /dev/null @@ -1,76 +0,0 @@ -package org.wikipedia.alphaupdater - -import android.Manifest -import android.content.Context -import android.content.Intent -import android.content.pm.PackageManager -import android.net.Uri -import androidx.core.app.NotificationCompat -import androidx.core.app.NotificationManagerCompat -import androidx.core.app.PendingIntentCompat -import androidx.core.content.ContextCompat -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import okhttp3.Request -import org.wikipedia.dataclient.okhttp.OkHttpConnectionFactory -import org.wikipedia.notifications.NotificationCategory -import org.wikipedia.recurring.RecurringTask -import org.wikipedia.settings.PrefsIoUtil -import java.io.IOException -import java.util.Date -import java.util.concurrent.TimeUnit - -class AlphaUpdateChecker(private val context: Context) : RecurringTask() { - override val name = "alpha-update-checker" - - override fun shouldRun(lastRun: Date): Boolean { - return System.currentTimeMillis() - lastRun.time >= RUN_INTERVAL_MILLI - } - - override suspend fun run(lastRun: Date) { - // Check for updates! - var hashString: String? = null - withContext(Dispatchers.IO) { - try { - val request: Request = Request.Builder().url(ALPHA_BUILD_DATA_URL).build() - OkHttpConnectionFactory.client.newCall(request).execute().use { - hashString = it.body?.string() - } - } catch (e: IOException) { - // It's ok, we can do nothing. - } - } - hashString?.let { - if (PrefsIoUtil.getString(PREFERENCE_KEY_ALPHA_COMMIT, "") != it) { - showNotification() - } - PrefsIoUtil.setString(PREFERENCE_KEY_ALPHA_COMMIT, it) - } - } - - private fun showNotification() { - if (ContextCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { - return - } - val intent = Intent(Intent.ACTION_VIEW, Uri.parse(ALPHA_BUILD_APK_URL)) - val pendingIntent = PendingIntentCompat.getActivity(context, 0, intent, 0, false) - - val notificationManagerCompat = NotificationManagerCompat.from(context) - val notificationCategory = NotificationCategory.ALPHA_BUILD_CHECKER - - val notificationBuilder = NotificationCompat.Builder(context, notificationCategory.id) - .setContentTitle(context.getString(notificationCategory.title)) - .setContentText(context.getString(notificationCategory.description)) - .setContentIntent(pendingIntent) - .setAutoCancel(true) - notificationBuilder.setSmallIcon(notificationCategory.iconResId) - notificationManagerCompat.notify(1, notificationBuilder.build()) - } - - companion object { - private val RUN_INTERVAL_MILLI = TimeUnit.DAYS.toMillis(1) - private const val PREFERENCE_KEY_ALPHA_COMMIT = "alpha_last_checked_commit" - private const val ALPHA_BUILD_APK_URL = "https://github.com/wikimedia/apps-android-wikipedia/releases/download/latest/app-alpha-universal-release.apk" - private const val ALPHA_BUILD_DATA_URL = "https://github.com/wikimedia/apps-android-wikipedia/releases/download/latest/rev-hash.txt" - } -} diff --git a/app/src/main/java/org/wikipedia/alphaupdater/AlphaUpdateWorker.kt b/app/src/main/java/org/wikipedia/alphaupdater/AlphaUpdateWorker.kt new file mode 100644 index 00000000000..0083d30520a --- /dev/null +++ b/app/src/main/java/org/wikipedia/alphaupdater/AlphaUpdateWorker.kt @@ -0,0 +1,71 @@ +package org.wikipedia.alphaupdater + +import android.Manifest +import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager +import android.net.Uri +import androidx.core.app.NotificationCompat +import androidx.core.app.NotificationManagerCompat +import androidx.core.app.PendingIntentCompat +import androidx.core.content.ContextCompat +import androidx.work.CoroutineWorker +import androidx.work.WorkerParameters +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import okhttp3.Request +import okio.IOException +import org.wikipedia.dataclient.okhttp.OkHttpConnectionFactory.client +import org.wikipedia.notifications.NotificationCategory +import org.wikipedia.settings.PrefsIoUtil + +class AlphaUpdateWorker( + appContext: Context, + params: WorkerParameters +) : CoroutineWorker(appContext, params) { + override suspend fun doWork(): Result { + val hashString = withContext(Dispatchers.IO) { + val request = Request.Builder().url(ALPHA_BUILD_DATA_URL).build() + try { + client.newCall(request).execute().body!!.use { it.string() } + } catch (e: IOException) { + // It's ok, we can do nothing. + null + } + } + if (hashString == null) { + return Result.failure() + } + if (PrefsIoUtil.getString(PREFERENCE_KEY_ALPHA_COMMIT, "") != hashString) { + showNotification() + } + PrefsIoUtil.setString(PREFERENCE_KEY_ALPHA_COMMIT, hashString) + return Result.success() + } + + private fun showNotification() { + if (ContextCompat.checkSelfPermission(applicationContext, Manifest.permission.POST_NOTIFICATIONS) + != PackageManager.PERMISSION_GRANTED) { + return + } + val intent = Intent(Intent.ACTION_VIEW, Uri.parse(ALPHA_BUILD_APK_URL)) + val pendingIntent = PendingIntentCompat.getActivity(applicationContext, 0, intent, 0, false) + + val notificationManagerCompat = NotificationManagerCompat.from(applicationContext) + val notificationCategory = NotificationCategory.ALPHA_BUILD_CHECKER + + val notificationBuilder = NotificationCompat.Builder(applicationContext, notificationCategory.id) + .setContentTitle(applicationContext.getString(notificationCategory.title)) + .setContentText(applicationContext.getString(notificationCategory.description)) + .setContentIntent(pendingIntent) + .setAutoCancel(true) + notificationBuilder.setSmallIcon(notificationCategory.iconResId) + notificationManagerCompat.notify(1, notificationBuilder.build()) + } + + companion object { + private const val PREFERENCE_KEY_ALPHA_COMMIT = "alpha_last_checked_commit" + private const val ALPHA_BUILD_APK_URL = "https://github.com/wikimedia/apps-android-wikipedia/releases/download/latest/app-alpha-universal-release.apk" + private const val ALPHA_BUILD_DATA_URL = "https://github.com/wikimedia/apps-android-wikipedia/releases/download/latest/rev-hash.txt" + } +} diff --git a/app/src/main/java/org/wikipedia/notifications/PollNotificationWorker.kt b/app/src/main/java/org/wikipedia/notifications/PollNotificationWorker.kt index 108a70e75a8..d957d7a8839 100644 --- a/app/src/main/java/org/wikipedia/notifications/PollNotificationWorker.kt +++ b/app/src/main/java/org/wikipedia/notifications/PollNotificationWorker.kt @@ -61,11 +61,8 @@ class PollNotificationWorker( companion object { fun schedulePollNotificationJob(context: Context) { - val constraints = Constraints.Builder() - .setRequiredNetworkType(NetworkType.CONNECTED) - .build() val workRequest = OneTimeWorkRequestBuilder() - .setConstraints(constraints) + .setConstraints(Constraints(NetworkType.CONNECTED)) .build() WorkManager.getInstance(context).enqueue(workRequest) } diff --git a/app/src/main/java/org/wikipedia/recurring/CategoriesTableCleanupTask.kt b/app/src/main/java/org/wikipedia/recurring/CategoriesTableCleanupTask.kt deleted file mode 100644 index dfa81038b65..00000000000 --- a/app/src/main/java/org/wikipedia/recurring/CategoriesTableCleanupTask.kt +++ /dev/null @@ -1,26 +0,0 @@ -package org.wikipedia.recurring - -import org.wikipedia.database.AppDatabase -import org.wikipedia.util.log.L -import java.time.LocalDateTime -import java.util.Date -import java.util.concurrent.TimeUnit - -class CategoriesTableCleanupTask : RecurringTask() { - override val name = "categoriesTableCleanupTask" - - override fun shouldRun(lastRun: Date): Boolean { - return millisSinceLastRun(lastRun) >= TimeUnit.DAYS.toMillis(DAYS_BETWEEN_RUNS) - } - - override suspend fun run(lastRun: Date) { - val twoYearsAgoTimeStamp = LocalDateTime.now().year - CLEANUP_TIME_IN_YEARS - AppDatabase.instance.categoryDao().deleteOlderThan(twoYearsAgoTimeStamp) - L.d("Successfully deleted Category data older than $CLEANUP_TIME_IN_YEARS years") - } - - companion object { - private const val CLEANUP_TIME_IN_YEARS = 2 - private const val DAYS_BETWEEN_RUNS = (365L / 2L) - } -} diff --git a/app/src/main/java/org/wikipedia/recurring/CategoriesTableCleanupWorker.kt b/app/src/main/java/org/wikipedia/recurring/CategoriesTableCleanupWorker.kt new file mode 100644 index 00000000000..4debcfa5370 --- /dev/null +++ b/app/src/main/java/org/wikipedia/recurring/CategoriesTableCleanupWorker.kt @@ -0,0 +1,24 @@ +package org.wikipedia.recurring + +import android.content.Context +import androidx.work.CoroutineWorker +import androidx.work.WorkerParameters +import org.wikipedia.database.AppDatabase +import org.wikipedia.util.log.L +import java.time.LocalDate + +class CategoriesTableCleanupWorker( + appContext: Context, + workerParams: WorkerParameters +) : CoroutineWorker(appContext, workerParams) { + override suspend fun doWork(): Result { + val twoYearsAgoTimeStamp = LocalDate.now().year - CLEANUP_TIME_IN_YEARS + AppDatabase.instance.categoryDao().deleteOlderThan(twoYearsAgoTimeStamp) + L.d("Successfully deleted Category data older than $CLEANUP_TIME_IN_YEARS years") + return Result.success() + } + + companion object { + const val CLEANUP_TIME_IN_YEARS = 2 + } +} diff --git a/app/src/main/java/org/wikipedia/recurring/DailyEventTask.kt b/app/src/main/java/org/wikipedia/recurring/DailyEventTask.kt deleted file mode 100644 index efbb4dd7da8..00000000000 --- a/app/src/main/java/org/wikipedia/recurring/DailyEventTask.kt +++ /dev/null @@ -1,23 +0,0 @@ -package org.wikipedia.recurring - -import org.wikipedia.R -import org.wikipedia.WikipediaApp -import org.wikipedia.analytics.eventplatform.DailyStatsEvent -import org.wikipedia.analytics.eventplatform.EventPlatformClient -import org.wikipedia.analytics.eventplatform.RecommendedReadingListEvent -import java.util.Date -import java.util.concurrent.TimeUnit - -class DailyEventTask(private val app: WikipediaApp) : RecurringTask() { - override val name = app.getString(R.string.preference_key_daily_event_time_task_name) - - override fun shouldRun(lastRun: Date): Boolean { - return millisSinceLastRun(lastRun) > TimeUnit.DAYS.toMillis(1) - } - - override suspend fun run(lastRun: Date) { - DailyStatsEvent.log(app) - EventPlatformClient.refreshStreamConfigs() - RecommendedReadingListEvent.submit("launch", "rrl_launch") - } -} diff --git a/app/src/main/java/org/wikipedia/recurring/DailyEventWorker.kt b/app/src/main/java/org/wikipedia/recurring/DailyEventWorker.kt new file mode 100644 index 00000000000..c111d1494f7 --- /dev/null +++ b/app/src/main/java/org/wikipedia/recurring/DailyEventWorker.kt @@ -0,0 +1,19 @@ +package org.wikipedia.recurring + +import android.content.Context +import androidx.work.CoroutineWorker +import androidx.work.WorkerParameters +import org.wikipedia.WikipediaApp +import org.wikipedia.analytics.eventplatform.DailyStatsEvent +import org.wikipedia.analytics.eventplatform.EventPlatformClient + +class DailyEventWorker( + appContext: Context, + params: WorkerParameters +) : CoroutineWorker(appContext, params) { + override suspend fun doWork(): Result { + DailyStatsEvent.log(WikipediaApp.instance) + EventPlatformClient.refreshStreamConfigs() + return Result.success() + } +} diff --git a/app/src/main/java/org/wikipedia/recurring/RecommendedReadingListTask.kt b/app/src/main/java/org/wikipedia/recurring/RecommendedReadingListWorker.kt similarity index 51% rename from app/src/main/java/org/wikipedia/recurring/RecommendedReadingListTask.kt rename to app/src/main/java/org/wikipedia/recurring/RecommendedReadingListWorker.kt index 1446b53ba21..1857e3bdc7b 100644 --- a/app/src/main/java/org/wikipedia/recurring/RecommendedReadingListTask.kt +++ b/app/src/main/java/org/wikipedia/recurring/RecommendedReadingListWorker.kt @@ -1,29 +1,29 @@ package org.wikipedia.recurring +import android.content.Context +import androidx.work.CoroutineWorker +import androidx.work.WorkerParameters import org.wikipedia.readinglist.recommended.RecommendedReadingListHelper import org.wikipedia.readinglist.recommended.RecommendedReadingListUpdateFrequency import org.wikipedia.settings.Prefs +import java.time.DayOfWeek import java.time.LocalDate -import java.util.Date -import java.util.concurrent.TimeUnit -class RecommendedReadingListTask() : RecurringTask() { - override val name = "generateRecommendedReadingListTask" - - override fun shouldRun(lastRun: Date): Boolean { - if (millisSinceLastRun(lastRun) < TimeUnit.DAYS.toMillis(1)) { - return false - } +class RecommendedReadingListWorker( + appContext: Context, + workerParams: WorkerParameters, +) : CoroutineWorker(appContext, workerParams) { + override suspend fun doWork(): Result { // And run either every day, or on the first day of the week or month val now = LocalDate.now() - return when (Prefs.recommendedReadingListUpdateFrequency) { + val shouldRun = when (Prefs.recommendedReadingListUpdateFrequency) { RecommendedReadingListUpdateFrequency.DAILY -> true - RecommendedReadingListUpdateFrequency.WEEKLY -> now.dayOfWeek.value == 1 + RecommendedReadingListUpdateFrequency.WEEKLY -> now.dayOfWeek == DayOfWeek.MONDAY RecommendedReadingListUpdateFrequency.MONTHLY -> now.dayOfMonth == 1 } - } - - override suspend fun run(lastRun: Date) { - RecommendedReadingListHelper.generateRecommendedReadingList(true) + if (shouldRun) { + RecommendedReadingListHelper.generateRecommendedReadingList(true) + } + return Result.success() } } diff --git a/app/src/main/java/org/wikipedia/recurring/RecurringTask.kt b/app/src/main/java/org/wikipedia/recurring/RecurringTask.kt deleted file mode 100644 index 93583d32186..00000000000 --- a/app/src/main/java/org/wikipedia/recurring/RecurringTask.kt +++ /dev/null @@ -1,45 +0,0 @@ -package org.wikipedia.recurring - -import org.wikipedia.settings.Prefs -import org.wikipedia.util.log.L -import java.util.Date -import kotlin.math.max -import kotlin.math.min - -/** - * Represents a task that needs to be run periodically. - * - * Usually an expensive task, that is run Async. Do not do anything - * that requires access to the UI thread on these tasks. - * - * Since it is an expensive task, there's a separate method that detects - * if the task should be run or not, and then runs it if necessary. The - * last run times are tracked automatically by the base class. - */ -abstract class RecurringTask { - suspend fun runIfNecessary() { - val lastRunDate = lastRunDate - val lastExecutionLog = "$name. Last execution was $lastRunDate." - if (shouldRun(lastRunDate)) { - L.d("Executing recurring task, $lastExecutionLog") - run(lastRunDate) - Prefs.setLastRunTime(name, absoluteTime) - } else { - L.d("Skipping recurring task, $lastExecutionLog") - } - } - - protected abstract fun shouldRun(lastRun: Date): Boolean - protected abstract suspend fun run(lastRun: Date) - - protected abstract val name: String - - protected val absoluteTime: Long - get() = System.currentTimeMillis() - private val lastRunDate: Date - get() = Date(Prefs.getLastRunTime(name)) - - protected fun millisSinceLastRun(lastRun: Date): Long { - return min(Long.MAX_VALUE, max(0, absoluteTime - lastRun.time)) - } -} diff --git a/app/src/main/java/org/wikipedia/recurring/RecurringTasksExecutor.kt b/app/src/main/java/org/wikipedia/recurring/RecurringTasksExecutor.kt index 30693ddaf2a..ed915f5cbf5 100644 --- a/app/src/main/java/org/wikipedia/recurring/RecurringTasksExecutor.kt +++ b/app/src/main/java/org/wikipedia/recurring/RecurringTasksExecutor.kt @@ -1,28 +1,69 @@ package org.wikipedia.recurring -import kotlinx.coroutines.CoroutineExceptionHandler -import kotlinx.coroutines.MainScope -import kotlinx.coroutines.launch +import androidx.work.Constraints +import androidx.work.ExistingPeriodicWorkPolicy +import androidx.work.NetworkType +import androidx.work.PeriodicWorkRequestBuilder +import androidx.work.WorkManager +import org.wikipedia.R import org.wikipedia.WikipediaApp -import org.wikipedia.alphaupdater.AlphaUpdateChecker -import org.wikipedia.settings.RemoteConfigRefreshTask +import org.wikipedia.alphaupdater.AlphaUpdateWorker +import org.wikipedia.settings.PrefsIoUtil +import org.wikipedia.settings.RemoteConfigRefreshWorker import org.wikipedia.util.ReleaseUtil -import org.wikipedia.util.log.L - -class RecurringTasksExecutor() { - fun run() { - val app = WikipediaApp.instance - MainScope().launch(CoroutineExceptionHandler { _, throwable -> - L.e(throwable) - }) { - RemoteConfigRefreshTask().runIfNecessary() - DailyEventTask(app).runIfNecessary() - TalkOfflineCleanupTask(app).runIfNecessary() - if (ReleaseUtil.isAlphaRelease) { - AlphaUpdateChecker(app).runIfNecessary() - } - CategoriesTableCleanupTask().runIfNecessary() - RecommendedReadingListTask().runIfNecessary() +import java.util.concurrent.TimeUnit + +object RecurringTasksExecutor { + fun schedule() { + // Clean up now-unused task time values, as WorkManager handles scheduling + PrefsIoUtil.remove("alpha-update-checker") + PrefsIoUtil.remove("remote-config-refresher") + PrefsIoUtil.remove(R.string.preference_key_talk_offline_cleanup_task_name) + PrefsIoUtil.remove(R.string.preference_key_daily_event_time_task_name) + + val networkConstraints = Constraints( + requiredNetworkType = NetworkType.CONNECTED, + requiresBatteryNotLow = true + ) + + val remoteConfigRefreshRequest = PeriodicWorkRequestBuilder(1, TimeUnit.DAYS) + .setConstraints(networkConstraints) + .build() + + val dailyEventRequest = PeriodicWorkRequestBuilder(1, TimeUnit.DAYS) + .setConstraints(networkConstraints) + .build() + + val offlineCleanupRequest = PeriodicWorkRequestBuilder(7, TimeUnit.DAYS) + .setConstraints(Constraints(requiresBatteryNotLow = true)) + .build() + + val cleanupInterval = 365L * CategoriesTableCleanupWorker.CLEANUP_TIME_IN_YEARS + val categoriesCleanupRequest = PeriodicWorkRequestBuilder(cleanupInterval, TimeUnit.DAYS) + .setConstraints(Constraints(requiresBatteryNotLow = true)) + .build() + + val recommendedReadingListRequest = PeriodicWorkRequestBuilder(1, TimeUnit.DAYS) + .setConstraints(networkConstraints) + .build() + + val tasks = mutableMapOf( + "REMOTE_CONFIG" to remoteConfigRefreshRequest, + "DAILY_EVENT" to dailyEventRequest, + "OFFLINE_CLEANUP" to offlineCleanupRequest, + "CATEGORIES_CLEANUP" to categoriesCleanupRequest, + "RECOMMENDED_READING" to recommendedReadingListRequest + ) + + if (ReleaseUtil.isAlphaRelease) { + tasks["ALPHA_UPDATE"] = PeriodicWorkRequestBuilder(1, TimeUnit.DAYS) + .setConstraints(networkConstraints) + .build() + } + + val workManager = WorkManager.getInstance(WikipediaApp.instance) + tasks.forEach { (taskName, task) -> + workManager.enqueueUniquePeriodicWork(taskName, ExistingPeriodicWorkPolicy.KEEP, task) } } } diff --git a/app/src/main/java/org/wikipedia/recurring/TalkOfflineCleanupTask.kt b/app/src/main/java/org/wikipedia/recurring/TalkOfflineCleanupWorker.kt similarity index 58% rename from app/src/main/java/org/wikipedia/recurring/TalkOfflineCleanupTask.kt rename to app/src/main/java/org/wikipedia/recurring/TalkOfflineCleanupWorker.kt index 9d7b3b1ee44..861d8cbfad1 100644 --- a/app/src/main/java/org/wikipedia/recurring/TalkOfflineCleanupTask.kt +++ b/app/src/main/java/org/wikipedia/recurring/TalkOfflineCleanupWorker.kt @@ -1,32 +1,32 @@ package org.wikipedia.recurring import android.content.Context +import androidx.work.CoroutineWorker +import androidx.work.WorkerParameters import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import org.wikipedia.R import org.wikipedia.database.AppDatabase import java.io.File -import java.util.Date -import java.util.concurrent.TimeUnit +import java.time.Instant +import java.time.temporal.ChronoUnit -class TalkOfflineCleanupTask(context: Context) : RecurringTask() { - override val name = context.getString(R.string.preference_key_talk_offline_cleanup_task_name) - - override fun shouldRun(lastRun: Date): Boolean { - return millisSinceLastRun(lastRun) > TimeUnit.DAYS.toMillis(CLEANUP_MAX_AGE_DAYS) - } - - override suspend fun run(lastRun: Date) { +class TalkOfflineCleanupWorker( + appContext: Context, + params: WorkerParameters +) : CoroutineWorker(appContext, params) { + override suspend fun doWork(): Result { withContext(Dispatchers.IO) { AppDatabase.instance.offlineObjectDao() .searchForOfflineObjects(CLEANUP_URL_SEARCH_KEY) .filter { - (absoluteTime - File(it.path + ".0").lastModified()) > TimeUnit.DAYS.toMillis(CLEANUP_MAX_AGE_DAYS) + val lastModified = Instant.ofEpochMilli(File("${it.path}.0").lastModified()) + ChronoUnit.DAYS.between(lastModified, Instant.now()) > CLEANUP_MAX_AGE_DAYS }.forEach { AppDatabase.instance.offlineObjectDao().deleteOfflineObject(it) AppDatabase.instance.offlineObjectDao().deleteFilesForObject(it) } } + return Result.success() } companion object { diff --git a/app/src/main/java/org/wikipedia/settings/RemoteConfigRefreshTask.kt b/app/src/main/java/org/wikipedia/settings/RemoteConfigRefreshTask.kt deleted file mode 100644 index 37e27d342d3..00000000000 --- a/app/src/main/java/org/wikipedia/settings/RemoteConfigRefreshTask.kt +++ /dev/null @@ -1,50 +0,0 @@ -package org.wikipedia.settings - -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import okhttp3.Request -import okhttp3.Response -import okhttp3.internal.closeQuietly -import org.wikipedia.WikipediaApp -import org.wikipedia.dataclient.ServiceFactory -import org.wikipedia.dataclient.okhttp.OkHttpConnectionFactory.client -import org.wikipedia.recurring.RecurringTask -import org.wikipedia.util.log.L -import java.util.Date -import java.util.concurrent.TimeUnit - -class RemoteConfigRefreshTask : RecurringTask() { - override val name = "remote-config-refresher" - - override fun shouldRun(lastRun: Date): Boolean { - return millisSinceLastRun(lastRun) >= TimeUnit.DAYS.toMillis(RUN_INTERVAL_DAYS) - } - - override suspend fun run(lastRun: Date) { - withContext(Dispatchers.IO) { - var response: Response? = null - try { - val request = Request.Builder().url(REMOTE_CONFIG_URL).build() - response = client.newCall(request).execute() - val configStr = response.body!!.string() - RemoteConfig.updateConfig(configStr) - L.d(configStr) - } catch (e: Exception) { - L.e(e) - } finally { - response?.closeQuietly() - } - - val userInfo = ServiceFactory.get(WikipediaApp.instance.wikiSite).getUserInfo() - // This clumsy comparison is necessary because the field is an integer value when enabled, but an empty string when disabled. - // Since we want the default to lean towards opt-in, we check very specifically for an empty string, to make sure the user has opted out. - val fundraisingOptOut = userInfo.query?.userInfo?.options?.fundraisingOptIn?.toString()?.replace("\"", "")?.isEmpty() - Prefs.donationBannerOptIn = fundraisingOptOut != true - } - } - - companion object { - private const val REMOTE_CONFIG_URL = "https://meta.wikimedia.org/w/extensions/MobileApp/config/android.json" - private const val RUN_INTERVAL_DAYS = 1L - } -} diff --git a/app/src/main/java/org/wikipedia/settings/RemoteConfigRefreshWorker.kt b/app/src/main/java/org/wikipedia/settings/RemoteConfigRefreshWorker.kt new file mode 100644 index 00000000000..16d3f2d1fd0 --- /dev/null +++ b/app/src/main/java/org/wikipedia/settings/RemoteConfigRefreshWorker.kt @@ -0,0 +1,47 @@ +package org.wikipedia.settings + +import android.content.Context +import androidx.work.CoroutineWorker +import androidx.work.WorkerParameters +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import okhttp3.Request +import okio.IOException +import org.wikipedia.WikipediaApp +import org.wikipedia.dataclient.ServiceFactory +import org.wikipedia.dataclient.okhttp.OkHttpConnectionFactory.client +import org.wikipedia.util.log.L + +class RemoteConfigRefreshWorker( + appContext: Context, + params: WorkerParameters +) : CoroutineWorker(appContext, params) { + override suspend fun doWork(): Result { + val configStr = withContext(Dispatchers.IO) { + val request = Request.Builder().url(REMOTE_CONFIG_URL).build() + try { + client.newCall(request).execute().body!!.use { it.string() } + } catch (e: IOException) { + L.e(e) + null + } + } + if (configStr == null) { + return Result.failure() + } + RemoteConfig.updateConfig(configStr) + L.d(configStr) + + val userInfo = ServiceFactory.get(WikipediaApp.instance.wikiSite).getUserInfo() + // This clumsy comparison is necessary because the field is an integer value when enabled, but an empty string when disabled. + // Since we want the default to lean towards opt-in, we check very specifically for an empty string, to make sure the user has opted out. + val fundraisingOptOut = userInfo.query?.userInfo?.options?.fundraisingOptIn?.toString()?.replace("\"", "")?.isEmpty() + Prefs.donationBannerOptIn = fundraisingOptOut != true + + return Result.success() + } + + companion object { + private const val REMOTE_CONFIG_URL = "https://meta.wikimedia.org/w/extensions/MobileApp/config/android.json" + } +}