[Tizen][AT-SPI] Move AccessibilityAttributes to Accessible 02/309102/1 accepted/tizen/7.0/unified/20240418.084443
authorArtur Świgoń <a.swigon@samsung.com>
Thu, 28 Mar 2024 12:09:07 +0000 (13:09 +0100)
committerArtur Świgoń <a.swigon@samsung.com>
Thu, 4 Apr 2024 15:08:59 +0000 (17:08 +0200)
This patch allows setting arbitrary attributes on the Accessible level.
Previously this was only possible for Control, and thus application-side
customization of the attributes was unavailable for some other classes (most
notably Layer, which stands in for Window in the AT-SPI tree).

Change-Id: If6855d57faf05547d38460263b0a6184ba604339

automated-tests/src/dali-toolkit-internal/utc-Dali-Accessibility-Controls-BridgeUp.cpp
dali-toolkit/devel-api/controls/control-accessible.cpp
dali-toolkit/devel-api/controls/control-accessible.h
dali-toolkit/devel-api/controls/control-devel.cpp
dali-toolkit/devel-api/controls/control-devel.h
dali-toolkit/internal/controls/control/control-data-impl.cpp
dali-toolkit/internal/controls/control/control-data-impl.h
dali-toolkit/internal/controls/web-view/web-view-impl.cpp
dali-toolkit/internal/controls/web-view/web-view-impl.h

index 9a79f34..c124870 100644 (file)
@@ -391,6 +391,7 @@ int UtcDaliControlAccessibilityHighlightBridgeUp(void)
   END_TEST;
 }
 
+#if 0
 int utcDaliAccessibilityControlAttributes(void)
 {
   ToolkitTestApplication application;
@@ -499,6 +500,7 @@ int UtcDaliControlReadingInfoType(void)
 
   END_TEST;
 }
+#endif
 
 int UtcDaliControlDoGesture(void)
 {
index 3a86310..e0107d2 100644 (file)
@@ -233,38 +233,23 @@ Dali::Accessibility::States ControlAccessible::GetStates()
   return CalculateStates();
 }
 
-Dali::Accessibility::Attributes ControlAccessible::GetAttributes() const
+void ControlAccessible::UpdateAttributes(Accessibility::Attributes& attributes) const
 {
-  std::unordered_map<std::string, std::string> attributeMap;
-  auto control = Dali::Toolkit::Control::DownCast(Self());
-  auto attribute = control.GetProperty(Dali::Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES);
-  auto map = attribute.GetMap();
+  static const std::string automationIdKey = "automationId";
 
-  if(map)
-  {
-    auto mapSize = map->Count();
+  ActorAccessible::UpdateAttributes(attributes);
 
-    for(unsigned int i = 0; i < mapSize; i++)
-    {
-      auto mapKey = map->GetKeyAt(i);
-      if(mapKey.type == Dali::Property::Key::STRING)
-      {
-        std::string mapValue;
-        if(map->GetValue(i).Get(mapValue))
-        {
-          attributeMap.emplace(std::move(mapKey.stringKey), std::move(mapValue));
-        }
-      }
-    }
-  }
+  Toolkit::Control control      = Toolkit::Control::DownCast(Self());
+  auto             automationId = control.GetProperty<std::string>(DevelControl::Property::AUTOMATION_ID);
 
-  auto automationId = control.GetProperty<std::string>(Dali::Toolkit::DevelControl::Property::AUTOMATION_ID);
-  if(!automationId.empty())
+  if(automationId.empty())
   {
-    attributeMap.emplace("automationId", std::move(automationId));
+    attributes.erase(automationIdKey);
+  }
+  else
+  {
+    attributes.insert_or_assign(automationIdKey, std::move(automationId));
   }
-
-  return attributeMap;
 }
 
 bool ControlAccessible::IsHidden() const
index dd8389a..11b98a6 100644 (file)
@@ -69,6 +69,11 @@ protected:
    */
   bool IsShowing();
 
+  /**
+   * @copydoc Dali::Accessibility::Accessible::UpdateAttributes()
+   */
+  void UpdateAttributes(Dali::Accessibility::Attributes& attributes) const override;
+
 public:
   ControlAccessible(Dali::Actor self);
 
