fix(android): surface mpv command failures
This commit is contained in:
@@ -159,7 +159,7 @@ open class MpvPlayerPlugin(
|
||||
"openContentFd" -> handleOpenContentFd(call, result)
|
||||
"closeContentFd" -> handleCloseContentFd(call, result)
|
||||
"isInitialized" -> result.success(playerCore?.isInitialized ?: false)
|
||||
"setLogLevel" -> result.success(null)
|
||||
"setLogLevel" -> handleSetLogLevel(call, result)
|
||||
else -> result.notImplemented()
|
||||
}
|
||||
}
|
||||
@@ -358,14 +358,30 @@ open class MpvPlayerPlugin(
|
||||
|
||||
val core = playerCore
|
||||
if (core == null) {
|
||||
result.success(null)
|
||||
result.error("NOT_INITIALIZED", "Player not initialized", null)
|
||||
return
|
||||
}
|
||||
core.command(args.toTypedArray()) {
|
||||
result.success(null)
|
||||
core.command(args.toTypedArray()) { success ->
|
||||
if (success) {
|
||||
result.success(null)
|
||||
} else {
|
||||
result.error("COMMAND_FAILED", "mpv command failed", args)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleSetLogLevel(call: MethodCall, result: MethodChannel.Result) {
|
||||
if (call.argument<String>("level") == null) {
|
||||
result.error("INVALID_ARGS", "Missing 'level'", null)
|
||||
return
|
||||
}
|
||||
result.error(
|
||||
"UNSUPPORTED",
|
||||
"Runtime mpv log level changes are not supported on Android",
|
||||
null
|
||||
)
|
||||
}
|
||||
|
||||
private fun handleSetVisible(call: MethodCall, result: MethodChannel.Result) {
|
||||
val visible = call.argument<Boolean>("visible")
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.edde746.plezy.mpv
|
||||
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
class MpvPlayerPluginTest {
|
||||
|
||||
@Test
|
||||
fun commandWithoutCoreReportsNotInitialized() {
|
||||
val result = RecordingResult()
|
||||
|
||||
MpvPlayerPlugin().onMethodCall(
|
||||
MethodCall("command", mapOf("args" to listOf("seek", "1", "absolute"))),
|
||||
result
|
||||
)
|
||||
|
||||
assertEquals("NOT_INITIALIZED", result.errorCode)
|
||||
assertNull(result.successValue)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun setLogLevelReportsUnsupported() {
|
||||
val result = RecordingResult()
|
||||
|
||||
MpvPlayerPlugin().onMethodCall(
|
||||
MethodCall("setLogLevel", mapOf("level" to "warn")),
|
||||
result
|
||||
)
|
||||
|
||||
assertEquals("UNSUPPORTED", result.errorCode)
|
||||
assertNull(result.successValue)
|
||||
}
|
||||
|
||||
private class RecordingResult : MethodChannel.Result {
|
||||
var successValue: Any? = null
|
||||
var errorCode: String? = null
|
||||
|
||||
override fun success(result: Any?) {
|
||||
successValue = result
|
||||
}
|
||||
|
||||
override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) {
|
||||
this.errorCode = errorCode
|
||||
}
|
||||
|
||||
override fun notImplemented() = Unit
|
||||
}
|
||||
}
|
||||
@@ -879,7 +879,9 @@ class VideoPlayerScreenState extends State<VideoPlayerScreen> with WidgetsBindin
|
||||
_audioFocusFuture!.ignore();
|
||||
}
|
||||
await currentPlayer.setProperty('msg-level', debugLoggingEnabled ? 'all=debug,ffmpeg/video=warn' : 'all=error');
|
||||
await currentPlayer.setLogLevel(debugLoggingEnabled ? 'v' : 'warn');
|
||||
if (!Platform.isAndroid || useExoPlayer) {
|
||||
await currentPlayer.setLogLevel(debugLoggingEnabled ? 'v' : 'warn');
|
||||
}
|
||||
await currentPlayer.setProperty('hwdec', _getHwdecValue(enableHardwareDecoding));
|
||||
|
||||
await currentPlayer.setProperty(
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:plezy/mpv/player/player_native.dart';
|
||||
import 'package:plezy/services/settings_service.dart';
|
||||
|
||||
import '../test_helpers/mock_player_channels.dart';
|
||||
import '../test_helpers/prefs.dart';
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
setUp(() async {
|
||||
resetSharedPreferencesForTest();
|
||||
SettingsService.resetForTesting();
|
||||
await SettingsService.getInstance();
|
||||
});
|
||||
|
||||
test('Android command failure reaches seek recovery', () async {
|
||||
await withMockPlayerChannels(
|
||||
methodChannelName: 'com.plezy/mpv_player',
|
||||
eventChannelName: 'com.plezy/mpv_player/events',
|
||||
methodHandler: (call) async {
|
||||
if (call.method == 'initialize') return true;
|
||||
if (call.method == 'command') {
|
||||
throw PlatformException(code: 'COMMAND_FAILED', message: 'mpv command failed');
|
||||
}
|
||||
return null;
|
||||
},
|
||||
testBody: () async {
|
||||
final player = PlayerNative();
|
||||
try {
|
||||
await player.seek(const Duration(seconds: 12));
|
||||
expect(player.state.position, Duration.zero);
|
||||
} finally {
|
||||
await player.dispose();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('Android setLogLevel failure is exposed to Dart', () async {
|
||||
await withMockPlayerChannels(
|
||||
methodChannelName: 'com.plezy/mpv_player',
|
||||
eventChannelName: 'com.plezy/mpv_player/events',
|
||||
methodHandler: (call) async {
|
||||
if (call.method == 'initialize') return true;
|
||||
if (call.method == 'setLogLevel') {
|
||||
throw PlatformException(code: 'UNSUPPORTED');
|
||||
}
|
||||
return null;
|
||||
},
|
||||
testBody: () async {
|
||||
final player = PlayerNative();
|
||||
try {
|
||||
await expectLater(
|
||||
player.setLogLevel('warn'),
|
||||
throwsA(isA<PlatformException>().having((error) => error.code, 'code', 'UNSUPPORTED')),
|
||||
);
|
||||
} finally {
|
||||
await player.dispose();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user