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, this,
R.drawable.exo_controls_play, R.drawable.exo_controls_play,
CHANNEL_ID, CHANNEL_ID,
downloadState.downloadAction.getData(), downloadState.downloadAction.data,
new ErrorMessageProvider<Throwable>() { new ErrorMessageProvider<Throwable>() {
@Override @Override
public Pair<Integer, String> getErrorMessage(Throwable throwable) { public Pair<Integer, String> getErrorMessage(Throwable throwable) {

View File

@ -293,12 +293,12 @@ public class DownloadActivity extends Activity {
String sampleName, ArrayList<Object> representationKeys) { String sampleName, ArrayList<Object> representationKeys) {
RepresentationKey[] keys = RepresentationKey[] keys =
representationKeys.toArray(new RepresentationKey[representationKeys.size()]); representationKeys.toArray(new RepresentationKey[representationKeys.size()]);
return new DashDownloadAction(manifestUri, false, sampleName, keys); return new DashDownloadAction(/* isRemoveAction= */ false, sampleName, manifestUri, keys);
} }
@Override @Override
public DownloadAction getRemoveAction() { 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( public DownloadAction getDownloadAction(
String sampleName, ArrayList<Object> representationKeys) { String sampleName, ArrayList<Object> representationKeys) {
RenditionKey[] keys = representationKeys.toArray(new RenditionKey[representationKeys.size()]); RenditionKey[] keys = representationKeys.toArray(new RenditionKey[representationKeys.size()]);
return new HlsDownloadAction(manifestUri, false, sampleName, keys); return new HlsDownloadAction(/* isRemoveAction= */ false, sampleName, manifestUri, keys);
} }
@Override @Override
public DownloadAction getRemoveAction() { 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( public DownloadAction getDownloadAction(
String sampleName, ArrayList<Object> representationKeys) { String sampleName, ArrayList<Object> representationKeys) {
TrackKey[] keys = representationKeys.toArray(new TrackKey[representationKeys.size()]); TrackKey[] keys = representationKeys.toArray(new TrackKey[representationKeys.size()]);
return new SsDownloadAction(manifestUri, false, sampleName, keys); return new SsDownloadAction(/* isRemoveAction= */ false, sampleName, manifestUri, keys);
} }
@Override @Override
public DownloadAction getRemoveAction() { 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 @Override
public DownloadAction getDownloadAction( public DownloadAction getDownloadAction(
String sampleName, ArrayList<Object> representationKeys) { String sampleName, ArrayList<Object> representationKeys) {
return new ProgressiveDownloadAction(manifestUri, null, false, sampleName); return new ProgressiveDownloadAction(
/* isRemoveAction= */ false, /* data= */ null, manifestUri, /* customCacheKey= */ null);
} }
@Override @Override
public DownloadAction getRemoveAction() { 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; public static final int MASTER_VERSION = 0;
/** Used to deserialize {@link DownloadAction}s. */ /** 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. */ public String type;
String getType();
public Deserializer(String type) {
this.type = type;
}
/** /**
* Deserializes a {@link DownloadAction} from the {@code input}. * Deserializes a {@link DownloadAction} from the {@code input}.
@ -47,7 +50,8 @@ public abstract class DownloadAction {
* @see DownloadAction#writeToStream(DataOutputStream) * @see DownloadAction#writeToStream(DataOutputStream)
* @see DownloadAction#MASTER_VERSION * @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); DataInputStream dataInputStream = new DataInputStream(input);
String type = dataInputStream.readUTF(); String type = dataInputStream.readUTF();
for (Deserializer deserializer : deserializers) { for (Deserializer deserializer : deserializers) {
if (type.equals(deserializer.getType())) { if (type.equals(deserializer.type)) {
return deserializer.readFromStream(version, dataInputStream); return deserializer.readFromStream(version, dataInputStream);
} }
} }
@ -101,15 +105,26 @@ public abstract class DownloadAction {
throws IOException { throws IOException {
// Don't close the stream as it closes the underlying stream too. // Don't close the stream as it closes the underlying stream too.
DataOutputStream dataOutputStream = new DataOutputStream(output); DataOutputStream dataOutputStream = new DataOutputStream(output);
dataOutputStream.writeUTF(action.getType()); dataOutputStream.writeUTF(action.type);
action.writeToStream(dataOutputStream); action.writeToStream(dataOutputStream);
dataOutputStream.flush(); 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 : ""; this.data = data != null ? data : "";
} }
@ -125,17 +140,6 @@ public abstract class DownloadAction {
return output.toByteArray(); 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}. */ /** Serializes itself into the {@code output}. */
protected abstract void writeToStream(DataOutputStream output) throws IOException; protected abstract void writeToStream(DataOutputStream output) throws IOException;
@ -152,13 +156,13 @@ public abstract class DownloadAction {
return false; return false;
} }
DownloadAction that = (DownloadAction) o; DownloadAction that = (DownloadAction) o;
return data.equals(that.data) && isRemoveAction() == that.isRemoveAction(); return data.equals(that.data) && isRemoveAction == that.isRemoveAction;
} }
@Override @Override
public int hashCode() { public int hashCode() {
int result = data.hashCode(); int result = data.hashCode();
result = 31 * result + (isRemoveAction() ? 1 : 0); result = 31 * result + (isRemoveAction ? 1 : 0);
return result; return result;
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -244,11 +244,11 @@ public class DownloadManagerDashTest {
} }
private void handleDownloadAction(RepresentationKey... keys) { 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() { private void handleRemoveAction() {
downloadManager.handleAction(new DashDownloadAction(TEST_MPD_URI, true, null)); downloadManager.handleAction(new DashDownloadAction(true, null, TEST_MPD_URI));
} }
private void createDownloadManager() { private void createDownloadManager() {

View File

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

View File

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

View File

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

View File

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