diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java index 65f43ae684..8fd508a2f0 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java @@ -117,6 +117,7 @@ import java.util.Collections; private final DefaultMediaClock mediaClock; private final PlaybackInfoUpdate playbackInfoUpdate; private final ArrayList customMessageInfos; + private final Clock clock; @SuppressWarnings("unused") private SeekParameters seekParameters; @@ -159,6 +160,7 @@ import java.util.Collections; this.shuffleModeEnabled = shuffleModeEnabled; this.eventHandler = eventHandler; this.player = player; + this.clock = clock; backBufferDurationUs = loadControl.getBackBufferDurationUs(); retainBackBufferFromKeyframe = loadControl.retainBackBufferFromKeyframe(); @@ -541,7 +543,7 @@ import java.util.Collections; } private void doSomeWork() throws ExoPlaybackException, IOException { - long operationStartTimeMs = SystemClock.elapsedRealtime(); + long operationStartTimeMs = clock.uptimeMillis(); updatePeriods(); if (playingPeriodHolder == null) { // We're still waiting for the first period to be prepared. @@ -632,7 +634,7 @@ import java.util.Collections; private void scheduleNextWork(long thisOperationStartTimeMs, long intervalMs) { handler.removeMessages(MSG_DO_SOME_WORK); - handler.sendEmptyMessageDelayed(MSG_DO_SOME_WORK, intervalMs, thisOperationStartTimeMs); + handler.sendEmptyMessageAtTime(MSG_DO_SOME_WORK, thisOperationStartTimeMs + intervalMs); } private void seekToInternal(SeekPosition seekPosition) throws ExoPlaybackException { 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 43c01bf53a..dced6752eb 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 @@ -30,14 +30,13 @@ public interface Clock { */ Clock DEFAULT = new SystemClock(); - /** - * @see android.os.SystemClock#elapsedRealtime() - */ + /** @see android.os.SystemClock#elapsedRealtime() */ long elapsedRealtime(); - /** - * @see android.os.SystemClock#sleep(long) - */ + /** @see android.os.SystemClock#uptimeMillis() */ + long uptimeMillis(); + + /** @see android.os.SystemClock#sleep(long) */ void sleep(long sleepTimeMs); /** diff --git a/library/core/src/main/java/com/google/android/exoplayer2/util/HandlerWrapper.java b/library/core/src/main/java/com/google/android/exoplayer2/util/HandlerWrapper.java index b101a5e199..3ce93f9370 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/util/HandlerWrapper.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/util/HandlerWrapper.java @@ -43,18 +43,8 @@ public interface HandlerWrapper { /** @see Handler#sendEmptyMessage(int). */ boolean sendEmptyMessage(int what); - /** - * Variant of {@code Handler#sendEmptyMessageDelayed(int, long)} which also takes a reference time - * measured by {@code android.os.SystemClock#elapsedRealtime()} to which the delay is added. - * - * @param what The message identifier. - * @param delayMs The delay in milliseconds to send the message. This delay is added to the {@code - * referenceTimeMs}. - * @param referenceTimeMs The time which the delay is added to. Always measured with {@code - * android.os.SystemClock#elapsedRealtime()}. - * @return Whether the message was successfully enqueued on the Handler thread. - */ - boolean sendEmptyMessageDelayed(int what, long delayMs, long referenceTimeMs); + /** @see Handler#sendEmptyMessageAtTime(int, long). */ + boolean sendEmptyMessageAtTime(int what, long uptimeMs); /** @see Handler#removeMessages(int). */ void removeMessages(int what); 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 b24a38ea3c..72d3df46e1 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 @@ -30,6 +30,11 @@ import android.support.annotation.Nullable; return android.os.SystemClock.elapsedRealtime(); } + @Override + public long uptimeMillis() { + return android.os.SystemClock.uptimeMillis(); + } + @Override public void sleep(long sleepTimeMs) { android.os.SystemClock.sleep(sleepTimeMs); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/util/SystemHandlerWrapper.java b/library/core/src/main/java/com/google/android/exoplayer2/util/SystemHandlerWrapper.java index aa290d9313..ee469a5b2a 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/util/SystemHandlerWrapper.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/util/SystemHandlerWrapper.java @@ -17,7 +17,6 @@ package com.google.android.exoplayer2.util; import android.os.Looper; import android.os.Message; -import android.os.SystemClock; /** The standard implementation of {@link HandlerWrapper}. */ /* package */ final class SystemHandlerWrapper implements HandlerWrapper { @@ -59,14 +58,8 @@ import android.os.SystemClock; } @Override - public boolean sendEmptyMessageDelayed(int what, long delayMs, long referenceTimeMs) { - long targetMessageTime = referenceTimeMs + delayMs; - long remainingDelayMs = targetMessageTime - SystemClock.elapsedRealtime(); - if (remainingDelayMs <= 0) { - return handler.sendEmptyMessage(what); - } else { - return handler.sendEmptyMessageDelayed(what, remainingDelayMs); - } + public boolean sendEmptyMessageAtTime(int what, long uptimeMs) { + return handler.sendEmptyMessageAtTime(what, uptimeMs); } @Override 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 49656eef99..a591546613 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 @@ -67,6 +67,11 @@ public class FakeClock implements Clock { return currentTimeMs; } + @Override + public long uptimeMillis() { + return elapsedRealtime(); + } + @Override public synchronized void sleep(long sleepTimeMs) { if (sleepTimeMs <= 0) { @@ -90,15 +95,23 @@ public class FakeClock implements Clock { } /** Adds a handler post to list of pending messages. */ - protected synchronized void addDelayedHandlerMessage( - HandlerWrapper handler, Runnable runnable, long delayMs) { - handlerMessages.add(new HandlerMessageData(currentTimeMs + delayMs, handler, runnable)); + protected synchronized boolean addHandlerMessageAtTime( + HandlerWrapper handler, Runnable runnable, long timeMs) { + if (timeMs <= currentTimeMs) { + return handler.post(runnable); + } + handlerMessages.add(new HandlerMessageData(timeMs, handler, runnable)); + return true; } /** Adds an empty handler message to list of pending messages. */ - protected synchronized void addDelayedHandlerMessage( - HandlerWrapper handler, int message, long delayMs) { - handlerMessages.add(new HandlerMessageData(currentTimeMs + delayMs, handler, message)); + protected synchronized boolean addHandlerMessageAtTime( + HandlerWrapper handler, int message, long timeMs) { + if (timeMs <= currentTimeMs) { + return handler.sendEmptyMessage(message); + } + handlerMessages.add(new HandlerMessageData(timeMs, handler, message)); + return true; } /** Message data saved to send messages or execute runnables at a later time on a Handler. */ @@ -177,14 +190,8 @@ public class FakeClock implements Clock { } @Override - public boolean sendEmptyMessageDelayed(int what, long delayMs, long referenceTimeMs) { - // Ignore referenceTimeMs measured by SystemClock and just send with requested delay. - if (delayMs <= 0) { - return handler.sendEmptyMessage(what); - } else { - addDelayedHandlerMessage(this, what, delayMs); - return true; - } + public boolean sendEmptyMessageAtTime(int what, long uptimeMs) { + return addHandlerMessageAtTime(this, what, uptimeMs); } @Override @@ -204,12 +211,7 @@ public class FakeClock implements Clock { @Override public boolean postDelayed(Runnable runnable, long delayMs) { - if (delayMs <= 0) { - return handler.post(runnable); - } else { - addDelayedHandlerMessage(this, runnable, delayMs); - return true; - } + return addHandlerMessageAtTime(this, runnable, uptimeMillis() + delayMs); } } }