Skip to content

Commit

Permalink
Update FlutterPlatformNodeDelegate (flutter#38615)
Browse files Browse the repository at this point in the history
* Update FlutterPlatformNodeDelegate

* Unit test
  • Loading branch information
yaakovschectman authored Jan 4, 2023
1 parent 398f5d3 commit ebf01dc
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 0 deletions.
44 changes: 44 additions & 0 deletions shell/platform/common/flutter_platform_node_delegate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@

#include <utility>

#include "flutter/shell/platform/common/accessibility_bridge.h"
#include "flutter/third_party/accessibility/ax/ax_action_data.h"
#include "flutter/third_party/accessibility/ax/ax_tree_manager_map.h"
#include "flutter/third_party/accessibility/gfx/geometry/rect_conversions.h"

namespace flutter {
Expand Down Expand Up @@ -118,4 +120,46 @@ ui::AXPlatformNode* FlutterPlatformNodeDelegate::GetPlatformNode() const {
return nullptr;
}

gfx::NativeViewAccessible
FlutterPlatformNodeDelegate::GetLowestPlatformAncestor() const {
auto bridge_ptr = bridge_.lock();
BASE_DCHECK(bridge_ptr);
auto lowest_platform_ancestor = ax_node_->GetLowestPlatformAncestor();
if (lowest_platform_ancestor) {
return bridge_ptr->GetNativeAccessibleFromId(
ax_node_->GetLowestPlatformAncestor()->id());
}
return nullptr;
}

ui::AXNodePosition::AXPositionInstance
FlutterPlatformNodeDelegate::CreateTextPositionAt(int offset) const {
return ui::AXNodePosition::CreatePosition(*ax_node_, offset);
}

ui::AXPlatformNode* FlutterPlatformNodeDelegate::GetFromNodeID(
int32_t node_id) {
ui::AXTreeManager* tree_manager =
ui::AXTreeManagerMap::GetInstance().GetManager(
ax_node_->tree()->GetAXTreeID());
AccessibilityBridge* platform_manager =
static_cast<AccessibilityBridge*>(tree_manager);
return platform_manager->GetPlatformNodeFromTree(node_id);
}

ui::AXPlatformNode* FlutterPlatformNodeDelegate::GetFromTreeIDAndNodeID(
const ui::AXTreeID& tree_id,
int32_t node_id) {
ui::AXTreeManager* tree_manager =
ui::AXTreeManagerMap::GetInstance().GetManager(tree_id);
AccessibilityBridge* platform_manager =
static_cast<AccessibilityBridge*>(tree_manager);
return platform_manager->GetPlatformNodeFromTree(node_id);
}

const ui::AXTree::Selection FlutterPlatformNodeDelegate::GetUnignoredSelection()
const {
return ax_node_->GetUnignoredSelection();
}

} // namespace flutter
18 changes: 18 additions & 0 deletions shell/platform/common/flutter_platform_node_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,13 @@ class FlutterPlatformNodeDelegate : public ui::AXPlatformNodeDelegateBase {
const ui::AXClippingBehavior clipping_behavior,
ui::AXOffscreenResult* offscreen_result) const override;

// |ui::AXPlatformNodeDelegateBase|
gfx::NativeViewAccessible GetLowestPlatformAncestor() const override;

// |ui::AXPlatformNodeDelegateBase|
ui::AXNodePosition::AXPositionInstance CreateTextPositionAt(
int offset) const override;

//------------------------------------------------------------------------------
/// @brief Called only once, immediately after construction. The
/// constructor doesn't take any arguments because in the Windows
Expand All @@ -147,6 +154,17 @@ class FlutterPlatformNodeDelegate : public ui::AXPlatformNodeDelegateBase {
// Get the platform node represented by this delegate.
virtual ui::AXPlatformNode* GetPlatformNode() const;

// |ui::AXPlatformNodeDelegateBase|
virtual ui::AXPlatformNode* GetFromNodeID(int32_t id) override;

// |ui::AXPlatformNodeDelegateBase|
virtual ui::AXPlatformNode* GetFromTreeIDAndNodeID(
const ui::AXTreeID& tree_id,
int32_t node_id) override;

// |ui::AXPlatformNodeDelegateBase|
virtual const ui::AXTree::Selection GetUnignoredSelection() const override;

private:
ui::AXNode* ax_node_;
std::weak_ptr<OwnerBridge> bridge_;
Expand Down
58 changes: 58 additions & 0 deletions shell/platform/common/flutter_platform_node_delegate_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -246,5 +246,63 @@ TEST(FlutterPlatformNodeDelegateTest, canUseOwnerBridge) {
EXPECT_EQ(result, false);
}

TEST(FlutterPlatformNodeDelegateTest, selfIsLowestPlatformAncestor) {
std::shared_ptr<TestAccessibilityBridge> bridge =
std::make_shared<TestAccessibilityBridge>();
FlutterSemanticsNode root;
root.id = 0;
root.label = "root";
root.hint = "";
root.value = "";
root.increased_value = "";
root.decreased_value = "";
root.tooltip = "";
root.child_count = 0;
root.children_in_traversal_order = nullptr;
root.custom_accessibility_actions_count = 0;
bridge->AddFlutterSemanticsNodeUpdate(&root);

bridge->CommitUpdates();
auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
auto lowest_platform_ancestor = root_node->GetLowestPlatformAncestor();
EXPECT_EQ(root_node->GetNativeViewAccessible(), lowest_platform_ancestor);
}

TEST(FlutterPlatformNodeDelegateTest, canGetFromNodeID) {
std::shared_ptr<TestAccessibilityBridge> bridge =
std::make_shared<TestAccessibilityBridge>();
FlutterSemanticsNode root;
root.id = 0;
root.label = "root";
root.hint = "";
root.value = "";
root.increased_value = "";
root.decreased_value = "";
root.tooltip = "";
root.child_count = 1;
int32_t children[] = {1};
root.children_in_traversal_order = children;
root.custom_accessibility_actions_count = 0;
bridge->AddFlutterSemanticsNodeUpdate(&root);

FlutterSemanticsNode child1;
child1.id = 1;
child1.label = "child 1";
child1.hint = "";
child1.value = "";
child1.increased_value = "";
child1.decreased_value = "";
child1.tooltip = "";
child1.child_count = 0;
child1.custom_accessibility_actions_count = 0;
bridge->AddFlutterSemanticsNodeUpdate(&child1);

bridge->CommitUpdates();
auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
auto node_by_id = root_node->GetFromNodeID(1);
EXPECT_EQ(child1_node->GetPlatformNode(), node_by_id);
}

} // namespace testing
} // namespace flutter

0 comments on commit ebf01dc

Please sign in to comment.