Clean up DownloadAction instances

This removes a fair chunk of code. The line delta would
be more negative if it not for adding all the /* x= */
comments in DashDownloadActionTest!

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=194136689
This commit is contained in:
olly 2018-04-24 13:32:17 -07:00 committed by Oliver Woodman
parent c9bb102f93
commit b6f646ed96
17 changed files with 342 additions and 344 deletions

View File

@ -95,7 +95,7 @@ public class DemoDownloadService extends DownloadService {
this,
R.drawable.exo_controls_play,
CHANNEL_ID,
downloadState.downloadAction.getData(),
downloadState.downloadAction.data,
new ErrorMessageProvider<Throwable>() {
@Override
public Pair<Integer, String> getErrorMessage(Throwable throwable) {

View File

@ -293,12 +293,12 @@ public class DownloadActivity extends Activity {
String sampleName, ArrayList<Object> representationKeys) {
RepresentationKey[] keys =
representationKeys.toArray(new RepresentationKey[representationKeys.size()]);
return new DashDownloadAction(manifestUri, false, sampleName, keys);
return new DashDownloadAction(/* isRemoveAction= */ false, sampleName, manifestUri, keys);
}
@Override
public DownloadAction getRemoveAction() {
return new DashDownloadAction(manifestUri, true, null);
return new DashDownloadAction(/* isRemoveAction= */ true, /* data= */ null, manifestUri);
}
}
@ -329,12 +329,12 @@ public class DownloadActivity extends Activity {
public DownloadAction getDownloadAction(
String sampleName, ArrayList<Object> representationKeys) {
RenditionKey[] keys = representationKeys.toArray(new RenditionKey[representationKeys.size()]);
return new HlsDownloadAction(manifestUri, false, sampleName, keys);
return new HlsDownloadAction(/* isRemoveAction= */ false, sampleName, manifestUri, keys);
}
@Override
public DownloadAction getRemoveAction() {
return new HlsDownloadAction(manifestUri, true, null);
return new HlsDownloadAction(/* isRemoveAction= */ true, /* data= */ null, manifestUri);
}
}
@ -368,12 +368,12 @@ public class DownloadActivity extends Activity {
public DownloadAction getDownloadAction(
String sampleName, ArrayList<Object> representationKeys) {
TrackKey[] keys = representationKeys.toArray(new TrackKey[representationKeys.size()]);
return new SsDownloadAction(manifestUri, false, sampleName, keys);
return new SsDownloadAction(/* isRemoveAction= */ false, sampleName, manifestUri, keys);
}
@Override
public DownloadAction getRemoveAction() {
return new SsDownloadAction(manifestUri, true, null);
return new SsDownloadAction(/* isRemoveAction= */ true, /* data= */ null, manifestUri);
}
}
@ -399,12 +399,14 @@ public class DownloadActivity extends Activity {
@Override
public DownloadAction getDownloadAction(
String sampleName, ArrayList<Object> representationKeys) {
return new ProgressiveDownloadAction(manifestUri, null, false, sampleName);
return new ProgressiveDownloadAction(
/* isRemoveAction= */ false, /* data= */ null, manifestUri, /* customCacheKey= */ null);
}
@Override
public DownloadAction getRemoveAction() {
return new ProgressiveDownloadAction(manifestUri, null, true, null);
return new ProgressiveDownloadAction(
/* isRemoveAction= */ true, /* data= */ null, manifestUri, /* customCacheKey= */ null);
}
}
}

View File

@ -34,10 +34,13 @@ public abstract class DownloadAction {
public static final int MASTER_VERSION = 0;
/** Used to deserialize {@link DownloadAction}s. */
public interface Deserializer {
public abstract static class Deserializer {
/** Returns the type string of the {@link DownloadAction}. This string should be unique. */
String getType();
public String type;
public Deserializer(String type) {
this.type = type;
}
/**
* Deserializes a {@link DownloadAction} from the {@code input}.
@ -47,7 +50,8 @@ public abstract class DownloadAction {
* @see DownloadAction#writeToStream(DataOutputStream)
* @see DownloadAction#MASTER_VERSION
*/
DownloadAction readFromStream(int version, DataInputStream input) throws IOException;
public abstract DownloadAction readFromStream(int version, DataInputStream input)
throws IOException;
}
/**
@ -89,7 +93,7 @@ public abstract class DownloadAction {
DataInputStream dataInputStream = new DataInputStream(input);
String type = dataInputStream.readUTF();
for (Deserializer deserializer : deserializers) {
if (type.equals(deserializer.getType())) {
if (type.equals(deserializer.type)) {
return deserializer.readFromStream(version, dataInputStream);
}
}
@ -101,15 +105,26 @@ public abstract class DownloadAction {
throws IOException {
// Don't close the stream as it closes the underlying stream too.
DataOutputStream dataOutputStream = new DataOutputStream(output);
dataOutputStream.writeUTF(action.getType());
dataOutputStream.writeUTF(action.type);
action.writeToStream(dataOutputStream);
dataOutputStream.flush();
}
private final String data;
/** The type of the action. */
public final String type;
/** Whether this is a remove action. If false, this is a download action. */
public final boolean isRemoveAction;
/** Custom data for this action. May be the empty string if no custom data was specified. */
public final String data;
/** @param data Optional custom data for this action. If null, an empty string is used. */
protected DownloadAction(@Nullable String data) {
/**
* @param type The type of the action.
* @param isRemoveAction Whether this is a remove action. If false, this is a download action.
* @param data Optional custom data for this action. If null, an empty string is used.
*/
protected DownloadAction(String type, boolean isRemoveAction, @Nullable String data) {
this.type = type;
this.isRemoveAction = isRemoveAction;
this.data = data != null ? data : "";
}
@ -125,17 +140,6 @@ public abstract class DownloadAction {
return output.toByteArray();
}
/** Returns custom data for this action. */
public final String getData() {
return data;
}
/** Returns whether this is a remove action or a download action. */
public abstract boolean isRemoveAction();
/** Returns the type string of the {@link DownloadAction}. This string should be unique. */
protected abstract String getType();
/** Serializes itself into the {@code output}. */
protected abstract void writeToStream(DataOutputStream output) throws IOException;
@ -152,13 +156,13 @@ public abstract class DownloadAction {
return false;
}
DownloadAction that = (DownloadAction) o;
return data.equals(that.data) && isRemoveAction() == that.isRemoveAction();
return data.equals(that.data) && isRemoveAction == that.isRemoveAction;
}
@Override
public int hashCode() {
int result = data.hashCode();
result = 31 * result + (isRemoveAction() ? 1 : 0);
result = 31 * result + (isRemoveAction ? 1 : 0);
return result;
}

View File

@ -264,7 +264,7 @@ public final class DownloadManager {
public int handleAction(DownloadAction downloadAction) {
DownloadTask downloadTask = createDownloadTask(downloadAction);
saveActions();
if (downloadsStopped && !downloadAction.isRemoveAction()) {
if (downloadsStopped && !downloadAction.isRemoveAction) {
logd("Can't start the task as downloads are stopped", downloadTask);
} else {
maybeStartTasks();
@ -345,7 +345,7 @@ public final class DownloadManager {
}
DownloadAction downloadAction = downloadTask.downloadAction;
boolean removeAction = downloadAction.isRemoveAction();
boolean removeAction = downloadAction.isRemoveAction;
if (!removeAction && skipDownloadActions) {
continue;
}
@ -359,7 +359,7 @@ public final class DownloadManager {
logd(downloadTask + " clashes with " + task);
task.cancel();
// Continue loop to cancel any other preceding clashing tasks.
} else if (task.downloadAction.isRemoveAction()) {
} else if (task.downloadAction.isRemoveAction) {
canStartTask = false;
skipDownloadActions = true;
break;
@ -668,11 +668,11 @@ public final class DownloadManager {
if (!DEBUG) {
return super.toString();
}
return downloadAction.getType()
return downloadAction.type
+ ' '
+ (downloadAction.isRemoveAction() ? "remove" : "download")
+ (downloadAction.isRemoveAction ? "remove" : "download")
+ ' '
+ downloadAction.getData()
+ downloadAction.data
+ ' '
+ getStateString();
}
@ -759,7 +759,7 @@ public final class DownloadManager {
Throwable error = null;
try {
downloader = downloadAction.createDownloader(downloadManager.downloaderConstructorHelper);
if (downloadAction.isRemoveAction()) {
if (downloadAction.isRemoveAction) {
downloader.remove();
} else {
int errorCount = 0;

View File

@ -27,49 +27,36 @@ import java.io.IOException;
/** An action to download or remove downloaded progressive streams. */
public final class ProgressiveDownloadAction extends DownloadAction {
private static final String TYPE = "ProgressiveDownloadAction";
public static final Deserializer DESERIALIZER =
new Deserializer() {
@Override
public String getType() {
return TYPE;
}
new Deserializer(TYPE) {
@Override
public ProgressiveDownloadAction readFromStream(int version, DataInputStream input)
throws IOException {
return new ProgressiveDownloadAction(
Uri.parse(input.readUTF()),
input.readBoolean() ? input.readUTF() : null,
input.readBoolean(),
input.readUTF());
boolean isRemoveAction = input.readBoolean();
String data = input.readUTF();
Uri uri = Uri.parse(input.readUTF());
String customCacheKey = input.readBoolean() ? input.readUTF() : null;
return new ProgressiveDownloadAction(isRemoveAction, data, uri, customCacheKey);
}
};
private static final String TYPE = "ProgressiveDownloadAction";
private final Uri uri;
private final @Nullable String customCacheKey;
private final boolean removeAction;
/**
* @param isRemoveAction Whether this is a remove action. If false, this is a download action.
* @param data Optional custom data for this action. If null, an empty string is used.
* @param uri Uri of the data to be downloaded.
* @param customCacheKey A custom key that uniquely identifies the original stream. If not null it
* is used for cache indexing.
* @param removeAction Whether the data should be downloaded or removed.
* @param data Optional custom data for this action. If null, an empty string is used.
*/
public ProgressiveDownloadAction(
Uri uri, @Nullable String customCacheKey, boolean removeAction, @Nullable String data) {
super(data);
boolean isRemoveAction, @Nullable String data, Uri uri, @Nullable String customCacheKey) {
super(TYPE, isRemoveAction, data);
this.uri = Assertions.checkNotNull(uri);
this.customCacheKey = customCacheKey;
this.removeAction = removeAction;
}
@Override
public boolean isRemoveAction() {
return removeAction;
}
@Override
@ -77,21 +64,16 @@ public final class ProgressiveDownloadAction extends DownloadAction {
return new ProgressiveDownloader(uri, customCacheKey, constructorHelper);
}
@Override
protected String getType() {
return TYPE;
}
@Override
protected void writeToStream(DataOutputStream output) throws IOException {
output.writeBoolean(isRemoveAction);
output.writeUTF(data);
output.writeUTF(uri.toString());
boolean customCacheKeyAvailable = customCacheKey != null;
output.writeBoolean(customCacheKeyAvailable);
if (customCacheKeyAvailable) {
boolean customCacheKeySet = customCacheKey != null;
output.writeBoolean(customCacheKeySet);
if (customCacheKeySet) {
output.writeUTF(customCacheKey);
}
output.writeBoolean(isRemoveAction());
output.writeUTF(getData());
}
@Override

View File

@ -28,26 +28,31 @@ import java.util.Arrays;
*
* @param <K> The type of the representation key object.
*/
public abstract class SegmentDownloadAction<K> extends DownloadAction {
public abstract class SegmentDownloadAction<K extends Comparable> extends DownloadAction {
/**
* Base class for {@link SegmentDownloadAction} {@link Deserializer}s.
*
* @param <K> The type of the representation key object.
*/
protected abstract static class SegmentDownloadActionDeserializer<K> implements Deserializer {
protected abstract static class SegmentDownloadActionDeserializer<K> extends Deserializer {
public SegmentDownloadActionDeserializer(String type) {
super(type);
}
@Override
public DownloadAction readFromStream(int version, DataInputStream input) throws IOException {
Uri manifestUri = Uri.parse(input.readUTF());
public final DownloadAction readFromStream(int version, DataInputStream input)
throws IOException {
boolean isRemoveAction = input.readBoolean();
String data = input.readUTF();
boolean removeAction = input.readBoolean();
Uri manifestUri = Uri.parse(input.readUTF());
int keyCount = input.readInt();
K[] keys = createKeyArray(keyCount);
for (int i = 0; i < keyCount; i++) {
keys[i] = readKey(input);
}
return createDownloadAction(manifestUri, removeAction, data, keys);
return createDownloadAction(isRemoveAction, data, manifestUri, keys);
}
/** Deserializes a key from the {@code input}. */
@ -57,43 +62,39 @@ public abstract class SegmentDownloadAction<K> extends DownloadAction {
protected abstract K[] createKeyArray(int keyCount);
/** Returns a {@link DownloadAction}. */
protected abstract DownloadAction createDownloadAction(Uri manifestUri, boolean removeAction,
String data, K[] keys);
protected abstract DownloadAction createDownloadAction(
boolean isRemoveAction, String data, Uri manifestUri, K[] keys);
}
protected final Uri manifestUri;
protected final K[] keys;
private final boolean removeAction;
/**
* @param manifestUri The {@link Uri} of the manifest to be downloaded.
* @param removeAction Whether the data will be removed. If {@code false} it will be downloaded.
* @param type The type of the action.
* @param data Optional custom data for this action. If null, an empty string is used.
* @param isRemoveAction Whether the data will be removed. If {@code false} it will be downloaded.
* @param manifestUri The {@link Uri} of the manifest to be downloaded.
* @param keys Keys of representations to be downloaded. If empty, all representations are
* downloaded. If {@code removeAction} is true, {@code keys} should be an empty array.
* downloaded. If {@code removeAction} is true, {@code keys} must be an empty array.
*/
protected SegmentDownloadAction(
Uri manifestUri, boolean removeAction, @Nullable String data, K[] keys) {
super(data);
String type, boolean isRemoveAction, @Nullable String data, Uri manifestUri, K[] keys) {
super(type, isRemoveAction, data);
this.manifestUri = manifestUri;
this.keys = Assertions.checkNotNull(keys);
this.removeAction = removeAction;
if (removeAction) {
if (isRemoveAction) {
Assertions.checkArgument(keys.length == 0);
this.keys = keys;
} else {
this.keys = keys.clone();
Arrays.sort(this.keys);
}
}
@Override
public final boolean isRemoveAction() {
return removeAction;
}
@Override
public final void writeToStream(DataOutputStream output) throws IOException {
output.writeBoolean(isRemoveAction);
output.writeUTF(data);
output.writeUTF(manifestUri.toString());
output.writeUTF(getData());
output.writeBoolean(removeAction);
output.writeInt(keys.length);
for (K key : keys) {
writeKey(output, key);
@ -103,7 +104,6 @@ public abstract class SegmentDownloadAction<K> extends DownloadAction {
/** Serializes the {@code key} into the {@code output}. */
protected abstract void writeKey(DataOutputStream output, K key) throws IOException;
@Override
public boolean isSameMedia(DownloadAction other) {
return other instanceof SegmentDownloadAction
@ -119,10 +119,7 @@ public abstract class SegmentDownloadAction<K> extends DownloadAction {
return false;
}
SegmentDownloadAction<?> that = (SegmentDownloadAction<?>) o;
return manifestUri.equals(that.manifestUri)
&& removeAction == that.removeAction
&& keys.length == that.keys.length
&& Arrays.asList(keys).containsAll(Arrays.asList(that.keys));
return manifestUri.equals(that.manifestUri) && Arrays.equals(keys, that.keys);
}
@Override

View File

@ -80,24 +80,35 @@ public class ActionFileTest {
@Test
public void testLoadAction() throws Exception {
DownloadAction[] actions = loadActions(
new Object[] {DownloadAction.MASTER_VERSION, /*action count*/1, /*action 1*/"type2", 321},
DownloadAction[] actions =
loadActions(
new Object[] {
DownloadAction.MASTER_VERSION, /*action count*/ 1, /*action 1*/ "type2", "321"
},
new FakeDeserializer("type2"));
assertThat(actions).isNotNull();
assertThat(actions).hasLength(1);
assertAction(actions[0], "type2", DownloadAction.MASTER_VERSION, 321);
assertAction(actions[0], "type2", DownloadAction.MASTER_VERSION, "321");
}
@Test
public void testLoadActions() throws Exception {
DownloadAction[] actions = loadActions(
new Object[] {DownloadAction.MASTER_VERSION, /*action count*/2, /*action 1*/"type1", 123,
/*action 2*/"type2", 321}, // Action 2
new FakeDeserializer("type1"), new FakeDeserializer("type2"));
DownloadAction[] actions =
loadActions(
new Object[] {
DownloadAction.MASTER_VERSION, /*action count*/
2, /*action 1*/
"type1",
"123",
/*action 2*/ "type2",
"321"
}, // Action 2
new FakeDeserializer("type1"),
new FakeDeserializer("type2"));
assertThat(actions).isNotNull();
assertThat(actions).hasLength(2);
assertAction(actions[0], "type1", DownloadAction.MASTER_VERSION, 123);
assertAction(actions[1], "type2", DownloadAction.MASTER_VERSION, 321);
assertAction(actions[0], "type1", DownloadAction.MASTER_VERSION, "123");
assertAction(actions[1], "type2", DownloadAction.MASTER_VERSION, "321");
}
@Test
@ -129,10 +140,13 @@ public class ActionFileTest {
@Test
public void testStoreAndLoadActions() throws Exception {
doTestSerializationRoundTrip(new DownloadAction[] {
new FakeDownloadAction("type1", DownloadAction.MASTER_VERSION, 123),
new FakeDownloadAction("type2", DownloadAction.MASTER_VERSION, 321),
}, new FakeDeserializer("type1"), new FakeDeserializer("type2"));
doTestSerializationRoundTrip(
new DownloadAction[] {
new FakeDownloadAction("type1", DownloadAction.MASTER_VERSION, "123"),
new FakeDownloadAction("type2", DownloadAction.MASTER_VERSION, "321"),
},
new FakeDeserializer("type1"),
new FakeDeserializer("type2"));
}
private void doTestSerializationRoundTrip(DownloadAction[] actions,
@ -149,9 +163,9 @@ public class ActionFileTest {
try {
for (Object value : values) {
if (value instanceof Integer) {
dataOutputStream.writeInt((Integer) value); // Action count
dataOutputStream.writeInt((Integer) value);
} else if (value instanceof String) {
dataOutputStream.writeUTF((String) value); // Action count
dataOutputStream.writeUTF((String) value);
} else {
throw new IllegalArgumentException();
}
@ -162,56 +176,37 @@ public class ActionFileTest {
return new ActionFile(tempFile).load(deserializers);
}
private static void assertAction(DownloadAction action, String type, int version, int data) {
private static void assertAction(DownloadAction action, String type, int version, String data) {
assertThat(action).isInstanceOf(FakeDownloadAction.class);
assertThat(action.getType()).isEqualTo(type);
assertThat(action.type).isEqualTo(type);
assertThat(((FakeDownloadAction) action).version).isEqualTo(version);
assertThat(((FakeDownloadAction) action).data).isEqualTo(data);
}
private static class FakeDeserializer implements Deserializer {
final String type;
private static class FakeDeserializer extends Deserializer {
FakeDeserializer(String type) {
this.type = type;
}
@Override
public String getType() {
return type;
super(type);
}
@Override
public DownloadAction readFromStream(int version, DataInputStream input) throws IOException {
return new FakeDownloadAction(type, version, input.readInt());
return new FakeDownloadAction(type, version, input.readUTF());
}
}
private static class FakeDownloadAction extends DownloadAction {
final String type;
final int version;
final int data;
private FakeDownloadAction(String type, int version, int data) {
super(null);
this.type = type;
public final int version;
private FakeDownloadAction(String type, int version, String data) {
super(type, false, data);
this.version = version;
this.data = data;
}
@Override
protected String getType() {
return type;
}
@Override
protected void writeToStream(DataOutputStream output) throws IOException {
output.writeInt(data);
}
@Override
public boolean isRemoveAction() {
return false;
output.writeUTF(data);
}
@Override
@ -235,14 +230,14 @@ public class ActionFileTest {
return false;
}
FakeDownloadAction that = (FakeDownloadAction) o;
return version == that.version && data == that.data && type.equals(that.type);
return version == that.version && data.equals(that.data) && type.equals(that.type);
}
@Override
public int hashCode() {
int result = type.hashCode();
result = 31 * result + version;
result = 31 * result + data;
result = 31 * result + data.hashCode();
return result;
}
}

View File

@ -482,11 +482,11 @@ public class DownloadManagerTest {
}
private FakeDownloadAction createDownloadAction(String mediaId) {
return new FakeDownloadAction(mediaId, false);
return new FakeDownloadAction(/* isRemoveAction= */ false, mediaId);
}
private FakeDownloadAction createRemoveAction(String mediaId) {
return new FakeDownloadAction(mediaId, true);
return new FakeDownloadAction(/* isRemoveAction= */ true, mediaId);
}
private void runOnMainThread(final Runnable r) throws Throwable {
@ -531,33 +531,21 @@ public class DownloadManagerTest {
private class FakeDownloadAction extends DownloadAction {
private final String mediaId;
private final boolean removeAction;
private final FakeDownloader downloader;
private final BlockingQueue<Integer> states;
private FakeDownloadAction(String mediaId, boolean removeAction) {
super(mediaId);
private FakeDownloadAction(boolean isRemoveAction, @Nullable String mediaId) {
super("FakeDownloadAction", isRemoveAction, mediaId);
this.mediaId = mediaId;
this.removeAction = removeAction;
this.downloader = new FakeDownloader(removeAction);
this.downloader = new FakeDownloader(isRemoveAction);
this.states = new ArrayBlockingQueue<>(10);
}
@Override
protected String getType() {
return "FakeDownloadAction";
}
@Override
protected void writeToStream(DataOutputStream output) throws IOException {
// do nothing.
}
@Override
public boolean isRemoveAction() {
return removeAction;
}
@Override
protected boolean isSameMedia(DownloadAction other) {
return other instanceof FakeDownloadAction
@ -661,15 +649,15 @@ public class DownloadManagerTest {
private static class FakeDownloader implements Downloader {
private final com.google.android.exoplayer2.util.ConditionVariable blocker;
private final boolean removeAction;
private final boolean isRemoveAction;
private CountDownLatch started;
private boolean ignoreInterrupts;
private volatile boolean enableDownloadIOException;
private volatile int downloadedBytes = C.LENGTH_UNSET;
private FakeDownloader(boolean removeAction) {
this.removeAction = removeAction;
private FakeDownloader(boolean isRemoveAction) {
this.isRemoveAction = isRemoveAction;
this.started = new CountDownLatch(1);
this.blocker = new com.google.android.exoplayer2.util.ConditionVariable();
}
@ -682,7 +670,7 @@ public class DownloadManagerTest {
@Override
public void download(@Nullable ProgressListener listener)
throws InterruptedException, IOException {
assertThat(removeAction).isFalse();
assertThat(isRemoveAction).isFalse();
started.countDown();
block();
if (enableDownloadIOException) {
@ -692,7 +680,7 @@ public class DownloadManagerTest {
@Override
public void remove() throws InterruptedException {
assertThat(removeAction).isTrue();
assertThat(isRemoveAction).isTrue();
started.countDown();
block();
}

View File

@ -49,20 +49,20 @@ public class ProgressiveDownloadActionTest {
@Test
public void testDownloadActionIsNotRemoveAction() throws Exception {
ProgressiveDownloadAction action = new ProgressiveDownloadAction(uri1, null, false, null);
assertThat(action.isRemoveAction()).isFalse();
ProgressiveDownloadAction action = new ProgressiveDownloadAction(false, null, uri1, null);
assertThat(action.isRemoveAction).isFalse();
}
@Test
public void testRemoveActionIsRemoveAction() throws Exception {
ProgressiveDownloadAction action2 = new ProgressiveDownloadAction(uri1, null, true, null);
assertThat(action2.isRemoveAction()).isTrue();
public void testRemoveActionisRemoveAction() throws Exception {
ProgressiveDownloadAction action2 = new ProgressiveDownloadAction(true, null, uri1, null);
assertThat(action2.isRemoveAction).isTrue();
}
@Test
public void testCreateDownloader() throws Exception {
MockitoAnnotations.initMocks(this);
ProgressiveDownloadAction action = new ProgressiveDownloadAction(uri1, null, false, null);
ProgressiveDownloadAction action = new ProgressiveDownloadAction(false, null, uri1, null);
DownloaderConstructorHelper constructorHelper = new DownloaderConstructorHelper(
Mockito.mock(Cache.class), DummyDataSource.FACTORY);
assertThat(action.createDownloader(constructorHelper)).isNotNull();
@ -70,75 +70,75 @@ public class ProgressiveDownloadActionTest {
@Test
public void testSameUriCacheKeyDifferentAction_IsSameMedia() throws Exception {
ProgressiveDownloadAction action1 = new ProgressiveDownloadAction(uri1, null, true, null);
ProgressiveDownloadAction action2 = new ProgressiveDownloadAction(uri1, null, false, null);
ProgressiveDownloadAction action1 = new ProgressiveDownloadAction(true, null, uri1, null);
ProgressiveDownloadAction action2 = new ProgressiveDownloadAction(false, null, uri1, null);
assertSameMedia(action1, action2);
}
@Test
public void testNullCacheKeyDifferentUriAction_IsNotSameMedia() throws Exception {
ProgressiveDownloadAction action3 = new ProgressiveDownloadAction(uri2, null, true, null);
ProgressiveDownloadAction action4 = new ProgressiveDownloadAction(uri1, null, false, null);
ProgressiveDownloadAction action3 = new ProgressiveDownloadAction(true, null, uri2, null);
ProgressiveDownloadAction action4 = new ProgressiveDownloadAction(false, null, uri1, null);
assertNotSameMedia(action3, action4);
}
@Test
public void testSameCacheKeyDifferentUriAction_IsSameMedia() throws Exception {
ProgressiveDownloadAction action5 = new ProgressiveDownloadAction(uri2, "key", true, null);
ProgressiveDownloadAction action6 = new ProgressiveDownloadAction(uri1, "key", false, null);
ProgressiveDownloadAction action5 = new ProgressiveDownloadAction(true, null, uri2, "key");
ProgressiveDownloadAction action6 = new ProgressiveDownloadAction(false, null, uri1, "key");
assertSameMedia(action5, action6);
}
@Test
public void testSameUriDifferentCacheKeyAction_IsNotSameMedia() throws Exception {
ProgressiveDownloadAction action7 = new ProgressiveDownloadAction(uri1, "key", true, null);
ProgressiveDownloadAction action8 = new ProgressiveDownloadAction(uri1, "key2", false, null);
ProgressiveDownloadAction action7 = new ProgressiveDownloadAction(true, null, uri1, "key");
ProgressiveDownloadAction action8 = new ProgressiveDownloadAction(false, null, uri1, "key2");
assertNotSameMedia(action7, action8);
}
@Test
public void testSameUriNullCacheKeyAction_IsNotSameMedia() throws Exception {
ProgressiveDownloadAction action1 = new ProgressiveDownloadAction(uri1, "key", true, null);
ProgressiveDownloadAction action2 = new ProgressiveDownloadAction(uri1, null, false, null);
ProgressiveDownloadAction action1 = new ProgressiveDownloadAction(true, null, uri1, "key");
ProgressiveDownloadAction action2 = new ProgressiveDownloadAction(false, null, uri1, null);
assertNotSameMedia(action1, action2);
}
@Test
public void testEquals() throws Exception {
ProgressiveDownloadAction action1 = new ProgressiveDownloadAction(uri1, null, true, null);
ProgressiveDownloadAction action1 = new ProgressiveDownloadAction(true, null, uri1, null);
assertThat(action1.equals(action1)).isTrue();
ProgressiveDownloadAction action2 = new ProgressiveDownloadAction(uri1, null, true, null);
ProgressiveDownloadAction action3 = new ProgressiveDownloadAction(uri1, null, true, null);
ProgressiveDownloadAction action2 = new ProgressiveDownloadAction(true, null, uri1, null);
ProgressiveDownloadAction action3 = new ProgressiveDownloadAction(true, null, uri1, null);
assertThat(action2.equals(action3)).isTrue();
ProgressiveDownloadAction action4 = new ProgressiveDownloadAction(uri1, null, true, null);
ProgressiveDownloadAction action5 = new ProgressiveDownloadAction(uri1, null, false, null);
ProgressiveDownloadAction action4 = new ProgressiveDownloadAction(true, null, uri1, null);
ProgressiveDownloadAction action5 = new ProgressiveDownloadAction(false, null, uri1, null);
assertThat(action4.equals(action5)).isFalse();
ProgressiveDownloadAction action6 = new ProgressiveDownloadAction(uri1, null, true, null);
ProgressiveDownloadAction action7 = new ProgressiveDownloadAction(uri1, "key", true, null);
ProgressiveDownloadAction action6 = new ProgressiveDownloadAction(true, null, uri1, null);
ProgressiveDownloadAction action7 = new ProgressiveDownloadAction(true, null, uri1, "key");
assertThat(action6.equals(action7)).isFalse();
ProgressiveDownloadAction action8 = new ProgressiveDownloadAction(uri1, "key2", true, null);
ProgressiveDownloadAction action9 = new ProgressiveDownloadAction(uri1, "key", true, null);
ProgressiveDownloadAction action8 = new ProgressiveDownloadAction(true, null, uri1, "key2");
ProgressiveDownloadAction action9 = new ProgressiveDownloadAction(true, null, uri1, "key");
assertThat(action8.equals(action9)).isFalse();
ProgressiveDownloadAction action10 = new ProgressiveDownloadAction(uri1, null, true, null);
ProgressiveDownloadAction action11 = new ProgressiveDownloadAction(uri2, null, true, null);
ProgressiveDownloadAction action10 = new ProgressiveDownloadAction(true, null, uri1, null);
ProgressiveDownloadAction action11 = new ProgressiveDownloadAction(true, null, uri2, null);
assertThat(action10.equals(action11)).isFalse();
}
@Test
public void testSerializerGetType() throws Exception {
ProgressiveDownloadAction action = new ProgressiveDownloadAction(uri1, null, false, null);
assertThat(action.getType()).isNotNull();
ProgressiveDownloadAction action = new ProgressiveDownloadAction(false, null, uri1, null);
assertThat(action.type).isNotNull();
}
@Test
public void testSerializerWriteRead() throws Exception {
doTestSerializationRoundTrip(new ProgressiveDownloadAction(uri1, null, false, null));
doTestSerializationRoundTrip(new ProgressiveDownloadAction(uri2, "key", true, null));
doTestSerializationRoundTrip(new ProgressiveDownloadAction(false, null, uri1, null));
doTestSerializationRoundTrip(new ProgressiveDownloadAction(true, null, uri2, "key"));
}
private void assertSameMedia(

View File

@ -28,13 +28,10 @@ import java.io.IOException;
/** An action to download or remove downloaded DASH streams. */
public final class DashDownloadAction extends SegmentDownloadAction<RepresentationKey> {
public static final Deserializer DESERIALIZER =
new SegmentDownloadActionDeserializer<RepresentationKey>() {
private static final String TYPE = "DashDownloadAction";
@Override
public String getType() {
return TYPE;
}
public static final Deserializer DESERIALIZER =
new SegmentDownloadActionDeserializer<RepresentationKey>(TYPE) {
@Override
protected RepresentationKey readKey(DataInputStream input) throws IOException {
@ -47,32 +44,24 @@ public final class DashDownloadAction extends SegmentDownloadAction<Representati
}
@Override
protected DownloadAction createDownloadAction(Uri manifestUri, boolean removeAction,
String data, RepresentationKey[] keys) {
return new DashDownloadAction(manifestUri, removeAction, data, keys);
protected DownloadAction createDownloadAction(
boolean isRemoveAction, String data, Uri manifestUri, RepresentationKey[] keys) {
return new DashDownloadAction(isRemoveAction, data, manifestUri, keys);
}
};
private static final String TYPE = "DashDownloadAction";
/** @see SegmentDownloadAction#SegmentDownloadAction(Uri, boolean, String, Object[]) */
/**
* @see SegmentDownloadAction#SegmentDownloadAction(String, boolean, String, Uri, Comparable[])
*/
public DashDownloadAction(
Uri manifestUri, boolean removeAction, @Nullable String data, RepresentationKey... keys) {
super(manifestUri, removeAction, data, keys);
}
@Override
protected String getType() {
return TYPE;
boolean isRemoveAction, @Nullable String data, Uri manifestUri, RepresentationKey... keys) {
super(TYPE, isRemoveAction, data, manifestUri, keys);
}
@Override
protected DashDownloader createDownloader(DownloaderConstructorHelper constructorHelper) {
DashDownloader downloader = new DashDownloader(manifestUri, constructorHelper);
if (!isRemoveAction()) {
downloader.selectRepresentations(keys);
}
return downloader;
}

View File

@ -28,6 +28,7 @@ import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
@ -40,22 +41,34 @@ import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class DashDownloadActionTest {
@Test
public void testDownloadActionIsNotRemoveAction() throws Exception {
DashDownloadAction action = new DashDownloadAction(Uri.parse("uri"), false, null);
assertThat(action.isRemoveAction()).isFalse();
private Uri uri1;
private Uri uri2;
@Before
public void setUp() {
uri1 = Uri.parse("http://test1.uri");
uri2 = Uri.parse("http://test2.uri");
}
@Test
public void testRemoveActionIsRemoveAction() throws Exception {
DashDownloadAction action2 = new DashDownloadAction(Uri.parse("uri"), true, null);
assertThat(action2.isRemoveAction()).isTrue();
public void testDownloadActionIsNotRemoveAction() throws Exception {
DashDownloadAction action =
new DashDownloadAction(/* isRemoveAction= */ false, /* data= */ null, uri1);
assertThat(action.isRemoveAction).isFalse();
}
@Test
public void testRemoveActionisRemoveAction() throws Exception {
DashDownloadAction action2 =
new DashDownloadAction(/* isRemoveAction= */ true, /* data= */ null, uri1);
assertThat(action2.isRemoveAction).isTrue();
}
@Test
public void testCreateDownloader() throws Exception {
MockitoAnnotations.initMocks(this);
DashDownloadAction action = new DashDownloadAction(Uri.parse("uri"), false, null);
DashDownloadAction action =
new DashDownloadAction(/* isRemoveAction= */ false, /* data= */ null, uri1);
DownloaderConstructorHelper constructorHelper = new DownloaderConstructorHelper(
Mockito.mock(Cache.class), DummyDataSource.FACTORY);
assertThat(action.createDownloader(constructorHelper)).isNotNull();
@ -63,77 +76,118 @@ public class DashDownloadActionTest {
@Test
public void testSameUriDifferentAction_IsSameMedia() throws Exception {
DashDownloadAction action1 = new DashDownloadAction(Uri.parse("uri"), true, null);
DashDownloadAction action2 = new DashDownloadAction(Uri.parse("uri"), false, null);
DashDownloadAction action1 =
new DashDownloadAction(/* isRemoveAction= */ true, /* data= */ null, uri1);
DashDownloadAction action2 =
new DashDownloadAction(/* isRemoveAction= */ false, /* data= */ null, uri1);
assertThat(action1.isSameMedia(action2)).isTrue();
}
@Test
public void testDifferentUriAndAction_IsNotSameMedia() throws Exception {
DashDownloadAction action3 = new DashDownloadAction(Uri.parse("uri2"), true, null);
DashDownloadAction action4 = new DashDownloadAction(Uri.parse("uri"), false, null);
DashDownloadAction action3 =
new DashDownloadAction(/* isRemoveAction= */ true, /* data= */ null, uri2);
DashDownloadAction action4 =
new DashDownloadAction(/* isRemoveAction= */ false, /* data= */ null, uri1);
assertThat(action3.isSameMedia(action4)).isFalse();
}
@SuppressWarnings("EqualsWithItself")
@Test
public void testEquals() throws Exception {
DashDownloadAction action1 = new DashDownloadAction(Uri.parse("uri"), true, null);
DashDownloadAction action1 =
new DashDownloadAction(/* isRemoveAction= */ true, /* data= */ null, uri1);
assertThat(action1.equals(action1)).isTrue();
DashDownloadAction action2 = new DashDownloadAction(Uri.parse("uri"), true, null);
DashDownloadAction action3 = new DashDownloadAction(Uri.parse("uri"), true, null);
DashDownloadAction action2 =
new DashDownloadAction(/* isRemoveAction= */ true, /* data= */ null, uri1);
DashDownloadAction action3 =
new DashDownloadAction(/* isRemoveAction= */ true, /* data= */ null, uri1);
assertEqual(action2, action3);
DashDownloadAction action4 = new DashDownloadAction(Uri.parse("uri"), true, null);
DashDownloadAction action5 = new DashDownloadAction(Uri.parse("uri"), false, null);
DashDownloadAction action4 =
new DashDownloadAction(/* isRemoveAction= */ true, /* data= */ null, uri1);
DashDownloadAction action5 =
new DashDownloadAction(/* isRemoveAction= */ false, /* data= */ null, uri1);
assertNotEqual(action4, action5);
DashDownloadAction action6 = new DashDownloadAction(Uri.parse("uri"), false, null);
DashDownloadAction action6 =
new DashDownloadAction(/* isRemoveAction= */ false, /* data= */ null, uri1);
DashDownloadAction action7 =
new DashDownloadAction(Uri.parse("uri"), false, null, new RepresentationKey(0, 0, 0));
new DashDownloadAction(
/* isRemoveAction= */ false, /* data= */ null, uri1, new RepresentationKey(0, 0, 0));
assertNotEqual(action6, action7);
DashDownloadAction action8 =
new DashDownloadAction(Uri.parse("uri"), false, null, new RepresentationKey(1, 1, 1));
new DashDownloadAction(
/* isRemoveAction= */ false, /* data= */ null, uri1, new RepresentationKey(1, 1, 1));
DashDownloadAction action9 =
new DashDownloadAction(Uri.parse("uri"), false, null, new RepresentationKey(0, 0, 0));
new DashDownloadAction(
/* isRemoveAction= */ false, /* data= */ null, uri1, new RepresentationKey(0, 0, 0));
assertNotEqual(action8, action9);
DashDownloadAction action10 = new DashDownloadAction(Uri.parse("uri"), true, null);
DashDownloadAction action11 = new DashDownloadAction(Uri.parse("uri2"), true, null);
DashDownloadAction action10 =
new DashDownloadAction(/* isRemoveAction= */ true, /* data= */ null, uri1);
DashDownloadAction action11 =
new DashDownloadAction(/* isRemoveAction= */ true, /* data= */ null, uri2);
assertNotEqual(action10, action11);
DashDownloadAction action12 = new DashDownloadAction(Uri.parse("uri"), false, null,
new RepresentationKey(0, 0, 0), new RepresentationKey(1, 1, 1));
DashDownloadAction action13 = new DashDownloadAction(Uri.parse("uri"), false, null,
new RepresentationKey(1, 1, 1), new RepresentationKey(0, 0, 0));
DashDownloadAction action12 =
new DashDownloadAction(
/* isRemoveAction= */ false,
/* data= */ null,
uri1,
new RepresentationKey(0, 0, 0),
new RepresentationKey(1, 1, 1));
DashDownloadAction action13 =
new DashDownloadAction(
/* isRemoveAction= */ false,
/* data= */ null,
uri1,
new RepresentationKey(1, 1, 1),
new RepresentationKey(0, 0, 0));
assertEqual(action12, action13);
DashDownloadAction action14 = new DashDownloadAction(Uri.parse("uri"), false, null,
DashDownloadAction action14 =
new DashDownloadAction(
/* isRemoveAction= */ false, /* data= */ null, uri1, new RepresentationKey(0, 0, 0));
DashDownloadAction action15 =
new DashDownloadAction(
/* isRemoveAction= */ false,
/* data= */ null,
uri1,
new RepresentationKey(1, 1, 1),
new RepresentationKey(0, 0, 0));
DashDownloadAction action15 = new DashDownloadAction(Uri.parse("uri"), false, null,
new RepresentationKey(1, 1, 1), new RepresentationKey(0, 0, 0));
assertNotEqual(action14, action15);
DashDownloadAction action16 = new DashDownloadAction(Uri.parse("uri"), false, null);
DashDownloadAction action16 =
new DashDownloadAction(/* isRemoveAction= */ false, /* data= */ null, uri1);
DashDownloadAction action17 =
new DashDownloadAction(Uri.parse("uri"), false, null, new RepresentationKey[0]);
new DashDownloadAction(
/* isRemoveAction= */ false, /* data= */ null, uri1, new RepresentationKey[0]);
assertEqual(action16, action17);
}
@Test
public void testSerializerGetType() throws Exception {
DashDownloadAction action = new DashDownloadAction(Uri.parse("uri"), false, null);
assertThat(action.getType()).isNotNull();
DashDownloadAction action =
new DashDownloadAction(/* isRemoveAction= */ false, /* data= */ null, uri1);
assertThat(action.type).isNotNull();
}
@Test
public void testSerializerWriteRead() throws Exception {
doTestSerializationRoundTrip(new DashDownloadAction(Uri.parse("uri"), false, null));
doTestSerializationRoundTrip(new DashDownloadAction(Uri.parse("uri"), true, null));
doTestSerializationRoundTrip(new DashDownloadAction(Uri.parse("uri2"), false, null,
new RepresentationKey(0, 0, 0), new RepresentationKey(1, 1, 1)));
doTestSerializationRoundTrip(
new DashDownloadAction(/* isRemoveAction= */ false, /* data= */ null, uri1));
doTestSerializationRoundTrip(
new DashDownloadAction(/* isRemoveAction= */ true, /* data= */ null, uri1));
doTestSerializationRoundTrip(
new DashDownloadAction(
/* isRemoveAction= */ false,
/* data= */ null,
uri2,
new RepresentationKey(0, 0, 0),
new RepresentationKey(1, 1, 1)));
}
private static void assertNotEqual(DashDownloadAction action1, DashDownloadAction action2) {

View File

@ -244,11 +244,11 @@ public class DownloadManagerDashTest {
}
private void handleDownloadAction(RepresentationKey... keys) {
downloadManager.handleAction(new DashDownloadAction(TEST_MPD_URI, false, null, keys));
downloadManager.handleAction(new DashDownloadAction(false, null, TEST_MPD_URI, keys));
}
private void handleRemoveAction() {
downloadManager.handleAction(new DashDownloadAction(TEST_MPD_URI, true, null));
downloadManager.handleAction(new DashDownloadAction(true, null, TEST_MPD_URI));
}
private void createDownloadManager() {

View File

@ -216,11 +216,11 @@ public class DownloadServiceDashTest {
}
private void removeAll() throws Throwable {
callDownloadServiceOnStart(new DashDownloadAction(TEST_MPD_URI, true, null));
callDownloadServiceOnStart(new DashDownloadAction(true, null, TEST_MPD_URI));
}
private void downloadKeys(RepresentationKey... keys) throws Throwable {
callDownloadServiceOnStart(new DashDownloadAction(TEST_MPD_URI, false, null, keys));
callDownloadServiceOnStart(new DashDownloadAction(false, null, TEST_MPD_URI, keys));
}
private void callDownloadServiceOnStart(final DashDownloadAction action) {

View File

@ -28,13 +28,10 @@ import java.io.IOException;
/** An action to download or remove downloaded HLS streams. */
public final class HlsDownloadAction extends SegmentDownloadAction<RenditionKey> {
public static final Deserializer DESERIALIZER =
new SegmentDownloadActionDeserializer<RenditionKey>() {
private static final String TYPE = "HlsDownloadAction";
@Override
public String getType() {
return TYPE;
}
public static final Deserializer DESERIALIZER =
new SegmentDownloadActionDeserializer<RenditionKey>(TYPE) {
@Override
protected RenditionKey readKey(DataInputStream input) throws IOException {
@ -48,30 +45,23 @@ public final class HlsDownloadAction extends SegmentDownloadAction<RenditionKey>
@Override
protected DownloadAction createDownloadAction(
Uri manifestUri, boolean removeAction, String data, RenditionKey[] keys) {
return new HlsDownloadAction(manifestUri, removeAction, data, keys);
boolean isRemoveAction, String data, Uri manifestUri, RenditionKey[] keys) {
return new HlsDownloadAction(isRemoveAction, data, manifestUri, keys);
}
};
private static final String TYPE = "HlsDownloadAction";
/** @see SegmentDownloadAction#SegmentDownloadAction(Uri, boolean, String, Object[]) */
/**
* @see SegmentDownloadAction#SegmentDownloadAction(String, boolean, String, Uri, Comparable[])
*/
public HlsDownloadAction(
Uri manifestUri, boolean removeAction, @Nullable String data, RenditionKey... keys) {
super(manifestUri, removeAction, data, keys);
}
@Override
protected String getType() {
return TYPE;
boolean isRemoveAction, @Nullable String data, Uri manifestUri, RenditionKey... keys) {
super(TYPE, isRemoveAction, data, manifestUri, keys);
}
@Override
protected HlsDownloader createDownloader(DownloaderConstructorHelper constructorHelper) {
HlsDownloader downloader = new HlsDownloader(manifestUri, constructorHelper);
if (!isRemoveAction()) {
downloader.selectRepresentations(keys);
}
return downloader;
}

View File

@ -17,9 +17,10 @@ package com.google.android.exoplayer2.source.hls.playlist;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
/** Uniquely identifies a rendition in an {@link HlsMasterPlaylist}. */
public final class RenditionKey implements Parcelable {
public final class RenditionKey implements Parcelable, Comparable<RenditionKey> {
public final String url;
@ -51,4 +52,11 @@ public final class RenditionKey implements Parcelable {
return new RenditionKey[size];
}
};
// Comparable implementation.
@Override
public int compareTo(@NonNull RenditionKey o) {
return url.compareTo(o.url);
}
}

View File

@ -28,13 +28,10 @@ import java.io.IOException;
/** An action to download or remove downloaded SmoothStreaming streams. */
public final class SsDownloadAction extends SegmentDownloadAction<TrackKey> {
public static final Deserializer DESERIALIZER =
new SegmentDownloadActionDeserializer<TrackKey>() {
private static final String TYPE = "SsDownloadAction";
@Override
public String getType() {
return TYPE;
}
public static final Deserializer DESERIALIZER =
new SegmentDownloadActionDeserializer<TrackKey>(TYPE) {
@Override
protected TrackKey readKey(DataInputStream input) throws IOException {
@ -47,32 +44,24 @@ public final class SsDownloadAction extends SegmentDownloadAction<TrackKey> {
}
@Override
protected DownloadAction createDownloadAction(Uri manifestUri, boolean removeAction,
String data, TrackKey[] keys) {
return new SsDownloadAction(manifestUri, removeAction, data, keys);
protected DownloadAction createDownloadAction(
boolean isRemoveAction, String data, Uri manifestUri, TrackKey[] keys) {
return new SsDownloadAction(isRemoveAction, data, manifestUri, keys);
}
};
private static final String TYPE = "SsDownloadAction";
/** @see SegmentDownloadAction#SegmentDownloadAction(Uri, boolean, String, Object[]) */
/**
* @see SegmentDownloadAction#SegmentDownloadAction(String, boolean, String, Uri, Comparable[])
*/
public SsDownloadAction(
Uri manifestUri, boolean removeAction, @Nullable String data, TrackKey... keys) {
super(manifestUri, removeAction, data, keys);
}
@Override
protected String getType() {
return TYPE;
boolean isRemoveAction, @Nullable String data, Uri manifestUri, TrackKey... keys) {
super(TYPE, isRemoveAction, data, manifestUri, keys);
}
@Override
protected SsDownloader createDownloader(DownloaderConstructorHelper constructorHelper) {
SsDownloader downloader = new SsDownloader(manifestUri, constructorHelper);
if (!isRemoveAction()) {
downloader.selectRepresentations(keys);
}
return downloader;
}

View File

@ -51,7 +51,7 @@ public final class DownloadNotificationUtil {
int determinatePercentageCount = 0;
boolean isAnyDownloadActive = false;
for (DownloadState downloadState : downloadStates) {
if (downloadState.downloadAction.isRemoveAction()
if (downloadState.downloadAction.isRemoveAction
|| downloadState.state != DownloadState.STATE_STARTED) {
continue;
}
@ -102,7 +102,7 @@ public final class DownloadNotificationUtil {
String channelId,
@Nullable String message,
@Nullable ErrorMessageProvider<Throwable> errorMessageProvider) {
if (downloadState.downloadAction.isRemoveAction()
if (downloadState.downloadAction.isRemoveAction
|| (downloadState.state != DownloadState.STATE_ENDED
&& downloadState.state != DownloadState.STATE_ERROR)) {
return null;