From 27884c70f88ea18a11678b4ec40f105e743ff5d2 Mon Sep 17 00:00:00 2001 From: eguven Date: Wed, 3 Apr 2019 18:52:03 +0100 Subject: [PATCH] Make DownloadState counters mutable PiperOrigin-RevId: 241763220 --- .../offline/DefaultDownloadIndex.java | 17 +++-- .../exoplayer2/offline/DownloadManager.java | 33 +++------- .../exoplayer2/offline/DownloadState.java | 66 ++++++++++++------- .../offline/DownloadManagerTest.java | 15 ++--- .../offline/DownloadStateBuilder.java | 22 +++---- .../exoplayer2/offline/DownloadStateTest.java | 6 +- .../ui/DownloadNotificationHelper.java | 7 +- 7 files changed, 83 insertions(+), 83 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/offline/DefaultDownloadIndex.java b/library/core/src/main/java/com/google/android/exoplayer2/offline/DefaultDownloadIndex.java index 10e01969bb..ae0817b27d 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/offline/DefaultDownloadIndex.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/offline/DefaultDownloadIndex.java @@ -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) { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadManager.java b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadManager.java index 5f4a0eae61..28f6fe00e6 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadManager.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadManager.java @@ -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()) { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadState.java b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadState.java index bb8be6b945..1981bb19ae 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadState.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadState.java @@ -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) { diff --git a/library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadManagerTest.java b/library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadManagerTest.java index 4046ff76e8..be1631304b 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadManagerTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadManagerTest.java @@ -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++; } } } diff --git a/library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadStateBuilder.java b/library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadStateBuilder.java index cfed9a61ce..084071cf7a 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadStateBuilder.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadStateBuilder.java @@ -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); } } diff --git a/library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadStateTest.java b/library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadStateTest.java index cedbd8a8c4..48bf894a60 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadStateTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/offline/DownloadStateTest.java @@ -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); diff --git a/library/ui/src/main/java/com/google/android/exoplayer2/ui/DownloadNotificationHelper.java b/library/ui/src/main/java/com/google/android/exoplayer2/ui/DownloadNotificationHelper.java index d68ab41733..ad50e26038 100644 --- a/library/ui/src/main/java/com/google/android/exoplayer2/ui/DownloadNotificationHelper.java +++ b/library/ui/src/main/java/com/google/android/exoplayer2/ui/DownloadNotificationHelper.java @@ -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++; }