package com.eveningoutpost.dexdrip.G5Model; // jamorham import com.eveningoutpost.dexdrip.Models.JoH; import com.eveningoutpost.dexdrip.Models.UserError; import com.eveningoutpost.dexdrip.UtilityModels.Constants; import com.eveningoutpost.dexdrip.UtilityModels.PersistentStore; import static com.eveningoutpost.dexdrip.UtilityModels.BgGraphBuilder.DEXCOM_PERIOD; public class DexSyncKeeper { private static final String TAG = DexTimeKeeper.class.getSimpleName(); private static final String DEX_SYNC_STORE = "DEX_SYNC_STORE-"; private static final long OLDEST_POSSIBLE = 1533839836123L; private static final long GRACE_TIME = 5000; private static final long VALIDITY_PERIOD = Constants.DAY_IN_MS; // store sync time as now public static void store(final String transmitterId) { store(transmitterId, JoH.tsl()); } // store sync time public static void store(final String transmitterId, final long when) { if ((transmitterId == null) || (transmitterId.length() != 6)) { UserError.Log.e(TAG, "Invalid dex transmitter in store: " + transmitterId); return; } if (when < OLDEST_POSSIBLE) { UserError.Log.wtf(TAG, "Invalid timestamp to store: " + JoH.dateTimeText(when)); return; } PersistentStore.setLong(DEX_SYNC_STORE + transmitterId, when); UserError.Log.d(TAG, "Sync time updated to: " + JoH.dateTimeText(when)); } // anticpiate next wake up from now public static long anticipate(final String transmitterId) { return anticipate(transmitterId, JoH.tsl()); } // anticipate next wake up from time // -1 means we don't know anything static long anticipate(final String transmitterId, final long now) { final long last = PersistentStore.getLong(DEX_SYNC_STORE + transmitterId); if (last < OLDEST_POSSIBLE) { return -1; } if (last > now) { UserError.Log.e(TAG, "Anticipation time in the future! cannot use: " + JoH.dateTimeText(last)); return -1; // can't be in the future } if (now - last > VALIDITY_PERIOD) { UserError.Log.e(TAG, "Anticipation time too old to use: " + JoH.dateTimeText(last)); return -1; } final long modulo = (now - last) % DEXCOM_PERIOD; if ((modulo < GRACE_TIME) && ((now - last) > GRACE_TIME)) return now; final long next = now + (DEXCOM_PERIOD - modulo); return next; } public static boolean isReady(final String transmitterId) { return anticipate(transmitterId, JoH.tsl()) != -1; } // are we outside connection window? // TODO also handle waking up before window PRE_GRACE_TIME = 20seconds? public static boolean outsideWindow(final String transmitterId) { final long now = JoH.tsl(); final long next = anticipate(transmitterId, now); return next != now; } }