mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-08-08 06:46:11 +00:00
fix: observe cancellation before promoting a verified APK
Codex is right about this one. Cancellation in Kotlin is cooperative, and everything from validateDownloadedApk() through saveMetadata() is plain blocking code with no suspension point. Stopping during the signature check was therefore not observed until after the temp file had been renamed and its metadata written, so the worker committed the APK while WorkManager reported the work cancelled. That also raced onCancelDownload(): its checkStatus() could read the cache before the commit and settle on NotDownloaded, after which the cancelled work maps to Idle and the observer ignores it. The row then advertised "Not ready" with a verified universal APK already in the cache, and tapping it downloaded the same bytes again. One checkpoint after validation, which is the slow step and so the most likely moment to press Stop. The verified temp file is left in place, so the next attempt resumes rather than starting over. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
408d1c760a
commit
b60b5121aa
@ -9,6 +9,7 @@ import com.bitchat.android.net.ArtiTorManager
|
||||
import com.bitchat.android.net.OkHttpProvider
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ensureActive
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import kotlinx.coroutines.withContext
|
||||
import okhttp3.Call
|
||||
@ -217,6 +218,12 @@ class UniversalApkManager(
|
||||
phaseCallback?.invoke(ApkDownloader.DownloadPhase.VerifyingSignature)
|
||||
validateDownloadedApk(tempFile, source)
|
||||
|
||||
// Everything from here to the metadata write is plain blocking code, so a
|
||||
// cancellation arriving during the (slow) signature check would otherwise go
|
||||
// unobserved and commit the APK anyway. The verified temp file survives for
|
||||
// resume; only the promotion is abandoned.
|
||||
ensureActive()
|
||||
|
||||
val version = downloadedVersionName(tempFile)
|
||||
val safeVersion = version.replace(Regex("[^A-Za-z0-9._-]"), "_")
|
||||
val finalFileName = "$APK_FILE_PREFIX$safeVersion.apk"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user