Simplify DownloadState to contain its DownloadAction

This makes sense now that DownloadAction is only for downloading,
and not also for removal.

PiperOrigin-RevId: 242561575
This commit is contained in:
olly 2019-04-09 00:26:07 +01:00 committed by Oliver Woodman
parent 73acdcf1e2
commit 18dcad9b8d
12 changed files with 161 additions and 222 deletions

View File

@ -74,13 +74,13 @@ public class DemoDownloadService extends DownloadService {
notificationHelper.buildDownloadCompletedNotification( notificationHelper.buildDownloadCompletedNotification(
R.drawable.ic_download_done, R.drawable.ic_download_done,
/* contentIntent= */ null, /* contentIntent= */ null,
Util.fromUtf8Bytes(downloadState.customMetadata)); Util.fromUtf8Bytes(downloadState.action.data));
} else if (downloadState.state == DownloadState.STATE_FAILED) { } else if (downloadState.state == DownloadState.STATE_FAILED) {
notification = notification =
notificationHelper.buildDownloadFailedNotification( notificationHelper.buildDownloadFailedNotification(
R.drawable.ic_download_done, R.drawable.ic_download_done,
/* contentIntent= */ null, /* contentIntent= */ null,
Util.fromUtf8Bytes(downloadState.customMetadata)); Util.fromUtf8Bytes(downloadState.action.data));
} else { } else {
return; return;
} }

View File

