diff --git a/library/core/src/main/java/com/google/android/exoplayer2/util/Clock.java b/library/core/src/main/java/com/google/android/exoplayer2/util/Clock.java index f8d5759c2c..9619ed53ea 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/util/Clock.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/util/Clock.java @@ -15,6 +15,8 @@ */ package com.google.android.exoplayer2.util; +import android.os.Handler; + /** * An interface through which system clocks can be read. The {@link #DEFAULT} implementation * must be used for all non-test cases. @@ -36,4 +38,14 @@ public interface Clock { */ void sleep(long sleepTimeMs); + /** + * Post a {@link Runnable} on a {@link Handler} thread with a delay measured by this clock. + * @see Handler#postDelayed(Runnable, long) + * + * @param handler The {@link Handler} to post the {@code runnable} on. + * @param runnable A {@link Runnable} to be posted. + * @param delayMs The delay in milliseconds as measured by this clock. + */ + void postDelayed(Handler handler, Runnable runnable, long delayMs); + } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/util/SystemClock.java b/library/core/src/main/java/com/google/android/exoplayer2/util/SystemClock.java index 1f937b721b..272c3f43ec 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/util/SystemClock.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/util/SystemClock.java @@ -15,6 +15,8 @@ */ package com.google.android.exoplayer2.util; +import android.os.Handler; + /** * The standard implementation of {@link Clock}. */ @@ -30,4 +32,9 @@ package com.google.android.exoplayer2.util; android.os.SystemClock.sleep(sleepTimeMs); } + @Override + public void postDelayed(Handler handler, Runnable runnable, long delayMs) { + handler.postDelayed(runnable, delayMs); + } + } diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeClock.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeClock.java index 36ce4b5c3e..843e5858d8 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeClock.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeClock.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.testutil; +import android.os.Handler; import com.google.android.exoplayer2.util.Clock; import java.util.ArrayList; import java.util.List; @@ -26,6 +27,7 @@ public final class FakeClock implements Clock { private long currentTimeMs; private final List wakeUpTimes; + private final List handlerPosts; /** * Create {@link FakeClock} with an arbitrary initial timestamp. @@ -35,6 +37,7 @@ public final class FakeClock implements Clock { public FakeClock(long initialTimeMs) { this.currentTimeMs = initialTimeMs; this.wakeUpTimes = new ArrayList<>(); + this.handlerPosts = new ArrayList<>(); } /** @@ -50,10 +53,16 @@ public final class FakeClock implements Clock { break; } } + for (int i = handlerPosts.size() - 1; i >= 0; i--) { + if (handlerPosts.get(i).postTime <= currentTimeMs) { + HandlerPostData postData = handlerPosts.remove(i); + postData.handler.post(postData.runnable); + } + } } @Override - public long elapsedRealtime() { + public synchronized long elapsedRealtime() { return currentTimeMs; } @@ -74,5 +83,28 @@ public final class FakeClock implements Clock { wakeUpTimes.remove(wakeUpTimeMs); } + @Override + public synchronized void postDelayed(Handler handler, Runnable runnable, long delayMs) { + if (delayMs <= 0) { + handler.post(runnable); + } else { + handlerPosts.add(new HandlerPostData(currentTimeMs + delayMs, handler, runnable)); + } + } + + private static final class HandlerPostData { + + public final long postTime; + public final Handler handler; + public final Runnable runnable; + + public HandlerPostData(long postTime, Handler handler, Runnable runnable) { + this.postTime = postTime; + this.handler = handler; + this.runnable = runnable; + } + + } + }