Search in sources :

Example 1 with SyncServiceEvent

use of de.danoeh.antennapod.event.SyncServiceEvent in project AntennaPod by AntennaPod.

the class SyncService method getWorkRequest.

private static OneTimeWorkRequest.Builder getWorkRequest() {
    Constraints.Builder constraints = new Constraints.Builder();
    if (UserPreferences.isAllowMobileFeedRefresh()) {
        constraints.setRequiredNetworkType(NetworkType.CONNECTED);
    } else {
        constraints.setRequiredNetworkType(NetworkType.UNMETERED);
    }
    OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(SyncService.class).setConstraints(constraints.build()).setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 10, TimeUnit.MINUTES);
    if (isCurrentlyActive) {
        // Debounce: don't start sync again immediately after it was finished.
        builder.setInitialDelay(2L, TimeUnit.MINUTES);
    } else {
        // Give it some time, so other possible actions can be queued.
        builder.setInitialDelay(20L, TimeUnit.SECONDS);
        EventBus.getDefault().postSticky(new SyncServiceEvent(R.string.sync_status_started));
    }
    return builder;
}
Also used : Constraints(androidx.work.Constraints) SyncServiceEvent(de.danoeh.antennapod.event.SyncServiceEvent) OneTimeWorkRequest(androidx.work.OneTimeWorkRequest)

Example 2 with SyncServiceEvent

use of de.danoeh.antennapod.event.SyncServiceEvent in project AntennaPod by AntennaPod.

the class SyncService method doWork.

@Override
@NonNull
public Result doWork() {
    ISyncService activeSyncProvider = getActiveSyncProvider();
    if (activeSyncProvider == null) {
        return Result.success();
    }
    SynchronizationSettings.updateLastSynchronizationAttempt();
    setCurrentlyActive(true);
    try {
        activeSyncProvider.login();
        syncSubscriptions(activeSyncProvider);
        waitForDownloadServiceCompleted();
        syncEpisodeActions(activeSyncProvider);
        activeSyncProvider.logout();
        clearErrorNotifications();
        EventBus.getDefault().postSticky(new SyncServiceEvent(R.string.sync_status_success));
        SynchronizationSettings.setLastSynchronizationAttemptSuccess(true);
        return Result.success();
    } catch (Exception e) {
        EventBus.getDefault().postSticky(new SyncServiceEvent(R.string.sync_status_error));
        SynchronizationSettings.setLastSynchronizationAttemptSuccess(false);
        Log.e(TAG, Log.getStackTraceString(e));
        if (e instanceof SyncServiceException) {
            if (getRunAttemptCount() % 3 == 2) {
                // Do not spam users with notification and retry before notifying
                updateErrorNotification(e);
            }
            return Result.retry();
        } else {
            updateErrorNotification(e);
            return Result.failure();
        }
    } finally {
        setCurrentlyActive(false);
    }
}
Also used : SyncServiceException(de.danoeh.antennapod.net.sync.model.SyncServiceException) SyncServiceEvent(de.danoeh.antennapod.event.SyncServiceEvent) ISyncService(de.danoeh.antennapod.net.sync.model.ISyncService) SyncServiceException(de.danoeh.antennapod.net.sync.model.SyncServiceException) NonNull(androidx.annotation.NonNull)

Example 3 with SyncServiceEvent

use of de.danoeh.antennapod.event.SyncServiceEvent in project AntennaPod by AntennaPod.

the class SyncService method syncEpisodeActions.

private void syncEpisodeActions(ISyncService syncServiceImpl) throws SyncServiceException {
    final long lastSync = SynchronizationSettings.getLastEpisodeActionSynchronizationTimestamp();
    EventBus.getDefault().postSticky(new SyncServiceEvent(R.string.sync_status_episodes_download));
    EpisodeActionChanges getResponse = syncServiceImpl.getEpisodeActionChanges(lastSync);
    long newTimeStamp = getResponse.getTimestamp();
    List<EpisodeAction> remoteActions = getResponse.getEpisodeActions();
    processEpisodeActions(remoteActions);
    // upload local actions
    EventBus.getDefault().postSticky(new SyncServiceEvent(R.string.sync_status_episodes_upload));
    List<EpisodeAction> queuedEpisodeActions = synchronizationQueueStorage.getQueuedEpisodeActions();
    if (lastSync == 0) {
        EventBus.getDefault().postSticky(new SyncServiceEvent(R.string.sync_status_upload_played));
        List<FeedItem> readItems = DBReader.getPlayedItems();
        Log.d(TAG, "First sync. Upload state for all " + readItems.size() + " played episodes");
        for (FeedItem item : readItems) {
            FeedMedia media = item.getMedia();
            if (media == null) {
                continue;
            }
            EpisodeAction played = new EpisodeAction.Builder(item, EpisodeAction.PLAY).currentTimestamp().started(media.getDuration() / 1000).position(media.getDuration() / 1000).total(media.getDuration() / 1000).build();
            queuedEpisodeActions.add(played);
        }
    }
    if (queuedEpisodeActions.size() > 0) {
        LockingAsyncExecutor.lock.lock();
        try {
            Log.d(TAG, "Uploading " + queuedEpisodeActions.size() + " actions: " + StringUtils.join(queuedEpisodeActions, ", "));
            UploadChangesResponse postResponse = syncServiceImpl.uploadEpisodeActions(queuedEpisodeActions);
            newTimeStamp = postResponse.timestamp;
            Log.d(TAG, "Upload episode response: " + postResponse);
            synchronizationQueueStorage.clearEpisodeActionQueue();
        } finally {
            LockingAsyncExecutor.lock.unlock();
        }
    }
    SynchronizationSettings.setLastEpisodeActionSynchronizationAttemptTimestamp(newTimeStamp);
}
Also used : FeedItem(de.danoeh.antennapod.model.feed.FeedItem) FeedMedia(de.danoeh.antennapod.model.feed.FeedMedia) SyncServiceEvent(de.danoeh.antennapod.event.SyncServiceEvent) UploadChangesResponse(de.danoeh.antennapod.net.sync.model.UploadChangesResponse) EpisodeActionChanges(de.danoeh.antennapod.net.sync.model.EpisodeActionChanges) EpisodeAction(de.danoeh.antennapod.net.sync.model.EpisodeAction)

