SOCKS5 Reconnect re-attached to the session the device already held. It
was the only path where a session began without an ad and without a
nonce binding it to one, and supporting it cost three parameters -
resume, release, resetSupportClaim - plus a carve-out in rule 4 that let
_fetchActiveSession accept whatever nonce the server happened to return.
It also wasn't the kindness it looked like. _handle_main calls
create_or_replace with a fresh full window, so a new session hands the
user *more* time, not less; re-attaching only preserved the remainder of
a session whose proxy had just died.
Reconnect now disconnects and connects again exactly as the button does,
ad included. All four special cases are deleted and the nonce check is
unconditional.
Costs one rewarded ad to repair an orphaned proxy once ads are enabled.
esef's call, and it buys a single way to start a session.
Also fixes the 3.3.7 regression where Reconnect released the session and
then asked for it back: there is no longer a path that does either.
Co-Authored-By: Claude Opus 5 <[email protected]>
Regression from e67f0b9, shipped in 3.3.7.
Reconnect repairs an orphaned proxy by tearing the runtime down and
re-attaching to the session the device already holds. It does that
through SessionTimer.disconnect(), which e67f0b9 taught to hand the
session back to the server - so it destroyed the very session the
following connect(resume: true) then asked for. Unawaited, so it raced:
the resume either found the session already gone or removed moments
later, surfacing as "Session not activated".
disconnect() now takes release, and the Reconnect path passes false.
Every other caller still hands the session back.
Narrow in practice: SOCKS5 mode only, only the Settings Reconnect
button, and the main-screen connect was unaffected because it mints a
new session anyway.
Co-Authored-By: Claude Opus 5 <[email protected]>
Source assertions, in the style of the existing release-verification
test. Every behaviour here was found broken on a device and fixed today;
none can be covered by an ordinary Dart test, because they live in the
vendored Android runtime or need a live tunnel. They all regress
silently, and each one looks like tidying when it does - inlining a
CountDownTimer, dropping a Handler callback, restoring a friendlier
notification string.
Checked that they fail without the fixes, not just that they pass with
them: restoring the "disconnects in 5 minutes" wording and moving
releaseSession() out of disconnect() both turn them red.
Co-Authored-By: Claude Opus 5 <[email protected]>