Make download action custom data a byte[]

This may be preferable for using custom binary data,
and it's still easy to store Strings if needed.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=195486817
This commit is contained in:
andrewlewis 2018-05-04 16:06:22 -07:00 committed by Oliver Woodman
parent 9e122cbaf9
commit 4ee1daef0e
13 changed files with 69 additions and 47 deletions

View File

@ -73,7 +73,7 @@ public class DemoDownloadService extends DownloadService {
R.drawable.exo_controls_play,
CHANNEL_ID,
/* contentIntent= */ null,
taskState.action.data);
Util.fromUtf8Bytes(taskState.action.data));
} else if (taskState.state == TaskState.STATE_FAILED) {
notification =
DownloadNotificationUtil.buildDownloadFailedNotification(
@ -81,7 +81,7 @@ public class DemoDownloadService extends DownloadService {
R.drawable.exo_controls_play,
CHANNEL_ID,
/* contentIntent= */ null,
taskState.action.data);
Util.fromUtf8Bytes(taskState.action.data));
}
int notificationId = FOREGROUND_NOTIFICATION_ID + 1 + taskState.taskId;
NotificationUtil.setNotification(this, notificationId, notification);

View File

@ -275,7 +275,8 @@ public class DownloadActivity extends Activity {
@Override
public DownloadAction getDownloadAction(
boolean isRemoveAction, String sampleName, int... trackIndices) {
return new DashDownloadAction(uri, isRemoveAction, sampleName, getTrackKeys(trackIndices));
return new DashDownloadAction(
uri, isRemoveAction, Util.getUtf8Bytes(sampleName), getTrackKeys(trackIndices));
}
}
@ -310,7 +311,8 @@ public class DownloadActivity extends Activity {
@Override
public DownloadAction getDownloadAction(
boolean isRemoveAction, String sampleName, int... trackIndices) {
return new HlsDownloadAction(uri, isRemoveAction, sampleName, getTrackKeys(trackIndices));
return new HlsDownloadAction(
uri, isRemoveAction, Util.getUtf8Bytes(sampleName), getTrackKeys(trackIndices));
}
}
@ -337,7 +339,8 @@ public class DownloadActivity extends Activity {
@Override
public DownloadAction getDownloadAction(
boolean isRemoveAction, String sampleName, int... trackIndices) {
return new SsDownloadAction(uri, isRemoveAction, sampleName, getTrackKeys(trackIndices));
return new SsDownloadAction(
uri, isRemoveAction, Util.getUtf8Bytes(sampleName), getTrackKeys(trackIndices));
}
}
@ -356,7 +359,7 @@ public class DownloadActivity extends Activity {
public DownloadAction getDownloadAction(
boolean isRemoveAction, String sampleName, int... trackIndices) {
return new ProgressiveDownloadAction(
uri, isRemoveAction, sampleName, /* customCacheKey= */ null);
uri, isRemoveAction, Util.getUtf8Bytes(sampleName), /* customCacheKey= */ null);
}
}
}

View File

