# background_downloader 9.6.5 — RM003 patch

This is a runtime-only vendoring of the exact published `background_downloader`
9.6.5 package, not a general dependency upgrade. `lib/`, `android/`, `ios/`,
`pubspec.yaml`, and `LICENSE` were copied from that pinned package. Examples,
upstream tests, and documentation are omitted to keep the fork small.

- Upstream: https://github.com/781flyingdutchman/background_downloader
- Published archive: https://pub.dev/api/archives/background_downloader-9.6.5.tar.gz
- Published archive SHA-256 (original application lockfile and pub cache):
  `4df9b2a2d5b78b883ebd4b6338cbc1b541ea3482da24112339468a66a7492b43`
- Upstream `LICENSE` is retained verbatim, including its BSD-3-Clause terms and
  the bundled localstore MIT notice. Preserve these notices in redistribution.
- Package version remains `9.6.5`; the root application's path override selects
  this reviewed copy.

## Only production changes

1. `lib/src/chunk.dart`: `resumeChunkTasks` resumes only chunks whose serialized
   status is not `TaskStatus.complete`. A completed chunk's final file and status
   must remain available to the real parent stitching worker. Completed chunks
   have no resume data; trying to resume them returns false and cancels the parent.
2. `lib/src/desktop/desktop_downloader.dart`: read and retain the parent's resume
   snapshot before enqueue. Enqueue starts a desktop worker which consumes that
   record; rereading after enqueue races the worker and can return null. This
   separate race was reproduced while exercising the actual Linux workers.

## Download crash recovery fixes (0.4.0)

3. `lib/src/permissions.dart`: retain the current request's completer locally;
   a permission callback may arrive before the request method returns. Release the
   shared in-flight slot in `finally`, including dispatch failures.
4. `lib/src/base_downloader.dart`: propagate initialization failures to `ready`,
   and mark readiness only after subclass/background-handler setup completes.
   Await initial connectivity so errors are owned by initialization.
5. `lib/src/base_downloader.dart`: the database update queue reports write errors
   through its flush barrier, including failed-then-successful batches, while
   allowing later recovery. Detached futures no longer leak these errors.

The 0.4.0 fixes above did not modify native downloader sources. Dart regressions for
those paths are in `test/download_android_*_test.dart`. They reproduce callback,
initialization, connectivity and persistence failures on the host; they do not
claim an Android process crash was reproduced without logcat/device evidence.

## In-app transfer fixes (0.4.2)

6. `lib/src/native_downloader.dart`: `enqueueChild` now awaits actual native
   enqueue and acknowledges its Boolean result. Rejection or a dispatch exception
   returns false, allowing the parent to fail instead of waiting forever for a
   nonexistent child. Background-channel tests cover rejection, a pending native
   acknowledgement and an exception without detached errors.
7. Android `BDPlugin.kt` and `DownloadNetworkPolicy.java`: on API 28+, both
   WorkManager and user-initiated JobScheduler jobs use the same explicit INTERNET
   network request, without VALIDATED or NOT_VPN. Wi-Fi transport remains required
   when the effective task policy is Wi-Fi-only. This avoids making successful
   external OS connectivity validation a prerequisite for a reachable media host.
   Older Android versions retain their original compatible scheduler constraints.

Application-side changes are outside this fork: multipart is selected only after
the server advertises the HEAD/length/range capabilities the native worker needs;
otherwise a normal streaming GET is used. A manual retry of failed multipart work
also uses a single stream and restores its ordinary retry budget.

