Commit 7eed60c9 by eguven Committed by Oliver Woodman

Add DownloadManager.stopDownloads(int manualStopReason)

Also removed STOP_FLAG_DOWNLOAD_MANAGER_NOT_READY.

PiperOrigin-RevId: 232669463
parent bdc87a4f
...@@ -50,6 +50,7 @@ public final class DefaultDownloadIndex implements DownloadIndex { ...@@ -50,6 +50,7 @@ public final class DefaultDownloadIndex implements DownloadIndex {
private static final String COLUMN_FAILURE_REASON = "failure_reason"; private static final String COLUMN_FAILURE_REASON = "failure_reason";
private static final String COLUMN_STOP_FLAGS = "stop_flags"; private static final String COLUMN_STOP_FLAGS = "stop_flags";
private static final String COLUMN_NOT_MET_REQUIREMENTS = "not_met_requirements"; private static final String COLUMN_NOT_MET_REQUIREMENTS = "not_met_requirements";
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_STREAM_KEYS = "stream_keys";
...@@ -66,10 +67,11 @@ public final class DefaultDownloadIndex implements DownloadIndex { ...@@ -66,10 +67,11 @@ public final class DefaultDownloadIndex implements DownloadIndex {
private static final int COLUMN_INDEX_FAILURE_REASON = 8; private static final int COLUMN_INDEX_FAILURE_REASON = 8;
private static final int COLUMN_INDEX_STOP_FLAGS = 9; private static final int COLUMN_INDEX_STOP_FLAGS = 9;
private static final int COLUMN_INDEX_NOT_MET_REQUIREMENTS = 10; private static final int COLUMN_INDEX_NOT_MET_REQUIREMENTS = 10;
private static final int COLUMN_INDEX_START_TIME_MS = 11; private static final int COLUMN_INDEX_MANUAL_STOP_REASON = 11;
private static final int COLUMN_INDEX_UPDATE_TIME_MS = 12; private static final int COLUMN_INDEX_START_TIME_MS = 12;
private static final int COLUMN_INDEX_STREAM_KEYS = 13; private static final int COLUMN_INDEX_UPDATE_TIME_MS = 13;
private static final int COLUMN_INDEX_CUSTOM_METADATA = 14; private static final int COLUMN_INDEX_STREAM_KEYS = 14;
private static final int COLUMN_INDEX_CUSTOM_METADATA = 15;
private static final String COLUMN_SELECTION_ID = COLUMN_ID + " = ?"; private static final String COLUMN_SELECTION_ID = COLUMN_ID + " = ?";
...@@ -86,6 +88,7 @@ public final class DefaultDownloadIndex implements DownloadIndex { ...@@ -86,6 +88,7 @@ public final class DefaultDownloadIndex implements DownloadIndex {
COLUMN_FAILURE_REASON, COLUMN_FAILURE_REASON,
COLUMN_STOP_FLAGS, COLUMN_STOP_FLAGS,
COLUMN_NOT_MET_REQUIREMENTS, COLUMN_NOT_MET_REQUIREMENTS,
COLUMN_MANUAL_STOP_REASON,
COLUMN_START_TIME_MS, COLUMN_START_TIME_MS,
COLUMN_UPDATE_TIME_MS, COLUMN_UPDATE_TIME_MS,
COLUMN_STREAM_KEYS, COLUMN_STREAM_KEYS,
...@@ -119,6 +122,8 @@ public final class DefaultDownloadIndex implements DownloadIndex { ...@@ -119,6 +122,8 @@ public final class DefaultDownloadIndex implements DownloadIndex {
+ " INTEGER NOT NULL," + " INTEGER NOT NULL,"
+ COLUMN_NOT_MET_REQUIREMENTS + COLUMN_NOT_MET_REQUIREMENTS
+ " INTEGER NOT NULL," + " INTEGER NOT NULL,"
+ COLUMN_MANUAL_STOP_REASON
+ " INTEGER NOT NULL,"
+ COLUMN_START_TIME_MS + COLUMN_START_TIME_MS
+ " INTEGER NOT NULL," + " INTEGER NOT NULL,"
+ COLUMN_UPDATE_TIME_MS + COLUMN_UPDATE_TIME_MS
...@@ -194,6 +199,7 @@ public final class DefaultDownloadIndex implements DownloadIndex { ...@@ -194,6 +199,7 @@ public final class DefaultDownloadIndex implements DownloadIndex {
values.put(COLUMN_FAILURE_REASON, downloadState.failureReason); values.put(COLUMN_FAILURE_REASON, downloadState.failureReason);
values.put(COLUMN_STOP_FLAGS, downloadState.stopFlags); values.put(COLUMN_STOP_FLAGS, downloadState.stopFlags);
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_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)); values.put(COLUMN_STREAM_KEYS, encodeStreamKeys(downloadState.streamKeys));
...@@ -260,6 +266,7 @@ public final class DefaultDownloadIndex implements DownloadIndex { ...@@ -260,6 +266,7 @@ public final class DefaultDownloadIndex implements DownloadIndex {
cursor.getInt(COLUMN_INDEX_FAILURE_REASON), cursor.getInt(COLUMN_INDEX_FAILURE_REASON),
cursor.getInt(COLUMN_INDEX_STOP_FLAGS), cursor.getInt(COLUMN_INDEX_STOP_FLAGS),
cursor.getInt(COLUMN_INDEX_NOT_MET_REQUIREMENTS), 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_START_TIME_MS),
cursor.getLong(COLUMN_INDEX_UPDATE_TIME_MS), cursor.getLong(COLUMN_INDEX_UPDATE_TIME_MS),
decodeStreamKeys(cursor.getString(COLUMN_INDEX_STREAM_KEYS)), decodeStreamKeys(cursor.getString(COLUMN_INDEX_STREAM_KEYS)),
......
...@@ -25,9 +25,8 @@ import static com.google.android.exoplayer2.offline.DownloadState.STATE_REMOVED; ...@@ -25,9 +25,8 @@ import static com.google.android.exoplayer2.offline.DownloadState.STATE_REMOVED;
import static com.google.android.exoplayer2.offline.DownloadState.STATE_REMOVING; import static com.google.android.exoplayer2.offline.DownloadState.STATE_REMOVING;
import static com.google.android.exoplayer2.offline.DownloadState.STATE_RESTARTING; import static com.google.android.exoplayer2.offline.DownloadState.STATE_RESTARTING;
import static com.google.android.exoplayer2.offline.DownloadState.STATE_STOPPED; import static com.google.android.exoplayer2.offline.DownloadState.STATE_STOPPED;
import static com.google.android.exoplayer2.offline.DownloadState.STOP_FLAG_DOWNLOAD_MANAGER_NOT_READY; import static com.google.android.exoplayer2.offline.DownloadState.STOP_FLAG_MANUAL;
import static com.google.android.exoplayer2.offline.DownloadState.STOP_FLAG_REQUIREMENTS_NOT_MET; import static com.google.android.exoplayer2.offline.DownloadState.STOP_FLAG_REQUIREMENTS_NOT_MET;
import static com.google.android.exoplayer2.offline.DownloadState.STOP_FLAG_STOPPED;
import android.content.Context; import android.content.Context;
import android.os.ConditionVariable; import android.os.ConditionVariable;
...@@ -109,15 +108,17 @@ public final class DownloadManager { ...@@ -109,15 +108,17 @@ public final class DownloadManager {
@IntDef({ @IntDef({
START_THREAD_SUCCEEDED, START_THREAD_SUCCEEDED,
START_THREAD_WAIT_REMOVAL_TO_FINISH, START_THREAD_WAIT_REMOVAL_TO_FINISH,
START_THREAD_WAIT_DOWNLOAD_CANCELATION, START_THREAD_WAIT_DOWNLOAD_CANCELLATION,
START_THREAD_TOO_MANY_DOWNLOADS START_THREAD_TOO_MANY_DOWNLOADS,
START_THREAD_NOT_ALLOWED
}) })
private @interface StartThreadResults {} private @interface StartThreadResults {}
private static final int START_THREAD_SUCCEEDED = 0; private static final int START_THREAD_SUCCEEDED = 0;
private static final int START_THREAD_WAIT_REMOVAL_TO_FINISH = 1; private static final int START_THREAD_WAIT_REMOVAL_TO_FINISH = 1;
private static final int START_THREAD_WAIT_DOWNLOAD_CANCELATION = 2; private static final int START_THREAD_WAIT_DOWNLOAD_CANCELLATION = 2;
private static final int START_THREAD_TOO_MANY_DOWNLOADS = 3; private static final int START_THREAD_TOO_MANY_DOWNLOADS = 3;
private static final int START_THREAD_NOT_ALLOWED = 4;
private static final String TAG = "DownloadManager"; private static final String TAG = "DownloadManager";
private static final boolean DEBUG = false; private static final boolean DEBUG = false;
...@@ -137,8 +138,9 @@ public final class DownloadManager { ...@@ -137,8 +138,9 @@ public final class DownloadManager {
private boolean initialized; private boolean initialized;
private boolean released; private boolean released;
@DownloadState.StopFlags private int stickyStopFlags; @DownloadState.StopFlags private int stopFlags;
@Requirements.RequirementFlags private int notMetRequirements; @Requirements.RequirementFlags private int notMetRequirements;
private int manualStopReason;
private RequirementsWatcher requirementsWatcher; private RequirementsWatcher requirementsWatcher;
private int simultaneousDownloads; private int simultaneousDownloads;
...@@ -181,8 +183,8 @@ public final class DownloadManager { ...@@ -181,8 +183,8 @@ public final class DownloadManager {
this.downloaderFactory = downloaderFactory; this.downloaderFactory = downloaderFactory;
this.maxSimultaneousDownloads = maxSimultaneousDownloads; this.maxSimultaneousDownloads = maxSimultaneousDownloads;
this.minRetryCount = minRetryCount; this.minRetryCount = minRetryCount;
this.stickyStopFlags = STOP_FLAG_STOPPED | STOP_FLAG_DOWNLOAD_MANAGER_NOT_READY;
stopFlags = STOP_FLAG_MANUAL;
downloads = new ArrayList<>(); downloads = new ArrayList<>();
activeDownloads = new HashMap<>(); activeDownloads = new HashMap<>();
...@@ -199,7 +201,7 @@ public final class DownloadManager { ...@@ -199,7 +201,7 @@ public final class DownloadManager {
listeners = new CopyOnWriteArraySet<>(); listeners = new CopyOnWriteArraySet<>();
actionQueue = new ArrayDeque<>(); actionQueue = new ArrayDeque<>();
watchRequirements(requirements); setNotMetRequirements(watchRequirements(requirements));
loadActions(); loadActions();
logd("Created"); logd("Created");
} }
...@@ -241,33 +243,35 @@ public final class DownloadManager { ...@@ -241,33 +243,35 @@ public final class DownloadManager {
listeners.remove(listener); listeners.remove(listener);
} }
/** Starts the downloads. */ /**
* Clears {@link DownloadState#STOP_FLAG_MANUAL} flag of all downloads. Downloads are started if
* the requirements are met.
*/
public void startDownloads() { public void startDownloads() {
clearStopFlags(STOP_FLAG_STOPPED); logd("manual stopped is cancelled");
} manualStopReason = 0;
stopFlags &= ~STOP_FLAG_MANUAL;
/** Stops all of the downloads. Call {@link #startDownloads()} to restart downloads. */ for (int i = 0; i < downloads.size(); i++) {
public void stopDownloads() { downloads.get(i).clearManualStopReason();
setStopFlags(STOP_FLAG_STOPPED);
} }
private void setStopFlags(int flags) {
updateStopFlags(flags, flags);
} }
private void clearStopFlags(int flags) { /** Signals all downloads to stop. Call {@link #startDownloads()} to let them to be started. */
updateStopFlags(flags, 0); public void stopDownloads() {
stopDownloads(0);
} }
private void updateStopFlags(int flags, int values) { /**
Assertions.checkState(!released); * Signals all downloads to stop. Call {@link #startDownloads()} to let them to be started.
int updatedStickyStopFlags = (values & flags) | (stickyStopFlags & ~flags); *
if (stickyStopFlags != updatedStickyStopFlags) { * @param manualStopReason An application defined stop reason.
stickyStopFlags = updatedStickyStopFlags; */
public void stopDownloads(int manualStopReason) {
logd("downloads are stopped manually");
this.manualStopReason = manualStopReason;
stopFlags |= STOP_FLAG_MANUAL;
for (int i = 0; i < downloads.size(); i++) { for (int i = 0; i < downloads.size(); i++) {
downloads.get(i).updateStopFlags(flags, values); downloads.get(i).setManualStopReason(this.manualStopReason);
}
logdFlags("Sticky stop flags are updated", updatedStickyStopFlags);
} }
} }
...@@ -341,8 +345,8 @@ public final class DownloadManager { ...@@ -341,8 +345,8 @@ public final class DownloadManager {
if (released) { if (released) {
return; return;
} }
setStopFlags(STOP_FLAG_DOWNLOAD_MANAGER_NOT_READY);
released = true; released = true;
stopAllDownloadThreads();
if (requirementsWatcher != null) { if (requirementsWatcher != null) {
requirementsWatcher.stop(); requirementsWatcher.stop();
} }
...@@ -361,7 +365,7 @@ public final class DownloadManager { ...@@ -361,7 +365,7 @@ public final class DownloadManager {
return; return;
} }
} }
Download download = new Download(this, action, stickyStopFlags, notMetRequirements); Download download = new Download(this, action, stopFlags, notMetRequirements, manualStopReason);
downloads.add(download); downloads.add(download);
logd("Download is added", download); logd("Download is added", download);
} }
...@@ -396,17 +400,26 @@ public final class DownloadManager { ...@@ -396,17 +400,26 @@ public final class DownloadManager {
} }
private void onRequirementsStateChanged(@Requirements.RequirementFlags int notMetRequirements) { private void onRequirementsStateChanged(@Requirements.RequirementFlags int notMetRequirements) {
this.notMetRequirements = notMetRequirements; setNotMetRequirements(notMetRequirements);
logdFlags("Not met requirements are changed", notMetRequirements); logdFlags("Not met requirements are changed", notMetRequirements);
Requirements requirements = requirementsWatcher.getRequirements();
for (Listener listener : listeners) { for (Listener listener : listeners) {
listener.onRequirementsStateChanged( listener.onRequirementsStateChanged(DownloadManager.this, requirements, notMetRequirements);
DownloadManager.this, requirementsWatcher.getRequirements(), notMetRequirements);
} }
for (int i = 0; i < downloads.size(); i++) { for (int i = 0; i < downloads.size(); i++) {
downloads.get(i).setNotMetRequirements(notMetRequirements); downloads.get(i).setNotMetRequirements(notMetRequirements);
} }
} }
private void setNotMetRequirements(@Requirements.RequirementFlags int notMetRequirements) {
this.notMetRequirements = notMetRequirements;
if (notMetRequirements == 0) {
stopFlags &= ~STOP_FLAG_REQUIREMENTS_NOT_MET;
} else {
stopFlags |= STOP_FLAG_REQUIREMENTS_NOT_MET;
}
}
private void loadActions() { private void loadActions() {
fileIOHandler.post( fileIOHandler.post(
() -> { () -> {
...@@ -438,7 +451,9 @@ public final class DownloadManager { ...@@ -438,7 +451,9 @@ public final class DownloadManager {
for (Listener listener : listeners) { for (Listener listener : listeners) {
listener.onInitialized(DownloadManager.this); listener.onInitialized(DownloadManager.this);
} }
clearStopFlags(STOP_FLAG_DOWNLOAD_MANAGER_NOT_READY); for (int i = 0; i < downloads.size(); i++) {
downloads.get(i).start();
}
}); });
}); });
} }
...@@ -497,9 +512,12 @@ public final class DownloadManager { ...@@ -497,9 +512,12 @@ public final class DownloadManager {
@StartThreadResults @StartThreadResults
private int startDownloadThread(Download download, DownloadAction action) { private int startDownloadThread(Download download, DownloadAction action) {
if (!initialized || released) {
return START_THREAD_NOT_ALLOWED;
}
if (activeDownloads.containsKey(download)) { if (activeDownloads.containsKey(download)) {
if (stopDownloadThread(download)) { if (stopDownloadThread(download)) {
return START_THREAD_WAIT_DOWNLOAD_CANCELATION; return START_THREAD_WAIT_DOWNLOAD_CANCELLATION;
} }
return START_THREAD_WAIT_REMOVAL_TO_FINISH; return START_THREAD_WAIT_REMOVAL_TO_FINISH;
} }
...@@ -526,6 +544,12 @@ public final class DownloadManager { ...@@ -526,6 +544,12 @@ public final class DownloadManager {
return false; return false;
} }
private void stopAllDownloadThreads() {
for (Download download : activeDownloads.keySet()) {
stopDownloadThread(download);
}
}
private void onDownloadThreadStopped(DownloadThread downloadThread, Throwable finalError) { private void onDownloadThreadStopped(DownloadThread downloadThread, Throwable finalError) {
Download download = downloadThread.download; Download download = downloadThread.download;
logd("Download is stopped", download); logd("Download is stopped", download);
...@@ -567,18 +591,18 @@ public final class DownloadManager { ...@@ -567,18 +591,18 @@ public final class DownloadManager {
@MonotonicNonNull @DownloadState.FailureReason private int failureReason; @MonotonicNonNull @DownloadState.FailureReason private int failureReason;
@DownloadState.StopFlags private int stopFlags; @DownloadState.StopFlags private int stopFlags;
@Requirements.RequirementFlags private int notMetRequirements; @Requirements.RequirementFlags private int notMetRequirements;
private int manualStopReason;
private Download( private Download(
DownloadManager downloadManager, DownloadManager downloadManager,
DownloadAction action, DownloadAction action,
@DownloadState.StopFlags int stopFlags, @DownloadState.StopFlags int stopFlags,
@Requirements.RequirementFlags int notMetRequirements) { @Requirements.RequirementFlags int notMetRequirements,
int manualStopReason) {
this.id = action.id; this.id = action.id;
this.downloadManager = downloadManager; this.downloadManager = downloadManager;
this.notMetRequirements = notMetRequirements; this.notMetRequirements = notMetRequirements;
if (notMetRequirements != 0) { this.manualStopReason = manualStopReason;
stopFlags |= STOP_FLAG_REQUIREMENTS_NOT_MET;
}
this.stopFlags = stopFlags; this.stopFlags = stopFlags;
this.startTimeMs = System.currentTimeMillis(); this.startTimeMs = System.currentTimeMillis();
actionQueue = new ArrayDeque<>(); actionQueue = new ArrayDeque<>();
...@@ -642,6 +666,7 @@ public final class DownloadManager { ...@@ -642,6 +666,7 @@ public final class DownloadManager {
failureReason, failureReason,
stopFlags, stopFlags,
notMetRequirements, notMetRequirements,
manualStopReason,
startTimeMs, startTimeMs,
/* updateTimeMs= */ System.currentTimeMillis(), /* updateTimeMs= */ System.currentTimeMillis(),
action.keys.toArray(new StreamKey[0]), action.keys.toArray(new StreamKey[0]),
...@@ -662,21 +687,34 @@ public final class DownloadManager { ...@@ -662,21 +687,34 @@ public final class DownloadManager {
} }
public void start() { public void start() {
if (state == STATE_QUEUED) { if (state == STATE_QUEUED || state == STATE_DOWNLOADING) {
startOrQueue(); startOrQueue();
} else if (state == STATE_REMOVING || state == STATE_RESTARTING) {
downloadManager.startDownloadThread(this, actionQueue.peek());
} }
} }
public void setStopFlags(int flags) { public void setNotMetRequirements(@Requirements.RequirementFlags int notMetRequirements) {
updateStopFlags(flags, flags); this.notMetRequirements = notMetRequirements;
updateStopFlags(STOP_FLAG_REQUIREMENTS_NOT_MET, /* setFlags= */ notMetRequirements != 0);
}
public void setManualStopReason(int manualStopReason) {
this.manualStopReason = manualStopReason;
updateStopFlags(STOP_FLAG_MANUAL, /* setFlags= */ true);
} }
public void clearStopFlags(int flags) { public void clearManualStopReason() {
updateStopFlags(flags, 0); this.manualStopReason = 0;
updateStopFlags(STOP_FLAG_MANUAL, /* setFlags= */ false);
} }
public void updateStopFlags(int flags, int values) { private void updateStopFlags(int flags, boolean setFlags) {
stopFlags = (values & flags) | (stopFlags & ~flags); if (setFlags) {
stopFlags |= flags;
} else {
stopFlags &= ~flags;
}
if (stopFlags != 0) { if (stopFlags != 0) {
if (state == STATE_DOWNLOADING || state == STATE_QUEUED) { if (state == STATE_DOWNLOADING || state == STATE_QUEUED) {
downloadManager.stopDownloadThread(this); downloadManager.stopDownloadThread(this);
...@@ -687,21 +725,14 @@ public final class DownloadManager { ...@@ -687,21 +725,14 @@ public final class DownloadManager {
} }
} }
public void setNotMetRequirements(@Requirements.RequirementFlags int notMetRequirements) {
this.notMetRequirements = notMetRequirements;
updateStopFlags(
STOP_FLAG_REQUIREMENTS_NOT_MET,
notMetRequirements != 0 ? STOP_FLAG_REQUIREMENTS_NOT_MET : 0);
}
private void initialize() { private void initialize() {
DownloadAction action = actionQueue.peek(); DownloadAction action = actionQueue.peek();
if (action.isRemoveAction) { if (action.isRemoveAction) {
if (!downloadManager.released) {
int result = downloadManager.startDownloadThread(this, action); int result = downloadManager.startDownloadThread(this, action);
Assertions.checkState( Assertions.checkState(
result == START_THREAD_SUCCEEDED || result == START_THREAD_WAIT_DOWNLOAD_CANCELATION); result == START_THREAD_SUCCEEDED
} || result == START_THREAD_WAIT_DOWNLOAD_CANCELLATION
|| result == START_THREAD_NOT_ALLOWED);
setState(actionQueue.size() == 1 ? STATE_REMOVING : STATE_RESTARTING); setState(actionQueue.size() == 1 ? STATE_REMOVING : STATE_RESTARTING);
} else if (stopFlags != 0) { } else if (stopFlags != 0) {
setState(STATE_STOPPED); setState(STATE_STOPPED);
...@@ -715,10 +746,10 @@ public final class DownloadManager { ...@@ -715,10 +746,10 @@ public final class DownloadManager {
Assertions.checkState(!action.isRemoveAction); Assertions.checkState(!action.isRemoveAction);
@StartThreadResults int result = downloadManager.startDownloadThread(this, action); @StartThreadResults int result = downloadManager.startDownloadThread(this, action);
Assertions.checkState(result != START_THREAD_WAIT_REMOVAL_TO_FINISH); Assertions.checkState(result != START_THREAD_WAIT_REMOVAL_TO_FINISH);
if (result == START_THREAD_TOO_MANY_DOWNLOADS) { if (result == START_THREAD_SUCCEEDED || result == START_THREAD_WAIT_DOWNLOAD_CANCELLATION) {
setState(STATE_QUEUED);
} else {
setState(STATE_DOWNLOADING); setState(STATE_DOWNLOADING);
} else {
setState(STATE_QUEUED);
} }
} }
......
...@@ -20,6 +20,7 @@ import android.support.annotation.IntDef; ...@@ -20,6 +20,7 @@ import android.support.annotation.IntDef;
import android.support.annotation.Nullable; import android.support.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.util.Assertions; 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;
...@@ -76,25 +77,19 @@ public final class DownloadState { ...@@ -76,25 +77,19 @@ public final class DownloadState {
public static final int FAILURE_REASON_UNKNOWN = 1; public static final int FAILURE_REASON_UNKNOWN = 1;
/** /**
* Download stop flags. Possible flag values are {@link #STOP_FLAG_DOWNLOAD_MANAGER_NOT_READY} and * Download stop flags. Possible flag values are {@link #STOP_FLAG_MANUAL} and {@link
* {@link #STOP_FLAG_STOPPED}. * #STOP_FLAG_REQUIREMENTS_NOT_MET}.
*/ */
@Documented @Documented
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@IntDef( @IntDef(
flag = true, flag = true,
value = { value = {STOP_FLAG_MANUAL, STOP_FLAG_REQUIREMENTS_NOT_MET})
STOP_FLAG_DOWNLOAD_MANAGER_NOT_READY,
STOP_FLAG_STOPPED,
STOP_FLAG_REQUIREMENTS_NOT_MET
})
public @interface StopFlags {} public @interface StopFlags {}
/** Download can't be started as the manager isn't ready. */
public static final int STOP_FLAG_DOWNLOAD_MANAGER_NOT_READY = 1;
/** Download is stopped by the application. */ /** Download is stopped by the application. */
public static final int STOP_FLAG_STOPPED = 1 << 1; public static final int STOP_FLAG_MANUAL = 1;
/** Download is stopped as the requirements are not met. */ /** Download is stopped as the requirements are not met. */
public static final int STOP_FLAG_REQUIREMENTS_NOT_MET = 1 << 2; public static final int STOP_FLAG_REQUIREMENTS_NOT_MET = 1 << 1;
/** Returns the state string for the given state value. */ /** Returns the state string for the given state value. */
public static String getStateString(@State int state) { public static String getStateString(@State int state) {
...@@ -165,6 +160,8 @@ public final class DownloadState { ...@@ -165,6 +160,8 @@ public final class DownloadState {
@StopFlags public final int stopFlags; @StopFlags public final int stopFlags;
/** Not met requirements to download. */ /** Not met requirements to download. */
@Requirements.RequirementFlags public final int notMetRequirements; @Requirements.RequirementFlags public final int notMetRequirements;
/** If {@link #STOP_FLAG_MANUAL} is set then this field holds the manual stop reason. */
public final int manualStopReason;
/** /**
* Creates a {@link DownloadState} using a {@link DownloadAction}. * Creates a {@link DownloadState} using a {@link DownloadAction}.
...@@ -188,6 +185,7 @@ public final class DownloadState { ...@@ -188,6 +185,7 @@ public final class DownloadState {
FAILURE_REASON_NONE, FAILURE_REASON_NONE,
/* stopFlags= */ 0, /* stopFlags= */ 0,
/* notMetRequirements= */ 0, /* notMetRequirements= */ 0,
/* manualStopReason= */ 0,
/* startTimeMs= */ currentTimeMs, /* startTimeMs= */ currentTimeMs,
/* updateTimeMs= */ currentTimeMs, /* updateTimeMs= */ currentTimeMs,
action.keys.toArray(new StreamKey[0]), action.keys.toArray(new StreamKey[0]),
...@@ -205,18 +203,17 @@ public final class DownloadState { ...@@ -205,18 +203,17 @@ public final class DownloadState {
long totalBytes, long totalBytes,
@FailureReason int failureReason, @FailureReason int failureReason,
@StopFlags int stopFlags, @StopFlags int stopFlags,
@Requirements.RequirementFlags int notMetRequirements, @RequirementFlags int notMetRequirements,
int manualStopReason,
long startTimeMs, long startTimeMs,
long updateTimeMs, long updateTimeMs,
StreamKey[] streamKeys, StreamKey[] streamKeys,
byte[] customMetadata) { byte[] customMetadata) {
Assertions.checkState( Assertions.checkState((failureReason == FAILURE_REASON_NONE) == (state != STATE_FAILED));
failureReason == FAILURE_REASON_NONE ? state != STATE_FAILED : state == STATE_FAILED);
Assertions.checkState(stopFlags == 0 || (state != STATE_DOWNLOADING && state != STATE_QUEUED)); Assertions.checkState(stopFlags == 0 || (state != STATE_DOWNLOADING && state != STATE_QUEUED));
Assertions.checkState( Assertions.checkState(
(stopFlags & STOP_FLAG_REQUIREMENTS_NOT_MET) == 0 ((stopFlags & STOP_FLAG_REQUIREMENTS_NOT_MET) == 0) == (notMetRequirements == 0));
? notMetRequirements == 0 Assertions.checkState(((stopFlags & STOP_FLAG_MANUAL) != 0) || (manualStopReason == 0));
: notMetRequirements != 0);
this.id = id; this.id = id;
this.type = type; this.type = type;
this.uri = uri; this.uri = uri;
...@@ -228,6 +225,7 @@ public final class DownloadState { ...@@ -228,6 +225,7 @@ public final class DownloadState {
this.failureReason = failureReason; this.failureReason = failureReason;
this.stopFlags = stopFlags; this.stopFlags = stopFlags;
this.notMetRequirements = notMetRequirements; this.notMetRequirements = notMetRequirements;
this.manualStopReason = manualStopReason;
this.startTimeMs = startTimeMs; this.startTimeMs = startTimeMs;
this.updateTimeMs = updateTimeMs; this.updateTimeMs = updateTimeMs;
this.streamKeys = streamKeys; this.streamKeys = streamKeys;
...@@ -256,6 +254,7 @@ public final class DownloadState { ...@@ -256,6 +254,7 @@ public final class DownloadState {
FAILURE_REASON_NONE, FAILURE_REASON_NONE,
stopFlags, stopFlags,
notMetRequirements, notMetRequirements,
manualStopReason,
startTimeMs, startTimeMs,
updateTimeMs, updateTimeMs,
mergeStreamKeys(this, action), mergeStreamKeys(this, action),
......
...@@ -77,8 +77,10 @@ public class DefaultDownloadIndexTest { ...@@ -77,8 +77,10 @@ public class DefaultDownloadIndexTest {
.setDownloadedBytes(200) .setDownloadedBytes(200)
.setTotalBytes(400) .setTotalBytes(400)
.setFailureReason(DownloadState.FAILURE_REASON_UNKNOWN) .setFailureReason(DownloadState.FAILURE_REASON_UNKNOWN)
.setStopFlags(DownloadState.STOP_FLAG_REQUIREMENTS_NOT_MET) .setStopFlags(
DownloadState.STOP_FLAG_REQUIREMENTS_NOT_MET | DownloadState.STOP_FLAG_MANUAL)
.setNotMetRequirements(0x87654321) .setNotMetRequirements(0x87654321)
.setManualStopReason(0x12345678)
.setStartTimeMs(10) .setStartTimeMs(10)
.setUpdateTimeMs(20) .setUpdateTimeMs(20)
.setStreamKeys( .setStreamKeys(
...@@ -206,5 +208,4 @@ public class DefaultDownloadIndexTest { ...@@ -206,5 +208,4 @@ public class DefaultDownloadIndexTest {
assertThat(VersionTable.getVersion(writableDatabase, VersionTable.FEATURE_OFFLINE)) assertThat(VersionTable.getVersion(writableDatabase, VersionTable.FEATURE_OFFLINE))
.isEqualTo(DefaultDownloadIndex.TABLE_VERSION); .isEqualTo(DefaultDownloadIndex.TABLE_VERSION);
} }
} }
...@@ -38,6 +38,7 @@ class DownloadStateBuilder { ...@@ -38,6 +38,7 @@ class DownloadStateBuilder {
private int failureReason; private int failureReason;
private int stopFlags; private int stopFlags;
private int notMetRequirements; private int notMetRequirements;
private int manualStopReason;
private long startTimeMs; private long startTimeMs;
private long updateTimeMs; private long updateTimeMs;
private StreamKey[] streamKeys; private StreamKey[] streamKeys;
...@@ -140,6 +141,11 @@ class DownloadStateBuilder { ...@@ -140,6 +141,11 @@ class DownloadStateBuilder {
return this; return this;
} }
public DownloadStateBuilder setManualStopReason(int manualStopReason) {
this.manualStopReason = manualStopReason;
return this;
}
public DownloadStateBuilder setStartTimeMs(long startTimeMs) { public DownloadStateBuilder setStartTimeMs(long startTimeMs) {
this.startTimeMs = startTimeMs; this.startTimeMs = startTimeMs;
return this; return this;
...@@ -173,6 +179,7 @@ class DownloadStateBuilder { ...@@ -173,6 +179,7 @@ class DownloadStateBuilder {
failureReason, failureReason,
stopFlags, stopFlags,
notMetRequirements, notMetRequirements,
manualStopReason,
startTimeMs, startTimeMs,
updateTimeMs, updateTimeMs,
streamKeys, streamKeys,
......
...@@ -171,7 +171,7 @@ public class DownloadStateTest { ...@@ -171,7 +171,7 @@ public class DownloadStateTest {
DownloadStateBuilder downloadStateBuilder = DownloadStateBuilder downloadStateBuilder =
new DownloadStateBuilder(downloadAction) new DownloadStateBuilder(downloadAction)
.setState(DownloadState.STATE_STOPPED) .setState(DownloadState.STATE_STOPPED)
.setStopFlags(DownloadState.STOP_FLAG_STOPPED); .setStopFlags(DownloadState.STOP_FLAG_MANUAL);
DownloadState downloadState = downloadStateBuilder.build(); DownloadState downloadState = downloadStateBuilder.build();
DownloadState mergedDownloadState = downloadState.mergeAction(downloadAction); DownloadState mergedDownloadState = downloadState.mergeAction(downloadAction);
...@@ -185,7 +185,7 @@ public class DownloadStateTest { ...@@ -185,7 +185,7 @@ public class DownloadStateTest {
DownloadStateBuilder downloadStateBuilder = DownloadStateBuilder downloadStateBuilder =
new DownloadStateBuilder(downloadAction) new DownloadStateBuilder(downloadAction)
.setState(DownloadState.STATE_STOPPED) .setState(DownloadState.STATE_STOPPED)
.setStopFlags(DownloadState.STOP_FLAG_STOPPED); .setStopFlags(DownloadState.STOP_FLAG_MANUAL);
DownloadState downloadState = downloadStateBuilder.build(); DownloadState downloadState = downloadStateBuilder.build();
DownloadState mergedDownloadState = downloadState.mergeAction(downloadAction); DownloadState mergedDownloadState = downloadState.mergeAction(downloadAction);
......
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