misc changes

* implement socket timeout error
* use 128k buffer size for copy
* use NewPipe HTTP user agent in the downloads
* automatically recover downloads with network errors that are queued
This commit is contained in:
kapodamy 2019-04-17 18:17:24 -03:00
parent 16d6bda85d
commit d1573a0a6e
16 changed files with 46 additions and 15 deletions

View file

@ -28,7 +28,7 @@ public class DownloadInitializer extends Thread {
@Override
public void run() {
if (mMission.current > 0) mMission.resetState(false,true, DownloadMission.ERROR_NOTHING);
if (mMission.current > 0) mMission.resetState(false, true, DownloadMission.ERROR_NOTHING);
int retryCount = 0;
while (true) {

View file

@ -4,11 +4,14 @@ import android.os.Handler;
import android.os.Message;
import android.util.Log;
import org.schabi.newpipe.Downloader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
@ -45,6 +48,7 @@ public class DownloadMission extends Mission {
public static final int ERROR_POSTPROCESSING_HOLD = 1009;
public static final int ERROR_INSUFFICIENT_STORAGE = 1010;
public static final int ERROR_PROGRESS_LOST = 1011;
public static final int ERROR_TIMEOUT = 1012;
public static final int ERROR_HTTP_NO_CONTENT = 204;
public static final int ERROR_HTTP_UNSUPPORTED_RANGE = 206;
@ -232,10 +236,9 @@ public class DownloadMission extends Mission {
URL url = new URL(urls[current]);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setInstanceFollowRedirects(true);
conn.setRequestProperty("User-Agent", Downloader.USER_AGENT);
// BUG workaround: switching between networks can freeze the download forever
//conn.setRequestProperty("Connection", "close");
conn.setConnectTimeout(30000);
conn.setReadTimeout(10000);
@ -329,6 +332,8 @@ public class DownloadMission extends Mission {
notifyError(ERROR_CONNECT_HOST, null);
} else if (err instanceof UnknownHostException) {
notifyError(ERROR_UNKNOWN_HOST, null);
} else if (err instanceof SocketTimeoutException) {
notifyError(ERROR_TIMEOUT, null);
} else {
notifyError(ERROR_UNKNOWN_EXCEPTION, err);
}
@ -338,7 +343,7 @@ public class DownloadMission extends Mission {
Log.e(TAG, "notifyError() code = " + code, err);
if (err instanceof IOException) {
if (storage.canWrite() || err.getMessage().contains("Permission denied")) {
if (!storage.canWrite() || err.getMessage().contains("Permission denied")) {
code = ERROR_PERMISSION_DENIED;
err = null;
} else if (err.getMessage().contains("ENOSPC")) {
@ -349,7 +354,19 @@ public class DownloadMission extends Mission {
errCode = code;
errObject = err;
enqueued = false;
switch (code) {
case ERROR_SSL_EXCEPTION:
case ERROR_UNKNOWN_HOST:
case ERROR_CONNECT_HOST:
case ERROR_TIMEOUT:
// do not change the queue flag for network errors, can be
// recovered silently without the user interaction
break;
default:
// also checks for server errors
if (code < 500 || code > 599) enqueued = false;
}
pause();

View file

@ -27,7 +27,6 @@ public class DownloadRunnable extends Thread {
if (mission == null) throw new NullPointerException("mission is null");
mMission = mission;
mId = id;
mConn = null;
}
@Override

View file

@ -1,6 +1,5 @@
package us.shandian.giga.get;
import android.annotation.SuppressLint;
import android.support.annotation.NonNull;
import android.util.Log;
@ -19,7 +18,7 @@ import static org.schabi.newpipe.BuildConfig.DEBUG;
* Single-threaded fallback mode
*/
public class DownloadRunnableFallback extends Thread {
private static final String TAG = "DownloadRunnableFallback";
private static final String TAG = "DownloadRunnableFallbac";
private final DownloadMission mMission;
@ -30,9 +29,6 @@ public class DownloadRunnableFallback extends Thread {
DownloadRunnableFallback(@NonNull DownloadMission mission) {
mMission = mission;
mIs = null;
mF = null;
mConn = null;
}
private void dispose() {
@ -46,7 +42,6 @@ public class DownloadRunnableFallback extends Thread {
}
@Override
@SuppressLint("LongLogTag")
public void run() {
boolean done;
@ -106,6 +101,10 @@ public class DownloadRunnableFallback extends Thread {
return;
}
if (DEBUG) {
Log.e(TAG, "got exception, retrying...", e);
}
run();// try again
return;
}

View file

@ -11,6 +11,7 @@ import java.io.IOException;
public class CircularFileWriter extends SharpStream {
private final static int QUEUE_BUFFER_SIZE = 8 * 1024;// 8 KiB
private final static int COPY_BUFFER_SIZE = 128 * 1024; // 128 KiB
private final static int NOTIFY_BYTES_INTERVAL = 64 * 1024;// 64 KiB
private final static int THRESHOLD_AUX_LENGTH = 15 * 1024 * 1024;// 15 MiB
@ -53,6 +54,7 @@ public class CircularFileWriter extends SharpStream {
aux.flush();
boolean underflow = aux.offset < aux.length || out.offset < out.length;
byte[] buffer = new byte[COPY_BUFFER_SIZE];
aux.target.seek(0);
out.target.seek(out.length);
@ -60,14 +62,14 @@ public class CircularFileWriter extends SharpStream {
long length = amount;
while (length > 0) {
int read = (int) Math.min(length, Integer.MAX_VALUE);
read = aux.target.read(aux.queue, 0, Math.min(read, aux.queue.length));
read = aux.target.read(buffer, 0, Math.min(read, buffer.length));
if (read < 1) {
amount -= length;
break;
}
out.writeProof(aux.queue, read);
out.writeProof(buffer, read);
length -= read;
}
@ -100,7 +102,6 @@ public class CircularFileWriter extends SharpStream {
// move the excess data to the beginning of the file
long readOffset = amount;
long writeOffset = 0;
byte[] buffer = new byte[128 * 1024]; // 128 KiB
aux.length -= amount;
length = aux.length;

View file

@ -73,6 +73,7 @@ import static us.shandian.giga.get.DownloadMission.ERROR_POSTPROCESSING_HOLD;
import static us.shandian.giga.get.DownloadMission.ERROR_POSTPROCESSING_STOPPED;
import static us.shandian.giga.get.DownloadMission.ERROR_PROGRESS_LOST;
import static us.shandian.giga.get.DownloadMission.ERROR_SSL_EXCEPTION;
import static us.shandian.giga.get.DownloadMission.ERROR_TIMEOUT;
import static us.shandian.giga.get.DownloadMission.ERROR_UNKNOWN_EXCEPTION;
import static us.shandian.giga.get.DownloadMission.ERROR_UNKNOWN_HOST;
@ -487,6 +488,9 @@ public class MissionAdapter extends Adapter<ViewHolder> {
case ERROR_PROGRESS_LOST:
msg = R.string.error_progress_lost;
break;
case ERROR_TIMEOUT:
msg = R.string.error_timeout;
break;
default:
if (mission.errCode >= 100 && mission.errCode < 600) {
msgEx = "HTTP " + mission.errCode;