From 9cd486f5a2c46b040bae80fc996918860af26929 Mon Sep 17 00:00:00 2001 From: aldobarr Date: Sat, 25 Jul 2026 16:43:36 -0400 Subject: [PATCH] Guard linux is available around actually installed linux commands. --- lib/models/external_player_models.dart | 24 +++++++++++++++++--- test/models/external_player_models_test.dart | 22 ++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 test/models/external_player_models_test.dart diff --git a/lib/models/external_player_models.dart b/lib/models/external_player_models.dart index 5d87667b..3f29325f 100644 --- a/lib/models/external_player_models.dart +++ b/lib/models/external_player_models.dart @@ -204,6 +204,19 @@ class KnownPlayers { return _androidPackageMap[id] ?? const []; } + static bool _isLinuxCommandAvailable(String command) { + if (!Platform.isLinux) { + return false; + } + + try { + final result = Process.runSync('sh', ['-c', r'command -v "$1" >/dev/null 2>&1', 'plezy-command-probe', command]); + return result.exitCode == 0; + } on ProcessException { + return false; + } + } + static List androidPackageCandidates(ExternalPlayer player) { final knownPackages = _androidPackageCandidatesForId(player.id); if (knownPackages.isNotEmpty) return knownPackages; @@ -220,7 +233,12 @@ class KnownPlayers { id: 'vlc', name: 'VLC', iconAsset: 'assets/player_icons/vlc.svg', - isAvailable: Platform.isAndroid || Platform.isIOS || Platform.isMacOS || Platform.isLinux || Platform.isWindows, + isAvailable: + Platform.isAndroid || + Platform.isIOS || + Platform.isMacOS || + _isLinuxCommandAvailable('vlc') || + Platform.isWindows, launch: (url) { if (Platform.isAndroid) return _launchAndroidIntentCandidates(url, _androidPackageCandidatesForId('vlc')); if (Platform.isIOS) return _launchUrlScheme('vlc://', url); @@ -233,7 +251,7 @@ class KnownPlayers { id: 'mpv', name: 'mpv', iconAsset: 'assets/player_icons/mpv.svg', - isAvailable: Platform.isAndroid || Platform.isMacOS || Platform.isLinux || Platform.isWindows, + isAvailable: Platform.isAndroid || Platform.isMacOS || _isLinuxCommandAvailable('mpv') || Platform.isWindows, launch: (url) { if (Platform.isAndroid) return _launchAndroidIntentCandidates(url, _androidPackageCandidatesForId('mpv')); return _launchCommand('mpv', url); @@ -281,7 +299,7 @@ class KnownPlayers { id: 'celluloid', name: 'Celluloid', iconAsset: 'assets/player_icons/celluloid.svg', - isAvailable: Platform.isLinux, + isAvailable: _isLinuxCommandAvailable('celluloid'), launch: (url) => _launchCommand('celluloid', url), ), ]; diff --git a/test/models/external_player_models_test.dart b/test/models/external_player_models_test.dart new file mode 100644 index 00000000..09d7c6d0 --- /dev/null +++ b/test/models/external_player_models_test.dart @@ -0,0 +1,22 @@ +import 'dart:io'; + +import 'package:flutter_test/flutter_test.dart'; +import 'package:plezy/models/external_player_models.dart'; + +void main() { + test('Linux exposes only known players whose commands are available', () { + final players = KnownPlayers.getForCurrentPlatform(); + + expect(players.map((player) => player.id), [ + 'system_default', + if (_commandIsAvailable('vlc')) 'vlc', + if (_commandIsAvailable('mpv')) 'mpv', + if (_commandIsAvailable('celluloid')) 'celluloid', + ]); + }, skip: !Platform.isLinux); +} + +bool _commandIsAvailable(String command) { + final result = Process.runSync('sh', ['-c', r'command -v "$1" >/dev/null 2>&1', 'plezy-test-command-probe', command]); + return result.exitCode == 0; +}