Skip to content

Commit 2e46240

Browse files
[video_player] Update for UIScene compatibility (#10676)
Replaces the code that used the key window's root view controller with a call to the new registrar `viewController` method to get the actual Flutter content's view controller. Since code behind the view provider abstraction is by definition not unit testable (since that's the interface used to DI a replacement in tests), this changes the API surface so that it's a direct passthrough to the registrar method. This does add some additional ifdefing, but minor compile-time complexity is better than having additional logic behind the test injection abstraction. Fixes flutter/flutter#174416 ## Pre-Review Checklist [^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
1 parent c4995d0 commit 2e46240

File tree

7 files changed

+60
-40
lines changed

7 files changed

+60
-40
lines changed

packages/video_player/video_player_avfoundation/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 2.8.10
2+
3+
* Improves compatibility with `UIScene`.
4+
* Updates minimum supported SDK version to Flutter 3.38/Dart 3.10.
5+
16
## 2.8.9
27

38
* Resolve `tracksWithMediaType:` deprecations.

packages/video_player/video_player_avfoundation/darwin/RunnerTests/VideoPlayerTests.m

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -79,24 +79,30 @@ - (void)seekToTime:(CMTime)time
7979

8080
@end
8181

82-
// Convience to avoid having two copies of the StubViewProvider code.
83-
#if TARGET_OS_OSX
84-
#define PROVIDED_VIEW_TYPE NSView
82+
@interface StubViewProvider : NSObject <FVPViewProvider>
83+
#if TARGET_OS_IOS
84+
- (instancetype)initWithViewController:(UIViewController *)viewController;
85+
@property(nonatomic, nullable) UIViewController *viewController;
8586
#else
86-
#define PROVIDED_VIEW_TYPE UIView
87+
- (instancetype)initWithView:(NSView *)view;
88+
@property(nonatomic, nullable) NSView *view;
8789
#endif
88-
89-
@interface StubViewProvider : NSObject <FVPViewProvider>
90-
- (instancetype)initWithView:(PROVIDED_VIEW_TYPE *)view;
91-
@property(nonatomic, nullable) PROVIDED_VIEW_TYPE *view;
9290
@end
9391

9492
@implementation StubViewProvider
95-
- (instancetype)initWithView:(PROVIDED_VIEW_TYPE *)view {
93+
#if TARGET_OS_IOS
94+
- (instancetype)initWithViewController:(UIViewController *)viewController {
95+
self = [super init];
96+
_viewController = viewController;
97+
return self;
98+
}
99+
#else
100+
- (instancetype)initWithView:(NSView *)view {
96101
self = [super init];
97102
_view = view;
98103
return self;
99104
}
105+
#endif
100106
@end
101107

102108
@interface StubFVPAVFactory : NSObject <FVPAVFactory>
@@ -227,14 +233,19 @@ - (void)testBlankVideoBugWithEncryptedVideoStreamAndInvertedAspectRatioBugForSom
227233
#if TARGET_OS_OSX
228234
NSView *view = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 10, 10)];
229235
view.wantsLayer = true;
236+
id<FVPViewProvider> viewProvider = [[StubViewProvider alloc] initWithView:view];
230237
#else
231238
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
239+
UIViewController *viewController = [[UIViewController alloc] init];
240+
viewController.view = view;
241+
id<FVPViewProvider> viewProvider =
242+
[[StubViewProvider alloc] initWithViewController:viewController];
232243
#endif
233244
NSObject<FlutterPluginRegistrar> *registrar = OCMProtocolMock(@protocol(FlutterPluginRegistrar));
234245
FVPVideoPlayerPlugin *videoPlayerPlugin = [[FVPVideoPlayerPlugin alloc]
235246
initWithAVFactory:[[StubFVPAVFactory alloc] initWithPlayer:nil output:nil]
236247
displayLinkFactory:nil
237-
viewProvider:[[StubViewProvider alloc] initWithView:view]
248+
viewProvider:viewProvider
238249
registrar:registrar];
239250

240251
FlutterError *error;
@@ -267,7 +278,7 @@ - (void)testPlayerForPlatformViewDoesNotRegisterTexture {
267278
FVPVideoPlayerPlugin *videoPlayerPlugin = [[FVPVideoPlayerPlugin alloc]
268279
initWithAVFactory:[[StubFVPAVFactory alloc] initWithPlayer:nil output:mockVideoOutput]
269280
displayLinkFactory:stubDisplayLinkFactory
270-
viewProvider:[[StubViewProvider alloc] initWithView:nil]
281+
viewProvider:[[StubViewProvider alloc] init]
271282
registrar:registrar];
272283

273284
FlutterError *initializationError;
@@ -294,7 +305,7 @@ - (void)testSeekToWhilePausedStartsDisplayLinkTemporarily {
294305
FVPVideoPlayerPlugin *videoPlayerPlugin = [[FVPVideoPlayerPlugin alloc]
295306
initWithAVFactory:[[StubFVPAVFactory alloc] initWithPlayer:nil output:mockVideoOutput]
296307
displayLinkFactory:stubDisplayLinkFactory
297-
viewProvider:[[StubViewProvider alloc] initWithView:nil]
308+
viewProvider:[[StubViewProvider alloc] init]
298309
registrar:registrar];
299310

300311
FlutterError *initializationError;
@@ -351,7 +362,7 @@ - (void)testInitStartsDisplayLinkTemporarily {
351362
initWithAVFactory:[[StubFVPAVFactory alloc] initWithPlayer:stubAVPlayer
352363
output:mockVideoOutput]
353364
displayLinkFactory:stubDisplayLinkFactory
354-
viewProvider:[[StubViewProvider alloc] initWithView:nil]
365+
viewProvider:[[StubViewProvider alloc] init]
355366
registrar:registrar];
356367

357368
FlutterError *initializationError;
@@ -397,7 +408,7 @@ - (void)testSeekToWhilePlayingDoesNotStopDisplayLink {
397408
FVPVideoPlayerPlugin *videoPlayerPlugin = [[FVPVideoPlayerPlugin alloc]
398409
initWithAVFactory:[[StubFVPAVFactory alloc] initWithPlayer:nil output:mockVideoOutput]
399410
displayLinkFactory:stubDisplayLinkFactory
400-
viewProvider:[[StubViewProvider alloc] initWithView:nil]
411+
viewProvider:[[StubViewProvider alloc] init]
401412
registrar:registrar];
402413

403414
FlutterError *initializationError;
@@ -452,7 +463,7 @@ - (void)testPauseWhileWaitingForFrameDoesNotStopDisplayLink {
452463
FVPVideoPlayerPlugin *videoPlayerPlugin = [[FVPVideoPlayerPlugin alloc]
453464
initWithAVFactory:[[StubFVPAVFactory alloc] initWithPlayer:nil output:mockVideoOutput]
454465
displayLinkFactory:stubDisplayLinkFactory
455-
viewProvider:[[StubViewProvider alloc] initWithView:nil]
466+
viewProvider:[[StubViewProvider alloc] init]
456467
registrar:registrar];
457468

458469
FlutterError *initializationError;
@@ -605,7 +616,7 @@ - (void)testSeekToleranceWhenNotSeekingToEnd {
605616
FVPVideoPlayer *player =
606617
[[FVPVideoPlayer alloc] initWithPlayerItem:[self playerItemWithURL:self.mp4TestURL]
607618
avFactory:stubAVFactory
608-
viewProvider:[[StubViewProvider alloc] initWithView:nil]];
619+
viewProvider:[[StubViewProvider alloc] init]];
609620
NSObject<FVPVideoEventListener> *listener = OCMProtocolMock(@protocol(FVPVideoEventListener));
610621
player.eventListener = listener;
611622

@@ -628,7 +639,7 @@ - (void)testSeekToleranceWhenSeekingToEnd {
628639
FVPVideoPlayer *player =
629640
[[FVPVideoPlayer alloc] initWithPlayerItem:[self playerItemWithURL:self.mp4TestURL]
630641
avFactory:stubAVFactory
631-
viewProvider:[[StubViewProvider alloc] initWithView:nil]];
642+
viewProvider:[[StubViewProvider alloc] init]];
632643
NSObject<FVPVideoEventListener> *listener = OCMProtocolMock(@protocol(FVPVideoEventListener));
633644
player.eventListener = listener;
634645

@@ -654,7 +665,7 @@ - (StubEventListener *)sanityTestURI:(NSString *)testURI {
654665
FVPVideoPlayer *player =
655666
[[FVPVideoPlayer alloc] initWithPlayerItem:[self playerItemWithURL:testURL]
656667
avFactory:[[FVPDefaultAVFactory alloc] init]
657-
viewProvider:[[StubViewProvider alloc] initWithView:nil]];
668+
viewProvider:[[StubViewProvider alloc] init]];
658669
XCTAssertNotNil(player);
659670

660671
XCTestExpectation *initializedExpectation = [self expectationWithDescription:@"initialized"];
@@ -850,7 +861,7 @@ - (void)testUpdatePlayingStateShouldNotResetRate {
850861
FVPVideoPlayer *player = [[FVPVideoPlayer alloc]
851862
initWithPlayerItem:[self playerItemWithURL:self.mp4TestURL]
852863
avFactory:[[StubFVPAVFactory alloc] initWithPlayer:nil output:nil]
853-
viewProvider:[[StubViewProvider alloc] initWithView:nil]];
864+
viewProvider:[[StubViewProvider alloc] init]];
854865

855866
XCTestExpectation *initializedExpectation = [self expectationWithDescription:@"initialized"];
856867
StubEventListener *listener =
@@ -875,7 +886,7 @@ - (void)testPlayerShouldNotDropEverySecondFrame {
875886
FVPVideoPlayerPlugin *videoPlayerPlugin = [[FVPVideoPlayerPlugin alloc]
876887
initWithAVFactory:[[StubFVPAVFactory alloc] initWithPlayer:nil output:mockVideoOutput]
877888
displayLinkFactory:stubDisplayLinkFactory
878-
viewProvider:[[StubViewProvider alloc] initWithView:nil]
889+
viewProvider:[[StubViewProvider alloc] init]
879890
registrar:registrar];
880891

881892
FlutterError *error;
@@ -1078,10 +1089,15 @@ - (void)testLoadTracksWithMediaTypeIsCalledOnNewerOS {
10781089
});
10791090

10801091
StubFVPAVFactory *stubAVFactory = [[StubFVPAVFactory alloc] initWithPlayer:nil output:nil];
1081-
FVPVideoPlayer *player =
1082-
[[FVPVideoPlayer alloc] initWithPlayerItem:mockItem
1083-
avFactory:stubAVFactory
1084-
viewProvider:[[StubViewProvider alloc] initWithView:nil]];
1092+
StubViewProvider *stubViewProvider =
1093+
#if TARGET_OS_OSX
1094+
[[StubViewProvider alloc] initWithView:nil];
1095+
#else
1096+
[[StubViewProvider alloc] initWithViewController:nil];
1097+
#endif
1098+
FVPVideoPlayer *player = [[FVPVideoPlayer alloc] initWithPlayerItem:mockItem
1099+
avFactory:stubAVFactory
1100+
viewProvider:stubViewProvider];
10851101
(void)player; // Keep reference
10861102

10871103
[self waitForExpectationsWithTimeout:5.0 handler:nil];

packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPTextureBasedVideoPlayer.m

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,12 @@ - (instancetype)initWithPlayerItem:(AVPlayerItem *)item
5454
// invisible AVPlayerLayer is used to overwrite the protection of pixel buffers in those streams
5555
// for issue #1, and restore the correct width and height for issue #2.
5656
_playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
57-
[viewProvider.view.layer addSublayer:self.playerLayer];
57+
#if TARGET_OS_IOS
58+
CALayer *flutterLayer = viewProvider.viewController.view.layer;
59+
#else
60+
CALayer *flutterLayer = viewProvider.view.layer;
61+
#endif
62+
[flutterLayer addSublayer:self.playerLayer];
5863
}
5964
return self;
6065
}

packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/FVPViewProvider.m

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,8 @@ - (NSView *)view {
2929
return self.registrar.view;
3030
}
3131
#else
32-
- (UIView *)view {
33-
#pragma clang diagnostic push
34-
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
35-
// TODO(hellohuanlin): Provide a non-deprecated codepath. See
36-
// https://github.com/flutter/flutter/issues/104117
37-
UIViewController *root = UIApplication.sharedApplication.keyWindow.rootViewController;
38-
#pragma clang diagnostic pop
39-
return root.view;
32+
- (UIViewController *)viewController {
33+
return self.registrar.viewController;
4034
}
4135
#endif
4236
@end

packages/video_player/video_player_avfoundation/darwin/video_player_avfoundation/Sources/video_player_avfoundation/include/video_player_avfoundation/FVPViewProvider.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ NS_ASSUME_NONNULL_BEGIN
1919
/// The view containing the Flutter content.
2020
@property(nonatomic, readonly, nullable) NSView *view;
2121
#else
22-
/// The view containing the Flutter content.
23-
@property(nonatomic, readonly, nullable) UIView *view;
22+
/// The view controller containing the Flutter content.
23+
@property(nonatomic, readonly, nullable) UIViewController *viewController;
2424
#endif
2525
@end
2626

packages/video_player/video_player_avfoundation/example/pubspec.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ description: Demonstrates how to use the video_player plugin.
33
publish_to: none
44

55
environment:
6-
sdk: ^3.9.0
7-
flutter: ">=3.35.0"
6+
sdk: ^3.10.0
7+
flutter: ">=3.38.0"
88

99
dependencies:
1010
flutter:

packages/video_player/video_player_avfoundation/pubspec.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ name: video_player_avfoundation
22
description: iOS and macOS implementation of the video_player plugin.
33
repository: https://github.com/flutter/packages/tree/main/packages/video_player/video_player_avfoundation
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22
5-
version: 2.8.9
5+
version: 2.8.10
66

77
environment:
8-
sdk: ^3.9.0
9-
flutter: ">=3.35.0"
8+
sdk: ^3.10.0
9+
flutter: ">=3.38.0"
1010

1111
flutter:
1212
plugin:

0 commit comments

Comments
 (0)