feat(update): serialize update processing and fix ConcurrentModificationException
Description
Review commit-by-commit for full context.
Process update installations sequentially to prevent batch update conflicts. Centralizes WorkManager dispatch into InstallOrchestrator and fixes ConcurrentModificationException.
Changes:
- Updates run sequentially — next starts after previous finishes
- WorkManager enqueue moved from InstallationEnqueuer → InstallOrchestrator
- Fixed ConcurrentModificationException in UpdatesWorker and UpdatesDao
- Restored install button in UpdatesFragment when progress tracking fails
Screenshots
Technical details
Serialization: InstallOrchestrator monitors download status + active WorkManager install work. Conflated Channel coalesces reevaluation requests. One AWAITING item dequeued at a time.
isUpdateRequest flag: New AppInstall field distinguishes updates from fresh installs. Set in AppInstallationFacade when application.status == Status.UPDATABLE. InstallationCompletionHandler uses it to prevent premature "updates completed" notifications.
Migration (7→8): Adds isUpdateRequest column, backfills rows where orgStatus = 'UPDATABLE'.
ConcurrentModificationException fixes: UpdatesWorker snapshots list before iteration. UpdatesDao returns .toList() copies instead of exposing mutable lists.
UI: DownloadProgressTracker returns -1 when app not found. UpdatesFragment restores install button on this signal. ApplicationListRVAdapter extracted bindInstallControls() for reuse.
Tests
Issues
https://gitlab.e.foundation/e/os/backlog/-/work_items/4235