From 2f4a3fe1f3a95ed9a8029c6e3d21e537852bc271 Mon Sep 17 00:00:00 2001 From: tonihei Date: Tue, 5 Sep 2017 05:50:43 -0700 Subject: [PATCH] Add postDelayed operation to Clock interface. The default implementation is just calling through to handler.postDelayed, while the fake clock uses its internal time value to trigger the handler calls at the correct time. This is useful to apply a fake clock in situations where a handler is used to post delayed messages. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=167567914 --- .../google/android/exoplayer2/util/Clock.java | 12 +++++++ .../android/exoplayer2/util/SystemClock.java | 7 ++++ .../exoplayer2/testutil/FakeClock.java | 34 ++++++++++++++++++- 3 files changed, 52 insertions(+), 1 deletion(-) 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; + } + + } + }