Replace canStop with blockUntilEnded in HostedActiviy.

The canStop method gets called every second in a seperate thread until the
test can be stopped. Replacing it with blockUntilEnded forwards the
responsibility to stop to the test itself which has better control over the
stop condition.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=163343824
This commit is contained in:
tonihei 2017-07-27 08:34:46 -07:00 committed by Oliver Woodman
parent c3d7ccc3cb
commit 5bd5af8c60
2 changed files with 28 additions and 56 deletions

View File

@ -15,6 +15,7 @@
*/ */
package com.google.android.exoplayer2.testutil; package com.google.android.exoplayer2.testutil;
import android.os.ConditionVariable;
import android.os.Handler; import android.os.Handler;
import android.os.SystemClock; import android.os.SystemClock;
import android.util.Log; import android.util.Log;
@ -72,6 +73,7 @@ public abstract class ExoHostedTest implements HostedTest, Player.EventListener,
private final long expectedPlayingTimeMs; private final long expectedPlayingTimeMs;
private final DecoderCounters videoDecoderCounters; private final DecoderCounters videoDecoderCounters;
private final DecoderCounters audioDecoderCounters; private final DecoderCounters audioDecoderCounters;
private final ConditionVariable playerFinished;
private ActionSchedule pendingSchedule; private ActionSchedule pendingSchedule;
private Handler actionHandler; private Handler actionHandler;
@ -81,7 +83,7 @@ public abstract class ExoHostedTest implements HostedTest, Player.EventListener,
private ExoPlaybackException playerError; private ExoPlaybackException playerError;
private Player.EventListener playerEventListener; private Player.EventListener playerEventListener;
private boolean playerWasPrepared; private boolean playerWasPrepared;
private boolean playerFinished;
private boolean playing; private boolean playing;
private long totalPlayingTimeMs; private long totalPlayingTimeMs;
private long lastPlayingStartTimeMs; private long lastPlayingStartTimeMs;
@ -114,8 +116,9 @@ public abstract class ExoHostedTest implements HostedTest, Player.EventListener,
this.tag = tag; this.tag = tag;
this.expectedPlayingTimeMs = expectedPlayingTimeMs; this.expectedPlayingTimeMs = expectedPlayingTimeMs;
this.failOnPlayerError = failOnPlayerError; this.failOnPlayerError = failOnPlayerError;
videoDecoderCounters = new DecoderCounters(); this.playerFinished = new ConditionVariable();
audioDecoderCounters = new DecoderCounters(); this.videoDecoderCounters = new DecoderCounters();
this.audioDecoderCounters = new DecoderCounters();
} }
/** /**
@ -169,8 +172,8 @@ public abstract class ExoHostedTest implements HostedTest, Player.EventListener,
} }
@Override @Override
public final boolean canStop() { public final boolean blockUntilEnded(long timeoutMs) {
return playerFinished; return playerFinished.block(timeoutMs);
} }
@Override @Override
@ -219,7 +222,7 @@ public abstract class ExoHostedTest implements HostedTest, Player.EventListener,
playerWasPrepared |= playbackState != Player.STATE_IDLE; playerWasPrepared |= playbackState != Player.STATE_IDLE;
if (playbackState == Player.STATE_ENDED if (playbackState == Player.STATE_ENDED
|| (playbackState == Player.STATE_IDLE && playerWasPrepared)) { || (playbackState == Player.STATE_IDLE && playerWasPrepared)) {
playerFinished = true; playerFinished.open();
} }
boolean playing = playWhenReady && playbackState == Player.STATE_READY; boolean playing = playWhenReady && playbackState == Player.STATE_READY;
if (!this.playing && playing) { if (!this.playing && playing) {

View File

@ -24,7 +24,6 @@ import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock; import android.net.wifi.WifiManager.WifiLock;
import android.os.Bundle; import android.os.Bundle;
import android.os.ConditionVariable; import android.os.ConditionVariable;
import android.os.Handler;
import android.os.PowerManager; import android.os.PowerManager;
import android.os.PowerManager.WakeLock; import android.os.PowerManager.WakeLock;
import android.util.Log; import android.util.Log;
@ -57,17 +56,19 @@ public final class HostActivity extends Activity implements SurfaceHolder.Callba
void onStart(HostActivity host, Surface surface); void onStart(HostActivity host, Surface surface);
/** /**
* Called on the main thread to check whether the test is ready to be stopped. * Called on the main thread to block until the test has stopped or {@link #onStop()} is called.
* *
* @return Whether the test is ready to be stopped. * @param timeoutMs The maximum time to block in milliseconds.
* @return Whether the test has stopped successful.
*/ */
boolean canStop(); boolean blockUntilEnded(long timeoutMs);
/** /**
* Called on the main thread when the test is stopped. * Called on the main thread when the test is stopped.
* <p> * <p>
* The test will be stopped if {@link #canStop()} returns true, if the {@link HostActivity} has * The test will be stopped when {@link #blockUntilEnded(long)} returns, if the
* been paused, or if the {@link HostActivity}'s {@link Surface} has been destroyed. * {@link HostActivity} has been paused, or if the {@link HostActivity}'s {@link Surface} has
* been destroyed.
*/ */
void onStop(); void onStop();
@ -85,13 +86,10 @@ public final class HostActivity extends Activity implements SurfaceHolder.Callba
private WakeLock wakeLock; private WakeLock wakeLock;
private WifiLock wifiLock; private WifiLock wifiLock;
private SurfaceView surfaceView; private SurfaceView surfaceView;
private Handler mainHandler;
private CheckCanStopRunnable checkCanStopRunnable;
private HostedTest hostedTest; private HostedTest hostedTest;
private ConditionVariable hostedTestStoppedCondition;
private boolean hostedTestStarted; private boolean hostedTestStarted;
private boolean hostedTestFinished; private boolean forcedFinished;
/** /**
* Executes a {@link HostedTest} inside the host. * Executes a {@link HostedTest} inside the host.
@ -100,7 +98,7 @@ public final class HostActivity extends Activity implements SurfaceHolder.Callba
* @param timeoutMs The number of milliseconds to wait for the test to finish. If the timeout * @param timeoutMs The number of milliseconds to wait for the test to finish. If the timeout
* is exceeded then the test will fail. * is exceeded then the test will fail.
*/ */
public void runTest(final HostedTest hostedTest, long timeoutMs) { public void runTest(HostedTest hostedTest, long timeoutMs) {
runTest(hostedTest, timeoutMs, true); runTest(hostedTest, timeoutMs, true);
} }
@ -111,27 +109,31 @@ public final class HostActivity extends Activity implements SurfaceHolder.Callba
* @param timeoutMs The number of milliseconds to wait for the test to finish. * @param timeoutMs The number of milliseconds to wait for the test to finish.
* @param failOnTimeout Whether the test fails when the timeout is exceeded. * @param failOnTimeout Whether the test fails when the timeout is exceeded.
*/ */
public void runTest(final HostedTest hostedTest, long timeoutMs, boolean failOnTimeout) { public void runTest(HostedTest hostedTest, long timeoutMs, boolean failOnTimeout) {
Assertions.checkArgument(timeoutMs > 0); Assertions.checkArgument(timeoutMs > 0);
Assertions.checkState(Thread.currentThread() != getMainLooper().getThread()); Assertions.checkState(Thread.currentThread() != getMainLooper().getThread());
Assertions.checkState(this.hostedTest == null); Assertions.checkState(this.hostedTest == null);
this.hostedTest = Assertions.checkNotNull(hostedTest); this.hostedTest = Assertions.checkNotNull(hostedTest);
hostedTestStoppedCondition = new ConditionVariable();
hostedTestStarted = false; hostedTestStarted = false;
hostedTestFinished = false; forcedFinished = false;
final ConditionVariable testStarted = new ConditionVariable();
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
maybeStartHostedTest(); maybeStartHostedTest();
testStarted.open();
} }
}); });
testStarted.block();
if (hostedTestStoppedCondition.block(timeoutMs)) { if (hostedTest.blockUntilEnded(timeoutMs)) {
if (hostedTestFinished) { hostedTest.onStop();
if (!forcedFinished) {
Log.d(TAG, "Test finished. Checking pass conditions."); Log.d(TAG, "Test finished. Checking pass conditions.");
hostedTest.onFinished(); hostedTest.onFinished();
this.hostedTest = null;
Log.d(TAG, "Pass conditions checked."); Log.d(TAG, "Pass conditions checked.");
} else { } else {
String message = "Test released before it finished. Activity may have been paused whilst " String message = "Test released before it finished. Activity may have been paused whilst "
@ -146,7 +148,6 @@ public final class HostActivity extends Activity implements SurfaceHolder.Callba
fail(message); fail(message);
} }
maybeStopHostedTest(); maybeStopHostedTest();
hostedTestStoppedCondition.block();
} }
} }
@ -160,8 +161,6 @@ public final class HostActivity extends Activity implements SurfaceHolder.Callba
surfaceView = (SurfaceView) findViewById( surfaceView = (SurfaceView) findViewById(
getResources().getIdentifier("surface_view", "id", getPackageName())); getResources().getIdentifier("surface_view", "id", getPackageName()));
surfaceView.getHolder().addCallback(this); surfaceView.getHolder().addCallback(this);
mainHandler = new Handler();
checkCanStopRunnable = new CheckCanStopRunnable();
} }
@Override @Override
@ -225,24 +224,14 @@ public final class HostActivity extends Activity implements SurfaceHolder.Callba
hostedTestStarted = true; hostedTestStarted = true;
Log.d(TAG, "Starting test."); Log.d(TAG, "Starting test.");
hostedTest.onStart(this, surface); hostedTest.onStart(this, surface);
checkCanStopRunnable.startChecking();
} }
} }
private void maybeStopHostedTest() { private void maybeStopHostedTest() {
if (hostedTest != null && hostedTestStarted) { if (hostedTest != null && hostedTestStarted) {
forcedFinished = true;
hostedTest.onStop(); hostedTest.onStop();
hostedTest = null; hostedTest = null;
mainHandler.removeCallbacks(checkCanStopRunnable);
// We post opening of the stopped condition so that any events posted to the main thread as a
// result of hostedTest.onStop() are guaranteed to be handled before hostedTest.onFinished()
// is called from runTest.
mainHandler.post(new Runnable() {
@Override
public void run() {
hostedTestStoppedCondition.open();
}
});
} }
} }
@ -251,24 +240,4 @@ public final class HostActivity extends Activity implements SurfaceHolder.Callba
return Util.SDK_INT < 12 ? WifiManager.WIFI_MODE_FULL : WifiManager.WIFI_MODE_FULL_HIGH_PERF; return Util.SDK_INT < 12 ? WifiManager.WIFI_MODE_FULL : WifiManager.WIFI_MODE_FULL_HIGH_PERF;
} }
private final class CheckCanStopRunnable implements Runnable {
private static final long CHECK_INTERVAL_MS = 1000;
private void startChecking() {
mainHandler.post(this);
}
@Override
public void run() {
if (hostedTest.canStop()) {
hostedTestFinished = true;
maybeStopHostedTest();
} else {
mainHandler.postDelayed(this, CHECK_INTERVAL_MS);
}
}
}
} }