mirror of
https://github.com/samsonjs/media.git
synced 2026-03-25 09:25:53 +00:00
Hide internal DownloadManager states
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=188481259
This commit is contained in:
parent
a58bffbe52
commit
e13789bfcc
3 changed files with 128 additions and 96 deletions
|
|
@ -16,12 +16,10 @@
|
|||
package com.google.android.exoplayer2.offline;
|
||||
|
||||
import static com.google.android.exoplayer2.offline.DownloadManager.DownloadState.STATE_CANCELED;
|
||||
import static com.google.android.exoplayer2.offline.DownloadManager.DownloadState.STATE_CANCELING;
|
||||
import static com.google.android.exoplayer2.offline.DownloadManager.DownloadState.STATE_ENDED;
|
||||
import static com.google.android.exoplayer2.offline.DownloadManager.DownloadState.STATE_ERROR;
|
||||
import static com.google.android.exoplayer2.offline.DownloadManager.DownloadState.STATE_QUEUED;
|
||||
import static com.google.android.exoplayer2.offline.DownloadManager.DownloadState.STATE_STARTED;
|
||||
import static com.google.android.exoplayer2.offline.DownloadManager.DownloadState.STATE_STOPPING;
|
||||
import static com.google.android.exoplayer2.offline.DownloadManager.DownloadState.STATE_WAITING;
|
||||
|
||||
import android.os.ConditionVariable;
|
||||
import android.os.Handler;
|
||||
|
|
@ -31,7 +29,6 @@ import android.support.annotation.IntDef;
|
|||
import android.util.Log;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.offline.DownloadAction.Deserializer;
|
||||
import com.google.android.exoplayer2.offline.DownloadManager.DownloadState.State;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
|
@ -264,7 +261,7 @@ public final class DownloadManager {
|
|||
return false;
|
||||
}
|
||||
for (int i = 0; i < tasks.size(); i++) {
|
||||
if (tasks.get(i).isRunning()) {
|
||||
if (tasks.get(i).isActive()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -344,7 +341,7 @@ public final class DownloadManager {
|
|||
return;
|
||||
}
|
||||
logd("Task state is changed", downloadTask);
|
||||
boolean stopped = !downloadTask.isRunning();
|
||||
boolean stopped = !downloadTask.isActive();
|
||||
if (stopped) {
|
||||
activeDownloadTasks.remove(downloadTask);
|
||||
}
|
||||
|
|
@ -446,62 +443,39 @@ public final class DownloadManager {
|
|||
/**
|
||||
* Task states.
|
||||
*
|
||||
* <p>Transition map (vertical states are source states):
|
||||
* <p>Transition diagram:
|
||||
*
|
||||
* <pre>
|
||||
* +-------+-------+-----+---------+--------+--------+-----+
|
||||
* |waiting|started|ended|canceling|canceled|stopping|error|
|
||||
* +---------+-------+-------+-----+---------+--------+--------+-----+
|
||||
* |waiting | | X | | X | | | |
|
||||
* |started | | | X | X | | X | X |
|
||||
* |canceling| | | | | X | | |
|
||||
* |stopping | X | | | | | | |
|
||||
* +---------+-------+-------+-----+---------+--------+--------+-----+
|
||||
* -> canceled
|
||||
* queued <-> started -> ended
|
||||
* -> error
|
||||
* </pre>
|
||||
*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({STATE_WAITING, STATE_STARTED, STATE_ENDED, STATE_CANCELING, STATE_CANCELED,
|
||||
STATE_STOPPING, STATE_ERROR})
|
||||
@IntDef({STATE_QUEUED, STATE_STARTED, STATE_ENDED, STATE_CANCELED, STATE_ERROR})
|
||||
public @interface State {}
|
||||
/** The task is waiting to be started. */
|
||||
public static final int STATE_WAITING = 0;
|
||||
public static final int STATE_QUEUED = 0;
|
||||
/** The task is currently started. */
|
||||
public static final int STATE_STARTED = 1;
|
||||
/** The task completed. */
|
||||
public static final int STATE_ENDED = 2;
|
||||
/** The task is about to be canceled. */
|
||||
public static final int STATE_CANCELING = 3;
|
||||
/** The task was canceled. */
|
||||
public static final int STATE_CANCELED = 4;
|
||||
/** The task is about to be stopped. */
|
||||
public static final int STATE_STOPPING = 5;
|
||||
public static final int STATE_CANCELED = 3;
|
||||
/** The task failed. */
|
||||
public static final int STATE_ERROR = 6;
|
||||
|
||||
/** Returns whether the task is running. */
|
||||
public static boolean isRunning(int state) {
|
||||
return state == STATE_STARTED || state == STATE_STOPPING || state == STATE_CANCELING;
|
||||
}
|
||||
|
||||
/** Returns whether the task is finished. */
|
||||
public static boolean isFinished(int state) {
|
||||
return state == STATE_ERROR || state == STATE_ENDED || state == STATE_CANCELED;
|
||||
}
|
||||
public static final int STATE_ERROR = 4;
|
||||
|
||||
/** Returns the state string for the given state value. */
|
||||
public static String getStateString(@State int state) {
|
||||
switch (state) {
|
||||
case STATE_WAITING:
|
||||
return "WAITING";
|
||||
case STATE_QUEUED:
|
||||
return "QUEUED";
|
||||
case STATE_STARTED:
|
||||
return "STARTED";
|
||||
case STATE_ENDED:
|
||||
return "ENDED";
|
||||
case STATE_CANCELING:
|
||||
return "CANCELING";
|
||||
case STATE_CANCELED:
|
||||
return "CANCELED";
|
||||
case STATE_STOPPING:
|
||||
return "STOPPING";
|
||||
case STATE_ERROR:
|
||||
return "ERROR";
|
||||
default:
|
||||
|
|
@ -531,7 +505,7 @@ public final class DownloadManager {
|
|||
private DownloadState(
|
||||
int taskId,
|
||||
DownloadAction downloadAction,
|
||||
int state,
|
||||
@State int state,
|
||||
float downloadPercentage,
|
||||
long downloadedBytes,
|
||||
Throwable error) {
|
||||
|
|
@ -543,24 +517,51 @@ public final class DownloadManager {
|
|||
this.error = error;
|
||||
}
|
||||
|
||||
/** Returns whether the task is finished. */
|
||||
public boolean isFinished() {
|
||||
return isFinished(state);
|
||||
}
|
||||
|
||||
/** Returns whether the task is running. */
|
||||
public boolean isRunning() {
|
||||
return isRunning(state);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class DownloadTask implements Runnable {
|
||||
|
||||
/**
|
||||
* Task states.
|
||||
*
|
||||
* <p>Transition map (vertical states are source states):
|
||||
*
|
||||
* <pre>
|
||||
* +------+-------+-----+-----------+-----------+--------+--------+-----+
|
||||
* |queued|started|ended|q_canceling|s_canceling|canceled|stopping|error|
|
||||
* +-----------+------+-------+-----+-----------+-----------+--------+--------+-----+
|
||||
* |queued | | X | | X | | | | |
|
||||
* |started | | | X | | X | | X | X |
|
||||
* |q_canceling| | | | | | X | | |
|
||||
* |s_canceling| | | | | | X | | |
|
||||
* |stopping | X | | | | | | | |
|
||||
* +-----------+------+-------+-----+-----------+-----------+--------+--------+-----+
|
||||
* </pre>
|
||||
*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({
|
||||
STATE_QUEUED,
|
||||
STATE_STARTED,
|
||||
STATE_ENDED,
|
||||
STATE_CANCELED,
|
||||
STATE_ERROR,
|
||||
STATE_QUEUED_CANCELING,
|
||||
STATE_STARTED_CANCELING,
|
||||
STATE_STARTED_STOPPING
|
||||
})
|
||||
public @interface InternalState {}
|
||||
/** The task is about to be canceled. */
|
||||
public static final int STATE_QUEUED_CANCELING = 5;
|
||||
/** The task is about to be canceled. */
|
||||
public static final int STATE_STARTED_CANCELING = 6;
|
||||
/** The task is about to be stopped. */
|
||||
public static final int STATE_STARTED_STOPPING = 7;
|
||||
|
||||
private final int id;
|
||||
private final DownloadManager downloadManager;
|
||||
private final DownloadAction downloadAction;
|
||||
private final int minRetryCount;
|
||||
private volatile @State int currentState;
|
||||
private volatile @InternalState int currentState;
|
||||
private volatile Downloader downloader;
|
||||
private Thread thread;
|
||||
private Throwable error;
|
||||
|
|
@ -570,28 +571,29 @@ public final class DownloadManager {
|
|||
this.id = id;
|
||||
this.downloadManager = downloadManager;
|
||||
this.downloadAction = downloadAction;
|
||||
this.currentState = STATE_WAITING;
|
||||
this.currentState = STATE_QUEUED;
|
||||
this.minRetryCount = minRetryCount;
|
||||
}
|
||||
|
||||
public DownloadState getDownloadState() {
|
||||
int externalState = getExternalState();
|
||||
return new DownloadState(
|
||||
id, downloadAction, currentState, getDownloadPercentage(), getDownloadedBytes(), error);
|
||||
}
|
||||
|
||||
/** Returns the state of the task. */
|
||||
public @State int getState() {
|
||||
return currentState;
|
||||
id, downloadAction, externalState, getDownloadPercentage(), getDownloadedBytes(), error);
|
||||
}
|
||||
|
||||
/** Returns whether the task is finished. */
|
||||
public boolean isFinished() {
|
||||
return DownloadState.isFinished(currentState);
|
||||
return currentState == STATE_ERROR
|
||||
|| currentState == STATE_ENDED
|
||||
|| currentState == STATE_CANCELED;
|
||||
}
|
||||
|
||||
/** Returns whether the task is running. */
|
||||
public boolean isRunning() {
|
||||
return DownloadState.isRunning(currentState);
|
||||
/** Returns whether the task is started. */
|
||||
public boolean isActive() {
|
||||
return currentState == STATE_QUEUED_CANCELING
|
||||
|| currentState == STATE_STARTED
|
||||
|| currentState == STATE_STARTED_STOPPING
|
||||
|| currentState == STATE_STARTED_CANCELING;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -621,52 +623,80 @@ public final class DownloadManager {
|
|||
+ ' '
|
||||
+ downloadAction.getData()
|
||||
+ ' '
|
||||
+ DownloadState.getStateString(currentState);
|
||||
+ getStateString();
|
||||
}
|
||||
|
||||
private String getStateString() {
|
||||
switch (currentState) {
|
||||
case STATE_QUEUED_CANCELING:
|
||||
case STATE_STARTED_CANCELING:
|
||||
return "CANCELING";
|
||||
case STATE_STARTED_STOPPING:
|
||||
return "STOPPING";
|
||||
default:
|
||||
return DownloadState.getStateString(currentState);
|
||||
}
|
||||
}
|
||||
|
||||
private int getExternalState() {
|
||||
switch (currentState) {
|
||||
case STATE_QUEUED_CANCELING:
|
||||
return STATE_QUEUED;
|
||||
case STATE_STARTED_CANCELING:
|
||||
case STATE_STARTED_STOPPING:
|
||||
return STATE_STARTED;
|
||||
default:
|
||||
return currentState;
|
||||
}
|
||||
}
|
||||
|
||||
private void start() {
|
||||
if (changeStateAndNotify(STATE_WAITING, STATE_STARTED)) {
|
||||
if (changeStateAndNotify(STATE_QUEUED, STATE_STARTED)) {
|
||||
thread = new Thread(this);
|
||||
thread.start();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canStart() {
|
||||
return currentState == STATE_WAITING;
|
||||
return currentState == STATE_QUEUED;
|
||||
}
|
||||
|
||||
private void cancel() {
|
||||
if (changeStateAndNotify(STATE_WAITING, STATE_CANCELING)) {
|
||||
downloadManager.handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
changeStateAndNotify(STATE_CANCELING, STATE_CANCELED);
|
||||
}
|
||||
});
|
||||
} else if (changeStateAndNotify(STATE_STARTED, STATE_CANCELING)) {
|
||||
if (changeStateAndNotify(STATE_QUEUED, STATE_QUEUED_CANCELING)) {
|
||||
downloadManager.handler.post(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
changeStateAndNotify(STATE_QUEUED_CANCELING, STATE_CANCELED);
|
||||
}
|
||||
});
|
||||
} else if (changeStateAndNotify(STATE_STARTED, STATE_STARTED_CANCELING)) {
|
||||
thread.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
private void stop() {
|
||||
if (changeStateAndNotify(STATE_STARTED, STATE_STOPPING)) {
|
||||
if (changeStateAndNotify(STATE_STARTED, STATE_STARTED_STOPPING)) {
|
||||
downloadManager.logd("Stopping", this);
|
||||
thread.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean changeStateAndNotify(@State int oldState, @State int newState) {
|
||||
private boolean changeStateAndNotify(@InternalState int oldState, @InternalState int newState) {
|
||||
return changeStateAndNotify(oldState, newState, null);
|
||||
}
|
||||
|
||||
private boolean changeStateAndNotify(@State int oldState, @State int newState,
|
||||
Throwable error) {
|
||||
private boolean changeStateAndNotify(
|
||||
@InternalState int oldState, @InternalState int newState, Throwable error) {
|
||||
if (currentState != oldState) {
|
||||
return false;
|
||||
}
|
||||
currentState = newState;
|
||||
this.error = error;
|
||||
downloadManager.onTaskStateChange(DownloadTask.this);
|
||||
boolean isInternalState = currentState != getExternalState();
|
||||
if (!isInternalState) {
|
||||
downloadManager.onTaskStateChange(DownloadTask.this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -707,18 +737,19 @@ public final class DownloadManager {
|
|||
error = e;
|
||||
}
|
||||
final Throwable finalError = error;
|
||||
downloadManager.handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (changeStateAndNotify(STATE_STARTED,
|
||||
finalError != null ? STATE_ERROR : STATE_ENDED, finalError)
|
||||
|| changeStateAndNotify(STATE_CANCELING, STATE_CANCELED)
|
||||
|| changeStateAndNotify(STATE_STOPPING, STATE_WAITING)) {
|
||||
return;
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
});
|
||||
downloadManager.handler.post(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (changeStateAndNotify(
|
||||
STATE_STARTED, finalError != null ? STATE_ERROR : STATE_ENDED, finalError)
|
||||
|| changeStateAndNotify(STATE_STARTED_CANCELING, STATE_CANCELED)
|
||||
|| changeStateAndNotify(STATE_STARTED_STOPPING, STATE_QUEUED)) {
|
||||
return;
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private int getRetryDelayMillis(int errorCount) {
|
||||
|
|
|
|||
|
|
@ -607,8 +607,7 @@ public class DownloadManagerTest {
|
|||
}
|
||||
|
||||
private FakeDownloadAction assertStopped() {
|
||||
assertState(DownloadState.STATE_STOPPING);
|
||||
return assertState(DownloadState.STATE_WAITING);
|
||||
return assertState(DownloadState.STATE_QUEUED);
|
||||
}
|
||||
|
||||
private FakeDownloadAction assertState(@State int expectedState) {
|
||||
|
|
|
|||
|
|
@ -67,12 +67,16 @@ public final class DownloadNotificationUtil {
|
|||
int titleStringId = getTitleStringId(downloadState);
|
||||
notificationBuilder.setContentTitle(context.getResources().getString(titleStringId));
|
||||
|
||||
if (downloadState.isRunning()) {
|
||||
if (downloadState.state == DownloadState.STATE_STARTED) {
|
||||
notificationBuilder.setOngoing(true);
|
||||
float percentage = downloadState.downloadPercentage;
|
||||
boolean indeterminate = Float.isNaN(percentage);
|
||||
notificationBuilder.setProgress(100, indeterminate ? 0 : (int) percentage, indeterminate);
|
||||
}
|
||||
if (Util.SDK_INT >= 17) {
|
||||
// Hide timestamp on the notification while download progresses.
|
||||
notificationBuilder.setShowWhen(downloadState.state != DownloadState.STATE_STARTED);
|
||||
}
|
||||
|
||||
if (downloadState.error != null && errorMessageProvider != null) {
|
||||
message = errorMessageProvider.getErrorMessage(downloadState.error).second;
|
||||
|
|
@ -90,12 +94,10 @@ public final class DownloadNotificationUtil {
|
|||
private static int getTitleStringId(DownloadState downloadState) {
|
||||
int titleStringId;
|
||||
switch (downloadState.state) {
|
||||
case DownloadState.STATE_WAITING:
|
||||
case DownloadState.STATE_QUEUED:
|
||||
titleStringId = R.string.exo_download_queued;
|
||||
break;
|
||||
case DownloadState.STATE_STARTED:
|
||||
case DownloadState.STATE_STOPPING:
|
||||
case DownloadState.STATE_CANCELING:
|
||||
titleStringId = R.string.exo_downloading;
|
||||
break;
|
||||
case DownloadState.STATE_ENDED:
|
||||
|
|
|
|||
Loading…
Reference in a new issue