fix(player): 修复切换频道时复用已释放的视频控制器
This commit is contained in:
1 parent
45a53180d9
commit
f3ec12e3c3
6 files changed
+229
-6
No files matched your search
@@ -123,6 +123,38 @@ void main() {
|
||||
await session.close();
|
||||
});
|
||||
|
||||
test(
|
||||
'should_detach_retiring_player_before_disposal_finishes',
|
||||
() async {
|
||||
final disposeStarted = Completer<void>();
|
||||
final disposeGate = Completer<void>();
|
||||
final factory = FakeFactory(
|
||||
firstDisposeStarted: disposeStarted,
|
||||
firstDisposeGate: disposeGate,
|
||||
);
|
||||
final session = PlaybackSession(
|
||||
episodes: episodes,
|
||||
factory: factory.create,
|
||||
canPlay: (episode) => episode.isFree,
|
||||
);
|
||||
await session.select(0);
|
||||
final retiring = factory.created.single;
|
||||
|
||||
final switching = session.select(1);
|
||||
await disposeStarted.future;
|
||||
|
||||
expect(retiring.disposed, isFalse);
|
||||
expect(session.active, isNull);
|
||||
expect(session.preparedPlayerAt(0), isNull);
|
||||
|
||||
disposeGate.complete();
|
||||
await switching;
|
||||
expect(retiring.disposed, isTrue);
|
||||
expect(session.active, isA<FakePlayer>());
|
||||
await session.close();
|
||||
},
|
||||
);
|
||||
|
||||
test('should_keep_user_pause_when_reselecting_the_same_episode', () async {
|
||||
final factory = FakeFactory();
|
||||
final session = PlaybackSession(
|
||||
@@ -164,8 +196,14 @@ void main() {
|
||||
}
|
||||
|
||||
class FakeFactory {
|
||||
FakeFactory({this.holdFirstInitialize = false});
|
||||
FakeFactory({
|
||||
this.holdFirstInitialize = false,
|
||||
this.firstDisposeStarted,
|
||||
this.firstDisposeGate,
|
||||
});
|
||||
final bool holdFirstInitialize;
|
||||
final Completer<void>? firstDisposeStarted;
|
||||
final Completer<void>? firstDisposeGate;
|
||||
final List<FakePlayer> created = [];
|
||||
final Completer<void> firstCreated = Completer<void>();
|
||||
int live = 0;
|
||||
@@ -176,6 +214,8 @@ class FakeFactory {
|
||||
if (live > peakLive) peakLive = live;
|
||||
final player = FakePlayer(
|
||||
holdInitialize: holdFirstInitialize && created.isEmpty,
|
||||
disposeStarted: created.isEmpty ? firstDisposeStarted : null,
|
||||
disposeGate: created.isEmpty ? firstDisposeGate : null,
|
||||
onDispose: () => live--,
|
||||
);
|
||||
created.add(player);
|
||||
@@ -185,9 +225,16 @@ class FakeFactory {
|
||||
}
|
||||
|
||||
class FakePlayer implements PlayerPort {
|
||||
FakePlayer({required this.holdInitialize, required this.onDispose});
|
||||
FakePlayer({
|
||||
required this.holdInitialize,
|
||||
required this.onDispose,
|
||||
this.disposeStarted,
|
||||
this.disposeGate,
|
||||
});
|
||||
final bool holdInitialize;
|
||||
final void Function() onDispose;
|
||||
final Completer<void>? disposeStarted;
|
||||
final Completer<void>? disposeGate;
|
||||
final Completer<void> _initializeGate = Completer<void>();
|
||||
bool initialized = false;
|
||||
bool disposed = false;
|
||||
@@ -211,6 +258,10 @@ class FakePlayer implements PlayerPort {
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
if (disposed) return;
|
||||
if (disposeStarted != null && !disposeStarted!.isCompleted) {
|
||||
disposeStarted!.complete();
|
||||
}
|
||||
await disposeGate?.future;
|
||||
disposed = true;
|
||||
onDispose();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user