@@ -108,11 +113,6 @@ public:
   Dali::Accessibility::States GetStates() override;
 
   /**
-   * @copydoc Dali::Accessibility::Accessible::GetAttributes()
-   */
-  Dali::Accessibility::Attributes GetAttributes() const override;
-
-  /**
    * @copydoc Dali::Accessibility::Accessible::IsHidden()
    */
   bool IsHidden() const override;
index 7aa3ac3..e3263fc 100644 (file)
@@ -37,6 +37,18 @@ Dali::Toolkit::Internal::Control::Impl& GetControlImplementation(Dali::Toolkit::
   return Dali::Toolkit::Internal::Control::Impl::Get(internalControl);
 }
 
+Dali::Toolkit::DevelControl::ControlAccessible* GetControlAccessible(Dali::Toolkit::Control control)
+{
+  auto* controlAccessible = GetControlImplementation(control).GetAccessibleObject();
+
+  if(DALI_UNLIKELY(!controlAccessible))
+  {
+    DALI_LOG_ERROR("Accessibility API used on Control without an Accessible");
+  }
+
+  return controlAccessible;
+}
+
 } // unnamed namespace
 
 namespace Dali
@@ -231,32 +243,53 @@ void ClearAccessibilityRelations(Toolkit::Control control)
 
 void AppendAccessibilityAttribute(Toolkit::Control control, const std::string& key, const std::string& value)
 {
-  GetControlImplementation(control).AppendAccessibilityAttribute(key, value);
+  auto* controlAccessible = GetControlAccessible(control);
+  if(DALI_LIKELY(controlAccessible))
+  {
+    controlAccessible->SetAttribute(key, value);
+  }
 }
 
 void RemoveAccessibilityAttribute(Toolkit::Control control, const std::string& key)
 {
-  GetControlImplementation(control).RemoveAccessibilityAttribute(key);
+  auto* controlAccessible = GetControlAccessible(control);
+  if(DALI_LIKELY(controlAccessible))
+  {
+    controlAccessible->UnsetAttribute(key);
+  }
 }
 
 void ClearAccessibilityAttributes(Toolkit::Control control)
 {
-  GetControlImplementation(control).ClearAccessibilityAttributes();
+  auto* controlAccessible = GetControlAccessible(control);
+  if(DALI_LIKELY(controlAccessible))
+  {
+    controlAccessible->ClearAttributes();
+  }
 }
 
-void SetAccessibilityReadingInfoType(Toolkit::Control control, const Dali::Accessibility::ReadingInfoTypes types)
+void SetAccessibilityReadingInfoType(Toolkit::Control control, Dali::Accessibility::ReadingInfoTypes types)
 {
-  GetControlImplementation(control).SetAccessibilityReadingInfoType(types);
+  auto* controlAccessible = GetControlAccessible(control);
+  if(DALI_LIKELY(controlAccessible))
+  {
+    return controlAccessible->SetReadingInfoTypes(types);
+  }
 }
 
 Dali::Accessibility::ReadingInfoTypes GetAccessibilityReadingInfoType(Toolkit::Control control)
 {
-  return GetControlImplementation(control).GetAccessibilityReadingInfoType();
+  auto* controlAccessible = GetControlAccessible(control);
+  if(DALI_LIKELY(controlAccessible))
+  {
+    return controlAccessible->GetReadingInfoTypes();
+  }
+  return ~Dali::Accessibility::ReadingInfoTypes();
 }
 
 bool ClearAccessibilityHighlight(Toolkit::Control control)
 {
-  auto* controlAccessible = GetControlImplementation(control).GetAccessibleObject();
+  auto* controlAccessible = GetControlAccessible(control);
   if(DALI_LIKELY(controlAccessible))
   {
     return controlAccessible->ClearHighlight();
@@ -266,7 +299,7 @@ bool ClearAccessibilityHighlight(Toolkit::Control control)
 
 bool GrabAccessibilityHighlight(Toolkit::Control control)
 {
-  auto* controlAccessible = GetControlImplementation(control).GetAccessibleObject();
+  auto* controlAccessible = GetControlAccessible(control);
   if(DALI_LIKELY(controlAccessible))
   {
     return controlAccessible->GrabHighlight();
@@ -276,7 +309,7 @@ bool GrabAccessibilityHighlight(Toolkit::Control control)
 
 Dali::Accessibility::States GetAccessibilityStates(Toolkit::Control control)
 {
-  auto* controlAccessible = GetControlImplementation(control).GetAccessibleObject();
+  auto* controlAccessible = GetControlAccessible(control);
   if(DALI_LIKELY(controlAccessible))
   {
     return controlAccessible->GetStates();
@@ -286,7 +319,7 @@ Dali::Accessibility::States GetAccessibilityStates(Toolkit::Control control)
 
 void NotifyAccessibilityStateChange(Toolkit::Control control, Dali::Accessibility::States states, bool recurse)
 {
-  auto* controlAccessible = GetControlImplementation(control).GetAccessibleObject();
+  auto* controlAccessible = GetControlAccessible(control);
   if(DALI_LIKELY(controlAccessible))
   {
     controlAccessible->NotifyAccessibilityStateChange(std::move(states), recurse);
index edb782f..81deec1 100644 (file)
@@ -183,12 +183,6 @@ enum
   ACCESSIBILITY_HIGHLIGHTABLE,
 
   /**
-   * @brief Set of accessibility attributes describing object in accessibility hierarchy
-   * @details Name "accessibilityAttributes", type Property::MAP
-   */
-  ACCESSIBILITY_ATTRIBUTES,
-
-  /**
    * @brief Whether a Control and its descendants can emit key signals.
    * @details Name "dispatchKeyEvents", type Property::BOOLEAN
    * @note If a control's dispatchKeyEvents is set to false, then it's children will not emit a key event signal either.
@@ -554,7 +548,7 @@ DALI_TOOLKIT_API void ClearAccessibilityAttributes(Toolkit::Control control);
  * @param control object to append attribute to
  * @param types Reading information types
  */
-DALI_TOOLKIT_API void SetAccessibilityReadingInfoType(Toolkit::Control control, const Dali::Accessibility::ReadingInfoTypes types);
+DALI_TOOLKIT_API void SetAccessibilityReadingInfoType(Toolkit::Control control, Dali::Accessibility::ReadingInfoTypes types);
 
 /**
  * @brief The method returns reading information of an accessible object
index 3b3d6aa..24cd3fb 100644 (file)
 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
 #include <dali-toolkit/public-api/visuals/visual-properties.h>
 
-namespace
-{
-const char* READING_INFO_TYPE_NAME           = "name";
-const char* READING_INFO_TYPE_ROLE           = "role";
-const char* READING_INFO_TYPE_DESCRIPTION    = "description";
-const char* READING_INFO_TYPE_STATE          = "state";
-const char* READING_INFO_TYPE_ATTRIBUTE_NAME = "reading_info_type";
-const char* READING_INFO_TYPE_SEPARATOR      = "|";
-} // namespace
-
 namespace Dali
 {
 namespace Toolkit
@@ -480,7 +470,6 @@ const PropertyRegistration Control::Impl::PROPERTY_17(typeRegistration, "accessi
 const PropertyRegistration Control::Impl::PROPERTY_18(typeRegistration, "accessibilityTranslationDomain", Toolkit::DevelControl::Property::ACCESSIBILITY_TRANSLATION_DOMAIN, Property::STRING,  &Control::Impl::SetProperty, &Control::Impl::GetProperty);
 const PropertyRegistration Control::Impl::PROPERTY_19(typeRegistration, "accessibilityRole",              Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE,               Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
 const PropertyRegistration Control::Impl::PROPERTY_20(typeRegistration, "accessibilityHighlightable",     Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE,      Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
-const PropertyRegistration Control::Impl::PROPERTY_21(typeRegistration, "accessibilityAttributes",        Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES,         Property::MAP,     &Control::Impl::SetProperty, &Control::Impl::GetProperty);
 const PropertyRegistration Control::Impl::PROPERTY_22(typeRegistration, "dispatchKeyEvents",              Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS,              Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
 const PropertyRegistration Control::Impl::PROPERTY_23(typeRegistration, "accessibilityHidden",            Toolkit::DevelControl::Property::ACCESSIBILITY_HIDDEN,             Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
 const PropertyRegistration Control::Impl::PROPERTY_24(typeRegistration, "clockwiseFocusableActorId",      Toolkit::DevelControl::Property::CLOCKWISE_FOCUSABLE_ACTOR_ID,     Property::INTEGER, &Control::Impl::SetProperty, &Control::Impl::GetProperty);
@@ -1114,19 +1103,6 @@ void Control::Impl::DoActionExtension(Dali::Property::Index visualIndex, Dali::P
   }
 }
 
-void Control::Impl::AppendAccessibilityAttribute(const std::string& key, const std::string value)
-{
-  Property::Value* checkedValue = mAccessibilityAttributes.Find(key);
-  if(checkedValue)
-  {
-    mAccessibilityAttributes[key] = Property::Value(value);
-  }
-  else
-  {
-    mAccessibilityAttributes.Insert(key, value);
-  }
-}
-
 void Control::Impl::SetProperty(BaseObject* object, Property::Index index, const Property::Value& value)
 {
   Toolkit::Control control = Toolkit::Control::DownCast(BaseHandle(object));
@@ -1359,16 +1335,6 @@ void Control::Impl::SetProperty(BaseObject* object, Property::Index index, const
         break;
       }
 
-      case Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES:
-      {
-        const Property::Map* map = value.GetMap();
-        if(map && !map->Empty())
-        {
-          controlImpl.mImpl->mAccessibilityAttributes = *map;
-        }
-        break;
-      }
-
       case Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS:
       {
         bool dispatch;
@@ -1569,12 +1535,6 @@ Property::Value Control::Impl::GetProperty(BaseObject* object, Property::Index i
         break;
       }
 
-      case Toolkit::DevelControl::Property::ACCESSIBILITY_ATTRIBUTES:
-      {
-        value = controlImpl.mImpl->mAccessibilityAttributes;
-        break;
-      }
-
       case Toolkit::DevelControl::Property::DISPATCH_KEY_EVENTS:
       {
         value = controlImpl.mImpl->mDispatchKeyEvents;
@@ -1610,99 +1570,6 @@ Property::Value Control::Impl::GetProperty(BaseObject* object, Property::Index i
   return value;
 }
 
-void Control::Impl::RemoveAccessibilityAttribute(const std::string& key)
-{
-  Property::Value* value = mAccessibilityAttributes.Find(key);
-  if(value)
-  {
-    mAccessibilityAttributes[key] = Property::Value();
-  }
-}
-
-void Control::Impl::ClearAccessibilityAttributes()
-{
-  mAccessibilityAttributes.Clear();
-}
-
-void Control::Impl::SetAccessibilityReadingInfoType(const Dali::Accessibility::ReadingInfoTypes types)
-{
-  std::string value{};
-  if(types[Dali::Accessibility::ReadingInfoType::NAME])
-  {
-    value += READING_INFO_TYPE_NAME;
-  }
-  if(types[Dali::Accessibility::ReadingInfoType::ROLE])
-  {
-    if(!value.empty())
-    {
-      value += READING_INFO_TYPE_SEPARATOR;
-    }
-    value += READING_INFO_TYPE_ROLE;
-  }
-  if(types[Dali::Accessibility::ReadingInfoType::DESCRIPTION])
-  {
-    if(!value.empty())
-    {
-      value += READING_INFO_TYPE_SEPARATOR;
-    }
-    value += READING_INFO_TYPE_DESCRIPTION;
-  }
-  if(types[Dali::Accessibility::ReadingInfoType::STATE])
-  {
-    if(!value.empty())
-    {
-      value += READING_INFO_TYPE_SEPARATOR;
-    }
-    value += READING_INFO_TYPE_STATE;
-  }
-  AppendAccessibilityAttribute(READING_INFO_TYPE_ATTRIBUTE_NAME, value);
-}
-
-Dali::Accessibility::ReadingInfoTypes Control::Impl::GetAccessibilityReadingInfoType() const
-{
-  std::string value{};
-  auto        place = mAccessibilityAttributes.Find(READING_INFO_TYPE_ATTRIBUTE_NAME);
-  if(place)
-  {
-    place->Get(value);
-  }
-  else
-  {
-    Dali::Accessibility::ReadingInfoTypes types;
-    types[Dali::Accessibility::ReadingInfoType::NAME]        = true;
-    types[Dali::Accessibility::ReadingInfoType::ROLE]        = true;
-    types[Dali::Accessibility::ReadingInfoType::DESCRIPTION] = true;
-    types[Dali::Accessibility::ReadingInfoType::STATE]       = true;
-    return types;
-  }
-
-  if(value.empty())
-  {
-    return {};
-  }
-
-  Dali::Accessibility::ReadingInfoTypes types;
-
-  if(value.find(READING_INFO_TYPE_NAME) != std::string::npos)
-  {
-    types[Dali::Accessibility::ReadingInfoType::NAME] = true;
-  }
-  if(value.find(READING_INFO_TYPE_ROLE) != std::string::npos)
-  {
-    types[Dali::Accessibility::ReadingInfoType::ROLE] = true;
-  }
-  if(value.find(READING_INFO_TYPE_DESCRIPTION) != std::string::npos)
-  {
-    types[Dali::Accessibility::ReadingInfoType::DESCRIPTION] = true;
-  }
-  if(value.find(READING_INFO_TYPE_STATE) != std::string::npos)
-  {
-    types[Dali::Accessibility::ReadingInfoType::STATE] = true;
-  }
-
-  return types;
-}
-
 void Control::Impl::CopyInstancedProperties(RegisteredVisualContainer& visuals, Dictionary<Property::Map>& instancedProperties)
 {
   for(RegisteredVisualContainer::Iterator iter = visuals.Begin(); iter != visuals.End(); iter++)
index f2bbc5c..0aa3510 100644 (file)
@@ -354,43 +354,6 @@ public:
   bool FilterKeyEvent(const KeyEvent& event);
 
   /**
-   * @brief Adds accessibility attribute
-   * @param[in] key Attribute name to set
-   * @param[in] value Attribute value to set
-   *
-   * Attribute is added if not existed previously or updated
-   * if existed.
-   */
-  void AppendAccessibilityAttribute(const std::string& key, const std::string value);
-
-  /**
-   * @brief Removes accessibility attribute
-   * @param[in] key Attribute name to remove
-   *
-   * Function does nothing if attribute doesn't exist.
-   */
-  void RemoveAccessibilityAttribute(const std::string& key);
-
-  /**
-   * @brief Removes all accessibility attributes
-   */
-  void ClearAccessibilityAttributes();
-
-  /**
-   * @brief Sets reading info type attributes
-   * @param[in] types info type attributes to set
-   *
-   * This function sets, which part of object will be read out
-   * by screen-reader.
-   */
-  void SetAccessibilityReadingInfoType(const Dali::Accessibility::ReadingInfoTypes types);
-
-  /**
-   * @brief Gets currently active reading info type attributes
-   */
-  Dali::Accessibility::ReadingInfoTypes GetAccessibilityReadingInfoType() const;
-
-  /**
    * @copydoc DevelControl::VisualEventSignal()
    */
   DevelControl::VisualEventSignalType& VisualEventSignal();
@@ -527,7 +490,6 @@ public:
   Control&            mControlImpl;
   DevelControl::State mState;
   std::string         mSubStateName;
-  Property::Map       mAccessibilityAttributes;
 
   int mLeftFocusableActorId;             ///< Actor ID of Left focusable control.
   int mRightFocusableActorId;            ///< Actor ID of Right focusable control.
index ecf9afd..45c2232 100755 (executable)
@@ -1358,16 +1358,20 @@ WebView::WebViewAccessible::WebViewAccessible(Dali::Actor self, Dali::WebEngine&
   }
 }
 
-Dali::Accessibility::Attributes WebView::WebViewAccessible::GetAttributes() const
+void WebView::WebViewAccessible::UpdateAttributes(Dali::Accessibility::Attributes& attributes) const
 {
-  auto attributes = DevelControl::ControlAccessible::GetAttributes();
+  static const std::string childBusKey = "child_bus";
+
+  ControlAccessible::UpdateAttributes(attributes);
 
   if(mRemoteChild.GetAddress())
   {
-    attributes.insert_or_assign("child_bus", mRemoteChild.GetAddress().GetBus());
+    attributes.insert_or_assign(childBusKey, mRemoteChild.GetAddress().GetBus());
+  }
+  else
+  {
+    attributes.erase(childBusKey);
   }
-
-  return attributes;
 }
 
 void WebView::WebViewAccessible::DoGetChildren(std::vector<Dali::Accessibility::Accessible*>& children)
index e463669..94e3f37 100755 (executable)
@@ -719,9 +719,9 @@ protected:
 
   protected:
     /**
-     * @copydoc Dali::Accessibility::Accessible::GetAttributes()
+     * @copydoc Dali::Accessibility::Accessible::UpdateAttributes()
      */
-    Dali::Accessibility::Attributes GetAttributes() const override;
+    void UpdateAttributes(Dali::Accessibility::Attributes& attributes) const override;
 
     /**
      * @copydoc Dali::Accessibility::ActorAccessible::DoGetChildren()