Check validity of accessible obj when accessed from coalescableMessage timer 01/313201/2
authorYoungsun Suh <youngsun.suh@samsung.com>
Thu, 20 Jun 2024 05:09:11 +0000 (14:09 +0900)
committerYoungsun Suh <youngsun.suh@samsung.com>
Thu, 20 Jun 2024 05:18:39 +0000 (14:18 +0900)
Change-Id: Ic2a5d567eb8fa09d32d2c00236b2c138efec9e43

dali/devel-api/adaptor-framework/accessibility-bridge.h
dali/devel-api/adaptor-framework/accessibility.cpp
dali/devel-api/atspi-interfaces/accessible.h
dali/internal/accessibility/bridge/accessible.cpp
dali/internal/accessibility/bridge/bridge-object.cpp
dali/internal/accessibility/bridge/bridge-object.h
dali/internal/accessibility/bridge/dummy/dummy-atspi.h

index 3cac8f50ddf8ad84309bc2cc29865540df893b68..71888423c02598151ee3bc0bf8c41ba20dbd8d36 100644 (file)
@@ -319,7 +319,7 @@ struct DALI_ADAPTOR_API Bridge
    * @param[in] newValue Whether the state value is changed to new value or not.
    * @param[in] reserved Reserved. (Currently, this argument is not implemented in dali)
    **/
-  virtual void EmitStateChanged(Accessible* obj, State state, int newValue, int reserved = 0) = 0;
+  virtual void EmitStateChanged(std::shared_ptr<Accessible> obj, State state, int newValue, int reserved = 0) = 0;
 
   /**
    * @brief Emits window event on at-spi bus.
@@ -336,7 +336,7 @@ struct DALI_ADAPTOR_API Bridge
    * @param[in] obj The accessible object
    * @param[in] event Property changed event
    **/
-  virtual void Emit(Accessible* obj, ObjectPropertyChangeEvent event) = 0;
+  virtual void Emit(std::shared_ptr<Accessible> obj, ObjectPropertyChangeEvent event) = 0;
 
   /**
    * @brief Emits bounds-changed event on at-spi bus.
@@ -344,7 +344,7 @@ struct DALI_ADAPTOR_API Bridge
    * @param[in] obj The accessible object
    * @param[in] rect The rectangle for changed bounds
    **/
-  virtual void EmitBoundsChanged(Accessible* obj, Rect<> rect) = 0;
+  virtual void EmitBoundsChanged(std::shared_ptr<Accessible> obj, Rect<> rect) = 0;
 
   /**
    * @brief Emits org.a11y.atspi.Event.Window.PostRender on the AT-SPI bus.
@@ -357,7 +357,7 @@ struct DALI_ADAPTOR_API Bridge
    * The actual number of events emitted during a given time interval may be smaller
    * than the number of calls to this method, but at least one is guaranteed.
    */
-  virtual void EmitPostRender(Accessible* obj) = 0;
+  virtual void EmitPostRender(std::shared_ptr<Accessible> obj) = 0;
 
   /**
    * @brief Emits key event on at-spi bus.
index 4b4fe25b03f92ea775b84a12ddd5c11518847ea4..6caf3d86bf7699ebeb039043246337263ba54fb8 100644 (file)
@@ -522,7 +522,7 @@ public:
 
   void OnPostRender()
   {
-    Accessibility::Bridge::GetCurrentBridge()->EmitPostRender(this);
+    Accessibility::Bridge::GetCurrentBridge()->EmitPostRender(shared_from_this());
   }
 }; // AdaptorAccessible
 
index 3590817acc86ab3636e98fbda0ee41af30b0dad2..476fbe69b49f9f5feb9df758ff9f32d3c3635711 100644 (file)
@@ -34,7 +34,7 @@ namespace Dali::Accessibility
 /**
  * @brief Basic interface implemented by all accessibility objects.
  */
