From 4ee1daef0e8648d69a18e643918c9d60ea919d17 Mon Sep 17 00:00:00 2001 From: andrewlewis Date: Fri, 4 May 2018 16:06:22 -0700 Subject: [PATCH] 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 --- .../exoplayer2/demo/DemoDownloadService.java | 4 +- .../exoplayer2/demo/DownloadActivity.java | 11 +++-- .../exoplayer2/offline/DownloadAction.java | 13 +++--- .../exoplayer2/offline/DownloadManager.java | 2 - .../offline/ProgressiveDownloadAction.java | 11 +++-- .../offline/SegmentDownloadAction.java | 13 +++--- .../exoplayer2/offline/ActionFileTest.java | 40 ++++++++++++------- .../dash/offline/DashDownloadAction.java | 6 +-- .../dash/offline/DashDownloadActionTest.java | 3 +- .../dash/offline/DownloadManagerDashTest.java | 3 +- .../dash/offline/DownloadServiceDashTest.java | 2 +- .../source/hls/offline/HlsDownloadAction.java | 4 +- .../offline/SsDownloadAction.java | 4 +- 13 files changed, 69 insertions(+), 47 deletions(-) diff --git a/demos/main/src/main/java/com/google/android/exoplayer2/demo/DemoDownloadService.java b/demos/main/src/main/java/com/google/android/exoplayer2/demo/DemoDownloadService.java index 3e28c13d1c..7d1ab16ce4 100644 --- a/demos/main/src/main/java/com/google/android/exoplayer2/demo/DemoDownloadService.java +++ b/demos/main/src/main/java/com/google/android/exoplayer2/demo/DemoDownloadService.java @@ -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); diff --git a/demos/main/src/main/java/com/google/android/exoplayer2/demo/DownloadActivity.java b/demos/main/src/main/java/com/google/android/exoplayer2/demo/DownloadActivity.java index c36514bcfd..285f5f282c 100644 --- a/demos/main/src/main/java/com/google/android/exoplayer2/demo/DownloadActivity.java +++ b/demos/main/src/main/java/com/google/android/exoplayer2/demo/DownloadActivity.java @@ -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); } } } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadAction.java b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadAction.java index 3fd59a17a5..cf061f3745 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadAction.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadAction.java @@ -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; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadManager.java b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadManager.java index 3fa1b7697f..bc06bbad60 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadManager.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadManager.java @@ -654,8 +654,6 @@ public final class DownloadManager { + ' ' + (action.isRemoveAction ? "remove" : "download") + ' ' - + action.data - + ' ' + getStateString(); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/offline/ProgressiveDownloadAction.java b/library/core/src/main/java/com/google/android/exoplayer2/offline/ProgressiveDownloadAction.java index a287c0adcd..02ef7a7aa7 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/offline/ProgressiveDownloadAction.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/offline/ProgressiveDownloadAction.java @@ -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) { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/offline/SegmentDownloadAction.java b/library/core/src/main/java/com/google/android/exoplayer2/offline/SegmentDownloadAction.java index 0b7a3220e4..f6a32a1253 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/offline/SegmentDownloadAction.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/offline/SegmentDownloadAction.java @@ -48,7 +48,9 @@ public abstract class SegmentDownloadAction> 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 keys = new ArrayList<>(); for (int i = 0; i < keyCount; i++) { @@ -62,7 +64,7 @@ public abstract class SegmentDownloadAction> extends Dow /** Returns a {@link DownloadAction}. */ protected abstract DownloadAction createDownloadAction( - Uri manifestUri, boolean isRemoveAction, String data, List keys); + Uri manifestUri, boolean isRemoveAction, byte[] data, List keys); } public final List keys; @@ -72,7 +74,7 @@ public abstract class SegmentDownloadAction> 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> extends Dow int version, Uri uri, boolean isRemoveAction, - @Nullable String data, + @Nullable byte[] data, List keys) { super(type, version, uri, isRemoveAction, data); if (isRemoveAction) { @@ -98,7 +100,8 @@ public abstract class SegmentDownloadAction> 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)); diff --git a/library/core/src/test/java/com/google/android/exoplayer2/offline/ActionFileTest.java b/library/core/src/test/java/com/google/android/exoplayer2/offline/ActionFileTest.java index 28ee39a46e..e821bc34a0 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/offline/ActionFileTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/offline/ActionFileTest.java @@ -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 diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/offline/DashDownloadAction.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/offline/DashDownloadAction.java index 8ebd137009..b431c38130 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/offline/DashDownloadAction.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/offline/DashDownloadAction.java @@ -42,7 +42,7 @@ public final class DashDownloadAction extends SegmentDownloadAction keys) { + Uri uri, boolean isRemoveAction, byte[] data, List keys) { return new DashDownloadAction(uri, isRemoveAction, data, keys); } }; @@ -50,12 +50,12 @@ public final class DashDownloadAction extends SegmentDownloadAction keys) { + Uri uri, boolean isRemoveAction, @Nullable byte[] data, List keys) { super(TYPE, VERSION, uri, isRemoveAction, data, keys); } diff --git a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DashDownloadActionTest.java b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DashDownloadActionTest.java index 0a14b2a2c2..43d9bd9965 100644 --- a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DashDownloadActionTest.java +++ b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DashDownloadActionTest.java @@ -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 keysList = new ArrayList<>(); Collections.addAll(keysList, keys); return new DashDownloadAction(uri, isRemoveAction, data, keysList); diff --git a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DownloadManagerDashTest.java b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DownloadManagerDashTest.java index d022e1a855..8ca2aa083b 100644 --- a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DownloadManagerDashTest.java +++ b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DownloadManagerDashTest.java @@ -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 keysList = new ArrayList<>(); Collections.addAll(keysList, keys); return new DashDownloadAction(uri, isRemoveAction, data, keysList); diff --git a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DownloadServiceDashTest.java b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DownloadServiceDashTest.java index cf6737e602..e256e4850d 100644 --- a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DownloadServiceDashTest.java +++ b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/offline/DownloadServiceDashTest.java @@ -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 keysList = new ArrayList<>(); Collections.addAll(keysList, keys); return new DashDownloadAction(uri, isRemoveAction, data, keysList); diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/offline/HlsDownloadAction.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/offline/HlsDownloadAction.java index 6e15818c53..ddf1e384a5 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/offline/HlsDownloadAction.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/offline/HlsDownloadAction.java @@ -44,7 +44,7 @@ public final class HlsDownloadAction extends SegmentDownloadAction @Override protected DownloadAction createDownloadAction( - Uri uri, boolean isRemoveAction, String data, List keys) { + Uri uri, boolean isRemoveAction, byte[] data, List keys) { return new HlsDownloadAction(uri, isRemoveAction, data, keys); } }; @@ -57,7 +57,7 @@ public final class HlsDownloadAction extends SegmentDownloadAction * {@code removeAction} is true, {@code keys} must empty. */ public HlsDownloadAction( - Uri uri, boolean isRemoveAction, @Nullable String data, List keys) { + Uri uri, boolean isRemoveAction, @Nullable byte[] data, List keys) { super(TYPE, VERSION, uri, isRemoveAction, data, keys); } diff --git a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/offline/SsDownloadAction.java b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/offline/SsDownloadAction.java index 5623d40c79..2e26915a86 100644 --- a/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/offline/SsDownloadAction.java +++ b/library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/offline/SsDownloadAction.java @@ -42,7 +42,7 @@ public final class SsDownloadAction extends SegmentDownloadAction { @Override protected DownloadAction createDownloadAction( - Uri uri, boolean isRemoveAction, String data, List keys) { + Uri uri, boolean isRemoveAction, byte[] data, List keys) { return new SsDownloadAction(uri, isRemoveAction, data, keys); } }; @@ -55,7 +55,7 @@ public final class SsDownloadAction extends SegmentDownloadAction { * removeAction} is true, {@code keys} must be empty. */ public SsDownloadAction( - Uri uri, boolean isRemoveAction, @Nullable String data, List keys) { + Uri uri, boolean isRemoveAction, @Nullable byte[] data, List keys) { super(TYPE, VERSION, uri, isRemoveAction, data, keys); }