// Copyright 2015 The Project Buendia Authors // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy // of the License at: http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distrib- // uted under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES // OR CONDITIONS OF ANY KIND, either express or implied. See the License for // specific language governing permissions and limitations under the License. package org.projectbuendia.client.sync; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import org.projectbuendia.client.AppSettings; import org.projectbuendia.client.events.sync.SyncCanceledEvent; import org.projectbuendia.client.events.sync.SyncFailedEvent; import org.projectbuendia.client.events.sync.SyncProgressEvent; import org.projectbuendia.client.events.sync.SyncStartedEvent; import org.projectbuendia.client.events.sync.SyncSucceededEvent; import org.projectbuendia.client.providers.Contracts; import org.projectbuendia.client.utils.Logger; import javax.annotation.Nullable; import de.greenrobot.event.EventBus; /** Manages the sync process and responds to sync events. */ public class SyncManager { private static final Logger LOG = Logger.create(); static final String SYNC_STATUS = "sync-status"; static final int STARTED = 1; static final int COMPLETED = 2; static final int FAILED = 3; static final int IN_PROGRESS = 4; static final int CANCELED = 5; /** * Intent extras using this key are integers representing the sync progress completed so far, * as a percentage. */ static final String SYNC_PROGRESS = "sync-progress"; /** * Intent extras using this key are nullable strings representing the current sync status. * They are localized and are suitable for presentation to the user. */ static final String SYNC_PROGRESS_LABEL = "sync-progress-label"; @Nullable private final AppSettings mSettings; public SyncManager(@Nullable AppSettings settings) { mSettings = settings; } /** Cancels an in-flight, non-periodic sync. */ public void cancelOnDemandSync() { ContentResolver.cancelSync( SyncAccountService.getAccount(), Contracts.CONTENT_AUTHORITY); // If sync was pending, it should now be idle and we can consider the sync immediately // canceled. if (!isSyncPending() && !isSyncActive()) { LOG.i("Sync was canceled before it began -- immediately firing SyncCanceledEvent."); EventBus.getDefault().post(new SyncCanceledEvent()); } } /** Returns {@code true} if a sync is pending. */ public boolean isSyncPending() { return ContentResolver.isSyncPending( SyncAccountService.getAccount(), Contracts.CONTENT_AUTHORITY); } /** Returns {@code true} if a sync is active. */ public boolean isSyncActive() { return ContentResolver.isSyncActive( SyncAccountService.getAccount(), Contracts.CONTENT_AUTHORITY); } /** Starts a full sync as soon as possible. */ public void startFullSync() { SyncAccountService.startFullSync(); } /** Starts a sync of only observations and orders. */ public static void startObservationsAndOrdersSync() { SyncAccountService.startObservationsAndOrdersSync(); } /** * A {@link BroadcastReceiver} that listens for sync status broadcasts sent by * {@link SyncAdapter}. */ public static class SyncStatusBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { int syncStatus = intent.getIntExtra(SYNC_STATUS, -1 /*defaultValue*/); switch (syncStatus) { case STARTED: LOG.i("Sync started"); EventBus.getDefault().post(new SyncStartedEvent()); break; case COMPLETED: LOG.i("Sync completed"); EventBus.getDefault().post(new SyncSucceededEvent()); break; case FAILED: LOG.i("Sync failed"); EventBus.getDefault().post(new SyncFailedEvent()); break; case IN_PROGRESS: int progress = intent.getIntExtra(SYNC_PROGRESS, 0); String label = intent.getStringExtra(SYNC_PROGRESS_LABEL); LOG.d("Sync in progress (%d%%, %s)", progress, label); EventBus.getDefault().post(new SyncProgressEvent(progress, label)); break; case CANCELED: LOG.i("Sync was canceled."); EventBus.getDefault().post(new SyncCanceledEvent()); break; case -1: LOG.i("Sync status broadcast intent received without a status code."); break; default: LOG.i("Sync status broadcast intent received with unknown status %1$d.", syncStatus); } } } }