import 'dart:convert'; import 'dart:io'; const _pinnedMdkVersion = '0.37.0'; Future main(List arguments) async { try { final projectRoot = _parseProjectRoot(arguments); await _invalidateStaleFvpAndroidSdk(projectRoot); } on FormatException catch (error) { stderr.writeln('error: ${error.message}'); exitCode = 2; } on FileSystemException catch (error) { stderr.writeln('error: ${error.message}'); exitCode = 1; } on StateError catch (error) { stderr.writeln('error: ${error.message}'); exitCode = 1; } } String _parseProjectRoot(List arguments) { if (arguments.isEmpty) return _defaultProjectRoot; if (arguments.length == 2 && arguments.first == '--project-root') { return Directory(arguments.last).absolute.path; } throw const FormatException( 'Usage: dart scripts/prepare_fvp_android_deps.dart ' '[--project-root ]', ); } Future _invalidateStaleFvpAndroidSdk(String projectRoot) async { final packageConfigFile = File( '$projectRoot${Platform.pathSeparator}.dart_tool' '${Platform.pathSeparator}package_config.json', ); if (!await packageConfigFile.exists()) { throw StateError( 'package_config.json not found: ${packageConfigFile.path} ' '(run flutter pub get first)', ); } final packageConfig = jsonDecode(await packageConfigFile.readAsString()); if (packageConfig is! Map) { throw StateError('Invalid package_config.json root object'); } final packages = packageConfig['packages']; if (packages is! List) { throw StateError('Invalid package_config.json packages list'); } Map? fvpPackage; for (final package in packages) { if (package is Map && package['name'] == 'fvp') { fvpPackage = package; break; } } if (fvpPackage == null) { throw StateError('Package fvp not found in package_config.json'); } final rootUriValue = fvpPackage['rootUri']; if (rootUriValue is! String || rootUriValue.isEmpty) { throw StateError('Package fvp has an invalid rootUri'); } final fvpRootUri = packageConfigFile.uri.resolve(rootUriValue); if (fvpRootUri.scheme != 'file') { throw StateError('Unsupported fvp rootUri: $rootUriValue'); } final fvpRootDirectory = Directory.fromUri(fvpRootUri); final fvpAndroidDirectory = Directory( '${fvpRootDirectory.path}${Platform.pathSeparator}android', ); if (!await fvpAndroidDirectory.exists()) { throw StateError( 'fvp Android directory not found: ${fvpAndroidDirectory.path}', ); } final sdkDirectory = Directory( '${fvpAndroidDirectory.path}${Platform.pathSeparator}mdk-sdk', ); final sdkArchive = File( '${fvpAndroidDirectory.path}${Platform.pathSeparator}mdk-sdk-android.7z', ); final versionMarker = File( '${fvpAndroidDirectory.path}' '${Platform.pathSeparator}.smplayer-mdk-version', ); final findMdkFile = File( '${sdkDirectory.path}${Platform.pathSeparator}lib' '${Platform.pathSeparator}cmake' '${Platform.pathSeparator}FindMDK.cmake', ); final installedVersion = await versionMarker.exists() ? (await versionMarker.readAsString()).trim() : ''; final sdkIsReady = installedVersion == _pinnedMdkVersion && await findMdkFile.exists(); if (sdkIsReady) { stdout.writeln( '[fvp-android] mdk-sdk v$_pinnedMdkVersion is ready: ' '${sdkDirectory.path}', ); return; } final displayVersion = installedVersion.isEmpty ? 'unknown' : installedVersion; stdout.writeln( '[fvp-android] Invalidating cached mdk-sdk v$displayVersion; ' 'the next Flutter build will download v$_pinnedMdkVersion.', ); if (await sdkDirectory.exists()) { await sdkDirectory.delete(recursive: true); } if (await sdkArchive.exists()) { await sdkArchive.delete(); } await versionMarker.writeAsString(_pinnedMdkVersion, flush: true); } String get _defaultProjectRoot => File.fromUri(Platform.script).parent.parent.absolute.path;