-class DALI_ADAPTOR_API Accessible
+class DALI_ADAPTOR_API Accessible : public std::enable_shared_from_this<Accessible>
 {
 public:
   virtual ~Accessible() noexcept;
index e50ba2f1a1d2049f54e9e580b03ca434b4d66b39..f7a6ef827e1326532a5afa33d196ec887159bf59 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.
@@ -50,7 +50,7 @@ void Accessible::EmitStateChanged(State state, int newValue, int reserved)
 {
   if(auto bridgeData = GetBridgeData())
   {
-    bridgeData->mBridge->EmitStateChanged(this, state, newValue, reserved);
+    bridgeData->mBridge->EmitStateChanged(shared_from_this(), state, newValue, reserved);
   }
 }
 
@@ -58,7 +58,7 @@ void Accessible::EmitShowing(bool isShowing)
 {
   if(auto bridgeData = GetBridgeData())
   {
-    bridgeData->mBridge->EmitStateChanged(this, State::SHOWING, isShowing ? 1 : 0, 0);
+    bridgeData->mBridge->EmitStateChanged(shared_from_this(), State::SHOWING, isShowing ? 1 : 0, 0);
   }
 }
 
@@ -66,7 +66,7 @@ void Accessible::EmitVisible(bool isVisible)
 {
   if(auto bridgeData = GetBridgeData())
   {
-    bridgeData->mBridge->EmitStateChanged(this, State::VISIBLE, isVisible ? 1 : 0, 0);
+    bridgeData->mBridge->EmitStateChanged(shared_from_this(), State::VISIBLE, isVisible ? 1 : 0, 0);
   }
 }
 
@@ -74,7 +74,7 @@ void Accessible::EmitHighlighted(bool isHighlighted)
 {
   if(auto bridgeData = GetBridgeData())
   {
-    bridgeData->mBridge->EmitStateChanged(this, State::HIGHLIGHTED, isHighlighted ? 1 : 0, 0);
+    bridgeData->mBridge->EmitStateChanged(shared_from_this(), State::HIGHLIGHTED, isHighlighted ? 1 : 0, 0);
   }
 }
 
@@ -82,7 +82,7 @@ void Accessible::EmitFocused(bool isFocused)
 {
   if(auto bridgeData = GetBridgeData())
   {
-    bridgeData->mBridge->EmitStateChanged(this, State::FOCUSED, isFocused ? 1 : 0, 0);
+    bridgeData->mBridge->EmitStateChanged(shared_from_this(), State::FOCUSED, isFocused ? 1 : 0, 0);
   }
 }
 void Accessible::EmitTextInserted(unsigned int position, unsigned int length, const std::string& content)
@@ -152,7 +152,7 @@ void Accessible::Emit(ObjectPropertyChangeEvent event)
 {
   if(auto bridgeData = GetBridgeData())
   {
-    bridgeData->mBridge->Emit(this, event);
+    bridgeData->mBridge->Emit(shared_from_this(), event);
   }
 }
 
@@ -160,7 +160,7 @@ void Accessible::EmitBoundsChanged(Rect<> rect)
 {
   if(auto bridgeData = GetBridgeData())
   {
-    bridgeData->mBridge->EmitBoundsChanged(this, rect);
+    bridgeData->mBridge->EmitBoundsChanged(shared_from_this(), rect);
   }
 }
 
@@ -225,7 +225,7 @@ void Accessible::NotifyAccessibilityStateChange(Dali::Accessibility::States stat
       auto index = static_cast<Dali::Accessibility::State>(i);
       if(states[index])
       {
-        data->mBridge->EmitStateChanged(this, index, GetStates()[index], 0);
+        data->mBridge->EmitStateChanged(shared_from_this(), index, GetStates()[index], 0);
       }
     }
 
index d1f553e1f8d370b6f0702d18bc3df07feb0f621b..0d21e3fe30ef87f017e3ee096306af34dcce39c6 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.
@@ -66,7 +66,7 @@ void BridgeObject::EmitActiveDescendantChanged(Accessible* obj, Accessible* chil
     {"", "root"});
 }
 
