fix(session): clamp the countdown to wall clock, correct two doc claims
Second review pass (Fable) cleared all six fixes; these are its leftovers. - _reconcileElapsedTime() runs off the same suspend-blind Stopwatch, so after a long device sleep the countdown over-reports - and with the API unreachable nothing corrects it, which is precisely the state the app now stays in instead of disconnecting. It now takes the lesser of the Stopwatch value and the wall-clock deadline; the minimum, so a clock set backwards cannot extend a session. - CHANGELOG claimed the alert covers "the tunnel reporting an error". It cannot: AppConfigs.V2RAY_STATES has no error state and the plugin's stateName when() ends in else -> "DISCONNECTED", so VpnStatus.error is unreachable from the status stream on Android. - AGENTS.md file map still listed a setSessionExpiry bridge in power_settings.dart; no such symbol exists. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
1 parent
34722c751b
commit
d1ea13b01a
2 files changed
+16
-2
No files matched your search
+2
-2
@@ -12,8 +12,8 @@ Versions follow [semver](https://semver.org/): MAJOR.MINOR.PATCH
|
|||||||
off the same deadline it already enforces, so the warning still arrives when
|
off the same deadline it already enforces, so the warning still arrives when
|
||||||
the app is closed, and a support top-up moves it with the deadline.
|
the app is closed, and a support top-up moves it with the deadline.
|
||||||
- **"Disconnected — not protected" notification** when a session ends without
|
- **"Disconnected — not protected" notification** when a session ends without
|
||||||
you asking: the 2-hour expiry, the data limit, the server ending the session,
|
you asking: the 2-hour expiry, the data limit, or the server ending the
|
||||||
or the tunnel reporting an error.
|
session.
|
||||||
- **SOCKS5 mode now asks for the notification permission.** It never did,
|
- **SOCKS5 mode now asks for the notification permission.** It never did,
|
||||||
because it never raises the VPN consent dialog, so on Android 13+ these
|
because it never raises the VPN consent dialog, so on Android 13+ these
|
||||||
alerts would have been dropped before they were shown.
|
alerts would have been dropped before they were shown.
|
||||||
|
|||||||
@@ -426,6 +426,20 @@ class SessionTimer extends ChangeNotifier with WidgetsBindingObserver {
|
|||||||
final elapsed = clock.elapsed.inSeconds;
|
final elapsed = clock.elapsed.inSeconds;
|
||||||
_remainingSeconds =
|
_remainingSeconds =
|
||||||
(_remainingAtLastSync - elapsed).clamp(0, 1 << 31).toInt();
|
(_remainingAtLastSync - elapsed).clamp(0, 1 << 31).toInt();
|
||||||
|
|
||||||
|
// The Stopwatch is CLOCK_MONOTONIC and stops while the device is
|
||||||
|
// suspended, so after a long sleep it over-reports - and with the server
|
||||||
|
// unreachable no sync arrives to correct it, which is exactly the state
|
||||||
|
// the app now stays in rather than disconnecting. Take whichever is
|
||||||
|
// smaller, never the wall clock alone: a clock set backwards must not be
|
||||||
|
// able to extend a session.
|
||||||
|
final deadline = _deadlineAt;
|
||||||
|
if (deadline != null) {
|
||||||
|
final byWallClock = deadline.difference(DateTime.now()).inSeconds;
|
||||||
|
if (byWallClock < _remainingSeconds) {
|
||||||
|
_remainingSeconds = byWallClock.clamp(0, 1 << 31).toInt();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
Reference in new issue
Block a user