// Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef FLUTTER_SHELL_PLATFORM_COMMON_FLUTTER_PLATFORM_NODE_DELEGATE_H_ #define FLUTTER_SHELL_PLATFORM_COMMON_FLUTTER_PLATFORM_NODE_DELEGATE_H_ #include "flutter/fml/mapping.h" #include "flutter/shell/platform/embedder/embedder.h" #include "flutter/third_party/accessibility/ax/ax_event_generator.h" #include "flutter/third_party/accessibility/ax/platform/ax_platform_node_delegate_base.h" namespace flutter { typedef ui::AXNode::AXID AccessibilityNodeId; //------------------------------------------------------------------------------ /// The platform node delegate to be used in accessibility bridge. This /// class is responsible for providing native accessibility object with /// appropriate information, such as accessibility label/value/bounds. /// /// While most methods have default implementations and are ready to be used /// as-is, the subclasses must override the GetNativeViewAccessible to return /// native accessibility objects. To do that, subclasses should create and /// maintain AXPlatformNode[s] which delegate their accessibility attributes to /// this class. /// /// For desktop platforms, subclasses also need to override the GetBoundsRect /// to apply window-to-screen transform. /// /// This class transforms bounds assuming the device pixel ratio is 1.0. See /// the https://github.com/flutter/flutter/issues/74283 for more information. class FlutterPlatformNodeDelegate : public ui::AXPlatformNodeDelegateBase { public: //---------------------------------------------------------------------------- /// The required interface to be able to own the flutter platform node /// delegate. class OwnerBridge { public: virtual ~OwnerBridge() = default; //--------------------------------------------------------------------------- /// @brief Gets the rectangular bounds of the ax node relative to /// global coordinate /// /// @param[in] node The ax node to look up. /// @param[in] offscreen the bool reference to hold the result whether /// the ax node is outside of its ancestors' bounds. /// @param[in] clip_bounds whether to clip the result if the ax node cannot /// be fully contained in its ancestors' bounds. virtual gfx::RectF RelativeToGlobalBounds(const ui::AXNode* node, bool& offscreen, bool clip_bounds) = 0; protected: friend class FlutterPlatformNodeDelegate; //--------------------------------------------------------------------------- /// @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 Get the native accessibility node with the given id. /// /// @param[in] id The id of the native accessibility node you /// want to retrieve. virtual gfx::NativeViewAccessible GetNativeAccessibleFromId( AccessibilityNodeId id) = 0; //--------------------------------------------------------------------------- /// @brief Get the last id of the node that received accessibility /// focus. virtual AccessibilityNodeId GetLastFocusedId() = 0; //--------------------------------------------------------------------------- /// @brief Update the id of the node that is currently foucsed by the /// native accessibility system. /// /// @param[in] node_id The id of the focused node. virtual void SetLastFocusedId(AccessibilityNodeId node_id) = 0; }; FlutterPlatformNodeDelegate(); // |ui::AXPlatformNodeDelegateBase| virtual ~FlutterPlatformNodeDelegate() override; // |ui::AXPlatformNodeDelegateBase| const ui::AXUniqueId& GetUniqueId() const override { return unique_id_; } // |ui::AXPlatformNodeDelegateBase| const ui::AXNodeData& GetData() const override; // |ui::AXPlatformNodeDelegateBase| bool AccessibilityPerformAction(const ui::AXActionData& data) override; // |ui::AXPlatformNodeDelegateBase| gfx::NativeViewAccessible GetParent() override; // |ui::AXPlatformNodeDelegateBase| gfx::NativeViewAccessible GetFocus() override; // |ui::AXPlatformNodeDelegateBase| int GetChildCount() const override; // |ui::AXPlatformNodeDelegateBase| gfx::NativeViewAccessible ChildAtIndex(int index) override; // |ui::AXPlatformNodeDelegateBase| gfx::Rect GetBoundsRect( const ui::AXCoordinateSystem coordinate_system, const ui::AXClippingBehavior clipping_behavior, ui::AXOffscreenResult* offscreen_result) const override; //------------------------------------------------------------------------------ /// @brief Called only once, immediately after construction. The /// constructor doesn't take any arguments because in the Windows /// subclass we use a special function to construct a COM object. /// Subclasses must call super. virtual void Init(std::weak_ptr bridge, ui::AXNode* node); //------------------------------------------------------------------------------ /// @brief Gets the underlying ax node for this platform node delegate. ui::AXNode* GetAXNode() const; //------------------------------------------------------------------------------ /// @brief Gets the owner of this platform node delegate. This is useful /// when you want to get the information about surrounding nodes /// of this platform node delegate, e.g. the global rect of this /// platform node delegate. This pointer is only safe in the /// platform thread. std::weak_ptr GetOwnerBridge() const; private: ui::AXNode* ax_node_; std::weak_ptr bridge_; ui::AXUniqueId unique_id_; }; } // namespace flutter #endif // FLUTTER_SHELL_PLATFORM_COMMON_FLUTTER_PLATFORM_NODE_DELEGATE_H_