-void BridgeObject::Emit(Accessible* obj, ObjectPropertyChangeEvent event)
+void BridgeObject::Emit(std::shared_ptr<Accessible> obj, ObjectPropertyChangeEvent event)
 {
   static const std::unordered_map<ObjectPropertyChangeEvent, std::string_view> eventMap{
     {ObjectPropertyChangeEvent::NAME, "accessible-name"},
@@ -85,16 +85,19 @@ void BridgeObject::Emit(Accessible* obj, ObjectPropertyChangeEvent event)
 
   if(eventName != eventMap.end())
   {
-    AddCoalescableMessage(static_cast<CoalescableMessages>(static_cast<int>(CoalescableMessages::PROPERTY_CHANGED_BEGIN) + static_cast<int>(event)), obj, 1.0f, [=]() {
-      mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
-        GetAccessiblePath(obj),
-        Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
-        "PropertyChange",
-        std::string{eventName->second},
-        0,
-        0,
-        {0},
-        {"", "root"});
+    AddCoalescableMessage(static_cast<CoalescableMessages>(static_cast<int>(CoalescableMessages::PROPERTY_CHANGED_BEGIN) + static_cast<int>(event)), obj.get(), 1.0f, [weakObj = std::weak_ptr<Accessible>(obj), eventName, this]() {
+      if(auto obj = weakObj.lock())
+      {
+        mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
+          GetAccessiblePath(obj.get()),
+          Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
+          "PropertyChange",
+          std::string{eventName->second},
+          0,
+          0,
+          {0},
+          {"", "root"});
+      }
     });
   }
 }
@@ -145,7 +148,7 @@ void BridgeObject::Emit(Accessible* obj, WindowEvent event, unsigned int detail)
   }
 }
 
