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 shutdownMethodChannel = MethodChannel('im.cwtch.flwtch/shutdownClickHandler');
final MethodChannel shutdownLinuxMethodChannel = MethodChannel('im.cwtch.linux.shutdown');
late StreamSubscription connectivityStream;
late StreamSubscription? connectivityStream;
ConnectivityState connectivityState = ConnectivityState.assumed_online;
final GlobalKey<NavigatorState> navKey = GlobalKey<NavigatorState>();
@ -95,35 +95,74 @@ class FlwtchState extends State<Flwtch> with WindowListener {
shutdownLinuxMethodChannel.setMethodCallHandler(shutdownDirect);
print("initState: creating cwtchnotifier, ffi");
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);
} else if (Platform.isLinux) {
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);
} else {
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);
}
connectivityStream = 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;
}
});
startConnectivityListener();
print("initState: invoking cwtch.Start()");
cwtch.Start();
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<ErrorHandler> getErrorHandlerProvider() => ChangeNotifierProvider.value(value: globalErrorHandler);
ChangeNotifierProvider<Settings> getSettingsProvider() => ChangeNotifierProvider.value(value: globalSettings);
@ -295,7 +334,7 @@ class FlwtchState extends State<Flwtch> with WindowListener {
cwtch.Shutdown();
windowManager.removeListener(this);
cwtch.dispose();
connectivityStream.cancel();
connectivityStream?.cancel();
super.dispose();
}
}

View File

@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:io';
import 'package:dbus/dbus.dart';
@ -314,6 +315,17 @@ class NetworkManagerClient {
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
_objectManagerSubscription = _root.signals.listen((signal) {
if (signal is DBusObjectManagerInterfacesAddedSignal) {

View File

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