package org.commcare.utils;
import android.content.SharedPreferences;
import android.text.format.DateUtils;
import org.commcare.CommCareApplication;
import org.commcare.preferences.CommCarePreferences;
import java.util.Calendar;
import java.util.Date;
public class PendingCalcs {
public static boolean isUpdatePending(SharedPreferences preferences) {
// Establish whether or not an AutoUpdate is Pending
String autoUpdateFreq =
preferences.getString(CommCarePreferences.AUTO_UPDATE_FREQUENCY,
CommCarePreferences.FREQUENCY_NEVER);
// See if auto update is even turned on
if (!autoUpdateFreq.equals(CommCarePreferences.FREQUENCY_NEVER)) {
long lastUpdateCheck =
preferences.getLong(CommCarePreferences.LAST_UPDATE_ATTEMPT, 0);
return isTimeForAutoUpdateCheck(lastUpdateCheck, autoUpdateFreq);
}
return false;
}
public static boolean isTimeForAutoUpdateCheck(long lastUpdateCheck, String autoUpdateFreq) {
int checkEveryNDays;
if (CommCarePreferences.FREQUENCY_DAILY.equals(autoUpdateFreq)) {
checkEveryNDays = 1;
} else {
checkEveryNDays = 7;
}
long duration = DateUtils.DAY_IN_MILLIS * checkEveryNDays;
return isPending(lastUpdateCheck, duration);
}
/**
* Used to check if an update, sync, or log submission is pending, based upon the last time
* it occurred and the expected period between occurrences
*/
public static boolean isPending(long last, long period) {
long now = new Date().getTime();
// 1) Straightforward - Time is greater than last + duration
long diff = now - last;
if (diff > period) {
return true;
}
// 2) For daily stuff, we want it to be the case that if the last time you synced was the day prior,
// you still sync, so people can get into the cycle of doing it once in the morning, which
// is more valuable than syncing mid-day.
if (isDifferentDayInPast(now, last, period)) {
return true;
}
// 3) Major time change - (Phone might have had its calendar day manipulated).
// for now we'll simply say that if last was more than a day in the future (timezone blur)
// we should also trigger
return (now < (last - DateUtils.DAY_IN_MILLIS));
}
private static boolean isDifferentDayInPast(long now, long last, long period) {
Calendar lastRestoreCalendar = Calendar.getInstance();
lastRestoreCalendar.setTimeInMillis(last);
return period == DateUtils.DAY_IN_MILLIS &&
lastRestoreCalendar.get(Calendar.DAY_OF_WEEK) != Calendar.getInstance().get(Calendar.DAY_OF_WEEK) &&
now > last;
}
/**
* @return True if there is a sync action pending.
*/
public static boolean getPendingSyncStatus() {
SharedPreferences prefs = CommCareApplication.instance().getCurrentApp().getAppPreferences();
long period = -1;
// Old flag, use a day by default
if ("true".equals(prefs.getString("cc-auto-update", "false"))) {
period = DateUtils.DAY_IN_MILLIS;
}
// new flag, read what it is.
String periodic = prefs.getString(CommCarePreferences.AUTO_SYNC_FREQUENCY, CommCarePreferences.FREQUENCY_NEVER);
if (!periodic.equals(CommCarePreferences.FREQUENCY_NEVER)) {
period = DateUtils.DAY_IN_MILLIS * (periodic.equals(CommCarePreferences.FREQUENCY_DAILY) ? 1 : 7);
}
// If we didn't find a period, bail
if (period == -1) {
return false;
}
long lastRestore = prefs.getLong(CommCarePreferences.LAST_SYNC_ATTEMPT, 0);
return PendingCalcs.isPending(lastRestore, period);
}
}