handle connectivity fails (like nm being unavail on build server) more gracefully

This commit is contained in:
Dan Ballard 2023-05-03 10:58:31 -05:00
parent f996590683
commit 4acb6c74c3
3 changed files with 70 additions and 18 deletions

View File

@ -65,7 +65,7 @@ class FlwtchState extends State<Flwtch> with WindowListener {
final MethodChannel notificationClickChannel = MethodChannel('im.cwtch.flwtch/notificationClickHandler'); final MethodChannel notificationClickChannel = MethodChannel('im.cwtch.flwtch/notificationClickHandler');
final MethodChannel shutdownMethodChannel = MethodChannel('im.cwtch.flwtch/shutdownClickHandler'); final MethodChannel shutdownMethodChannel = MethodChannel('im.cwtch.flwtch/shutdownClickHandler');
final MethodChannel shutdownLinuxMethodChannel = MethodChannel('im.cwtch.linux.shutdown'); final MethodChannel shutdownLinuxMethodChannel = MethodChannel('im.cwtch.linux.shutdown');
late StreamSubscription connectivityStream; late StreamSubscription? connectivityStream;
ConnectivityState connectivityState = ConnectivityState.assumed_online; ConnectivityState connectivityState = ConnectivityState.assumed_online;
final GlobalKey<NavigatorState> navKey = GlobalKey<NavigatorState>(); final GlobalKey<NavigatorState> navKey = GlobalKey<NavigatorState>();
@ -95,35 +95,74 @@ class FlwtchState extends State<Flwtch> with WindowListener {
shutdownLinuxMethodChannel.setMethodCallHandler(shutdownDirect); shutdownLinuxMethodChannel.setMethodCallHandler(shutdownDirect);
print("initState: creating cwtchnotifier, ffi"); print("initState: creating cwtchnotifier, ffi");
if (Platform.isAndroid) { if (Platform.isAndroid) {
var cwtchNotifier = new CwtchNotifier(profs, globalSettings, globalErrorHandler, globalTorStatus, NullNotificationsManager(), globalAppState, globalServersList, this); var cwtchNotifier = new CwtchNotifier(
profs,
globalSettings,
globalErrorHandler,
globalTorStatus,
NullNotificationsManager(),
globalAppState,
globalServersList,
this);
cwtch = CwtchGomobile(cwtchNotifier); cwtch = CwtchGomobile(cwtchNotifier);
} else if (Platform.isLinux) { } else if (Platform.isLinux) {
var cwtchNotifier = var cwtchNotifier =
new CwtchNotifier(profs, globalSettings, globalErrorHandler, globalTorStatus, newDesktopNotificationsManager(_notificationSelectConvo), globalAppState, globalServersList, this); new CwtchNotifier(
profs,
globalSettings,
globalErrorHandler,
globalTorStatus,
newDesktopNotificationsManager(_notificationSelectConvo),
globalAppState,
globalServersList,
this);
cwtch = CwtchFfi(cwtchNotifier); cwtch = CwtchFfi(cwtchNotifier);
} else { } else {
var cwtchNotifier = var cwtchNotifier =
new CwtchNotifier(profs, globalSettings, globalErrorHandler, globalTorStatus, newDesktopNotificationsManager(_notificationSelectConvo), globalAppState, globalServersList, this); new CwtchNotifier(
profs,
globalSettings,
globalErrorHandler,
globalTorStatus,
newDesktopNotificationsManager(_notificationSelectConvo),
globalAppState,
globalServersList,
this);
cwtch = CwtchFfi(cwtchNotifier); cwtch = CwtchFfi(cwtchNotifier);
} }
connectivityStream = Connectivity().onConnectivityChanged.listen((ConnectivityResult result) { startConnectivityListener();
// Got a new connectivity status!
if (result == ConnectivityResult.none) {
connectivityState = ConnectivityState.confirmed_offline;
} else {
// were we offline?
if (connectivityState == ConnectivityState.confirmed_offline) {
EnvironmentConfig.debugLog("Network appears to have come back online, restarting Tor");
cwtch.ResetTor();
}
connectivityState = ConnectivityState.confirmed_online;
}
});
print("initState: invoking cwtch.Start()"); print("initState: invoking cwtch.Start()");
cwtch.Start(); cwtch.Start();
print("initState: done!"); print("initState: done!");
} }
// connectivity listening is an optional enhancement feature that tries to listen for OS events about the network
// and if it detects coming back online, restarts the ACN/tor
// gracefully fails and NOPs, as it's not a required functionality
startConnectivityListener() async {
try {
connectivityStream = await Connectivity().onConnectivityChanged.listen((ConnectivityResult result) {
// Got a new connectivity status!
if (result == ConnectivityResult.none) {
connectivityState = ConnectivityState.confirmed_offline;
} else {
// were we offline?
if (connectivityState == ConnectivityState.confirmed_offline) {
EnvironmentConfig.debugLog("Network appears to have come back online, restarting Tor");
cwtch.ResetTor();
}
connectivityState = ConnectivityState.confirmed_online;
}
}, onError: (Object error) {
print("Error listening to connectivity for network state: {$error}");
return null;
}, cancelOnError: true);
} catch (e) {
print("Warning: Unable to open connectivity for listening to network state: {$e}");
connectivityStream = null;
}
}
ChangeNotifierProvider<TorStatus> getTorStatusProvider() => ChangeNotifierProvider.value(value: globalTorStatus); ChangeNotifierProvider<TorStatus> getTorStatusProvider() => ChangeNotifierProvider.value(value: globalTorStatus);
ChangeNotifierProvider<ErrorHandler> getErrorHandlerProvider() => ChangeNotifierProvider.value(value: globalErrorHandler); ChangeNotifierProvider<ErrorHandler> getErrorHandlerProvider() => ChangeNotifierProvider.value(value: globalErrorHandler);
ChangeNotifierProvider<Settings> getSettingsProvider() => ChangeNotifierProvider.value(value: globalSettings); ChangeNotifierProvider<Settings> getSettingsProvider() => ChangeNotifierProvider.value(value: globalSettings);
@ -295,7 +334,7 @@ class FlwtchState extends State<Flwtch> with WindowListener {
cwtch.Shutdown(); cwtch.Shutdown();
windowManager.removeListener(this); windowManager.removeListener(this);
cwtch.dispose(); cwtch.dispose();
connectivityStream.cancel(); connectivityStream?.cancel();
super.dispose(); super.dispose();
} }
} }

