Commit 37bab0a9 by eguven Committed by Oliver Woodman

Temporally make DataIndex accessing code run on main thread

This is the second cl of a series of cls that will convert DownloadManager
threading model as public methods post actions on an internal thread
which then do the work.

PiperOrigin-RevId: 241773765
parent 9c081900
...@@ -29,9 +29,7 @@ import static com.google.android.exoplayer2.offline.DownloadState.STATE_RESTARTI ...@@ -29,9 +29,7 @@ import static com.google.android.exoplayer2.offline.DownloadState.STATE_RESTARTI
import static com.google.android.exoplayer2.offline.DownloadState.STATE_STOPPED; import static com.google.android.exoplayer2.offline.DownloadState.STATE_STOPPED;
import android.content.Context; import android.content.Context;
import android.os.ConditionVariable;
import android.os.Handler; import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper; import android.os.Looper;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
...@@ -46,7 +44,6 @@ import com.google.android.exoplayer2.util.Log; ...@@ -46,7 +44,6 @@ import com.google.android.exoplayer2.util.Log;
import java.io.IOException; import java.io.IOException;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.ArrayDeque;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
...@@ -135,11 +132,11 @@ public final class DownloadManager { ...@@ -135,11 +132,11 @@ public final class DownloadManager {
private final DownloaderFactory downloaderFactory; private final DownloaderFactory downloaderFactory;
private final ArrayList<Download> downloads; private final ArrayList<Download> downloads;
private final HashMap<Download, DownloadThread> activeDownloads; private final HashMap<Download, DownloadThread> activeDownloads;
private final Handler handler; private final Handler mainHandler;
private final HandlerThread fileIOThread; /*TODO
private final Handler fileIOHandler; private final HandlerThread internalThread;
private final Handler internalHandler;*/
private final CopyOnWriteArraySet<Listener> listeners; private final CopyOnWriteArraySet<Listener> listeners;
private final ArrayDeque<DownloadUpdater> dowloadUpdateQueue;
private boolean initialized; private boolean initialized;
private boolean released; private boolean released;
...@@ -147,7 +144,6 @@ public final class DownloadManager { ...@@ -147,7 +144,6 @@ public final class DownloadManager {
private int manualStopReason; private int manualStopReason;
private RequirementsWatcher requirementsWatcher; private RequirementsWatcher requirementsWatcher;
private int simultaneousDownloads; private int simultaneousDownloads;
private boolean loadingDownload;
/** /**
* Constructs a {@link DownloadManager}. * Constructs a {@link DownloadManager}.
...@@ -224,14 +220,14 @@ public final class DownloadManager { ...@@ -224,14 +220,14 @@ public final class DownloadManager {
if (looper == null) { if (looper == null) {
looper = Looper.getMainLooper(); looper = Looper.getMainLooper();
} }
handler = new Handler(looper); mainHandler = new Handler(looper);
fileIOThread = new HandlerThread("DownloadManager file i/o"); /*TODO
fileIOThread.start(); internalThread = new HandlerThread("DownloadManager file i/o");
fileIOHandler = new Handler(fileIOThread.getLooper()); internalThread.start();
internalHandler = new Handler(internalThread.getLooper());*/
listeners = new CopyOnWriteArraySet<>(); listeners = new CopyOnWriteArraySet<>();
dowloadUpdateQueue = new ArrayDeque<>();
setNotMetRequirements(watchRequirements(requirements)); setNotMetRequirements(watchRequirements(requirements));
loadDownloads(); loadDownloads();
...@@ -247,10 +243,7 @@ public final class DownloadManager { ...@@ -247,10 +243,7 @@ public final class DownloadManager {
/** Returns whether there are no active downloads. */ /** Returns whether there are no active downloads. */
public boolean isIdle() { public boolean isIdle() {
Assertions.checkState(!released); Assertions.checkState(!released);
return initialized return initialized && activeDownloads.isEmpty();
&& activeDownloads.isEmpty()
&& dowloadUpdateQueue.isEmpty()
&& !loadingDownload;
} }
/** Returns the used {@link DownloadIndex}. */ /** Returns the used {@link DownloadIndex}. */
...@@ -398,6 +391,12 @@ public final class DownloadManager { ...@@ -398,6 +391,12 @@ public final class DownloadManager {
if (released) { if (released) {
return; return;
} }
/*TODO call releaseInternal on internal thread.
final ConditionVariable fileIOFinishedCondition = new ConditionVariable();
internalHandler.post(fileIOFinishedCondition::open);
fileIOFinishedCondition.block();
internalThread.quit();
*/
releaseInternal(); releaseInternal();
} }
...@@ -409,10 +408,6 @@ public final class DownloadManager { ...@@ -409,10 +408,6 @@ public final class DownloadManager {
if (requirementsWatcher != null) { if (requirementsWatcher != null) {
requirementsWatcher.stop(); requirementsWatcher.stop();
} }
final ConditionVariable fileIOFinishedCondition = new ConditionVariable();
fileIOHandler.post(fileIOFinishedCondition::open);
fileIOFinishedCondition.block();
fileIOThread.quit();
logd("Released"); logd("Released");
} }
...@@ -438,8 +433,6 @@ public final class DownloadManager { ...@@ -438,8 +433,6 @@ public final class DownloadManager {
downloads.get(i).setManualStopReason(manualStopReason); downloads.get(i).setManualStopReason(manualStopReason);
} }
} }
fileIOHandler.post(
() -> {
try { try {
if (id != null) { if (id != null) {
downloadIndex.setManualStopReason(id, manualStopReason); downloadIndex.setManualStopReason(id, manualStopReason);
...@@ -449,56 +442,37 @@ public final class DownloadManager { ...@@ -449,56 +442,37 @@ public final class DownloadManager {
} catch (DatabaseIOException e) { } catch (DatabaseIOException e) {
Log.e(TAG, "setManualStopReason failed", e); Log.e(TAG, "setManualStopReason failed", e);
} }
});
} }
private void addDownloadInternal(DownloadAction action) { private void addDownloadInternal(DownloadAction action) {
dowloadUpdateQueue.add( Download download = getDownload(action.id);
new DownloadUpdater(action.id) { if (download != null) {
@Override
void onExisting(Download download) {
download.addAction(action); download.addAction(action);
logd("Action is added to existing download", download); logd("Action is added to existing download", download);
} } else {
DownloadState downloadState = loadDownloadState(action.id);
@Override
DownloadState onLoad(@Nullable DownloadState downloadState) {
DownloadState state;
if (downloadState == null) { if (downloadState == null) {
state = new DownloadState(action); downloadState = new DownloadState(action);
logd("Download state is created for " + id); logd("Download state is created for " + action.id);
} else { } else {
state = downloadState.mergeAction(action); downloadState = downloadState.mergeAction(action);
logd("Download state is loaded for " + id); logd("Download state is loaded for " + action.id);
} }
return state; addDownloadForState(downloadState);
}
});
if (initialized) {
processDownloadUpdateQueue();
} }
} }
private void removeDownloadInternal(String id) { private void removeDownloadInternal(String id) {
dowloadUpdateQueue.add( Download download = getDownload(id);
new DownloadUpdater(id) { if (download != null) {
@Override
void onExisting(Download download) {
download.remove(); download.remove();
} } else {
DownloadState downloadState = loadDownloadState(id);
@Override
DownloadState onLoad(@Nullable DownloadState downloadState) {
if (downloadState != null) { if (downloadState != null) {
downloadState = downloadState.setRemoveState(); addDownloadForState(downloadState.setRemoveState());
} else { } else {
logd("Can't remove download. No download with id: " + id); logd("Can't remove download. No download with id: " + id);
} }
return downloadState;
}
});
if (initialized) {
processDownloadUpdateQueue();
} }
} }
...@@ -561,54 +535,20 @@ public final class DownloadManager { ...@@ -561,54 +535,20 @@ public final class DownloadManager {
return null; return null;
} }
private void processDownloadUpdateQueue() { private DownloadState loadDownloadState(String id) {
while (!loadingDownload && !dowloadUpdateQueue.isEmpty()) {
DownloadUpdater downloadUpdater = dowloadUpdateQueue.remove();
Download download = getDownload(downloadUpdater.id);
if (download != null) {
downloadUpdater.onExisting(download);
} else {
loadDownload(downloadUpdater);
}
}
}
private void loadDownload(DownloadUpdater callback) {
loadingDownload = true;
fileIOHandler.post(
() -> {
DownloadState downloadState = null;
try { try {
downloadState = downloadIndex.getDownloadState(callback.id); return downloadIndex.getDownloadState(id);
} catch (DatabaseIOException e) { } catch (DatabaseIOException e) {
Log.e(TAG, "loadDownload failed", e); Log.e(TAG, "loadDownload failed", e);
} }
DownloadState finalDownloadState = downloadState; return null;
handler.post(
() -> {
loadingDownload = false;
if (!released) {
DownloadState state = callback.onLoad(finalDownloadState);
if (state != null) {
addDownloadForState(state);
}
processDownloadUpdateQueue();
}
});
});
} }
private void loadDownloads() { private void loadDownloads() {
fileIOHandler.post(
() -> {
DownloadState[] loadedStates; DownloadState[] loadedStates;
try (DownloadStateCursor cursor = try (DownloadStateCursor cursor =
downloadIndex.getDownloadStates( downloadIndex.getDownloadStates(
STATE_QUEUED, STATE_QUEUED, STATE_STOPPED, STATE_DOWNLOADING, STATE_REMOVING, STATE_RESTARTING)) {
STATE_STOPPED,
STATE_DOWNLOADING,
STATE_REMOVING,
STATE_RESTARTING)) {
loadedStates = new DownloadState[cursor.getCount()]; loadedStates = new DownloadState[cursor.getCount()];
for (int i = 0, length = loadedStates.length; i < length; i++) { for (int i = 0, length = loadedStates.length; i < length; i++) {
cursor.moveToNext(); cursor.moveToNext();
...@@ -619,26 +559,17 @@ public final class DownloadManager { ...@@ -619,26 +559,17 @@ public final class DownloadManager {
Log.e(TAG, "Download state loading failed.", e); Log.e(TAG, "Download state loading failed.", e);
loadedStates = new DownloadState[0]; loadedStates = new DownloadState[0];
} }
final DownloadState[] states = loadedStates; for (DownloadState downloadState : loadedStates) {
handler.post(
() -> {
if (released) {
return;
}
for (DownloadState downloadState : states) {
addDownloadForState(downloadState); addDownloadForState(downloadState);
} }
logd("Downloads are created."); logd("Downloads are created.");
initialized = true; initialized = true;
processDownloadUpdateQueue();
for (Listener listener : listeners) { for (Listener listener : listeners) {
listener.onInitialized(DownloadManager.this); listener.onInitialized(DownloadManager.this);
} }
for (int i = 0; i < downloads.size(); i++) { for (int i = 0; i < downloads.size(); i++) {
downloads.get(i).start(); downloads.get(i).start();
} }
});
});
} }
private void addDownloadForState(DownloadState downloadState) { private void addDownloadForState(DownloadState downloadState) {
...@@ -648,11 +579,6 @@ public final class DownloadManager { ...@@ -648,11 +579,6 @@ public final class DownloadManager {
} }
private void updateDownloadIndex(DownloadState downloadState) { private void updateDownloadIndex(DownloadState downloadState) {
fileIOHandler.post(
() -> {
if (released) {
return;
}
try { try {
if (downloadState.state == DownloadState.STATE_REMOVED) { if (downloadState.state == DownloadState.STATE_REMOVED) {
downloadIndex.removeDownloadState(downloadState.id); downloadIndex.removeDownloadState(downloadState.id);
...@@ -662,7 +588,6 @@ public final class DownloadManager { ...@@ -662,7 +588,6 @@ public final class DownloadManager {
} catch (DatabaseIOException e) { } catch (DatabaseIOException e) {
Log.e(TAG, "updateDownloadIndex failed", e); Log.e(TAG, "updateDownloadIndex failed", e);
} }
});
} }
private static void logd(String message) { private static void logd(String message) {
...@@ -685,7 +610,7 @@ public final class DownloadManager { ...@@ -685,7 +610,7 @@ public final class DownloadManager {
@StartThreadResults @StartThreadResults
private int startDownloadThread(Download download) { private int startDownloadThread(Download download) {
if (!initialized || released) { if (released) {
return START_THREAD_NOT_ALLOWED; return START_THREAD_NOT_ALLOWED;
} }
if (activeDownloads.containsKey(download)) { if (activeDownloads.containsKey(download)) {
...@@ -990,23 +915,11 @@ public final class DownloadManager { ...@@ -990,23 +915,11 @@ public final class DownloadManager {
error = e; error = e;
} }
final Throwable finalError = error; final Throwable finalError = error;
handler.post(() -> onDownloadThreadStopped(this, finalError)); mainHandler.post(() -> onDownloadThreadStopped(this, finalError));
} }
private int getRetryDelayMillis(int errorCount) { private int getRetryDelayMillis(int errorCount) {
return Math.min((errorCount - 1) * 1000, 5000); return Math.min((errorCount - 1) * 1000, 5000);
} }
} }
private abstract static class DownloadUpdater {
final String id;
private DownloadUpdater(String id) {
this.id = id;
}
abstract void onExisting(Download download);
abstract DownloadState onLoad(@Nullable DownloadState downloadState);
}
} }
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