Moe Hamade 05896f354d fix: route every hotspot failure through one teardown path
Addresses three issues from Codex review on #808.

The Wi-Fi Aware hold could be defeated by a race. startIfPossible()
does a long stretch of async work between checking the hold and
assigning the service, so holdForHotspot() landing in that window
left an in-flight start free to resurrect NAN behind the hotspot's
back, putting every P2P attempt back on BUSY. The hold is now
rechecked before committing the service, and the freshly started
service is torn down if the hotspot claimed the radio meanwhile.

Startup error paths bypassed cleanup. A web-server failure, a null
connection info, or a throw from the outer block stopped the manager
but left the Aware hold set, blocking all mesh starts until the user
happened to retry or close the screen. Worse, an error after the
server had started left it serving the APK on port 9999 -- including
after the device reconnected to an ordinary Wi-Fi network -- because
only stopHotspot() cleared it.

Both follow from the same gap: cleanup lived at the call sites rather
than in one place. All failures now go through failWith(), which
shares teardown() with stopHotspot() and releases the server, the
manager and the hold together.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 13:09:04 +03:00
..
2025-12-14 21:55:41 +07:00