feat(app): OS session-expiry enforcement, session persistence, support sync
Enforce session expiry at the OS level (AlarmManager + handler) so the tunnel dies even if the UI process is killed; persist the session so a START_STICKY restart re-establishes it; sync immediately after a support top-up; slow the session beacon 5s/30s -> 60s/60s; drop the Always-on-VPN deep-link and the legacy 'ass' migration. Docs: CHANGELOG 3.3.4, privacy-policy log disclosure, README.
This commit is contained in:
1 parent
dfeb7f161c
commit
9ac236a981
15 files changed
+447
-383
No files matched your search
@@ -5,9 +5,9 @@ import 'package:flutter/services.dart';
|
||||
///
|
||||
/// Android stops background services of apps that are not exempt from Doze and
|
||||
/// App Standby, and it tears down the whole process group when a task is swiped
|
||||
/// away. Those are OS behaviours, not app bugs, and the OS provides exactly two
|
||||
/// sanctioned ways around them: a battery-optimisation exemption, and the
|
||||
/// system's own Always-on VPN. Both need one user tap; neither can be forced.
|
||||
/// away. Those are OS behaviours, not app bugs; the battery-optimisation
|
||||
/// exemption is the one sanctioned way an app can ask for around them, and it
|
||||
/// still needs one user tap.
|
||||
abstract final class PowerSettings {
|
||||
PowerSettings._();
|
||||
|
||||
@@ -42,16 +42,6 @@ abstract final class PowerSettings {
|
||||
}
|
||||
}
|
||||
|
||||
/// Opens the OS VPN settings screen, where Always-on VPN is configured.
|
||||
static Future<bool> openVpnSettings() async {
|
||||
if (kIsWeb) return false;
|
||||
try {
|
||||
return await _channel.invokeMethod<bool>('openVpnSettings') ?? false;
|
||||
} catch (_) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether the VPN runtime is genuinely alive.
|
||||
///
|
||||
/// The Xray service runs in a separate process, so nothing it stores in
|
||||
@@ -71,6 +61,19 @@ abstract final class PowerSettings {
|
||||
return const VpnRuntimeState(processAlive: false, vpnTransport: false);
|
||||
}
|
||||
}
|
||||
|
||||
/// Pushes the absolute session-expiry timestamp (epoch ms) to the VPN
|
||||
/// service so it can tear the tunnel down even when the UI process is gone.
|
||||
static Future<void> setSessionExpiry(int expiresAtMs) async {
|
||||
if (kIsWeb) return;
|
||||
try {
|
||||
await _channel.invokeMethod<void>('setSessionExpiry', {
|
||||
'expiresAtMs': expiresAtMs,
|
||||
});
|
||||
} catch (_) {
|
||||
// Best-effort. The daemon also keeps its last persisted expiry.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@immutable
|
||||
|
||||
Reference in new issue
Block a user