mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Remove DownloadAction.createRemoveAction
PiperOrigin-RevId: 240557315
This commit is contained in:
parent
d4f5c9c721
commit
facd32e65e
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.offline;
|
||||
|
||||
import com.google.android.exoplayer2.offline.DownloadAction.UnsupportedActionException;
|
||||
import com.google.android.exoplayer2.util.AtomicFile;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.DataInputStream;
|
||||
@ -22,12 +23,14 @@ import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Stores and loads {@link DownloadAction}s to/from a file.
|
||||
*/
|
||||
public final class ActionFile {
|
||||
|
||||
private static final String TAG = "ActionFile";
|
||||
/* package */ static final int VERSION = 0;
|
||||
|
||||
private final AtomicFile atomicFile;
|
||||
@ -58,11 +61,15 @@ public final class ActionFile {
|
||||
throw new IOException("Unsupported action file version: " + version);
|
||||
}
|
||||
int actionCount = dataInputStream.readInt();
|
||||
DownloadAction[] actions = new DownloadAction[actionCount];
|
||||
ArrayList<DownloadAction> actions = new ArrayList<>();
|
||||
for (int i = 0; i < actionCount; i++) {
|
||||
actions[i] = DownloadAction.deserializeFromStream(dataInputStream);
|
||||
try {
|
||||
actions.add(DownloadAction.deserializeFromStream(dataInputStream));
|
||||
} catch (UnsupportedActionException e) {
|
||||
// remove DownloadAction is not supported. Ignore the exception and continue loading rest.
|
||||
}
|
||||
}
|
||||
return actions;
|
||||
return actions.toArray(new DownloadAction[0]);
|
||||
} finally {
|
||||
Util.closeQuietly(inputStream);
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ package com.google.android.exoplayer2.offline;
|
||||
|
||||
import android.net.Uri;
|
||||
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;
|
||||
@ -31,9 +30,12 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/** Contains the necessary parameters for a download or remove action. */
|
||||
/** Contains the necessary parameters for a download action. */
|
||||
public final class DownloadAction {
|
||||
|
||||
/** Thrown when the encoded action data belongs to an unsupported DownloadAction type. */
|
||||
public static class UnsupportedActionException extends IOException {}
|
||||
|
||||
/** Type for progressive downloads. */
|
||||
public static final String TYPE_PROGRESSIVE = "progressive";
|
||||
/** Type for DASH downloads. */
|
||||
@ -51,6 +53,8 @@ public final class DownloadAction {
|
||||
* @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);
|
||||
@ -67,6 +71,8 @@ public final class DownloadAction {
|
||||
* @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));
|
||||
@ -108,41 +114,16 @@ public final class DownloadAction {
|
||||
List<StreamKey> keys,
|
||||
@Nullable String customCacheKey,
|
||||
@Nullable byte[] data) {
|
||||
return new DownloadAction(
|
||||
id, type, uri, /* isRemoveAction= */ false, keys, customCacheKey, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a DASH remove action.
|
||||
*
|
||||
* @param type The type of the action.
|
||||
* @param uri The URI of the media to be removed.
|
||||
* @param customCacheKey A custom key for cache indexing, or null.
|
||||
*/
|
||||
public static DownloadAction createRemoveAction(
|
||||
String type, Uri uri, @Nullable String customCacheKey) {
|
||||
return new DownloadAction(
|
||||
generateId(uri, customCacheKey),
|
||||
type,
|
||||
uri,
|
||||
/* isRemoveAction= */ true,
|
||||
Collections.emptyList(),
|
||||
customCacheKey,
|
||||
/* data= */ null);
|
||||
return new DownloadAction(id, type, uri, keys, customCacheKey, data);
|
||||
}
|
||||
|
||||
/** The unique content id. */
|
||||
public final String id;
|
||||
/** The type of the action. */
|
||||
public final String type;
|
||||
/** The uri being downloaded or removed. */
|
||||
/** The uri being downloaded. */
|
||||
public final Uri uri;
|
||||
/** Whether this is a remove action. If false, this is a download action. */
|
||||
public final boolean isRemoveAction;
|
||||
/**
|
||||
* Keys of streams to be downloaded. If empty, all streams will be downloaded. Empty if this
|
||||
* action is a remove action.
|
||||
*/
|
||||
/** Keys of streams to be downloaded. If empty, all streams will be downloaded. */
|
||||
public final List<StreamKey> keys;
|
||||
/** A custom key for cache indexing, or null. */
|
||||
@Nullable public final String customCacheKey;
|
||||
@ -152,37 +133,26 @@ public final class DownloadAction {
|
||||
/**
|
||||
* @param id The content id.
|
||||
* @param type The type of the action.
|
||||
* @param uri The uri being downloaded or removed.
|
||||
* @param isRemoveAction Whether this is a remove action. If false, this is a download action.
|
||||
* @param keys Keys of streams to be downloaded. If empty, all streams will be downloaded. Empty
|
||||
* if this action is a remove action.
|
||||
* @param uri The uri being 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 Custom data for this action. Null if this action is a remove action.
|
||||
* @param data Custom data for this action.
|
||||
*/
|
||||
private DownloadAction(
|
||||
String id,
|
||||
String type,
|
||||
Uri uri,
|
||||
boolean isRemoveAction,
|
||||
List<StreamKey> keys,
|
||||
@Nullable String customCacheKey,
|
||||
@Nullable byte[] data) {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
this.uri = uri;
|
||||
this.isRemoveAction = isRemoveAction;
|
||||
this.customCacheKey = customCacheKey;
|
||||
if (isRemoveAction) {
|
||||
Assertions.checkArgument(keys.isEmpty());
|
||||
Assertions.checkArgument(data == null);
|
||||
this.keys = Collections.emptyList();
|
||||
this.data = Util.EMPTY_BYTE_ARRAY;
|
||||
} else {
|
||||
ArrayList<StreamKey> mutableKeys = new ArrayList<>(keys);
|
||||
Collections.sort(mutableKeys);
|
||||
this.keys = Collections.unmodifiableList(mutableKeys);
|
||||
this.data = data != null ? Arrays.copyOf(data, data.length) : Util.EMPTY_BYTE_ARRAY;
|
||||
}
|
||||
ArrayList<StreamKey> mutableKeys = new ArrayList<>(keys);
|
||||
Collections.sort(mutableKeys);
|
||||
this.keys = Collections.unmodifiableList(mutableKeys);
|
||||
this.data = data != null ? Arrays.copyOf(data, data.length) : Util.EMPTY_BYTE_ARRAY;
|
||||
}
|
||||
|
||||
/** Serializes itself into a byte array. */
|
||||
@ -211,7 +181,6 @@ public final class DownloadAction {
|
||||
return id.equals(that.id)
|
||||
&& type.equals(that.type)
|
||||
&& uri.equals(that.uri)
|
||||
&& isRemoveAction == that.isRemoveAction
|
||||
&& keys.equals(that.keys)
|
||||
&& Util.areEqual(customCacheKey, that.customCacheKey)
|
||||
&& Arrays.equals(data, that.data);
|
||||
@ -222,7 +191,6 @@ public final class DownloadAction {
|
||||
int result = type.hashCode();
|
||||
result = 31 * result + id.hashCode();
|
||||
result = 31 * result + uri.hashCode();
|
||||
result = 31 * result + (isRemoveAction ? 1 : 0);
|
||||
result = 31 * result + keys.hashCode();
|
||||
result = 31 * result + (customCacheKey != null ? customCacheKey.hashCode() : 0);
|
||||
result = 31 * result + Arrays.hashCode(data);
|
||||
@ -242,7 +210,7 @@ public final class DownloadAction {
|
||||
dataOutputStream.writeUTF(type);
|
||||
dataOutputStream.writeInt(VERSION);
|
||||
dataOutputStream.writeUTF(uri.toString());
|
||||
dataOutputStream.writeBoolean(isRemoveAction);
|
||||
dataOutputStream.writeBoolean(false);
|
||||
dataOutputStream.writeInt(data.length);
|
||||
dataOutputStream.write(data);
|
||||
dataOutputStream.writeInt(keys.size());
|
||||
@ -271,10 +239,6 @@ public final class DownloadAction {
|
||||
if (dataLength != 0) {
|
||||
data = new byte[dataLength];
|
||||
input.readFully(data);
|
||||
if (isRemoveAction) {
|
||||
// Remove actions are no longer permitted to have data.
|
||||
data = null;
|
||||
}
|
||||
} else {
|
||||
data = null;
|
||||
}
|
||||
@ -297,8 +261,12 @@ public final class DownloadAction {
|
||||
customCacheKey = input.readBoolean() ? input.readUTF() : null;
|
||||
}
|
||||
|
||||
if (isRemoveAction) {
|
||||
// Remove actions are not supported anymore.
|
||||
throw new UnsupportedActionException();
|
||||
}
|
||||
return new DownloadAction(
|
||||
generateId(uri, customCacheKey), type, uri, isRemoveAction, keys, customCacheKey, data);
|
||||
generateId(uri, customCacheKey), type, uri, keys, customCacheKey, data);
|
||||
}
|
||||
|
||||
private static String generateId(Uri uri, @Nullable String customCacheKey) {
|
||||
|
@ -342,11 +342,11 @@ public final class DownloadManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the given action.
|
||||
* Adds a download defined by the given action.
|
||||
*
|
||||
* @param action The action to be executed.
|
||||
* @param action The download action.
|
||||
*/
|
||||
public void handleAction(DownloadAction action) {
|
||||
public void addDownload(DownloadAction action) {
|
||||
Assertions.checkState(!released);
|
||||
dowloadUpdateQueue.add(
|
||||
new DownloadUpdater(action.id) {
|
||||
@ -392,6 +392,8 @@ public final class DownloadManager {
|
||||
DownloadState onLoad(@Nullable DownloadState downloadState) {
|
||||
if (downloadState != null) {
|
||||
downloadState = downloadState.setRemoveState();
|
||||
} else {
|
||||
logd("Can't remove download. No download with id: " + id);
|
||||
}
|
||||
return downloadState;
|
||||
}
|
||||
@ -541,15 +543,14 @@ public final class DownloadManager {
|
||||
}
|
||||
|
||||
private void processDownloadUpdateQueue() {
|
||||
if (loadingDownload || dowloadUpdateQueue.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
DownloadUpdater downloadUpdater = dowloadUpdateQueue.remove();
|
||||
Download download = getDownload(downloadUpdater.id);
|
||||
if (download != null) {
|
||||
downloadUpdater.onExisting(download);
|
||||
} else {
|
||||
loadDownload(downloadUpdater);
|
||||
while (!loadingDownload && !dowloadUpdateQueue.isEmpty()) {
|
||||
DownloadUpdater downloadUpdater = dowloadUpdateQueue.remove();
|
||||
Download download = getDownload(downloadUpdater.id);
|
||||
if (download != null) {
|
||||
downloadUpdater.onExisting(download);
|
||||
} else {
|
||||
loadDownload(downloadUpdater);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -270,11 +270,14 @@ public abstract class DownloadService extends Service {
|
||||
* @param context A {@link Context}.
|
||||
* @param clazz The concrete download service being targeted by the intent.
|
||||
* @param id The content id.
|
||||
* @param foreground Whether this intent will be used to start the service in the foreground.
|
||||
* @return Created Intent.
|
||||
*/
|
||||
public static Intent buildRemoveDownloadIntent(
|
||||
Context context, Class<? extends DownloadService> clazz, String id) {
|
||||
return getIntent(context, clazz, ACTION_REMOVE).putExtra(KEY_CONTENT_ID, id);
|
||||
Context context, Class<? extends DownloadService> clazz, String id, boolean foreground) {
|
||||
return getIntent(context, clazz, ACTION_REMOVE)
|
||||
.putExtra(KEY_CONTENT_ID, id)
|
||||
.putExtra(KEY_FOREGROUND, foreground);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -308,7 +311,7 @@ public abstract class DownloadService extends Service {
|
||||
*/
|
||||
public static void startWithRemoveDownload(
|
||||
Context context, Class<? extends DownloadService> clazz, String id, boolean foreground) {
|
||||
Intent intent = buildRemoveDownloadIntent(context, clazz, id);
|
||||
Intent intent = buildRemoveDownloadIntent(context, clazz, id, foreground);
|
||||
if (foreground) {
|
||||
Util.startForegroundService(context, intent);
|
||||
} else {
|
||||
@ -393,7 +396,7 @@ public abstract class DownloadService extends Service {
|
||||
Log.e(TAG, "Ignored ADD action: Failed to deserialize download_action extra", e);
|
||||
}
|
||||
if (downloadAction != null) {
|
||||
downloadManager.handleAction(downloadAction);
|
||||
downloadManager.addDownload(downloadAction);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -166,7 +166,7 @@ public final class DownloadState {
|
||||
action.type,
|
||||
action.uri,
|
||||
action.customCacheKey,
|
||||
/* state= */ action.isRemoveAction ? STATE_REMOVING : STATE_QUEUED,
|
||||
/* state= */ STATE_QUEUED,
|
||||
/* downloadPercentage= */ C.PERCENTAGE_UNSET,
|
||||
/* downloadedBytes= */ 0,
|
||||
/* totalBytes= */ C.LENGTH_UNSET,
|
||||
@ -231,8 +231,7 @@ public final class DownloadState {
|
||||
type,
|
||||
action.uri,
|
||||
action.customCacheKey,
|
||||
getNextState(
|
||||
state, manualStopReason != 0 || notMetRequirements != 0, action.isRemoveAction),
|
||||
getNextState(state, manualStopReason != 0 || notMetRequirements != 0),
|
||||
/* downloadPercentage= */ C.PERCENTAGE_UNSET,
|
||||
downloadedBytes,
|
||||
/* totalBytes= */ C.LENGTH_UNSET,
|
||||
@ -252,7 +251,7 @@ public final class DownloadState {
|
||||
type,
|
||||
uri,
|
||||
cacheKey,
|
||||
getNextState(state, manualStopReason != 0 || notMetRequirements != 0, true),
|
||||
STATE_REMOVING,
|
||||
/* downloadPercentage= */ C.PERCENTAGE_UNSET,
|
||||
downloadedBytes,
|
||||
/* totalBytes= */ C.LENGTH_UNSET,
|
||||
@ -265,25 +264,19 @@ public final class DownloadState {
|
||||
customMetadata);
|
||||
}
|
||||
|
||||
private static int getNextState(int currentState, boolean isStopped, boolean remove) {
|
||||
int nextState;
|
||||
if (remove) {
|
||||
nextState = STATE_REMOVING;
|
||||
private static int getNextState(int currentState, boolean isStopped) {
|
||||
if (currentState == STATE_REMOVING || currentState == STATE_RESTARTING) {
|
||||
return STATE_RESTARTING;
|
||||
} else if (isStopped) {
|
||||
return STATE_STOPPED;
|
||||
} else {
|
||||
if (currentState == STATE_REMOVING || currentState == STATE_RESTARTING) {
|
||||
nextState = STATE_RESTARTING;
|
||||
} else if (isStopped) {
|
||||
nextState = STATE_STOPPED;
|
||||
} else {
|
||||
nextState = STATE_QUEUED;
|
||||
}
|
||||
return STATE_QUEUED;
|
||||
}
|
||||
return nextState;
|
||||
}
|
||||
|
||||
private static StreamKey[] mergeStreamKeys(DownloadState downloadState, DownloadAction action) {
|
||||
StreamKey[] streamKeys = downloadState.streamKeys;
|
||||
if (!action.isRemoveAction && streamKeys.length > 0) {
|
||||
if (streamKeys.length > 0) {
|
||||
if (action.keys.isEmpty()) {
|
||||
streamKeys = new StreamKey[0];
|
||||
} else {
|
||||
|
@ -20,10 +20,13 @@ 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 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;
|
||||
@ -53,92 +56,73 @@ public class DownloadActionTest {
|
||||
data = TestUtil.buildTestData(32);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDownloadActionIsNotRemoveAction() {
|
||||
DownloadAction action = createDownloadAction(uri1);
|
||||
assertThat(action.isRemoveAction).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveActionIsRemoveAction() {
|
||||
DownloadAction action2 = createRemoveAction(uri1);
|
||||
assertThat(action2.isRemoveAction).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSameUri_hasSameId() {
|
||||
DownloadAction action1 = createDownloadAction(uri1);
|
||||
DownloadAction action2 = createDownloadAction(uri1);
|
||||
DownloadAction action1 = createAction(uri1);
|
||||
DownloadAction action2 = createAction(uri1);
|
||||
assertThat(action1.id.equals(action2.id)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSameUriDifferentAction_hasSameId() {
|
||||
DownloadAction action1 = createDownloadAction(uri1);
|
||||
DownloadAction action2 = createRemoveAction(uri1);
|
||||
DownloadAction action1 = createAction(uri1);
|
||||
DownloadAction action2 = createAction(uri1);
|
||||
assertThat(action1.id.equals(action2.id)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDifferentUri_IsNotSameMedia() {
|
||||
DownloadAction action1 = createDownloadAction(uri1);
|
||||
DownloadAction action2 = createDownloadAction(uri2);
|
||||
DownloadAction action1 = createAction(uri1);
|
||||
DownloadAction action2 = createAction(uri2);
|
||||
assertThat(action1.id.equals(action2.id)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSameCacheKeyDifferentUri_hasSameId() {
|
||||
DownloadAction action1 = DownloadAction.createRemoveAction(TYPE_DASH, uri1, "key123");
|
||||
DownloadAction action2 = DownloadAction.createRemoveAction(TYPE_DASH, uri2, "key123");
|
||||
DownloadAction action1 = createAction(uri1, "key123");
|
||||
DownloadAction action2 = createAction(uri2, "key123");
|
||||
assertThat(action1.id.equals(action2.id)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDifferentCacheKeyDifferentUri_hasDifferentId() {
|
||||
DownloadAction action1 = DownloadAction.createRemoveAction(TYPE_DASH, uri1, "key123");
|
||||
DownloadAction action2 = DownloadAction.createRemoveAction(TYPE_DASH, uri2, "key456");
|
||||
DownloadAction action1 = createAction(uri1, "key123");
|
||||
DownloadAction action2 = createAction(uri2, "key456");
|
||||
assertThat(action1.id.equals(action2.id)).isFalse();
|
||||
}
|
||||
|
||||
@SuppressWarnings("EqualsWithItself")
|
||||
@Test
|
||||
public void testEquals() {
|
||||
DownloadAction action1 = createRemoveAction(uri1);
|
||||
DownloadAction action1 = createAction(uri1);
|
||||
assertThat(action1.equals(action1)).isTrue();
|
||||
|
||||
DownloadAction action2 = createRemoveAction(uri1);
|
||||
DownloadAction action3 = createRemoveAction(uri1);
|
||||
DownloadAction action2 = createAction(uri1);
|
||||
DownloadAction action3 = createAction(uri1);
|
||||
assertEqual(action2, action3);
|
||||
|
||||
DownloadAction action4 = createRemoveAction(uri1);
|
||||
DownloadAction action5 = createDownloadAction(uri1);
|
||||
assertNotEqual(action4, action5);
|
||||
|
||||
DownloadAction action6 = createDownloadAction(uri1);
|
||||
DownloadAction action7 = createDownloadAction(uri1, new StreamKey(0, 0, 0));
|
||||
DownloadAction action6 = createAction(uri1);
|
||||
DownloadAction action7 = createAction(uri1, new StreamKey(0, 0, 0));
|
||||
assertNotEqual(action6, action7);
|
||||
|
||||
DownloadAction action8 = createDownloadAction(uri1, new StreamKey(0, 1, 1));
|
||||
DownloadAction action9 = createDownloadAction(uri1, new StreamKey(0, 0, 0));
|
||||
DownloadAction action8 = createAction(uri1, new StreamKey(0, 1, 1));
|
||||
DownloadAction action9 = createAction(uri1, new StreamKey(0, 0, 0));
|
||||
assertNotEqual(action8, action9);
|
||||
|
||||
DownloadAction action10 = createRemoveAction(uri1);
|
||||
DownloadAction action11 = createRemoveAction(uri2);
|
||||
DownloadAction action10 = createAction(uri1);
|
||||
DownloadAction action11 = createAction(uri2);
|
||||
assertNotEqual(action10, action11);
|
||||
|
||||
DownloadAction action12 =
|
||||
createDownloadAction(uri1, new StreamKey(0, 0, 0), new StreamKey(0, 1, 1));
|
||||
DownloadAction action13 =
|
||||
createDownloadAction(uri1, new StreamKey(0, 1, 1), new StreamKey(0, 0, 0));
|
||||
DownloadAction action12 = createAction(uri1, new StreamKey(0, 0, 0), new StreamKey(0, 1, 1));
|
||||
DownloadAction action13 = createAction(uri1, new StreamKey(0, 1, 1), new StreamKey(0, 0, 0));
|
||||
assertEqual(action12, action13);
|
||||
|
||||
DownloadAction action14 = createDownloadAction(uri1, new StreamKey(0, 0, 0));
|
||||
DownloadAction action15 =
|
||||
createDownloadAction(uri1, new StreamKey(0, 1, 1), new StreamKey(0, 0, 0));
|
||||
DownloadAction action14 = createAction(uri1, new StreamKey(0, 0, 0));
|
||||
DownloadAction action15 = createAction(uri1, new StreamKey(0, 1, 1), new StreamKey(0, 0, 0));
|
||||
assertNotEqual(action14, action15);
|
||||
|
||||
DownloadAction action16 = createDownloadAction(uri1);
|
||||
DownloadAction action17 = createDownloadAction(uri1);
|
||||
DownloadAction action16 = createAction(uri1);
|
||||
DownloadAction action17 = createAction(uri1);
|
||||
assertEqual(action16, action17);
|
||||
}
|
||||
|
||||
@ -151,8 +135,7 @@ public class DownloadActionTest {
|
||||
toList(new StreamKey(0, 1, 2), new StreamKey(3, 4, 5)),
|
||||
"key123",
|
||||
data));
|
||||
assertStreamSerializationRoundTrip(
|
||||
DownloadAction.createRemoveAction(TYPE_DASH, uri1, "key123"));
|
||||
assertStreamSerializationRoundTrip(createAction(uri1, "key123"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -164,7 +147,7 @@ public class DownloadActionTest {
|
||||
toList(new StreamKey(0, 1, 2), new StreamKey(3, 4, 5)),
|
||||
"key123",
|
||||
data));
|
||||
assertArraySerializationRoundTrip(DownloadAction.createRemoveAction(TYPE_DASH, uri1, "key123"));
|
||||
assertArraySerializationRoundTrip(createAction(uri1, "key123"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -173,9 +156,7 @@ public class DownloadActionTest {
|
||||
"progressive-download-v0",
|
||||
DownloadAction.createDownloadAction(
|
||||
TYPE_PROGRESSIVE, uri1, Collections.emptyList(), "key123", data));
|
||||
assertDeserialization(
|
||||
"progressive-remove-v0",
|
||||
DownloadAction.createRemoveAction(TYPE_PROGRESSIVE, uri1, "key123"));
|
||||
assertUnsupportedAction("progressive-remove-v0");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -188,9 +169,7 @@ public class DownloadActionTest {
|
||||
toList(new StreamKey(0, 1, 2), new StreamKey(3, 4, 5)),
|
||||
/* customCacheKey= */ null,
|
||||
data));
|
||||
assertDeserialization(
|
||||
"dash-remove-v0",
|
||||
DownloadAction.createRemoveAction(TYPE_DASH, uri1, /* customCacheKey= */ null));
|
||||
assertUnsupportedAction("dash-remove-v0");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -203,9 +182,7 @@ public class DownloadActionTest {
|
||||
toList(new StreamKey(0, 1), new StreamKey(2, 3)),
|
||||
/* customCacheKey= */ null,
|
||||
data));
|
||||
assertDeserialization(
|
||||
"hls-remove-v0",
|
||||
DownloadAction.createRemoveAction(TYPE_HLS, uri1, /* customCacheKey= */ null));
|
||||
assertUnsupportedAction("hls-remove-v0");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -218,9 +195,7 @@ public class DownloadActionTest {
|
||||
toList(new StreamKey(0, 1, 2), new StreamKey(3, 4, 5)),
|
||||
/* customCacheKey= */ null,
|
||||
data));
|
||||
assertDeserialization(
|
||||
"hls-remove-v1",
|
||||
DownloadAction.createRemoveAction(TYPE_HLS, uri1, /* customCacheKey= */ null));
|
||||
assertUnsupportedAction("hls-remove-v1");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -233,9 +208,7 @@ public class DownloadActionTest {
|
||||
toList(new StreamKey(0, 1), new StreamKey(2, 3)),
|
||||
/* customCacheKey= */ null,
|
||||
data));
|
||||
assertDeserialization(
|
||||
"ss-remove-v0",
|
||||
DownloadAction.createRemoveAction(TYPE_SS, uri1, /* customCacheKey= */ null));
|
||||
assertUnsupportedAction("ss-remove-v0");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -248,18 +221,17 @@ public class DownloadActionTest {
|
||||
toList(new StreamKey(0, 1, 2), new StreamKey(3, 4, 5)),
|
||||
/* customCacheKey= */ null,
|
||||
data));
|
||||
assertDeserialization(
|
||||
"ss-remove-v1",
|
||||
DownloadAction.createRemoveAction(TYPE_SS, uri1, /* customCacheKey= */ null));
|
||||
assertUnsupportedAction("ss-remove-v1");
|
||||
}
|
||||
|
||||
private DownloadAction createDownloadAction(Uri uri, StreamKey... keys) {
|
||||
private DownloadAction createAction(Uri uri, StreamKey... keys) {
|
||||
return DownloadAction.createDownloadAction(
|
||||
TYPE_DASH, uri, toList(keys), /* customCacheKey= */ null, data);
|
||||
}
|
||||
|
||||
private DownloadAction createRemoveAction(Uri uri) {
|
||||
return DownloadAction.createRemoveAction(TYPE_DASH, uri, /* customCacheKey= */ null);
|
||||
private DownloadAction createAction(Uri uri, @Nullable String customCacheKey) {
|
||||
return DownloadAction.createDownloadAction(
|
||||
DownloadAction.TYPE_DASH, uri, Collections.emptyList(), customCacheKey, /* data= */ null);
|
||||
}
|
||||
|
||||
private static void assertNotEqual(DownloadAction action1, DownloadAction action2) {
|
||||
@ -298,6 +270,18 @@ public class DownloadActionTest {
|
||||
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 List<StreamKey> toList(StreamKey... keys) {
|
||||
ArrayList<StreamKey> keysList = new ArrayList<>();
|
||||
Collections.addAll(keysList, keys);
|
||||
|
@ -397,7 +397,6 @@ public class DownloadHelperTest {
|
||||
assertThat(downloadAction.type).isEqualTo(TEST_DOWNLOAD_TYPE);
|
||||
assertThat(downloadAction.uri).isEqualTo(testUri);
|
||||
assertThat(downloadAction.customCacheKey).isEqualTo(TEST_CACHE_KEY);
|
||||
assertThat(downloadAction.isRemoveAction).isFalse();
|
||||
assertThat(downloadAction.data).isEqualTo(data);
|
||||
assertThat(downloadAction.keys)
|
||||
.containsExactly(
|
||||
|
@ -127,16 +127,11 @@ public class DownloadIndexUtilTest {
|
||||
/* customCacheKey= */ "key234",
|
||||
new byte[] {5, 4, 3, 2, 1});
|
||||
actionFile.store(action1, action2);
|
||||
DownloadAction action3 =
|
||||
DownloadAction.createRemoveAction(
|
||||
TYPE_DASH, Uri.parse("https://www.test.com/download3"), /* customCacheKey= */ "key345");
|
||||
actionFile.store(action1, action2, action3);
|
||||
|
||||
DownloadIndexUtil.upgradeActionFile(actionFile, downloadIndex, /* downloadIdProvider= */ null);
|
||||
|
||||
assertDownloadIndexContainsAction(action1, DownloadState.STATE_QUEUED);
|
||||
assertDownloadIndexContainsAction(action2, DownloadState.STATE_QUEUED);
|
||||
assertDownloadIndexContainsAction(action3, DownloadState.STATE_REMOVING);
|
||||
}
|
||||
|
||||
private void assertDownloadIndexContainsAction(DownloadAction action, int state)
|
||||
|
@ -16,7 +16,6 @@
|
||||
package com.google.android.exoplayer2.offline;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import android.net.Uri;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
@ -33,7 +32,6 @@ import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.junit.After;
|
||||
@ -101,21 +99,6 @@ public class DownloadManagerTest {
|
||||
assertThat(exceptionThrown).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void downloadRunner_handleActionReturnsDifferentTaskId_throwsException() {
|
||||
DownloadRunner runner = new DownloadRunner(uri1).postDownloadAction();
|
||||
TaskWrapper task = runner.getTask();
|
||||
runner.setTask(new TaskWrapper(task.taskId + 10000));
|
||||
boolean exceptionThrown = false;
|
||||
try {
|
||||
runner.postDownloadAction();
|
||||
// can't put fail() here as it would be caught in the catch below.
|
||||
} catch (Throwable e) {
|
||||
exceptionThrown = true;
|
||||
}
|
||||
assertThat(exceptionThrown).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleActionsForTheSameContent_executedOnTheSameTask() {
|
||||
// Two download actions on first task
|
||||
@ -150,11 +133,11 @@ public class DownloadManagerTest {
|
||||
@Test
|
||||
public void postRemoveAction_removes() throws Throwable {
|
||||
DownloadRunner runner = new DownloadRunner(uri1);
|
||||
TaskWrapper task = runner.postRemoveAction().getTask();
|
||||
TaskWrapper task = runner.postDownloadAction().postRemoveAction().getTask();
|
||||
task.assertRemoving();
|
||||
runner.getDownloader(0).unblock().assertReleased().assertStartCount(1);
|
||||
runner.getDownloader(1).unblock().assertReleased().assertStartCount(1);
|
||||
task.assertRemoved();
|
||||
runner.assertCreatedDownloaderCount(1);
|
||||
runner.assertCreatedDownloaderCount(2);
|
||||
downloadManagerListener.blockUntilTasksCompleteAndThrowAnyDownloadError();
|
||||
}
|
||||
|
||||
@ -224,29 +207,29 @@ public class DownloadManagerTest {
|
||||
@Test
|
||||
public void downloadNotCancelRemove() throws Throwable {
|
||||
DownloadRunner runner = new DownloadRunner(uri1);
|
||||
FakeDownloader downloader1 = runner.getDownloader(0);
|
||||
FakeDownloader downloader1 = runner.getDownloader(1);
|
||||
|
||||
runner.postRemoveAction();
|
||||
runner.postDownloadAction().postRemoveAction();
|
||||
downloader1.assertStarted();
|
||||
runner.postDownloadAction();
|
||||
|
||||
downloader1.unblock().assertNotCanceled();
|
||||
runner.getDownloader(1).unblock().assertNotCanceled();
|
||||
runner.getDownloader(2).unblock().assertNotCanceled();
|
||||
downloadManagerListener.blockUntilTasksCompleteAndThrowAnyDownloadError();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void secondSameRemoveActionIgnored() throws Throwable {
|
||||
DownloadRunner runner = new DownloadRunner(uri1);
|
||||
FakeDownloader downloader1 = runner.getDownloader(0);
|
||||
FakeDownloader downloader1 = runner.getDownloader(1);
|
||||
|
||||
runner.postRemoveAction();
|
||||
runner.postDownloadAction().postRemoveAction();
|
||||
downloader1.assertStarted();
|
||||
runner.postRemoveAction();
|
||||
|
||||
downloader1.unblock().assertNotCanceled();
|
||||
runner.getTask().assertRemoved();
|
||||
runner.assertCreatedDownloaderCount(1);
|
||||
runner.assertCreatedDownloaderCount(2);
|
||||
downloadManagerListener.blockUntilTasksCompleteAndThrowAnyDownloadError();
|
||||
}
|
||||
|
||||
@ -316,7 +299,7 @@ public class DownloadManagerTest {
|
||||
throws Throwable {
|
||||
setUpDownloadManager(1);
|
||||
DownloadRunner runner1 = new DownloadRunner(uri1).postDownloadAction();
|
||||
DownloadRunner runner2 = new DownloadRunner(uri2).postRemoveAction();
|
||||
DownloadRunner runner2 = new DownloadRunner(uri2).postDownloadAction().postRemoveAction();
|
||||
FakeDownloader downloader1 = runner1.getDownloader(0);
|
||||
FakeDownloader downloader2 = runner2.getDownloader(0);
|
||||
|
||||
@ -334,7 +317,8 @@ public class DownloadManagerTest {
|
||||
public void downloadActionFollowingRemove_ifMaxDownloadIs1_isNotStarted() throws Throwable {
|
||||
setUpDownloadManager(1);
|
||||
DownloadRunner runner1 = new DownloadRunner(uri1).postDownloadAction();
|
||||
DownloadRunner runner2 = new DownloadRunner(uri2).postRemoveAction().postDownloadAction();
|
||||
DownloadRunner runner2 = new DownloadRunner(uri2).postDownloadAction().postRemoveAction();
|
||||
runner2.postDownloadAction();
|
||||
FakeDownloader downloader1 = runner1.getDownloader(0);
|
||||
FakeDownloader downloader2 = runner2.getDownloader(0);
|
||||
FakeDownloader downloader3 = runner2.getDownloader(1);
|
||||
@ -356,7 +340,7 @@ public class DownloadManagerTest {
|
||||
public void getTasks_returnTasks() {
|
||||
TaskWrapper task1 = new DownloadRunner(uri1).postDownloadAction().getTask();
|
||||
TaskWrapper task2 = new DownloadRunner(uri2).postDownloadAction().getTask();
|
||||
TaskWrapper task3 = new DownloadRunner(uri3).postRemoveAction().getTask();
|
||||
TaskWrapper task3 = new DownloadRunner(uri3).postDownloadAction().postRemoveAction().getTask();
|
||||
|
||||
task3.assertRemoving();
|
||||
DownloadState[] states = downloadManager.getAllDownloadStates();
|
||||
@ -374,7 +358,7 @@ public class DownloadManagerTest {
|
||||
DownloadRunner runner3 = new DownloadRunner(uri3);
|
||||
|
||||
runner1.postDownloadAction().getTask().assertDownloading();
|
||||
runner2.postRemoveAction().getTask().assertRemoving();
|
||||
runner2.postDownloadAction().postRemoveAction().getTask().assertRemoving();
|
||||
runner2.postDownloadAction();
|
||||
|
||||
runOnMainThread(() -> downloadManager.stopDownloads());
|
||||
@ -382,10 +366,10 @@ public class DownloadManagerTest {
|
||||
runner1.getTask().assertStopped();
|
||||
|
||||
// remove actions aren't stopped.
|
||||
runner2.getDownloader(0).unblock().assertReleased();
|
||||
runner2.getDownloader(1).unblock().assertReleased();
|
||||
runner2.getTask().assertStopped();
|
||||
// Although remove2 is finished, download2 doesn't start.
|
||||
runner2.getDownloader(1).assertDoesNotStart();
|
||||
runner2.getDownloader(2).assertDoesNotStart();
|
||||
|
||||
// When a new remove action is added, it cancels stopped download actions with the same media.
|
||||
runner1.postRemoveAction();
|
||||
@ -397,7 +381,7 @@ public class DownloadManagerTest {
|
||||
|
||||
runOnMainThread(() -> downloadManager.startDownloads());
|
||||
|
||||
runner2.getDownloader(1).assertStarted().unblock();
|
||||
runner2.getDownloader(2).assertStarted().unblock();
|
||||
runner3.getDownloader(0).assertStarted().unblock();
|
||||
|
||||
downloadManagerListener.blockUntilTasksCompleteAndThrowAnyDownloadError();
|
||||
@ -446,14 +430,14 @@ public class DownloadManagerTest {
|
||||
DownloadRunner runner3 = new DownloadRunner(uri3);
|
||||
|
||||
runner1.postDownloadAction().getTask().assertDownloading();
|
||||
runner2.postRemoveAction().getTask().assertRemoving();
|
||||
runner2.postDownloadAction().postRemoveAction().getTask().assertRemoving();
|
||||
|
||||
runOnMainThread(() -> downloadManager.stopDownload(runner1.getTask().taskId));
|
||||
|
||||
runner1.getTask().assertStopped();
|
||||
|
||||
// Other downloads aren't affected.
|
||||
runner2.getDownloader(0).unblock().assertReleased();
|
||||
runner2.getDownloader(1).unblock().assertReleased();
|
||||
|
||||
// New download actions can be added and they start.
|
||||
runner3.postDownloadAction().getDownloader(0).assertStarted().unblock();
|
||||
@ -501,33 +485,36 @@ public class DownloadManagerTest {
|
||||
private final class DownloadRunner {
|
||||
|
||||
private final Uri uri;
|
||||
private final String id;
|
||||
private final ArrayList<FakeDownloader> downloaders;
|
||||
private int createdDownloaderCount = 0;
|
||||
private FakeDownloader downloader;
|
||||
private TaskWrapper taskWrapper;
|
||||
private final TaskWrapper taskWrapper;
|
||||
|
||||
private DownloadRunner(Uri uri) {
|
||||
this.uri = uri;
|
||||
id = uri.toString();
|
||||
downloaders = new ArrayList<>();
|
||||
downloader = addDownloader();
|
||||
downloaderFactory.registerDownloadRunner(this);
|
||||
taskWrapper = new TaskWrapper(id);
|
||||
}
|
||||
|
||||
private DownloadRunner postRemoveAction() {
|
||||
return postAction(createRemoveAction(uri));
|
||||
runOnMainThread(() -> downloadManager.removeDownload(id));
|
||||
return this;
|
||||
}
|
||||
|
||||
private DownloadRunner postDownloadAction(StreamKey... keys) {
|
||||
return postAction(createDownloadAction(uri, keys));
|
||||
}
|
||||
|
||||
private DownloadRunner postAction(DownloadAction action) {
|
||||
runOnMainThread(() -> downloadManager.handleAction(action));
|
||||
if (taskWrapper == null) {
|
||||
taskWrapper = new TaskWrapper(action.id);
|
||||
} else {
|
||||
assertThat(action.id).isEqualTo(taskWrapper.taskId);
|
||||
}
|
||||
DownloadAction downloadAction =
|
||||
DownloadAction.createDownloadAction(
|
||||
id,
|
||||
DownloadAction.TYPE_PROGRESSIVE,
|
||||
uri,
|
||||
Arrays.asList(keys),
|
||||
/* customCacheKey= */ null,
|
||||
/* data= */ null);
|
||||
runOnMainThread(() -> downloadManager.addDownload(downloadAction));
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -554,10 +541,6 @@ public class DownloadManagerTest {
|
||||
return taskWrapper;
|
||||
}
|
||||
|
||||
public void setTask(TaskWrapper taskWrapper) {
|
||||
this.taskWrapper = taskWrapper;
|
||||
}
|
||||
|
||||
private void assertCreatedDownloaderCount(int count) {
|
||||
assertThat(createdDownloaderCount).isEqualTo(count);
|
||||
}
|
||||
@ -599,35 +582,8 @@ public class DownloadManagerTest {
|
||||
}
|
||||
|
||||
private TaskWrapper assertState(@State int expectedState) {
|
||||
ArrayList<Integer> receivedStates = new ArrayList<>();
|
||||
while (true) {
|
||||
Integer state = null;
|
||||
try {
|
||||
state = downloadManagerListener.pollStateChange(taskId, ASSERT_TRUE_TIMEOUT);
|
||||
} catch (InterruptedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
if (state != null) {
|
||||
if (expectedState == state) {
|
||||
return this;
|
||||
}
|
||||
receivedStates.add(state);
|
||||
} else {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < receivedStates.size(); i++) {
|
||||
if (i > 0) {
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append(DownloadState.getStateString(receivedStates.get(i)));
|
||||
}
|
||||
fail(
|
||||
String.format(
|
||||
Locale.US,
|
||||
"expected:<%s> but was:<%s>",
|
||||
DownloadState.getStateString(expectedState),
|
||||
sb));
|
||||
}
|
||||
}
|
||||
downloadManagerListener.assertState(taskId, expectedState, ASSERT_TRUE_TIMEOUT);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -647,20 +603,6 @@ public class DownloadManagerTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static DownloadAction createDownloadAction(Uri uri, StreamKey... keys) {
|
||||
return DownloadAction.createDownloadAction(
|
||||
DownloadAction.TYPE_PROGRESSIVE,
|
||||
uri,
|
||||
Arrays.asList(keys),
|
||||
/* customCacheKey= */ null,
|
||||
/* data= */ null);
|
||||
}
|
||||
|
||||
private static DownloadAction createRemoveAction(Uri uri) {
|
||||
return DownloadAction.createRemoveAction(
|
||||
DownloadAction.TYPE_PROGRESSIVE, uri, /* customCacheKey= */ null);
|
||||
}
|
||||
|
||||
private static final class FakeDownloaderFactory implements DownloaderFactory {
|
||||
|
||||
private final HashMap<Uri, DownloadRunner> downloaders;
|
||||
|
@ -118,20 +118,6 @@ public class DownloadStateTest {
|
||||
assertEqual(mergedDownloadState, expectedDownloadState);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mergeAction_queuedDownloadRemoveAction_stateBecomesRemoving() {
|
||||
DownloadAction downloadAction = createRemoveAction();
|
||||
DownloadStateBuilder downloadStateBuilder =
|
||||
new DownloadStateBuilder(downloadAction).setState(DownloadState.STATE_QUEUED);
|
||||
DownloadState downloadState = downloadStateBuilder.build();
|
||||
|
||||
DownloadState mergedDownloadState = downloadState.mergeAction(downloadAction);
|
||||
|
||||
DownloadState expectedDownloadState =
|
||||
downloadStateBuilder.setState(DownloadState.STATE_REMOVING).build();
|
||||
assertEqual(mergedDownloadState, expectedDownloadState);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mergeAction_removingDownloadDownloadAction_stateBecomesRestarting() {
|
||||
DownloadAction downloadAction = createDownloadAction();
|
||||
@ -179,22 +165,6 @@ public class DownloadStateTest {
|
||||
assertEqual(mergedDownloadState, downloadState);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mergeAction_stoppedDownloadRemoveAction_stateBecomesRemoving() {
|
||||
DownloadAction downloadAction = createRemoveAction();
|
||||
DownloadStateBuilder downloadStateBuilder =
|
||||
new DownloadStateBuilder(downloadAction)
|
||||
.setState(DownloadState.STATE_STOPPED)
|
||||
.setManualStopReason(DownloadState.MANUAL_STOP_REASON_UNDEFINED);
|
||||
DownloadState downloadState = downloadStateBuilder.build();
|
||||
|
||||
DownloadState mergedDownloadState = downloadState.mergeAction(downloadAction);
|
||||
|
||||
DownloadState expectedDownloadState =
|
||||
downloadStateBuilder.setState(DownloadState.STATE_REMOVING).build();
|
||||
assertEqual(mergedDownloadState, expectedDownloadState);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mergeAction_manualStopReasonSetButNotInStoppedState_stateBecomesStopped() {
|
||||
DownloadAction downloadAction = createDownloadAction();
|
||||
@ -227,20 +197,6 @@ public class DownloadStateTest {
|
||||
assertEqual(mergedDownloadState, expectedDownloadState);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mergeAction_restartingDownloadRemoveAction_stateBecomesRemoving() {
|
||||
DownloadAction downloadAction = createRemoveAction();
|
||||
DownloadStateBuilder downloadStateBuilder =
|
||||
new DownloadStateBuilder(downloadAction).setState(DownloadState.STATE_RESTARTING);
|
||||
DownloadState downloadState = downloadStateBuilder.build();
|
||||
|
||||
DownloadState mergedDownloadState = downloadState.mergeAction(downloadAction);
|
||||
|
||||
DownloadState expectedDownloadState =
|
||||
downloadStateBuilder.setState(DownloadState.STATE_REMOVING).build();
|
||||
assertEqual(mergedDownloadState, expectedDownloadState);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mergeAction_returnsMergedKeys() {
|
||||
StreamKey streamKey1 = new StreamKey(/* groupIndex= */ 0, /* trackIndex= */ 0);
|
||||
@ -340,9 +296,4 @@ public class DownloadStateTest {
|
||||
/* customCacheKey= */ null,
|
||||
/* data= */ null);
|
||||
}
|
||||
|
||||
private DownloadAction createRemoveAction() {
|
||||
return DownloadAction.createRemoveAction(
|
||||
DownloadAction.TYPE_DASH, testUri, /* customCacheKey= */ null);
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,8 @@ import java.nio.charset.Charset;
|
||||
/** Data for DASH downloading tests. */
|
||||
/* package */ interface DashDownloadTestData {
|
||||
|
||||
Uri TEST_MPD_URI = Uri.parse("test.mpd");
|
||||
String TEST_ID = "test.mpd";
|
||||
Uri TEST_MPD_URI = Uri.parse(TEST_ID);
|
||||
|
||||
byte[] TEST_MPD =
|
||||
("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.source.dash.offline;
|
||||
|
||||
import static com.google.android.exoplayer2.source.dash.offline.DashDownloadTestData.TEST_ID;
|
||||
import static com.google.android.exoplayer2.source.dash.offline.DashDownloadTestData.TEST_MPD;
|
||||
import static com.google.android.exoplayer2.source.dash.offline.DashDownloadTestData.TEST_MPD_URI;
|
||||
import static com.google.android.exoplayer2.testutil.CacheAsserts.assertCacheEmpty;
|
||||
@ -22,9 +23,7 @@ import static com.google.android.exoplayer2.testutil.CacheAsserts.assertCachedDa
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.ConditionVariable;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.android.exoplayer2.offline.DefaultDownloadIndex;
|
||||
@ -230,11 +229,16 @@ public class DownloadManagerDashTest {
|
||||
}
|
||||
|
||||
private void handleDownloadAction(StreamKey... keys) {
|
||||
downloadManager.handleAction(newAction(TEST_MPD_URI, false, null, keys));
|
||||
ArrayList<StreamKey> keysList = new ArrayList<>();
|
||||
Collections.addAll(keysList, keys);
|
||||
DownloadAction action =
|
||||
DownloadAction.createDownloadAction(
|
||||
DownloadAction.TYPE_DASH, TEST_MPD_URI, keysList, /* customCacheKey= */ null, null);
|
||||
downloadManager.addDownload(action);
|
||||
}
|
||||
|
||||
private void handleRemoveAction() {
|
||||
downloadManager.handleAction(newAction(TEST_MPD_URI, true, null));
|
||||
downloadManager.removeDownload(TEST_ID);
|
||||
}
|
||||
|
||||
private void createDownloadManager() {
|
||||
@ -257,20 +261,4 @@ public class DownloadManagerDashTest {
|
||||
});
|
||||
}
|
||||
|
||||
private static DownloadAction newAction(
|
||||
Uri uri, boolean isRemoveAction, @Nullable byte[] data, StreamKey... keys) {
|
||||
ArrayList<StreamKey> keysList = new ArrayList<>();
|
||||
Collections.addAll(keysList, keys);
|
||||
DownloadAction result;
|
||||
if (isRemoveAction) {
|
||||
result =
|
||||
DownloadAction.createRemoveAction(
|
||||
DownloadAction.TYPE_DASH, uri, /* customCacheKey= */ null);
|
||||
} else {
|
||||
result =
|
||||
DownloadAction.createDownloadAction(
|
||||
DownloadAction.TYPE_DASH, uri, keysList, /* customCacheKey= */ null, data);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.source.dash.offline;
|
||||
|
||||
import static com.google.android.exoplayer2.source.dash.offline.DashDownloadTestData.TEST_ID;
|
||||
import static com.google.android.exoplayer2.source.dash.offline.DashDownloadTestData.TEST_MPD;
|
||||
import static com.google.android.exoplayer2.source.dash.offline.DashDownloadTestData.TEST_MPD_URI;
|
||||
import static com.google.android.exoplayer2.testutil.CacheAsserts.assertCacheEmpty;
|
||||
@ -22,7 +23,6 @@ import static com.google.android.exoplayer2.testutil.CacheAsserts.assertCachedDa
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
@ -187,37 +187,29 @@ public class DownloadServiceDashTest {
|
||||
assertCacheEmpty(cache);
|
||||
}
|
||||
|
||||
private void removeAll() throws Throwable {
|
||||
callDownloadServiceOnStart(newAction(TEST_MPD_URI, true, null));
|
||||
}
|
||||
|
||||
private void downloadKeys(StreamKey... keys) {
|
||||
callDownloadServiceOnStart(newAction(TEST_MPD_URI, false, null, keys));
|
||||
}
|
||||
|
||||
private void callDownloadServiceOnStart(final DownloadAction action) {
|
||||
private void removeAll() {
|
||||
dummyMainThread.runOnMainThread(
|
||||
() -> {
|
||||
Intent startIntent =
|
||||
DownloadService.buildAddActionIntent(context, DownloadService.class, action, false);
|
||||
DownloadService.buildRemoveDownloadIntent(
|
||||
context, DownloadService.class, TEST_ID, /* foreground= */ false);
|
||||
dashDownloadService.onStartCommand(startIntent, 0, 0);
|
||||
});
|
||||
}
|
||||
|
||||
private static DownloadAction newAction(
|
||||
Uri uri, boolean isRemoveAction, @Nullable byte[] data, StreamKey... keys) {
|
||||
private void downloadKeys(StreamKey... keys) {
|
||||
ArrayList<StreamKey> keysList = new ArrayList<>();
|
||||
Collections.addAll(keysList, keys);
|
||||
DownloadAction result;
|
||||
if (isRemoveAction) {
|
||||
result =
|
||||
DownloadAction.createRemoveAction(
|
||||
DownloadAction.TYPE_DASH, uri, /* customCacheKey= */ null);
|
||||
} else {
|
||||
result =
|
||||
DownloadAction.createDownloadAction(
|
||||
DownloadAction.TYPE_DASH, uri, keysList, /* customCacheKey= */ null, data);
|
||||
}
|
||||
return result;
|
||||
DownloadAction action =
|
||||
DownloadAction.createDownloadAction(
|
||||
DownloadAction.TYPE_DASH, TEST_MPD_URI, keysList, /* customCacheKey= */ null, null);
|
||||
dummyMainThread.runOnMainThread(
|
||||
() -> {
|
||||
Intent startIntent =
|
||||
DownloadService.buildAddActionIntent(
|
||||
context, DownloadService.class, action, /* foreground= */ false);
|
||||
dashDownloadService.onStartCommand(startIntent, 0, 0);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,11 +16,15 @@
|
||||
package com.google.android.exoplayer2.testutil;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import android.os.ConditionVariable;
|
||||
import com.google.android.exoplayer2.offline.DownloadManager;
|
||||
import com.google.android.exoplayer2.offline.DownloadState;
|
||||
import com.google.android.exoplayer2.offline.DownloadState.State;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -115,4 +119,37 @@ public final class TestDownloadManagerListener implements DownloadManager.Listen
|
||||
return actionStates.get(taskId);
|
||||
}
|
||||
}
|
||||
|
||||
public void assertState(String taskId, @State int expectedState, int timeoutMs) {
|
||||
ArrayList<Integer> receivedStates = new ArrayList<>();
|
||||
while (true) {
|
||||
Integer state = null;
|
||||
try {
|
||||
state = pollStateChange(taskId, timeoutMs);
|
||||
} catch (InterruptedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
if (state != null) {
|
||||
if (expectedState == state) {
|
||||
return;
|
||||
}
|
||||
receivedStates.add(state);
|
||||
} else {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < receivedStates.size(); i++) {
|
||||
if (i > 0) {
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append(DownloadState.getStateString(receivedStates.get(i)));
|
||||
}
|
||||
fail(
|
||||
String.format(
|
||||
Locale.US,
|
||||
"for download (%s) expected:<%s> but was:<%s>",
|
||||
taskId,
|
||||
DownloadState.getStateString(expectedState),
|
||||
sb));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user