Skip to content

ADFA-4576 (F1 slice 1): carve the OTA self-updater into UpdateController#140

Merged
luisguzman-adfa merged 1 commit into
mainfrom
feat/ADFA-4576-update-controller
Jul 7, 2026
Merged

ADFA-4576 (F1 slice 1): carve the OTA self-updater into UpdateController#140
luisguzman-adfa merged 1 commit into
mainfrom
feat/ADFA-4576-update-controller

Conversation

@luisguzman-adfa

@luisguzman-adfa luisguzman-adfa commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Context

F1 in TECH_DEBT_PLAN.md: MainActivity (~2288 LOC) is the last god class. This is the first slice of its carve, using the same Controller seam as DeployFragment/SyncFragment. The OTA self-updater is fully self-contained (Activity-scoped, no callbacks back into MainActivity), so no Host is needed — the controller just takes the AppCompatActivity.

Changes

  • New update/presentation/UpdateController — owns the whole OTA flow: checkForUpdates, the update dialog, the download (staged in the app's private external dir), the DownloadManager completion receiver, same-certificate ApkVerifier check, the in-app progress dialog (renderUpdateState) and the install hand-off (FileProvider + unknown-sources permission). Sits on the existing layered update/ slice (UpdateViewModel/UpdateUiState/ApkVerifier/UpdateViewModelFactory — same package, no new domain code). The manual-trigger 10s cooldown moved in as checkForUpdatesManual().
  • MainActivity — removed the 4 OTA fields, the downloadReceiver, and the 10 OTA methods. Now updateController = new UpdateController(this) in onCreate; the version-footer tap/click call updateController.checkForUpdatesManual(); onResume/onPause forward register/unregisterDownloadReceiver(); startup check is updateController.checkForUpdates(false). 2288 → 1918 LOC (−370).

Behaviour-preserving. The version-footer long-press (terminal spawn) stays in MainActivity — it belongs to the terminal slice (next).

Verification (sandbox)

  • No javac here (JRE only) — please build :app:lintDebug + assembleDebug.
  • No remaining reference in MainActivity to any removed OTA symbol (only the three updateController.* calls remain).
  • Brace balance: MainActivity 289/289, UpdateController 64/64.
  • API match confirmed: UpdateViewModelFactory(Context), UpdateViewModel.track/onReady/onInstalling/onError/cancel/state, UpdateUiState.Status + fields, ApkVerifier.isSignedBySameCertAsApp(Context, File).

Test (device)

  1. Build + lint pass.
  2. Tap the version footer → "checking…" toast; if up to date → "latest" toast (10s cooldown). Long-press (3s) still opens the terminal.
  3. Higher server version → update dialog → download → in-app progress → Install (signature verified; unknown-sources prompt on API 26+) → system installer.
  4. A corrupt/HTML "apk" fails verification and does not install.

Next slices (same F1 family, separate PRs)

  • addNewTerminalSession() (~730 LOC) → a terminal-session controller.
  • Server launch/lifecycle → a server-control controller.

First slice of the MainActivity god-class carve (F1). Moves the OTA self-update
glue out of MainActivity into update/presentation/UpdateController, mirroring the
Controller seam used for DeployFragment/SyncFragment. No Host needed — the flow
is self-contained (Activity-scoped), so the controller just takes the Activity.

- New UpdateController: owns checkForUpdates, the update dialog, the download
  (staged in the app's private external dir), the DownloadManager receiver,
  same-cert signature verification, the in-app progress dialog and the install
  hand-off. Sits on the existing update/ slice (UpdateViewModel/ApkVerifier).
  Cooldown for the manual trigger moved in as checkForUpdatesManual().
- MainActivity: dropped the 4 OTA fields, the downloadReceiver and the 10 OTA
  methods; the version-footer tap/click now calls updateController.checkForUpdatesManual(),
  onResume/onPause forward register/unregister, and the initial check is
  updateController.checkForUpdates(false). 2288 -> 1918 LOC (-370).

Behaviour-preserving.
@luisguzman-adfa luisguzman-adfa merged commit b3926cf into main Jul 7, 2026
1 check passed
@luisguzman-adfa luisguzman-adfa deleted the feat/ADFA-4576-update-controller branch July 7, 2026 03:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant