diff options
-rw-r--r-- | common/java/com/android/common/OperationScheduler.java | 24 | ||||
-rw-r--r-- | common/tests/src/com/android/common/OperationSchedulerTest.java | 28 |
2 files changed, 51 insertions, 1 deletions
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 @@ public class OperationScheduler { /** * 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 @@ public class OperationScheduler { } /** + * 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 @@ public class OperationSchedulerTest extends AndroidTestCase { "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")); + } } |