Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion app/src/main/java/us/shandian/giga/get/DownloadMission.java
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,8 @@ public void psContinue(boolean recover) {
* @return {@code true}, if storage is invalid and cannot be used
*/
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();
}

/**
Expand Down
60 changes: 48 additions & 12 deletions app/src/main/java/us/shandian/giga/service/DownloadManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import us.shandian.giga.util.Utility;

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 {
private static final String TAG = DownloadManager.class.getSimpleName();
Expand Down Expand Up @@ -149,12 +151,31 @@ private void loadPendingMissions(Context ctx) {
if (sub.getName().equals(".tmp")) continue;

DownloadMission mis = Utility.readFromFile(sub);
if (mis == null || mis.isFinished() || mis.hasInvalidStorage()) {
if (mis == null) {
//noinspection ResultOfMethodCallIgnored
sub.delete();
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) {
Comment thread
whistlingwoods marked this conversation as resolved.
Outdated
//noinspection ResultOfMethodCallIgnored
sub.delete();
continue;
}
}

mis.threads = new Thread[0];

boolean exists;
Expand All @@ -163,16 +184,13 @@ private void loadPendingMissions(Context ctx) {
exists = !mis.storage.isInvalid() && mis.storage.existsAsFile();
} catch (Exception 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;
}

if (mis.isPsRunning()) {
if (mis.psAlgorithm.worksOnSameFile) {
// 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())
Log.w(TAG, "Unable to delete incomplete download file: " + sub.getPath());
}
Expand All @@ -181,10 +199,11 @@ private void loadPendingMissions(Context ctx) {
mis.errCode = DownloadMission.ERROR_POSTPROCESSING_STOPPED;
} else if (!exists) {
tryRecover(mis);

// the progress is lost, reset mission state
if (mis.isInitialized())
mis.resetState(true, true, DownloadMission.ERROR_PROGRESS_LOST);
// Keep the mission even if recovery fails - don't reset to ERROR_PROGRESS_LOST
// This allows user to see the failed download and potentially retry
if (mis.isInitialized() && mis.errCode == ERROR_NOTHING) {
mis.resetState(true, true, ERROR_PROGRESS_LOST);
}
}

if (mis.psAlgorithm != null) {
Expand Down Expand Up @@ -446,7 +465,7 @@ boolean runMissions() {
continue;

resumeMission(mission);
if (mission.errCode != DownloadMission.ERROR_NOTHING) continue;
if (mission.errCode != ERROR_NOTHING) continue;

if (mPrefQueueLimit) return true;
flag = true;
Expand Down Expand Up @@ -510,6 +529,15 @@ void updateMaximumAttempts() {
}
}

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) {
synchronized (this) {
DownloadMission pending = getPendingMission(storage);
Expand Down Expand Up @@ -582,8 +610,16 @@ private ArrayList<Object> getSpecialItems() {
ArrayList<Mission> finished = new ArrayList<>(mMissionsFinished);
List<Mission> remove = new ArrayList<>(hidden);

// hide missions (if required)
remove.removeIf(mission -> pending.remove(mission) || finished.remove(mission));
// Don't hide recoverable missions
remove.removeIf(mission -> {
if (mission instanceof DownloadMission) {
DownloadMission dm = (DownloadMission) mission;
if (canRecoverMission(dm)) {
return false; // Don't remove recoverable missions
}
}
Comment thread
whistlingwoods marked this conversation as resolved.
Outdated
return pending.remove(mission) || finished.remove(mission);
});

int fakeTotal = pending.size();
if (fakeTotal > 0) fakeTotal++;
Expand Down