Fix double-close panic on DownloadDone: skip re-navigation between HOME-mapped states

Primary fix: checkState() now detects when both old and new states map
to the HOME page (DOWNLOADING_ASSETS and READY) and skips re-navigation.
This prevents destroying and recreating the Home page, which would
close the already-closed DownloadDone channel.

Defense-in-depth: Home.downloadDone flag prevents close if a new Home
page somehow reaches the close path.

12 application tests, 4 page tests, 18 mixer tests (34 total).
Tests cover: prerequisite priority ordering, state blocking on
downloads, non-blocking channel read, double-close guard, download
failure path, and repeated computeState calls.
This commit is contained in:
NeilClack
2026-07-11 16:43:16 -05:00
parent a93e475899
commit 2ef826fe63
3 changed files with 318 additions and 0 deletions
+11
View File
@@ -274,8 +274,19 @@ func (app *Application) checkState() {
return
}
oldState := app.state
app.state = newState
// Both DOWNLOADING_ASSETS and READY map to the HOME page.
// Skip re-navigation when transitioning between them to avoid
// destroying and recreating the Home page (which would close
// the already-closed DownloadDone channel).
oldIsHome := oldState == DOWNLOADING_ASSETS || oldState == READY
newIsHome := newState == DOWNLOADING_ASSETS || newState == READY
if oldIsHome && newIsHome {
return
}
switch newState {
case NEEDS_INTERNET:
app.PageRouter.NavigateTo(page.WIFI)