From c93bb58102daf231424f75ca7dc92ba3e01ec61e Mon Sep 17 00:00:00 2001 From: chunhtai <47866232+chunhtai@users.noreply.github.com> Date: Thu, 16 Jul 2020 11:00:28 -0700 Subject: [PATCH] Makes IOS dispatch showOnCcreen action for header semantics nodes (flutter/engine#19788) * Makes IOS dispatchs showOnCcreen action for header semantics nodes * update * format --- .../ios/framework/Source/SemanticsObject.mm | 3 +- .../framework/Source/SemanticsObjectTest.mm | 65 ++++++++++++++++++- 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObject.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObject.mm index 34694b55175..8819e6374c8 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObject.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObject.mm @@ -452,7 +452,8 @@ flutter::SemanticsAction GetSemanticsActionForScrollDirection( - (void)accessibilityElementDidBecomeFocused { if (![self isAccessibilityBridgeAlive]) return; - if ([self node].HasFlag(flutter::SemanticsFlags::kIsHidden)) { + if ([self node].HasFlag(flutter::SemanticsFlags::kIsHidden) || + [self node].HasFlag(flutter::SemanticsFlags::kIsHeader)) { [self bridge]->DispatchSemanticsAction([self uid], flutter::SemanticsAction::kShowOnScreen); } if ([self node].HasAction(flutter::SemanticsAction::kDidGainAccessibilityFocus)) { diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObjectTest.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObjectTest.mm index 7ee7df2d2b7..3c42aeacb3e 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObjectTest.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/SemanticsObjectTest.mm @@ -8,16 +8,33 @@ FLUTTER_ASSERT_ARC namespace flutter { namespace { + +class SemanticsActionObservation { + public: + SemanticsActionObservation(int32_t observed_id, SemanticsAction observed_action) + : id(observed_id), action(observed_action) {} + + int32_t id; + SemanticsAction action; +}; + class MockAccessibilityBridge : public AccessibilityBridgeIos { public: - MockAccessibilityBridge() { view_ = [[UIView alloc] init]; } + MockAccessibilityBridge() : observations({}) { view_ = [[UIView alloc] init]; } UIView* view() const override { return view_; } UIView* textInputView() override { return nil; } - void DispatchSemanticsAction(int32_t id, SemanticsAction action) override {} + void DispatchSemanticsAction(int32_t id, SemanticsAction action) override { + SemanticsActionObservation observation(id, action); + observations.push_back(observation); + } void DispatchSemanticsAction(int32_t id, SemanticsAction action, - std::vector args) override {} + std::vector args) override { + SemanticsActionObservation observation(id, action); + observations.push_back(observation); + } FlutterPlatformViewsController* GetPlatformViewsController() const override { return nil; } + std::vector observations; private: UIView* view_; @@ -102,4 +119,46 @@ class MockAccessibilityBridge : public AccessibilityBridgeIos { XCTAssertTrue([object nodeShouldTriggerAnnouncement:&node]); } +- (void)testShouldDispatchShowOnScreenActionForHeader { + fml::WeakPtrFactory factory( + new flutter::MockAccessibilityBridge()); + fml::WeakPtr bridge = factory.GetWeakPtr(); + SemanticsObject* object = [[SemanticsObject alloc] initWithBridge:bridge uid:1]; + + // Handle initial setting of node with header. + flutter::SemanticsNode node; + node.flags = static_cast(flutter::SemanticsFlags::kIsHeader); + node.label = "foo"; + + [object setSemanticsNode:&node]; + + // Simulate accessibility focus. + [object accessibilityElementDidBecomeFocused]; + + XCTAssertTrue(bridge->observations.size() == 1); + XCTAssertTrue(bridge->observations[0].id == 1); + XCTAssertTrue(bridge->observations[0].action == flutter::SemanticsAction::kShowOnScreen); +} + +- (void)testShouldDispatchShowOnScreenActionForHidden { + fml::WeakPtrFactory factory( + new flutter::MockAccessibilityBridge()); + fml::WeakPtr bridge = factory.GetWeakPtr(); + SemanticsObject* object = [[SemanticsObject alloc] initWithBridge:bridge uid:1]; + + // Handle initial setting of node with hidden. + flutter::SemanticsNode node; + node.flags = static_cast(flutter::SemanticsFlags::kIsHidden); + node.label = "foo"; + + [object setSemanticsNode:&node]; + + // Simulate accessibility focus. + [object accessibilityElementDidBecomeFocused]; + + XCTAssertTrue(bridge->observations.size() == 1); + XCTAssertTrue(bridge->observations[0].id == 1); + XCTAssertTrue(bridge->observations[0].action == flutter::SemanticsAction::kShowOnScreen); +} + @end