@ -37,7 +37,6 @@ import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.util.Log; import com.google.android.exoplayer2.util.Log;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -96,7 +95,7 @@ public class DownloadTracker implements DownloadManager.Listener {
public List<StreamKey> getOfflineStreamKeys(Uri uri) { public List<StreamKey> getOfflineStreamKeys(Uri uri) {
DownloadState downloadState = downloadStates.get(uri); DownloadState downloadState = downloadStates.get(uri);
return downloadState != null && downloadState.state != DownloadState.STATE_FAILED return downloadState != null && downloadState.state != DownloadState.STATE_FAILED
? Arrays.asList(downloadState.streamKeys) ? downloadState.action.streamKeys
: Collections.emptyList(); : Collections.emptyList();
} }
@ -109,7 +108,7 @@ public class DownloadTracker implements DownloadManager.Listener {
DownloadState downloadState = downloadStates.get(uri); DownloadState downloadState = downloadStates.get(uri);
if (downloadState != null) { if (downloadState != null) {
DownloadService.startWithRemoveDownload( DownloadService.startWithRemoveDownload(
context, DemoDownloadService.class, downloadState.id, /* foreground= */ false); context, DemoDownloadService.class, downloadState.action.id, /* foreground= */ false);
} else { } else {
if (startDownloadDialogHelper != null) { if (startDownloadDialogHelper != null) {
startDownloadDialogHelper.release(); startDownloadDialogHelper.release();
@ -124,23 +123,19 @@ public class DownloadTracker implements DownloadManager.Listener {
@Override @Override
public void onDownloadStateChanged(DownloadManager downloadManager, DownloadState downloadState) { public void onDownloadStateChanged(DownloadManager downloadManager, DownloadState downloadState) {
boolean downloadAdded = downloadStates.put(downloadState.uri, downloadState) == null; downloadStates.put(downloadState.action.uri, downloadState);
if (downloadAdded) {
for (Listener listener : listeners) { for (Listener listener : listeners) {
listener.onDownloadsChanged(); listener.onDownloadsChanged();
} }
} }
}
@Override @Override
public void onDownloadRemoved(DownloadManager downloadManager, DownloadState downloadState) { public void onDownloadRemoved(DownloadManager downloadManager, DownloadState downloadState) {
boolean downloadRemoved = downloadStates.remove(downloadState.uri) != null; downloadStates.remove(downloadState.action.uri);
if (downloadRemoved) {
for (Listener listener : listeners) { for (Listener listener : listeners) {
listener.onDownloadsChanged(); listener.onDownloadsChanged();
} }
} }
}
// Internal methods // Internal methods
@ -148,7 +143,7 @@ public class DownloadTracker implements DownloadManager.Listener {
try (DownloadStateCursor loadedDownloadStates = downloadIndex.getDownloadStates()) { try (DownloadStateCursor loadedDownloadStates = downloadIndex.getDownloadStates()) {
while (loadedDownloadStates.moveToNext()) { while (loadedDownloadStates.moveToNext()) {
DownloadState downloadState = loadedDownloadStates.getDownloadState(); DownloadState downloadState = loadedDownloadStates.getDownloadState();
downloadStates.put(downloadState.uri, downloadState); downloadStates.put(downloadState.action.uri, downloadState);
} }
} catch (IOException e) { } catch (IOException e) {
Log.w(TAG, "Failed to query download states", e); Log.w(TAG, "Failed to query download states", e);

View File

@ -29,6 +29,8 @@ import com.google.android.exoplayer2.database.VersionTable;
import com.google.android.exoplayer2.upstream.cache.CacheUtil.CachingCounters; import com.google.android.exoplayer2.upstream.cache.CacheUtil.CachingCounters;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import java.util.ArrayList;
import java.util.List;
/** /**
* A {@link DownloadIndex} which uses SQLite to persist {@link DownloadState}s. * A {@link DownloadIndex} which uses SQLite to persist {@link DownloadState}s.
@ -38,8 +40,7 @@ import com.google.android.exoplayer2.util.Util;
*/ */
public final class DefaultDownloadIndex implements DownloadIndex { public final class DefaultDownloadIndex implements DownloadIndex {
@VisibleForTesting private static final String TABLE_NAME = DatabaseProvider.TABLE_PREFIX + "Downloads";
/* package */ static final String TABLE_NAME = DatabaseProvider.TABLE_PREFIX + "Downloads";
// TODO: Support multiple instances. Probably using the underlying cache UID. // TODO: Support multiple instances. Probably using the underlying cache UID.
@VisibleForTesting /* package */ static final String INSTANCE_UID = "singleton"; @VisibleForTesting /* package */ static final String INSTANCE_UID = "singleton";
@ -48,7 +49,9 @@ public final class DefaultDownloadIndex implements DownloadIndex {
private static final String COLUMN_ID = "id"; private static final String COLUMN_ID = "id";
private static final String COLUMN_TYPE = "title"; private static final String COLUMN_TYPE = "title";
private static final String COLUMN_URI = "subtitle"; private static final String COLUMN_URI = "subtitle";
private static final String COLUMN_CACHE_KEY = "cache_key"; private static final String COLUMN_STREAM_KEYS = "stream_keys";
private static final String COLUMN_CUSTOM_CACHE_KEY = "cache_key";
private static final String COLUMN_DATA = "custom_metadata";
private static final String COLUMN_STATE = "state"; private static final String COLUMN_STATE = "state";
private static final String COLUMN_DOWNLOAD_PERCENTAGE = "download_percentage"; private static final String COLUMN_DOWNLOAD_PERCENTAGE = "download_percentage";
private static final String COLUMN_DOWNLOADED_BYTES = "downloaded_bytes"; private static final String COLUMN_DOWNLOADED_BYTES = "downloaded_bytes";
@ -58,8 +61,6 @@ public final class DefaultDownloadIndex implements DownloadIndex {
private static final String COLUMN_MANUAL_STOP_REASON = "manual_stop_reason"; private static final String COLUMN_MANUAL_STOP_REASON = "manual_stop_reason";
private static final String COLUMN_START_TIME_MS = "start_time_ms"; private static final String COLUMN_START_TIME_MS = "start_time_ms";
private static final String COLUMN_UPDATE_TIME_MS = "update_time_ms"; private static final String COLUMN_UPDATE_TIME_MS = "update_time_ms";
private static final String COLUMN_STREAM_KEYS = "stream_keys";
private static final String COLUMN_CUSTOM_METADATA = "custom_metadata";
@SuppressWarnings("DeprecatedIsStillUsed") @SuppressWarnings("DeprecatedIsStillUsed")
@Deprecated @Deprecated
@ -68,18 +69,18 @@ public final class DefaultDownloadIndex implements DownloadIndex {
private static final int COLUMN_INDEX_ID = 0; private static final int COLUMN_INDEX_ID = 0;
private static final int COLUMN_INDEX_TYPE = 1; private static final int COLUMN_INDEX_TYPE = 1;
private static final int COLUMN_INDEX_URI = 2; private static final int COLUMN_INDEX_URI = 2;
private static final int COLUMN_INDEX_CACHE_KEY = 3; private static final int COLUMN_INDEX_STREAM_KEYS = 3;
private static final int COLUMN_INDEX_STATE = 4; private static final int COLUMN_INDEX_CUSTOM_CACHE_KEY = 4;
private static final int COLUMN_INDEX_DOWNLOAD_PERCENTAGE = 5; private static final int COLUMN_INDEX_DATA = 5;
private static final int COLUMN_INDEX_DOWNLOADED_BYTES = 6; private static final int COLUMN_INDEX_STATE = 6;
private static final int COLUMN_INDEX_TOTAL_BYTES = 7; private static final int COLUMN_INDEX_DOWNLOAD_PERCENTAGE = 7;
private static final int COLUMN_INDEX_FAILURE_REASON = 8; private static final int COLUMN_INDEX_DOWNLOADED_BYTES = 8;
private static final int COLUMN_INDEX_NOT_MET_REQUIREMENTS = 9; private static final int COLUMN_INDEX_TOTAL_BYTES = 9;
private static final int COLUMN_INDEX_MANUAL_STOP_REASON = 10; private static final int COLUMN_INDEX_FAILURE_REASON = 10;
private static final int COLUMN_INDEX_START_TIME_MS = 11; private static final int COLUMN_INDEX_NOT_MET_REQUIREMENTS = 11;
private static final int COLUMN_INDEX_UPDATE_TIME_MS = 12; private static final int COLUMN_INDEX_MANUAL_STOP_REASON = 12;
private static final int COLUMN_INDEX_STREAM_KEYS = 13; private static final int COLUMN_INDEX_START_TIME_MS = 13;
private static final int COLUMN_INDEX_CUSTOM_METADATA = 14; private static final int COLUMN_INDEX_UPDATE_TIME_MS = 14;
private static final String WHERE_ID_EQUALS = COLUMN_ID + " = ?"; private static final String WHERE_ID_EQUALS = COLUMN_ID + " = ?";
private static final String WHERE_STATE_TERMINAL = private static final String WHERE_STATE_TERMINAL =
@ -90,7 +91,9 @@ public final class DefaultDownloadIndex implements DownloadIndex {
COLUMN_ID, COLUMN_ID,
COLUMN_TYPE, COLUMN_TYPE,
COLUMN_URI, COLUMN_URI,
COLUMN_CACHE_KEY, COLUMN_STREAM_KEYS,
COLUMN_CUSTOM_CACHE_KEY,
COLUMN_DATA,
COLUMN_STATE, COLUMN_STATE,
COLUMN_DOWNLOAD_PERCENTAGE, COLUMN_DOWNLOAD_PERCENTAGE,
COLUMN_DOWNLOADED_BYTES, COLUMN_DOWNLOADED_BYTES,
@ -99,9 +102,7 @@ public final class DefaultDownloadIndex implements DownloadIndex {
COLUMN_NOT_MET_REQUIREMENTS, COLUMN_NOT_MET_REQUIREMENTS,
COLUMN_MANUAL_STOP_REASON, COLUMN_MANUAL_STOP_REASON,
COLUMN_START_TIME_MS, COLUMN_START_TIME_MS,
COLUMN_UPDATE_TIME_MS, COLUMN_UPDATE_TIME_MS
COLUMN_STREAM_KEYS,
COLUMN_CUSTOM_METADATA
}; };
private static final String SQL_DROP_TABLE_IF_EXISTS = "DROP TABLE IF EXISTS " + TABLE_NAME; private static final String SQL_DROP_TABLE_IF_EXISTS = "DROP TABLE IF EXISTS " + TABLE_NAME;
@ -115,7 +116,7 @@ public final class DefaultDownloadIndex implements DownloadIndex {
+ " TEXT NOT NULL," + " TEXT NOT NULL,"
+ COLUMN_URI + COLUMN_URI
+ " TEXT NOT NULL," + " TEXT NOT NULL,"
+ COLUMN_CACHE_KEY + COLUMN_CUSTOM_CACHE_KEY
+ " TEXT," + " TEXT,"
+ COLUMN_STATE + COLUMN_STATE
+ " INTEGER NOT NULL," + " INTEGER NOT NULL,"
@ -139,7 +140,7 @@ public final class DefaultDownloadIndex implements DownloadIndex {
+ " INTEGER NOT NULL," + " INTEGER NOT NULL,"
+ COLUMN_STREAM_KEYS + COLUMN_STREAM_KEYS
+ " TEXT NOT NULL," + " TEXT NOT NULL,"
+ COLUMN_CUSTOM_METADATA + COLUMN_DATA
+ " BLOB NOT NULL)"; + " BLOB NOT NULL)";
private static final String TRUE = "1"; private static final String TRUE = "1";
@ -168,9 +169,7 @@ public final class DefaultDownloadIndex implements DownloadIndex {
return null; return null;
} }
cursor.moveToNext(); cursor.moveToNext();
DownloadState downloadState = getDownloadStateForCurrentRow(cursor); return getDownloadStateForCurrentRow(cursor);
Assertions.checkState(id.equals(downloadState.id));
return downloadState;
} catch (SQLiteException e) { } catch (SQLiteException e) {
throw new DatabaseIOException(e); throw new DatabaseIOException(e);
} }
@ -192,24 +191,24 @@ public final class DefaultDownloadIndex implements DownloadIndex {
*/ */
public void putDownloadState(DownloadState downloadState) throws DatabaseIOException { public void putDownloadState(DownloadState downloadState) throws DatabaseIOException {
ensureInitialized(); ensureInitialized();
try {
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
values.put(COLUMN_ID, downloadState.id); values.put(COLUMN_ID, downloadState.action.id);
values.put(COLUMN_TYPE, downloadState.type); values.put(COLUMN_TYPE, downloadState.action.type);
values.put(COLUMN_URI, downloadState.uri.toString()); values.put(COLUMN_URI, downloadState.action.uri.toString());
values.put(COLUMN_CACHE_KEY, downloadState.cacheKey); values.put(COLUMN_STREAM_KEYS, encodeStreamKeys(downloadState.action.streamKeys));
values.put(COLUMN_CUSTOM_CACHE_KEY, downloadState.action.customCacheKey);
values.put(COLUMN_DATA, downloadState.action.data);
values.put(COLUMN_STATE, downloadState.state); values.put(COLUMN_STATE, downloadState.state);
values.put(COLUMN_DOWNLOAD_PERCENTAGE, downloadState.getDownloadPercentage()); values.put(COLUMN_DOWNLOAD_PERCENTAGE, downloadState.getDownloadPercentage());
values.put(COLUMN_DOWNLOADED_BYTES, downloadState.getDownloadedBytes()); values.put(COLUMN_DOWNLOADED_BYTES, downloadState.getDownloadedBytes());
values.put(COLUMN_TOTAL_BYTES, downloadState.getTotalBytes()); values.put(COLUMN_TOTAL_BYTES, downloadState.getTotalBytes());
values.put(COLUMN_FAILURE_REASON, downloadState.failureReason); values.put(COLUMN_FAILURE_REASON, downloadState.failureReason);
values.put(COLUMN_STOP_FLAGS, /*stopFlags*/ 0); values.put(COLUMN_STOP_FLAGS, 0);
values.put(COLUMN_NOT_MET_REQUIREMENTS, downloadState.notMetRequirements); values.put(COLUMN_NOT_MET_REQUIREMENTS, downloadState.notMetRequirements);
values.put(COLUMN_MANUAL_STOP_REASON, downloadState.manualStopReason); values.put(COLUMN_MANUAL_STOP_REASON, downloadState.manualStopReason);
values.put(COLUMN_START_TIME_MS, downloadState.startTimeMs); values.put(COLUMN_START_TIME_MS, downloadState.startTimeMs);
values.put(COLUMN_UPDATE_TIME_MS, downloadState.updateTimeMs); values.put(COLUMN_UPDATE_TIME_MS, downloadState.updateTimeMs);
values.put(COLUMN_STREAM_KEYS, encodeStreamKeys(downloadState.streamKeys)); try {
values.put(COLUMN_CUSTOM_METADATA, downloadState.customMetadata);
SQLiteDatabase writableDatabase = databaseProvider.getWritableDatabase(); SQLiteDatabase writableDatabase = databaseProvider.getWritableDatabase();
writableDatabase.replaceOrThrow(TABLE_NAME, /* nullColumnHack= */ null, values); writableDatabase.replaceOrThrow(TABLE_NAME, /* nullColumnHack= */ null, values);
} catch (SQLiteException e) { } catch (SQLiteException e) {
@ -341,29 +340,33 @@ public final class DefaultDownloadIndex implements DownloadIndex {
} }
private static DownloadState getDownloadStateForCurrentRow(Cursor cursor) { private static DownloadState getDownloadStateForCurrentRow(Cursor cursor) {
DownloadAction action =
DownloadAction.createDownloadAction(
cursor.getString(COLUMN_INDEX_ID),
cursor.getString(COLUMN_INDEX_TYPE),
Uri.parse(cursor.getString(COLUMN_INDEX_URI)),
decodeStreamKeys(cursor.getString(COLUMN_INDEX_STREAM_KEYS)),
cursor.getString(COLUMN_INDEX_CUSTOM_CACHE_KEY),
cursor.getBlob(COLUMN_INDEX_DATA));
CachingCounters cachingCounters = new CachingCounters(); CachingCounters cachingCounters = new CachingCounters();
cachingCounters.alreadyCachedBytes = cursor.getLong(COLUMN_INDEX_DOWNLOADED_BYTES); cachingCounters.alreadyCachedBytes = cursor.getLong(COLUMN_INDEX_DOWNLOADED_BYTES);
cachingCounters.contentLength = cursor.getLong(COLUMN_INDEX_TOTAL_BYTES); cachingCounters.contentLength = cursor.getLong(COLUMN_INDEX_TOTAL_BYTES);
cachingCounters.percentage = cursor.getFloat(COLUMN_INDEX_DOWNLOAD_PERCENTAGE); cachingCounters.percentage = cursor.getFloat(COLUMN_INDEX_DOWNLOAD_PERCENTAGE);
return new DownloadState( return new DownloadState(
cursor.getString(COLUMN_INDEX_ID), action,
cursor.getString(COLUMN_INDEX_TYPE),
Uri.parse(cursor.getString(COLUMN_INDEX_URI)),
cursor.getString(COLUMN_INDEX_CACHE_KEY),
cursor.getInt(COLUMN_INDEX_STATE), cursor.getInt(COLUMN_INDEX_STATE),
cursor.getInt(COLUMN_INDEX_FAILURE_REASON), cursor.getInt(COLUMN_INDEX_FAILURE_REASON),
cursor.getInt(COLUMN_INDEX_NOT_MET_REQUIREMENTS), cursor.getInt(COLUMN_INDEX_NOT_MET_REQUIREMENTS),
cursor.getInt(COLUMN_INDEX_MANUAL_STOP_REASON), cursor.getInt(COLUMN_INDEX_MANUAL_STOP_REASON),
cursor.getLong(COLUMN_INDEX_START_TIME_MS), cursor.getLong(COLUMN_INDEX_START_TIME_MS),
cursor.getLong(COLUMN_INDEX_UPDATE_TIME_MS), cursor.getLong(COLUMN_INDEX_UPDATE_TIME_MS),
decodeStreamKeys(cursor.getString(COLUMN_INDEX_STREAM_KEYS)),
cursor.getBlob(COLUMN_INDEX_CUSTOM_METADATA),
cachingCounters); cachingCounters);
} }
private static String encodeStreamKeys(StreamKey[] streamKeys) { private static String encodeStreamKeys(List<StreamKey> streamKeys) {
StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder();
for (StreamKey streamKey : streamKeys) { for (int i = 0; i < streamKeys.size(); i++) {
StreamKey streamKey = streamKeys.get(i);
stringBuilder stringBuilder
.append(streamKey.periodIndex) .append(streamKey.periodIndex)
.append('.') .append('.')
@ -378,21 +381,20 @@ public final class DefaultDownloadIndex implements DownloadIndex {
return stringBuilder.toString(); return stringBuilder.toString();
} }
private static StreamKey[] decodeStreamKeys(String encodedStreamKeys) { private static List<StreamKey> decodeStreamKeys(String encodedStreamKeys) {
ArrayList<StreamKey> streamKeys = new ArrayList<>();
if (encodedStreamKeys.isEmpty()) { if (encodedStreamKeys.isEmpty()) {
return new StreamKey[0]; return streamKeys;
} }
String[] streamKeysStrings = Util.split(encodedStreamKeys, ","); String[] streamKeysStrings = Util.split(encodedStreamKeys, ",");
int streamKeysCount = streamKeysStrings.length; for (String streamKeysString : streamKeysStrings) {
StreamKey[] streamKeys = new StreamKey[streamKeysCount]; String[] indices = Util.split(streamKeysString, "\\.");
for (int i = 0; i < streamKeysCount; i++) {
String[] indices = Util.split(streamKeysStrings[i], "\\.");
Assertions.checkState(indices.length == 3); Assertions.checkState(indices.length == 3);
streamKeys[i] = streamKeys.add(
new StreamKey( new StreamKey(
Integer.parseInt(indices[0]), Integer.parseInt(indices[0]),
Integer.parseInt(indices[1]), Integer.parseInt(indices[1]),
Integer.parseInt(indices[2])); Integer.parseInt(indices[2])));
} }
return streamKeys; return streamKeys;
} }

View File

@ -17,6 +17,7 @@ package com.google.android.exoplayer2.offline;
import android.net.Uri; import android.net.Uri;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@ -133,6 +134,33 @@ public final class DownloadAction {
this.data = data != null ? Arrays.copyOf(data, data.length) : Util.EMPTY_BYTE_ARRAY; this.data = data != null ? Arrays.copyOf(data, data.length) : Util.EMPTY_BYTE_ARRAY;
} }
/**
* Returns the result of merging {@code newAction} into this action.
*
* @param newAction The new action.
* @return The merged result.
*/
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.
mergedKeys = Collections.emptyList();
} else {
mergedKeys = new ArrayList<>(streamKeys);
for (int i = 0; i < newAction.streamKeys.size(); i++) {
StreamKey newKey = newAction.streamKeys.get(i);
if (!mergedKeys.contains(newKey)) {
mergedKeys.add(newKey);
}
}
}
return new DownloadAction(
id, type, newAction.uri, mergedKeys, newAction.customCacheKey, newAction.data);
}
/** Serializes itself into a byte array. */ /** Serializes itself into a byte array. */
public byte[] toByteArray() { public byte[] toByteArray() {
ByteArrayOutputStream output = new ByteArrayOutputStream(); ByteArrayOutputStream output = new ByteArrayOutputStream();

View File

@ -76,7 +76,7 @@ public final class DownloadIndexUtil {
throws IOException { throws IOException {
DownloadState downloadState = downloadIndex.getDownloadState(id != null ? id : action.id); DownloadState downloadState = downloadIndex.getDownloadState(id != null ? id : action.id);
if (downloadState != null) { if (downloadState != null) {
downloadState = downloadState.mergeAction(action); downloadState = downloadState.copyWithMergedAction(action);
} else { } else {
downloadState = new DownloadState(action); downloadState = new DownloadState(action);
} }

View File

@ -47,7 +47,6 @@ import java.io.IOException;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.CopyOnWriteArraySet;
@ -504,7 +503,7 @@ public final class DownloadManager {
} }
private void onDownloadStateChanged(DownloadState downloadState) { private void onDownloadStateChanged(DownloadState downloadState) {
int downloadStateIndex = getDownloadStateIndex(downloadState.id); int downloadStateIndex = getDownloadStateIndex(downloadState.action.id);
if (downloadState.state == STATE_COMPLETED || downloadState.state == STATE_FAILED) { if (downloadState.state == STATE_COMPLETED || downloadState.state == STATE_FAILED) {
if (downloadStateIndex != C.INDEX_UNSET) { if (downloadStateIndex != C.INDEX_UNSET) {
downloadStates.remove(downloadStateIndex); downloadStates.remove(downloadStateIndex);
@ -520,7 +519,7 @@ public final class DownloadManager {
} }
private void onDownloadRemoved(DownloadState downloadState) { private void onDownloadRemoved(DownloadState downloadState) {
downloadStates.remove(getDownloadStateIndex(downloadState.id)); downloadStates.remove(getDownloadStateIndex(downloadState.action.id));
for (Listener listener : listeners) { for (Listener listener : listeners) {
listener.onDownloadRemoved(this, downloadState); listener.onDownloadRemoved(this, downloadState);
} }
@ -538,7 +537,7 @@ public final class DownloadManager {
private int getDownloadStateIndex(String id) { private int getDownloadStateIndex(String id) {
for (int i = 0; i < downloadStates.size(); i++) { for (int i = 0; i < downloadStates.size(); i++) {
if (downloadStates.get(i).id.equals(id)) { if (downloadStates.get(i).action.id.equals(id)) {
return i; return i;
} }
} }
@ -624,7 +623,7 @@ public final class DownloadManager {
downloadState = new DownloadState(action); downloadState = new DownloadState(action);
logd("Download state is created for " + action.id); logd("Download state is created for " + action.id);
} else { } else {
downloadState = downloadState.mergeAction(action); downloadState = downloadState.copyWithMergedAction(action);
logd("Download state is loaded for " + action.id); logd("Download state is loaded for " + action.id);
} }
addDownloadForState(downloadState); addDownloadForState(downloadState);
@ -638,7 +637,7 @@ public final class DownloadManager {
} else { } else {
DownloadState downloadState = loadDownloadState(id); DownloadState downloadState = loadDownloadState(id);
if (downloadState != null) { if (downloadState != null) {
addDownloadForState(downloadState.setRemoveState()); addDownloadForState(downloadState.copyWithState(STATE_REMOVING));
} else { } else {
logd("Can't remove download. No download with id: " + id); logd("Can't remove download. No download with id: " + id);
} }
@ -661,7 +660,7 @@ public final class DownloadManager {
private void onDownloadRemovedInternal(Download download, DownloadState downloadState) { private void onDownloadRemovedInternal(Download download, DownloadState downloadState) {
logd("Download is removed", download); logd("Download is removed", download);
try { try {
downloadIndex.removeDownloadState(downloadState.id); downloadIndex.removeDownloadState(downloadState.action.id);
} catch (DatabaseIOException e) { } catch (DatabaseIOException e) {
Log.e(TAG, "Failed to remove from index", e); Log.e(TAG, "Failed to remove from index", e);
} }
@ -837,11 +836,11 @@ public final class DownloadManager {
} }
public String getId() { public String getId() {
return downloadState.id; return downloadState.action.id;
} }
public void addAction(DownloadAction newAction) { public void addAction(DownloadAction newAction) {
downloadState = downloadState.mergeAction(newAction); downloadState = downloadState.copyWithMergedAction(newAction);
initialize(); initialize();
} }
@ -852,18 +851,13 @@ public final class DownloadManager {
public DownloadState getUpdatedDownloadState() { public DownloadState getUpdatedDownloadState() {
downloadState = downloadState =
new DownloadState( new DownloadState(
downloadState.id, downloadState.action,
downloadState.type,
downloadState.uri,
downloadState.cacheKey,
state, state,
state != STATE_FAILED ? FAILURE_REASON_NONE : failureReason, state != STATE_FAILED ? FAILURE_REASON_NONE : failureReason,
notMetRequirements, notMetRequirements,
manualStopReason, manualStopReason,
downloadState.startTimeMs, downloadState.startTimeMs,
/* updateTimeMs= */ System.currentTimeMillis(), /* updateTimeMs= */ System.currentTimeMillis(),
downloadState.streamKeys,
downloadState.customMetadata,
downloadState.counters); downloadState.counters);
return downloadState; return downloadState;
} }
@ -895,16 +889,6 @@ public final class DownloadManager {
updateStopState(); updateStopState();
} }
public DownloadAction getAction() {
return DownloadAction.createDownloadAction(
downloadState.id,
downloadState.type,
downloadState.uri,
Arrays.asList(downloadState.streamKeys),
downloadState.cacheKey,
downloadState.customMetadata);
}
public boolean isInRemoveState() { public boolean isInRemoveState() {
return state == STATE_REMOVING || state == STATE_RESTARTING; return state == STATE_REMOVING || state == STATE_RESTARTING;
} }
@ -980,7 +964,7 @@ public final class DownloadManager {
initialize(STATE_QUEUED); initialize(STATE_QUEUED);
} else { // STATE_DOWNLOADING } else { // STATE_DOWNLOADING
if (error != null) { if (error != null) {
Log.e(TAG, "Download failed: " + downloadState.id, error); Log.e(TAG, "Download failed: " + downloadState.action.id, error);
failureReason = FAILURE_REASON_UNKNOWN; failureReason = FAILURE_REASON_UNKNOWN;
setState(STATE_FAILED); setState(STATE_FAILED);
} else { } else {
@ -1001,7 +985,7 @@ public final class DownloadManager {
private DownloadThread(Download download) { private DownloadThread(Download download) {
this.download = download; this.download = download;
this.downloader = downloaderFactory.createDownloader(download.getAction()); this.downloader = downloaderFactory.createDownloader(download.downloadState.action);
this.isRemoveThread = download.isInRemoveState(); this.isRemoveThread = download.isInRemoveState();
start(); start();
} }

View File

@ -15,9 +15,7 @@
*/ */
package com.google.android.exoplayer2.offline; package com.google.android.exoplayer2.offline;
import android.net.Uri;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.scheduler.Requirements; import com.google.android.exoplayer2.scheduler.Requirements;
import com.google.android.exoplayer2.scheduler.Requirements.RequirementFlags; import com.google.android.exoplayer2.scheduler.Requirements.RequirementFlags;
@ -26,8 +24,6 @@ import com.google.android.exoplayer2.util.Assertions;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.Collections;
import java.util.HashSet;
/** Represents state of a download. */ /** Represents state of a download. */
public final class DownloadState { public final class DownloadState {
@ -114,24 +110,15 @@ public final class DownloadState {
} }
} }
/** The unique content id. */ /** The download action. */
public final String id; public final DownloadAction action;
/** The type of the content. */
public final String type;
/** The Uri of the content. */
public final Uri uri;
/** A custom key for cache indexing. */
@Nullable public final String cacheKey;
/** The state of the download. */ /** The state of the download. */
@State public final int state; @State public final int state;
/** The first time when download entry is created. */ /** The first time when download entry is created. */
public final long startTimeMs; public final long startTimeMs;
/** The last update time. */ /** The last update time. */
public final long updateTimeMs; public final long updateTimeMs;
/** Keys of streams to be downloaded. If empty, all streams will be downloaded. */
public final StreamKey[] streamKeys;
/** Optional custom data. */
public final byte[] customMetadata;
/** /**
* If {@link #state} is {@link #STATE_FAILED} then this is the cause, otherwise {@link * If {@link #state} is {@link #STATE_FAILED} then this is the cause, otherwise {@link
* #FAILURE_REASON_NONE}. * #FAILURE_REASON_NONE}.
@ -155,52 +142,37 @@ public final class DownloadState {
private DownloadState(DownloadAction action, long currentTimeMs) { private DownloadState(DownloadAction action, long currentTimeMs) {
this( this(
action.id, action,
action.type,
action.uri,
action.customCacheKey,
/* state= */ STATE_QUEUED, /* state= */ STATE_QUEUED,
FAILURE_REASON_NONE, FAILURE_REASON_NONE,
/* notMetRequirements= */ 0, /* notMetRequirements= */ 0,
/* manualStopReason= */ 0, /* manualStopReason= */ 0,
/* startTimeMs= */ currentTimeMs, /* startTimeMs= */ currentTimeMs,
/* updateTimeMs= */ currentTimeMs, /* updateTimeMs= */ currentTimeMs,
action.streamKeys.toArray(new StreamKey[0]),
action.data,
new CachingCounters()); new CachingCounters());
} }
/* package */ DownloadState( /* package */ DownloadState(
String id, DownloadAction action,
String type,
Uri uri,
@Nullable String cacheKey,
@State int state, @State int state,
@FailureReason int failureReason, @FailureReason int failureReason,
@RequirementFlags int notMetRequirements, @RequirementFlags int notMetRequirements,
int manualStopReason, int manualStopReason,
long startTimeMs, long startTimeMs,
long updateTimeMs, long updateTimeMs,
StreamKey[] streamKeys,
byte[] customMetadata,
CachingCounters counters) { CachingCounters counters) {
Assertions.checkNotNull(counters); Assertions.checkNotNull(counters);
Assertions.checkState((failureReason == FAILURE_REASON_NONE) == (state != STATE_FAILED)); Assertions.checkState((failureReason == FAILURE_REASON_NONE) == (state != STATE_FAILED));
if (manualStopReason != 0 || notMetRequirements != 0) { if (manualStopReason != 0 || notMetRequirements != 0) {
Assertions.checkState(state != STATE_DOWNLOADING && state != STATE_QUEUED); Assertions.checkState(state != STATE_DOWNLOADING && state != STATE_QUEUED);
} }
this.id = id; this.action = action;
this.type = type;
this.uri = uri;
this.cacheKey = cacheKey;
this.state = state; this.state = state;
this.failureReason = failureReason; this.failureReason = failureReason;
this.notMetRequirements = notMetRequirements; this.notMetRequirements = notMetRequirements;
this.manualStopReason = manualStopReason; this.manualStopReason = manualStopReason;
this.startTimeMs = startTimeMs; this.startTimeMs = startTimeMs;
this.updateTimeMs = updateTimeMs; this.updateTimeMs = updateTimeMs;
this.streamKeys = streamKeys;
this.customMetadata = customMetadata;
this.counters = counters; this.counters = counters;
} }
@ -208,43 +180,35 @@ public final class DownloadState {
* Merges the given {@link DownloadAction} and creates a new {@link DownloadState}. The action * Merges the given {@link DownloadAction} and creates a new {@link DownloadState}. The action
* must have the same id and type. * must have the same id and type.
* *
* @param action The {@link DownloadAction} to be merged. * @param newAction The {@link DownloadAction} to be merged.
* @return A new {@link DownloadState}. * @return A new {@link DownloadState}.
*/ */
public DownloadState mergeAction(DownloadAction action) { public DownloadState copyWithMergedAction(DownloadAction newAction) {
Assertions.checkArgument(action.id.equals(id));
Assertions.checkArgument(action.type.equals(type));
return new DownloadState( return new DownloadState(
id, action.copyWithMergedAction(newAction),
type,
action.uri,
action.customCacheKey,
getNextState(state, manualStopReason != 0 || notMetRequirements != 0), getNextState(state, manualStopReason != 0 || notMetRequirements != 0),
FAILURE_REASON_NONE, FAILURE_REASON_NONE,
notMetRequirements, notMetRequirements,
manualStopReason, manualStopReason,
startTimeMs, startTimeMs,
/* updateTimeMs= */ System.currentTimeMillis(), /* updateTimeMs= */ System.currentTimeMillis(),
mergeStreamKeys(this, action),
action.data,
counters); counters);
} }
/** Returns a duplicate {@link DownloadState} in {@link #STATE_REMOVING}. */ /**
public DownloadState setRemoveState() { * Returns a copy with the specified state, clearing {@link #failureReason}.
*
* @param state The {@link State}.
*/
public DownloadState copyWithState(@State int state) {
return new DownloadState( return new DownloadState(
id, action,
type, state,
uri,
cacheKey,
STATE_REMOVING,
FAILURE_REASON_NONE, FAILURE_REASON_NONE,
notMetRequirements, notMetRequirements,
manualStopReason, manualStopReason,
startTimeMs, startTimeMs,
/* updateTimeMs= */ System.currentTimeMillis(), /* updateTimeMs= */ System.currentTimeMillis(),
streamKeys,
customMetadata,
counters); counters);
} }
@ -285,18 +249,4 @@ public final class DownloadState {
return STATE_QUEUED; return STATE_QUEUED;
} }
} }
private static StreamKey[] mergeStreamKeys(DownloadState downloadState, DownloadAction action) {
StreamKey[] streamKeys = downloadState.streamKeys;
if (streamKeys.length > 0) {
if (action.streamKeys.isEmpty()) {
streamKeys = new StreamKey[0];
} else {
HashSet<StreamKey> keys = new HashSet<>(action.streamKeys);
Collections.addAll(keys, downloadState.streamKeys);
streamKeys = keys.toArray(new StreamKey[0]);
}
}
return streamKeys;
}
} }

View File

@ -102,11 +102,11 @@ public class DownloadIndexUtilTest {
DownloadState downloadState = downloadIndex.getDownloadState(action2.id); DownloadState downloadState = downloadIndex.getDownloadState(action2.id);
assertThat(downloadState).isNotNull(); assertThat(downloadState).isNotNull();
assertThat(downloadState.type).isEqualTo(action2.type); assertThat(downloadState.action.type).isEqualTo(action2.type);
assertThat(downloadState.cacheKey).isEqualTo(action2.customCacheKey); assertThat(downloadState.action.customCacheKey).isEqualTo(action2.customCacheKey);
assertThat(downloadState.customMetadata).isEqualTo(action2.data); assertThat(downloadState.action.data).isEqualTo(action2.data);
assertThat(downloadState.uri).isEqualTo(action2.uri); assertThat(downloadState.action.uri).isEqualTo(action2.uri);
assertThat(Arrays.asList(downloadState.streamKeys)).containsExactly(streamKey1, streamKey2); assertThat(downloadState.action.streamKeys).containsExactly(streamKey1, streamKey2);
assertThat(downloadState.state).isEqualTo(DownloadState.STATE_QUEUED); assertThat(downloadState.state).isEqualTo(DownloadState.STATE_QUEUED);
} }
@ -151,12 +151,7 @@ public class DownloadIndexUtilTest {
private void assertDownloadIndexContainsAction(DownloadAction action, int state) private void assertDownloadIndexContainsAction(DownloadAction action, int state)
throws IOException { throws IOException {
DownloadState downloadState = downloadIndex.getDownloadState(action.id); DownloadState downloadState = downloadIndex.getDownloadState(action.id);
assertThat(downloadState.type).isEqualTo(action.type); assertThat(downloadState.action).isEqualTo(action);
assertThat(downloadState.cacheKey).isEqualTo(action.customCacheKey);
assertThat(downloadState.customMetadata).isEqualTo(action.data);
assertThat(downloadState.uri).isEqualTo(action.uri);
assertThat(Arrays.asList(downloadState.streamKeys))
.containsExactlyElementsIn(action.streamKeys);
assertThat(downloadState.state).isEqualTo(state); assertThat(downloadState.state).isEqualTo(state);
} }

View File

@ -347,7 +347,7 @@ public class DownloadManagerTest {
assertThat(states).hasLength(3); assertThat(states).hasLength(3);
String[] taskIds = {task1.taskId, task2.taskId, task3.taskId}; String[] taskIds = {task1.taskId, task2.taskId, task3.taskId};
String[] stateTaskIds = {states[0].id, states[1].id, states[2].id}; String[] stateTaskIds = {states[0].action.id, states[1].action.id, states[2].action.id};
assertThat(stateTaskIds).isEqualTo(taskIds); assertThat(stateTaskIds).isEqualTo(taskIds);
} }

View File

@ -18,6 +18,9 @@ package com.google.android.exoplayer2.offline;
import android.net.Uri; import android.net.Uri;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.upstream.cache.CacheUtil.CachingCounters; import com.google.android.exoplayer2.upstream.cache.CacheUtil.CachingCounters;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/** /**
* Builder for DownloadState. * Builder for DownloadState.
@ -38,21 +41,15 @@ class DownloadStateBuilder {
private int manualStopReason; private int manualStopReason;
private long startTimeMs; private long startTimeMs;
private long updateTimeMs; private long updateTimeMs;
private StreamKey[] streamKeys; private List<StreamKey> streamKeys;
private byte[] customMetadata; private byte[] customMetadata;
DownloadStateBuilder(String id) { DownloadStateBuilder(String id) {
this(id, "type", Uri.parse("uri"), /* cacheKey= */ null, new byte[0], new StreamKey[0]); this(id, "type", Uri.parse("uri"), /* cacheKey= */ null, new byte[0], Collections.emptyList());
} }
DownloadStateBuilder(DownloadAction action) { DownloadStateBuilder(DownloadAction action) {
this( this(action.id, action.type, action.uri, action.customCacheKey, action.data, action.streamKeys);
action.id,
action.type,
action.uri,
action.customCacheKey,
action.data,
action.streamKeys.toArray(new StreamKey[0]));
} }
DownloadStateBuilder( DownloadStateBuilder(
@ -61,7 +58,7 @@ class DownloadStateBuilder {
Uri uri, Uri uri,
String cacheKey, String cacheKey,
byte[] customMetadata, byte[] customMetadata,
StreamKey[] streamKeys) { List<StreamKey> streamKeys) {
this.id = id; this.id = id;
this.type = type; this.type = type;
this.uri = uri; this.uri = uri;
@ -146,7 +143,7 @@ class DownloadStateBuilder {
} }
public DownloadStateBuilder setStreamKeys(StreamKey... streamKeys) { public DownloadStateBuilder setStreamKeys(StreamKey... streamKeys) {
this.streamKeys = streamKeys; this.streamKeys = Arrays.asList(streamKeys);
return this; return this;
} }
@ -156,19 +153,16 @@ class DownloadStateBuilder {
} }
public DownloadState build() { public DownloadState build() {
DownloadAction action =
DownloadAction.createDownloadAction(id, type, uri, streamKeys, cacheKey, customMetadata);
return new DownloadState( return new DownloadState(
id, action,
type,
uri,
cacheKey,
state, state,
failureReason, failureReason,
notMetRequirements, notMetRequirements,
manualStopReason, manualStopReason,
startTimeMs, startTimeMs,
updateTimeMs, updateTimeMs,
streamKeys,
customMetadata,
counters); counters);
} }
} }

View File

@ -47,7 +47,7 @@ public class DownloadStateTest {
.build(); .build();
try { try {
downloadState.mergeAction(downloadAction); downloadState.copyWithMergedAction(downloadAction);
fail(); fail();
} catch (Exception e) { } catch (Exception e) {
// Expected. // Expected.
@ -64,7 +64,7 @@ public class DownloadStateTest {
.build(); .build();
try { try {
downloadState.mergeAction(downloadAction); downloadState.copyWithMergedAction(downloadAction);
fail(); fail();
} catch (Exception e) { } catch (Exception e) {
// Expected. // Expected.
@ -78,7 +78,7 @@ public class DownloadStateTest {
new DownloadStateBuilder(downloadAction).setState(DownloadState.STATE_QUEUED); new DownloadStateBuilder(downloadAction).setState(DownloadState.STATE_QUEUED);
DownloadState downloadState = downloadStateBuilder.build(); DownloadState downloadState = downloadStateBuilder.build();
downloadState.mergeAction(downloadAction); downloadState.copyWithMergedAction(downloadAction);
} }
@Test @Test
@ -90,7 +90,7 @@ public class DownloadStateTest {
.setState(DownloadState.STATE_QUEUED); .setState(DownloadState.STATE_QUEUED);
DownloadState downloadState = downloadStateBuilder.build(); DownloadState downloadState = downloadStateBuilder.build();
DownloadState mergedDownloadState = downloadState.mergeAction(downloadAction); DownloadState mergedDownloadState = downloadState.copyWithMergedAction(downloadAction);
DownloadState expectedDownloadState = downloadStateBuilder.setUri(downloadAction.uri).build(); DownloadState expectedDownloadState = downloadStateBuilder.setUri(downloadAction.uri).build();
assertEqual(mergedDownloadState, expectedDownloadState); assertEqual(mergedDownloadState, expectedDownloadState);
@ -112,7 +112,7 @@ public class DownloadStateTest {
.setCustomMetadata(new byte[0]); .setCustomMetadata(new byte[0]);
DownloadState downloadState = downloadStateBuilder.build(); DownloadState downloadState = downloadStateBuilder.build();
DownloadState mergedDownloadState = downloadState.mergeAction(downloadAction); DownloadState mergedDownloadState = downloadState.copyWithMergedAction(downloadAction);
DownloadState expectedDownloadState = DownloadState expectedDownloadState =
downloadStateBuilder.setCustomMetadata(downloadAction.data).build(); downloadStateBuilder.setCustomMetadata(downloadAction.data).build();
@ -126,7 +126,7 @@ public class DownloadStateTest {
new DownloadStateBuilder(downloadAction).setState(DownloadState.STATE_REMOVING); new DownloadStateBuilder(downloadAction).setState(DownloadState.STATE_REMOVING);
DownloadState downloadState = downloadStateBuilder.build(); DownloadState downloadState = downloadStateBuilder.build();
DownloadState mergedDownloadState = downloadState.mergeAction(downloadAction); DownloadState mergedDownloadState = downloadState.copyWithMergedAction(downloadAction);
DownloadState expectedDownloadState = DownloadState expectedDownloadState =
downloadStateBuilder.setState(DownloadState.STATE_RESTARTING).build(); downloadStateBuilder.setState(DownloadState.STATE_RESTARTING).build();
@ -142,7 +142,7 @@ public class DownloadStateTest {
.setFailureReason(DownloadState.FAILURE_REASON_UNKNOWN); .setFailureReason(DownloadState.FAILURE_REASON_UNKNOWN);
DownloadState downloadState = downloadStateBuilder.build(); DownloadState downloadState = downloadStateBuilder.build();
DownloadState mergedDownloadState = downloadState.mergeAction(downloadAction); DownloadState mergedDownloadState = downloadState.copyWithMergedAction(downloadAction);
DownloadState expectedDownloadState = DownloadState expectedDownloadState =
downloadStateBuilder downloadStateBuilder
@ -161,7 +161,7 @@ public class DownloadStateTest {
.setManualStopReason(DownloadState.MANUAL_STOP_REASON_UNDEFINED); .setManualStopReason(DownloadState.MANUAL_STOP_REASON_UNDEFINED);
DownloadState downloadState = downloadStateBuilder.build(); DownloadState downloadState = downloadStateBuilder.build();
DownloadState mergedDownloadState = downloadState.mergeAction(downloadAction); DownloadState mergedDownloadState = downloadState.copyWithMergedAction(downloadAction);
assertEqual(mergedDownloadState, downloadState); assertEqual(mergedDownloadState, downloadState);
} }
@ -175,7 +175,7 @@ public class DownloadStateTest {
.setManualStopReason(DownloadState.MANUAL_STOP_REASON_UNDEFINED); .setManualStopReason(DownloadState.MANUAL_STOP_REASON_UNDEFINED);
DownloadState downloadState = downloadStateBuilder.build(); DownloadState downloadState = downloadStateBuilder.build();
DownloadState mergedDownloadState = downloadState.mergeAction(downloadAction); DownloadState mergedDownloadState = downloadState.copyWithMergedAction(downloadAction);
DownloadState expectedDownloadState = DownloadState expectedDownloadState =
downloadStateBuilder.setState(DownloadState.STATE_STOPPED).build(); downloadStateBuilder.setState(DownloadState.STATE_STOPPED).build();
@ -191,7 +191,7 @@ public class DownloadStateTest {
.setNotMetRequirements(0x12345678); .setNotMetRequirements(0x12345678);
DownloadState downloadState = downloadStateBuilder.build(); DownloadState downloadState = downloadStateBuilder.build();
DownloadState mergedDownloadState = downloadState.mergeAction(downloadAction); DownloadState mergedDownloadState = downloadState.copyWithMergedAction(downloadAction);
DownloadState expectedDownloadState = DownloadState expectedDownloadState =
downloadStateBuilder.setState(DownloadState.STATE_STOPPED).build(); downloadStateBuilder.setState(DownloadState.STATE_STOPPED).build();
@ -259,7 +259,7 @@ public class DownloadStateTest {
.setStreamKeys(keys1); .setStreamKeys(keys1);
DownloadState downloadState = downloadStateBuilder.build(); DownloadState downloadState = downloadStateBuilder.build();
DownloadState mergedDownloadState = downloadState.mergeAction(downloadAction); DownloadState mergedDownloadState = downloadState.copyWithMergedAction(downloadAction);
DownloadState expectedDownloadState = downloadStateBuilder.setStreamKeys(expectedKeys).build(); DownloadState expectedDownloadState = downloadStateBuilder.setStreamKeys(expectedKeys).build();
assertEqual(mergedDownloadState, expectedDownloadState); assertEqual(mergedDownloadState, expectedDownloadState);
@ -271,6 +271,7 @@ public class DownloadStateTest {
static void assertEqual( static void assertEqual(
DownloadState downloadState, DownloadState that, boolean compareTimeFields) { DownloadState downloadState, DownloadState that, boolean compareTimeFields) {
assertThat(downloadState.action).isEqualTo(that.action);
assertThat(downloadState.state).isEqualTo(that.state); assertThat(downloadState.state).isEqualTo(that.state);
assertThat(downloadState.getDownloadPercentage()).isEqualTo(that.getDownloadPercentage()); assertThat(downloadState.getDownloadPercentage()).isEqualTo(that.getDownloadPercentage());
assertThat(downloadState.getDownloadedBytes()).isEqualTo(that.getDownloadedBytes()); assertThat(downloadState.getDownloadedBytes()).isEqualTo(that.getDownloadedBytes());
@ -282,12 +283,6 @@ public class DownloadStateTest {
assertThat(downloadState.failureReason).isEqualTo(that.failureReason); assertThat(downloadState.failureReason).isEqualTo(that.failureReason);
assertThat(downloadState.manualStopReason).isEqualTo(that.manualStopReason); assertThat(downloadState.manualStopReason).isEqualTo(that.manualStopReason);
assertThat(downloadState.notMetRequirements).isEqualTo(that.notMetRequirements); assertThat(downloadState.notMetRequirements).isEqualTo(that.notMetRequirements);
assertThat(downloadState.id).isEqualTo(that.id);
assertThat(downloadState.type).isEqualTo(that.type);
assertThat(downloadState.uri).isEqualTo(that.uri);
assertThat(downloadState.cacheKey).isEqualTo(that.cacheKey);
assertThat(Arrays.asList(downloadState.streamKeys)).containsExactlyElementsIn(that.streamKeys);
assertThat(downloadState.customMetadata).isEqualTo(that.customMetadata);
} }
private DownloadAction createDownloadAction() { private DownloadAction createDownloadAction() {

View File

@ -57,10 +57,6 @@ public final class TestDownloadManagerListener implements DownloadManager.Listen
return getStateQueue(taskId).poll(timeoutMs, TimeUnit.MILLISECONDS); return getStateQueue(taskId).poll(timeoutMs, TimeUnit.MILLISECONDS);
} }
public void clearDownloadError() {
this.failureReason = DownloadState.FAILURE_REASON_NONE;
}
@Override @Override
public void onInitialized(DownloadManager downloadManager) { public void onInitialized(DownloadManager downloadManager) {
initializedCondition.open(); initializedCondition.open();
@ -77,12 +73,12 @@ public final class TestDownloadManagerListener implements DownloadManager.Listen
if (downloadState.state == DownloadState.STATE_FAILED) { if (downloadState.state == DownloadState.STATE_FAILED) {
failureReason = downloadState.failureReason; failureReason = downloadState.failureReason;
} }
getStateQueue(downloadState.id).add(downloadState.state); getStateQueue(downloadState.action.id).add(downloadState.state);
} }
@Override @Override
public void onDownloadRemoved(DownloadManager downloadManager, DownloadState downloadState) { public void onDownloadRemoved(DownloadManager downloadManager, DownloadState downloadState) {
getStateQueue(downloadState.id).add(STATE_REMOVED); getStateQueue(downloadState.action.id).add(STATE_REMOVED);
} }
@Override @Override