mirror of https://github.com/TeamNewPipe/NewPipe
159 lines
6.1 KiB
Java
159 lines
6.1 KiB
Java
package us.shandian.giga.get;
|
|
|
|
import android.support.annotation.NonNull;
|
|
import android.util.Log;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.io.RandomAccessFile;
|
|
import java.net.HttpURLConnection;
|
|
import java.nio.channels.ClosedByInterruptException;
|
|
|
|
import us.shandian.giga.util.Utility;
|
|
|
|
import static org.schabi.newpipe.BuildConfig.DEBUG;
|
|
|
|
public class DownloadInitializer implements Runnable {
|
|
private final static String TAG = "DownloadInitializer";
|
|
final static int mId = 0;
|
|
|
|
private DownloadMission mMission;
|
|
|
|
DownloadInitializer(@NonNull DownloadMission mission) {
|
|
mMission = mission;
|
|
}
|
|
|
|
@Override
|
|
public void run() {
|
|
if (mMission.current > 0) mMission.resetState();
|
|
|
|
int retryCount = 0;
|
|
while (true) {
|
|
try {
|
|
mMission.currentThreadCount = mMission.threadCount;
|
|
|
|
HttpURLConnection conn = mMission.openConnection(mId, -1, -1);
|
|
if (!mMission.running || Thread.interrupted()) return;
|
|
|
|
mMission.length = conn.getContentLength();
|
|
if (mMission.length == 0) {
|
|
mMission.notifyError(DownloadMission.ERROR_HTTP_NO_CONTENT, null);
|
|
return;
|
|
}
|
|
|
|
// check for dynamic generated content
|
|
if (mMission.length == -1 && conn.getResponseCode() == 200) {
|
|
mMission.blocks = 0;
|
|
mMission.length = 0;
|
|
mMission.fallback = true;
|
|
mMission.unknownLength = true;
|
|
mMission.currentThreadCount = 1;
|
|
|
|
if (DEBUG) {
|
|
Log.d(TAG, "falling back (unknown length)");
|
|
}
|
|
} else {
|
|
// Open again
|
|
conn = mMission.openConnection(mId, mMission.length - 10, mMission.length);
|
|
|
|
int code = conn.getResponseCode();
|
|
if (!mMission.running || Thread.interrupted()) return;
|
|
|
|
if (code == 206) {
|
|
if (mMission.currentThreadCount > 1) {
|
|
mMission.blocks = mMission.length / DownloadMission.BLOCK_SIZE;
|
|
|
|
if (mMission.currentThreadCount > mMission.blocks) {
|
|
mMission.currentThreadCount = (int) mMission.blocks;
|
|
}
|
|
if (mMission.currentThreadCount <= 0) {
|
|
mMission.currentThreadCount = 1;
|
|
}
|
|
if (mMission.blocks * DownloadMission.BLOCK_SIZE < mMission.length) {
|
|
mMission.blocks++;
|
|
}
|
|
} else {
|
|
// if one thread is solicited don't calculate blocks, is useless
|
|
mMission.blocks = 1;
|
|
mMission.fallback = true;
|
|
mMission.unknownLength = false;
|
|
}
|
|
|
|
if (DEBUG) {
|
|
Log.d(TAG, "http response code = " + code);
|
|
}
|
|
} else {
|
|
// Fallback to single thread
|
|
mMission.blocks = 0;
|
|
mMission.fallback = true;
|
|
mMission.unknownLength = false;
|
|
mMission.currentThreadCount = 1;
|
|
|
|
if (DEBUG) {
|
|
Log.d(TAG, "falling back due http response code = " + code);
|
|
}
|
|
}
|
|
}
|
|
|
|
for (long i = 0; i < mMission.currentThreadCount; i++) {
|
|
mMission.threadBlockPositions.add(i);
|
|
mMission.threadBytePositions.add(0);
|
|
}
|
|
|
|
File file;
|
|
if (mMission.current == 0) {
|
|
file = new File(mMission.location);
|
|
if (!Utility.mkdir(file, true)) {
|
|
mMission.notifyError(DownloadMission.ERROR_PATH_CREATION, null);
|
|
return;
|
|
}
|
|
|
|
file = new File(file, mMission.name);
|
|
|
|
// if the name is used by "something", delete it
|
|
if (file.exists() && !file.isFile() && !file.delete()) {
|
|
mMission.notifyError(DownloadMission.ERROR_FILE_CREATION, null);
|
|
return;
|
|
}
|
|
|
|
if (!file.exists() && !file.createNewFile()) {
|
|
mMission.notifyError(DownloadMission.ERROR_FILE_CREATION, null);
|
|
return;
|
|
}
|
|
} else {
|
|
file = new File(mMission.location, mMission.name);
|
|
}
|
|
|
|
RandomAccessFile af = new RandomAccessFile(file, "rw");
|
|
af.setLength(mMission.offsets[mMission.current] + mMission.length);
|
|
af.seek(mMission.offsets[mMission.current]);
|
|
af.close();
|
|
|
|
if (Thread.interrupted()) return;
|
|
|
|
mMission.running = false;
|
|
break;
|
|
} catch (Exception e) {
|
|
if (e instanceof ClosedByInterruptException) {
|
|
return;
|
|
} else if (e instanceof IOException && e.getMessage().contains("Permission denied")) {
|
|
mMission.notifyError(DownloadMission.ERROR_PERMISSION_DENIED, e);
|
|
return;
|
|
}
|
|
|
|
if (retryCount++ > mMission.maxRetry) {
|
|
Log.e(TAG, "initializer failed", e);
|
|
mMission.running = false;
|
|
mMission.notifyError(e);
|
|
return;
|
|
}
|
|
|
|
//try again
|
|
Log.e(TAG, "initializer failed, retrying", e);
|
|
}
|
|
}
|
|
|
|
mMission.start();
|
|
}
|
|
}
|