fix(app-update): android downloadAPK Range/.partial resume#58
Open
huhuanming wants to merge 3 commits into
Open
fix(app-update): android downloadAPK Range/.partial resume#58huhuanming wants to merge 3 commits into
huhuanming wants to merge 3 commits into
Conversation
…tate verify
The Android downloadAPK path wrote bytes straight to the final filePath and
verified an existing APK by booleanly comparing it against a freshly-fetched
SHA256SUMS.asc. When the network dropped mid-download every retry path landed
on "ASC unreachable → existing APK invalid → delete" and restarted from byte
zero, throwing away the previously-downloaded bytes on every reconnect.
Mirror the proven react-native-bundle-update pattern:
- In-flight bytes live in <filePath>.partial; the final path only ever
holds a fully transferred APK. Old half-baked files at the final path
are promoted to .partial so existing installs benefit from resume on
the next attempt.
- Resume via `Range: bytes=<offset>-`; handle 206 (append), 200 (server
ignored Range → restart), and 416 with Content-Range recovery for the
crashed-just-before-rename case.
- verifyExistingApk returns an ApkVerifyOutcome tri-state — Valid /
HashMismatch / Indeterminate. Indeterminate (ASC fetch failure, ASC
parse failure, etc.) preserves the partial and bubbles up a transient
error so the JS retry layer can wait for network instead of wiping
the bytes preemptively.
7 tasks
…ck, 206 start check Follow-up on the Range/.partial resume work: - Extract the three-times-duplicated promote+verify+dispatch into `tryPromoteAndVerify` so future tweaks to promotion semantics happen in one place. - `rollbackFinalToPartial` falls back to a stream copy when the same-fs rename fails, so a transient FS hiccup cannot wipe the only copy of an already-downloaded payload. - Validate `Content-Range: bytes start-end/total` on 206 responses — if start ≠ requested offset (CDN bug / proxy rewrite), demote to a full restart instead of appending mis-aligned bytes and only catching it at SHA verify. - 416 + hash mismatch now surfaces "server build changed mid-download" instead of the misleading raw "HTTP 416". - Type the deferred-verification error as `ApkVerificationDeferredException` (extends IOException) so JS retry layer can branch on class name instead of substring-matching the message.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
downloadAPKhad noRangesupport and treated the only possible cache hit as "fully-downloaded + ASC-verified or delete". When a download dropped mid-transfer the next attempt deleted the residual bytes and restarted from byte zero.What changed
Mirrors the proven
react-native-bundle-update.downloadBundlepattern:<filePath>.partial; the final path only ever holds a fully transferred APK. Old half-baked files at the final path are promoted to.partialfor one-shot migration of existing installs.Range: bytes=<offset>-. Handles206(append),200(server ignored Range — restart from byte zero), and416withContent-Rangerecovery for the crashed-just-before-rename case.verifyExistingApknow returns anApkVerifyOutcometri-state (Valid/HashMismatch/Indeterminate).Indeterminate(ASC unreachable, ASC parse fail) preserves the partial and bubbles up a transientIOExceptionso the JS retry layer can wait for network instead of deleting bytes preemptively.Test plan
Range: bytes=<offset>-and progress continues from where it left off.existing APK invalid, deleting and re-downloadingmust NOT appear in logs; instead expectcannot verify existing APK (ASC unavailable); preserving file and aborting this attempt..partialon the first run after upgrade.Companion monorepo PR: OneKeyHQ/app-monorepo#11623 (or whatever number — links patch-package wrapper until next release).