diff --git a/lib/android/init.dart b/lib/android/init.dart index 5c406fab..ab7d6e85 100644 --- a/lib/android/init.dart +++ b/lib/android/init.dart @@ -3,8 +3,12 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:logging/logging.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import '../app/app.dart'; import '../app/models.dart'; +import '../app/views/main_page.dart'; +import '../core/state.dart'; import '../management/state.dart'; import 'management/state.dart'; import 'oath/state.dart'; @@ -15,7 +19,7 @@ import '../oath/state.dart'; final _log = Logger('android.init'); -initializeLogging() { +Future initialize() async { Logger.root.onRecord.listen((record) { if (record.level >= Logger.root.level) { debugPrint('[${record.loggerName}] ${record.level}: ${record.message}'); @@ -25,24 +29,27 @@ initializeLogging() { } }); _log.info('Logging initialized, outputting to stderr'); -} -Future> initializeAndGetOverrides() async { /// initializes global handler for dialogs TapRequestDialog.initialize(); - return [ - supportedAppsProvider.overrideWithValue([ - Application.oath, - Application.management, - ]), - attachedDevicesProvider - .overrideWithProvider(androidAttachedDevicesProvider), - currentDeviceDataProvider.overrideWithProvider(androidDeviceDataProvider), - oathStateProvider.overrideWithProvider(androidOathStateProvider), - credentialListProvider.overrideWithProvider(androidCredentialListProvider), - currentAppProvider.overrideWithProvider(androidSubPageProvider), - managementStateProvider.overrideWithProvider(androidManagementState), - currentDeviceProvider.overrideWithProvider(androidCurrentDeviceProvider) - ]; + return ProviderScope( + overrides: [ + supportedAppsProvider.overrideWithValue([ + Application.oath, + Application.management, + ]), + prefProvider.overrideWithValue(await SharedPreferences.getInstance()), + attachedDevicesProvider + .overrideWithProvider(androidAttachedDevicesProvider), + currentDeviceDataProvider.overrideWithProvider(androidDeviceDataProvider), + oathStateProvider.overrideWithProvider(androidOathStateProvider), + credentialListProvider + .overrideWithProvider(androidCredentialListProvider), + currentAppProvider.overrideWithProvider(androidSubPageProvider), + managementStateProvider.overrideWithProvider(androidManagementState), + currentDeviceProvider.overrideWithProvider(androidCurrentDeviceProvider) + ], + child: const YubicoAuthenticatorApp(page: MainPage()), + ); } diff --git a/lib/desktop/init.dart b/lib/desktop/init.dart index b824e682..43a51b63 100755 --- a/lib/desktop/init.dart +++ b/lib/desktop/init.dart @@ -1,12 +1,15 @@ import 'dart:async'; import 'dart:io'; -import 'dart:ui'; +import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:logging/logging.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:window_manager/window_manager.dart'; +import '../app/app.dart'; +import '../app/views/main_page.dart'; +import '../core/state.dart'; import '../fido/state.dart'; import '../oath/state.dart'; import '../app/models.dart'; @@ -24,16 +27,6 @@ final _log = Logger('desktop.init'); const String _keyWidth = 'DESKTOP_WINDOW_WIDTH'; const String _keyHeight = 'DESKTOP_WINDOW_HEIGHT'; -initializeLogging() { - Logger.root.onRecord.listen((record) { - stderr.writeln('[${record.loggerName}] ${record.level}: ${record.message}'); - if (record.error != null) { - stderr.writeln(record.error); - } - }); - _log.info('Logging initialized, outputting to stderr'); -} - class _WindowResizeListener extends WindowListener { final SharedPreferences _prefs; _WindowResizeListener(this._prefs); @@ -46,9 +39,17 @@ class _WindowResizeListener extends WindowListener { } } -Future> initializeAndGetOverrides( - SharedPreferences prefs) async { +Future initialize() async { + Logger.root.onRecord.listen((record) { + stderr.writeln('[${record.loggerName}] ${record.level}: ${record.message}'); + if (record.error != null) { + stderr.writeln(record.error); + } + }); + _log.info('Logging initialized, outputting to stderr'); + await windowManager.ensureInitialized(); + final prefs = await SharedPreferences.getInstance(); unawaited(windowManager.waitUntilReadyToShow().then((_) async { await windowManager.setMinimumSize(const Size(270, 0)); @@ -78,31 +79,43 @@ Future> initializeAndGetOverrides( } _log.info('Starting subprocess: $exe'); - var rpc = await RpcSession.launch(exe!); + final rpc = await RpcSession.launch(exe!); _log.info('ykman-rpc process started', exe); rpc.setLogLevel(Logger.root.level); - return [ - supportedAppsProvider.overrideWithValue([ - Application.oath, - Application.fido, - Application.otp, - Application.piv, - Application.management, - ]), - rpcProvider.overrideWithValue(rpc), - windowStateProvider.overrideWithProvider(desktopWindowStateProvider), - attachedDevicesProvider.overrideWithProvider(desktopDevicesProvider), - currentDeviceDataProvider.overrideWithProvider(desktopDeviceDataProvider), - oathStateProvider.overrideWithProvider(desktopOathState), - credentialListProvider - .overrideWithProvider(desktopOathCredentialListProvider), - qrScannerProvider.overrideWithProvider(desktopQrScannerProvider), - managementStateProvider.overrideWithProvider(desktopManagementState), - fidoStateProvider.overrideWithProvider(desktopFidoState), - fidoPinProvider.overrideWithProvider(desktopFidoPinProvider), - fingerprintProvider.overrideWithProvider(desktopFingerprintProvider), - credentialProvider.overrideWithProvider(desktopCredentialProvider), - currentDeviceProvider.overrideWithProvider(desktopCurrentDeviceProvider) - ]; + return ProviderScope( + overrides: [ + supportedAppsProvider.overrideWithValue([ + Application.oath, + Application.fido, + Application.otp, + Application.piv, + Application.management, + ]), + prefProvider.overrideWithValue(prefs), + rpcProvider.overrideWithValue(rpc), + windowStateProvider.overrideWithProvider(desktopWindowStateProvider), + attachedDevicesProvider.overrideWithProvider(desktopDevicesProvider), + currentDeviceDataProvider.overrideWithProvider(desktopDeviceDataProvider), + oathStateProvider.overrideWithProvider(desktopOathState), + credentialListProvider + .overrideWithProvider(desktopOathCredentialListProvider), + qrScannerProvider.overrideWithProvider(desktopQrScannerProvider), + managementStateProvider.overrideWithProvider(desktopManagementState), + fidoStateProvider.overrideWithProvider(desktopFidoState), + fidoPinProvider.overrideWithProvider(desktopFidoPinProvider), + fingerprintProvider.overrideWithProvider(desktopFingerprintProvider), + credentialProvider.overrideWithProvider(desktopCredentialProvider), + currentDeviceProvider.overrideWithProvider(desktopCurrentDeviceProvider) + ], + child: YubicoAuthenticatorApp(page: Consumer( + builder: (context, ref, child) { + // Keep RPC log level synced with main app. + ref.listen(logLevelProvider, (_, level) { + rpc.setLogLevel(level); + }); + return const MainPage(); + }, + )), + ); } diff --git a/lib/desktop/state.dart b/lib/desktop/state.dart index 81907517..379d0f9f 100755 --- a/lib/desktop/state.dart +++ b/lib/desktop/state.dart @@ -20,13 +20,7 @@ final rpcProvider = Provider((ref) { }); final rpcStateProvider = StateNotifierProvider<_RpcStateNotifier, RpcState>( - (ref) { - final rpc = ref.watch(rpcProvider); - ref.listen(logLevelProvider, (_, level) { - rpc.setLogLevel(level); - }, fireImmediately: true); - return _RpcStateNotifier(rpc); - }, + (ref) => _RpcStateNotifier(ref.watch(rpcProvider)), ); class _RpcStateNotifier extends StateNotifier { diff --git a/lib/main.dart b/lib/main.dart index c0daa28e..719768c2 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,7 +1,5 @@ import 'dart:developer' as developer; -import 'dart:io'; -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:logging/logging.dart'; @@ -9,7 +7,6 @@ import 'package:shared_preferences/shared_preferences.dart'; import 'android/init.dart' as android; import 'app/app.dart'; -import 'app/views/main_page.dart'; import 'core/state.dart'; import 'desktop/init.dart' as desktop; import 'error_page.dart'; @@ -17,46 +14,30 @@ import 'error_page.dart'; final _log = Logger('main'); void main() async { - // Set YUBIOATH_DEV_LOG=true to use the developer log. - if (kDebugMode && Platform.environment['YUBIOATH_DEV_LOG'] == 'true') { - _initializeDebugLogging(); - Logger.root.level = Level.INFO; - _log.info('Logging to debug console'); - } else { - if (isDesktop) { - desktop.initializeLogging(); - } - if (isAndroid) { - android.initializeLogging(); - } - } - WidgetsFlutterBinding.ensureInitialized(); - var prefs = await SharedPreferences.getInstance(); - List overrides = [ - prefProvider.overrideWithValue(prefs), - ]; - Widget page; try { - // Platform specific initialization + final Widget initializedApp; if (isDesktop) { - _log.config('Initializing desktop platform.'); - overrides.addAll(await desktop.initializeAndGetOverrides(prefs)); + initializedApp = await desktop.initialize(); } else if (isAndroid) { - _log.config('Initializing Android platform.'); - overrides.addAll(await android.initializeAndGetOverrides()); + initializedApp = await android.initialize(); + } else { + _initializeDebugLogging(); + throw UnimplementedError('Platform not supported'); } - page = const MainPage(); + runApp(initializedApp); } catch (e) { _log.warning('Platform initialization failed: $e'); - page = ErrorPage(error: e.toString()); + runApp( + ProviderScope( + child: YubicoAuthenticatorApp(page: ErrorPage(error: e.toString())), + overrides: [ + prefProvider.overrideWithValue(await SharedPreferences.getInstance()) + ], + ), + ); } - - runApp(ProviderScope( - overrides: overrides, - child: YubicoAuthenticatorApp(page: page), - )); } void _initializeDebugLogging() {