Example 4 with SyncServiceEvent

use of de.danoeh.antennapod.event.SyncServiceEvent in project AntennaPod by AntennaPod.

the class SyncService method syncSubscriptions.

private void syncSubscriptions(ISyncService syncServiceImpl) throws SyncServiceException {
    final long lastSync = SynchronizationSettings.getLastSubscriptionSynchronizationTimestamp();
    EventBus.getDefault().postSticky(new SyncServiceEvent(R.string.sync_status_subscriptions));
    final List<String> localSubscriptions = DBReader.getFeedListDownloadUrls();
    SubscriptionChanges subscriptionChanges = syncServiceImpl.getSubscriptionChanges(lastSync);
    long newTimeStamp = subscriptionChanges.getTimestamp();
    List<String> queuedRemovedFeeds = synchronizationQueueStorage.getQueuedRemovedFeeds();
    List<String> queuedAddedFeeds = synchronizationQueueStorage.getQueuedAddedFeeds();
    Log.d(TAG, "Downloaded subscription changes: " + subscriptionChanges);
    for (String downloadUrl : subscriptionChanges.getAdded()) {
        if (!URLChecker.containsUrl(localSubscriptions, downloadUrl) && !queuedRemovedFeeds.contains(downloadUrl)) {
            Feed feed = new Feed(downloadUrl, null);
            DownloadRequest.Builder builder = DownloadRequestCreator.create(feed);
            DownloadService.download(getApplicationContext(), false, builder.build());
        }
    }
    // remove subscription if not just subscribed (again)
    for (String downloadUrl : subscriptionChanges.getRemoved()) {
        if (!queuedAddedFeeds.contains(downloadUrl)) {
            DBTasks.removeFeedWithDownloadUrl(getApplicationContext(), downloadUrl);
        }
    }
    if (lastSync == 0) {
        Log.d(TAG, "First sync. Adding all local subscriptions.");
        queuedAddedFeeds = localSubscriptions;
        queuedAddedFeeds.removeAll(subscriptionChanges.getAdded());
        queuedRemovedFeeds.removeAll(subscriptionChanges.getRemoved());
    }
    if (queuedAddedFeeds.size() > 0 || queuedRemovedFeeds.size() > 0) {
        Log.d(TAG, "Added: " + StringUtils.join(queuedAddedFeeds, ", "));
        Log.d(TAG, "Removed: " + StringUtils.join(queuedRemovedFeeds, ", "));
        LockingAsyncExecutor.lock.lock();
        try {
            UploadChangesResponse uploadResponse = syncServiceImpl.uploadSubscriptionChanges(queuedAddedFeeds, queuedRemovedFeeds);
            synchronizationQueueStorage.clearFeedQueues();
            newTimeStamp = uploadResponse.timestamp;
        } finally {
            LockingAsyncExecutor.lock.unlock();
        }
    }
    SynchronizationSettings.setLastSubscriptionSynchronizationAttemptTimestamp(newTimeStamp);
}
Also used : DownloadRequest(de.danoeh.antennapod.core.service.download.DownloadRequest) SubscriptionChanges(de.danoeh.antennapod.net.sync.model.SubscriptionChanges) SyncServiceEvent(de.danoeh.antennapod.event.SyncServiceEvent) UploadChangesResponse(de.danoeh.antennapod.net.sync.model.UploadChangesResponse) Feed(de.danoeh.antennapod.model.feed.Feed)

Aggregations

SyncServiceEvent (de.danoeh.antennapod.event.SyncServiceEvent)4 UploadChangesResponse (de.danoeh.antennapod.net.sync.model.UploadChangesResponse)2 NonNull (androidx.annotation.NonNull)1 Constraints (androidx.work.Constraints)1 OneTimeWorkRequest (androidx.work.OneTimeWorkRequest)1 DownloadRequest (de.danoeh.antennapod.core.service.download.DownloadRequest)1 Feed (de.danoeh.antennapod.model.feed.Feed)1 FeedItem (de.danoeh.antennapod.model.feed.FeedItem)1 FeedMedia (de.danoeh.antennapod.model.feed.FeedMedia)1 EpisodeAction (de.danoeh.antennapod.net.sync.model.EpisodeAction)1 EpisodeActionChanges (de.danoeh.antennapod.net.sync.model.EpisodeActionChanges)1 ISyncService (de.danoeh.antennapod.net.sync.model.ISyncService)1 SubscriptionChanges (de.danoeh.antennapod.net.sync.model.SubscriptionChanges)1 SyncServiceException (de.danoeh.antennapod.net.sync.model.SyncServiceException)1