24
24
import us .shandian .giga .util .Utility ;
25
25
26
26
import 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 ;
27
29
28
30
public class DownloadManager {
29
31
private static final String TAG = DownloadManager .class .getSimpleName ();
@@ -149,12 +151,31 @@ private void loadPendingMissions(Context ctx) {
149
151
if (sub .getName ().equals (".tmp" )) continue ;
150
152
151
153
DownloadMission mis = Utility .readFromFile (sub );
152
- if (mis == null || mis . isFinished () || mis . hasInvalidStorage () ) {
154
+ if (mis == null ) {
153
155
//noinspection ResultOfMethodCallIgnored
154
156
sub .delete ();
155
157
continue ;
156
158
}
157
159
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 && mis .errCode != ERROR_PROGRESS_LOST ) {
173
+ //noinspection ResultOfMethodCallIgnored
174
+ sub .delete ();
175
+ continue ;
176
+ }
177
+ }
178
+
158
179
mis .threads = new Thread [0 ];
159
180
160
181
boolean exists ;
@@ -163,16 +184,13 @@ private void loadPendingMissions(Context ctx) {
163
184
exists = !mis .storage .isInvalid () && mis .storage .existsAsFile ();
164
185
} catch (Exception ex ) {
165
186
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
167
188
exists = false ;
168
189
}
169
190
170
191
if (mis .isPsRunning ()) {
171
192
if (mis .psAlgorithm .worksOnSameFile ) {
172
193
// 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)
176
194
if (exists && mis .storage .isDirect () && !mis .storage .delete ())
177
195
Log .w (TAG , "Unable to delete incomplete download file: " + sub .getPath ());
178
196
}
@@ -181,10 +199,11 @@ private void loadPendingMissions(Context ctx) {
181
199
mis .errCode = DownloadMission .ERROR_POSTPROCESSING_STOPPED ;
182
200
} else if (!exists ) {
183
201
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
+ }
188
207
}
189
208
190
209
if (mis .psAlgorithm != null ) {
@@ -446,7 +465,7 @@ boolean runMissions() {
446
465
continue ;
447
466
448
467
resumeMission (mission );
449
- if (mission .errCode != DownloadMission . ERROR_NOTHING ) continue ;
468
+ if (mission .errCode != ERROR_NOTHING ) continue ;
450
469
451
470
if (mPrefQueueLimit ) return true ;
452
471
flag = true ;
@@ -510,6 +529,15 @@ void updateMaximumAttempts() {
510
529
}
511
530
}
512
531
532
+ public boolean canRecoverMission (DownloadMission mission ) {
533
+ if (mission == null ) return false ;
534
+
535
+ // Can recover missions with progress lost or storage issues
536
+ return mission .errCode == ERROR_PROGRESS_LOST ||
537
+ mission .storage == null ||
538
+ !mission .storage .existsAsFile ();
539
+ }
540
+
513
541
public MissionState checkForExistingMission (StoredFileHelper storage ) {
514
542
synchronized (this ) {
515
543
DownloadMission pending = getPendingMission (storage );
@@ -582,8 +610,16 @@ private ArrayList<Object> getSpecialItems() {
582
610
ArrayList <Mission > finished = new ArrayList <>(mMissionsFinished );
583
611
List <Mission > remove = new ArrayList <>(hidden );
584
612
585
- // hide missions (if required)
586
- remove .removeIf (mission -> pending .remove (mission ) || finished .remove (mission ));
613
+ // Don't hide recoverable missions
614
+ remove .removeIf (mission -> {
615
+ if (mission instanceof DownloadMission ) {
616
+ DownloadMission dm = (DownloadMission ) mission ;
617
+ if (canRecoverMission (dm )) {
618
+ return false ; // Don't remove recoverable missions
619
+ }
620
+ }
621
+ return pending .remove (mission ) || finished .remove (mission );
622
+ });
587
623
588
624
int fakeTotal = pending .size ();
589
625
if (fakeTotal > 0 ) fakeTotal ++;
0 commit comments