431 lines
14 KiB
Java
431 lines
14 KiB
Java
package com.liulishuo.filedownloader.download;
|
|
|
|
import android.database.sqlite.SQLiteFullException;
|
|
import android.os.Build;
|
|
import android.os.Handler;
|
|
import android.os.HandlerThread;
|
|
import android.os.Message;
|
|
import android.os.SystemClock;
|
|
import com.liulishuo.filedownloader.database.FileDownloadDatabase;
|
|
import com.liulishuo.filedownloader.exception.FileDownloadGiveUpRetryException;
|
|
import com.liulishuo.filedownloader.exception.FileDownloadOutOfSpaceException;
|
|
import com.liulishuo.filedownloader.message.MessageSnapshotFlow;
|
|
import com.liulishuo.filedownloader.message.MessageSnapshotTaker;
|
|
import com.liulishuo.filedownloader.model.FileDownloadModel;
|
|
import com.liulishuo.filedownloader.services.FileDownloadBroadcastHandler;
|
|
import com.liulishuo.filedownloader.util.FileDownloadLog;
|
|
import com.liulishuo.filedownloader.util.FileDownloadProperties;
|
|
import com.liulishuo.filedownloader.util.FileDownloadUtils;
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.util.concurrent.TimeUnit;
|
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
import java.util.concurrent.atomic.AtomicLong;
|
|
import java.util.concurrent.locks.LockSupport;
|
|
|
|
/* loaded from: classes.dex */
|
|
public class DownloadStatusCallback implements Handler.Callback {
|
|
private final FileDownloadModel a;
|
|
private final ProcessParams c;
|
|
private final int d;
|
|
private final int e;
|
|
private final int f;
|
|
private long g;
|
|
private Handler h;
|
|
private HandlerThread i;
|
|
private volatile Thread k;
|
|
private volatile boolean j = false;
|
|
private volatile long l = 0;
|
|
private final AtomicLong m = new AtomicLong();
|
|
private final AtomicBoolean n = new AtomicBoolean(false);
|
|
private final AtomicBoolean o = new AtomicBoolean(false);
|
|
private final AtomicBoolean p = new AtomicBoolean(true);
|
|
private final FileDownloadDatabase b = CustomComponentHolder.i().a();
|
|
|
|
public static class ProcessParams {
|
|
private boolean a;
|
|
private Exception b;
|
|
private int c;
|
|
|
|
void a(boolean z) {
|
|
this.a = z;
|
|
}
|
|
|
|
public int b() {
|
|
return this.c;
|
|
}
|
|
|
|
public boolean c() {
|
|
return this.a;
|
|
}
|
|
|
|
void a(Exception exc) {
|
|
this.b = exc;
|
|
}
|
|
|
|
void a(int i) {
|
|
this.c = i;
|
|
}
|
|
|
|
public Exception a() {
|
|
return this.b;
|
|
}
|
|
}
|
|
|
|
DownloadStatusCallback(FileDownloadModel fileDownloadModel, int i, int i2, int i3) {
|
|
this.a = fileDownloadModel;
|
|
this.e = i2 >= 5 ? i2 : 5;
|
|
this.f = i3;
|
|
this.c = new ProcessParams();
|
|
this.d = i;
|
|
}
|
|
|
|
private void h() throws IOException {
|
|
l();
|
|
this.a.setStatus((byte) -3);
|
|
this.b.a(this.a.getId(), this.a.getTotal());
|
|
this.b.b(this.a.getId());
|
|
a((byte) -3);
|
|
if (FileDownloadProperties.a().g) {
|
|
FileDownloadBroadcastHandler.a(this.a);
|
|
}
|
|
}
|
|
|
|
private void i() {
|
|
this.a.setStatus((byte) -2);
|
|
this.b.c(this.a.getId(), this.a.getSoFar());
|
|
a((byte) -2);
|
|
}
|
|
|
|
private void j() {
|
|
if (this.a.getSoFar() == this.a.getTotal()) {
|
|
this.b.b(this.a.getId(), this.a.getSoFar());
|
|
return;
|
|
}
|
|
if (this.o.compareAndSet(true, false)) {
|
|
if (FileDownloadLog.a) {
|
|
FileDownloadLog.c(this, "handleProgress update model's status with progress", new Object[0]);
|
|
}
|
|
this.a.setStatus((byte) 3);
|
|
}
|
|
if (this.n.compareAndSet(true, false)) {
|
|
if (FileDownloadLog.a) {
|
|
FileDownloadLog.c(this, "handleProgress notify user progress status", new Object[0]);
|
|
}
|
|
a((byte) 3);
|
|
}
|
|
}
|
|
|
|
private boolean k() {
|
|
if (this.a.isChunked()) {
|
|
FileDownloadModel fileDownloadModel = this.a;
|
|
fileDownloadModel.setTotal(fileDownloadModel.getSoFar());
|
|
} else if (this.a.getSoFar() != this.a.getTotal()) {
|
|
a(new FileDownloadGiveUpRetryException(FileDownloadUtils.a("sofar[%d] not equal total[%d]", Long.valueOf(this.a.getSoFar()), Long.valueOf(this.a.getTotal()))));
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private void l() throws IOException {
|
|
boolean z;
|
|
String tempFilePath = this.a.getTempFilePath();
|
|
String targetFilePath = this.a.getTargetFilePath();
|
|
File file = new File(tempFilePath);
|
|
try {
|
|
File file2 = new File(targetFilePath);
|
|
if (file2.exists()) {
|
|
long length = file2.length();
|
|
if (!file2.delete()) {
|
|
throw new IOException(FileDownloadUtils.a("Can't delete the old file([%s], [%d]), so can't replace it with the new downloaded one.", targetFilePath, Long.valueOf(length)));
|
|
}
|
|
FileDownloadLog.e(this, "The target file([%s], [%d]) will be replaced with the new downloaded file[%d]", targetFilePath, Long.valueOf(length), Long.valueOf(file.length()));
|
|
}
|
|
z = !file.renameTo(file2);
|
|
if (!z) {
|
|
if (z && file.exists() && !file.delete()) {
|
|
FileDownloadLog.e(this, "delete the temp file(%s) failed, on completed downloading.", tempFilePath);
|
|
return;
|
|
}
|
|
return;
|
|
}
|
|
try {
|
|
throw new IOException(FileDownloadUtils.a("Can't rename the temp downloaded file(%s) to the target file(%s)", tempFilePath, targetFilePath));
|
|
} catch (Throwable th) {
|
|
th = th;
|
|
if (z && file.exists() && !file.delete()) {
|
|
FileDownloadLog.e(this, "delete the temp file(%s) failed, on completed downloading.", tempFilePath);
|
|
}
|
|
throw th;
|
|
}
|
|
} catch (Throwable th2) {
|
|
th = th2;
|
|
z = true;
|
|
}
|
|
}
|
|
|
|
void a() {
|
|
Handler handler = this.h;
|
|
if (handler != null) {
|
|
handler.removeCallbacksAndMessages(null);
|
|
this.i.quit();
|
|
this.k = Thread.currentThread();
|
|
while (this.j) {
|
|
LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(100L));
|
|
}
|
|
this.k = null;
|
|
}
|
|
}
|
|
|
|
public boolean b() {
|
|
HandlerThread handlerThread = this.i;
|
|
return handlerThread != null && handlerThread.isAlive();
|
|
}
|
|
|
|
void c() throws IOException {
|
|
if (k()) {
|
|
return;
|
|
}
|
|
h();
|
|
}
|
|
|
|
void d() {
|
|
this.i = new HandlerThread("source-status-callback");
|
|
this.i.start();
|
|
this.h = new Handler(this.i.getLooper(), this);
|
|
}
|
|
|
|
void e() {
|
|
i();
|
|
}
|
|
|
|
public void f() {
|
|
this.a.setStatus((byte) 1);
|
|
this.b.a(this.a.getId());
|
|
a((byte) 1);
|
|
}
|
|
|
|
void g() {
|
|
this.a.setStatus((byte) 6);
|
|
a((byte) 6);
|
|
this.b.c(this.a.getId());
|
|
}
|
|
|
|
/* JADX WARN: Removed duplicated region for block: B:11:0x0020 A[DONT_GENERATE] */
|
|
@Override // android.os.Handler.Callback
|
|
/*
|
|
Code decompiled incorrectly, please refer to instructions dump.
|
|
To view partially-correct code enable 'Show inconsistent code' option in preferences
|
|
*/
|
|
public boolean handleMessage(android.os.Message r5) {
|
|
/*
|
|
r4 = this;
|
|
r0 = 1
|
|
r4.j = r0
|
|
int r1 = r5.what
|
|
r2 = 3
|
|
r3 = 0
|
|
if (r1 == r2) goto L17
|
|
r2 = 5
|
|
if (r1 == r2) goto Ld
|
|
goto L1a
|
|
Ld:
|
|
java.lang.Object r1 = r5.obj // Catch: java.lang.Throwable -> L26
|
|
java.lang.Exception r1 = (java.lang.Exception) r1 // Catch: java.lang.Throwable -> L26
|
|
int r5 = r5.arg1 // Catch: java.lang.Throwable -> L26
|
|
r4.b(r1, r5) // Catch: java.lang.Throwable -> L26
|
|
goto L1a
|
|
L17:
|
|
r4.j() // Catch: java.lang.Throwable -> L26
|
|
L1a:
|
|
r4.j = r3
|
|
java.lang.Thread r5 = r4.k
|
|
if (r5 == 0) goto L25
|
|
java.lang.Thread r5 = r4.k
|
|
java.util.concurrent.locks.LockSupport.unpark(r5)
|
|
L25:
|
|
return r0
|
|
L26:
|
|
r5 = move-exception
|
|
r4.j = r3
|
|
java.lang.Thread r0 = r4.k
|
|
if (r0 == 0) goto L32
|
|
java.lang.Thread r0 = r4.k
|
|
java.util.concurrent.locks.LockSupport.unpark(r0)
|
|
L32:
|
|
throw r5
|
|
*/
|
|
throw new UnsupportedOperationException("Method not decompiled: com.liulishuo.filedownloader.download.DownloadStatusCallback.handleMessage(android.os.Message):boolean");
|
|
}
|
|
|
|
private Exception b(Exception exc) {
|
|
long length;
|
|
String tempFilePath = this.a.getTempFilePath();
|
|
if ((!this.a.isChunked() && !FileDownloadProperties.a().f) || !(exc instanceof IOException) || !new File(tempFilePath).exists()) {
|
|
return exc;
|
|
}
|
|
long h = FileDownloadUtils.h(tempFilePath);
|
|
if (h > 4096) {
|
|
return exc;
|
|
}
|
|
File file = new File(tempFilePath);
|
|
if (file.exists()) {
|
|
length = file.length();
|
|
} else {
|
|
FileDownloadLog.a(this, exc, "Exception with: free space isn't enough, and the target file not exist.", new Object[0]);
|
|
length = 0;
|
|
}
|
|
return Build.VERSION.SDK_INT >= 9 ? new FileDownloadOutOfSpaceException(h, 4096L, length, exc) : new FileDownloadOutOfSpaceException(h, 4096L, length);
|
|
}
|
|
|
|
private void c(Exception exc) {
|
|
Exception exc2;
|
|
Exception b = b(exc);
|
|
if (b instanceof SQLiteFullException) {
|
|
a((SQLiteFullException) b);
|
|
exc2 = b;
|
|
} else {
|
|
try {
|
|
this.a.setStatus((byte) -1);
|
|
this.a.setErrMsg(exc.toString());
|
|
this.b.a(this.a.getId(), b, this.a.getSoFar());
|
|
exc2 = b;
|
|
} catch (SQLiteFullException e) {
|
|
SQLiteFullException sQLiteFullException = e;
|
|
a(sQLiteFullException);
|
|
exc2 = sQLiteFullException;
|
|
}
|
|
}
|
|
this.c.a(exc2);
|
|
a((byte) -1);
|
|
}
|
|
|
|
void a(boolean z, long j, String str, String str2) throws IllegalArgumentException {
|
|
String eTag = this.a.getETag();
|
|
if (eTag != null && !eTag.equals(str)) {
|
|
throw new IllegalArgumentException(FileDownloadUtils.a("callback onConnected must with precondition succeed, but the etag is changes(%s != %s)", str, eTag));
|
|
}
|
|
this.c.a(z);
|
|
this.a.setStatus((byte) 2);
|
|
this.a.setTotal(j);
|
|
this.a.setETag(str);
|
|
this.a.setFilename(str2);
|
|
this.b.a(this.a.getId(), j, str, str2);
|
|
a((byte) 2);
|
|
this.g = a(j, this.f);
|
|
this.o.compareAndSet(false, true);
|
|
}
|
|
|
|
private void b(Exception exc, int i) {
|
|
Exception b = b(exc);
|
|
this.c.a(b);
|
|
this.c.a(this.d - i);
|
|
this.a.setStatus((byte) 5);
|
|
this.a.setErrMsg(b.toString());
|
|
this.b.a(this.a.getId(), b);
|
|
a((byte) 5);
|
|
}
|
|
|
|
private void b(long j) {
|
|
boolean z;
|
|
if (!this.p.compareAndSet(true, false)) {
|
|
long j2 = j - this.l;
|
|
if (this.g == -1 || this.m.get() < this.g || j2 < this.e) {
|
|
z = false;
|
|
if (z || !this.n.compareAndSet(false, true)) {
|
|
}
|
|
if (FileDownloadLog.a) {
|
|
FileDownloadLog.c(this, "inspectNeedCallbackToUser need callback to user", new Object[0]);
|
|
}
|
|
this.l = j;
|
|
this.m.set(0L);
|
|
return;
|
|
}
|
|
}
|
|
z = true;
|
|
if (z) {
|
|
}
|
|
}
|
|
|
|
void a(long j) {
|
|
this.m.addAndGet(j);
|
|
this.a.increaseSoFar(j);
|
|
b(SystemClock.elapsedRealtime());
|
|
if (this.h == null) {
|
|
j();
|
|
} else if (this.n.get()) {
|
|
a(this.h.obtainMessage(3));
|
|
}
|
|
}
|
|
|
|
void a(Exception exc, int i) {
|
|
this.m.set(0L);
|
|
Handler handler = this.h;
|
|
if (handler == null) {
|
|
b(exc, i);
|
|
} else {
|
|
a(handler.obtainMessage(5, i, 0, exc));
|
|
}
|
|
}
|
|
|
|
void a(Exception exc) {
|
|
c(exc);
|
|
}
|
|
|
|
private synchronized void a(Message message) {
|
|
if (!this.i.isAlive()) {
|
|
if (FileDownloadLog.a) {
|
|
FileDownloadLog.a(this, "require callback %d but the host thread of the flow has already dead, what is occurred because of there are several reason can final this flow on different thread.", Integer.valueOf(message.what));
|
|
}
|
|
return;
|
|
}
|
|
try {
|
|
this.h.sendMessage(message);
|
|
} catch (IllegalStateException e) {
|
|
if (!this.i.isAlive()) {
|
|
if (FileDownloadLog.a) {
|
|
FileDownloadLog.a(this, "require callback %d but the host thread of the flow has already dead, what is occurred because of there are several reason can final this flow on different thread.", Integer.valueOf(message.what));
|
|
}
|
|
} else {
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static long a(long j, long j2) {
|
|
if (j2 <= 0) {
|
|
return -1L;
|
|
}
|
|
if (j == -1) {
|
|
return 1L;
|
|
}
|
|
long j3 = j / j2;
|
|
if (j3 <= 0) {
|
|
return 1L;
|
|
}
|
|
return j3;
|
|
}
|
|
|
|
private void a(SQLiteFullException sQLiteFullException) {
|
|
int id = this.a.getId();
|
|
if (FileDownloadLog.a) {
|
|
FileDownloadLog.a(this, "the data of the task[%d] is dirty, because the SQLite full exception[%s], so remove it from the database directly.", Integer.valueOf(id), sQLiteFullException.toString());
|
|
}
|
|
this.a.setErrMsg(sQLiteFullException.toString());
|
|
this.a.setStatus((byte) -1);
|
|
this.b.remove(id);
|
|
this.b.b(id);
|
|
}
|
|
|
|
private void a(byte b) {
|
|
if (b == -2) {
|
|
if (FileDownloadLog.a) {
|
|
FileDownloadLog.a(this, "High concurrent cause, Already paused and we don't need to call-back to Task in here, %d", Integer.valueOf(this.a.getId()));
|
|
return;
|
|
}
|
|
return;
|
|
}
|
|
MessageSnapshotFlow.a().a(MessageSnapshotTaker.a(b, this.a, this.c));
|
|
}
|
|
}
|