-void BridgeObject::EmitStateChanged(Accessible* obj, State state, int newValue, int reserved)
+void BridgeObject::EmitStateChanged(std::shared_ptr<Accessible> obj, State state, int newValue, int reserved)
 {
   static const std::unordered_map<State, std::string_view> stateMap{
     {State::INVALID, "invalid"},
@@ -205,52 +208,61 @@ void BridgeObject::EmitStateChanged(Accessible* obj, State state, int newValue,
 
   if(stateName != stateMap.end())
   {
-    AddCoalescableMessage(static_cast<CoalescableMessages>(static_cast<int>(CoalescableMessages::STATE_CHANGED_BEGIN) + static_cast<int>(state)), obj, 1.0f, [=]() {
-      mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
-        GetAccessiblePath(obj),
-        Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
-        "StateChanged",
-        std::string{stateName->second},
-        newValue,
-        reserved,
-        {0},
-        {"", "root"});
+    AddCoalescableMessage(static_cast<CoalescableMessages>(static_cast<int>(CoalescableMessages::STATE_CHANGED_BEGIN) + static_cast<int>(state)), obj.get(), 1.0f, [weakObj = std::weak_ptr<Accessible>(obj), stateName, newValue, reserved, this]() {
+      if(auto obj = weakObj.lock())
+      {
+        mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
+          GetAccessiblePath(obj.get()),
+          Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
+          "StateChanged",
+          std::string{stateName->second},
+          newValue,
+          reserved,
+          {0},
+          {"", "root"});
+      }
     });
   }
 }
 
-void BridgeObject::EmitBoundsChanged(Accessible* obj, Dali::Rect<> rect)
+void BridgeObject::EmitBoundsChanged(std::shared_ptr<Accessible> obj, Dali::Rect<> rect)
 {
   if(!IsUp() || !IsBoundsChangedEventAllowed || obj->IsHidden() || obj->GetSuppressedEvents()[AtspiEvent::BOUNDS_CHANGED])
   {
     return;
   }
 
-  DBus::EldbusVariant<std::tuple<int32_t, int32_t, int32_t, int32_t> > tmp{
-    std::tuple<int32_t, int32_t, int32_t, int32_t>{rect.x, rect.y, rect.width, rect.height}};
+  AddCoalescableMessage(CoalescableMessages::BOUNDS_CHANGED, obj.get(), 1.0f, [weakObj = std::weak_ptr<Accessible>(obj), rect = std::move(rect), this]() {
+    if(auto obj = weakObj.lock())
+    {
+      DBus::EldbusVariant<std::tuple<int32_t, int32_t, int32_t, int32_t> > tmp{
+        std::tuple<int32_t, int32_t, int32_t, int32_t>{rect.x, rect.y, rect.width, rect.height}};
 
-  AddCoalescableMessage(CoalescableMessages::BOUNDS_CHANGED, obj, 1.0f, [=]() {
-    mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<std::tuple<int32_t, int32_t, int32_t, int32_t> >, Address>(
-      GetAccessiblePath(obj),
-      Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
-      "BoundsChanged",
-      "",
-      0,
-      0,
-      tmp,
-      {"", "root"});
+      mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<std::tuple<int32_t, int32_t, int32_t, int32_t> >, Address>(
+        GetAccessiblePath(obj.get()),
+        Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
+        "BoundsChanged",
+        "",
+        0,
+        0,
+        tmp,
+        {"", "root"});
+    }
   });
 }
 
-void BridgeObject::EmitPostRender(Accessible *obj)
+void BridgeObject::EmitPostRender(std::shared_ptr<Accessible> obj)
 {
   if(!IsUp() || obj->IsHidden())
   {
     return;
   }
 
-  AddCoalescableMessage(CoalescableMessages::POST_RENDER, obj, 0.5f, [=]() {
-    Emit(obj, WindowEvent::POST_RENDER);
+  AddCoalescableMessage(CoalescableMessages::POST_RENDER, obj.get(), 0.5f, [weakObj = std::weak_ptr<Accessible>(obj), this]() {
+    if(auto obj = weakObj.lock())
+    {
+      Emit(obj.get(), WindowEvent::POST_RENDER);
+    }
   });
 }
 
index 8ca6924c2038e015a3800f288f2c4cff42fde79b..e7130c38db6e6065c068393e54a9074bd72936d2 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_OBJECT_H
 
 /*
- * Copyright (c) 2021 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.
@@ -63,7 +63,7 @@ protected:
   /**
    * @copydoc Dali::Accessibility::Bridge::EmitStateChanged()
    */
-  void EmitStateChanged(Dali::Accessibility::Accessible* obj, Dali::Accessibility::State state, int newValue, int reserved) override;
+  void EmitStateChanged(std::shared_ptr<Dali::Accessibility::Accessible> obj, Dali::Accessibility::State state, int newValue, int reserved) override;
 
   /**
    * @copydoc Dali::Accessibility::Bridge::Emit()
@@ -73,17 +73,17 @@ protected:
   /**
    * @copydoc Dali::Accessibility::Bridge::Emit()
    */
-  void Emit(Dali::Accessibility::Accessible* obj, Dali::Accessibility::ObjectPropertyChangeEvent event) override;
+  void Emit(std::shared_ptr<Dali::Accessibility::Accessible> obj, Dali::Accessibility::ObjectPropertyChangeEvent event) override;
 
   /**
    * @copydoc Dali::Accessibility::Bridge::EmitBoundsChanged()
    */
-  void EmitBoundsChanged(Dali::Accessibility::Accessible* obj, Dali::Rect<> rect) override;
+  void EmitBoundsChanged(std::shared_ptr<Dali::Accessibility::Accessible> obj, Dali::Rect<> rect) override;
 
   /**
    * @copydoc Dali::Accessibility::Bridge::EmitPostRender()
    */
-  void EmitPostRender(Dali::Accessibility::Accessible* obj) override;
+  void EmitPostRender(std::shared_ptr<Dali::Accessibility::Accessible> obj) override;
 
   /**
    * @copydoc Dali::Accessibility::Bridge::EmitMovedOutOfScreen()
index 7f1166f36668bbb4118c4b10d4e1a864c2e862c4..6792e10356be5bc7eeb4c73514f9a1448d6cab55 100644 (file)
@@ -154,7 +154,7 @@ struct DummyBridge : Dali::Accessibility::Bridge
   {
   }
 
-  void EmitStateChanged(Accessibility::Accessible* obj, Accessibility::State state, int newValue, int reserved) override
+  void EmitStateChanged(std::shared_ptr<Accessibility::Accessible> obj, Accessibility::State state, int newValue, int reserved) override
   {
   }
 
@@ -162,15 +162,15 @@ struct DummyBridge : Dali::Accessibility::Bridge
   {
   }
 
-  void Emit(Accessibility::Accessible* obj, Accessibility::ObjectPropertyChangeEvent event) override
+  void Emit(std::shared_ptr<Accessibility::Accessible> obj, Accessibility::ObjectPropertyChangeEvent event) override
   {
   }
 
-  void EmitBoundsChanged(Accessibility::Accessible* obj, Rect<> rect) override
+  void EmitBoundsChanged(std::shared_ptr<Accessibility::Accessible> obj, Rect<> rect) override
   {
   }
 
-  void EmitPostRender(Accessibility::Accessible* obj) override
+  void EmitPostRender(std::shared_ptr<Accessibility::Accessible> obj) override
   {
   }