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
This commit is contained in:
tonihei 2017-09-05 05:50:43 -07:00 committed by Oliver Woodman
parent 264f1c903d
commit 2f4a3fe1f3
3 changed files with 52 additions and 1 deletions

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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<Long> wakeUpTimes;
private final List<HandlerPostData> 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;
}
}
}