Remove DownloadAction serialization
Implement Parcelable instead, which is a more intented way of passing structured data via Intents. PiperOrigin-RevId: 242646441
This commit is contained in:
parent
14d40b0faf
commit
d3b63a97ad
@ -136,7 +136,8 @@ public class DemoApplication extends Application {
|
||||
ActionFile actionFile = new ActionFile(new File(getDownloadDirectory(), file));
|
||||
if (actionFile.exists()) {
|
||||
try {
|
||||
DownloadIndexUtil.upgradeActionFile(actionFile, downloadIndex, null);
|
||||
DownloadIndexUtil.mergeActionFile(
|
||||
actionFile, /* downloadIdProvider= */ null, downloadIndex);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Upgrading action file failed", e);
|
||||
}
|
||||
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.offline;
|
||||
|
||||
import android.net.Uri;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.offline.DownloadAction.UnsupportedActionException;
|
||||
import com.google.android.exoplayer2.util.AtomicFile;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
@ -23,10 +25,9 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Stores and loads {@link DownloadAction}s to/from a file.
|
||||
*/
|
||||
/** Loads {@link DownloadAction DownloadActions} from legacy action files. */
|
||||
public final class ActionFile {
|
||||
|
||||
private static final int VERSION = 0;
|
||||
@ -34,17 +35,28 @@ public final class ActionFile {
|
||||
private final AtomicFile atomicFile;
|
||||
|
||||
/**
|
||||
* @param actionFile File to be used to store and load {@link DownloadAction}s.
|
||||
* @param actionFile The file from which {@link DownloadAction DownloadActions} will be loaded.
|
||||
*/
|
||||
public ActionFile(File actionFile) {
|
||||
atomicFile = new AtomicFile(actionFile);
|
||||
}
|
||||
|
||||
/** Returns whether the file or its backup exists. */
|
||||
public boolean exists() {
|
||||
return atomicFile.exists();
|
||||
}
|
||||
|
||||
/** Deletes the action file and its backup. */
|
||||
public void delete() {
|
||||
atomicFile.delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads {@link DownloadAction}s from file.
|
||||
* Loads {@link DownloadAction DownloadActions} from the file.
|
||||
*
|
||||
* @return Loaded DownloadActions. If the action file doesn't exists returns an empty array.
|
||||
* @throws IOException If there is an error during loading.
|
||||
* @return The loaded {@link DownloadAction DownloadActions}, or an empty array if the file does
|
||||
* not exist.
|
||||
* @throws IOException If there is an error reading the file.
|
||||
*/
|
||||
public DownloadAction[] load() throws IOException {
|
||||
if (!exists()) {
|
||||
@ -62,7 +74,7 @@ public final class ActionFile {
|
||||
ArrayList<DownloadAction> actions = new ArrayList<>();
|
||||
for (int i = 0; i < actionCount; i++) {
|
||||
try {
|
||||
actions.add(DownloadAction.deserializeFromStream(dataInputStream));
|
||||
actions.add(readDownloadAction(dataInputStream));
|
||||
} catch (UnsupportedActionException e) {
|
||||
// remove DownloadAction is not supported. Ignore the exception and continue loading rest.
|
||||
}
|
||||
@ -73,13 +85,74 @@ public final class ActionFile {
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns whether the file or its backup exists. */
|
||||
public boolean exists() {
|
||||
return atomicFile.exists();
|
||||
private static DownloadAction readDownloadAction(DataInputStream input) throws IOException {
|
||||
String type = input.readUTF();
|
||||
int version = input.readInt();
|
||||
|
||||
Uri uri = Uri.parse(input.readUTF());
|
||||
boolean isRemoveAction = input.readBoolean();
|
||||
|
||||
int dataLength = input.readInt();
|
||||
byte[] data;
|
||||
if (dataLength != 0) {
|
||||
data = new byte[dataLength];
|
||||
input.readFully(data);
|
||||
} else {
|
||||
data = null;
|
||||
}
|
||||
|
||||
/** Delete the action file and its backup. */
|
||||
public void delete() {
|
||||
atomicFile.delete();
|
||||
// Serialized version 0 progressive actions did not contain keys.
|
||||
boolean isLegacyProgressive = version == 0 && DownloadAction.TYPE_PROGRESSIVE.equals(type);
|
||||
List<StreamKey> keys = new ArrayList<>();
|
||||
if (!isLegacyProgressive) {
|
||||
int keyCount = input.readInt();
|
||||
for (int i = 0; i < keyCount; i++) {
|
||||
keys.add(readKey(type, version, input));
|
||||
}
|
||||
}
|
||||
|
||||
// Serialized version 0 and 1 DASH/HLS/SS actions did not contain a custom cache key.
|
||||
boolean isLegacySegmented =
|
||||
version < 2
|
||||
&& (DownloadAction.TYPE_DASH.equals(type)
|
||||
|| DownloadAction.TYPE_HLS.equals(type)
|
||||
|| DownloadAction.TYPE_SS.equals(type));
|
||||
String customCacheKey = null;
|
||||
if (!isLegacySegmented) {
|
||||
customCacheKey = input.readBoolean() ? input.readUTF() : null;
|
||||
}
|
||||
|
||||
// Serialized version 0, 1 and 2 did not contain an id. We need to generate one.
|
||||
String id = version < 3 ? generateDownloadActionId(uri, customCacheKey) : input.readUTF();
|
||||
|
||||
if (isRemoveAction) {
|
||||
// Remove actions are not supported anymore.
|
||||
throw new UnsupportedActionException();
|
||||
}
|
||||
return new DownloadAction(id, type, uri, keys, customCacheKey, data);
|
||||
}
|
||||
|
||||
private static StreamKey readKey(String type, int version, DataInputStream input)
|
||||
throws IOException {
|
||||
int periodIndex;
|
||||
int groupIndex;
|
||||
int trackIndex;
|
||||
|
||||
// Serialized version 0 HLS/SS actions did not contain a period index.
|
||||
if ((DownloadAction.TYPE_HLS.equals(type) || DownloadAction.TYPE_SS.equals(type))
|
||||
&& version == 0) {
|
||||
periodIndex = 0;
|
||||
groupIndex = input.readInt();
|
||||
trackIndex = input.readInt();
|
||||
} else {
|
||||
periodIndex = input.readInt();
|
||||
groupIndex = input.readInt();
|
||||
trackIndex = input.readInt();
|
||||
}
|
||||
return new StreamKey(periodIndex, groupIndex, trackIndex);
|
||||
}
|
||||
|
||||
private static String generateDownloadActionId(Uri uri, @Nullable String customCacheKey) {
|
||||
return customCacheKey != null ? customCacheKey : uri.toString();
|
||||
}
|
||||
}
|
||||
|
@ -341,7 +341,7 @@ public final class DefaultDownloadIndex implements DownloadIndex {
|
||||
|
||||
private static DownloadState getDownloadStateForCurrentRow(Cursor cursor) {
|
||||
DownloadAction action =
|
||||
DownloadAction.createDownloadAction(
|
||||
new DownloadAction(
|
||||
cursor.getString(COLUMN_INDEX_ID),
|
||||
cursor.getString(COLUMN_INDEX_TYPE),
|
||||
Uri.parse(cursor.getString(COLUMN_INDEX_URI)),
|
||||
|
@ -15,24 +15,22 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.offline;
|
||||
|
||||
import static com.google.android.exoplayer2.util.Util.castNonNull;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/** Contains the necessary parameters for a download action. */
|
||||
public final class DownloadAction {
|
||||
public final class DownloadAction implements Parcelable {
|
||||
|
||||
/** Thrown when the encoded action data belongs to an unsupported DownloadAction type. */
|
||||
public static class UnsupportedActionException extends IOException {}
|
||||
@ -46,56 +44,6 @@ public final class DownloadAction {
|
||||
/** Type for SmoothStreaming downloads. */
|
||||
public static final String TYPE_SS = "ss";
|
||||
|
||||
private static final int VERSION = 3;
|
||||
|
||||
/**
|
||||
* Deserializes a download action from the {@code data}.
|
||||
*
|
||||
* @param data The action data to deserialize.
|
||||
* @return The deserialized action.
|
||||
* @throws IOException If the data could not be deserialized.
|
||||
* @throws UnsupportedActionException If the data belongs to an unsupported {@link DownloadAction}
|
||||
* type. Input read position is set to the end of the data.
|
||||
*/
|
||||
public static DownloadAction fromByteArray(byte[] data) throws IOException {
|
||||
ByteArrayInputStream input = new ByteArrayInputStream(data);
|
||||
return deserializeFromStream(input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes a single download action from {@code input}.
|
||||
*
|
||||
* @param input The stream from which to read.
|
||||
* @return The deserialized action.
|
||||
* @throws IOException If there is an IO error reading from {@code input}, or if the data could
|
||||
* not be deserialized.
|
||||
* @throws UnsupportedActionException If the data belongs to an unsupported {@link DownloadAction}
|
||||
* type. Input read position is set to the end of the data.
|
||||
*/
|
||||
public static DownloadAction deserializeFromStream(InputStream input) throws IOException {
|
||||
return readFromStream(new DataInputStream(input));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a DASH download action.
|
||||
*
|
||||
* @param id The content id.
|
||||
* @param type The type of the action.
|
||||
* @param uri The URI of the media to be downloaded.
|
||||
* @param keys Keys of streams to be downloaded. If empty, all streams will be downloaded.
|
||||
* @param customCacheKey A custom key for cache indexing, or null.
|
||||
* @param data Optional custom data for this action. If {@code null} an empty array will be used.
|
||||
*/
|
||||
public static DownloadAction createDownloadAction(
|
||||
String id,
|
||||
String type,
|
||||
Uri uri,
|
||||
List<StreamKey> keys,
|
||||
@Nullable String customCacheKey,
|
||||
@Nullable byte[] data) {
|
||||
return new DownloadAction(id, type, uri, keys, customCacheKey, data);
|
||||
}
|
||||
|
||||
/** The unique content id. */
|
||||
public final String id;
|
||||
/** The type of the action. */
|
||||
@ -117,7 +65,7 @@ public final class DownloadAction {
|
||||
* @param customCacheKey See {@link #customCacheKey}.
|
||||
* @param data See {@link #data}.
|
||||
*/
|
||||
private DownloadAction(
|
||||
public DownloadAction(
|
||||
String id,
|
||||
String type,
|
||||
Uri uri,
|
||||
@ -127,13 +75,38 @@ public final class DownloadAction {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
this.uri = uri;
|
||||
this.customCacheKey = customCacheKey;
|
||||
ArrayList<StreamKey> mutableKeys = new ArrayList<>(streamKeys);
|
||||
Collections.sort(mutableKeys);
|
||||
this.streamKeys = Collections.unmodifiableList(mutableKeys);
|
||||
this.customCacheKey = customCacheKey;
|
||||
this.data = data != null ? Arrays.copyOf(data, data.length) : Util.EMPTY_BYTE_ARRAY;
|
||||
}
|
||||
|
||||
/* package */ DownloadAction(Parcel in) {
|
||||
id = castNonNull(in.readString());
|
||||
type = castNonNull(in.readString());
|
||||
uri = Uri.parse(castNonNull(in.readString()));
|
||||
int streamKeyCount = in.readInt();
|
||||
ArrayList<StreamKey> mutableStreamKeys = new ArrayList<>(streamKeyCount);
|
||||
for (int i = 0; i < streamKeyCount; i++) {
|
||||
mutableStreamKeys.add(in.readParcelable(StreamKey.class.getClassLoader()));
|
||||
}
|
||||
streamKeys = Collections.unmodifiableList(mutableStreamKeys);
|
||||
customCacheKey = in.readString();
|
||||
data = new byte[in.readInt()];
|
||||
in.readByteArray(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy with the specified ID.
|
||||
*
|
||||
* @param id The ID of the copy.
|
||||
* @return The copy with the specified ID.
|
||||
*/
|
||||
public DownloadAction copyWithId(String id) {
|
||||
return new DownloadAction(id, type, uri, streamKeys, customCacheKey, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of merging {@code newAction} into this action.
|
||||
*
|
||||
@ -143,7 +116,6 @@ public final class DownloadAction {
|
||||
public DownloadAction copyWithMergedAction(DownloadAction newAction) {
|
||||
Assertions.checkState(id.equals(newAction.id));
|
||||
Assertions.checkState(type.equals(newAction.type));
|
||||
|
||||
List<StreamKey> mergedKeys;
|
||||
if (streamKeys.isEmpty() || newAction.streamKeys.isEmpty()) {
|
||||
// If either streamKeys is empty then all streams should be downloaded.
|
||||
@ -161,18 +133,6 @@ public final class DownloadAction {
|
||||
id, type, newAction.uri, mergedKeys, newAction.customCacheKey, newAction.data);
|
||||
}
|
||||
|
||||
/** Serializes itself into a byte array. */
|
||||
public byte[] toByteArray() {
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
try {
|
||||
serializeToStream(output);
|
||||
} catch (IOException e) {
|
||||
// ByteArrayOutputStream shouldn't throw IOException.
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
return output.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (!(o instanceof DownloadAction)) {
|
||||
@ -191,6 +151,7 @@ public final class DownloadAction {
|
||||
public final int hashCode() {
|
||||
int result = type.hashCode();
|
||||
result = 31 * result + id.hashCode();
|
||||
result = 31 * result + type.hashCode();
|
||||
result = 31 * result + uri.hashCode();
|
||||
result = 31 * result + streamKeys.hashCode();
|
||||
result = 31 * result + (customCacheKey != null ? customCacheKey.hashCode() : 0);
|
||||
@ -198,101 +159,38 @@ public final class DownloadAction {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Serialization.
|
||||
// Parcelable implementation.
|
||||
|
||||
/**
|
||||
* Serializes this action into an {@link OutputStream}.
|
||||
*
|
||||
* @param output The stream to write to.
|
||||
*/
|
||||
public final void serializeToStream(OutputStream output) throws IOException {
|
||||
// Don't close the stream as it closes the underlying stream too.
|
||||
DataOutputStream dataOutputStream = new DataOutputStream(output);
|
||||
dataOutputStream.writeUTF(type);
|
||||
dataOutputStream.writeInt(VERSION);
|
||||
dataOutputStream.writeUTF(uri.toString());
|
||||
dataOutputStream.writeBoolean(false);
|
||||
dataOutputStream.writeInt(data.length);
|
||||
dataOutputStream.write(data);
|
||||
dataOutputStream.writeInt(streamKeys.size());
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(id);
|
||||
dest.writeString(type);
|
||||
dest.writeString(uri.toString());
|
||||
dest.writeInt(streamKeys.size());
|
||||
for (int i = 0; i < streamKeys.size(); i++) {
|
||||
StreamKey key = streamKeys.get(i);
|
||||
dataOutputStream.writeInt(key.periodIndex);
|
||||
dataOutputStream.writeInt(key.groupIndex);
|
||||
dataOutputStream.writeInt(key.trackIndex);
|
||||
dest.writeParcelable(streamKeys.get(i), /* parcelableFlags= */ 0);
|
||||
}
|
||||
dataOutputStream.writeBoolean(customCacheKey != null);
|
||||
if (customCacheKey != null) {
|
||||
dataOutputStream.writeUTF(customCacheKey);
|
||||
}
|
||||
dataOutputStream.writeUTF(id);
|
||||
dataOutputStream.flush();
|
||||
dest.writeString(customCacheKey);
|
||||
dest.writeInt(data.length);
|
||||
dest.writeByteArray(data);
|
||||
}
|
||||
|
||||
private static DownloadAction readFromStream(DataInputStream input) throws IOException {
|
||||
String type = input.readUTF();
|
||||
int version = input.readInt();
|
||||
public static final Parcelable.Creator<DownloadAction> CREATOR =
|
||||
new Parcelable.Creator<DownloadAction>() {
|
||||
|
||||
Uri uri = Uri.parse(input.readUTF());
|
||||
boolean isRemoveAction = input.readBoolean();
|
||||
|
||||
int dataLength = input.readInt();
|
||||
byte[] data;
|
||||
if (dataLength != 0) {
|
||||
data = new byte[dataLength];
|
||||
input.readFully(data);
|
||||
} else {
|
||||
data = null;
|
||||
@Override
|
||||
public DownloadAction createFromParcel(Parcel in) {
|
||||
return new DownloadAction(in);
|
||||
}
|
||||
|
||||
// Serialized version 0 progressive actions did not contain keys.
|
||||
boolean isLegacyProgressive = version == 0 && TYPE_PROGRESSIVE.equals(type);
|
||||
List<StreamKey> keys = new ArrayList<>();
|
||||
if (!isLegacyProgressive) {
|
||||
int keyCount = input.readInt();
|
||||
for (int i = 0; i < keyCount; i++) {
|
||||
keys.add(readKey(type, version, input));
|
||||
}
|
||||
}
|
||||
|
||||
// Serialized version 0 and 1 DASH/HLS/SS actions did not contain a custom cache key.
|
||||
boolean isLegacySegmented =
|
||||
version < 2 && (TYPE_DASH.equals(type) || TYPE_HLS.equals(type) || TYPE_SS.equals(type));
|
||||
String customCacheKey = null;
|
||||
if (!isLegacySegmented) {
|
||||
customCacheKey = input.readBoolean() ? input.readUTF() : null;
|
||||
}
|
||||
|
||||
// Serialized version 0, 1 and 2 did not contain an id.
|
||||
String id = version < 3 ? generateId(uri, customCacheKey) : input.readUTF();
|
||||
|
||||
if (isRemoveAction) {
|
||||
// Remove actions are not supported anymore.
|
||||
throw new UnsupportedActionException();
|
||||
}
|
||||
return new DownloadAction(id, type, uri, keys, customCacheKey, data);
|
||||
}
|
||||
|
||||
/* package */ static String generateId(Uri uri, @Nullable String customCacheKey) {
|
||||
return customCacheKey != null ? customCacheKey : uri.toString();
|
||||
}
|
||||
|
||||
private static StreamKey readKey(String type, int version, DataInputStream input)
|
||||
throws IOException {
|
||||
int periodIndex;
|
||||
int groupIndex;
|
||||
int trackIndex;
|
||||
|
||||
// Serialized version 0 HLS/SS actions did not contain a period index.
|
||||
if ((TYPE_HLS.equals(type) || TYPE_SS.equals(type)) && version == 0) {
|
||||
periodIndex = 0;
|
||||
groupIndex = input.readInt();
|
||||
trackIndex = input.readInt();
|
||||
} else {
|
||||
periodIndex = input.readInt();
|
||||
groupIndex = input.readInt();
|
||||
trackIndex = input.readInt();
|
||||
}
|
||||
return new StreamKey(periodIndex, groupIndex, trackIndex);
|
||||
@Override
|
||||
public DownloadAction[] newArray(int size) {
|
||||
return new DownloadAction[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -586,8 +586,8 @@ public final class DownloadHelper {
|
||||
public DownloadAction getDownloadAction(@Nullable byte[] data) {
|
||||
String downloadId = uri.toString();
|
||||
if (mediaSource == null) {
|
||||
return DownloadAction.createDownloadAction(
|
||||
downloadId, downloadType, uri, /* keys= */ Collections.emptyList(), cacheKey, data);
|
||||
return new DownloadAction(
|
||||
downloadId, downloadType, uri, /* streamKeys= */ Collections.emptyList(), cacheKey, data);
|
||||
}
|
||||
assertPreparedWithMedia();
|
||||
List<StreamKey> streamKeys = new ArrayList<>();
|
||||
@ -601,8 +601,7 @@ public final class DownloadHelper {
|
||||
}
|
||||
streamKeys.addAll(mediaPreparer.mediaPeriods[periodIndex].getStreamKeys(allSelections));
|
||||
}
|
||||
return DownloadAction.createDownloadAction(
|
||||
downloadId, downloadType, uri, streamKeys, cacheKey, data);
|
||||
return new DownloadAction(downloadId, downloadType, uri, streamKeys, cacheKey, data);
|
||||
}
|
||||
|
||||
// Initialization of array of Lists.
|
||||
|
@ -36,45 +36,40 @@ public final class DownloadIndexUtil {
|
||||
private DownloadIndexUtil() {}
|
||||
|
||||
/**
|
||||
* Upgrades an {@link ActionFile} to {@link DownloadIndex}.
|
||||
* Merges {@link DownloadAction DownloadActions} contained in an {@link ActionFile} into a {@link
|
||||
* DownloadIndex}.
|
||||
*
|
||||
* <p>This method shouldn't be called while {@link DownloadIndex} is used by {@link
|
||||
* <p>This method must not be called while the {@link DownloadIndex} is being used by a {@link
|
||||
* DownloadManager}.
|
||||
*
|
||||
* @param actionFile The action file to upgrade.
|
||||
* @param downloadIndex Actions are converted to {@link DownloadState}s and stored in this index.
|
||||
* @param downloadIdProvider A nullable custom download id provider.
|
||||
* @throws IOException If there is an error during loading actions.
|
||||
* @param actionFile The action file.
|
||||
* @param downloadIdProvider A custom download id provider, or {@code null}.
|
||||
* @param downloadIndex The index into which the action will be merged.
|
||||
* @throws IOException If an error occurs loading or merging the actions.
|
||||
*/
|
||||
public static void upgradeActionFile(
|
||||
public static void mergeActionFile(
|
||||
ActionFile actionFile,
|
||||
DefaultDownloadIndex downloadIndex,
|
||||
@Nullable DownloadIdProvider downloadIdProvider)
|
||||
@Nullable DownloadIdProvider downloadIdProvider,
|
||||
DefaultDownloadIndex downloadIndex)
|
||||
throws IOException {
|
||||
if (downloadIdProvider == null) {
|
||||
downloadIdProvider = downloadAction -> downloadAction.id;
|
||||
}
|
||||
for (DownloadAction action : actionFile.load()) {
|
||||
addAction(downloadIndex, downloadIdProvider.getId(action), action);
|
||||
if (downloadIdProvider != null) {
|
||||
action = action.copyWithId(downloadIdProvider.getId(action));
|
||||
}
|
||||
mergeAction(action, downloadIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a {@link DownloadAction} to {@link DownloadState} and stored in the given {@link
|
||||
* DownloadIndex}.
|
||||
* Merges a {@link DownloadAction} into a {@link DownloadIndexUtil}.
|
||||
*
|
||||
* <p>This method shouldn't be called while {@link DownloadIndex} is used by {@link
|
||||
* DownloadManager}.
|
||||
*
|
||||
* @param downloadIndex The action is converted to {@link DownloadState} and stored in this index.
|
||||
* @param id A nullable custom download id which overwrites {@link DownloadAction#id}.
|
||||
* @param action The action to be stored in {@link DownloadIndex}.
|
||||
* @throws IOException If an error occurs storing the state in the {@link DownloadIndex}.
|
||||
* @param action The action to be merged.
|
||||
* @param downloadIndex The index into which the action will be merged.
|
||||
* @throws IOException If an error occurs merging the action.
|
||||
*/
|
||||
public static void addAction(
|
||||
DefaultDownloadIndex downloadIndex, @Nullable String id, DownloadAction action)
|
||||
/* package */ static void mergeAction(DownloadAction action, DefaultDownloadIndex downloadIndex)
|
||||
throws IOException {
|
||||
DownloadState downloadState = downloadIndex.getDownloadState(id != null ? id : action.id);
|
||||
DownloadState downloadState = downloadIndex.getDownloadState(action.id);
|
||||
if (downloadState != null) {
|
||||
downloadState = downloadState.copyWithMergedAction(action);
|
||||
} else {
|
||||
|
@ -30,7 +30,6 @@ import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Log;
|
||||
import com.google.android.exoplayer2.util.NotificationUtil;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
/** A {@link Service} for downloading media. */
|
||||
@ -54,9 +53,8 @@ public abstract class DownloadService extends Service {
|
||||
* Adds a new download. Extras:
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@link #KEY_DOWNLOAD_ACTION} - The {@code byte[]} representation of the {@link
|
||||
* DownloadAction} that defines the download to be added. The required representation can be
|
||||
* obtained by calling {@link DownloadAction#toByteArray()}.
|
||||
* <li>{@link #KEY_DOWNLOAD_ACTION} - A {@link DownloadAction} defining the download to be
|
||||
* added.
|
||||
* <li>{@link #KEY_FOREGROUND} - See {@link #KEY_FOREGROUND}.
|
||||
* </ul>
|
||||
*/
|
||||
@ -231,7 +229,7 @@ public abstract class DownloadService extends Service {
|
||||
DownloadAction downloadAction,
|
||||
boolean foreground) {
|
||||
return getIntent(context, clazz, ACTION_ADD)
|
||||
.putExtra(KEY_DOWNLOAD_ACTION, downloadAction.toByteArray())
|
||||
.putExtra(KEY_DOWNLOAD_ACTION, downloadAction)
|
||||
.putExtra(KEY_FOREGROUND, foreground);
|
||||
}
|
||||
|
||||
@ -390,20 +388,12 @@ public abstract class DownloadService extends Service {
|
||||
// Do nothing.
|
||||
break;
|
||||
case ACTION_ADD:
|
||||
byte[] actionData = intent.getByteArrayExtra(KEY_DOWNLOAD_ACTION);
|
||||
if (actionData == null) {
|
||||
DownloadAction downloadAction = intent.getParcelableExtra(KEY_DOWNLOAD_ACTION);
|
||||
if (downloadAction == null) {
|
||||
Log.e(TAG, "Ignored ADD action: Missing download_action extra");
|
||||
} else {
|
||||
DownloadAction downloadAction = null;
|
||||
try {
|
||||
downloadAction = DownloadAction.fromByteArray(actionData);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Ignored ADD action: Failed to deserialize download_action extra", e);
|
||||
}
|
||||
if (downloadAction != null) {
|
||||
downloadManager.addDownload(downloadAction);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ACTION_START:
|
||||
String contentId = intent.getStringExtra(KEY_CONTENT_ID);
|
||||
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.offline;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
@ -25,7 +27,7 @@ import androidx.annotation.Nullable;
|
||||
* within the group. The interpretation of these indices depends on the type of media for which the
|
||||
* stream key is used.
|
||||
*/
|
||||
public final class StreamKey implements Comparable<StreamKey> {
|
||||
public final class StreamKey implements Comparable<StreamKey>, Parcelable {
|
||||
|
||||
/** The period index. */
|
||||
public final int periodIndex;
|
||||
@ -53,6 +55,12 @@ public final class StreamKey implements Comparable<StreamKey> {
|
||||
this.trackIndex = trackIndex;
|
||||
}
|
||||
|
||||
/* package */ StreamKey(Parcel in) {
|
||||
periodIndex = in.readInt();
|
||||
groupIndex = in.readInt();
|
||||
trackIndex = in.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return periodIndex + "." + groupIndex + "." + trackIndex;
|
||||
@ -94,4 +102,32 @@ public final class StreamKey implements Comparable<StreamKey> {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Parcelable implementation.
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(periodIndex);
|
||||
dest.writeInt(groupIndex);
|
||||
dest.writeInt(trackIndex);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<StreamKey> CREATOR =
|
||||
new Parcelable.Creator<StreamKey>() {
|
||||
|
||||
@Override
|
||||
public StreamKey createFromParcel(Parcel in) {
|
||||
return new StreamKey(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamKey[] newArray(int size) {
|
||||
return new StreamKey[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -124,11 +124,11 @@ public class ActionFileTest {
|
||||
}
|
||||
|
||||
private static DownloadAction buildExpectedAction(Uri uri, byte[] data) {
|
||||
return DownloadAction.createDownloadAction(
|
||||
return new DownloadAction(
|
||||
/* id= */ uri.toString(),
|
||||
DownloadAction.TYPE_PROGRESSIVE,
|
||||
uri,
|
||||
/* keys= */ Collections.emptyList(),
|
||||
/* streamKeys= */ Collections.emptyList(),
|
||||
/* customCacheKey= */ null,
|
||||
data);
|
||||
}
|
||||
|
@ -38,11 +38,11 @@ public final class DefaultDownloaderFactoryTest {
|
||||
|
||||
Downloader downloader =
|
||||
factory.createDownloader(
|
||||
DownloadAction.createDownloadAction(
|
||||
new DownloadAction(
|
||||
"id",
|
||||
DownloadAction.TYPE_PROGRESSIVE,
|
||||
Uri.parse("https://www.test.com/download"),
|
||||
/* keys= */ Collections.emptyList(),
|
||||
/* streamKeys= */ Collections.emptyList(),
|
||||
/* customCacheKey= */ null,
|
||||
/* data= */ null));
|
||||
assertThat(downloader).isInstanceOf(ProgressiveDownloader.class);
|
||||
|
@ -16,24 +16,11 @@
|
||||
package com.google.android.exoplayer2.offline;
|
||||
|
||||
import static com.google.android.exoplayer2.offline.DownloadAction.TYPE_DASH;
|
||||
import static com.google.android.exoplayer2.offline.DownloadAction.TYPE_HLS;
|
||||
import static com.google.android.exoplayer2.offline.DownloadAction.TYPE_PROGRESSIVE;
|
||||
import static com.google.android.exoplayer2.offline.DownloadAction.TYPE_SS;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import android.net.Uri;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import android.os.Parcel;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.android.exoplayer2.offline.DownloadAction.UnsupportedActionException;
|
||||
import com.google.android.exoplayer2.testutil.TestUtil;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@ -47,41 +34,34 @@ public class DownloadActionTest {
|
||||
|
||||
private Uri uri1;
|
||||
private Uri uri2;
|
||||
private byte[] data;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
uri1 = Uri.parse("http://test/1.uri");
|
||||
uri2 = Uri.parse("http://test/2.uri");
|
||||
data = TestUtil.buildTestData(32);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSameUri_hasSameId() {
|
||||
DownloadAction action1 = createAction(uri1);
|
||||
DownloadAction action2 = createAction(uri1);
|
||||
assertThat(action1.id.equals(action2.id)).isTrue();
|
||||
}
|
||||
public void testParcelable() {
|
||||
ArrayList<StreamKey> streamKeys = new ArrayList<>();
|
||||
streamKeys.add(new StreamKey(1, 2, 3));
|
||||
streamKeys.add(new StreamKey(4, 5, 6));
|
||||
DownloadAction actionToParcel =
|
||||
new DownloadAction(
|
||||
"id",
|
||||
"type",
|
||||
Uri.parse("https://abc.def/ghi"),
|
||||
streamKeys,
|
||||
"key",
|
||||
new byte[] {1, 2, 3, 4, 5});
|
||||
Parcel parcel = Parcel.obtain();
|
||||
actionToParcel.writeToParcel(parcel, 0);
|
||||
parcel.setDataPosition(0);
|
||||
|
||||
@Test
|
||||
public void testSameUriDifferentAction_hasSameId() {
|
||||
DownloadAction action1 = createAction(uri1);
|
||||
DownloadAction action2 = createAction(uri1);
|
||||
assertThat(action1.id.equals(action2.id)).isTrue();
|
||||
}
|
||||
DownloadAction actionFromParcel = DownloadAction.CREATOR.createFromParcel(parcel);
|
||||
assertThat(actionFromParcel).isEqualTo(actionToParcel);
|
||||
|
||||
@Test
|
||||
public void testDifferentUri_IsNotSameMedia() {
|
||||
DownloadAction action1 = createAction(uri1);
|
||||
DownloadAction action2 = createAction(uri2);
|
||||
assertThat(action1.id.equals(action2.id)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSameCacheKeyDifferentUri_hasSameId() {
|
||||
DownloadAction action1 = createAction(uri1, "key123");
|
||||
DownloadAction action2 = createAction(uri2, "key123");
|
||||
assertThat(action1.id.equals(action2.id)).isTrue();
|
||||
parcel.recycle();
|
||||
}
|
||||
|
||||
@SuppressWarnings("EqualsWithItself")
|
||||
@ -119,128 +99,6 @@ public class DownloadActionTest {
|
||||
assertEqual(action16, action17);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializerWriteRead() throws Exception {
|
||||
assertStreamSerializationRoundTrip(
|
||||
DownloadAction.createDownloadAction(
|
||||
"id",
|
||||
TYPE_DASH,
|
||||
uri1,
|
||||
toList(new StreamKey(0, 1, 2), new StreamKey(3, 4, 5)),
|
||||
"key123",
|
||||
data));
|
||||
assertStreamSerializationRoundTrip(createAction(uri1, "key123"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArraySerialization() throws Exception {
|
||||
assertArraySerializationRoundTrip(
|
||||
DownloadAction.createDownloadAction(
|
||||
"id",
|
||||
TYPE_DASH,
|
||||
uri1,
|
||||
toList(new StreamKey(0, 1, 2), new StreamKey(3, 4, 5)),
|
||||
"key123",
|
||||
data));
|
||||
assertArraySerializationRoundTrip(createAction(uri1, "key123"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializerProgressiveVersion0() throws Exception {
|
||||
String customCacheKey = "key123";
|
||||
String expectedId = DownloadAction.generateId(uri1, customCacheKey);
|
||||
assertDeserialization(
|
||||
"progressive-download-v0",
|
||||
DownloadAction.createDownloadAction(
|
||||
expectedId, TYPE_PROGRESSIVE, uri1, Collections.emptyList(), customCacheKey, data));
|
||||
assertUnsupportedAction("progressive-remove-v0");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializerDashVersion0() throws Exception {
|
||||
assertDeserialization(
|
||||
"dash-download-v0",
|
||||
DownloadAction.createDownloadAction(
|
||||
uri1.toString(),
|
||||
TYPE_DASH,
|
||||
uri1,
|
||||
toList(new StreamKey(0, 1, 2), new StreamKey(3, 4, 5)),
|
||||
/* customCacheKey= */ null,
|
||||
data));
|
||||
assertUnsupportedAction("dash-remove-v0");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializerHlsVersion0() throws Exception {
|
||||
assertDeserialization(
|
||||
"hls-download-v0",
|
||||
DownloadAction.createDownloadAction(
|
||||
uri1.toString(),
|
||||
TYPE_HLS,
|
||||
uri1,
|
||||
toList(new StreamKey(0, 1), new StreamKey(2, 3)),
|
||||
/* customCacheKey= */ null,
|
||||
data));
|
||||
assertUnsupportedAction("hls-remove-v0");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializerHlsVersion1() throws Exception {
|
||||
assertDeserialization(
|
||||
"hls-download-v1",
|
||||
DownloadAction.createDownloadAction(
|
||||
uri1.toString(),
|
||||
TYPE_HLS,
|
||||
uri1,
|
||||
toList(new StreamKey(0, 1, 2), new StreamKey(3, 4, 5)),
|
||||
/* customCacheKey= */ null,
|
||||
data));
|
||||
assertUnsupportedAction("hls-remove-v1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializerSsVersion0() throws Exception {
|
||||
assertDeserialization(
|
||||
"ss-download-v0",
|
||||
DownloadAction.createDownloadAction(
|
||||
uri1.toString(),
|
||||
TYPE_SS,
|
||||
uri1,
|
||||
toList(new StreamKey(0, 1), new StreamKey(2, 3)),
|
||||
/* customCacheKey= */ null,
|
||||
data));
|
||||
assertUnsupportedAction("ss-remove-v0");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializerSsVersion1() throws Exception {
|
||||
assertDeserialization(
|
||||
"ss-download-v1",
|
||||
DownloadAction.createDownloadAction(
|
||||
uri1.toString(),
|
||||
TYPE_SS,
|
||||
uri1,
|
||||
toList(new StreamKey(0, 1, 2), new StreamKey(3, 4, 5)),
|
||||
/* customCacheKey= */ null,
|
||||
data));
|
||||
assertUnsupportedAction("ss-remove-v1");
|
||||
}
|
||||
|
||||
private DownloadAction createAction(Uri uri, StreamKey... keys) {
|
||||
return DownloadAction.createDownloadAction(
|
||||
uri.toString(), TYPE_DASH, uri, toList(keys), /* customCacheKey= */ null, data);
|
||||
}
|
||||
|
||||
private DownloadAction createAction(Uri uri, @Nullable String customCacheKey) {
|
||||
return DownloadAction.createDownloadAction(
|
||||
"id",
|
||||
DownloadAction.TYPE_DASH,
|
||||
uri,
|
||||
Collections.emptyList(),
|
||||
customCacheKey,
|
||||
/* data= */ null);
|
||||
}
|
||||
|
||||
private static void assertNotEqual(DownloadAction action1, DownloadAction action2) {
|
||||
assertThat(action1).isNotEqualTo(action2);
|
||||
assertThat(action2).isNotEqualTo(action1);
|
||||
@ -251,42 +109,9 @@ public class DownloadActionTest {
|
||||
assertThat(action2).isEqualTo(action1);
|
||||
}
|
||||
|
||||
private static void assertStreamSerializationRoundTrip(DownloadAction action) throws IOException {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
DataOutputStream output = new DataOutputStream(out);
|
||||
action.serializeToStream(output);
|
||||
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
|
||||
DataInputStream input = new DataInputStream(in);
|
||||
DownloadAction deserializedAction = DownloadAction.deserializeFromStream(input);
|
||||
|
||||
assertEqual(action, deserializedAction);
|
||||
}
|
||||
|
||||
private static void assertArraySerializationRoundTrip(DownloadAction action) throws IOException {
|
||||
assertEqual(action, DownloadAction.fromByteArray(action.toByteArray()));
|
||||
}
|
||||
|
||||
private static void assertDeserialization(String fileName, DownloadAction expectedAction)
|
||||
throws IOException {
|
||||
InputStream input =
|
||||
TestUtil.getInputStream(
|
||||
ApplicationProvider.getApplicationContext(), "download-actions/" + fileName);
|
||||
DownloadAction deserializedAction = DownloadAction.deserializeFromStream(input);
|
||||
|
||||
assertEqual(deserializedAction, expectedAction);
|
||||
}
|
||||
|
||||
private static void assertUnsupportedAction(String fileName) throws IOException {
|
||||
InputStream input =
|
||||
TestUtil.getInputStream(
|
||||
ApplicationProvider.getApplicationContext(), "download-actions/" + fileName);
|
||||
try {
|
||||
DownloadAction.deserializeFromStream(input);
|
||||
fail();
|
||||
} catch (UnsupportedActionException e) {
|
||||
// Expected exception.
|
||||
}
|
||||
private static DownloadAction createAction(Uri uri, StreamKey... keys) {
|
||||
return new DownloadAction(
|
||||
uri.toString(), TYPE_DASH, uri, toList(keys), /* customCacheKey= */ null, /* data= */ null);
|
||||
}
|
||||
|
||||
private static List<StreamKey> toList(StreamKey... keys) {
|
||||
|
@ -59,7 +59,7 @@ public class DownloadIndexUtilTest {
|
||||
public void addAction_nonExistingDownloadState_createsNewDownloadState() throws IOException {
|
||||
byte[] data = new byte[] {1, 2, 3, 4};
|
||||
DownloadAction action =
|
||||
DownloadAction.createDownloadAction(
|
||||
new DownloadAction(
|
||||
"id",
|
||||
TYPE_DASH,
|
||||
Uri.parse("https://www.test.com/download"),
|
||||
@ -69,7 +69,7 @@ public class DownloadIndexUtilTest {
|
||||
/* customCacheKey= */ "key123",
|
||||
data);
|
||||
|
||||
DownloadIndexUtil.addAction(downloadIndex, action.id, action);
|
||||
DownloadIndexUtil.mergeAction(action, downloadIndex);
|
||||
|
||||
assertDownloadIndexContainsAction(action, DownloadState.STATE_QUEUED);
|
||||
}
|
||||
@ -81,7 +81,7 @@ public class DownloadIndexUtilTest {
|
||||
StreamKey streamKey2 =
|
||||
new StreamKey(/* periodIndex= */ 0, /* groupIndex= */ 1, /* trackIndex= */ 2);
|
||||
DownloadAction action1 =
|
||||
DownloadAction.createDownloadAction(
|
||||
new DownloadAction(
|
||||
"id",
|
||||
TYPE_DASH,
|
||||
Uri.parse("https://www.test.com/download1"),
|
||||
@ -89,16 +89,16 @@ public class DownloadIndexUtilTest {
|
||||
/* customCacheKey= */ "key123",
|
||||
new byte[] {1, 2, 3, 4});
|
||||
DownloadAction action2 =
|
||||
DownloadAction.createDownloadAction(
|
||||
new DownloadAction(
|
||||
"id",
|
||||
TYPE_DASH,
|
||||
Uri.parse("https://www.test.com/download2"),
|
||||
asList(streamKey2),
|
||||
/* customCacheKey= */ "key123",
|
||||
new byte[] {5, 4, 3, 2, 1});
|
||||
DownloadIndexUtil.addAction(downloadIndex, action1.id, action1);
|
||||
DownloadIndexUtil.mergeAction(action1, downloadIndex);
|
||||
|
||||
DownloadIndexUtil.addAction(downloadIndex, action2.id, action2);
|
||||
DownloadIndexUtil.mergeAction(action2, downloadIndex);
|
||||
|
||||
DownloadState downloadState = downloadIndex.getDownloadState(action2.id);
|
||||
assertThat(downloadState).isNotNull();
|
||||
@ -126,7 +126,7 @@ public class DownloadIndexUtilTest {
|
||||
StreamKey expectedStreamKey2 =
|
||||
new StreamKey(/* periodIndex= */ 0, /* groupIndex= */ 1, /* trackIndex= */ 2);
|
||||
DownloadAction expectedAction1 =
|
||||
DownloadAction.createDownloadAction(
|
||||
new DownloadAction(
|
||||
"key123",
|
||||
TYPE_DASH,
|
||||
Uri.parse("https://www.test.com/download1"),
|
||||
@ -134,7 +134,7 @@ public class DownloadIndexUtilTest {
|
||||
/* customCacheKey= */ "key123",
|
||||
new byte[] {1, 2, 3, 4});
|
||||
DownloadAction expectedAction2 =
|
||||
DownloadAction.createDownloadAction(
|
||||
new DownloadAction(
|
||||
"key234",
|
||||
TYPE_DASH,
|
||||
Uri.parse("https://www.test.com/download2"),
|
||||
@ -143,7 +143,7 @@ public class DownloadIndexUtilTest {
|
||||
new byte[] {5, 4, 3, 2, 1});
|
||||
|
||||
ActionFile actionFile = new ActionFile(tempFile);
|
||||
DownloadIndexUtil.upgradeActionFile(actionFile, downloadIndex, /* downloadIdProvider= */ null);
|
||||
DownloadIndexUtil.mergeActionFile(actionFile, /* downloadIdProvider= */ null, downloadIndex);
|
||||
assertDownloadIndexContainsAction(expectedAction1, DownloadState.STATE_QUEUED);
|
||||
assertDownloadIndexContainsAction(expectedAction2, DownloadState.STATE_QUEUED);
|
||||
}
|
||||
|
@ -507,7 +507,7 @@ public class DownloadManagerTest {
|
||||
|
||||
private DownloadRunner postDownloadAction(StreamKey... keys) {
|
||||
DownloadAction downloadAction =
|
||||
DownloadAction.createDownloadAction(
|
||||
new DownloadAction(
|
||||
id,
|
||||
DownloadAction.TYPE_PROGRESSIVE,
|
||||
uri,
|
||||
|
@ -153,8 +153,7 @@ class DownloadStateBuilder {
|
||||
}
|
||||
|
||||
public DownloadState build() {
|
||||
DownloadAction action =
|
||||
DownloadAction.createDownloadAction(id, type, uri, streamKeys, cacheKey, customMetadata);
|
||||
DownloadAction action = new DownloadAction(id, type, uri, streamKeys, cacheKey, customMetadata);
|
||||
return new DownloadState(
|
||||
action,
|
||||
state,
|
||||
|
@ -99,7 +99,7 @@ public class DownloadStateTest {
|
||||
@Test
|
||||
public void mergeAction_actionHaveDifferentData_downloadStateDataIsUpdated() {
|
||||
DownloadAction downloadAction =
|
||||
DownloadAction.createDownloadAction(
|
||||
new DownloadAction(
|
||||
"id",
|
||||
DownloadAction.TYPE_DASH,
|
||||
testUri,
|
||||
@ -246,7 +246,7 @@ public class DownloadStateTest {
|
||||
private void doTestMergeActionReturnsMergedKeys(
|
||||
StreamKey[] keys1, StreamKey[] keys2, StreamKey[] expectedKeys) {
|
||||
DownloadAction downloadAction =
|
||||
DownloadAction.createDownloadAction(
|
||||
new DownloadAction(
|
||||
"id",
|
||||
DownloadAction.TYPE_DASH,
|
||||
testUri,
|
||||
@ -286,7 +286,7 @@ public class DownloadStateTest {
|
||||
}
|
||||
|
||||
private DownloadAction createDownloadAction() {
|
||||
return DownloadAction.createDownloadAction(
|
||||
return new DownloadAction(
|
||||
"id",
|
||||
DownloadAction.TYPE_DASH,
|
||||
testUri,
|
||||
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.offline;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.os.Parcel;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
/** Unit tests for {@link StreamKey}. */
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class StreamKeyTest {
|
||||
|
||||
@Test
|
||||
public void testParcelable() {
|
||||
StreamKey streamKeyToParcel = new StreamKey(1, 2, 3);
|
||||
Parcel parcel = Parcel.obtain();
|
||||
streamKeyToParcel.writeToParcel(parcel, 0);
|
||||
parcel.setDataPosition(0);
|
||||
|
||||
StreamKey streamKeyFromParcel = StreamKey.CREATOR.createFromParcel(parcel);
|
||||
assertThat(streamKeyFromParcel).isEqualTo(streamKeyToParcel);
|
||||
|
||||
parcel.recycle();
|
||||
}
|
||||
}
|
@ -84,7 +84,7 @@ public class DashDownloaderTest {
|
||||
|
||||
Downloader downloader =
|
||||
factory.createDownloader(
|
||||
DownloadAction.createDownloadAction(
|
||||
new DownloadAction(
|
||||
"id",
|
||||
DownloadAction.TYPE_DASH,
|
||||
Uri.parse("https://www.test.com/download"),
|
||||
|
@ -232,7 +232,7 @@ public class DownloadManagerDashTest {
|
||||
ArrayList<StreamKey> keysList = new ArrayList<>();
|
||||
Collections.addAll(keysList, keys);
|
||||
DownloadAction action =
|
||||
DownloadAction.createDownloadAction(
|
||||
new DownloadAction(
|
||||
TEST_ID,
|
||||
DownloadAction.TYPE_DASH,
|
||||
TEST_MPD_URI,
|
||||
|
@ -208,7 +208,7 @@ public class DownloadServiceDashTest {
|
||||
ArrayList<StreamKey> keysList = new ArrayList<>();
|
||||
Collections.addAll(keysList, keys);
|
||||
DownloadAction action =
|
||||
DownloadAction.createDownloadAction(
|
||||
new DownloadAction(
|
||||
TEST_ID,
|
||||
DownloadAction.TYPE_DASH,
|
||||
TEST_MPD_URI,
|
||||
|
@ -101,7 +101,7 @@ public class HlsDownloaderTest {
|
||||
|
||||
Downloader downloader =
|
||||
factory.createDownloader(
|
||||
DownloadAction.createDownloadAction(
|
||||
new DownloadAction(
|
||||
"id",
|
||||
DownloadAction.TYPE_HLS,
|
||||
Uri.parse("https://www.test.com/download"),
|
||||
|
@ -44,7 +44,7 @@ public final class SsDownloaderTest {
|
||||
|
||||
Downloader downloader =
|
||||
factory.createDownloader(
|
||||
DownloadAction.createDownloadAction(
|
||||
new DownloadAction(
|
||||
"id",
|
||||
DownloadAction.TYPE_SS,
|
||||
Uri.parse("https://www.test.com/download"),
|
||||
|
Loading…
x
Reference in New Issue
Block a user