2424import us .shandian .giga .util .Utility ;
2525
2626import static org .schabi .newpipe .BuildConfig .DEBUG ;
27+ import static us .shandian .giga .get .DownloadMission .ERROR_NOTHING ;
28+ import static us .shandian .giga .get .DownloadMission .ERROR_PROGRESS_LOST ;
2729
2830public class DownloadManager {
2931 private static final String TAG = DownloadManager .class .getSimpleName ();
@@ -149,12 +151,31 @@ private void loadPendingMissions(Context ctx) {
149151 if (sub .getName ().equals (".tmp" )) continue ;
150152
151153 DownloadMission mis = Utility .readFromFile (sub );
152- if (mis == null || mis . isFinished () || mis . hasInvalidStorage () ) {
154+ if (mis == null ) {
153155 //noinspection ResultOfMethodCallIgnored
154156 sub .delete ();
155157 continue ;
156158 }
157159
160+ // DON'T delete missions that are truly finished - let them be moved to finished list
161+ if (mis .isFinished ()) {
162+ // Move to finished missions instead of deleting
163+ setFinished (mis );
164+ //noinspection ResultOfMethodCallIgnored
165+ sub .delete ();
166+ continue ;
167+ }
168+
169+ // DON'T delete missions with storage issues - try to recover them
170+ if (mis .hasInvalidStorage () && mis .errCode != ERROR_PROGRESS_LOST ) {
171+ // Only delete if it's truly unrecoverable (not just progress lost)
172+ if (mis .storage == null ) {
173+ //noinspection ResultOfMethodCallIgnored
174+ sub .delete ();
175+ continue ;
176+ }
177+ }
178+
158179 mis .threads = new Thread [0 ];
159180
160181 boolean exists ;
@@ -163,16 +184,13 @@ private void loadPendingMissions(Context ctx) {
163184 exists = !mis .storage .isInvalid () && mis .storage .existsAsFile ();
164185 } catch (Exception ex ) {
165186 Log .e (TAG , "Failed to load the file source of " + mis .storage .toString (), ex );
166- mis . storage . invalidate ();
187+ // Don't invalidate storage immediately - try to recover first
167188 exists = false ;
168189 }
169190
170191 if (mis .isPsRunning ()) {
171192 if (mis .psAlgorithm .worksOnSameFile ) {
172193 // Incomplete post-processing results in a corrupted download file
173- // because the selected algorithm works on the same file to save space.
174- // the file will be deleted if the storage API
175- // is Java IO (avoid showing the "Save as..." dialog)
176194 if (exists && mis .storage .isDirect () && !mis .storage .delete ())
177195 Log .w (TAG , "Unable to delete incomplete download file: " + sub .getPath ());
178196 }
@@ -181,10 +199,11 @@ private void loadPendingMissions(Context ctx) {
181199 mis .errCode = DownloadMission .ERROR_POSTPROCESSING_STOPPED ;
182200 } else if (!exists ) {
183201 tryRecover (mis );
184-
185- // the progress is lost, reset mission state
186- if (mis .isInitialized ())
187- mis .resetState (true , true , DownloadMission .ERROR_PROGRESS_LOST );
202+ // Keep the mission even if recovery fails - don't reset to ERROR_PROGRESS_LOST
203+ // This allows user to see the failed download and potentially retry
204+ if (mis .isInitialized () && mis .errCode == ERROR_NOTHING ) {
205+ mis .resetState (true , true , ERROR_PROGRESS_LOST );
206+ }
188207 }
189208
190209 if (mis .psAlgorithm != null ) {
@@ -448,7 +467,7 @@ boolean runMissions() {
448467 continue ;
449468
450469 resumeMission (mission );
451- if (mission .errCode != DownloadMission . ERROR_NOTHING ) continue ;
470+ if (mission .errCode != ERROR_NOTHING ) continue ;
452471
453472 if (mPrefQueueLimit ) return true ;
454473 flag = true ;
@@ -512,6 +531,15 @@ void updateMaximumAttempts() {
512531 }
513532 }
514533
534+ public boolean canRecoverMission (DownloadMission mission ) {
535+ if (mission == null ) return false ;
536+
537+ // Can recover missions with progress lost or storage issues
538+ return mission .errCode == ERROR_PROGRESS_LOST ||
539+ mission .storage == null ||
540+ !mission .storage .existsAsFile ();
541+ }
542+
515543 public MissionState checkForExistingMission (StoredFileHelper storage ) {
516544 synchronized (this ) {
517545 DownloadMission pending = getPendingMission (storage );
@@ -584,8 +612,13 @@ private ArrayList<Object> getSpecialItems() {
584612 ArrayList <Mission > finished = new ArrayList <>(mMissionsFinished );
585613 List <Mission > remove = new ArrayList <>(hidden );
586614
587- // hide missions (if required)
588- remove .removeIf (mission -> pending .remove (mission ) || finished .remove (mission ));
615+ // Don't hide recoverable missions
616+ remove .removeIf (mission -> {
617+ if (mission instanceof DownloadMission dm && canRecoverMission (dm )) {
618+ return false ; // Don't remove recoverable missions
619+ }
620+ return pending .remove (mission ) || finished .remove (mission );
621+ });
589622
590623 int fakeTotal = pending .size ();
591624 if (fakeTotal > 0 ) fakeTotal ++;
0 commit comments