Commit 56520b7c by olly Committed by Oliver Woodman

Move DownloadManager internal logic into isolated inner class

There are no logic changes here. It's just moving code around and removing
the "internal" part of names where no longer required.

PiperOrigin-RevId: 245407238
parent d187d9ec
...@@ -160,38 +160,21 @@ public final class DownloadManager { ...@@ -160,38 +160,21 @@ public final class DownloadManager {
private final Context context; private final Context context;
private final WritableDownloadIndex downloadIndex; private final WritableDownloadIndex downloadIndex;
private final DownloaderFactory downloaderFactory;
private final Handler mainHandler; private final Handler mainHandler;
private final HandlerThread internalThread; private final InternalHandler internalHandler;
private final Handler internalHandler;
private final RequirementsWatcher.Listener requirementsListener; private final RequirementsWatcher.Listener requirementsListener;
private final Object releaseLock;
// Collections that are accessed on the main thread.
private final CopyOnWriteArraySet<Listener> listeners; private final CopyOnWriteArraySet<Listener> listeners;
private final ArrayList<Download> downloads; private final ArrayList<Download> downloads;
// Collections that are accessed on the internal thread.
private final ArrayList<DownloadInternal> downloadInternals;
private final HashMap<String, DownloadThread> downloadThreads;
// Mutable fields that are accessed on the main thread.
private int pendingMessages; private int pendingMessages;
private int activeDownloadCount; private int activeDownloadCount;
private boolean initialized; private boolean initialized;
private boolean released;
private boolean downloadsPaused; private boolean downloadsPaused;
private int maxParallelDownloads; private int maxParallelDownloads;
private int minRetryCount; private int minRetryCount;
private RequirementsWatcher requirementsWatcher; private RequirementsWatcher requirementsWatcher;
// Mutable fields that are accessed on the internal thread.
@Requirements.RequirementFlags private int notMetRequirements;
private boolean downloadsPausedInternal;
private int maxParallelDownloadsInternal;
private int minRetryCountInternal;
private int parallelDownloads;
/** /**
* Constructs a {@link DownloadManager}. * Constructs a {@link DownloadManager}.
* *
...@@ -221,31 +204,29 @@ public final class DownloadManager { ...@@ -221,31 +204,29 @@ public final class DownloadManager {
Context context, WritableDownloadIndex downloadIndex, DownloaderFactory downloaderFactory) { Context context, WritableDownloadIndex downloadIndex, DownloaderFactory downloaderFactory) {
this.context = context.getApplicationContext(); this.context = context.getApplicationContext();
this.downloadIndex = downloadIndex; this.downloadIndex = downloadIndex;
this.downloaderFactory = downloaderFactory;
maxParallelDownloads = DEFAULT_MAX_PARALLEL_DOWNLOADS; maxParallelDownloads = DEFAULT_MAX_PARALLEL_DOWNLOADS;
maxParallelDownloadsInternal = DEFAULT_MAX_PARALLEL_DOWNLOADS;
minRetryCount = DEFAULT_MIN_RETRY_COUNT; minRetryCount = DEFAULT_MIN_RETRY_COUNT;
minRetryCountInternal = DEFAULT_MIN_RETRY_COUNT;
downloadsPaused = true; downloadsPaused = true;
downloadsPausedInternal = true;
downloadInternals = new ArrayList<>();
downloads = new ArrayList<>(); downloads = new ArrayList<>();
downloadThreads = new HashMap<>();
listeners = new CopyOnWriteArraySet<>(); listeners = new CopyOnWriteArraySet<>();
releaseLock = new Object();
requirementsListener = this::onRequirementsStateChanged; requirementsListener = this::onRequirementsStateChanged;
mainHandler = new Handler(Util.getLooper(), this::handleMainMessage);
internalThread = new HandlerThread("DownloadManager file i/o");
internalThread.start();
internalHandler = new Handler(internalThread.getLooper(), this::handleInternalMessage);
requirementsWatcher = requirementsWatcher =
new RequirementsWatcher(context, requirementsListener, DEFAULT_REQUIREMENTS); new RequirementsWatcher(context, requirementsListener, DEFAULT_REQUIREMENTS);
int notMetRequirements = requirementsWatcher.start(); int notMetRequirements = requirementsWatcher.start();
mainHandler = new Handler(Util.getLooper(), this::handleMainMessage);
HandlerThread internalThread = new HandlerThread("DownloadManager file i/o");
internalThread.start();
internalHandler =
new InternalHandler(
internalThread,
downloadIndex,
downloaderFactory,
mainHandler,
maxParallelDownloads,
minRetryCount,
downloadsPaused);
pendingMessages = 1; pendingMessages = 1;
internalHandler internalHandler
.obtainMessage(MSG_INITIALIZE, notMetRequirements, /* unused */ 0) .obtainMessage(MSG_INITIALIZE, notMetRequirements, /* unused */ 0)
...@@ -464,15 +445,15 @@ public final class DownloadManager { ...@@ -464,15 +445,15 @@ public final class DownloadManager {
* download index. The manager must not be accessed after this method has been called. * download index. The manager must not be accessed after this method has been called.
*/ */
public void release() { public void release() {
synchronized (releaseLock) { synchronized (internalHandler) {
if (released) { if (internalHandler.released) {
return; return;
} }
internalHandler.sendEmptyMessage(MSG_RELEASE); internalHandler.sendEmptyMessage(MSG_RELEASE);
boolean wasInterrupted = false; boolean wasInterrupted = false;
while (!released) { while (!internalHandler.released) {
try { try {
releaseLock.wait(); internalHandler.wait();
} catch (InterruptedException e) { } catch (InterruptedException e) {
wasInterrupted = true; wasInterrupted = true;
} }
...@@ -581,68 +562,160 @@ public final class DownloadManager { ...@@ -581,68 +562,160 @@ public final class DownloadManager {
return C.INDEX_UNSET; return C.INDEX_UNSET;
} }
// Internal thread message handling. /* package */ static Download mergeRequest(
Download download, DownloadRequest request, int stopReason) {
@Download.State int state = download.state;
if (state == STATE_REMOVING || state == STATE_RESTARTING) {
state = STATE_RESTARTING;
} else if (stopReason != STOP_REASON_NONE) {
state = STATE_STOPPED;
} else {
state = STATE_QUEUED;
}
long nowMs = System.currentTimeMillis();
long startTimeMs = download.isTerminalState() ? nowMs : download.startTimeMs;
return new Download(
download.request.copyWithMergedRequest(request),
state,
startTimeMs,
/* updateTimeMs= */ nowMs,
/* contentLength= */ C.LENGTH_UNSET,
stopReason,
FAILURE_REASON_NONE);
}
private static Download copyWithState(Download download, @Download.State int state) {
return new Download(
download.request,
state,
download.startTimeMs,
/* updateTimeMs= */ System.currentTimeMillis(),
download.contentLength,
download.stopReason,
FAILURE_REASON_NONE,
download.progress);
}
private static void logd(String message) {
if (DEBUG) {
Log.d(TAG, message);
}
}
private boolean handleInternalMessage(Message message) { private static void logd(String message, DownloadInternal downloadInternal) {
logd(message, downloadInternal.download.request);
}
private static void logd(String message, DownloadRequest request) {
if (DEBUG) {
logd(message + ": " + request);
}
}
private static void logdFlags(String message, int flags) {
if (DEBUG) {
logd(message + ": " + Integer.toBinaryString(flags));
}
}
private static final class InternalHandler extends Handler {
public boolean released;
private final HandlerThread thread;
private final WritableDownloadIndex downloadIndex;
private final DownloaderFactory downloaderFactory;
private final Handler mainHandler;
private final ArrayList<DownloadInternal> downloadInternals;
private final HashMap<String, DownloadThread> downloadThreads;
// Mutable fields that are accessed on the internal thread.
@Requirements.RequirementFlags private int notMetRequirements;
private boolean downloadsPaused;
private int maxParallelDownloads;
private int minRetryCount;
private int parallelDownloads;
public InternalHandler(
HandlerThread thread,
WritableDownloadIndex downloadIndex,
DownloaderFactory downloaderFactory,
Handler mainHandler,
int maxParallelDownloads,
int minRetryCount,
boolean downloadsPaused) {
super(thread.getLooper());
this.thread = thread;
this.downloadIndex = downloadIndex;
this.downloaderFactory = downloaderFactory;
this.mainHandler = mainHandler;
this.maxParallelDownloads = maxParallelDownloads;
this.minRetryCount = minRetryCount;
this.downloadsPaused = downloadsPaused;
downloadInternals = new ArrayList<>();
downloadThreads = new HashMap<>();
}
@Override
public void handleMessage(Message message) {
boolean processedExternalMessage = true; boolean processedExternalMessage = true;
switch (message.what) { switch (message.what) {
case MSG_INITIALIZE: case MSG_INITIALIZE:
int notMetRequirements = message.arg1; int notMetRequirements = message.arg1;
initializeInternal(notMetRequirements); initialize(notMetRequirements);
break; break;
case MSG_SET_DOWNLOADS_PAUSED: case MSG_SET_DOWNLOADS_PAUSED:
boolean downloadsPaused = message.arg1 != 0; boolean downloadsPaused = message.arg1 != 0;
setDownloadsPausedInternal(downloadsPaused); setDownloadsPaused(downloadsPaused);
break; break;
case MSG_SET_NOT_MET_REQUIREMENTS: case MSG_SET_NOT_MET_REQUIREMENTS:
notMetRequirements = message.arg1; notMetRequirements = message.arg1;
setNotMetRequirementsInternal(notMetRequirements); setNotMetRequirements(notMetRequirements);
break; break;
case MSG_SET_STOP_REASON: case MSG_SET_STOP_REASON:
String id = (String) message.obj; String id = (String) message.obj;
int stopReason = message.arg1; int stopReason = message.arg1;
setStopReasonInternal(id, stopReason); setStopReason(id, stopReason);
break; break;
case MSG_SET_MAX_PARALLEL_DOWNLOADS: case MSG_SET_MAX_PARALLEL_DOWNLOADS:
int maxParallelDownloads = message.arg1; int maxParallelDownloads = message.arg1;
setMaxParallelDownloadsInternal(maxParallelDownloads); setMaxParallelDownloads(maxParallelDownloads);
break; break;
case MSG_SET_MIN_RETRY_COUNT: case MSG_SET_MIN_RETRY_COUNT:
int minRetryCount = message.arg1; int minRetryCount = message.arg1;
setMinRetryCountInternal(minRetryCount); setMinRetryCount(minRetryCount);
break; break;
case MSG_ADD_DOWNLOAD: case MSG_ADD_DOWNLOAD:
DownloadRequest request = (DownloadRequest) message.obj; DownloadRequest request = (DownloadRequest) message.obj;
stopReason = message.arg1; stopReason = message.arg1;
addDownloadInternal(request, stopReason); addDownload(request, stopReason);
break; break;
case MSG_REMOVE_DOWNLOAD: case MSG_REMOVE_DOWNLOAD:
id = (String) message.obj; id = (String) message.obj;
removeDownloadInternal(id); removeDownload(id);
break; break;
case MSG_DOWNLOAD_THREAD_STOPPED: case MSG_DOWNLOAD_THREAD_STOPPED:
DownloadThread downloadThread = (DownloadThread) message.obj; DownloadThread downloadThread = (DownloadThread) message.obj;
onDownloadThreadStoppedInternal(downloadThread); onDownloadThreadStopped(downloadThread);
processedExternalMessage = false; // This message is posted internally. processedExternalMessage = false; // This message is posted internally.
break; break;
case MSG_CONTENT_LENGTH_CHANGED: case MSG_CONTENT_LENGTH_CHANGED:
downloadThread = (DownloadThread) message.obj; downloadThread = (DownloadThread) message.obj;
onDownloadThreadContentLengthChangedInternal(downloadThread); onDownloadThreadContentLengthChanged(downloadThread);
processedExternalMessage = false; // This message is posted internally. processedExternalMessage = false; // This message is posted internally.
break; break;
case MSG_RELEASE: case MSG_RELEASE:
releaseInternal(); release();
return true; // Don't post back to mainHandler on release. return; // Don't post back to mainHandler on release.
default: default:
throw new IllegalStateException(); throw new IllegalStateException();
} }
mainHandler mainHandler
.obtainMessage(MSG_PROCESSED, processedExternalMessage ? 1 : 0, downloadThreads.size()) .obtainMessage(MSG_PROCESSED, processedExternalMessage ? 1 : 0, downloadThreads.size())
.sendToTarget(); .sendToTarget();
return true;
} }
private void initializeInternal(int notMetRequirements) { private void initialize(int notMetRequirements) {
this.notMetRequirements = notMetRequirements; this.notMetRequirements = notMetRequirements;
ArrayList<Download> loadedStates = new ArrayList<>(); ArrayList<Download> loadedStates = new ArrayList<>();
try (DownloadCursor cursor = try (DownloadCursor cursor =
...@@ -666,18 +739,15 @@ public final class DownloadManager { ...@@ -666,18 +739,15 @@ public final class DownloadManager {
} }
} }
private void setDownloadsPausedInternal(boolean downloadsPaused) { private void setDownloadsPaused(boolean downloadsPaused) {
if (this.downloadsPausedInternal == downloadsPaused) { this.downloadsPaused = downloadsPaused;
return;
}
this.downloadsPausedInternal = downloadsPaused;
for (int i = 0; i < downloadInternals.size(); i++) { for (int i = 0; i < downloadInternals.size(); i++) {
downloadInternals.get(i).updateStopState(); downloadInternals.get(i).updateStopState();
} }
} }
private void setNotMetRequirementsInternal( private void setNotMetRequirements(@Requirements.RequirementFlags int notMetRequirements) {
@Requirements.RequirementFlags int notMetRequirements) { // TODO: Move this deduplication check to the main thread.
if (this.notMetRequirements == notMetRequirements) { if (this.notMetRequirements == notMetRequirements) {
return; return;
} }
...@@ -688,7 +758,7 @@ public final class DownloadManager { ...@@ -688,7 +758,7 @@ public final class DownloadManager {
} }
} }
private void setStopReasonInternal(@Nullable String id, int stopReason) { private void setStopReason(@Nullable String id, int stopReason) {
if (id != null) { if (id != null) {
DownloadInternal downloadInternal = getDownload(id); DownloadInternal downloadInternal = getDownload(id);
if (downloadInternal != null) { if (downloadInternal != null) {
...@@ -712,16 +782,16 @@ public final class DownloadManager { ...@@ -712,16 +782,16 @@ public final class DownloadManager {
} }
} }
private void setMaxParallelDownloadsInternal(int maxParallelDownloads) { private void setMaxParallelDownloads(int maxParallelDownloads) {
maxParallelDownloadsInternal = maxParallelDownloads; this.maxParallelDownloads = maxParallelDownloads;
// TODO: Start or stop downloads if necessary. // TODO: Start or stop downloads if necessary.
} }
private void setMinRetryCountInternal(int minRetryCount) { private void setMinRetryCount(int minRetryCount) {
minRetryCountInternal = minRetryCount; this.minRetryCount = minRetryCount;
} }
private void addDownloadInternal(DownloadRequest request, int stopReason) { private void addDownload(DownloadRequest request, int stopReason) {
DownloadInternal downloadInternal = getDownload(request.id); DownloadInternal downloadInternal = getDownload(request.id);
if (downloadInternal != null) { if (downloadInternal != null) {
downloadInternal.addRequest(request, stopReason); downloadInternal.addRequest(request, stopReason);
...@@ -748,7 +818,7 @@ public final class DownloadManager { ...@@ -748,7 +818,7 @@ public final class DownloadManager {
} }
} }
private void removeDownloadInternal(String id) { private void removeDownload(String id) {
DownloadInternal downloadInternal = getDownload(id); DownloadInternal downloadInternal = getDownload(id);
if (downloadInternal != null) { if (downloadInternal != null) {
downloadInternal.remove(); downloadInternal.remove();
...@@ -762,42 +832,42 @@ public final class DownloadManager { ...@@ -762,42 +832,42 @@ public final class DownloadManager {
} }
} }
private void onDownloadThreadStoppedInternal(DownloadThread downloadThread) { private void onDownloadThreadStopped(DownloadThread downloadThread) {
logd("Download is stopped", downloadThread.request); logd("Download is stopped", downloadThread.request);
String downloadId = downloadThread.request.id; String downloadId = downloadThread.request.id;
downloadThreads.remove(downloadId); downloadThreads.remove(downloadId);
boolean tryToStartDownloads = false; boolean tryToStartDownloads = false;
if (!downloadThread.isRemove) { if (!downloadThread.isRemove) {
// If maxParallelDownloads was hit, there might be a download waiting for a slot. // If maxParallelDownloads was hit, there might be a download waiting for a slot.
tryToStartDownloads = parallelDownloads == maxParallelDownloadsInternal; tryToStartDownloads = parallelDownloads == maxParallelDownloads;
parallelDownloads--; parallelDownloads--;
} }
getDownload(downloadId) getDownload(downloadId)
.onDownloadThreadStopped(downloadThread.isCanceled, downloadThread.finalError); .onDownloadThreadStopped(downloadThread.isCanceled, downloadThread.finalError);
if (tryToStartDownloads) { if (tryToStartDownloads) {
for (int i = 0; for (int i = 0;
parallelDownloads < maxParallelDownloadsInternal && i < downloadInternals.size(); parallelDownloads < maxParallelDownloads && i < downloadInternals.size();
i++) { i++) {
downloadInternals.get(i).start(); downloadInternals.get(i).start();
} }
} }
} }
private void onDownloadThreadContentLengthChangedInternal(DownloadThread downloadThread) { private void onDownloadThreadContentLengthChanged(DownloadThread downloadThread) {
String downloadId = downloadThread.request.id; String downloadId = downloadThread.request.id;
getDownload(downloadId).setContentLength(downloadThread.contentLength); getDownload(downloadId).setContentLength(downloadThread.contentLength);
} }
private void releaseInternal() { private void release() {
for (DownloadThread downloadThread : downloadThreads.values()) { for (DownloadThread downloadThread : downloadThreads.values()) {
downloadThread.cancel(/* released= */ true); downloadThread.cancel(/* released= */ true);
} }
downloadThreads.clear(); downloadThreads.clear();
downloadInternals.clear(); downloadInternals.clear();
internalThread.quit(); thread.quit();
synchronized (releaseLock) { synchronized (this) {
released = true; released = true;
releaseLock.notifyAll(); notifyAll();
} }
} }
...@@ -837,7 +907,7 @@ public final class DownloadManager { ...@@ -837,7 +907,7 @@ public final class DownloadManager {
} }
boolean isRemove = downloadInternal.isInRemoveState(); boolean isRemove = downloadInternal.isInRemoveState();
if (!isRemove) { if (!isRemove) {
if (parallelDownloads == maxParallelDownloadsInternal) { if (parallelDownloads == maxParallelDownloads) {
return START_THREAD_TOO_MANY_DOWNLOADS; return START_THREAD_TOO_MANY_DOWNLOADS;
} }
parallelDownloads++; parallelDownloads++;
...@@ -845,13 +915,7 @@ public final class DownloadManager { ...@@ -845,13 +915,7 @@ public final class DownloadManager {
Downloader downloader = downloaderFactory.createDownloader(request); Downloader downloader = downloaderFactory.createDownloader(request);
DownloadProgress downloadProgress = downloadInternal.download.progress; DownloadProgress downloadProgress = downloadInternal.download.progress;
DownloadThread downloadThread = DownloadThread downloadThread =
new DownloadThread( new DownloadThread(request, downloader, downloadProgress, isRemove, minRetryCount, this);
request,
downloader,
downloadProgress,
isRemove,
minRetryCountInternal,
internalHandler);
downloadThreads.put(downloadId, downloadThread); downloadThreads.put(downloadId, downloadThread);
downloadThread.start(); downloadThread.start();
logd("Download is started", downloadInternal); logd("Download is started", downloadInternal);
...@@ -896,68 +960,13 @@ public final class DownloadManager { ...@@ -896,68 +960,13 @@ public final class DownloadManager {
} }
private boolean canStartDownloads() { private boolean canStartDownloads() {
return !downloadsPausedInternal && notMetRequirements == 0; return !downloadsPaused && notMetRequirements == 0;
}
/* package */ static Download mergeRequest(
Download download, DownloadRequest request, int stopReason) {
@Download.State int state = download.state;
if (state == STATE_REMOVING || state == STATE_RESTARTING) {
state = STATE_RESTARTING;
} else if (stopReason != STOP_REASON_NONE) {
state = STATE_STOPPED;
} else {
state = STATE_QUEUED;
}
long nowMs = System.currentTimeMillis();
long startTimeMs = download.isTerminalState() ? nowMs : download.startTimeMs;
return new Download(
download.request.copyWithMergedRequest(request),
state,
startTimeMs,
/* updateTimeMs= */ nowMs,
/* contentLength= */ C.LENGTH_UNSET,
stopReason,
FAILURE_REASON_NONE);
}
private static Download copyWithState(Download download, @Download.State int state) {
return new Download(
download.request,
state,
download.startTimeMs,
/* updateTimeMs= */ System.currentTimeMillis(),
download.contentLength,
download.stopReason,
FAILURE_REASON_NONE,
download.progress);
}
private static void logd(String message) {
if (DEBUG) {
Log.d(TAG, message);
}
}
private static void logd(String message, DownloadInternal downloadInternal) {
logd(message, downloadInternal.download.request);
}
private static void logd(String message, DownloadRequest request) {
if (DEBUG) {
logd(message + ": " + request);
}
}
private static void logdFlags(String message, int flags) {
if (DEBUG) {
logd(message + ": " + Integer.toBinaryString(flags));
} }
} }
private static final class DownloadInternal { private static final class DownloadInternal {
private final DownloadManager downloadManager; private final InternalHandler internalHandler;
private Download download; private Download download;
...@@ -967,8 +976,8 @@ public final class DownloadManager { ...@@ -967,8 +976,8 @@ public final class DownloadManager {
private int stopReason; private int stopReason;
@MonotonicNonNull @Download.FailureReason private int failureReason; @MonotonicNonNull @Download.FailureReason private int failureReason;
private DownloadInternal(DownloadManager downloadManager, Download download) { private DownloadInternal(InternalHandler internalHandler, Download download) {
this.downloadManager = downloadManager; this.internalHandler = internalHandler;
this.download = download; this.download = download;
state = download.state; state = download.state;
contentLength = download.contentLength; contentLength = download.contentLength;
...@@ -1016,7 +1025,7 @@ public final class DownloadManager { ...@@ -1016,7 +1025,7 @@ public final class DownloadManager {
if (state == STATE_QUEUED || state == STATE_DOWNLOADING) { if (state == STATE_QUEUED || state == STATE_DOWNLOADING) {
startOrQueue(); startOrQueue();
} else if (isInRemoveState()) { } else if (isInRemoveState()) {
downloadManager.startDownloadThread(this); internalHandler.startDownloadThread(this);
} }
} }
...@@ -1034,7 +1043,7 @@ public final class DownloadManager { ...@@ -1034,7 +1043,7 @@ public final class DownloadManager {
return; return;
} }
this.contentLength = contentLength; this.contentLength = contentLength;
downloadManager.onDownloadChangedInternal(this, getUpdatedDownload()); internalHandler.onDownloadChangedInternal(this, getUpdatedDownload());
} }
private void updateStopState() { private void updateStopState() {
...@@ -1045,12 +1054,12 @@ public final class DownloadManager { ...@@ -1045,12 +1054,12 @@ public final class DownloadManager {
} }
} else { } else {
if (state == STATE_DOWNLOADING || state == STATE_QUEUED) { if (state == STATE_DOWNLOADING || state == STATE_QUEUED) {
downloadManager.stopDownloadThreadInternal(download.request.id); internalHandler.stopDownloadThreadInternal(download.request.id);
setState(STATE_STOPPED); setState(STATE_STOPPED);
} }
} }
if (oldDownload == download) { if (oldDownload == download) {
downloadManager.onDownloadChangedInternal(this, getUpdatedDownload()); internalHandler.onDownloadChangedInternal(this, getUpdatedDownload());
} }
} }
...@@ -1059,24 +1068,24 @@ public final class DownloadManager { ...@@ -1059,24 +1068,24 @@ public final class DownloadManager {
// state immediately. // state immediately.
state = initialState; state = initialState;
if (isInRemoveState()) { if (isInRemoveState()) {
downloadManager.startDownloadThread(this); internalHandler.startDownloadThread(this);
} else if (canStart()) { } else if (canStart()) {
startOrQueue(); startOrQueue();
} else { } else {
setState(STATE_STOPPED); setState(STATE_STOPPED);
} }
if (state == initialState) { if (state == initialState) {
downloadManager.onDownloadChangedInternal(this, getUpdatedDownload()); internalHandler.onDownloadChangedInternal(this, getUpdatedDownload());
} }
} }
private boolean canStart() { private boolean canStart() {
return downloadManager.canStartDownloads() && stopReason == STOP_REASON_NONE; return internalHandler.canStartDownloads() && stopReason == STOP_REASON_NONE;
} }
private void startOrQueue() { private void startOrQueue() {
Assertions.checkState(!isInRemoveState()); Assertions.checkState(!isInRemoveState());
@StartThreadResults int result = downloadManager.startDownloadThread(this); @StartThreadResults int result = internalHandler.startDownloadThread(this);
Assertions.checkState(result != START_THREAD_WAIT_REMOVAL_TO_FINISH); Assertions.checkState(result != START_THREAD_WAIT_REMOVAL_TO_FINISH);
if (result == START_THREAD_SUCCEEDED || result == START_THREAD_WAIT_DOWNLOAD_CANCELLATION) { if (result == START_THREAD_SUCCEEDED || result == START_THREAD_WAIT_DOWNLOAD_CANCELLATION) {
setState(STATE_DOWNLOADING); setState(STATE_DOWNLOADING);
...@@ -1088,7 +1097,7 @@ public final class DownloadManager { ...@@ -1088,7 +1097,7 @@ public final class DownloadManager {
private void setState(@Download.State int newState) { private void setState(@Download.State int newState) {
if (state != newState) { if (state != newState) {
state = newState; state = newState;
downloadManager.onDownloadChangedInternal(this, getUpdatedDownload()); internalHandler.onDownloadChangedInternal(this, getUpdatedDownload());
} }
} }
...@@ -1097,9 +1106,9 @@ public final class DownloadManager { ...@@ -1097,9 +1106,9 @@ public final class DownloadManager {
return; return;
} }
if (isCanceled) { if (isCanceled) {
downloadManager.startDownloadThread(this); internalHandler.startDownloadThread(this);
} else if (state == STATE_REMOVING) { } else if (state == STATE_REMOVING) {
downloadManager.onDownloadRemovedInternal(this, getUpdatedDownload()); internalHandler.onDownloadRemovedInternal(this, getUpdatedDownload());
} else if (state == STATE_RESTARTING) { } else if (state == STATE_RESTARTING) {
initialize(STATE_QUEUED); initialize(STATE_QUEUED);
} else { // STATE_DOWNLOADING } else { // STATE_DOWNLOADING
...@@ -1122,7 +1131,7 @@ public final class DownloadManager { ...@@ -1122,7 +1131,7 @@ public final class DownloadManager {
private final boolean isRemove; private final boolean isRemove;
private final int minRetryCount; private final int minRetryCount;
private volatile Handler updateHandler; private volatile InternalHandler internalHandler;
private volatile boolean isCanceled; private volatile boolean isCanceled;
private Throwable finalError; private Throwable finalError;
...@@ -1134,13 +1143,13 @@ public final class DownloadManager { ...@@ -1134,13 +1143,13 @@ public final class DownloadManager {
DownloadProgress downloadProgress, DownloadProgress downloadProgress,
boolean isRemove, boolean isRemove,
int minRetryCount, int minRetryCount,
Handler updateHandler) { InternalHandler internalHandler) {
this.request = request; this.request = request;
this.downloader = downloader; this.downloader = downloader;
this.downloadProgress = downloadProgress; this.downloadProgress = downloadProgress;
this.isRemove = isRemove; this.isRemove = isRemove;
this.minRetryCount = minRetryCount; this.minRetryCount = minRetryCount;
this.updateHandler = updateHandler; this.internalHandler = internalHandler;
contentLength = C.LENGTH_UNSET; contentLength = C.LENGTH_UNSET;
} }
...@@ -1150,7 +1159,7 @@ public final class DownloadManager { ...@@ -1150,7 +1159,7 @@ public final class DownloadManager {
// cancellation to complete depends on the implementation of the downloader being used. We // cancellation to complete depends on the implementation of the downloader being used. We
// null the handler reference here so that it doesn't prevent garbage collection of the // null the handler reference here so that it doesn't prevent garbage collection of the
// download manager whilst cancellation is ongoing. // download manager whilst cancellation is ongoing.
updateHandler = null; internalHandler = null;
} }
isCanceled = true; isCanceled = true;
downloader.cancel(); downloader.cancel();
...@@ -1192,9 +1201,9 @@ public final class DownloadManager { ...@@ -1192,9 +1201,9 @@ public final class DownloadManager {
} catch (Throwable e) { } catch (Throwable e) {
finalError = e; finalError = e;
} }
Handler updateHandler = this.updateHandler; Handler internalHandler = this.internalHandler;
if (updateHandler != null) { if (internalHandler != null) {
updateHandler.obtainMessage(MSG_DOWNLOAD_THREAD_STOPPED, this).sendToTarget(); internalHandler.obtainMessage(MSG_DOWNLOAD_THREAD_STOPPED, this).sendToTarget();
} }
} }
...@@ -1204,9 +1213,9 @@ public final class DownloadManager { ...@@ -1204,9 +1213,9 @@ public final class DownloadManager {
downloadProgress.percentDownloaded = percentDownloaded; downloadProgress.percentDownloaded = percentDownloaded;
if (contentLength != this.contentLength) { if (contentLength != this.contentLength) {
this.contentLength = contentLength; this.contentLength = contentLength;
Handler updateHandler = this.updateHandler; Handler internalHandler = this.internalHandler;
if (updateHandler != null) { if (internalHandler != null) {
updateHandler.obtainMessage(MSG_CONTENT_LENGTH_CHANGED, this).sendToTarget(); internalHandler.obtainMessage(MSG_CONTENT_LENGTH_CHANGED, this).sendToTarget();
} }
} }
} }
......
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