diff --git a/lib/core/sync/background_sync.dart b/lib/core/sync/background_sync.dart index d4c8304..5d17523 100644 --- a/lib/core/sync/background_sync.dart +++ b/lib/core/sync/background_sync.dart @@ -5,6 +5,7 @@ import 'dart:io'; import 'package:drift/drift.dart'; import 'package:drift/native.dart'; import 'package:enough_mail/enough_mail.dart' as imap; +import 'package:flutter/services.dart'; import 'package:path/path.dart' as p; import 'package:path_provider/path_provider.dart'; @@ -32,14 +33,22 @@ void callbackDispatcher() { } Future registerBackgroundSync() async { - await Workmanager().initialize(callbackDispatcher); - await Workmanager().registerPeriodicTask( - _kTaskName, - _kTaskName, - frequency: const Duration(minutes: 15), - constraints: Constraints(networkType: NetworkType.connected), - existingWorkPolicy: ExistingPeriodicWorkPolicy.keep, - ); + try { + await Workmanager().initialize(callbackDispatcher); + await Workmanager().registerPeriodicTask( + _kTaskName, + _kTaskName, + frequency: const Duration(minutes: 15), + constraints: Constraints(networkType: NetworkType.connected), + existingWorkPolicy: ExistingPeriodicWorkPolicy.keep, + ); + } on PlatformException { + // WorkManager channel unavailable on this device; background sync disabled. + } on MissingPluginException { + // Plugin not registered on this device; background sync disabled. + } catch (_) { + // Unexpected initialization failure; background sync disabled. + } } Future _doBackgroundSync() async { diff --git a/test/unit/background_sync_test.dart b/test/unit/background_sync_test.dart new file mode 100644 index 0000000..0c3b273 --- /dev/null +++ b/test/unit/background_sync_test.dart @@ -0,0 +1,20 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:sharedinbox/core/sync/background_sync.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + // Regression test for https://codeberg.org/guettli/sharedinbox/issues/149: + // On some Android devices the WorkManager platform channel is absent at + // startup, throwing PlatformException(channel-error, ...). + // registerBackgroundSync() must absorb the failure and let the app continue. + test( + 'registerBackgroundSync completes without throwing when plugin is unavailable', + () async { + // In the unit-test environment the native WorkManager plugin is not + // registered, so Workmanager().initialize() throws a PlatformException or + // MissingPluginException. The fix catches it. This test fails before the + // fix (exception propagates) and passes after it (exception is swallowed). + await expectLater(registerBackgroundSync(), completes); + }); +}