View File

@ -1,4 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'dart:io';
import 'package:dbus/dbus.dart'; import 'package:dbus/dbus.dart';
@ -314,6 +315,17 @@ class NetworkManagerClient {
return; return;
} }
// Big old grody Hack
// DBus/nm doesnt seem to offer a way to deter ine if dbus is available on system
// worse the first connections get triggered in dbus_client onListen an isn't a catahable exception so crashes the app
// this is a hacky way to force an exception on thread if dbus isn't available and bail with out crashing
try {
await _root.client.getNameOwner(_root.name);
} on SocketException catch (e) {
print("nm dbus connect/emit test threw exception, dbus likely unavailable on system, aborting connect: $e");
return;
}
// Subscribe to changes // Subscribe to changes
_objectManagerSubscription = _root.signals.listen((signal) { _objectManagerSubscription = _root.signals.listen((signal) {
if (signal is DBusObjectManagerInterfacesAddedSignal) { if (signal is DBusObjectManagerInterfacesAddedSignal) {

View File

@ -32,6 +32,7 @@ dependencies:
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.0 cupertino_icons: ^1.0.0
# Todo: upgrade to 2.x, allow other package upgrades (dbus)
ffi: ^1.2.1 ffi: ^1.2.1
path_provider: ^2.0.0 path_provider: ^2.0.0
crypto: ^3.0.2 crypto: ^3.0.2