mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Add DownloadState.mergeAction method
This method is needed by DownloadManager. PiperOrigin-RevId: 232447145
This commit is contained in:
parent
67be9e7783
commit
c0e6cd1b17
5 changed files with 593 additions and 233 deletions
|
|
@ -16,12 +16,7 @@
|
||||||
package com.google.android.exoplayer2.offline;
|
package com.google.android.exoplayer2.offline;
|
||||||
|
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.C;
|
|
||||||
import com.google.android.exoplayer2.offline.DownloadState.State;
|
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
|
|
||||||
/** {@link DownloadIndex} related utility methods. */
|
/** {@link DownloadIndex} related utility methods. */
|
||||||
public final class DownloadIndexUtil {
|
public final class DownloadIndexUtil {
|
||||||
|
|
@ -79,46 +74,10 @@ public final class DownloadIndexUtil {
|
||||||
DownloadIndex downloadIndex, @Nullable String id, DownloadAction action) {
|
DownloadIndex downloadIndex, @Nullable String id, DownloadAction action) {
|
||||||
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 = merge(downloadState, action);
|
downloadState = downloadState.mergeAction(action);
|
||||||
} else {
|
} else {
|
||||||
downloadState = new DownloadState(action);
|
downloadState = new DownloadState(action);
|
||||||
}
|
}
|
||||||
downloadIndex.putDownloadState(downloadState);
|
downloadIndex.putDownloadState(downloadState);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DownloadState merge(DownloadState downloadState, DownloadAction action) {
|
|
||||||
Assertions.checkArgument(action.type.equals(downloadState.type));
|
|
||||||
@State int newState;
|
|
||||||
if (action.isRemoveAction) {
|
|
||||||
newState = DownloadState.STATE_REMOVING;
|
|
||||||
} else {
|
|
||||||
if (downloadState.state == DownloadState.STATE_REMOVING
|
|
||||||
|| downloadState.state == DownloadState.STATE_RESTARTING) {
|
|
||||||
newState = DownloadState.STATE_RESTARTING;
|
|
||||||
} else if (downloadState.state == DownloadState.STATE_STOPPED) {
|
|
||||||
newState = DownloadState.STATE_STOPPED;
|
|
||||||
} else {
|
|
||||||
newState = DownloadState.STATE_QUEUED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
HashSet<StreamKey> keys = new HashSet<>(action.keys);
|
|
||||||
Collections.addAll(keys, downloadState.streamKeys);
|
|
||||||
StreamKey[] newKeys = keys.toArray(new StreamKey[0]);
|
|
||||||
return new DownloadState(
|
|
||||||
downloadState.id,
|
|
||||||
downloadState.type,
|
|
||||||
action.uri,
|
|
||||||
action.customCacheKey,
|
|
||||||
newState,
|
|
||||||
/* downloadPercentage= */ C.PERCENTAGE_UNSET,
|
|
||||||
downloadState.downloadedBytes,
|
|
||||||
/* totalBytes= */ C.LENGTH_UNSET,
|
|
||||||
downloadState.failureReason,
|
|
||||||
downloadState.stopFlags,
|
|
||||||
downloadState.notMetRequirements,
|
|
||||||
downloadState.startTimeMs,
|
|
||||||
downloadState.updateTimeMs,
|
|
||||||
newKeys,
|
|
||||||
action.data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ 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 {
|
||||||
|
|
@ -231,4 +233,62 @@ public final class DownloadState {
|
||||||
this.streamKeys = streamKeys;
|
this.streamKeys = streamKeys;
|
||||||
this.customMetadata = customMetadata;
|
this.customMetadata = customMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merges the given {@link DownloadAction} and creates a new {@link DownloadState}. The action
|
||||||
|
* must have the same id and type.
|
||||||
|
*
|
||||||
|
* @param action The {@link DownloadAction} to be merged.
|
||||||
|
* @return A new {@link DownloadState}.
|
||||||
|
*/
|
||||||
|
public DownloadState mergeAction(DownloadAction action) {
|
||||||
|
Assertions.checkArgument(action.id.equals(id));
|
||||||
|
Assertions.checkArgument(action.type.equals(type));
|
||||||
|
return new DownloadState(
|
||||||
|
id,
|
||||||
|
type,
|
||||||
|
action.uri,
|
||||||
|
action.customCacheKey,
|
||||||
|
getNextState(action, state),
|
||||||
|
/* downloadPercentage= */ C.PERCENTAGE_UNSET,
|
||||||
|
downloadedBytes,
|
||||||
|
/* totalBytes= */ C.LENGTH_UNSET,
|
||||||
|
FAILURE_REASON_NONE,
|
||||||
|
stopFlags,
|
||||||
|
notMetRequirements,
|
||||||
|
startTimeMs,
|
||||||
|
updateTimeMs,
|
||||||
|
mergeStreamKeys(this, action),
|
||||||
|
action.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getNextState(DownloadAction action, int currentState) {
|
||||||
|
int newState;
|
||||||
|
if (action.isRemoveAction) {
|
||||||
|
newState = STATE_REMOVING;
|
||||||
|
} else {
|
||||||
|
if (currentState == STATE_REMOVING || currentState == STATE_RESTARTING) {
|
||||||
|
newState = STATE_RESTARTING;
|
||||||
|
} else if (currentState == STATE_STOPPED) {
|
||||||
|
newState = STATE_STOPPED;
|
||||||
|
} else {
|
||||||
|
newState = STATE_QUEUED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newState;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static StreamKey[] mergeStreamKeys(DownloadState downloadState, DownloadAction action) {
|
||||||
|
StreamKey[] streamKeys = downloadState.streamKeys;
|
||||||
|
if (!action.isRemoveAction && streamKeys.length > 0) {
|
||||||
|
if (action.keys.isEmpty()) {
|
||||||
|
streamKeys = new StreamKey[0];
|
||||||
|
} else {
|
||||||
|
HashSet<StreamKey> keys = new HashSet<>(action.keys);
|
||||||
|
Collections.addAll(keys, downloadState.streamKeys);
|
||||||
|
streamKeys = keys.toArray(new StreamKey[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return streamKeys;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,8 @@ package com.google.android.exoplayer2.offline;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.net.Uri;
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import com.google.android.exoplayer2.C;
|
|
||||||
import com.google.android.exoplayer2.database.ExoDatabaseProvider;
|
import com.google.android.exoplayer2.database.ExoDatabaseProvider;
|
||||||
import com.google.android.exoplayer2.database.VersionTable;
|
import com.google.android.exoplayer2.database.VersionTable;
|
||||||
import java.util.Arrays;
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
@ -62,7 +58,7 @@ public class DefaultDownloadIndexTest {
|
||||||
downloadIndex.putDownloadState(downloadState);
|
downloadIndex.putDownloadState(downloadState);
|
||||||
DownloadState readDownloadState = downloadIndex.getDownloadState(id);
|
DownloadState readDownloadState = downloadIndex.getDownloadState(id);
|
||||||
|
|
||||||
assertEqual(readDownloadState, downloadState);
|
DownloadStateTest.assertEqual(readDownloadState, downloadState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -94,7 +90,7 @@ public class DefaultDownloadIndexTest {
|
||||||
DownloadState readDownloadState = downloadIndex.getDownloadState(id);
|
DownloadState readDownloadState = downloadIndex.getDownloadState(id);
|
||||||
|
|
||||||
assertThat(readDownloadState).isNotNull();
|
assertThat(readDownloadState).isNotNull();
|
||||||
assertEqual(readDownloadState, downloadState);
|
DownloadStateTest.assertEqual(readDownloadState, downloadState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -106,7 +102,7 @@ public class DefaultDownloadIndexTest {
|
||||||
downloadIndex = new DefaultDownloadIndex(databaseProvider);
|
downloadIndex = new DefaultDownloadIndex(databaseProvider);
|
||||||
DownloadState readDownloadState = downloadIndex.getDownloadState(id);
|
DownloadState readDownloadState = downloadIndex.getDownloadState(id);
|
||||||
assertThat(readDownloadState).isNotNull();
|
assertThat(readDownloadState).isNotNull();
|
||||||
assertEqual(readDownloadState, downloadState);
|
DownloadStateTest.assertEqual(readDownloadState, downloadState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -141,9 +137,9 @@ public class DefaultDownloadIndexTest {
|
||||||
|
|
||||||
assertThat(cursor.getCount()).isEqualTo(2);
|
assertThat(cursor.getCount()).isEqualTo(2);
|
||||||
cursor.moveToNext();
|
cursor.moveToNext();
|
||||||
assertEqual(cursor.getDownloadState(), downloadState2);
|
DownloadStateTest.assertEqual(cursor.getDownloadState(), downloadState2);
|
||||||
cursor.moveToNext();
|
cursor.moveToNext();
|
||||||
assertEqual(cursor.getDownloadState(), downloadState1);
|
DownloadStateTest.assertEqual(cursor.getDownloadState(), downloadState1);
|
||||||
cursor.close();
|
cursor.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -173,9 +169,9 @@ public class DefaultDownloadIndexTest {
|
||||||
|
|
||||||
assertThat(cursor.getCount()).isEqualTo(2);
|
assertThat(cursor.getCount()).isEqualTo(2);
|
||||||
cursor.moveToNext();
|
cursor.moveToNext();
|
||||||
assertEqual(cursor.getDownloadState(), downloadState1);
|
DownloadStateTest.assertEqual(cursor.getDownloadState(), downloadState1);
|
||||||
cursor.moveToNext();
|
cursor.moveToNext();
|
||||||
assertEqual(cursor.getDownloadState(), downloadState3);
|
DownloadStateTest.assertEqual(cursor.getDownloadState(), downloadState3);
|
||||||
cursor.close();
|
cursor.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -211,184 +207,4 @@ public class DefaultDownloadIndexTest {
|
||||||
.isEqualTo(DefaultDownloadIndex.TABLE_VERSION);
|
.isEqualTo(DefaultDownloadIndex.TABLE_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void assertEqual(DownloadState downloadState, DownloadState expected) {
|
|
||||||
assertThat(areEqual(downloadState, expected)).isTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean areEqual(DownloadState downloadState, DownloadState that) {
|
|
||||||
if (downloadState.state != that.state) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (Float.compare(that.downloadPercentage, downloadState.downloadPercentage) != 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (downloadState.downloadedBytes != that.downloadedBytes) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (downloadState.totalBytes != that.totalBytes) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (downloadState.startTimeMs != that.startTimeMs) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (downloadState.updateTimeMs != that.updateTimeMs) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (downloadState.failureReason != that.failureReason) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (downloadState.stopFlags != that.stopFlags) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (downloadState.notMetRequirements != that.notMetRequirements) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!downloadState.id.equals(that.id)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!downloadState.type.equals(that.type)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!downloadState.uri.equals(that.uri)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (downloadState.cacheKey != null
|
|
||||||
? !downloadState.cacheKey.equals(that.cacheKey)
|
|
||||||
: that.cacheKey != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!Arrays.equals(downloadState.streamKeys, that.streamKeys)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return Arrays.equals(downloadState.customMetadata, that.customMetadata);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class DownloadStateBuilder {
|
|
||||||
private String id;
|
|
||||||
private String type;
|
|
||||||
private String uri;
|
|
||||||
@Nullable private String cacheKey;
|
|
||||||
private int state;
|
|
||||||
private float downloadPercentage;
|
|
||||||
private long downloadedBytes;
|
|
||||||
private long totalBytes;
|
|
||||||
private int failureReason;
|
|
||||||
private int stopFlags;
|
|
||||||
private int notMetRequirements;
|
|
||||||
private long startTimeMs;
|
|
||||||
private long updateTimeMs;
|
|
||||||
private StreamKey[] streamKeys;
|
|
||||||
private byte[] customMetadata;
|
|
||||||
|
|
||||||
private DownloadStateBuilder(String id) {
|
|
||||||
this.id = id;
|
|
||||||
this.type = "type";
|
|
||||||
this.uri = "uri";
|
|
||||||
this.cacheKey = null;
|
|
||||||
this.state = DownloadState.STATE_QUEUED;
|
|
||||||
this.downloadPercentage = (float) C.PERCENTAGE_UNSET;
|
|
||||||
this.downloadedBytes = (long) 0;
|
|
||||||
this.totalBytes = (long) C.LENGTH_UNSET;
|
|
||||||
this.failureReason = DownloadState.FAILURE_REASON_NONE;
|
|
||||||
this.stopFlags = 0;
|
|
||||||
this.startTimeMs = (long) 0;
|
|
||||||
this.updateTimeMs = (long) 0;
|
|
||||||
this.streamKeys = new StreamKey[0];
|
|
||||||
this.customMetadata = new byte[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
public DownloadStateBuilder setId(String id) {
|
|
||||||
this.id = id;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DownloadStateBuilder setType(String type) {
|
|
||||||
this.type = type;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DownloadStateBuilder setUri(String uri) {
|
|
||||||
this.uri = uri;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DownloadStateBuilder setCacheKey(@Nullable String cacheKey) {
|
|
||||||
this.cacheKey = cacheKey;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DownloadStateBuilder setState(int state) {
|
|
||||||
this.state = state;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DownloadStateBuilder setDownloadPercentage(float downloadPercentage) {
|
|
||||||
this.downloadPercentage = downloadPercentage;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DownloadStateBuilder setDownloadedBytes(long downloadedBytes) {
|
|
||||||
this.downloadedBytes = downloadedBytes;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DownloadStateBuilder setTotalBytes(long totalBytes) {
|
|
||||||
this.totalBytes = totalBytes;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DownloadStateBuilder setFailureReason(int failureReason) {
|
|
||||||
this.failureReason = failureReason;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DownloadStateBuilder setStopFlags(int stopFlags) {
|
|
||||||
this.stopFlags = stopFlags;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DownloadStateBuilder setNotMetRequirements(int notMetRequirements) {
|
|
||||||
this.notMetRequirements = notMetRequirements;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DownloadStateBuilder setStartTimeMs(long startTimeMs) {
|
|
||||||
this.startTimeMs = startTimeMs;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DownloadStateBuilder setUpdateTimeMs(long updateTimeMs) {
|
|
||||||
this.updateTimeMs = updateTimeMs;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DownloadStateBuilder setStreamKeys(StreamKey... streamKeys) {
|
|
||||||
this.streamKeys = streamKeys;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DownloadStateBuilder setCustomMetadata(byte[] customMetadata) {
|
|
||||||
this.customMetadata = customMetadata;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DownloadState build() {
|
|
||||||
return new DownloadState(
|
|
||||||
id,
|
|
||||||
type,
|
|
||||||
Uri.parse(uri),
|
|
||||||
cacheKey,
|
|
||||||
state,
|
|
||||||
downloadPercentage,
|
|
||||||
downloadedBytes,
|
|
||||||
totalBytes,
|
|
||||||
failureReason,
|
|
||||||
stopFlags,
|
|
||||||
notMetRequirements,
|
|
||||||
startTimeMs,
|
|
||||||
updateTimeMs,
|
|
||||||
streamKeys,
|
|
||||||
customMetadata);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,181 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.google.android.exoplayer2.offline;
|
||||||
|
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import com.google.android.exoplayer2.C;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builder for DownloadState.
|
||||||
|
*
|
||||||
|
* <p>Defines default values for each field (except {@code id}) to facilitate DownloadState creation
|
||||||
|
* for tests. Tests must avoid depending on the default values but explicitly set tested parameters
|
||||||
|
* during test initialization.
|
||||||
|
*/
|
||||||
|
class DownloadStateBuilder {
|
||||||
|
private String id;
|
||||||
|
private String type;
|
||||||
|
private Uri uri;
|
||||||
|
@Nullable private String cacheKey;
|
||||||
|
private int state;
|
||||||
|
private float downloadPercentage;
|
||||||
|
private long downloadedBytes;
|
||||||
|
private long totalBytes;
|
||||||
|
private int failureReason;
|
||||||
|
private int stopFlags;
|
||||||
|
private int notMetRequirements;
|
||||||
|
private long startTimeMs;
|
||||||
|
private long updateTimeMs;
|
||||||
|
private StreamKey[] streamKeys;
|
||||||
|
private byte[] customMetadata;
|
||||||
|
|
||||||
|
DownloadStateBuilder(String id) {
|
||||||
|
this(id, "type", Uri.parse("uri"), /* cacheKey= */ null, new byte[0], new StreamKey[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
DownloadStateBuilder(DownloadAction action) {
|
||||||
|
this(
|
||||||
|
action.id,
|
||||||
|
action.type,
|
||||||
|
action.uri,
|
||||||
|
action.customCacheKey,
|
||||||
|
action.data,
|
||||||
|
action.keys.toArray(new StreamKey[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
DownloadStateBuilder(
|
||||||
|
String id,
|
||||||
|
String type,
|
||||||
|
Uri uri,
|
||||||
|
String cacheKey,
|
||||||
|
byte[] customMetadata,
|
||||||
|
StreamKey[] streamKeys) {
|
||||||
|
this.id = id;
|
||||||
|
this.type = type;
|
||||||
|
this.uri = uri;
|
||||||
|
this.cacheKey = cacheKey;
|
||||||
|
this.state = DownloadState.STATE_QUEUED;
|
||||||
|
this.downloadPercentage = (float) C.PERCENTAGE_UNSET;
|
||||||
|
this.downloadedBytes = (long) 0;
|
||||||
|
this.totalBytes = (long) C.LENGTH_UNSET;
|
||||||
|
this.failureReason = DownloadState.FAILURE_REASON_NONE;
|
||||||
|
this.stopFlags = 0;
|
||||||
|
this.startTimeMs = (long) 0;
|
||||||
|
this.updateTimeMs = (long) 0;
|
||||||
|
this.streamKeys = streamKeys;
|
||||||
|
this.customMetadata = customMetadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadStateBuilder setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadStateBuilder setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadStateBuilder setUri(String uri) {
|
||||||
|
this.uri = Uri.parse(uri);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadStateBuilder setUri(Uri uri) {
|
||||||
|
this.uri = uri;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadStateBuilder setCacheKey(@Nullable String cacheKey) {
|
||||||
|
this.cacheKey = cacheKey;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadStateBuilder setState(int state) {
|
||||||
|
this.state = state;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadStateBuilder setDownloadPercentage(float downloadPercentage) {
|
||||||
|
this.downloadPercentage = downloadPercentage;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadStateBuilder setDownloadedBytes(long downloadedBytes) {
|
||||||
|
this.downloadedBytes = downloadedBytes;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadStateBuilder setTotalBytes(long totalBytes) {
|
||||||
|
this.totalBytes = totalBytes;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadStateBuilder setFailureReason(int failureReason) {
|
||||||
|
this.failureReason = failureReason;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadStateBuilder setStopFlags(int stopFlags) {
|
||||||
|
this.stopFlags = stopFlags;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadStateBuilder setNotMetRequirements(int notMetRequirements) {
|
||||||
|
this.notMetRequirements = notMetRequirements;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadStateBuilder setStartTimeMs(long startTimeMs) {
|
||||||
|
this.startTimeMs = startTimeMs;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadStateBuilder setUpdateTimeMs(long updateTimeMs) {
|
||||||
|
this.updateTimeMs = updateTimeMs;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadStateBuilder setStreamKeys(StreamKey... streamKeys) {
|
||||||
|
this.streamKeys = streamKeys;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadStateBuilder setCustomMetadata(byte[] customMetadata) {
|
||||||
|
this.customMetadata = customMetadata;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadState build() {
|
||||||
|
return new DownloadState(
|
||||||
|
id,
|
||||||
|
type,
|
||||||
|
uri,
|
||||||
|
cacheKey,
|
||||||
|
state,
|
||||||
|
downloadPercentage,
|
||||||
|
downloadedBytes,
|
||||||
|
totalBytes,
|
||||||
|
failureReason,
|
||||||
|
stopFlags,
|
||||||
|
notMetRequirements,
|
||||||
|
startTimeMs,
|
||||||
|
updateTimeMs,
|
||||||
|
streamKeys,
|
||||||
|
customMetadata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,344 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.google.android.exoplayer2.offline;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import android.net.Uri;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
|
||||||
|
/** Unit tests for {@link DownloadState}. */
|
||||||
|
@RunWith(RobolectricTestRunner.class)
|
||||||
|
public class DownloadStateTest {
|
||||||
|
|
||||||
|
private Uri testUri;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
testUri = Uri.parse("https://www.test.com/download1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mergeAction_actionHaveDifferentType_throwsException() {
|
||||||
|
DownloadAction downloadAction = createDownloadAction();
|
||||||
|
DownloadState downloadState =
|
||||||
|
new DownloadStateBuilder(downloadAction)
|
||||||
|
.setType(downloadAction.type + "_different")
|
||||||
|
.setState(DownloadState.STATE_QUEUED)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try {
|
||||||
|
downloadState.mergeAction(downloadAction);
|
||||||
|
fail();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Expected.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mergeAction_actionHaveDifferentId_throwsException() {
|
||||||
|
DownloadAction downloadAction = createDownloadAction();
|
||||||
|
DownloadState downloadState =
|
||||||
|
new DownloadStateBuilder(downloadAction)
|
||||||
|
.setId(downloadAction.id + "_different")
|
||||||
|
.setState(DownloadState.STATE_QUEUED)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try {
|
||||||
|
downloadState.mergeAction(downloadAction);
|
||||||
|
fail();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Expected.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mergeAction_actionsWithSameIdAndType_doesNotFail() {
|
||||||
|
DownloadAction downloadAction = createDownloadAction();
|
||||||
|
DownloadStateBuilder downloadStateBuilder =
|
||||||
|
new DownloadStateBuilder(downloadAction).setState(DownloadState.STATE_QUEUED);
|
||||||
|
DownloadState downloadState = downloadStateBuilder.build();
|
||||||
|
|
||||||
|
downloadState.mergeAction(downloadAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mergeAction_actionHaveDifferentUri_downloadStateUriIsUpdated() {
|
||||||
|
DownloadAction downloadAction = createDownloadAction();
|
||||||
|
DownloadStateBuilder downloadStateBuilder =
|
||||||
|
new DownloadStateBuilder(downloadAction)
|
||||||
|
.setUri(downloadAction.uri + "_different")
|
||||||
|
.setState(DownloadState.STATE_QUEUED);
|
||||||
|
DownloadState downloadState = downloadStateBuilder.build();
|
||||||
|
|
||||||
|
DownloadState mergedDownloadState = downloadState.mergeAction(downloadAction);
|
||||||
|
|
||||||
|
DownloadState expectedDownloadState = downloadStateBuilder.setUri(downloadAction.uri).build();
|
||||||
|
assertEqual(mergedDownloadState, expectedDownloadState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mergeAction_actionHaveDifferentData_downloadStateDataIsUpdated() {
|
||||||
|
DownloadAction downloadAction =
|
||||||
|
DownloadAction.createDownloadAction(
|
||||||
|
DownloadAction.TYPE_DASH,
|
||||||
|
testUri,
|
||||||
|
Collections.emptyList(),
|
||||||
|
/* customCacheKey= */ null,
|
||||||
|
/* data= */ new byte[] {1, 2, 3, 4});
|
||||||
|
DownloadStateBuilder downloadStateBuilder =
|
||||||
|
new DownloadStateBuilder(downloadAction)
|
||||||
|
.setState(DownloadState.STATE_QUEUED)
|
||||||
|
.setCustomMetadata(new byte[0]);
|
||||||
|
DownloadState downloadState = downloadStateBuilder.build();
|
||||||
|
|
||||||
|
DownloadState mergedDownloadState = downloadState.mergeAction(downloadAction);
|
||||||
|
|
||||||
|
DownloadState expectedDownloadState =
|
||||||
|
downloadStateBuilder.setCustomMetadata(downloadAction.data).build();
|
||||||
|
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();
|
||||||
|
DownloadStateBuilder downloadStateBuilder =
|
||||||
|
new DownloadStateBuilder(downloadAction).setState(DownloadState.STATE_REMOVING);
|
||||||
|
DownloadState downloadState = downloadStateBuilder.build();
|
||||||
|
|
||||||
|
DownloadState mergedDownloadState = downloadState.mergeAction(downloadAction);
|
||||||
|
|
||||||
|
DownloadState expectedDownloadState =
|
||||||
|
downloadStateBuilder.setState(DownloadState.STATE_RESTARTING).build();
|
||||||
|
assertEqual(mergedDownloadState, expectedDownloadState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mergeAction_failedDownloadDownloadAction_stateBecomesQueued() {
|
||||||
|
DownloadAction downloadAction = createDownloadAction();
|
||||||
|
DownloadStateBuilder downloadStateBuilder =
|
||||||
|
new DownloadStateBuilder(downloadAction)
|
||||||
|
.setState(DownloadState.STATE_FAILED)
|
||||||
|
.setFailureReason(DownloadState.FAILURE_REASON_UNKNOWN);
|
||||||
|
DownloadState downloadState = downloadStateBuilder.build();
|
||||||
|
|
||||||
|
DownloadState mergedDownloadState = downloadState.mergeAction(downloadAction);
|
||||||
|
|
||||||
|
DownloadState expectedDownloadState =
|
||||||
|
downloadStateBuilder
|
||||||
|
.setState(DownloadState.STATE_QUEUED)
|
||||||
|
.setFailureReason(DownloadState.FAILURE_REASON_NONE)
|
||||||
|
.build();
|
||||||
|
assertEqual(mergedDownloadState, expectedDownloadState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mergeAction_stoppedDownloadDownloadAction_stateStaysStopped() {
|
||||||
|
DownloadAction downloadAction = createDownloadAction();
|
||||||
|
DownloadStateBuilder downloadStateBuilder =
|
||||||
|
new DownloadStateBuilder(downloadAction)
|
||||||
|
.setState(DownloadState.STATE_STOPPED)
|
||||||
|
.setStopFlags(DownloadState.STOP_FLAG_STOPPED);
|
||||||
|
DownloadState downloadState = downloadStateBuilder.build();
|
||||||
|
|
||||||
|
DownloadState mergedDownloadState = downloadState.mergeAction(downloadAction);
|
||||||
|
|
||||||
|
assertEqual(mergedDownloadState, downloadState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mergeAction_stoppedDownloadRemoveAction_stateBecomesRemoving() {
|
||||||
|
DownloadAction downloadAction = createRemoveAction();
|
||||||
|
DownloadStateBuilder downloadStateBuilder =
|
||||||
|
new DownloadStateBuilder(downloadAction)
|
||||||
|
.setState(DownloadState.STATE_STOPPED)
|
||||||
|
.setStopFlags(DownloadState.STOP_FLAG_STOPPED);
|
||||||
|
DownloadState downloadState = downloadStateBuilder.build();
|
||||||
|
|
||||||
|
DownloadState mergedDownloadState = downloadState.mergeAction(downloadAction);
|
||||||
|
|
||||||
|
DownloadState expectedDownloadState =
|
||||||
|
downloadStateBuilder.setState(DownloadState.STATE_REMOVING).build();
|
||||||
|
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);
|
||||||
|
StreamKey streamKey2 = new StreamKey(/* groupIndex= */ 1, /* trackIndex= */ 1);
|
||||||
|
StreamKey[] keys1 = new StreamKey[] {streamKey1};
|
||||||
|
StreamKey[] keys2 = new StreamKey[] {streamKey2};
|
||||||
|
StreamKey[] expectedKeys = new StreamKey[] {streamKey1, streamKey2};
|
||||||
|
|
||||||
|
doTestMergeActionReturnsMergedKeys(keys1, keys2, expectedKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mergeAction_returnsUniqueKeys() {
|
||||||
|
StreamKey streamKey1 = new StreamKey(/* groupIndex= */ 0, /* trackIndex= */ 0);
|
||||||
|
StreamKey streamKey1Copy = new StreamKey(/* groupIndex= */ 0, /* trackIndex= */ 0);
|
||||||
|
StreamKey streamKey2 = new StreamKey(/* groupIndex= */ 1, /* trackIndex= */ 1);
|
||||||
|
StreamKey[] keys1 = new StreamKey[] {streamKey1};
|
||||||
|
StreamKey[] keys2 = new StreamKey[] {streamKey2, streamKey1Copy};
|
||||||
|
StreamKey[] expectedKeys = new StreamKey[] {streamKey1, streamKey2};
|
||||||
|
|
||||||
|
doTestMergeActionReturnsMergedKeys(keys1, keys2, expectedKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mergeAction_ifFirstActionKeysEmpty_returnsEmptyKeys() {
|
||||||
|
StreamKey streamKey1 = new StreamKey(/* groupIndex= */ 0, /* trackIndex= */ 0);
|
||||||
|
StreamKey streamKey2 = new StreamKey(/* groupIndex= */ 1, /* trackIndex= */ 1);
|
||||||
|
StreamKey[] keys1 = new StreamKey[] {};
|
||||||
|
StreamKey[] keys2 = new StreamKey[] {streamKey2, streamKey1};
|
||||||
|
StreamKey[] expectedKeys = new StreamKey[] {};
|
||||||
|
|
||||||
|
doTestMergeActionReturnsMergedKeys(keys1, keys2, expectedKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mergeAction_ifNotFirstActionKeysEmpty_returnsEmptyKeys() {
|
||||||
|
StreamKey streamKey1 = new StreamKey(/* groupIndex= */ 0, /* trackIndex= */ 0);
|
||||||
|
StreamKey streamKey2 = new StreamKey(/* groupIndex= */ 1, /* trackIndex= */ 1);
|
||||||
|
StreamKey[] keys1 = new StreamKey[] {streamKey2, streamKey1};
|
||||||
|
StreamKey[] keys2 = new StreamKey[] {};
|
||||||
|
StreamKey[] expectedKeys = new StreamKey[] {};
|
||||||
|
|
||||||
|
doTestMergeActionReturnsMergedKeys(keys1, keys2, expectedKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doTestMergeActionReturnsMergedKeys(
|
||||||
|
StreamKey[] keys1, StreamKey[] keys2, StreamKey[] expectedKeys) {
|
||||||
|
DownloadAction downloadAction =
|
||||||
|
DownloadAction.createDownloadAction(
|
||||||
|
DownloadAction.TYPE_DASH,
|
||||||
|
testUri,
|
||||||
|
Arrays.asList(keys2),
|
||||||
|
/* customCacheKey= */ null,
|
||||||
|
/* data= */ null);
|
||||||
|
DownloadStateBuilder downloadStateBuilder =
|
||||||
|
new DownloadStateBuilder(downloadAction)
|
||||||
|
.setState(DownloadState.STATE_QUEUED)
|
||||||
|
.setStreamKeys(keys1);
|
||||||
|
DownloadState downloadState = downloadStateBuilder.build();
|
||||||
|
|
||||||
|
DownloadState mergedDownloadState = downloadState.mergeAction(downloadAction);
|
||||||
|
|
||||||
|
DownloadState expectedDownloadState = downloadStateBuilder.setStreamKeys(expectedKeys).build();
|
||||||
|
assertEqual(mergedDownloadState, expectedDownloadState);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void assertEqual(DownloadState downloadState, DownloadState expected) {
|
||||||
|
assertThat(areEqual(downloadState, expected)).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean areEqual(DownloadState downloadState, DownloadState that) {
|
||||||
|
if (downloadState.state != that.state) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Float.compare(that.downloadPercentage, downloadState.downloadPercentage) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (downloadState.downloadedBytes != that.downloadedBytes) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (downloadState.totalBytes != that.totalBytes) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (downloadState.startTimeMs != that.startTimeMs) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (downloadState.updateTimeMs != that.updateTimeMs) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (downloadState.failureReason != that.failureReason) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (downloadState.stopFlags != that.stopFlags) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (downloadState.notMetRequirements != that.notMetRequirements) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!downloadState.id.equals(that.id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!downloadState.type.equals(that.type)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!downloadState.uri.equals(that.uri)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (downloadState.cacheKey != null
|
||||||
|
? !downloadState.cacheKey.equals(that.cacheKey)
|
||||||
|
: that.cacheKey != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (downloadState.streamKeys.length != that.streamKeys.length
|
||||||
|
|| !Arrays.asList(downloadState.streamKeys).containsAll(Arrays.asList(that.streamKeys))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Arrays.equals(downloadState.customMetadata, that.customMetadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
private DownloadAction createDownloadAction() {
|
||||||
|
return DownloadAction.createDownloadAction(
|
||||||
|
DownloadAction.TYPE_DASH,
|
||||||
|
testUri,
|
||||||
|
Collections.emptyList(),
|
||||||
|
/* customCacheKey= */ null,
|
||||||
|
/* data= */ null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private DownloadAction createRemoveAction() {
|
||||||
|
return DownloadAction.createRemoveAction(
|
||||||
|
DownloadAction.TYPE_DASH, testUri, /* customCacheKey= */ null);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue