From f30cdf0e80f19aca59853b0e167716bcee51ec89 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Fri, 1 Nov 2024 10:29:11 +0100 Subject: [PATCH] Sync after refreshing (#7475) - Enables users to manually trigger sync - Makes sure that we actually refresh when a new feed arrives: Previously, we might request the feed to be refreshed but then don't actually wait for it to be completed because the refresh service wouldn't start up quickly enough. This makes sure that we do not try to sync again before the refresh actually went through, even if the sync service is called multiple times. --- .../service/feed/FeedUpdateWorker.java | 2 + .../net/sync/service/SyncService.java | 52 ++++++++++--------- ui/i18n/src/main/res/values/strings.xml | 2 +- 3 files changed, 31 insertions(+), 25 deletions(-) diff --git a/net/download/service/src/main/java/de/danoeh/antennapod/net/download/service/feed/FeedUpdateWorker.java b/net/download/service/src/main/java/de/danoeh/antennapod/net/download/service/feed/FeedUpdateWorker.java index fb0cb7e40..a62ded3a3 100644 --- a/net/download/service/src/main/java/de/danoeh/antennapod/net/download/service/feed/FeedUpdateWorker.java +++ b/net/download/service/src/main/java/de/danoeh/antennapod/net/download/service/feed/FeedUpdateWorker.java @@ -24,6 +24,7 @@ import de.danoeh.antennapod.net.download.service.feed.remote.Downloader; import de.danoeh.antennapod.net.download.service.feed.remote.FeedParserTask; import de.danoeh.antennapod.net.download.serviceinterface.AutoDownloadManager; import de.danoeh.antennapod.net.download.serviceinterface.DownloadRequestCreator; +import de.danoeh.antennapod.net.sync.serviceinterface.SynchronizationQueue; import de.danoeh.antennapod.storage.database.DBReader; import de.danoeh.antennapod.storage.database.FeedDatabaseWriter; import de.danoeh.antennapod.storage.database.DBWriter; @@ -103,6 +104,7 @@ public class FeedUpdateWorker extends Worker { NonSubscribedFeedsCleaner.deleteOldNonSubscribedFeeds(getApplicationContext()); AutoDownloadManager.getInstance().autodownloadUndownloadedItems(getApplicationContext()); notificationManager.cancel(R.id.notification_updating_feeds); + SynchronizationQueue.getInstance().syncImmediately(); return Result.success(); } diff --git a/net/sync/service/src/main/java/de/danoeh/antennapod/net/sync/service/SyncService.java b/net/sync/service/src/main/java/de/danoeh/antennapod/net/sync/service/SyncService.java index 6076f4b5a..fd8ed94a4 100644 --- a/net/sync/service/src/main/java/de/danoeh/antennapod/net/sync/service/SyncService.java +++ b/net/sync/service/src/main/java/de/danoeh/antennapod/net/sync/service/SyncService.java @@ -15,7 +15,6 @@ import androidx.core.content.ContextCompat; import androidx.core.util.Pair; import androidx.work.Worker; import androidx.work.WorkerParameters; -import de.danoeh.antennapod.event.FeedUpdateRunningEvent; import de.danoeh.antennapod.event.MessageEvent; import de.danoeh.antennapod.event.SyncServiceEvent; import de.danoeh.antennapod.model.feed.Feed; @@ -70,12 +69,21 @@ public class SyncService extends Worker { return Result.success(); } - SynchronizationSettings.updateLastSynchronizationAttempt(); + if (currentlyActive) { + return Result.success(); + } currentlyActive = true; + SynchronizationSettings.updateLastSynchronizationAttempt(); try { activeSyncProvider.login(); syncSubscriptions(activeSyncProvider); - waitForDownloadServiceCompleted(); + if (someFeedWasNotRefreshedYet()) { + // Note that this service might get called several times before the FeedUpdate completes + Log.d(TAG, "Found new subscriptions. Need to refresh them before syncing episode actions"); + EventBus.getDefault().postSticky(new SyncServiceEvent(R.string.sync_status_wait_for_downloads)); + FeedUpdateManager.getInstance().runOnce(getApplicationContext()); + return Result.success(); + } syncEpisodeActions(activeSyncProvider); activeSyncProvider.logout(); clearErrorNotifications(); @@ -102,6 +110,15 @@ public class SyncService extends Worker { } } + private boolean someFeedWasNotRefreshedYet() { + for (Feed feed : DBReader.getFeedList()) { + if (feed.getLastRefreshAttempt() == 0) { + return true; + } + } + return false; + } + /* package-private */ static boolean isCurrentlyActive() { return currentlyActive; } @@ -125,8 +142,7 @@ public class SyncService extends Worker { if (!UrlChecker.containsUrl(localSubscriptions, downloadUrl) && !queuedRemovedFeeds.contains(downloadUrl)) { Feed feed = new Feed(downloadUrl, null, "Unknown podcast"); feed.setItems(Collections.emptyList()); - Feed newFeed = FeedDatabaseWriter.updateFeed(getApplicationContext(), feed, false); - FeedUpdateManager.getInstance().runOnce(getApplicationContext(), newFeed); + FeedDatabaseWriter.updateFeed(getApplicationContext(), feed, false); } } @@ -140,11 +156,15 @@ public class SyncService extends Worker { if (lastSync == 0) { Log.d(TAG, "First sync. Adding all local subscriptions."); queuedAddedFeeds = localSubscriptions; - queuedAddedFeeds.removeAll(subscriptionChanges.getAdded()); - queuedRemovedFeeds.removeAll(subscriptionChanges.getRemoved()); } - if (!queuedAddedFeeds.isEmpty() || !queuedRemovedFeeds.isEmpty()) { + queuedAddedFeeds.removeAll(subscriptionChanges.getAdded()); + queuedRemovedFeeds.removeAll(subscriptionChanges.getRemoved()); + + if (queuedAddedFeeds.isEmpty() && queuedRemovedFeeds.isEmpty()) { + Log.d(TAG, "No feeds to add or remove from server"); + synchronizationQueueStorage.clearFeedQueues(); + } else { Log.d(TAG, "Added: " + StringUtils.join(queuedAddedFeeds, ", ")); Log.d(TAG, "Removed: " + StringUtils.join(queuedRemovedFeeds, ", ")); @@ -161,22 +181,6 @@ public class SyncService extends Worker { SynchronizationSettings.setLastSubscriptionSynchronizationAttemptTimestamp(newTimeStamp); } - private void waitForDownloadServiceCompleted() { - EventBus.getDefault().postSticky(new SyncServiceEvent(R.string.sync_status_wait_for_downloads)); - try { - while (true) { - //noinspection BusyWait - Thread.sleep(1000); - FeedUpdateRunningEvent event = EventBus.getDefault().getStickyEvent(FeedUpdateRunningEvent.class); - if (event == null || !event.isFeedUpdateRunning) { - return; - } - } - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - private void syncEpisodeActions(ISyncService syncServiceImpl) throws SyncServiceException { final long lastSync = SynchronizationSettings.getLastEpisodeActionSynchronizationTimestamp(); EventBus.getDefault().postSticky(new SyncServiceEvent(R.string.sync_status_episodes_download)); diff --git a/ui/i18n/src/main/res/values/strings.xml b/ui/i18n/src/main/res/values/strings.xml index bfdd5ae99..fe03c8ed5 100644 --- a/ui/i18n/src/main/res/values/strings.xml +++ b/ui/i18n/src/main/res/values/strings.xml @@ -571,7 +571,7 @@ Downloading episode changes… Uploading played status… Synchronizing subscriptions… - Waiting for downloads to complete… + Waiting for subscriptions refresh… Synchronization successful Synchronization failed