Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Merge AccessibilityBridge and AccessibilityBridgeDelegate #36597

Merged
merged 26 commits into from
Nov 4, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 7 additions & 17 deletions shell/platform/common/accessibility_bridge.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ constexpr int kHasScrollingAction =
FlutterSemanticsAction::kFlutterSemanticsActionScrollDown;

// AccessibilityBridge
AccessibilityBridge::AccessibilityBridge(
std::unique_ptr<AccessibilityBridgeDelegate> delegate)
: delegate_(std::move(delegate)) {
AccessibilityBridge::AccessibilityBridge() {
event_generator_.SetTree(&tree_);
tree_.AddObserver(static_cast<ui::AXTreeObserver*>(this));
}
Expand Down Expand Up @@ -107,7 +105,7 @@ void AccessibilityBridge::CommitUpdates() {
continue;
}

delegate_->OnAccessibilityEvent(targeted_event);
OnAccessibilityEvent(targeted_event);
}
event_generator_.ClearEvents();
}
Expand All @@ -134,14 +132,13 @@ AccessibilityBridge::GetPendingEvents() {
return result;
}

void AccessibilityBridge::UpdateDelegate(
std::unique_ptr<AccessibilityBridgeDelegate> delegate) {
delegate_ = std::move(delegate);
void AccessibilityBridge::Reset() {
// delegate_ = std::move(delegate);
// Recreate FlutterPlatformNodeDelegates since they may contain stale state
// from the previous AccessibilityBridgeDelegate.
for (const auto& [node_id, old_platform_node_delegate] : id_wrapper_map_) {
std::shared_ptr<FlutterPlatformNodeDelegate> platform_node_delegate =
delegate_->CreateFlutterPlatformNodeDelegate();
CreateFlutterPlatformNodeDelegate();
platform_node_delegate->Init(
std::static_pointer_cast<FlutterPlatformNodeDelegate::OwnerBridge>(
shared_from_this()),
Expand All @@ -166,7 +163,7 @@ void AccessibilityBridge::OnRoleChanged(ui::AXTree* tree,

void AccessibilityBridge::OnNodeCreated(ui::AXTree* tree, ui::AXNode* node) {
BASE_DCHECK(node);
id_wrapper_map_[node->id()] = delegate_->CreateFlutterPlatformNodeDelegate();
id_wrapper_map_[node->id()] = CreateFlutterPlatformNodeDelegate();
id_wrapper_map_[node->id()]->Init(
std::static_pointer_cast<FlutterPlatformNodeDelegate::OwnerBridge>(
shared_from_this()),
Expand Down Expand Up @@ -619,7 +616,7 @@ void AccessibilityBridge::SetLastFocusedId(AccessibilityNodeId node_id) {
auto last_focused_child =
GetFlutterPlatformNodeDelegateFromID(last_focused_id_);
if (!last_focused_child.expired()) {
delegate_->DispatchAccessibilityAction(
DispatchAccessibilityAction(
last_focused_id_,
FlutterSemanticsAction::
kFlutterSemanticsActionDidLoseAccessibilityFocus,
Expand Down Expand Up @@ -649,11 +646,4 @@ gfx::RectF AccessibilityBridge::RelativeToGlobalBounds(const ui::AXNode* node,
clip_bounds);
}

void AccessibilityBridge::DispatchAccessibilityAction(
AccessibilityNodeId target,
FlutterSemanticsAction action,
fml::MallocMapping data) {
delegate_->DispatchAccessibilityAction(target, action, std::move(data));
}

} // namespace flutter
93 changes: 24 additions & 69 deletions shell/platform/common/accessibility_bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,74 +42,34 @@ class AccessibilityBridge
public FlutterPlatformNodeDelegate::OwnerBridge,
private ui::AXTreeObserver {
public:
//-----------------------------------------------------------------------------
/// Delegate to handle requests from the accessibility bridge. The requests
/// include sending accessibility event to native accessibility system,
/// routing accessibility action to the Flutter framework, and creating
/// platform specific FlutterPlatformNodeDelegate.
///
/// The accessibility events are generated when accessibility tree changes.
/// These events must be sent to the native accessibility system through
/// the native API for the system to pick up the changes
/// (e.g. NSAccessibilityPostNotification in MacOS).
///
/// The accessibility actions are generated by the native accessibility system
/// when users interacted with the assistive technologies. Those actions
/// needed to be sent to the Flutter framework.
///
/// Each platform needs to implement the FlutterPlatformNodeDelegate and
/// returns its platform specific instance of FlutterPlatformNodeDelegate
/// in this delegate.
class AccessibilityBridgeDelegate {
public:
virtual ~AccessibilityBridgeDelegate() = default;
//---------------------------------------------------------------------------
/// @brief Handle accessibility events generated due to accessibility
/// tree changes. These events are generated in accessibility
/// bridge and needed to be sent to native accessibility system.
/// See ui::AXEventGenerator::Event for possible events.
///
/// @param[in] targeted_event The object that contains both the
/// generated event and the event target.
virtual void OnAccessibilityEvent(
ui::AXEventGenerator::TargetedEvent targeted_event) = 0;

//---------------------------------------------------------------------------
/// @brief Dispatch accessibility action back to the Flutter framework.
/// These actions are generated in the native accessibility
/// system when users interact with the assistive technologies.
/// For example, a
/// FlutterSemanticsAction::kFlutterSemanticsActionTap is
/// fired when user click or touch the screen.
///
/// @param[in] target The semantics node id of the action
/// target.
/// @param[in] action The generated flutter semantics action.
/// @param[in] data Additional data associated with the
/// action.
virtual void DispatchAccessibilityAction(AccessibilityNodeId target,
FlutterSemanticsAction action,
fml::MallocMapping data) = 0;

//---------------------------------------------------------------------------
/// @brief Creates a platform specific FlutterPlatformNodeDelegate.
/// Ownership passes to the caller. This method will be called
/// by accessibility bridge whenever a new AXNode is created in
/// AXTree. Each platform needs to implement this method in
/// order to inject its subclass into the accessibility bridge.
virtual std::shared_ptr<FlutterPlatformNodeDelegate>
CreateFlutterPlatformNodeDelegate() = 0;
};

//-----------------------------------------------------------------------------
/// @brief Creates a new instance of a accessibility bridge.
///
/// @param[in] user_data A custom pointer to the data of your
/// choice. This pointer can be retrieve later
/// through GetUserData().
explicit AccessibilityBridge(
std::unique_ptr<AccessibilityBridgeDelegate> delegate);
~AccessibilityBridge();
AccessibilityBridge();
virtual ~AccessibilityBridge();

//---------------------------------------------------------------------------
/// @brief Handle accessibility events generated due to accessibility
/// tree changes. These events are generated in accessibility
/// bridge and needed to be sent to native accessibility system.
/// See ui::AXEventGenerator::Event for possible events.
///
/// @param[in] targeted_event The object that contains both the
/// generated event and the event target.
virtual void OnAccessibilityEvent(
ui::AXEventGenerator::TargetedEvent targeted_event) = 0;

//---------------------------------------------------------------------------
/// @brief Creates a platform specific FlutterPlatformNodeDelegate.
/// Ownership passes to the caller. This method will be called
/// by accessibility bridge whenever a new AXNode is created in
/// AXTree. Each platform needs to implement this method in
/// order to inject its subclass into the accessibility bridge.
virtual std::shared_ptr<FlutterPlatformNodeDelegate>
CreateFlutterPlatformNodeDelegate() = 0;

//-----------------------------------------------------------------------------
/// @brief The ID of the root node in the accessibility tree. In Flutter,
Expand Down Expand Up @@ -170,10 +130,11 @@ class AccessibilityBridge
/// all pending events.
const std::vector<ui::AXEventGenerator::TargetedEvent> GetPendingEvents();

protected:
//------------------------------------------------------------------------------
/// @brief Update the AccessibilityBridgeDelegate stored in the
/// accessibility bridge to a new one.
void UpdateDelegate(std::unique_ptr<AccessibilityBridgeDelegate> delegate);
void Reset();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment above needs to be updated


private:
// See FlutterSemanticsNode in embedder.h
Expand Down Expand Up @@ -219,7 +180,6 @@ class AccessibilityBridge
std::unordered_map<int32_t, SemanticsCustomAction>
pending_semantics_custom_action_updates_;
AccessibilityNodeId last_focused_id_ = ui::AXNode::kInvalidAXID;
std::unique_ptr<AccessibilityBridgeDelegate> delegate_;

void InitAXTree(const ui::AXTreeUpdate& initial_state);

Expand Down Expand Up @@ -292,11 +252,6 @@ class AccessibilityBridge
gfx::NativeViewAccessible GetNativeAccessibleFromId(
AccessibilityNodeId id) override;

// |FlutterPlatformNodeDelegate::OwnerBridge|
void DispatchAccessibilityAction(AccessibilityNodeId target,
FlutterSemanticsAction action,
fml::MallocMapping data) override;

// |FlutterPlatformNodeDelegate::OwnerBridge|
gfx::RectF RelativeToGlobalBounds(const ui::AXNode* node,
bool& offscreen,
Expand Down
Loading