@ -23,6 +23,7 @@ import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
/** Contains the necessary parameters for a download or remove action. */
public abstract class DownloadAction {
@ -95,8 +96,8 @@ public abstract class DownloadAction {
public final Uri uri;
/** Whether this is a remove action. If false, this is a download action. */
public final boolean isRemoveAction;
/** Custom data for this action, or the empty string if no custom data was specified. */
public final String data;
/** Custom data for this action. May be empty. */
public final byte[] data;
/**
* @param type The type of the action.
@ -106,12 +107,12 @@ public abstract class DownloadAction {
* @param data Optional custom data for this action.
*/
protected DownloadAction(
String type, int version, Uri uri, boolean isRemoveAction, @Nullable String data) {
String type, int version, Uri uri, boolean isRemoveAction, @Nullable byte[] data) {
this.type = type;
this.version = version;
this.uri = uri;
this.isRemoveAction = isRemoveAction;
this.data = data != null ? data : "";
this.data = data != null ? data : new byte[0];
}
/** Serializes itself into a byte array. */
@ -148,14 +149,14 @@ public abstract class DownloadAction {
&& version == that.version
&& uri.equals(that.uri)
&& isRemoveAction == that.isRemoveAction
&& data.equals(that.data);
&& Arrays.equals(data, that.data);
}
@Override
public int hashCode() {
int result = uri.hashCode();
result = 31 * result + (isRemoveAction ? 1 : 0);
result = 31 * result + data.hashCode();
result = 31 * result + Arrays.hashCode(data);
return result;
}

View File

@ -654,8 +654,6 @@ public final class DownloadManager {
+ ' '
+ (action.isRemoveAction ? "remove" : "download")
+ ' '
+ action.data
+ ' '
+ getStateString();
}

View File

@ -36,7 +36,9 @@ public final class ProgressiveDownloadAction extends DownloadAction {
throws IOException {
Uri uri = Uri.parse(input.readUTF());
boolean isRemoveAction = input.readBoolean();
String data = input.readUTF();
int dataLength = input.readInt();
byte[] data = new byte[dataLength];
input.readFully(data);
String customCacheKey = input.readBoolean() ? input.readUTF() : null;
return new ProgressiveDownloadAction(uri, isRemoveAction, data, customCacheKey);
}
@ -47,12 +49,12 @@ public final class ProgressiveDownloadAction extends DownloadAction {
/**
* @param uri Uri of the data to be downloaded.
* @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 data Optional custom data for this action.
* @param customCacheKey A custom key that uniquely identifies the original stream. If not null it
* is used for cache indexing.
*/
public ProgressiveDownloadAction(
Uri uri, boolean isRemoveAction, @Nullable String data, @Nullable String customCacheKey) {
Uri uri, boolean isRemoveAction, @Nullable byte[] data, @Nullable String customCacheKey) {
super(TYPE, VERSION, uri, isRemoveAction, data);
this.customCacheKey = customCacheKey;
}
@ -66,7 +68,8 @@ public final class ProgressiveDownloadAction extends DownloadAction {
protected void writeToStream(DataOutputStream output) throws IOException {
output.writeUTF(uri.toString());
output.writeBoolean(isRemoveAction);
output.writeUTF(data);
output.writeInt(data.length);
output.write(data);
boolean customCacheKeySet = customCacheKey != null;
output.writeBoolean(customCacheKeySet);
if (customCacheKeySet) {

View File

@ -48,7 +48,9 @@ public abstract class SegmentDownloadAction<K extends Comparable<K>> extends Dow
throws IOException {
Uri uri = Uri.parse(input.readUTF());
boolean isRemoveAction = input.readBoolean();
String data = input.readUTF();
int dataLength = input.readInt();
byte[] data = new byte[dataLength];
input.readFully(data);
int keyCount = input.readInt();
List<K> keys = new ArrayList<>();
for (int i = 0; i < keyCount; i++) {
@ -62,7 +64,7 @@ public abstract class SegmentDownloadAction<K extends Comparable<K>> extends Dow
/** Returns a {@link DownloadAction}. */
protected abstract DownloadAction createDownloadAction(
Uri manifestUri, boolean isRemoveAction, String data, List<K> keys);
Uri manifestUri, boolean isRemoveAction, byte[] data, List<K> keys);
}
public final List<K> keys;
@ -72,7 +74,7 @@ public abstract class SegmentDownloadAction<K extends Comparable<K>> extends Dow
* @param version The action version.
* @param uri The URI of the media being downloaded.
* @param isRemoveAction Whether the data will be removed. If {@code false} it will be downloaded.
* @param data Optional custom data for this action.
* @param data Optional custom data for this action. If {@code null} an empty array will be used.
* @param keys Keys of tracks to be downloaded. If empty, all tracks will be downloaded. If {@code
* removeAction} is true, {@code keys} must be empty.
*/
@ -81,7 +83,7 @@ public abstract class SegmentDownloadAction<K extends Comparable<K>> extends Dow
int version,
Uri uri,
boolean isRemoveAction,
@Nullable String data,
@Nullable byte[] data,
List<K> keys) {
super(type, version, uri, isRemoveAction, data);
if (isRemoveAction) {
@ -98,7 +100,8 @@ public abstract class SegmentDownloadAction<K extends Comparable<K>> extends Dow
public final void writeToStream(DataOutputStream output) throws IOException {
output.writeUTF(uri.toString());
output.writeBoolean(isRemoveAction);
output.writeUTF(data);
output.writeInt(data.length);
output.write(data);
output.writeInt(keys.size());
for (int i = 0; i < keys.size(); i++) {
writeKey(output, keys.get(i));

View File

@ -80,6 +80,7 @@ public class ActionFileTest {
@Test
public void testLoadAction() throws Exception {
byte[] data = Util.getUtf8Bytes("321");
DownloadAction[] actions =
loadActions(
new Object[] {
@ -87,16 +88,18 @@ public class ActionFileTest {
1, // Action count
"type2", // Action 1
FakeDownloadAction.VERSION,
"321"
data,
},
new FakeDeserializer("type2"));
assertThat(actions).isNotNull();
assertThat(actions).hasLength(1);
assertAction(actions[0], "type2", FakeDownloadAction.VERSION, "321");
assertAction(actions[0], "type2", FakeDownloadAction.VERSION, data);
}
@Test
public void testLoadActions() throws Exception {
byte[] data1 = Util.getUtf8Bytes("123");
byte[] data2 = Util.getUtf8Bytes("321");
DownloadAction[] actions =
loadActions(
new Object[] {
@ -104,17 +107,17 @@ public class ActionFileTest {
2, // Action count
"type1", // Action 1
FakeDownloadAction.VERSION,
"123",
data1,
"type2", // Action 2
FakeDownloadAction.VERSION,
"321"
data2,
},
new FakeDeserializer("type1"),
new FakeDeserializer("type2"));
assertThat(actions).isNotNull();
assertThat(actions).hasLength(2);
assertAction(actions[0], "type1", FakeDownloadAction.VERSION, "123");
assertAction(actions[1], "type2", FakeDownloadAction.VERSION, "321");
assertAction(actions[0], "type1", FakeDownloadAction.VERSION, data1);
assertAction(actions[1], "type2", FakeDownloadAction.VERSION, data2);
}
@Test
@ -126,7 +129,7 @@ public class ActionFileTest {
1, // Action count
"type2", // Action 1
FakeDownloadAction.VERSION,
321
Util.getUtf8Bytes("321"),
},
new FakeDeserializer("type2"));
Assert.fail();
@ -144,7 +147,7 @@ public class ActionFileTest {
1, // Action count
"type2", // Action 1
FakeDownloadAction.VERSION + 1,
321
Util.getUtf8Bytes("321"),
},
new FakeDeserializer("type2"));
Assert.fail();
@ -162,7 +165,7 @@ public class ActionFileTest {
1, // Action count
"type2", // Action 1
FakeDownloadAction.VERSION,
321
Util.getUtf8Bytes("321"),
},
new FakeDeserializer("type1"));
Assert.fail();
@ -180,7 +183,8 @@ public class ActionFileTest {
public void testStoreAndLoadActions() throws Exception {
doTestSerializationRoundTrip(
new DownloadAction[] {
new FakeDownloadAction("type1", "123"), new FakeDownloadAction("type2", "321"),
new FakeDownloadAction("type1", Util.getUtf8Bytes("123")),
new FakeDownloadAction("type2", Util.getUtf8Bytes("321")),
},
new FakeDeserializer("type1"),
new FakeDeserializer("type2"));
@ -203,6 +207,10 @@ public class ActionFileTest {
dataOutputStream.writeInt((Integer) value);
} else if (value instanceof String) {
dataOutputStream.writeUTF((String) value);
} else if (value instanceof byte[]) {
byte[] data = (byte[]) value;
dataOutputStream.writeInt(data.length);
dataOutputStream.write(data);
} else {
throw new IllegalArgumentException();
}
@ -213,7 +221,7 @@ public class ActionFileTest {
return new ActionFile(tempFile).load(deserializers);
}
private static void assertAction(DownloadAction action, String type, int version, String data) {
private static void assertAction(DownloadAction action, String type, int version, byte[] data) {
assertThat(action).isInstanceOf(FakeDownloadAction.class);
assertThat(action.type).isEqualTo(type);
assertThat(((FakeDownloadAction) action).version).isEqualTo(version);
@ -228,7 +236,10 @@ public class ActionFileTest {
@Override
public DownloadAction readFromStream(int version, DataInputStream input) throws IOException {
return new FakeDownloadAction(type, input.readUTF());
int dataLength = input.readInt();
byte[] data = new byte[dataLength];
input.readFully(data);
return new FakeDownloadAction(type, data);
}
}
@ -236,13 +247,14 @@ public class ActionFileTest {
public static final int VERSION = 0;
private FakeDownloadAction(String type, String data) {
private FakeDownloadAction(String type, byte[] data) {
super(type, VERSION, Uri.parse("http://test.com"), /* isRemoveAction= */ false, data);
}
@Override
protected void writeToStream(DataOutputStream output) throws IOException {
output.writeUTF(data);
output.writeInt(data.length);
output.write(data);
}
@Override

View File

@ -42,7 +42,7 @@ public final class DashDownloadAction extends SegmentDownloadAction<Representati
@Override
protected DownloadAction createDownloadAction(
Uri uri, boolean isRemoveAction, String data, List<RepresentationKey> keys) {
Uri uri, boolean isRemoveAction, byte[] data, List<RepresentationKey> keys) {
return new DashDownloadAction(uri, isRemoveAction, data, keys);
}
};
@ -50,12 +50,12 @@ public final class DashDownloadAction extends SegmentDownloadAction<Representati
/**
* @param uri The DASH manifest URI.
* @param isRemoveAction 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.
* @param keys Keys of representations to be downloaded. If empty, all representations are
* downloaded. If {@code removeAction} is true, {@code keys} must be empty.
*/
public DashDownloadAction(
Uri uri, boolean isRemoveAction, @Nullable String data, List<RepresentationKey> keys) {
Uri uri, boolean isRemoveAction, @Nullable byte[] data, List<RepresentationKey> keys) {
super(TYPE, VERSION, uri, isRemoveAction, data, keys);
}

View File

@ -18,6 +18,7 @@ package com.google.android.exoplayer2.source.dash.offline;
import static com.google.common.truth.Truth.assertThat;
import android.net.Uri;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.offline.DownloadAction;
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
import com.google.android.exoplayer2.source.dash.manifest.RepresentationKey;
@ -196,7 +197,7 @@ public class DashDownloadActionTest {
}
private static DashDownloadAction newAction(
Uri uri, boolean isRemoveAction, String data, RepresentationKey... keys) {
Uri uri, boolean isRemoveAction, @Nullable byte[] data, RepresentationKey... keys) {
ArrayList<RepresentationKey> keysList = new ArrayList<>();
Collections.addAll(keysList, keys);
return new DashDownloadAction(uri, isRemoveAction, data, keysList);

View File

@ -24,6 +24,7 @@ import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.net.Uri;
import android.os.ConditionVariable;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.offline.DownloadManager;
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
import com.google.android.exoplayer2.source.dash.manifest.RepresentationKey;
@ -279,7 +280,7 @@ public class DownloadManagerDashTest {
}
private static DashDownloadAction newAction(
Uri uri, boolean isRemoveAction, String data, RepresentationKey... keys) {
Uri uri, boolean isRemoveAction, @Nullable byte[] data, RepresentationKey... keys) {
ArrayList<RepresentationKey> keysList = new ArrayList<>();
Collections.addAll(keysList, keys);
return new DashDownloadAction(uri, isRemoveAction, data, keysList);

View File

@ -237,7 +237,7 @@ public class DownloadServiceDashTest {
}
private static DashDownloadAction newAction(
Uri uri, boolean isRemoveAction, String data, RepresentationKey... keys) {
Uri uri, boolean isRemoveAction, @Nullable byte[] data, RepresentationKey... keys) {
ArrayList<RepresentationKey> keysList = new ArrayList<>();
Collections.addAll(keysList, keys);
return new DashDownloadAction(uri, isRemoveAction, data, keysList);

View File

@ -44,7 +44,7 @@ public final class HlsDownloadAction extends SegmentDownloadAction<RenditionKey>
@Override
protected DownloadAction createDownloadAction(
Uri uri, boolean isRemoveAction, String data, List<RenditionKey> keys) {
Uri uri, boolean isRemoveAction, byte[] data, List<RenditionKey> keys) {
return new HlsDownloadAction(uri, isRemoveAction, data, keys);
}
};
@ -57,7 +57,7 @@ public final class HlsDownloadAction extends SegmentDownloadAction<RenditionKey>
* {@code removeAction} is true, {@code keys} must empty.
*/
public HlsDownloadAction(
Uri uri, boolean isRemoveAction, @Nullable String data, List<RenditionKey> keys) {
Uri uri, boolean isRemoveAction, @Nullable byte[] data, List<RenditionKey> keys) {
super(TYPE, VERSION, uri, isRemoveAction, data, keys);
}

View File

@ -42,7 +42,7 @@ public final class SsDownloadAction extends SegmentDownloadAction<TrackKey> {
@Override
protected DownloadAction createDownloadAction(
Uri uri, boolean isRemoveAction, String data, List<TrackKey> keys) {
Uri uri, boolean isRemoveAction, byte[] data, List<TrackKey> keys) {
return new SsDownloadAction(uri, isRemoveAction, data, keys);
}
};
@ -55,7 +55,7 @@ public final class SsDownloadAction extends SegmentDownloadAction<TrackKey> {
* removeAction} is true, {@code keys} must be empty.
*/
public SsDownloadAction(
Uri uri, boolean isRemoveAction, @Nullable String data, List<TrackKey> keys) {
Uri uri, boolean isRemoveAction, @Nullable byte[] data, List<TrackKey> keys) {
super(TYPE, VERSION, uri, isRemoveAction, data, keys);
}