mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2025-10-20 18:07:38 +00:00
fix: unfinished downloads disappear from the downloads list after app gets killed
Author: InfinityLoop1308
Adapted for NewPipe from a fork's this commit 1cf059ce5e
This commit is contained in:
@@ -661,7 +661,8 @@ public class DownloadMission extends Mission {
|
|||||||
* @return {@code true}, if storage is invalid and cannot be used
|
* @return {@code true}, if storage is invalid and cannot be used
|
||||||
*/
|
*/
|
||||||
public boolean hasInvalidStorage() {
|
public boolean hasInvalidStorage() {
|
||||||
return errCode == ERROR_PROGRESS_LOST || storage == null || !storage.existsAsFile();
|
// Don't consider ERROR_PROGRESS_LOST as invalid storage - it can be recovered
|
||||||
|
return storage == null || !storage.existsAsFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -24,6 +24,8 @@ import org.schabi.newpipe.streams.io.StoredFileHelper;
|
|||||||
import us.shandian.giga.util.Utility;
|
import us.shandian.giga.util.Utility;
|
||||||
|
|
||||||
import static org.schabi.newpipe.BuildConfig.DEBUG;
|
import static org.schabi.newpipe.BuildConfig.DEBUG;
|
||||||
|
import static us.shandian.giga.get.DownloadMission.ERROR_NOTHING;
|
||||||
|
import static us.shandian.giga.get.DownloadMission.ERROR_PROGRESS_LOST;
|
||||||
|
|
||||||
public class DownloadManager {
|
public class DownloadManager {
|
||||||
private static final String TAG = DownloadManager.class.getSimpleName();
|
private static final String TAG = DownloadManager.class.getSimpleName();
|
||||||
@@ -149,12 +151,31 @@ public class DownloadManager {
|
|||||||
if (sub.getName().equals(".tmp")) continue;
|
if (sub.getName().equals(".tmp")) continue;
|
||||||
|
|
||||||
DownloadMission mis = Utility.readFromFile(sub);
|
DownloadMission mis = Utility.readFromFile(sub);
|
||||||
if (mis == null || mis.isFinished() || mis.hasInvalidStorage()) {
|
if (mis == null) {
|
||||||
//noinspection ResultOfMethodCallIgnored
|
//noinspection ResultOfMethodCallIgnored
|
||||||
sub.delete();
|
sub.delete();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DON'T delete missions that are truly finished - let them be moved to finished list
|
||||||
|
if (mis.isFinished()) {
|
||||||
|
// Move to finished missions instead of deleting
|
||||||
|
setFinished(mis);
|
||||||
|
//noinspection ResultOfMethodCallIgnored
|
||||||
|
sub.delete();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DON'T delete missions with storage issues - try to recover them
|
||||||
|
if (mis.hasInvalidStorage() && mis.errCode != ERROR_PROGRESS_LOST) {
|
||||||
|
// Only delete if it's truly unrecoverable (not just progress lost)
|
||||||
|
if (mis.storage == null && mis.errCode != ERROR_PROGRESS_LOST) {
|
||||||
|
//noinspection ResultOfMethodCallIgnored
|
||||||
|
sub.delete();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mis.threads = new Thread[0];
|
mis.threads = new Thread[0];
|
||||||
|
|
||||||
boolean exists;
|
boolean exists;
|
||||||
@@ -163,16 +184,13 @@ public class DownloadManager {
|
|||||||
exists = !mis.storage.isInvalid() && mis.storage.existsAsFile();
|
exists = !mis.storage.isInvalid() && mis.storage.existsAsFile();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Log.e(TAG, "Failed to load the file source of " + mis.storage.toString(), ex);
|
Log.e(TAG, "Failed to load the file source of " + mis.storage.toString(), ex);
|
||||||
mis.storage.invalidate();
|
// Don't invalidate storage immediately - try to recover first
|
||||||
exists = false;
|
exists = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mis.isPsRunning()) {
|
if (mis.isPsRunning()) {
|
||||||
if (mis.psAlgorithm.worksOnSameFile) {
|
if (mis.psAlgorithm.worksOnSameFile) {
|
||||||
// Incomplete post-processing results in a corrupted download file
|
// Incomplete post-processing results in a corrupted download file
|
||||||
// because the selected algorithm works on the same file to save space.
|
|
||||||
// the file will be deleted if the storage API
|
|
||||||
// is Java IO (avoid showing the "Save as..." dialog)
|
|
||||||
if (exists && mis.storage.isDirect() && !mis.storage.delete())
|
if (exists && mis.storage.isDirect() && !mis.storage.delete())
|
||||||
Log.w(TAG, "Unable to delete incomplete download file: " + sub.getPath());
|
Log.w(TAG, "Unable to delete incomplete download file: " + sub.getPath());
|
||||||
}
|
}
|
||||||
@@ -181,10 +199,11 @@ public class DownloadManager {
|
|||||||
mis.errCode = DownloadMission.ERROR_POSTPROCESSING_STOPPED;
|
mis.errCode = DownloadMission.ERROR_POSTPROCESSING_STOPPED;
|
||||||
} else if (!exists) {
|
} else if (!exists) {
|
||||||
tryRecover(mis);
|
tryRecover(mis);
|
||||||
|
// Keep the mission even if recovery fails - don't reset to ERROR_PROGRESS_LOST
|
||||||
// the progress is lost, reset mission state
|
// This allows user to see the failed download and potentially retry
|
||||||
if (mis.isInitialized())
|
if (mis.isInitialized() && mis.errCode == ERROR_NOTHING) {
|
||||||
mis.resetState(true, true, DownloadMission.ERROR_PROGRESS_LOST);
|
mis.resetState(true, true, ERROR_PROGRESS_LOST);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mis.psAlgorithm != null) {
|
if (mis.psAlgorithm != null) {
|
||||||
@@ -446,7 +465,7 @@ public class DownloadManager {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
resumeMission(mission);
|
resumeMission(mission);
|
||||||
if (mission.errCode != DownloadMission.ERROR_NOTHING) continue;
|
if (mission.errCode != ERROR_NOTHING) continue;
|
||||||
|
|
||||||
if (mPrefQueueLimit) return true;
|
if (mPrefQueueLimit) return true;
|
||||||
flag = true;
|
flag = true;
|
||||||
@@ -510,6 +529,15 @@ public class DownloadManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean canRecoverMission(DownloadMission mission) {
|
||||||
|
if (mission == null) return false;
|
||||||
|
|
||||||
|
// Can recover missions with progress lost or storage issues
|
||||||
|
return mission.errCode == ERROR_PROGRESS_LOST ||
|
||||||
|
mission.storage == null ||
|
||||||
|
!mission.storage.existsAsFile();
|
||||||
|
}
|
||||||
|
|
||||||
public MissionState checkForExistingMission(StoredFileHelper storage) {
|
public MissionState checkForExistingMission(StoredFileHelper storage) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
DownloadMission pending = getPendingMission(storage);
|
DownloadMission pending = getPendingMission(storage);
|
||||||
@@ -582,8 +610,16 @@ public class DownloadManager {
|
|||||||
ArrayList<Mission> finished = new ArrayList<>(mMissionsFinished);
|
ArrayList<Mission> finished = new ArrayList<>(mMissionsFinished);
|
||||||
List<Mission> remove = new ArrayList<>(hidden);
|
List<Mission> remove = new ArrayList<>(hidden);
|
||||||
|
|
||||||
// hide missions (if required)
|
// Don't hide recoverable missions
|
||||||
remove.removeIf(mission -> pending.remove(mission) || finished.remove(mission));
|
remove.removeIf(mission -> {
|
||||||
|
if (mission instanceof DownloadMission) {
|
||||||
|
DownloadMission dm = (DownloadMission) mission;
|
||||||
|
if (canRecoverMission(dm)) {
|
||||||
|
return false; // Don't remove recoverable missions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pending.remove(mission) || finished.remove(mission);
|
||||||
|
});
|
||||||
|
|
||||||
int fakeTotal = pending.size();
|
int fakeTotal = pending.size();
|
||||||
if (fakeTotal > 0) fakeTotal++;
|
if (fakeTotal > 0) fakeTotal++;
|
||||||
|
Reference in New Issue
Block a user