import 'package:webview_flutter/webview_flutter.dart'; import 'package:webview_flutter_android/webview_flutter_android.dart'; import '../../services/diagnostic_log.dart'; class SchoolBrowserInfo { const SchoolBrowserInfo({this.chromiumVersion}); final String? chromiumVersion; } typedef SchoolBrowserConfigurator = Future Function( WebViewController controller, String school, ); /// Configure only the dedicated school browser before its first request. Future configureSchoolBrowser( WebViewController controller, String school, ) async { final android = controller.platform; if (android is! AndroidWebViewController) return const SchoolBrowserInfo(); try { await android.setUseWideViewPort(true); final cookies = WebViewCookieManager().platform; if (cookies is AndroidWebViewCookieManager) { await cookies.setAcceptThirdPartyCookies(android, true); } await controller.setOnConsoleMessage((message) { final text = message.message.toLowerCase(); final code = text.contains('mixed content') ? 'mixed_content' : text.contains('content security policy') ? 'content_security_policy' : text.contains('cors') ? 'cross_origin' : text.contains('refused to') ? 'resource_refused' : message.level == JavaScriptLogLevel.error ? 'script_error' : null; if (code != null) { DiagnosticLog.instance.add( 'school_console_error', fields: {'school': school, 'code': code}, ); } }); String? version; try { version = RegExp(r'\bChrome/(\d+(?:\.\d+){0,3})\b') .firstMatch(await android.getUserAgent() ?? '') ?.group(1); } catch (_) { /* Version inspection must not block authentication. */ } DiagnosticLog.instance.add( 'browser_configured', fields: { 'school': school, 'phase': 'wide_viewport', 'result': true, 'code': 'third_party_cookies', 'version': version, }, ); return SchoolBrowserInfo(chromiumVersion: version); } catch (error) { DiagnosticLog.instance.add( 'browser_setup_failed', fields: {'school': school, 'code': error.runtimeType.toString()}, ); rethrow; } }