summaryrefslogtreecommitdiffstats
path: root/mobile/android/services/src/main/java/org/mozilla/gecko/sync/InfoCollections.java
diff options
context:
space:
mode:
Diffstat (limited to 'mobile/android/services/src/main/java/org/mozilla/gecko/sync/InfoCollections.java')
-rw-r--r--mobile/android/services/src/main/java/org/mozilla/gecko/sync/InfoCollections.java103
1 files changed, 103 insertions, 0 deletions
diff --git a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/InfoCollections.java b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/InfoCollections.java
new file mode 100644
index 000000000..374fa5cf5
--- /dev/null
+++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/InfoCollections.java
@@ -0,0 +1,103 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.gecko.sync;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.mozilla.gecko.background.common.log.Logger;
+
+/**
+ * Fetches the timestamp information in <code>info/collections</code> on the
+ * Sync server. Provides access to those timestamps, along with logic to check
+ * for whether a collection requires an update.
+ */
+public class InfoCollections {
+ private static final String LOG_TAG = "InfoCollections";
+
+ /**
+ * Fields fetched from the server, or <code>null</code> if not yet fetched.
+ * <p>
+ * Rather than storing decimal/double timestamps, as provided by the server,
+ * we convert immediately to milliseconds since epoch.
+ */
+ final Map<String, Long> timestamps;
+
+ public InfoCollections() {
+ this(new ExtendedJSONObject());
+ }
+
+ public InfoCollections(final ExtendedJSONObject record) {
+ Logger.debug(LOG_TAG, "info/collections is " + record.toJSONString());
+ HashMap<String, Long> map = new HashMap<String, Long>();
+
+ for (Entry<String, Object> entry : record.entrySet()) {
+ final String key = entry.getKey();
+ final Object value = entry.getValue();
+
+ // These objects are most likely going to be Doubles. Regardless, we
+ // want to get them in a more sane time format.
+ if (value instanceof Double) {
+ map.put(key, Utils.decimalSecondsToMilliseconds((Double) value));
+ continue;
+ }
+ if (value instanceof Long) {
+ map.put(key, Utils.decimalSecondsToMilliseconds((Long) value));
+ continue;
+ }
+ if (value instanceof Integer) {
+ map.put(key, Utils.decimalSecondsToMilliseconds((Integer) value));
+ continue;
+ }
+ Logger.warn(LOG_TAG, "Skipping info/collections entry for " + key);
+ }
+
+ this.timestamps = Collections.unmodifiableMap(map);
+ }
+
+ /**
+ * Return the timestamp for the given collection, or null if the timestamps
+ * have not been fetched or the given collection does not have a timestamp.
+ *
+ * @param collection
+ * The collection to inspect.
+ * @return the timestamp in milliseconds since epoch.
+ */
+ public Long getTimestamp(String collection) {
+ if (timestamps == null) {
+ return null;
+ }
+ return timestamps.get(collection);
+ }
+
+ /**
+ * Test if a given collection needs to be updated.
+ *
+ * @param collection
+ * The collection to test.
+ * @param lastModified
+ * Timestamp when local record was last modified.
+ */
+ public boolean updateNeeded(String collection, long lastModified) {
+ Logger.trace(LOG_TAG, "Testing " + collection + " for updateNeeded. Local last modified is " + lastModified + ".");
+
+ // No local record of modification time? Need an update.
+ if (lastModified <= 0) {
+ return true;
+ }
+
+ // No meta/global on the server? We need an update. The server fetch will fail and
+ // then we will upload a fresh meta/global.
+ Long serverLastModified = getTimestamp(collection);
+ if (serverLastModified == null) {
+ return true;
+ }
+
+ // Otherwise, we need an update if our modification time is stale.
+ return serverLastModified > lastModified;
+ }
+}