package org.michenux.drodrolib.network.sync;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.PeriodicSync;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.SparseIntArray;
import org.michenux.drodrolib.info.AppUsageUtils;
import java.util.List;
public abstract class AbstractSyncHelper {
private static final String SYNCINTERVAL_PARAM = "syncInterval";
public static final int MINUTE_PER_HOUR = 60;
public static final int SECONDS_PER_MINUTE = 60;
private Account mAccount;
private String mAuthority;
private int mDefaultIntervalIndex;
private SparseIntArray mIntervals;
/**
* Adjust synchronization interval
*
* @param context context
*/
public void adjustSyncInterval(Context context) {
long lastSync = AppUsageUtils.getLastSync(context);
long appLastUsed = AppUsageUtils.getLastUsedTimestamp(context);
// if app used since last sync, increase frequency
if (appLastUsed > lastSync) {
increaseFrequency(context);
}
// if app not used since last sync, reduce frequency
else {
reduceFrequency(context);
}
}
private int getSyncIntervalIndex(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getInt(SYNCINTERVAL_PARAM, mDefaultIntervalIndex);
}
private int getSyncIntervalInMinute(Context context) {
return getSyncIntervalInMinute(getSyncIntervalIndex(context), context);
}
private int getSyncIntervalInMinute(int intervalIndex, Context context) {
return mIntervals.get(intervalIndex);
}
protected void increaseFrequency(Context context) {
int syncIntervalIndex = getSyncIntervalIndex(context);
if (syncIntervalIndex > 1) {
saveIntervalIndex(--syncIntervalIndex, context);
addPeriodicSync(getSyncIntervalInMinute(syncIntervalIndex, context));
}
}
protected void reduceFrequency(Context context) {
int syncIntervalIndex = getSyncIntervalIndex(context);
if (syncIntervalIndex < mIntervals.size()) {
saveIntervalIndex(++syncIntervalIndex, context);
addPeriodicSync(getSyncIntervalInMinute(syncIntervalIndex, context));
}
}
protected void saveIntervalIndex(int intervalIndex, Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = prefs.edit();
editor.putInt(SYNCINTERVAL_PARAM, intervalIndex);
editor.commit();
}
public boolean createAccount(String accountName, String accountType, String authority, boolean enableSync, Context context) {
this.mAccount = new Account(accountName, accountType);
this.mAuthority = authority;
AccountManager accountManager = (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);
boolean result = accountManager.addAccountExplicitly(mAccount, null, null);
if (enableSync) {
addPeriodicSync(getSyncIntervalInMinute(context));
}
AppUsageUtils.updateLastSync(context);
return result;
}
/**
* Remove any periodic sync for this account
*/
public void removePeriodicSync() {
Bundle bundle = new Bundle();
ContentResolver.removePeriodicSync(mAccount, mAuthority, bundle);
}
public void enablePeriodicSync(Context context) {
addPeriodicSync(getSyncIntervalInMinute(context));
}
/**
* Schedule syncAdapter by interval
*
* @param intervalInMinute interval in minute
*/
protected boolean addPeriodicSync(int intervalInMinute) {
boolean added = false;
if (!periodicSyncExists(intervalInMinute)) {
Bundle bundle = new Bundle();
// remove all others
removePeriodicSync();
ContentResolver.setIsSyncable(mAccount, mAuthority, 1);
ContentResolver.setSyncAutomatically(mAccount, mAuthority, true);
long syncInSecond = intervalInMinute * SECONDS_PER_MINUTE;
ContentResolver.addPeriodicSync(
mAccount,
mAuthority,
bundle,
syncInSecond);
added = true;
}
return added;
}
/**
* Test if periodic sync is already configured
*
* @param intervalInMinute interval in minute
* @return true if already exists
*/
private boolean periodicSyncExists(int intervalInMinute) {
boolean exists = false;
long syncInSecond = intervalInMinute * SECONDS_PER_MINUTE;
List<PeriodicSync> periodicSyncs = ContentResolver.getPeriodicSyncs(mAccount, mAuthority);
if (periodicSyncs != null && !periodicSyncs.isEmpty()) {
for (PeriodicSync periodicSync : periodicSyncs) {
if (periodicSync.period == syncInSecond) {
exists = true;
}
}
}
return exists;
}
public void performSync() {
Bundle settingsBundle = new Bundle();
settingsBundle.putBoolean(
ContentResolver.SYNC_EXTRAS_MANUAL, true);
settingsBundle.putBoolean(
ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
ContentResolver.requestSync(mAccount, mAuthority, settingsBundle);
}
public boolean isActiveOrPending() {
return ContentResolver.isSyncActive(mAccount, mAuthority) ||
ContentResolver.isSyncPending(mAccount, mAuthority);
}
public void setDefaultIntervalIndex(int defaultIntervalIndex) {
this.mDefaultIntervalIndex = defaultIntervalIndex;
}
public void setIntervals(SparseIntArray intervals) {
this.mIntervals = intervals;
}
}