diff --git a/.cirrus.yml b/.cirrus.yml index 2d17926ed4923..052d88dbb219f 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -83,7 +83,7 @@ task: fetch_framework_script: | mkdir -p $FRAMEWORK_PATH cd $FRAMEWORK_PATH - git clone https://github.com/flutter/flutter.git + git clone -b 'flutter-1.20-candidate.7' https://github.com/flutter/flutter.git test_web_script: | cd $FRAMEWORK_PATH/flutter/dev/integration_tests/web ../../../bin/flutter config --local-engine=host_debug_unopt --no-analytics --enable-web diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 60751e774da1a..bf97ba8ead1d6 100755 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -908,6 +908,7 @@ FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterOverlay FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm +FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.mm FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPluginAppLifeCycleDelegate.mm diff --git a/lib/web_ui/dev/web_engine_analysis.sh b/lib/web_ui/dev/web_engine_analysis.sh new file mode 100755 index 0000000000000..1ea919f499d18 --- /dev/null +++ b/lib/web_ui/dev/web_engine_analysis.sh @@ -0,0 +1,20 @@ +#!/bin/bash +set -e +set -x + +# web_analysis: a command-line utility for running dart analyzer on Flutter Web +# Engine. Used/Called by LUCI recipes: +# +# See: https://flutter.googlesource.com/recipes/+/refs/heads/master/recipes/web_engine.py + +echo "Engine path $ENGINE_PATH" + +DART_SDK_DIR="${ENGINE_PATH}/src/out/host_debug_unopt/dart-sdk" +PUB_PATH="$DART_SDK_DIR/bin/pub" +DART_ANALYZER_PATH="$DART_SDK_DIR/bin/dartanalyzer" + +echo "Running \`pub get\` in 'engine/src/flutter/lib/web_ui'" +(cd "$WEB_UI_DIR"; $PUB_PATH get) + +echo "Running \`dartanalyzer\` in 'engine/src/flutter/lib/web_ui'" +(cd "$WEB_UI_DIR"; $DART_ANALYZER_PATH --enable-experiment=non-nullable --fatal-warnings --fatal-hints dev/ lib/ test/ tool/) diff --git a/shell/platform/darwin/ios/BUILD.gn b/shell/platform/darwin/ios/BUILD.gn index e8d1c67beed90..67daeedcbc77f 100644 --- a/shell/platform/darwin/ios/BUILD.gn +++ b/shell/platform/darwin/ios/BUILD.gn @@ -167,6 +167,7 @@ source_set("ios_test_flutter_mrc") { "-mios-simulator-version-min=$ios_testing_deployment_target", ] sources = [ + "framework/Source/FlutterPlatformViewsTest.mm", "framework/Source/accessibility_bridge_test.mm", ] deps = [ diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm index 1b021bc60818d..abf854f15731b 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm @@ -122,15 +122,6 @@ } void FlutterPlatformViewsController::OnCreate(FlutterMethodCall* call, FlutterResult& result) { - if (!flutter_view_.get()) { - // Right now we assume we have a reference to FlutterView when creating a new view. - // TODO(amirh): support this by setting the reference to FlutterView when it becomes available. - // https://github.com/flutter/flutter/issues/23787 - result([FlutterError errorWithCode:@"create_failed" - message:@"can't create a view on a headless engine" - details:nil]); - return; - } NSDictionary* args = [call arguments]; long viewId = [args[@"id"] longValue]; @@ -407,6 +398,7 @@ void FlutterPlatformViewsController::CompositeWithParams(int view_id, const EmbeddedViewParams& params) { + FML_DCHECK(flutter_view_); CGRect frame = CGRectMake(0, 0, params.sizePoints().width(), params.sizePoints().height()); UIView* touchInterceptor = touch_interceptors_[view_id].get(); touchInterceptor.layer.transform = CATransform3DIdentity; @@ -429,6 +421,7 @@ } SkCanvas* FlutterPlatformViewsController::CompositeEmbeddedView(int view_id) { + FML_DCHECK(flutter_view_); // TODO(amirh): assert that this is running on the platform thread once we support the iOS // embedded views thread configuration. @@ -472,6 +465,7 @@ bool FlutterPlatformViewsController::SubmitFrame(GrContext* gr_context, std::shared_ptr ios_context, std::unique_ptr frame) { + FML_DCHECK(flutter_view_); if (merge_threads_) { // Threads are about to be merged, we drop everything from this frame // and possibly resubmit the same layer tree in the next frame. @@ -578,6 +572,7 @@ } void FlutterPlatformViewsController::BringLayersIntoView(LayersMap layer_map) { + FML_DCHECK(flutter_view_); UIView* flutter_view = flutter_view_.get(); auto zIndex = 0; // Clear the `active_composition_order_`, which will be populated down below. @@ -619,6 +614,7 @@ SkRect rect, int64_t view_id, int64_t overlay_id) { + FML_DCHECK(flutter_view_); std::shared_ptr layer = layer_pool_->GetLayer(gr_context, ios_context); UIView* overlay_view_wrapper = layer->overlay_view_wrapper.get(); diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm new file mode 100644 index 0000000000000..e2a0088dfc96b --- /dev/null +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm @@ -0,0 +1,146 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import + +#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h" +#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h" +#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlatformViews.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h" +#import "flutter/shell/platform/darwin/ios/platform_view_ios.h" +#import "third_party/ocmock/Source/OCMock/OCMock.h" + +FLUTTER_ASSERT_NOT_ARC +@class FlutterPlatformViewsTestMockPlatformView; +static FlutterPlatformViewsTestMockPlatformView* gMockPlatformView = nil; + +@interface FlutterPlatformViewsTestMockPlatformView : UIView +@end +@implementation FlutterPlatformViewsTestMockPlatformView + +- (instancetype)init { + self = [super init]; + if (self) { + gMockPlatformView = self; + } + return self; +} + +- (void)dealloc { + gMockPlatformView = nil; + [super dealloc]; +} + +@end + +@interface FlutterPlatformViewsTestMockFlutterPlatformView : NSObject +@property(nonatomic, strong) UIView* view; +@end + +@implementation FlutterPlatformViewsTestMockFlutterPlatformView + +- (instancetype)init { + if (self = [super init]) { + _view = [[FlutterPlatformViewsTestMockPlatformView alloc] init]; + } + return self; +} + +- (void)dealloc { + [_view release]; + _view = nil; + [super dealloc]; +} + +@end + +@interface FlutterPlatformViewsTestMockFlutterPlatformFactory + : NSObject +@end + +@implementation FlutterPlatformViewsTestMockFlutterPlatformFactory +- (NSObject*)createWithFrame:(CGRect)frame + viewIdentifier:(int64_t)viewId + arguments:(id _Nullable)args { + return [[[FlutterPlatformViewsTestMockFlutterPlatformView alloc] init] autorelease]; +} + +@end + +namespace flutter { +namespace { +class FlutterPlatformViewsTestMockPlatformViewDelegate : public PlatformView::Delegate { + void OnPlatformViewCreated(std::unique_ptr surface) override {} + void OnPlatformViewDestroyed() override {} + void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) override {} + void OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) override {} + void OnPlatformViewDispatchPlatformMessage(fml::RefPtr message) override {} + void OnPlatformViewDispatchPointerDataPacket(std::unique_ptr packet) override { + } + void OnPlatformViewDispatchSemanticsAction(int32_t id, + SemanticsAction action, + std::vector args) override {} + void OnPlatformViewSetSemanticsEnabled(bool enabled) override {} + void OnPlatformViewSetAccessibilityFeatures(int32_t flags) override {} + void OnPlatformViewRegisterTexture(std::shared_ptr texture) override {} + void OnPlatformViewUnregisterTexture(int64_t texture_id) override {} + void OnPlatformViewMarkTextureFrameAvailable(int64_t texture_id) override {} + + std::unique_ptr> ComputePlatformViewResolvedLocale( + const std::vector& supported_locale_data) override { + std::unique_ptr> out = std::make_unique>(); + return out; + } +}; + +} // namespace +} // namespace flutter + +namespace { +fml::RefPtr CreateNewThread(std::string name) { + auto thread = std::make_unique(name); + auto runner = thread->GetTaskRunner(); + return runner; +} +} // namespace + +@interface FlutterPlatformViewsTest : XCTestCase +@end + +@implementation FlutterPlatformViewsTest + +- (void)testCanCreatePlatformViewWithoutFlutterView { + flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate; + auto thread_task_runner = CreateNewThread("FlutterPlatformViewsTest"); + flutter::TaskRunners runners(/*label=*/self.name.UTF8String, + /*platform=*/thread_task_runner, + /*raster=*/thread_task_runner, + /*ui=*/thread_task_runner, + /*io=*/thread_task_runner); + auto platform_view = std::make_unique( + /*delegate=*/mock_delegate, + /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, + /*task_runners=*/runners); + + auto flutterPlatformViewsController = std::make_unique(); + + FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = + [[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease]; + flutterPlatformViewsController->RegisterViewFactory( + factory, @"MockFlutterPlatformView", + FlutterPlatformViewGestureRecognizersBlockingPolicyEager); + FlutterResult result = ^(id result) { + }; + flutterPlatformViewsController->OnMethodCall( + [FlutterMethodCall + methodCallWithMethodName:@"create" + arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], + result); + + XCTAssertNotNil(gMockPlatformView); + + flutterPlatformViewsController->Reset(); +} + +@end