Make DownloadState counters mutable

PiperOrigin-RevId: 241763220
This commit is contained in:
eguven 2019-04-03 18:52:03 +01:00 committed by Oliver Woodman
parent b10f4023f0
commit 27884c70f8
7 changed files with 83 additions and 83 deletions

View File

@ -26,6 +26,7 @@ import androidx.annotation.VisibleForTesting;
import com.google.android.exoplayer2.database.DatabaseIOException;
import com.google.android.exoplayer2.database.DatabaseProvider;
import com.google.android.exoplayer2.database.VersionTable;
import com.google.android.exoplayer2.upstream.cache.CacheUtil.CachingCounters;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util;
@ -199,9 +200,9 @@ public final class DefaultDownloadIndex implements DownloadIndex {
values.put(COLUMN_URI, downloadState.uri.toString());
values.put(COLUMN_CACHE_KEY, downloadState.cacheKey);
values.put(COLUMN_STATE, downloadState.state);
values.put(COLUMN_DOWNLOAD_PERCENTAGE, downloadState.downloadPercentage);
values.put(COLUMN_DOWNLOADED_BYTES, downloadState.downloadedBytes);
values.put(COLUMN_TOTAL_BYTES, downloadState.totalBytes);
values.put(COLUMN_DOWNLOAD_PERCENTAGE, downloadState.getDownloadPercentage());
values.put(COLUMN_DOWNLOADED_BYTES, downloadState.getDownloadedBytes());
values.put(COLUMN_TOTAL_BYTES, downloadState.getTotalBytes());
values.put(COLUMN_FAILURE_REASON, downloadState.failureReason);
values.put(COLUMN_STOP_FLAGS, /*stopFlags*/ 0);
values.put(COLUMN_NOT_MET_REQUIREMENTS, downloadState.notMetRequirements);
@ -341,22 +342,24 @@ public final class DefaultDownloadIndex implements DownloadIndex {
}
private static DownloadState getDownloadStateForCurrentRow(Cursor cursor) {
CachingCounters cachingCounters = new CachingCounters();
cachingCounters.alreadyCachedBytes = cursor.getLong(COLUMN_INDEX_DOWNLOADED_BYTES);
cachingCounters.contentLength = cursor.getLong(COLUMN_INDEX_TOTAL_BYTES);
cachingCounters.percentage = cursor.getFloat(COLUMN_INDEX_DOWNLOAD_PERCENTAGE);
return new DownloadState(
cursor.getString(COLUMN_INDEX_ID),
cursor.getString(COLUMN_INDEX_TYPE),
Uri.parse(cursor.getString(COLUMN_INDEX_URI)),
cursor.getString(COLUMN_INDEX_CACHE_KEY),
cursor.getInt(COLUMN_INDEX_STATE),
cursor.getFloat(COLUMN_INDEX_DOWNLOAD_PERCENTAGE),
cursor.getLong(COLUMN_INDEX_DOWNLOADED_BYTES),
cursor.getLong(COLUMN_INDEX_TOTAL_BYTES),
cursor.getInt(COLUMN_INDEX_FAILURE_REASON),
cursor.getInt(COLUMN_INDEX_NOT_MET_REQUIREMENTS),
cursor.getInt(COLUMN_INDEX_MANUAL_STOP_REASON),
cursor.getLong(COLUMN_INDEX_START_TIME_MS),
cursor.getLong(COLUMN_INDEX_UPDATE_TIME_MS),
decodeStreamKeys(cursor.getString(COLUMN_INDEX_STREAM_KEYS)),
cursor.getBlob(COLUMN_INDEX_CUSTOM_METADATA));
cursor.getBlob(COLUMN_INDEX_CUSTOM_METADATA),
cachingCounters);
}
private static String encodeStreamKeys(StreamKey[] streamKeys) {

View File

@ -40,6 +40,7 @@ import com.google.android.exoplayer2.database.DatabaseIOException;
import com.google.android.exoplayer2.database.DatabaseProvider;
import com.google.android.exoplayer2.scheduler.Requirements;
import com.google.android.exoplayer2.scheduler.RequirementsWatcher;
import com.google.android.exoplayer2.upstream.cache.CacheUtil.CachingCounters;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Log;
import java.io.IOException;
@ -699,7 +700,9 @@ public final class DownloadManager {
}
simultaneousDownloads++;
}
activeDownloads.put(download, new DownloadThread(download));
DownloadThread downloadThread = new DownloadThread(download);
activeDownloads.put(download, downloadThread);
download.setCounters(downloadThread.downloader.getCounters());
logd("Download is started", download);
return START_THREAD_SUCCEEDED;
}
@ -744,15 +747,6 @@ public final class DownloadManager {
maybeNotifyListenersIdle();
}
@Nullable
private Downloader getDownloader(Download download) {
DownloadThread downloadThread = activeDownloads.get(download);
if (downloadThread != null) {
return downloadThread.downloader;
}
return null;
}
private static final class Download {
private final DownloadManager downloadManager;
@ -794,15 +788,6 @@ public final class DownloadManager {
}
public DownloadState getUpdatedDownloadState() {
float downloadPercentage = C.PERCENTAGE_UNSET;
long downloadedBytes = 0;
long totalBytes = C.LENGTH_UNSET;
Downloader downloader = downloadManager.getDownloader(this);
if (downloader != null) {
downloadPercentage = downloader.getDownloadPercentage();
downloadedBytes = downloader.getDownloadedBytes();
totalBytes = downloader.getTotalBytes();
}
downloadState =
new DownloadState(
downloadState.id,
@ -810,16 +795,14 @@ public final class DownloadManager {
downloadState.uri,
downloadState.cacheKey,
state,
downloadPercentage,
downloadedBytes,
totalBytes,
state != STATE_FAILED ? FAILURE_REASON_NONE : failureReason,
notMetRequirements,
manualStopReason,
downloadState.startTimeMs,
/* updateTimeMs= */ System.currentTimeMillis(),
downloadState.streamKeys,
downloadState.customMetadata);
downloadState.customMetadata,
downloadState.counters);
return downloadState;
}
@ -868,6 +851,10 @@ public final class DownloadManager {
return state == STATE_REMOVING || state == STATE_RESTARTING;
}
public void setCounters(CachingCounters counters) {
downloadState.setCounters(counters);
}
private void updateStopState() {
DownloadState oldDownloadState = downloadState;
if (canStart()) {

View File

@ -21,6 +21,7 @@ import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.scheduler.Requirements;
import com.google.android.exoplayer2.scheduler.Requirements.RequirementFlags;
import com.google.android.exoplayer2.upstream.cache.CacheUtil.CachingCounters;
import com.google.android.exoplayer2.util.Assertions;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
@ -127,12 +128,6 @@ public final class DownloadState {
@Nullable public final String cacheKey;
/** The state of the download. */
@State public final int state;
/** The estimated download percentage, or {@link C#PERCENTAGE_UNSET} if unavailable. */
public final float downloadPercentage;
/** The total number of downloaded bytes. */
public final long downloadedBytes;
/** The total size of the media, or {@link C#LENGTH_UNSET} if unknown. */
public final long totalBytes;
/** The first time when download entry is created. */
public final long startTimeMs;
/** The last update time. */
@ -151,6 +146,8 @@ public final class DownloadState {
/** The manual stop reason. */
public final int manualStopReason;
/*package*/ CachingCounters counters;
/**
* Creates a {@link DownloadState} using a {@link DownloadAction}.
*
@ -167,16 +164,14 @@ public final class DownloadState {
action.uri,
action.customCacheKey,
/* state= */ STATE_QUEUED,
/* downloadPercentage= */ C.PERCENTAGE_UNSET,
/* downloadedBytes= */ 0,
/* totalBytes= */ C.LENGTH_UNSET,
FAILURE_REASON_NONE,
/* notMetRequirements= */ 0,
/* manualStopReason= */ 0,
/* startTimeMs= */ currentTimeMs,
/* updateTimeMs= */ currentTimeMs,
action.keys.toArray(new StreamKey[0]),
action.data);
action.data,
new CachingCounters());
}
/* package */ DownloadState(
@ -185,16 +180,15 @@ public final class DownloadState {
Uri uri,
@Nullable String cacheKey,
@State int state,
float downloadPercentage,
long downloadedBytes,
long totalBytes,
@FailureReason int failureReason,
@RequirementFlags int notMetRequirements,
int manualStopReason,
long startTimeMs,
long updateTimeMs,
StreamKey[] streamKeys,
byte[] customMetadata) {
byte[] customMetadata,
CachingCounters counters) {
Assertions.checkNotNull(counters);
Assertions.checkState((failureReason == FAILURE_REASON_NONE) == (state != STATE_FAILED));
if (manualStopReason != 0 || notMetRequirements != 0) {
Assertions.checkState(state != STATE_DOWNLOADING && state != STATE_QUEUED);
@ -204,9 +198,6 @@ public final class DownloadState {
this.uri = uri;
this.cacheKey = cacheKey;
this.state = state;
this.downloadPercentage = downloadPercentage;
this.downloadedBytes = downloadedBytes;
this.totalBytes = totalBytes;
this.failureReason = failureReason;
this.notMetRequirements = notMetRequirements;
this.manualStopReason = manualStopReason;
@ -214,6 +205,7 @@ public final class DownloadState {
this.updateTimeMs = updateTimeMs;
this.streamKeys = streamKeys;
this.customMetadata = customMetadata;
this.counters = counters;
}
/**
@ -232,16 +224,14 @@ public final class DownloadState {
action.uri,
action.customCacheKey,
getNextState(state, manualStopReason != 0 || notMetRequirements != 0),
/* downloadPercentage= */ C.PERCENTAGE_UNSET,
downloadedBytes,
/* totalBytes= */ C.LENGTH_UNSET,
FAILURE_REASON_NONE,
notMetRequirements,
manualStopReason,
startTimeMs,
/* updateTimeMs= */ System.currentTimeMillis(),
mergeStreamKeys(this, action),
action.data);
action.data,
counters);
}
/** Returns a duplicate {@link DownloadState} in {@link #STATE_REMOVING}. */
@ -252,16 +242,42 @@ public final class DownloadState {
uri,
cacheKey,
STATE_REMOVING,
/* downloadPercentage= */ C.PERCENTAGE_UNSET,
downloadedBytes,
/* totalBytes= */ C.LENGTH_UNSET,
FAILURE_REASON_NONE,
notMetRequirements,
manualStopReason,
startTimeMs,
/* updateTimeMs= */ System.currentTimeMillis(),
streamKeys,
customMetadata);
customMetadata,
counters);
}
/** Returns the total number of downloaded bytes. */
public long getDownloadedBytes() {
return counters.totalCachedBytes();
}
/** Returns the total size of the media, or {@link C#LENGTH_UNSET} if unknown. */
public long getTotalBytes() {
return counters.contentLength;
}
/**
* Returns the estimated download percentage, or {@link C#PERCENTAGE_UNSET} if no estimate is
* available.
*/
public float getDownloadPercentage() {
return counters.percentage;
}
/**
* Sets counters which are updated by a {@link Downloader}.
*
* @param counters An instance of {@link CachingCounters}.
*/
protected void setCounters(CachingCounters counters) {
Assertions.checkNotNull(counters);
this.counters = counters;
}
private static int getNextState(int currentState, boolean isStopped) {

View File

@ -20,7 +20,6 @@ import static com.google.common.truth.Truth.assertThat;
import android.net.Uri;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.offline.DownloadState.State;
import com.google.android.exoplayer2.scheduler.Requirements;
import com.google.android.exoplayer2.testutil.DummyMainThread;
@ -631,13 +630,13 @@ public class DownloadManagerTest {
private volatile boolean interrupted;
private volatile boolean cancelled;
private volatile boolean enableDownloadIOException;
private volatile int downloadedBytes;
private volatile int startCount;
private CachingCounters counters;
private FakeDownloader() {
this.started = new CountDownLatch(1);
this.blocker = new com.google.android.exoplayer2.util.ConditionVariable();
downloadedBytes = C.LENGTH_UNSET;
counters = new CachingCounters();
}
@SuppressWarnings({"NonAtomicOperationOnVolatileField", "NonAtomicVolatileUpdate"})
@ -735,22 +734,22 @@ public class DownloadManagerTest {
@Override
public long getDownloadedBytes() {
return downloadedBytes;
return counters.newlyCachedBytes;
}
@Override
public long getTotalBytes() {
return C.LENGTH_UNSET;
return counters.contentLength;
}
@Override
public float getDownloadPercentage() {
return C.PERCENTAGE_UNSET;
return counters.percentage;
}
@Override
public CachingCounters getCounters() {
return null;
return counters;
}
private void assertDoesNotStart() throws InterruptedException {
@ -760,7 +759,7 @@ public class DownloadManagerTest {
@SuppressWarnings({"NonAtomicOperationOnVolatileField", "NonAtomicVolatileUpdate"})
private void increaseDownloadedByteCount() {
downloadedBytes++;
counters.newlyCachedBytes++;
}
}
}

View File

@ -17,7 +17,7 @@ package com.google.android.exoplayer2.offline;
import android.net.Uri;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.upstream.cache.CacheUtil.CachingCounters;
/**
* Builder for DownloadState.
@ -27,14 +27,12 @@ import com.google.android.exoplayer2.C;
* during test initialization.
*/
class DownloadStateBuilder {
private final CachingCounters counters;
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 notMetRequirements;
private int manualStopReason;
@ -69,14 +67,12 @@ class DownloadStateBuilder {
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.startTimeMs = (long) 0;
this.updateTimeMs = (long) 0;
this.streamKeys = streamKeys;
this.customMetadata = customMetadata;
this.counters = new CachingCounters();
}
public DownloadStateBuilder setId(String id) {
@ -110,17 +106,17 @@ class DownloadStateBuilder {
}
public DownloadStateBuilder setDownloadPercentage(float downloadPercentage) {
this.downloadPercentage = downloadPercentage;
counters.percentage = downloadPercentage;
return this;
}
public DownloadStateBuilder setDownloadedBytes(long downloadedBytes) {
this.downloadedBytes = downloadedBytes;
counters.alreadyCachedBytes = downloadedBytes;
return this;
}
public DownloadStateBuilder setTotalBytes(long totalBytes) {
this.totalBytes = totalBytes;
counters.contentLength = totalBytes;
return this;
}
@ -166,15 +162,13 @@ class DownloadStateBuilder {
uri,
cacheKey,
state,
downloadPercentage,
downloadedBytes,
totalBytes,
failureReason,
notMetRequirements,
manualStopReason,
startTimeMs,
updateTimeMs,
streamKeys,
customMetadata);
customMetadata,
counters);
}
}

View File

@ -270,9 +270,9 @@ public class DownloadStateTest {
static void assertEqual(
DownloadState downloadState, DownloadState that, boolean compareTimeFields) {
assertThat(downloadState.state).isEqualTo(that.state);
assertThat(downloadState.downloadPercentage).isEqualTo(that.downloadPercentage);
assertThat(downloadState.downloadedBytes).isEqualTo(that.downloadedBytes);
assertThat(downloadState.totalBytes).isEqualTo(that.totalBytes);
assertThat(downloadState.getDownloadPercentage()).isEqualTo(that.getDownloadPercentage());
assertThat(downloadState.getDownloadedBytes()).isEqualTo(that.getDownloadedBytes());
assertThat(downloadState.getTotalBytes()).isEqualTo(that.getTotalBytes());
if (compareTimeFields) {
assertThat(downloadState.startTimeMs).isEqualTo(that.startTimeMs);
assertThat(downloadState.updateTimeMs).isEqualTo(that.updateTimeMs);

View File

@ -75,11 +75,12 @@ public final class DownloadNotificationHelper {
continue;
}
haveDownloadTasks = true;
if (downloadState.downloadPercentage != C.PERCENTAGE_UNSET) {
float downloadPercentage = downloadState.getDownloadPercentage();
if (downloadPercentage != C.PERCENTAGE_UNSET) {
allDownloadPercentagesUnknown = false;
totalPercentage += downloadState.downloadPercentage;
totalPercentage += downloadPercentage;
}
haveDownloadedBytes |= downloadState.downloadedBytes > 0;
haveDownloadedBytes |= downloadState.getDownloadedBytes() > 0;
downloadTaskCount++;
}