Add ability to parse HTTP-format moratorium times
(since pretty much every user wants this).
diff --git a/common/java/com/android/common/OperationScheduler.java b/common/java/com/android/common/OperationScheduler.java
index 71b22ce..c7b12d3 100644
--- a/common/java/com/android/common/OperationScheduler.java
+++ b/common/java/com/android/common/OperationScheduler.java
@@ -192,7 +192,6 @@
/**
* Forbid any operations until after a certain (absolute) time.
- * Commonly used when a server returns a "Retry-After:" type directive.
* Limited by {@link #Options.maxMoratoriumMillis}.
*
* @param millis wall clock time ({@link System#currentTimeMillis()}) to
@@ -206,6 +205,29 @@
}
/**
+ * Forbid any operations until after a certain time, as specified in
+ * the format used by the HTTP "Retry-After" header.
+ * Limited by {@link #Options.maxMoratoriumMillis}.
+ *
+ * @param retryAfter moratorium time in HTTP format
+ * @return true if a time was successfully parsed
+ */
+ public boolean setMoratoriumTimeHttp(String retryAfter) {
+ try {
+ long ms = Long.valueOf(retryAfter) * 1000;
+ setMoratoriumTimeMillis(ms + System.currentTimeMillis());
+ return true;
+ } catch (NumberFormatException nfe) {
+ try {
+ setMoratoriumTimeMillis(HttpDateTime.parse(retryAfter));
+ return true;
+ } catch (IllegalArgumentException iae) {
+ return false;
+ }
+ }
+ }
+
+ /**
* Enable or disable all operations. When disabled, all calls to
* {@link #getNextTimeMillis()} return {@link Long#MAX_VALUE}.
* Commonly used when data network availability goes up and down.
diff --git a/common/tests/src/com/android/common/OperationSchedulerTest.java b/common/tests/src/com/android/common/OperationSchedulerTest.java
index 13f710d..28178b5 100644
--- a/common/tests/src/com/android/common/OperationSchedulerTest.java
+++ b/common/tests/src/com/android/common/OperationSchedulerTest.java
@@ -113,4 +113,32 @@
"OperationScheduler.Options[backoff=10.0+2.5 max=12345.6 min=7.0 period=3800.0]",
OperationScheduler.parseOptions("", options).toString());
}
+
+ public void testMoratoriumWithHttpDate() throws Exception {
+ String name = "OperationSchedulerTest.testMoratoriumWithHttpDate";
+ SharedPreferences storage = getContext().getSharedPreferences(name, 0);
+ storage.edit().clear().commit();
+
+ OperationScheduler scheduler = new OperationScheduler(storage);
+ OperationScheduler.Options options = new OperationScheduler.Options();
+
+ long beforeTrigger = System.currentTimeMillis();
+ scheduler.setTriggerTimeMillis(beforeTrigger + 1000000);
+ assertEquals(beforeTrigger + 1000000, scheduler.getNextTimeMillis(options));
+
+ scheduler.setMoratoriumTimeMillis(beforeTrigger + 2000000);
+ assertEquals(beforeTrigger + 2000000, scheduler.getNextTimeMillis(options));
+
+ long beforeMoratorium = System.currentTimeMillis();
+ assertTrue(scheduler.setMoratoriumTimeHttp("3000"));
+ long afterMoratorium = System.currentTimeMillis();
+ assertTrue(beforeMoratorium + 3000000 <= scheduler.getNextTimeMillis(options));
+ assertTrue(afterMoratorium + 3000000 >= scheduler.getNextTimeMillis(options));
+
+ options.maxMoratoriumMillis = Long.MAX_VALUE / 2;
+ assertTrue(scheduler.setMoratoriumTimeHttp("Fri, 31 Dec 2030 23:59:59 GMT"));
+ assertEquals(1924991999000L, scheduler.getNextTimeMillis(options));
+
+ assertFalse(scheduler.setMoratoriumTimeHttp("not actually a date"));
+ }
}