From f988f524febc6a7d543a11e892df21a393620ac6 Mon Sep 17 00:00:00 2001 From: Chris Bracken Date: Thu, 28 Nov 2024 09:44:23 -0800 Subject: [PATCH] iOS: Apply nullability annotations to FlutterPlatformViewsController (flutter/engine#56839) Applies non-null by default annotations to FlutterPlatformViewsController with opt-outs where necessary. Updates unit tests to create graphics contexts where requried. [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style --- .../Source/FlutterPlatformViewsController.h | 17 ++--- .../Source/FlutterPlatformViewsController.mm | 1 + .../Source/FlutterPlatformViewsTest.mm | 72 ++++++++++--------- 3 files changed, 48 insertions(+), 42 deletions(-) diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.h b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.h index 9ce3c7f8ac..5b55ce6d72 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.h +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.h @@ -23,24 +23,23 @@ #import "flutter/shell/platform/darwin/ios/framework/Source/overlay_layer_pool.h" #import "flutter/shell/platform/darwin/ios/ios_context.h" +NS_ASSUME_NONNULL_BEGIN + @class FlutterTouchInterceptingView; @class FlutterClippingMaskViewPool; @interface FlutterPlatformViewsController : NSObject -- (id)init NS_DESIGNATED_INITIALIZER; +- (instancetype)init NS_DESIGNATED_INITIALIZER; /// The task runner used to post rendering tasks to the platform thread. @property(nonatomic, assign) const fml::RefPtr& taskRunner; /// The flutter view. -@property(nonatomic, weak) UIView* flutterView; +@property(nonatomic, weak) UIView* _Nullable flutterView; /// @brief The flutter view controller. -@property(nonatomic, weak) UIViewController* flutterViewController; - -/// @brief Retrieve the view controller. -- (UIViewController*)flutterViewController; +@property(nonatomic, weak) UIViewController* _Nullable flutterViewController; /// @brief set the factory used to construct embedded UI Views. - (void)registerViewFactory:(NSObject*)factory @@ -101,7 +100,7 @@ /// Called from the raster thread. - (BOOL)submitFrame:(std::unique_ptr)frame withIosContext:(const std::shared_ptr&)iosContext - grContext:(GrDirectContext*)grContext; + grContext:(GrDirectContext* _Nullable)grContext; /// @brief Handler for platform view message channels. - (void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result; @@ -130,7 +129,7 @@ // If the `PlatformViewsController` does not contain any `FlutterPlatformView` object or // a `FlutterPlatformView` object associated with the view_id cannot be found, the method // returns nil. -- (UIView*)platformViewForId:(int64_t)viewId; +- (UIView* _Nullable)platformViewForId:(int64_t)viewId; // Composite the PlatformView with `viewId`. // @@ -146,4 +145,6 @@ @end +NS_ASSUME_NONNULL_END + #endif // FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERPLATFORMVIEWSCONTROLLER_H_ diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.mm index ba531cad83..7a452ba744 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.mm @@ -705,6 +705,7 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect, } - (flutter::DlCanvas*)compositeEmbeddedViewWithId:(int64_t)viewId { + FML_DCHECK(self.slices.find(viewId) != self.slices.end()); return self.slices[viewId]->canvas(); } diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm index dd48e60364..2a890cc8e6 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm @@ -8,6 +8,8 @@ #import #import +#include + #include "flutter/display_list/effects/dl_image_filters.h" #include "flutter/fml/synchronization/count_down_latch.h" #include "flutter/fml/thread.h" @@ -17,6 +19,7 @@ #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterTouchInterceptingView_Test.h" +#include "flutter/shell/platform/darwin/ios/ios_context_noop.h" #include "flutter/shell/platform/darwin/ios/platform_view_ios.h" FLUTTER_ASSERT_ARC @@ -3103,9 +3106,10 @@ fml::RefPtr GetDefaultTaskRunner() { [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return false; }, [](const flutter::SurfaceFrame& surface_frame) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertFalse([flutterPlatformViewsController submitFrame:std::move(mock_surface) - withIosContext:nil - grContext:nil]); + XCTAssertFalse([flutterPlatformViewsController + submitFrame:std::move(mock_surface) + withIosContext:std::make_shared() + grContext:nil]); auto embeddedViewParams_2 = std::make_unique(finalMatrix, SkSize::Make(300, 300), stack); @@ -3120,9 +3124,10 @@ fml::RefPtr GetDefaultTaskRunner() { [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, [](const flutter::SurfaceFrame& surface_frame) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertTrue([flutterPlatformViewsController submitFrame:std::move(mock_surface_submit_true) - withIosContext:nil - grContext:nil]); + XCTAssertTrue([flutterPlatformViewsController + submitFrame:std::move(mock_surface_submit_true) + withIosContext:std::make_shared() + grContext:nil]); } - (void) @@ -3328,10 +3333,10 @@ fml::RefPtr GetDefaultTaskRunner() { [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, [](const flutter::SurfaceFrame& surface_frame) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - - XCTAssertTrue([flutterPlatformViewsController submitFrame:std::move(mock_surface) - withIosContext:nil - grContext:nil]); + XCTAssertTrue([flutterPlatformViewsController + submitFrame:std::move(mock_surface) + withIosContext:std::make_shared() + grContext:nil]); // platform view is wrapped by touch interceptor, which itself is wrapped by clipping view. UIView* clippingView1 = view1.superview.superview; @@ -3359,9 +3364,10 @@ fml::RefPtr GetDefaultTaskRunner() { [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, [](const flutter::SurfaceFrame& surface_frame) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertTrue([flutterPlatformViewsController submitFrame:std::move(mock_surface) - withIosContext:nil - grContext:nil]); + XCTAssertTrue([flutterPlatformViewsController + submitFrame:std::move(mock_surface) + withIosContext:std::make_shared() + grContext:nil]); XCTAssertTrue([flutterView.subviews indexOfObject:clippingView1] > [flutterView.subviews indexOfObject:clippingView2], @@ -3442,10 +3448,10 @@ fml::RefPtr GetDefaultTaskRunner() { [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, [](const flutter::SurfaceFrame& surface_frame) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - - XCTAssertTrue([flutterPlatformViewsController submitFrame:std::move(mock_surface) - withIosContext:nil - grContext:nil]); + XCTAssertTrue([flutterPlatformViewsController + submitFrame:std::move(mock_surface) + withIosContext:std::make_shared() + grContext:nil]); // platform view is wrapped by touch interceptor, which itself is wrapped by clipping view. UIView* clippingView1 = view1.superview.superview; @@ -3473,10 +3479,10 @@ fml::RefPtr GetDefaultTaskRunner() { [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, [](const flutter::SurfaceFrame& surface_frame) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - - XCTAssertTrue([flutterPlatformViewsController submitFrame:std::move(mock_surface) - withIosContext:nil - grContext:nil]); + XCTAssertTrue([flutterPlatformViewsController + submitFrame:std::move(mock_surface) + withIosContext:std::make_shared() + grContext:nil]); XCTAssertTrue([flutterView.subviews indexOfObject:clippingView1] < [flutterView.subviews indexOfObject:clippingView2], @@ -3945,10 +3951,10 @@ fml::RefPtr GetDefaultTaskRunner() { [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, [](const flutter::SurfaceFrame& surface_frame) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - - XCTAssertTrue([flutterPlatformViewsController submitFrame:std::move(mock_surface) - withIosContext:nil - grContext:nil]); + XCTAssertTrue([flutterPlatformViewsController + submitFrame:std::move(mock_surface) + withIosContext:std::make_shared() + grContext:nil]); // Disposing won't remove embedded views until the view is removed from the composition_order_ XCTAssertEqual(flutterPlatformViewsController.embeddedViewCount, 2UL); @@ -3975,10 +3981,10 @@ fml::RefPtr GetDefaultTaskRunner() { [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, [](const flutter::SurfaceFrame& surface_frame) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - - XCTAssertTrue([flutterPlatformViewsController submitFrame:std::move(mock_surface) - withIosContext:nil - grContext:nil]); + XCTAssertTrue([flutterPlatformViewsController + submitFrame:std::move(mock_surface) + withIosContext:std::make_shared() + grContext:nil]); // Disposing won't remove embedded views until the view is removed from the composition_order_ XCTAssertEqual(flutterPlatformViewsController.embeddedViewCount, 1UL); @@ -4051,9 +4057,8 @@ fml::RefPtr GetDefaultTaskRunner() { [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, [](const flutter::SurfaceFrame& surface_frame) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - [flutterPlatformViewsController submitFrame:std::move(mock_surface) - withIosContext:nil + withIosContext:std::make_shared() grContext:nil]; UIView* someView = [[UIView alloc] init]; @@ -4130,9 +4135,8 @@ fml::RefPtr GetDefaultTaskRunner() { [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, [](const flutter::SurfaceFrame& surface_frame) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - [flutterPlatformViewsController submitFrame:std::move(mock_surface) - withIosContext:nil + withIosContext:std::make_shared() grContext:nil]; XCTAssertEqual(flutterView.subviews.count, 1u); @@ -4252,7 +4256,7 @@ fml::RefPtr GetDefaultTaskRunner() { }); [flutterPlatformViewsController submitFrame:std::move(mock_surface) - withIosContext:nil + withIosContext:std::make_shared() grContext:nil]; XCTAssertTrue(submit_info.has_value());