diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..9a40236 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,3 @@ + + + diff --git a/app/src/main/java/cz/c3c/webviewkiosk/BackoffPolicy.kt b/app/src/main/java/cz/c3c/webviewkiosk/BackoffPolicy.kt new file mode 100644 index 0000000..57bb87a --- /dev/null +++ b/app/src/main/java/cz/c3c/webviewkiosk/BackoffPolicy.kt @@ -0,0 +1,19 @@ +package cz.c3c.webviewkiosk + +class BackoffPolicy( + private val initialDelayMs: Long, + private val maxDelayMs: Long, + private val factor: Double = 2.0, +) { + private var nextMs = initialDelayMs + + fun nextDelayMs(): Long { + val current = nextMs + nextMs = (nextMs * factor).toLong().coerceAtMost(maxDelayMs) + return current + } + + fun reset() { + nextMs = initialDelayMs + } +} diff --git a/app/src/test/java/cz/c3c/webviewkiosk/BackoffPolicyTest.kt b/app/src/test/java/cz/c3c/webviewkiosk/BackoffPolicyTest.kt new file mode 100644 index 0000000..6c98219 --- /dev/null +++ b/app/src/test/java/cz/c3c/webviewkiosk/BackoffPolicyTest.kt @@ -0,0 +1,39 @@ +package cz.c3c.webviewkiosk + +import org.junit.Assert.assertEquals +import org.junit.Test + +class BackoffPolicyTest { + + @Test + fun firstDelayIsInitial() { + val b = BackoffPolicy(initialDelayMs = 2_000, maxDelayMs = 60_000) + assertEquals(2_000, b.nextDelayMs()) + } + + @Test + fun delayDoublesOnEachCall() { + val b = BackoffPolicy(initialDelayMs = 2_000, maxDelayMs = 60_000) + b.nextDelayMs() + assertEquals(4_000, b.nextDelayMs()) + assertEquals(8_000, b.nextDelayMs()) + } + + @Test + fun delayCapsAtMax() { + val b = BackoffPolicy(initialDelayMs = 2_000, maxDelayMs = 5_000) + b.nextDelayMs() // 2000 + b.nextDelayMs() // 4000 + assertEquals(5_000, b.nextDelayMs()) + assertEquals(5_000, b.nextDelayMs()) + } + + @Test + fun resetReturnsToInitial() { + val b = BackoffPolicy(initialDelayMs = 2_000, maxDelayMs = 60_000) + b.nextDelayMs() + b.nextDelayMs() + b.reset() + assertEquals(2_000, b.nextDelayMs()) + } +}