From acb9dd9b7242ca96325cd47e066619f11d45b304 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 1 Mar 2019 13:00:33 -0800 Subject: [PATCH 1/7] implement callback for a11y readiness --- shell/common/platform_view.cc | 7 +++++ shell/common/platform_view.h | 2 ++ .../ios/framework/Headers/FlutterEngine.h | 28 +++++++++++++++++++ .../ios/framework/Source/FlutterEngine.mm | 10 +++++++ .../framework/Source/FlutterViewController.mm | 5 +++- shell/platform/darwin/ios/platform_view_ios.h | 10 +++++-- .../platform/darwin/ios/platform_view_ios.mm | 17 +++++++++-- 7 files changed, 73 insertions(+), 6 deletions(-) diff --git a/shell/common/platform_view.cc b/shell/common/platform_view.cc index 7c7c1dc258aad..a8a31856dd570 100644 --- a/shell/common/platform_view.cc +++ b/shell/common/platform_view.cc @@ -85,6 +85,13 @@ void PlatformView::UpdateSemantics( blink::SemanticsNodeUpdates update, blink::CustomAccessibilityActionUpdates actions) {} +bool PlatformView::RegisterSemanticsAvailableCallback(fml::closure closure) { + FML_LOG(WARNING) << "The default implementation of " + "PlatformView::RegisterSemanticsAvailableCallback will " + "not register any callback and always returns false."; + return false; +} + void PlatformView::HandlePlatformMessage( fml::RefPtr message) { if (auto response = message->response()) diff --git a/shell/common/platform_view.h b/shell/common/platform_view.h index ed3b6e999a3ea..e686e0703620c 100644 --- a/shell/common/platform_view.h +++ b/shell/common/platform_view.h @@ -78,6 +78,8 @@ class PlatformView { virtual void SetAccessibilityFeatures(int32_t flags); + virtual bool RegisterSemanticsAvailableCallback(fml::closure closure); + void SetViewportMetrics(const blink::ViewportMetrics& metrics); void NotifyCreated(); diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h index 262a97a1dc2d3..1c1412e5c6f8b 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h @@ -133,6 +133,34 @@ FLUTTER_EXPORT */ - (void)destroyContext; +/** + * Ensures that Flutter will generate a semantics tree. + * + * This is enabled by default if certain accessibility services are turned on by + * the user, or when using a Simulator. This method allows a user to turn + * semantics on when they would not ordinarily be generated and the performance + * overhead is not a concern, e.g. for UI testing. Note that semantics should + * never be programatically turned off, as it would potentially disable + * accessibility services an end user has requested. + * + * This method must only be called after launching the engine via + * `-runWithEntrypoint:` or `-runWithEntryPoint:libraryURI`. + */ +- (void)ensureSemanticsEnabled; + +/** + * Registers a callback that will be called once when semantics are available. + * + * If the semantics tree has already been build at least once, this callback + * will fire immediately. If semantics are disabled, this callback will never + * fire; consider calling `-ensureSemanticsEnabled` first. + * + * Multiple calls to this method will replace the callback. + * + * @return `YES` if the callback is registered, `NO` otherwise. + */ +- (BOOL)registerSemanticsAvailableCallback:(void (^)(void))callback; + /** * Sets the `FlutterViewController` for this instance. The FlutterEngine must be * running (e.g. a successful call to `-runWithEntrypoint:` or `-runWithEntrypoint:libraryURI`) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 8b8bd33fdba2a..5ee52fd0ee35e 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -146,6 +146,16 @@ - (void)dispatchPointerDataPacket:(std::unique_ptr)pac return _shell->GetTaskRunners().GetPlatformTaskRunner(); } +- (void)ensureSemanticsEnabled { + FML_DCHECK(self.iosPlatformView); + self.iosPlatformView->SetSemanticsEnabled(true); +} + +- (BOOL)registerSemanticsAvailableCallback:(void (^)(void))callback { + FML_DCHECK(self.iosPlatformView); + return self.iosPlatformView->RegisterSemanticsAvailableCallback(std::move(callback)); +} + - (void)setViewController:(FlutterViewController*)viewController { FML_DCHECK(self.iosPlatformView); _viewController = [viewController getWeakPtr]; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index 2e4a265d17f0e..caa7a26992cfb 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -367,7 +367,10 @@ - (void)setSplashScreenView:(UIView*)view { } - (void)setFlutterViewDidRenderCallback:(void (^)(void))callback { - _flutterViewRenderedCallback.reset(callback, fml::OwnershipPolicy::Retain); + auto platformView = [_engine.get() platformView]; + if (platformView) { + platformView->SetNextFrameCallback(std::move(callback)); + } } #pragma mark - Surface creation and teardown updates diff --git a/shell/platform/darwin/ios/platform_view_ios.h b/shell/platform/darwin/ios/platform_view_ios.h index a0d85a7ffd0f9..9eff61852e731 100644 --- a/shell/platform/darwin/ios/platform_view_ios.h +++ b/shell/platform/darwin/ios/platform_view_ios.h @@ -40,7 +40,14 @@ class PlatformViewIOS final : public PlatformView { void SetTextInputPlugin(fml::scoped_nsprotocol plugin); + // |shell::PlatformView| + void SetSemanticsEnabled(bool enabled) override; + + // |shell::PlatformView| + bool RegisterSemanticsAvailableCallback(fml::closure closure) override; + private: + fml::closure semantics_available_callback_; fml::WeakPtr owner_controller_; std::unique_ptr ios_surface_; PlatformMessageRouter platform_message_router_; @@ -57,9 +64,6 @@ class PlatformViewIOS final : public PlatformView { // |shell::PlatformView| sk_sp CreateResourceContext() const override; - // |shell::PlatformView| - void SetSemanticsEnabled(bool enabled) override; - // |shell::PlatformView| void SetAccessibilityFeatures(int32_t flags) override; diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index 4bcb08d21afe6..b94c976bc3718 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -90,8 +90,8 @@ // |shell::PlatformView| void PlatformViewIOS::SetSemanticsEnabled(bool enabled) { if (!owner_controller_) { - FML_DLOG(WARNING) << "Could not set semantics to enabled, this " - "PlatformViewIOS has no ViewController."; + FML_LOG(WARNING) << "Could not set semantics to enabled, this " + "PlatformViewIOS has no ViewController."; return; } if (enabled && !accessibility_bridge_) { @@ -113,7 +113,20 @@ blink::CustomAccessibilityActionUpdates actions) { if (accessibility_bridge_) { accessibility_bridge_->UpdateSemantics(std::move(update), std::move(actions)); + if (semantics_available_callback_) { + semantics_available_callback_(); + semantics_available_callback_ = nullptr; + } + } +} + +// |shell::PlatformView| +bool PlatformViewIOS::RegisterSemanticsAvailableCallback(fml::closure closure) { + semantics_available_callback_ = std::move(closure); + if (!semantics_available_callback_ || !accessibility_bridge_) { + return false; } + return true; } // |shell::PlatformView| From c51c40bc0209b9bc85d80f0801ba868cb6965659 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 1 Mar 2019 14:05:02 -0800 Subject: [PATCH 2/7] fix unintended change, update docs, nit --- .../platform/darwin/ios/framework/Headers/FlutterEngine.h | 8 ++++---- .../darwin/ios/framework/Source/FlutterViewController.mm | 5 +---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h index 1c1412e5c6f8b..83a66b6d45f0c 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h @@ -151,13 +151,13 @@ FLUTTER_EXPORT /** * Registers a callback that will be called once when semantics are available. * - * If the semantics tree has already been build at least once, this callback - * will fire immediately. If semantics are disabled, this callback will never - * fire; consider calling `-ensureSemanticsEnabled` first. + * If semantics are disabled, this callback will be stored but will not fire + * until they are enabled and the tree has been updated. Consider calling + * `-ensureSemanticsEnabled` first. * * Multiple calls to this method will replace the callback. * - * @return `YES` if the callback is registered, `NO` otherwise. + * @return `YES` if the semantics are enabled, `NO` otherwise. */ - (BOOL)registerSemanticsAvailableCallback:(void (^)(void))callback; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index caa7a26992cfb..2e4a265d17f0e 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -367,10 +367,7 @@ - (void)setSplashScreenView:(UIView*)view { } - (void)setFlutterViewDidRenderCallback:(void (^)(void))callback { - auto platformView = [_engine.get() platformView]; - if (platformView) { - platformView->SetNextFrameCallback(std::move(callback)); - } + _flutterViewRenderedCallback.reset(callback, fml::OwnershipPolicy::Retain); } #pragma mark - Surface creation and teardown updates From d8e6ba5b611e3db9fa3f44e286d74966b5d3bb73 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 1 Mar 2019 14:11:02 -0800 Subject: [PATCH 3/7] save before commiting --- shell/platform/darwin/ios/platform_view_ios.mm | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index b94c976bc3718..b21b032d41f2a 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -123,10 +123,7 @@ // |shell::PlatformView| bool PlatformViewIOS::RegisterSemanticsAvailableCallback(fml::closure closure) { semantics_available_callback_ = std::move(closure); - if (!semantics_available_callback_ || !accessibility_bridge_) { - return false; - } - return true; + return semantics_available_callback_ && accessibility_bridge_; } // |shell::PlatformView| From f814fcc886298131a7cead76053f85409864388d Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 4 Mar 2019 14:18:46 -0800 Subject: [PATCH 4/7] Use NSNotificationCenter --- shell/common/platform_view.cc | 7 ------- shell/common/platform_view.h | 2 -- .../darwin/ios/framework/Headers/FlutterEngine.h | 13 ------------- .../darwin/ios/framework/Source/FlutterEngine.mm | 6 ------ shell/platform/darwin/ios/platform_view_ios.h | 4 ---- shell/platform/darwin/ios/platform_view_ios.mm | 13 +++---------- 6 files changed, 3 insertions(+), 42 deletions(-) diff --git a/shell/common/platform_view.cc b/shell/common/platform_view.cc index a8a31856dd570..7c7c1dc258aad 100644 --- a/shell/common/platform_view.cc +++ b/shell/common/platform_view.cc @@ -85,13 +85,6 @@ void PlatformView::UpdateSemantics( blink::SemanticsNodeUpdates update, blink::CustomAccessibilityActionUpdates actions) {} -bool PlatformView::RegisterSemanticsAvailableCallback(fml::closure closure) { - FML_LOG(WARNING) << "The default implementation of " - "PlatformView::RegisterSemanticsAvailableCallback will " - "not register any callback and always returns false."; - return false; -} - void PlatformView::HandlePlatformMessage( fml::RefPtr message) { if (auto response = message->response()) diff --git a/shell/common/platform_view.h b/shell/common/platform_view.h index e686e0703620c..ed3b6e999a3ea 100644 --- a/shell/common/platform_view.h +++ b/shell/common/platform_view.h @@ -78,8 +78,6 @@ class PlatformView { virtual void SetAccessibilityFeatures(int32_t flags); - virtual bool RegisterSemanticsAvailableCallback(fml::closure closure); - void SetViewportMetrics(const blink::ViewportMetrics& metrics); void NotifyCreated(); diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h index 83a66b6d45f0c..4079110526ad4 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h @@ -148,19 +148,6 @@ FLUTTER_EXPORT */ - (void)ensureSemanticsEnabled; -/** - * Registers a callback that will be called once when semantics are available. - * - * If semantics are disabled, this callback will be stored but will not fire - * until they are enabled and the tree has been updated. Consider calling - * `-ensureSemanticsEnabled` first. - * - * Multiple calls to this method will replace the callback. - * - * @return `YES` if the semantics are enabled, `NO` otherwise. - */ -- (BOOL)registerSemanticsAvailableCallback:(void (^)(void))callback; - /** * Sets the `FlutterViewController` for this instance. The FlutterEngine must be * running (e.g. a successful call to `-runWithEntrypoint:` or `-runWithEntrypoint:libraryURI`) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 5ee52fd0ee35e..a90e49c7085fa 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -147,15 +147,9 @@ - (void)dispatchPointerDataPacket:(std::unique_ptr)pac } - (void)ensureSemanticsEnabled { - FML_DCHECK(self.iosPlatformView); self.iosPlatformView->SetSemanticsEnabled(true); } -- (BOOL)registerSemanticsAvailableCallback:(void (^)(void))callback { - FML_DCHECK(self.iosPlatformView); - return self.iosPlatformView->RegisterSemanticsAvailableCallback(std::move(callback)); -} - - (void)setViewController:(FlutterViewController*)viewController { FML_DCHECK(self.iosPlatformView); _viewController = [viewController getWeakPtr]; diff --git a/shell/platform/darwin/ios/platform_view_ios.h b/shell/platform/darwin/ios/platform_view_ios.h index 9eff61852e731..b7495b90fec51 100644 --- a/shell/platform/darwin/ios/platform_view_ios.h +++ b/shell/platform/darwin/ios/platform_view_ios.h @@ -43,11 +43,7 @@ class PlatformViewIOS final : public PlatformView { // |shell::PlatformView| void SetSemanticsEnabled(bool enabled) override; - // |shell::PlatformView| - bool RegisterSemanticsAvailableCallback(fml::closure closure) override; - private: - fml::closure semantics_available_callback_; fml::WeakPtr owner_controller_; std::unique_ptr ios_surface_; PlatformMessageRouter platform_message_router_; diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index b21b032d41f2a..5c03b7f35406d 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -111,21 +111,14 @@ // |shell::PlatformView| void PlatformViewIOS::UpdateSemantics(blink::SemanticsNodeUpdates update, blink::CustomAccessibilityActionUpdates actions) { + FML_DCHECK(owner_controller_); if (accessibility_bridge_) { accessibility_bridge_->UpdateSemantics(std::move(update), std::move(actions)); - if (semantics_available_callback_) { - semantics_available_callback_(); - semantics_available_callback_ = nullptr; - } + [[NSNotificationCenter defaultCenter] postNotificationName:@"FlutterSemanticsUpdate" + object:owner_controller_.get()]; } } -// |shell::PlatformView| -bool PlatformViewIOS::RegisterSemanticsAvailableCallback(fml::closure closure) { - semantics_available_callback_ = std::move(closure); - return semantics_available_callback_ && accessibility_bridge_; -} - // |shell::PlatformView| std::unique_ptr PlatformViewIOS::CreateVSyncWaiter() { return std::make_unique(task_runners_); From 865043e054e24dbe52d5d206c474fe537c6a9a98 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 6 Mar 2019 13:42:46 -0800 Subject: [PATCH 5/7] Add doc with notification name --- shell/platform/darwin/ios/framework/Headers/FlutterEngine.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h index 4079110526ad4..711d4b8839abb 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h @@ -145,6 +145,10 @@ FLUTTER_EXPORT * * This method must only be called after launching the engine via * `-runWithEntrypoint:` or `-runWithEntryPoint:libraryURI`. + * + * You can subscribe to semantics updates via `NSNotificationCenter` by adding + * an observer for the name "FlutterSemanticsUpdate". The `object` parameter + * will be the `FlutterViewController` associated with the semantics update. */ - (void)ensureSemanticsEnabled; From 1d2b8c12772ba6a0e006e2d01f0041773905f099 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 6 Mar 2019 14:06:15 -0800 Subject: [PATCH 6/7] add constant --- .../darwin/ios/framework/Headers/FlutterEngine.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h index 711d4b8839abb..b4e91a0f45c02 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h @@ -16,6 +16,14 @@ @class FlutterViewController; +/** + * The name used for semantic update nofications via `NSNotificationCenter`. + * + * The object passed as the sender is the `FlutterViewController` associated + * with the update. + */ +const NSNotificationName FlutterSemanticsUpdateNotification = @"FlutterSemanticsUpdate"; + /** * The FlutterEngine class coordinates a single instance of execution for a * `FlutterDartProject`. It may have zero or one `FlutterViewController` at a @@ -147,8 +155,9 @@ FLUTTER_EXPORT * `-runWithEntrypoint:` or `-runWithEntryPoint:libraryURI`. * * You can subscribe to semantics updates via `NSNotificationCenter` by adding - * an observer for the name "FlutterSemanticsUpdate". The `object` parameter - * will be the `FlutterViewController` associated with the semantics update. + * an observer for the name `FlutterSemanticsUpdateNotification`. The `object` + * parameter will be the `FlutterViewController` associated with the semantics + * update. */ - (void)ensureSemanticsEnabled; From f5e8b39432d0648d6fb3ebd9fe145e805555878a Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 6 Mar 2019 16:30:44 -0800 Subject: [PATCH 7/7] use FlutterSemanticsUpdateNotification from header, move to VC header --- .../platform/darwin/ios/framework/Headers/FlutterEngine.h | 8 -------- .../darwin/ios/framework/Headers/FlutterViewController.h | 8 ++++++++ shell/platform/darwin/ios/platform_view_ios.mm | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h index b4e91a0f45c02..c7a4836a9f50c 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h @@ -16,14 +16,6 @@ @class FlutterViewController; -/** - * The name used for semantic update nofications via `NSNotificationCenter`. - * - * The object passed as the sender is the `FlutterViewController` associated - * with the update. - */ -const NSNotificationName FlutterSemanticsUpdateNotification = @"FlutterSemanticsUpdate"; - /** * The FlutterEngine class coordinates a single instance of execution for a * `FlutterDartProject`. It may have zero or one `FlutterViewController` at a diff --git a/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h b/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h index 371a888c88394..1ac7d61c5e614 100644 --- a/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h +++ b/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h @@ -17,6 +17,14 @@ @class FlutterEngine; +/** + * The name used for semantic update nofications via `NSNotificationCenter`. + * + * The object passed as the sender is the `FlutterViewController` associated + * with the update. + */ +const NSNotificationName FlutterSemanticsUpdateNotification = @"FlutterSemanticsUpdate"; + /** * A `UIViewController` implementation for Flutter views. * diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index 5c03b7f35406d..6f138edcfdd11 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -114,7 +114,7 @@ FML_DCHECK(owner_controller_); if (accessibility_bridge_) { accessibility_bridge_->UpdateSemantics(std::move(update), std::move(actions)); - [[NSNotificationCenter defaultCenter] postNotificationName:@"FlutterSemanticsUpdate" + [[NSNotificationCenter defaultCenter] postNotificationName:FlutterSemanticsUpdateNotification object:owner_controller_.get()]; } }