From c6459224cc0c9113e4e025edd209f3b997baba20 Mon Sep 17 00:00:00 2001 From: Christopher Fujino Date: Wed, 26 Aug 2020 14:39:58 -0700 Subject: [PATCH 1/5] update dart revision --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index 4dc98eecab93a..19b1d028e3998 100644 --- a/DEPS +++ b/DEPS @@ -34,7 +34,7 @@ vars = { # Dart is: https://github.com/dart-lang/sdk/blob/master/DEPS. # You can use //tools/dart/create_updated_flutter_deps.py to produce # updated revision list of existing dependencies. - 'dart_revision': '7cb472077b56a99aef7233bb616ba200b4de8682', + 'dart_revision': '2ea332979fbc9e8c42f9efe4a33dec83108c897b', # WARNING: DO NOT EDIT MANUALLY # The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py From 7df1015bec64f4c15532dadb6c94357451ff5bdc Mon Sep 17 00:00:00 2001 From: Emmanuel Garcia Date: Tue, 25 Aug 2020 12:39:40 -0700 Subject: [PATCH 2/5] Fix EGL_BAD_SURFACE when app is paused (#20735) --- shell/platform/android/android_surface_gl.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/shell/platform/android/android_surface_gl.cc b/shell/platform/android/android_surface_gl.cc index a3356653df9a8..061694bee9807 100644 --- a/shell/platform/android/android_surface_gl.cc +++ b/shell/platform/android/android_surface_gl.cc @@ -35,7 +35,11 @@ AndroidSurfaceGL::AndroidSurfaceGL( AndroidSurfaceGL::~AndroidSurfaceGL() = default; void AndroidSurfaceGL::TeardownOnScreenContext() { + // When the onscreen surface is destroyed, the context and the surface + // instance should be deleted. Issue: + // https://github.com/flutter/flutter/issues/64414 android_context_->ClearCurrent(); + onscreen_surface_ = nullptr; } bool AndroidSurfaceGL::IsValid() const { From 0a37fca61b43b086a1446fa0c679f1c4453b4090 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Mon, 24 Aug 2020 12:41:02 -0700 Subject: [PATCH 3/5] The `ForwardingGestureRecognizers` to have back reference to the `PlatformViewsController` so it can access `FlutterViewController` when its available (#20708) --- .../framework/Source/FlutterPlatformViews.mm | 48 ++++++++------ .../Source/FlutterPlatformViewsTest.mm | 66 +++++++++++++++++++ .../Source/FlutterPlatformViews_Internal.h | 45 ++++++++----- .../Source/FlutterPlatformViews_Internal.mm | 7 +- 4 files changed, 128 insertions(+), 38 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm index 891f8ed1a86e9..8826c7c74edb1 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm @@ -107,6 +107,10 @@ flutter_view_controller_.reset([flutter_view_controller retain]); } +UIViewController* FlutterPlatformViewsController::getFlutterViewController() { + return flutter_view_controller_.get(); +} + void FlutterPlatformViewsController::OnMethodCall(FlutterMethodCall* call, FlutterResult& result) { if ([[call method] isEqualToString:@"create"]) { OnCreate(call, result); @@ -161,7 +165,7 @@ FlutterTouchInterceptingView* touch_interceptor = [[[FlutterTouchInterceptingView alloc] initWithEmbeddedView:embedded_view.view - flutterViewController:flutter_view_controller_.get() + platformViewsController:GetWeakPtr() gestureRecognizersBlockingPolicy:gesture_recognizers_blocking_policies[viewType]] autorelease]; @@ -701,7 +705,8 @@ - (instancetype)initWithTarget:(id)target // directly to the FlutterView. @interface ForwardingGestureRecognizer : UIGestureRecognizer - (instancetype)initWithTarget:(id)target - flutterViewController:(UIViewController*)flutterViewController; + platformViewsController: + (fml::WeakPtr)platformViewsController; @end @implementation FlutterTouchInterceptingView { @@ -709,7 +714,8 @@ @implementation FlutterTouchInterceptingView { FlutterPlatformViewGestureRecognizersBlockingPolicy _blockingPolicy; } - (instancetype)initWithEmbeddedView:(UIView*)embeddedView - flutterViewController:(UIViewController*)flutterViewController + platformViewsController: + (fml::WeakPtr)platformViewsController gestureRecognizersBlockingPolicy: (FlutterPlatformViewGestureRecognizersBlockingPolicy)blockingPolicy { self = [super initWithFrame:embeddedView.frame]; @@ -720,9 +726,9 @@ - (instancetype)initWithEmbeddedView:(UIView*)embeddedView [self addSubview:embeddedView]; - ForwardingGestureRecognizer* forwardingRecognizer = - [[[ForwardingGestureRecognizer alloc] initWithTarget:self - flutterViewController:flutterViewController] autorelease]; + ForwardingGestureRecognizer* forwardingRecognizer = [[[ForwardingGestureRecognizer alloc] + initWithTarget:self + platformViewsController:std::move(platformViewsController)] autorelease]; _delayingRecognizer.reset([[DelayingGestureRecognizer alloc] initWithTarget:self @@ -833,39 +839,42 @@ - (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event { @end @implementation ForwardingGestureRecognizer { - // We can't dispatch events to the framework without this back pointer. - // This is a weak reference, the ForwardingGestureRecognizer is owned by the - // FlutterTouchInterceptingView which is strong referenced only by the FlutterView, - // which is strongly referenced by the FlutterViewController. - // So this is safe as when FlutterView is deallocated the reference to ForwardingGestureRecognizer - // will go away. - UIViewController* _flutterViewController; + // Weak reference to FlutterPlatformViewsController. The FlutterPlatformViewsController has + // a reference to the FlutterViewController, where we can dispatch pointer events to. + // + // The lifecycle of FlutterPlatformViewsController is bind to FlutterEngine, which should always + // outlives the FlutterViewController. And ForwardingGestureRecognizer is owned by a subview of + // FlutterView, so the ForwardingGestureRecognizer never out lives FlutterViewController. + // Therefore, `_platformViewsController` should never be nullptr. + fml::WeakPtr _platformViewsController; // Counting the pointers that has started in one touch sequence. NSInteger _currentTouchPointersCount; } - (instancetype)initWithTarget:(id)target - flutterViewController:(UIViewController*)flutterViewController { + platformViewsController: + (fml::WeakPtr)platformViewsController { self = [super initWithTarget:target action:nil]; if (self) { self.delegate = self; - _flutterViewController = flutterViewController; + FML_DCHECK(platformViewsController.get() != nullptr); + _platformViewsController = std::move(platformViewsController); _currentTouchPointersCount = 0; } return self; } - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { - [_flutterViewController touchesBegan:touches withEvent:event]; + [_platformViewsController.get()->getFlutterViewController() touchesBegan:touches withEvent:event]; _currentTouchPointersCount += touches.count; } - (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event { - [_flutterViewController touchesMoved:touches withEvent:event]; + [_platformViewsController.get()->getFlutterViewController() touchesMoved:touches withEvent:event]; } - (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event { - [_flutterViewController touchesEnded:touches withEvent:event]; + [_platformViewsController.get()->getFlutterViewController() touchesEnded:touches withEvent:event]; _currentTouchPointersCount -= touches.count; // Touches in one touch sequence are sent to the touchesEnded method separately if different // fingers stop touching the screen at different time. So one touchesEnded method triggering does @@ -877,7 +886,8 @@ - (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event { } - (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event { - [_flutterViewController touchesCancelled:touches withEvent:event]; + [_platformViewsController.get()->getFlutterViewController() touchesCancelled:touches + withEvent:event]; _currentTouchPointersCount = 0; self.state = UIGestureRecognizerStateFailed; } diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm index 0e8397e1146b4..39d6b987dc4ca 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm @@ -7,7 +7,9 @@ #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/Headers/FlutterViewController.h" #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h" +#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h" #import "flutter/shell/platform/darwin/ios/platform_view_ios.h" #import "third_party/ocmock/Source/OCMock/OCMock.h" @@ -508,6 +510,70 @@ - (void)testClipPath { flutterPlatformViewsController->Reset(); } +- (void)testSetFlutterViewControllerAfterCreateCanStillDispatchTouchEvents { + 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); + + // Find touch inteceptor view + UIView* touchInteceptorView = gMockPlatformView; + while (touchInteceptorView != nil && + ![touchInteceptorView isKindOfClass:[FlutterTouchInterceptingView class]]) { + touchInteceptorView = touchInteceptorView.superview; + } + XCTAssertNotNil(touchInteceptorView); + + // Find ForwardGestureRecognizer + UIGestureRecognizer* forwardGectureRecognizer = nil; + for (UIGestureRecognizer* gestureRecognizer in touchInteceptorView.gestureRecognizers) { + if ([gestureRecognizer isKindOfClass:NSClassFromString(@"ForwardingGestureRecognizer")]) { + forwardGectureRecognizer = gestureRecognizer; + break; + } + } + + // Before setting flutter view controller, events are not dispatched. + NSSet* touches1 = OCMClassMock([NSSet class]); + UIEvent* event1 = OCMClassMock([UIEvent class]); + UIViewController* mockFlutterViewContoller = OCMClassMock([UIViewController class]); + [forwardGectureRecognizer touchesBegan:touches1 withEvent:event1]; + OCMReject([mockFlutterViewContoller touchesBegan:touches1 withEvent:event1]); + + // Set flutter view controller allows events to be dispatched. + NSSet* touches2 = OCMClassMock([NSSet class]); + UIEvent* event2 = OCMClassMock([UIEvent class]); + flutterPlatformViewsController->SetFlutterViewController(mockFlutterViewContoller); + [forwardGectureRecognizer touchesBegan:touches2 withEvent:event2]; + OCMVerify([mockFlutterViewContoller touchesBegan:touches2 withEvent:event2]); + + flutterPlatformViewsController->Reset(); +} + - (int)alphaOfPoint:(CGPoint)point onView:(UIView*)view { unsigned char pixel[4] = {0}; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h index 311414b9d682d..92d043a7357e8 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h @@ -16,6 +16,8 @@ #include "flutter/shell/platform/darwin/ios/ios_context.h" #include "third_party/skia/include/core/SkPictureRecorder.h" +@class FlutterTouchInterceptingView; + // A UIView that acts as a clipping mask for the |ChildClippingView|. // // On the [UIView drawRect:] method, this view performs a series of clipping operations and sets the @@ -43,24 +45,6 @@ @end -// A UIView that is used as the parent for embedded UIViews. -// -// This view has 2 roles: -// 1. Delay or prevent touch events from arriving the embedded view. -// 2. Dispatching all events that are hittested to the embedded view to the FlutterView. -@interface FlutterTouchInterceptingView : UIView -- (instancetype)initWithEmbeddedView:(UIView*)embeddedView - flutterViewController:(UIViewController*)flutterViewController - gestureRecognizersBlockingPolicy: - (FlutterPlatformViewGestureRecognizersBlockingPolicy)blockingPolicy; - -// Stop delaying any active touch sequence (and let it arrive the embedded view). -- (void)releaseGesture; - -// Prevent the touch sequence from ever arriving to the embedded view. -- (void)blockGesture; -@end - // The parent view handles clipping to its subviews. @interface ChildClippingView : UIView @@ -143,10 +127,14 @@ class FlutterPlatformViewsController { ~FlutterPlatformViewsController(); + fml::WeakPtr GetWeakPtr(); + void SetFlutterView(UIView* flutter_view); void SetFlutterViewController(UIViewController* flutter_view_controller); + UIViewController* getFlutterViewController(); + void RegisterViewFactory( NSObject* factory, NSString* factoryId, @@ -255,6 +243,8 @@ class FlutterPlatformViewsController { std::map gesture_recognizers_blocking_policies; + std::unique_ptr> weak_factory_; + void OnCreate(FlutterMethodCall* call, FlutterResult& result); void OnDispose(FlutterMethodCall* call, FlutterResult& result); void OnAcceptGesture(FlutterMethodCall* call, FlutterResult& result); @@ -313,4 +303,23 @@ class FlutterPlatformViewsController { } // namespace flutter +// A UIView that is used as the parent for embedded UIViews. +// +// This view has 2 roles: +// 1. Delay or prevent touch events from arriving the embedded view. +// 2. Dispatching all events that are hittested to the embedded view to the FlutterView. +@interface FlutterTouchInterceptingView : UIView +- (instancetype)initWithEmbeddedView:(UIView*)embeddedView + platformViewsController: + (fml::WeakPtr)platformViewsController + gestureRecognizersBlockingPolicy: + (FlutterPlatformViewGestureRecognizersBlockingPolicy)blockingPolicy; + +// Stop delaying any active touch sequence (and let it arrive the embedded view). +- (void)releaseGesture; + +// Prevent the touch sequence from ever arriving to the embedded view. +- (void)blockGesture; +@end + #endif // FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERPLATFORMVIEWS_INTERNAL_H_ diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.mm index 5e9ed80279975..0179debf2c5a4 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.mm @@ -24,10 +24,15 @@ FlutterPlatformViewLayer::~FlutterPlatformViewLayer() = default; FlutterPlatformViewsController::FlutterPlatformViewsController() - : layer_pool_(std::make_unique()){}; + : layer_pool_(std::make_unique()), + weak_factory_(std::make_unique>(this)){}; FlutterPlatformViewsController::~FlutterPlatformViewsController() = default; +fml::WeakPtr FlutterPlatformViewsController::GetWeakPtr() { + return weak_factory_->GetWeakPtr(); +} + CATransform3D GetCATransform3DFromSkMatrix(const SkMatrix& matrix) { // Skia only supports 2D transform so we don't map z. CATransform3D transform = CATransform3DIdentity; From f28b027bc8fa042ec0ee0db68fae5681fddd6f72 Mon Sep 17 00:00:00 2001 From: Jason Simmons Date: Fri, 21 Aug 2020 16:26:02 -0700 Subject: [PATCH 4/5] Remove image sizes from Picture::GetAllocationSize (#20673) --- lib/ui/painting/canvas.cc | 3 --- testing/dart/canvas_test.dart | 28 ---------------------------- 2 files changed, 31 deletions(-) diff --git a/lib/ui/painting/canvas.cc b/lib/ui/painting/canvas.cc index 129226d36a4ce..449b0d0be9b21 100644 --- a/lib/ui/painting/canvas.cc +++ b/lib/ui/painting/canvas.cc @@ -327,7 +327,6 @@ void Canvas::drawImage(const CanvasImage* image, ToDart("Canvas.drawImage called with non-genuine Image.")); return; } - external_allocation_size_ += image->GetAllocationSize(); canvas_->drawImage(image->image(), x, y, paint.paint()); } @@ -352,7 +351,6 @@ void Canvas::drawImageRect(const CanvasImage* image, } SkRect src = SkRect::MakeLTRB(src_left, src_top, src_right, src_bottom); SkRect dst = SkRect::MakeLTRB(dst_left, dst_top, dst_right, dst_bottom); - external_allocation_size_ += image->GetAllocationSize(); canvas_->drawImageRect(image->image(), src, dst, paint.paint(), SkCanvas::kFast_SrcRectConstraint); } @@ -381,7 +379,6 @@ void Canvas::drawImageNine(const CanvasImage* image, SkIRect icenter; center.round(&icenter); SkRect dst = SkRect::MakeLTRB(dst_left, dst_top, dst_right, dst_bottom); - external_allocation_size_ += image->GetAllocationSize(); canvas_->drawImageNine(image->image(), icenter, dst, paint.paint()); } diff --git a/testing/dart/canvas_test.dart b/testing/dart/canvas_test.dart index 09255ab86a6d8..8640cc86bf63d 100644 --- a/testing/dart/canvas_test.dart +++ b/testing/dart/canvas_test.dart @@ -297,34 +297,6 @@ void main() { expectArgumentError(() => canvas.drawRawAtlas(image, Float32List(4), Float32List(4), Int32List(2), BlendMode.src, rect, paint)); }); - test('Image size reflected in picture size for image*, drawAtlas, and drawPicture methods', () async { - final Image image = await createImage(100, 100); - final PictureRecorder recorder = PictureRecorder(); - final Canvas canvas = Canvas(recorder); - const Rect rect = Rect.fromLTWH(0, 0, 100, 100); - canvas.drawImage(image, Offset.zero, Paint()); - canvas.drawImageRect(image, rect, rect, Paint()); - canvas.drawImageNine(image, rect, rect, Paint()); - canvas.drawAtlas(image, [], [], [], BlendMode.src, rect, Paint()); - final Picture picture = recorder.endRecording(); - - // Some of the numbers here appear to utilize sharing/reuse of common items, - // e.g. of the Paint() or same `Rect` usage, etc. - // The raw utilization of a 100x100 picture here should be 53333: - // 100 * 100 * 4 * (4/3) = 53333.333333.... - // To avoid platform specific idiosyncrasies and brittleness against changes - // to Skia, we just assert this is _at least_ 4x the image size. - const int minimumExpected = 53333 * 4; - expect(picture.approximateBytesUsed, greaterThan(minimumExpected)); - - final PictureRecorder recorder2 = PictureRecorder(); - final Canvas canvas2 = Canvas(recorder2); - canvas2.drawPicture(picture); - final Picture picture2 = recorder2.endRecording(); - - expect(picture2.approximateBytesUsed, greaterThan(minimumExpected)); - }); - test('Vertex buffer size reflected in picture size for drawVertices', () async { final PictureRecorder recorder = PictureRecorder(); final Canvas canvas = Canvas(recorder); From 0e39da6d9ccbaa3bba7dca006975cf3ac917e868 Mon Sep 17 00:00:00 2001 From: Christopher Fujino Date: Wed, 26 Aug 2020 15:43:14 -0700 Subject: [PATCH 5/5] update licenses golden --- ci/licenses_golden/licenses_third_party | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/licenses_golden/licenses_third_party b/ci/licenses_golden/licenses_third_party index ff84ef7d93226..042c44743712e 100644 --- a/ci/licenses_golden/licenses_third_party +++ b/ci/licenses_golden/licenses_third_party @@ -1,4 +1,4 @@ -Signature: 3c7ccf0ef2eb71e1bae57c50cd60559a +Signature: 876879bfd1a568b37f8d08027f0f42a9 UNUSED LICENSES: