[Tizen] Backport accessible lifecycle refactoring 07/317707/1
authorYoungsun Suh <youngsun.suh@samsung.com>
Fri, 14 Jun 2024 07:01:44 +0000 (16:01 +0900)
committerYoungsun Suh <youngsun.suh@samsung.com>
Fri, 13 Sep 2024 06:40:16 +0000 (15:40 +0900)
Use shared_ptr for Accessible object

Change-Id: I83e50c800587fa413d235d15952cbf2dec8bdfe7

Revert "Revert "Update the bridge to own accessible objects""

This reverts commit d7334f5f25d69f3231b9ee64d39d02561452afb7.

Change-Id: Idb61242ede92cf6062ed86e37ab636e3e308987b

automated-tests/src/dali-toolkit-internal/utc-Dali-Accessibility-Controls-BridgeUp.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-test-application.cpp
dali-toolkit/devel-api/controls/control-devel.cpp
dali-toolkit/internal/controls/buttons/check-box-button-impl.cpp
dali-toolkit/internal/controls/buttons/push-button-impl.cpp
dali-toolkit/internal/controls/buttons/radio-button-impl.cpp
dali-toolkit/internal/controls/buttons/toggle-button-impl.cpp
dali-toolkit/internal/controls/control/control-data-impl.cpp
dali-toolkit/internal/controls/control/control-data-impl.h
dali-toolkit/public-api/controls/control-impl.cpp
dali-toolkit/public-api/controls/control-impl.h

index 4dbb9c1..b1df045 100644 (file)
@@ -1926,5 +1926,43 @@ int UtcDaliEmitAccessibilityStateChanged(void)
   DALI_TEST_CHECK(Dali::Accessibility::TestStateChangedResult("showing", 1));
   DALI_TEST_CHECK(Accessibility::Bridge::GetCurrentBridge()->GetDefaultLabel(rootAccessible) != buttonAccessible);
 
+  Dali::Accessibility::TestEnableSC(false);
+
+  END_TEST;
+}
+
+int UtcDaliGetAcessibleTestWithSceneConnection(void)
+{
+  ToolkitTestApplication application;
+
+  Dali::Accessibility::TestEnableSC(true);
+
+  auto layer = Layer::New();
+
+  auto control = Control::New();
+
+  std::weak_ptr<Accessibility::Accessible> layerAccessible   = Accessibility::Accessible::GetOwningPtr(layer);   // AdaptorAccessible
+  std::weak_ptr<Accessibility::Accessible> controlAccessible = Accessibility::Accessible::GetOwningPtr(control); // ControlAccessible
+  DALI_TEST_CHECK(layerAccessible.lock());
+  DALI_TEST_CHECK(controlAccessible.lock());
+
+  // Test Getting already added accessible from the map
+  DALI_TEST_CHECK(!layerAccessible.expired());
+  DALI_TEST_CHECK(!controlAccessible.expired());
+  DALI_TEST_CHECK(Accessibility::Accessible::Get(layer) == layerAccessible.lock().get());
+  DALI_TEST_CHECK(Accessibility::Accessible::Get(control) == controlAccessible.lock().get());
+
+  // Test ControlAccessible Removal
+  control.Reset();
+  DALI_TEST_CHECK(controlAccessible.expired());
+  DALI_TEST_CHECK(Accessibility::Accessible::Get(control) == nullptr);
+
+  // Test AdaptorAccessible Removal
+  layer.Reset();
+  DALI_TEST_CHECK(layerAccessible.expired());
+  DALI_TEST_CHECK(Accessibility::Accessible::Get(layer) == nullptr);
+
+  Dali::Accessibility::TestEnableSC(false);
+
   END_TEST;
 }
index 07b1013..3d2d040 100644 (file)
@@ -52,7 +52,6 @@ ToolkitTestApplication::ToolkitTestApplication(size_t surfaceWidth, size_t surfa
 
   // Core needs to be initialized next before we start the adaptor
   InitializeCore();
-  Accessibility::Accessible::SetObjectRegistry(mCore->GetObjectRegistry());
 
   // This will also emit the window created signals
   AdaptorImpl::GetImpl(*mAdaptor).Start(*mMainWindow);
index d80f3d9..07418d4 100644 (file)
@@ -39,14 +39,14 @@ Dali::Toolkit::Internal::Control::Impl& GetControlImplementation(Dali::Toolkit::
 
 Dali::Toolkit::DevelControl::ControlAccessible* GetControlAccessible(Dali::Toolkit::Control control)
 {
-  auto* controlAccessible = GetControlImplementation(control).GetAccessibleObject();
+  auto controlAccessible = GetControlImplementation(control).GetAccessibleObject();
 
   if(DALI_UNLIKELY(!controlAccessible))
   {
     DALI_LOG_ERROR("Accessibility API used on Control without an Accessible");
   }
 
-  return controlAccessible;
+  return controlAccessible.get();
 }
 
 } // unnamed namespace
@@ -294,7 +294,7 @@ Dali::Accessibility::ReadingInfoTypes GetAccessibilityReadingInfoType(Toolkit::C
 
 bool ClearAccessibilityHighlight(Toolkit::Control control)
 {
-  auto* controlAccessible = GetControlAccessible(control);
+  auto controlAccessible = GetControlImplementation(control).GetAccessibleObject();
   if(DALI_LIKELY(controlAccessible))
   {
     return controlAccessible->ClearHighlight();
@@ -304,7 +304,7 @@ bool ClearAccessibilityHighlight(Toolkit::Control control)
 
 bool GrabAccessibilityHighlight(Toolkit::Control control)
 {
-  auto* controlAccessible = GetControlAccessible(control);
+  auto controlAccessible = GetControlImplementation(control).GetAccessibleObject();
   if(DALI_LIKELY(controlAccessible))
   {
     return controlAccessible->GrabHighlight();
@@ -314,7 +314,7 @@ bool GrabAccessibilityHighlight(Toolkit::Control control)
 
 Dali::Accessibility::States GetAccessibilityStates(Toolkit::Control control)
 {
-  auto* controlAccessible = GetControlAccessible(control);
+  auto controlAccessible = GetControlImplementation(control).GetAccessibleObject();
   if(DALI_LIKELY(controlAccessible))
   {
     return controlAccessible->GetStates();
@@ -324,7 +324,7 @@ Dali::Accessibility::States GetAccessibilityStates(Toolkit::Control control)
 
 void NotifyAccessibilityStateChange(Toolkit::Control control, Dali::Accessibility::States states, bool recurse)
 {
-  auto* controlAccessible = GetControlAccessible(control);
+  auto controlAccessible = GetControlImplementation(control).GetAccessibleObject();
   if(DALI_LIKELY(controlAccessible))
   {
     controlAccessible->NotifyAccessibilityStateChange(std::move(states), recurse);
@@ -348,7 +348,7 @@ bool IsCreateAccessibleEnabled(Toolkit::Control control)
 
 void EmitAccessibilityStateChanged(Dali::Actor actor, Accessibility::State state, int newValue)
 {
-  auto accessible = Accessibility::Accessible::Get(actor);
+  auto accessible = Accessibility::Accessible::GetOwningPtr(actor);
   if(DALI_LIKELY(accessible))
   {
     auto control = Toolkit::Control::DownCast(actor);
index 574ef08..89a0ee0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -101,7 +101,7 @@ void CheckBoxButton::OnStateChange(State newState)
   // TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used
   if((Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self()) && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
   {
-    auto* accessible = GetAccessibleObject();
+    auto accessible = GetAccessibleObject();
     if(DALI_LIKELY(accessible))
     {
       accessible->EmitStateChanged(Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0);
index dea0ee0..00b4546 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -209,7 +209,7 @@ void PushButton::OnStateChange(State newState)
   // TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used
   if((Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self()) && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
   {
-    auto* accessible = GetAccessibleObject();
+    auto accessible = GetAccessibleObject();
     if(DALI_LIKELY(accessible))
     {
       accessible->EmitStateChanged(Dali::Accessibility::State::PRESSED, newState == SELECTED_STATE ? 1 : 0, 0);
index 9aace1a..1aef5f0 100644 (file)
@@ -109,7 +109,7 @@ void RadioButton::OnStateChange(State newState)
   // TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used
   if((Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self()) && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
   {
-    auto* accessible = GetAccessibleObject();
+    auto accessible = GetAccessibleObject();
     if(DALI_LIKELY(accessible))
     {
       accessible->EmitStateChanged(Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0);
index de6cbce..3c08e30 100644 (file)
@@ -404,7 +404,7 @@ void ToggleButton::OnStateChange(State newState)
   // TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used
   if((Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor()) && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
   {
-    auto* accessible = GetAccessibleObject();
+    auto accessible = GetAccessibleObject();
     if(DALI_LIKELY(accessible))
     {
       accessible->EmitStateChanged(Dali::Accessibility::State::CHECKED, mCurrentToggleIndex ? 1 : 0, 0);
index 4cde9b0..1b6028b 100644 (file)
@@ -507,19 +507,6 @@ static bool IsShowingGeometryOnScreen(Dali::Rect<> rect)
   return rect.width > 0 && rect.height > 0;
 }
 
-Dali::Accessibility::Accessible* ExternalAccessibleGetter(Dali::Actor actor)
-{
-  auto control = Toolkit::Control::DownCast(actor);
-  if(!control)
-  {
-    return nullptr;
-  }
-
-  auto& controlImpl = Toolkit::Internal::GetImplementation(control);
-
-  return controlImpl.GetAccessibleObject();
-}
-
 } // unnamed namespace
 
 // clang-format off
@@ -591,7 +578,21 @@ Control::Impl::Impl(Control& controlImpl)
   mNeedToEmitResourceReady(false),
   mDispatchKeyEvents(true)
 {
-  Dali::Accessibility::Accessible::RegisterExternalAccessibleGetter(&ExternalAccessibleGetter);
+  Accessibility::Accessible::RegisterExternalAccessibleGetter([](Dali::Actor actor) -> std::pair<std::shared_ptr<Accessibility::Accessible>, bool> {
+    auto control = Toolkit::Control::DownCast(actor);
+    if(!control)
+    {
+      return {nullptr, true};
+    }
+
+    auto& controlImpl = Toolkit::Internal::GetImplementation(control);
+    if(controlImpl.mImpl->IsCreateAccessibleEnabled())
+    {
+      return {std::shared_ptr<DevelControl::ControlAccessible>(controlImpl.CreateAccessibleObject()), true};
+    }
+
+    return {nullptr, false};
+  });
   mAccessibilityProps.states[DevelControl::AccessibilityState::ENABLED] = true;
 }
 
@@ -634,7 +635,7 @@ void Control::Impl::CheckHighlightedObjectGeometry()
   {
     auto lastPosition   = accessible->GetLastPosition();
     auto accessibleRect = accessible->GetExtents(Dali::Accessibility::CoordinateType::WINDOW);
-    auto rect           = GetShowingGeometry(accessibleRect, accessible);
+    auto rect           = GetShowingGeometry(accessibleRect, accessible.get());
 
     switch(mAccessibilityLastScreenRelativeMoveType)
     {
@@ -1476,7 +1477,7 @@ void Control::Impl::SetProperty(BaseObject* object, Property::Index index, const
         {
           controlImpl.mImpl->mAccessibilityProps.isHidden = hidden;
 
-          auto* accessible = controlImpl.GetAccessibleObject();
+          auto accessible = controlImpl.GetAccessibleObject();
           if(DALI_LIKELY(accessible))
           {
             auto* parent = dynamic_cast<Dali::Accessibility::ActorAccessible*>(accessible->GetParent());
@@ -2178,19 +2179,14 @@ void Control::Impl::OnIdleCallback()
   mIdleCallback = nullptr;
 }
 
-Toolkit::DevelControl::ControlAccessible* Control::Impl::GetAccessibleObject()
+std::shared_ptr<Toolkit::DevelControl::ControlAccessible> Control::Impl::GetAccessibleObject()
 {
-  if(mAccessibleCreatable && !mAccessibleObject)
-  {
-    mAccessibleObject.reset(mControlImpl.CreateAccessibleObject());
-  }
-
-  return mAccessibleObject.get();
+  return std::dynamic_pointer_cast<DevelControl::ControlAccessible>(Accessibility::Accessible::GetOwningPtr(mControlImpl.Self()));
 }
 
 bool Control::Impl::IsAccessibleCreated() const
 {
-  return !!mAccessibleObject;
+  return !!Accessibility::Bridge::GetCurrentBridge()->GetAccessible(mControlImpl.Self());
 }
 
 void Control::Impl::EnableCreateAccessible(bool enable)
index b74efef..47594c9 100644 (file)
@@ -406,7 +406,7 @@ public:
   /**
    * @copydoc Dali::Toolkit::Internal::Control::GetAccessibleObject()
    */
-  Toolkit::DevelControl::ControlAccessible* GetAccessibleObject();
+  std::shared_ptr<Toolkit::DevelControl::ControlAccessible> GetAccessibleObject();
 
   /**
    * @copydoc Dali::Toolkit::DevelControl::IsAccessibleCreated()
@@ -559,8 +559,7 @@ public:
     bool                                                                              isModal{false};
   } mAccessibilityProps;
 
-  bool                                                      mAccessibleCreatable = true;
-  std::unique_ptr<Toolkit::DevelControl::ControlAccessible> mAccessibleObject;
+  bool mAccessibleCreatable = true;
 
   // Gesture Detection
   PinchGestureDetector     mPinchGestureDetector;
index 60aaa28..c4a6dba 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -37,8 +37,8 @@
 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
-#include <dali-toolkit/devel-api/visuals/visual-actions-devel.h>
 #include <dali-toolkit/devel-api/visuals/color-visual-properties-devel.h>
+#include <dali-toolkit/devel-api/visuals/visual-actions-devel.h>
 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
 #include <dali-toolkit/internal/styling/style-manager-impl.h>
 #include <dali-toolkit/internal/visuals/color/color-visual.h>
@@ -173,7 +173,7 @@ void Control::SetResourceReady(bool relayoutRequest)
   controlDataImpl.ResourceReady(relayoutRequest);
 }
 
-Toolkit::DevelControl::ControlAccessible* Control::GetAccessibleObject()
+std::shared_ptr<Toolkit::DevelControl::ControlAccessible> Control::GetAccessibleObject()
 {
   return mImpl->GetAccessibleObject();
 }
@@ -513,7 +513,7 @@ void Control::EmitKeyInputFocusSignal(bool focusGained)
       auto parent = accessible->GetParent();
       if(parent && !accessible->GetStates()[Dali::Accessibility::State::MANAGES_DESCENDANTS])
       {
-        parent->EmitActiveDescendantChanged(accessible);
+        parent->EmitActiveDescendantChanged(accessible.get());
       }
     }
   }
@@ -596,7 +596,7 @@ void Control::OnPropertySet(Property::Index index, const Property::Value& proper
     }
     case Actor::Property::VISIBLE:
     {
-      auto* accessible = GetAccessibleObject();
+      auto accessible = GetAccessibleObject();
       if(DALI_LIKELY(accessible))
       {
         accessible->EmitVisible(Self().GetProperty<bool>(Actor::Property::VISIBLE));
@@ -606,7 +606,7 @@ void Control::OnPropertySet(Property::Index index, const Property::Value& proper
     case DevelActor::Property::USER_INTERACTION_ENABLED:
     {
       const bool enabled = propertyValue.Get<bool>();
-      if (!enabled && Self() == Dali::Toolkit::KeyboardFocusManager::Get().GetCurrentFocusActor())
+      if(!enabled && Self() == Dali::Toolkit::KeyboardFocusManager::Get().GetCurrentFocusActor())
       {
         Dali::Toolkit::KeyboardFocusManager::Get().ClearFocus();
       }
@@ -750,8 +750,7 @@ void Control::SignalDisconnected(SlotObserver* slotObserver, CallbackBase* callb
   mImpl->SignalDisconnected(slotObserver, callback);
 }
 
-void Control::MakeVisualTransition(Dali::Property::Map& sourcePropertyMap, Dali::Property::Map& destinationPropertyMap,
-                                   Dali::Toolkit::Control source, Dali::Toolkit::Control destination, Dali::Property::Index visualIndex)
+void Control::MakeVisualTransition(Dali::Property::Map& sourcePropertyMap, Dali::Property::Map& destinationPropertyMap, Dali::Toolkit::Control source, Dali::Toolkit::Control destination, Dali::Property::Index visualIndex)
 {
   sourcePropertyMap.Clear();
   destinationPropertyMap.Clear();
@@ -770,8 +769,7 @@ void Control::MakeVisualTransition(Dali::Property::Map& sourcePropertyMap, Dali:
   sourceVisual.CreatePropertyMap(sourceMap);
   destinationVisual.CreatePropertyMap(destinationMap);
 
-  static auto findValueVector4 = [](const Property::Map& map, Property::Index index, const Vector4& defaultValue = Vector4()) -> Vector4
-  {
+  static auto findValueVector4 = [](const Property::Map& map, Property::Index index, const Vector4& defaultValue = Vector4()) -> Vector4 {
     Property::Value* propertyValue = map.Find(index);
     if(propertyValue)
     {
@@ -780,8 +778,7 @@ void Control::MakeVisualTransition(Dali::Property::Map& sourcePropertyMap, Dali:
     return defaultValue;
   };
 
-  static auto findValueFloat = [](const Property::Map& map, Property::Index index, const float& defaultValue = 0.0f) -> float
-  {
+  static auto findValueFloat = [](const Property::Map& map, Property::Index index, const float& defaultValue = 0.0f) -> float {
     Property::Value* propertyValue = map.Find(index);
     if(propertyValue)
     {
index b7d3c2e..9e0439e 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_CONTROL_IMPL_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -51,7 +51,6 @@ class ControlAccessible;
 
 namespace Internal
 {
-
 /**
  * @brief This is the internal base class for all controls.
  *
@@ -132,7 +131,7 @@ public:
    *
    * @see CreateAccessibleObject()
    */
-  Toolkit::DevelControl::ControlAccessible* GetAccessibleObject();
+  std::shared_ptr<Toolkit::DevelControl::ControlAccessible> GetAccessibleObject();
 
   // Gesture Detection
 
@@ -278,7 +277,6 @@ public:
   DALI_INTERNAL void KeyboardEnter();
   /// @endcond
 
-
   // Signals
 
   /**
@@ -407,7 +405,6 @@ protected: // From CustomActorImpl
   void OnLayoutNegotiated(float size, Dimension::Type dimension) override;
 
 public: // Helpers for deriving classes
-
   /**
    * @brief Flags for the constructor.
    * @SINCE_1_0.0
@@ -689,8 +686,7 @@ public: // API for derived classes to override
    * @param[in] destination Destination control of the animation.
    * @param[in] visualIndex Property::Index to make animation.
    */
-  void MakeVisualTransition(Dali::Property::Map& sourcePropertyMap, Dali::Property::Map& destinationPropertyMap,
-                            Dali::Toolkit::Control source, Dali::Toolkit::Control destination, Dali::Property::Index visualIndex);
+  void MakeVisualTransition(Dali::Property::Map& sourcePropertyMap, Dali::Property::Map& destinationPropertyMap, Dali::Toolkit::Control source, Dali::Toolkit::Control destination, Dali::Property::Index visualIndex);
 
   /**
    * @brief Retrieves source and destination visual properties for the Transition of this Control.