diff options
author | ByteHamster <info@bytehamster.com> | 2023-11-05 08:27:34 +0100 |
---|---|---|
committer | ByteHamster <info@bytehamster.com> | 2023-11-05 08:27:34 +0100 |
commit | f7a13065a9c92ba26d3686aeb18269f2313bd0b6 (patch) | |
tree | f7f7a49aa65acc295cc99dc0e3e870a1f5f4130f /core | |
parent | 2c3fb5610a98d80db25b85fdf0607bfc2b6216fc (diff) | |
parent | 8d4270ab87d82dadccab177f6710637b28750c7a (diff) | |
download | AntennaPod-f7a13065a9c92ba26d3686aeb18269f2313bd0b6.zip |
Merge branch 'master' into develop
Diffstat (limited to 'core')
9 files changed, 152 insertions, 87 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java b/core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java index 52b2d61dc..d63fd50f2 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java +++ b/core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java @@ -28,6 +28,7 @@ import androidx.annotation.VisibleForTesting; import androidx.documentfile.provider.DocumentFile; import de.danoeh.antennapod.core.R; import de.danoeh.antennapod.core.util.FastDocumentFile; +import de.danoeh.antennapod.model.MediaMetadataRetrieverCompat; import de.danoeh.antennapod.model.download.DownloadResult; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBTasks; @@ -194,8 +195,8 @@ public class LocalFeedUpdater { return item; } - private static void loadMetadata(FeedItem item, FastDocumentFile file, Context context) throws IOException { - try (MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever()) { + private static void loadMetadata(FeedItem item, FastDocumentFile file, Context context) { + try (MediaMetadataRetrieverCompat mediaMetadataRetriever = new MediaMetadataRetrieverCompat()) { mediaMetadataRetriever.setDataSource(context, file.getUri()); String dateStr = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DATE); diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateWorker.java b/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateWorker.java index 2f763e78e..eea4d2082 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateWorker.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/FeedUpdateWorker.java @@ -4,13 +4,17 @@ import android.app.Notification; import android.content.Context; import android.util.Log; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationManagerCompat; +import androidx.work.ForegroundInfo; import androidx.work.WorkManager; import androidx.work.Worker; import androidx.work.WorkerParameters; import com.annimon.stream.Collectors; import com.annimon.stream.Stream; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; import de.danoeh.antennapod.core.ClientConfigurator; import de.danoeh.antennapod.core.R; import de.danoeh.antennapod.core.feed.LocalFeedUpdater; @@ -53,15 +57,10 @@ public class FeedUpdateWorker extends Worker { ClientConfigurator.initialize(getApplicationContext()); newEpisodesNotification.loadCountersBeforeRefresh(); - if (!getInputData().getBoolean(FeedUpdateManager.EXTRA_EVEN_ON_MOBILE, false)) { - if (!NetworkUtils.networkAvailable() || !NetworkUtils.isFeedRefreshAllowed()) { - Log.d(TAG, "Blocking automatic update: no wifi available / no mobile updates allowed"); - return Result.retry(); - } - } - List<Feed> toUpdate; long feedId = getInputData().getLong(FeedUpdateManager.EXTRA_FEED_ID, -1); + boolean allAreLocal = true; + boolean force = false; if (feedId == -1) { // Update all toUpdate = DBReader.getFeedList(); Iterator<Feed> itr = toUpdate.iterator(); @@ -70,29 +69,47 @@ public class FeedUpdateWorker extends Worker { if (!feed.getPreferences().getKeepUpdated()) { itr.remove(); } + if (!feed.isLocalFeed()) { + allAreLocal = false; + } } Collections.shuffle(toUpdate); // If the worker gets cancelled early, every feed has a chance to be updated - refreshFeeds(toUpdate, false); } else { - toUpdate = new ArrayList<>(); Feed feed = DBReader.getFeed(feedId); if (feed == null) { return Result.success(); } - toUpdate.add(feed); - refreshFeeds(toUpdate, true); + if (!feed.isLocalFeed()) { + allAreLocal = false; + } + toUpdate = new ArrayList<>(); + toUpdate.add(feed); // Needs to be updatable, so no singletonList + force = true; + } + + if (!getInputData().getBoolean(FeedUpdateManager.EXTRA_EVEN_ON_MOBILE, false) && !allAreLocal) { + if (!NetworkUtils.networkAvailable() || !NetworkUtils.isFeedRefreshAllowed()) { + Log.d(TAG, "Blocking automatic update"); + return Result.retry(); + } } + refreshFeeds(toUpdate, force); + notificationManager.cancel(R.id.notification_updating_feeds); DBTasks.autodownloadUndownloadedItems(getApplicationContext()); return Result.success(); } @NonNull - private Notification createNotification(List<Feed> toUpdate) { + private Notification createNotification(@Nullable List<Feed> toUpdate) { Context context = getApplicationContext(); - String contentText = context.getResources().getQuantityString(R.plurals.downloads_left, - toUpdate.size(), toUpdate.size()); - String bigText = Stream.of(toUpdate).map(feed -> "• " + feed.getTitle()).collect(Collectors.joining("\n")); + String contentText = ""; + String bigText = ""; + if (toUpdate != null) { + contentText = context.getResources().getQuantityString(R.plurals.downloads_left, + toUpdate.size(), toUpdate.size()); + bigText = Stream.of(toUpdate).map(feed -> "• " + feed.getTitle()).collect(Collectors.joining("\n")); + } return new NotificationCompat.Builder(context, NotificationUtils.CHANNEL_ID_DOWNLOADING) .setContentTitle(context.getString(R.string.download_notification_title_feeds)) .setContentText(contentText) @@ -104,6 +121,12 @@ public class FeedUpdateWorker extends Worker { .build(); } + @NonNull + @Override + public ListenableFuture<ForegroundInfo> getForegroundInfoAsync() { + return Futures.immediateFuture(new ForegroundInfo(R.id.notification_updating_feeds, createNotification(null))); + } + private void refreshFeeds(List<Feed> toUpdate, boolean force) { while (!toUpdate.isEmpty()) { if (isStopped()) { diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadRequestCreator.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadRequestCreator.java index 4d5f2883d..fd5babdd1 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadRequestCreator.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadRequestCreator.java @@ -21,6 +21,9 @@ public class DownloadRequestCreator { public static DownloadRequest.Builder create(Feed feed) { File dest = new File(getFeedfilePath(), getFeedfileName(feed)); + if (dest.exists()) { + dest.delete(); + } Log.d(TAG, "Requesting download of url " + feed.getDownload_url()); String username = (feed.getPreferences() != null) ? feed.getPreferences().getUsername() : null; diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceInterfaceImpl.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceInterfaceImpl.java index 87cbeda84..894a7153b 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceInterfaceImpl.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadServiceInterfaceImpl.java @@ -7,12 +7,18 @@ import androidx.work.ExistingWorkPolicy; import androidx.work.NetworkType; import androidx.work.OneTimeWorkRequest; import androidx.work.OutOfQuotaPolicy; +import androidx.work.WorkInfo; import androidx.work.WorkManager; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.model.feed.FeedItem; +import de.danoeh.antennapod.model.feed.FeedMedia; import de.danoeh.antennapod.net.download.serviceinterface.DownloadServiceInterface; import de.danoeh.antennapod.storage.preferences.UserPreferences; +import io.reactivex.Observable; +import io.reactivex.schedulers.Schedulers; +import java.util.List; +import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; public class DownloadServiceInterfaceImpl extends DownloadServiceInterface { @@ -40,13 +46,11 @@ public class DownloadServiceInterfaceImpl extends DownloadServiceInterface { .setInitialDelay(0L, TimeUnit.MILLISECONDS) .addTag(DownloadServiceInterface.WORK_TAG) .addTag(DownloadServiceInterface.WORK_TAG_EPISODE_URL + item.getMedia().getDownload_url()); - Data.Builder builder = new Data.Builder(); - builder.putLong(WORK_DATA_MEDIA_ID, item.getMedia().getId()); if (!item.isTagged(FeedItem.TAG_QUEUE) && UserPreferences.enqueueDownloadedEpisodes()) { DBWriter.addQueueItem(context, false, item.getId()); - builder.putBoolean(WORK_DATA_WAS_QUEUED, true); + workRequest.addTag(DownloadServiceInterface.WORK_DATA_WAS_QUEUED); } - workRequest.setInputData(builder.build()); + workRequest.setInputData(new Data.Builder().putLong(WORK_DATA_MEDIA_ID, item.getMedia().getId()).build()); return workRequest; } @@ -61,8 +65,26 @@ public class DownloadServiceInterfaceImpl extends DownloadServiceInterface { } @Override - public void cancel(Context context, String url) { - WorkManager.getInstance(context).cancelAllWorkByTag(WORK_TAG_EPISODE_URL + url); + public void cancel(Context context, FeedMedia media) { + // This needs to be done here, not in the worker. Reason: The worker might or might not be running. + DBWriter.deleteFeedMediaOfItem(context, media.getId()); // Remove partially downloaded file + String tag = WORK_TAG_EPISODE_URL + media.getDownload_url(); + Future<List<WorkInfo>> future = WorkManager.getInstance(context).getWorkInfosByTag(tag); + Observable.fromFuture(future) + .subscribeOn(Schedulers.io()) + .observeOn(Schedulers.io()) + .subscribe( + workInfos -> { + for (WorkInfo info : workInfos) { + if (info.getTags().contains(DownloadServiceInterface.WORK_DATA_WAS_QUEUED)) { + DBWriter.removeQueueItem(context, false, media.getItem()); + } + } + WorkManager.getInstance(context).cancelAllWorkByTag(tag); + }, exception -> { + WorkManager.getInstance(context).cancelAllWorkByTag(tag); + exception.printStackTrace(); + }); } @Override diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/EpisodeDownloadWorker.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/EpisodeDownloadWorker.java index dcce26042..e80f9b47f 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/EpisodeDownloadWorker.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/EpisodeDownloadWorker.java @@ -1,5 +1,6 @@ package de.danoeh.antennapod.core.service.download; +import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; @@ -9,8 +10,11 @@ import android.util.Log; import androidx.annotation.NonNull; import androidx.core.app.NotificationCompat; import androidx.work.Data; +import androidx.work.ForegroundInfo; import androidx.work.Worker; import androidx.work.WorkerParameters; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; import de.danoeh.antennapod.core.ClientConfigurator; import de.danoeh.antennapod.core.R; import de.danoeh.antennapod.core.service.download.handler.MediaDownloadedHandler; @@ -58,16 +62,23 @@ public class EpisodeDownloadWorker extends Worker { Thread progressUpdaterThread = new Thread() { @Override public void run() { - while (!isInterrupted()) { + while (true) { try { - Thread.sleep(1000); - notificationProgress.put(media.getEpisodeTitle(), request.getProgressPercent()); + synchronized (notificationProgress) { + if (isInterrupted()) { + return; + } + notificationProgress.put(media.getEpisodeTitle(), request.getProgressPercent()); + } setProgressAsync( new Data.Builder() .putInt(DownloadServiceInterface.WORK_DATA_PROGRESS, request.getProgressPercent()) .build()) .get(); - sendProgressNotification(); + NotificationManager nm = (NotificationManager) getApplicationContext() + .getSystemService(Context.NOTIFICATION_SERVICE); + nm.notify(R.id.notification_downloading, generateProgressNotification()); + Thread.sleep(1000); } catch (InterruptedException | ExecutionException e) { return; } @@ -75,18 +86,29 @@ public class EpisodeDownloadWorker extends Worker { } }; progressUpdaterThread.start(); - final Result result = performDownload(media, request); + Result result; + try { + result = performDownload(media, request); + } catch (Exception e) { + e.printStackTrace(); + result = Result.failure(); + } + if (result.equals(Result.failure()) && downloader != null) { + FileUtils.deleteQuietly(new File(downloader.getDownloadRequest().getDestination())); + } progressUpdaterThread.interrupt(); try { progressUpdaterThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } - notificationProgress.remove(media.getEpisodeTitle()); - if (notificationProgress.isEmpty()) { - NotificationManager nm = (NotificationManager) getApplicationContext() - .getSystemService(Context.NOTIFICATION_SERVICE); - nm.cancel(R.id.notification_downloading); + synchronized (notificationProgress) { + notificationProgress.remove(media.getEpisodeTitle()); + if (notificationProgress.isEmpty()) { + NotificationManager nm = (NotificationManager) getApplicationContext() + .getSystemService(Context.NOTIFICATION_SERVICE); + nm.cancel(R.id.notification_downloading); + } } Log.d(TAG, "Worker for " + media.getDownload_url() + " returned."); return result; @@ -100,6 +122,13 @@ public class EpisodeDownloadWorker extends Worker { } } + @NonNull + @Override + public ListenableFuture<ForegroundInfo> getForegroundInfoAsync() { + return Futures.immediateFuture( + new ForegroundInfo(R.id.notification_downloading, generateProgressNotification())); + } + private Result performDownload(FeedMedia media, DownloadRequest request) { File dest = new File(request.getDestination()); if (!dest.exists()) { @@ -130,18 +159,11 @@ public class EpisodeDownloadWorker extends Worker { } catch (Exception e) { DBWriter.addDownloadStatus(downloader.getResult()); sendErrorNotification(request.getTitle()); - FileUtils.deleteQuietly(new File(downloader.getDownloadRequest().getDestination())); return Result.failure(); } if (downloader.cancelled) { - if (getInputData().getBoolean(DownloadServiceInterface.WORK_DATA_WAS_QUEUED, false)) { - try { - DBWriter.removeQueueItem(getApplicationContext(), false, media.getItem()).get(); - } catch (ExecutionException | InterruptedException e) { - e.printStackTrace(); - } - } + // This also happens when the worker was preempted, not just when the user cancelled it return Result.success(); } @@ -158,10 +180,7 @@ public class EpisodeDownloadWorker extends Worker { && Integer.parseInt(status.getReasonDetailed()) == 416) { Log.d(TAG, "Requested invalid range, restarting download from the beginning"); FileUtils.deleteQuietly(new File(downloader.getDownloadRequest().getDestination())); - sendMessage(request.getTitle(), true); - if (isLastRunAttempt()) { - FileUtils.deleteQuietly(new File(downloader.getDownloadRequest().getDestination())); - } + sendMessage(request.getTitle(), false); return retry3times(); } @@ -173,13 +192,9 @@ public class EpisodeDownloadWorker extends Worker { || status.getReason() == DownloadError.ERROR_IO_BLOCKED) { // Fail fast, these are probably unrecoverable sendErrorNotification(request.getTitle()); - FileUtils.deleteQuietly(new File(downloader.getDownloadRequest().getDestination())); return Result.failure(); } - sendMessage(request.getTitle(), true); - if (isLastRunAttempt()) { - FileUtils.deleteQuietly(new File(downloader.getDownloadRequest().getDestination())); - } + sendMessage(request.getTitle(), false); return retry3times(); } @@ -196,7 +211,8 @@ public class EpisodeDownloadWorker extends Worker { return getRunAttemptCount() >= 2; } - private void sendMessage(String episodeTitle, boolean retrying) { + private void sendMessage(String episodeTitle, boolean isImmediateFail) { + boolean retrying = !isLastRunAttempt() && !isImmediateFail; if (episodeTitle.length() > 20) { episodeTitle = episodeTitle.substring(0, 19) + "…"; } @@ -239,19 +255,22 @@ public class EpisodeDownloadWorker extends Worker { nm.notify(R.id.notification_download_report, builder.build()); } - private void sendProgressNotification() { + private Notification generateProgressNotification() { StringBuilder bigTextB = new StringBuilder(); - Map<String, Integer> progressCopy = new HashMap<>(notificationProgress); + Map<String, Integer> progressCopy; + synchronized (notificationProgress) { + progressCopy = new HashMap<>(notificationProgress); + } for (Map.Entry<String, Integer> entry : progressCopy.entrySet()) { bigTextB.append(String.format(Locale.getDefault(), "%s (%d%%)\n", entry.getKey(), entry.getValue())); } String bigText = bigTextB.toString().trim(); String contentText; - if (notificationProgress.size() == 1) { + if (progressCopy.size() == 1) { contentText = bigText; } else { contentText = getApplicationContext().getResources().getQuantityString(R.plurals.downloads_left, - notificationProgress.size(), notificationProgress.size()); + progressCopy.size(), progressCopy.size()); } NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), NotificationUtils.CHANNEL_ID_DOWNLOADING); @@ -267,8 +286,6 @@ public class EpisodeDownloadWorker extends Worker { .setShowWhen(false) .setSmallIcon(R.drawable.ic_notification_sync) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC); - NotificationManager nm = (NotificationManager) getApplicationContext() - .getSystemService(Context.NOTIFICATION_SERVICE); - nm.notify(R.id.notification_downloading, builder.build()); + return builder.build(); } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java index a46b4c6d0..019f311d2 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java @@ -6,6 +6,7 @@ import android.util.Log; import androidx.annotation.NonNull; +import de.danoeh.antennapod.model.MediaMetadataRetrieverCompat; import org.greenrobot.eventbus.EventBus; import java.io.File; @@ -63,7 +64,7 @@ public class MediaDownloadedHandler implements Runnable { } // Get duration String durationStr = null; - try (MediaMetadataRetriever mmr = new MediaMetadataRetriever()) { + try (MediaMetadataRetrieverCompat mmr = new MediaMetadataRetrieverCompat()) { mmr.setDataSource(media.getFile_url()); durationStr = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); media.setDuration(Integer.parseInt(durationStr)); diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java index f7e8592e1..1453f701d 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java @@ -116,7 +116,7 @@ public class DBWriter { Log.i(TAG, String.format(Locale.US, "Requested to delete FeedMedia [id=%d, title=%s, downloaded=%s", media.getId(), media.getEpisodeTitle(), media.isDownloaded())); boolean localDelete = false; - if (media.isDownloaded()) { + if (media.isDownloaded() || media.getFile_url() != null) { // delete downloaded media file File mediaFile = new File(media.getFile_url()); if (mediaFile.exists() && !mediaFile.delete()) { @@ -227,7 +227,7 @@ public class DBWriter { if (item.getMedia().isDownloaded()) { deleteFeedMediaSynchronous(context, item.getMedia()); } - DownloadServiceInterface.get().cancel(context, item.getMedia().getDownload_url()); + DownloadServiceInterface.get().cancel(context, item.getMedia()); } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/NetworkUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/NetworkUtils.java index 8be8a113b..dfdc6c32a 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/NetworkUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/NetworkUtils.java @@ -78,18 +78,18 @@ public class NetworkUtils { private static boolean isNetworkMetered() { ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + return connManager.isActiveNetworkMetered(); + } - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { - NetworkCapabilities capabilities = connManager.getNetworkCapabilities( - connManager.getActiveNetwork()); - - if (capabilities != null - && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) - && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) { - return false; - } + public static boolean isVpnOverWifi() { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + return false; } - return connManager.isActiveNetworkMetered(); + ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkCapabilities capabilities = connManager.getNetworkCapabilities(connManager.getActiveNetwork()); + return capabilities != null + && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) + && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN); } private static boolean isNetworkCellular() { diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/download/FeedUpdateManager.java b/core/src/main/java/de/danoeh/antennapod/core/util/download/FeedUpdateManager.java index b09e58fad..2f2726bdb 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/download/FeedUpdateManager.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/download/FeedUpdateManager.java @@ -47,7 +47,9 @@ public class FeedUpdateManager { } else { PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder( FeedUpdateWorker.class, UserPreferences.getUpdateInterval(), TimeUnit.HOURS) - .setConstraints(getConstraints()) + .setConstraints(new Constraints.Builder() + .setRequiredNetworkType(UserPreferences.isAllowMobileFeedRefresh() + ? NetworkType.CONNECTED : NetworkType.UNMETERED).build()) .build(); WorkManager.getInstance(context).enqueueUniquePeriodicWork(WORK_ID_FEED_UPDATE, replace ? ExistingPeriodicWorkPolicy.REPLACE : ExistingPeriodicWorkPolicy.KEEP, workRequest); @@ -66,9 +68,11 @@ public class FeedUpdateManager { OneTimeWorkRequest.Builder workRequest = new OneTimeWorkRequest.Builder(FeedUpdateWorker.class) .setInitialDelay(0L, TimeUnit.MILLISECONDS) .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST) - .addTag(WORK_TAG_FEED_UPDATE) - .setConstraints(new Constraints.Builder() + .addTag(WORK_TAG_FEED_UPDATE); + if (feed == null || !feed.isLocalFeed()) { + workRequest.setConstraints(new Constraints.Builder() .setRequiredNetworkType(NetworkType.CONNECTED).build()); + } Data.Builder builder = new Data.Builder(); builder.putBoolean(EXTRA_EVEN_ON_MOBILE, true); if (feed != null) { @@ -86,7 +90,9 @@ public class FeedUpdateManager { public static void runOnceOrAsk(@NonNull Context context, @Nullable Feed feed) { Log.d(TAG, "Run auto update immediately in background."); - if (!NetworkUtils.networkAvailable()) { + if (feed != null && feed.isLocalFeed()) { + runOnce(context, feed); + } else if (!NetworkUtils.networkAvailable()) { EventBus.getDefault().post(new MessageEvent(context.getString(R.string.download_error_no_connection))); } else if (NetworkUtils.isFeedRefreshAllowed()) { runOnce(context, feed); @@ -98,7 +104,6 @@ public class FeedUpdateManager { private static void confirmMobileRefresh(final Context context, @Nullable Feed feed) { MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context) .setTitle(R.string.feed_refresh_title) - .setMessage(R.string.confirm_mobile_feed_refresh_dialog_message) .setPositiveButton(R.string.confirm_mobile_streaming_button_once, (dialog, which) -> runOnce(context, feed)) .setNeutralButton(R.string.confirm_mobile_streaming_button_always, (dialog, which) -> { @@ -106,18 +111,11 @@ public class FeedUpdateManager { runOnce(context, feed); }) .setNegativeButton(R.string.no, null); - builder.show(); - } - - private static Constraints getConstraints() { - Constraints.Builder constraints = new Constraints.Builder(); - - if (UserPreferences.isAllowMobileFeedRefresh()) { - constraints.setRequiredNetworkType(NetworkType.CONNECTED); + if (NetworkUtils.isNetworkRestricted() && NetworkUtils.isVpnOverWifi()) { + builder.setMessage(R.string.confirm_mobile_feed_refresh_dialog_message_vpn); } else { - constraints.setRequiredNetworkType(NetworkType.UNMETERED); + builder.setMessage(R.string.confirm_mobile_feed_refresh_dialog_message); } - return constraints.build(); + builder.show(); } - } |