Commit c0e6cd1b by eguven Committed by Oliver Woodman

Add DownloadState.mergeAction method

This method is needed by DownloadManager.

PiperOrigin-RevId: 232447145
parent 67be9e77
......@@ -16,12 +16,7 @@
package com.google.android.exoplayer2.offline;
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.util.Collections;
import java.util.HashSet;
/** {@link DownloadIndex} related utility methods. */
public final class DownloadIndexUtil {
......@@ -79,46 +74,10 @@ public final class DownloadIndexUtil {
DownloadIndex downloadIndex, @Nullable String id, DownloadAction action) {
DownloadState downloadState = downloadIndex.getDownloadState(id != null ? id : action.id);
if (downloadState != null) {
downloadState = merge(downloadState, action);
downloadState = downloadState.mergeAction(action);
} else {
downloadState = new DownloadState(action);
}
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.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collections;
import java.util.HashSet;
/** Represents state of a download. */
public final class DownloadState {
......@@ -231,4 +233,62 @@ public final class DownloadState {
this.streamKeys = streamKeys;
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 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.VersionTable;
import java.util.Arrays;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
......@@ -62,7 +58,7 @@ public class DefaultDownloadIndexTest {
downloadIndex.putDownloadState(downloadState);
DownloadState readDownloadState = downloadIndex.getDownloadState(id);
assertEqual(readDownloadState, downloadState);
DownloadStateTest.assertEqual(readDownloadState, downloadState);
}
@Test
......@@ -94,7 +90,7 @@ public class DefaultDownloadIndexTest {
DownloadState readDownloadState = downloadIndex.getDownloadState(id);
assertThat(readDownloadState).isNotNull();
assertEqual(readDownloadState, downloadState);
DownloadStateTest.assertEqual(readDownloadState, downloadState);
}
@Test
......@@ -106,7 +102,7 @@ public class DefaultDownloadIndexTest {
downloadIndex = new DefaultDownloadIndex(databaseProvider);
DownloadState readDownloadState = downloadIndex.getDownloadState(id);
assertThat(readDownloadState).isNotNull();
assertEqual(readDownloadState, downloadState);
DownloadStateTest.assertEqual(readDownloadState, downloadState);
}
@Test
......@@ -141,9 +137,9 @@ public class DefaultDownloadIndexTest {
assertThat(cursor.getCount()).isEqualTo(2);
cursor.moveToNext();
assertEqual(cursor.getDownloadState(), downloadState2);
DownloadStateTest.assertEqual(cursor.getDownloadState(), downloadState2);
cursor.moveToNext();
assertEqual(cursor.getDownloadState(), downloadState1);
DownloadStateTest.assertEqual(cursor.getDownloadState(), downloadState1);
cursor.close();
}
......@@ -173,9 +169,9 @@ public class DefaultDownloadIndexTest {
assertThat(cursor.getCount()).isEqualTo(2);
cursor.moveToNext();
assertEqual(cursor.getDownloadState(), downloadState1);
DownloadStateTest.assertEqual(cursor.getDownloadState(), downloadState1);
cursor.moveToNext();
assertEqual(cursor.getDownloadState(), downloadState3);
DownloadStateTest.assertEqual(cursor.getDownloadState(), downloadState3);
cursor.close();
}
......@@ -211,184 +207,4 @@ public class DefaultDownloadIndexTest {
.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);
}
}
}
/*
* 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);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment