Moe Hamade 141adf5468 fix(hotspot): only remove our own group; ask consent to replace a foreign one
removeGroup() is device-scoped: it removes whatever Wi-Fi Direct group
exists, including one owned by Cast, Android Auto or Quick Share.
stopHotspot() called it unconditionally, so the path built to protect a
foreign group tore that group down anyway. Removal on stop is now gated on
a createdGroup flag, set once our own createGroup command is accepted; with
nothing of ours on the framework, stop closes the channel and leaves the
group alone.

When a group we did not record creating is active at start, the app no
longer guesses about ownership - it asks. A confirmation dialog explains
that starting will disconnect the current Wi-Fi Direct connection;
confirming retries the start with replacement authorized, cancelling
leaves everything untouched. Consent is bound to the group it was given
for: the conflicting group's name travels through the dialog, and the
policy only authorizes removing a group with exactly that name - one that
appeared later, or swapped in mid-retry, re-prompts instead of riding on
stale approval.

Because consent replaces ownership proof, the DIRECT-BC- prefix heuristic
is gone: a prefix match is not ownership (this device can be connected to
another phone's bitchat group), so only the exact recorded name counts.
The record is also kept honest: never taken from a group we do not host,
and never overwritten while an old group of ours may still exist, so a
BUSY retry cannot misclassify our own stale group as foreign.

Also: SecurityException guards on the removeGroup() sites reached from
framework callbacks (permission revoked mid-session crashed instead of
failing cleanly); stopHotspot() takes a completion callback so the
ViewModel releases its Wi-Fi Aware lease only after the framework
acknowledges the removal, with an idempotent 10s fallback so a dropped
acknowledgement cannot pin the mesh down; and the confirm/cancel handlers
guard on the ConfirmDisconnect state so a tap landing through a screen
transition cannot tear down a just-confirmed session.

Replaces the state-machine approach of #811 - same protection at
proportionate cost.

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