[Tizen] Re-enable a11y refactor + includeHidden w/ crash fix 02/319102/1 accepted/tizen_7.0_unified tizen_7.0 accepted/tizen/7.0/unified/20241017.161237
authorYoungsun Suh <youngsun.suh@samsung.com>
Tue, 15 Oct 2024 07:51:00 +0000 (16:51 +0900)
committerYoungsun Suh <youngsun.suh@samsung.com>
Tue, 15 Oct 2024 08:05:07 +0000 (17:05 +0900)
Revert "Revert "[Tizen] Add IncludeHidden interface""

This reverts commit b6b30e6edbb0cc78090d1cae94deaae7928bc51b.

Prevent crash when a11y bridge is disabled

Change-Id: Iba2bd83d2623ead9e907cd1a6d0ffe4f9e4548db

21 files changed:
dali/devel-api/adaptor-framework/accessibility-bridge.h
dali/devel-api/adaptor-framework/accessibility.cpp
dali/devel-api/adaptor-framework/accessibility.h
dali/devel-api/adaptor-framework/actor-accessible.cpp
dali/devel-api/adaptor-framework/actor-accessible.h
dali/devel-api/atspi-interfaces/accessible.h
dali/devel-api/atspi-interfaces/application.h
dali/internal/accessibility/bridge/accessible.cpp
dali/internal/accessibility/bridge/bridge-application.cpp
dali/internal/accessibility/bridge/bridge-application.h
dali/internal/accessibility/bridge/bridge-base.cpp
dali/internal/accessibility/bridge/bridge-base.h
dali/internal/accessibility/bridge/bridge-impl.cpp
dali/internal/accessibility/bridge/bridge-object.cpp
dali/internal/accessibility/bridge/bridge-object.h
dali/internal/accessibility/bridge/dummy/dummy-atspi.h
dali/internal/adaptor/common/adaptor-impl.cpp
dali/internal/adaptor/common/adaptor-impl.h
dali/internal/adaptor/common/application-impl.cpp
dali/internal/system/tizen-wayland/widget-controller-tizen.cpp
dali/internal/window-system/common/window-impl.cpp

index ac827cb..8184223 100644 (file)
@@ -62,6 +62,31 @@ struct DALI_ADAPTOR_API Bridge
   virtual ~Bridge() = default;
 
   /**
+   * @brief Adds the accessible object associated with given actorId to the brige.
+   *
+   * @param[in] actorId The actorId assosiated with the accessible
+   * @param[in] accessible The accessible object
+   *
+   * @return true if given accessible is added to the bridge
+   */
+  virtual bool AddAccessible(uint32_t actorId, std::shared_ptr<Accessible> accessible) = 0;
+
+  /**
+   * @brief Removed the accessible object associated with given actorId from the brige.
+   */
+  virtual void RemoveAccessible(uint32_t actorId) = 0;
+
+  /**
+   * @brief Gets the accessible object associated with given actor from the brige.
+   */
+  virtual std::shared_ptr<Accessible> GetAccessible(Actor actor) const = 0;
+
+  /**
+   * @brief Returns true if GetChildren should include hidden objects; false otherwise.
+   */
+  virtual bool ShouldIncludeHidden() const = 0;
+
+  /**
    * @brief Gets bus name which bridge is initialized on.
    *
    * @return The bus name
@@ -98,7 +123,7 @@ struct DALI_ADAPTOR_API Bridge
    *
    * @param[in] object The accessible object
    */
-  virtual void RegisterDefaultLabel(Accessible* object) = 0;
+  virtual void RegisterDefaultLabel(std::shared_ptr<Accessible> object) = 0;
 
   /**
    * @brief Removes object from the stack of "default label" sourcing objects.
@@ -107,7 +132,7 @@ struct DALI_ADAPTOR_API Bridge
    *
    * @param[in] object The accessible object
    */
-  virtual void UnregisterDefaultLabel(Accessible* object) = 0;
+  virtual void UnregisterDefaultLabel(std::shared_ptr<Accessible> object) = 0;
 
   /**
    * @brief Gets the top-most object from the stack of "default label" sourcing objects.
@@ -125,7 +150,7 @@ struct DALI_ADAPTOR_API Bridge
    * Following strings are valid values for "default_label" attribute: "enabled", "disabled".
    * Any other value will be interpreted as "enabled".
    */
-  virtual Accessible* GetDefaultLabel(Accessible* root) const = 0;
+  virtual Accessible* GetDefaultLabel(Accessible* root) = 0;
 
   /**
    * @brief Sets name of current application which will be visible on accessibility bus.
@@ -292,7 +317,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.
@@ -309,7 +334,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.
@@ -317,22 +342,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;
-
-  /**
-   * @brief Emits key event on at-spi bus.
-   *
-   * Screen-reader might receive this event and reply, that given keycode is consumed. In that case
-   * further processing of the keycode should be ignored.
-   *
-   * @param[in] type Key event type
-   * @param[in] keyCode Key code
-   * @param[in] keyName Key name
-   * @param[in] timeStamp Time stamp
-   * @param[in] isText Whether it's text or not
-   * @return Whether this event is consumed or not
-   **/
-  virtual Consumed Emit(KeyEventType type, unsigned int keyCode, const std::string& keyName, unsigned int timeStamp, bool isText) = 0;
+  virtual void EmitBoundsChanged(std::shared_ptr<Accessible> obj, Rect<> rect) = 0;
 
   /**
    * @brief Reads given text by screen reader
index 3a6475f..b570840 100644 (file)
@@ -19,7 +19,6 @@
 #include <dali/public-api/actors/actor.h>
 #include <dali/public-api/actors/layer.h>
 #include <dali/public-api/object/base-object.h>
-#include <dali/public-api/object/object-registry.h>
 #include <dali/public-api/object/type-info.h>
 #include <dali/public-api/object/type-registry-helper.h>
 #include <map>
@@ -421,10 +420,8 @@ namespace
 class AdaptorAccessible : public ActorAccessible
 {
 private:
-  std::unique_ptr<TriggerEventInterface> mRenderNotification = nullptr;
-
-protected:
-  bool mRoot = false;
+  std::unique_ptr<TriggerEventInterface> mRenderNotification{nullptr};
+  bool                                   mRoot{false};
 
 public:
   AdaptorAccessible(Dali::Actor actor, bool isRoot)
@@ -595,54 +592,71 @@ public:
 
 }; // AdaptorAccessible
 
-using AdaptorAccessiblesType = std::map<const Dali::RefObject*, std::unique_ptr<AdaptorAccessible>>;
-
-// Save RefObject from an Actor in Accessible::Get()
-AdaptorAccessiblesType gAdaptorAccessibles;
+using ConvertingResult = std::pair<std::shared_ptr<Accessible>, bool>;
 
-std::function<Accessible*(Dali::Actor)> convertingFunctor = [](Dali::Actor) -> Accessible* {
-  return nullptr;
+std::function<ConvertingResult(Dali::Actor)> convertingFunctor = [](Dali::Actor) -> ConvertingResult {
+  return {nullptr, true};
 };
 
-ObjectRegistry objectRegistry;
 } // namespace
 
-void Accessible::SetObjectRegistry(ObjectRegistry registry)
-{
-  objectRegistry = registry;
-  objectRegistry.ObjectDestroyedSignal().Connect([](const Dali::RefObject* obj) {
-    gAdaptorAccessibles.erase(obj);
-  });
-}
-
-void Accessible::RegisterExternalAccessibleGetter(std::function<Accessible*(Dali::Actor)> functor)
+void Accessible::RegisterExternalAccessibleGetter(std::function<ConvertingResult(Dali::Actor)> functor)
 {
   convertingFunctor = functor;
 }
 
-Accessible* Accessible::Get(Dali::Actor actor)
+std::shared_ptr<Accessible> Accessible::GetOwningPtr(Dali::Actor actor)
 {
   if(!actor)
   {
     return nullptr;
   }
 
-  auto accessible = convertingFunctor(actor);
-  if(!accessible)
+  auto bridge = Bridge::GetCurrentBridge();
+
+  // Try finding exsiting accessible object.
+  auto accessible = bridge->GetAccessible(actor);
+  if(accessible)
   {
-    auto pair = gAdaptorAccessibles.emplace(&actor.GetBaseObject(), nullptr);
-    if(pair.second)
+    return accessible;
+  }
+
+  // No acessible object created, let's create one.
+  auto result                = convertingFunctor(actor);
+  accessible                 = result.first;
+  const bool creationEnabled = result.second;
+  if(!accessible && creationEnabled)
+  {
+    bool                     isRoot = false;
+    Dali::Integration::Scene scene  = Dali::Integration::Scene::Get(actor);
+    if(scene)
     {
-      bool                     isRoot = false;
-      Dali::Integration::Scene scene  = Dali::Integration::Scene::Get(actor);
-      if(scene)
+      isRoot = (actor == scene.GetRootLayer());
+    }
+    accessible = std::make_shared<AdaptorAccessible>(actor, isRoot);
+  }
+
+  if(accessible)
+  {
+    uint32_t actorId = actor.GetProperty<int>(Dali::Actor::Property::ID);
+    if(bridge->AddAccessible(actorId, accessible))
+    {
+      if(auto actorAccesible = std::dynamic_pointer_cast<ActorAccessible>(accessible))
       {
-        isRoot = (actor == scene.GetRootLayer());
+        actorAccesible->StartObservingDestruction();
       }
-      pair.first->second.reset(new AdaptorAccessible(actor, isRoot));
     }
-    accessible = pair.first->second.get();
+    else
+    {
+      return nullptr;
+    }
   }
 
   return accessible;
 }
+
+Accessible* Accessible::Get(Dali::Actor actor)
+{
+  auto accessible = Accessible::GetOwningPtr(actor);
+  return accessible ? accessible.get() : nullptr;
+}
\ No newline at end of file
index 6a091da..8f7e654 100644 (file)
@@ -592,16 +592,6 @@ private:
 };\r
 \r
 /**\r
- * @brief Enumeration describing type of key event\r
- * @see Adaptor::AccessibilityObserver::OnAccessibleKeyEvent\r
- */\r
-enum class KeyEventType\r
-{\r
-  KEY_PRESSED,\r
-  KEY_RELEASED,\r
-};\r
-\r
-/**\r
  * @brief Enumeration with human readable values describing state of event\r
  * @see Dali::Accessibility::Bridge::Emit\r
  */\r
index c392b9e..0efad7a 100644 (file)
 namespace Dali::Accessibility
 {
 ActorAccessible::ActorAccessible(Actor actor)
-: mSelf(actor),
-  mChildrenDirty{true} // to trigger the initial UpdateChildren()
+: Dali::BaseObjectObserver(actor),
+  mSelf(actor),
+  mChildrenDirty{true}, // to trigger the initial UpdateChildren()
+  mActorId{static_cast<uint32_t>(actor.GetProperty<int>(Dali::Actor::Property::ID))}
 {
   // Select the right overload manually because Connect(this, &OnChildrenChanged) is ambiguous.
   void (ActorAccessible::*handler)(Dali::Actor) = &ActorAccessible::OnChildrenChanged;
@@ -39,6 +41,11 @@ ActorAccessible::ActorAccessible(Actor actor)
   Dali::DevelActor::ChildOrderChangedSignal(actor).Connect(this, handler);
 }
 
+void ActorAccessible::ObjectDestroyed()
+{
+  Bridge::GetCurrentBridge()->RemoveAccessible(mActorId);
+}
+
 std::string ActorAccessible::GetName() const
 {
   return Self().GetProperty<std::string>(Dali::Actor::Property::NAME);
@@ -214,10 +221,12 @@ void ActorAccessible::UpdateChildren()
   mChildren.clear();
   DoGetChildren(mChildren);
 
+  const bool shouldIncludeHidden = Bridge::GetCurrentBridge()->ShouldIncludeHidden();
+
   // Erase-remove idiom
   // TODO (C++20): Replace with std::erase_if
-  auto it = std::remove_if(mChildren.begin(), mChildren.end(), [](const Accessible* child) {
-    return !child || child->IsHidden();
+  auto it = std::remove_if(mChildren.begin(), mChildren.end(), [shouldIncludeHidden](const Accessible* child) {
+    return !child || (!shouldIncludeHidden && child->IsHidden());
   });
   mChildren.erase(it, mChildren.end());
   mChildren.shrink_to_fit();
index 9682c19..ba74c1e 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 // EXTERNAL INCLUDES
+#include <dali/devel-api/object/base-object-observer.h>
 #include <dali/public-api/actors/actor.h>
 #include <dali/public-api/object/weak-handle.h>
 #include <dali/public-api/signals/connection-tracker.h>
@@ -32,13 +33,17 @@ namespace Dali::Accessibility
 class DALI_ADAPTOR_API ActorAccessible : public virtual Accessible,
                                          public virtual Collection,
                                          public virtual Component,
-                                         public Dali::ConnectionTracker
+                                         public Dali::ConnectionTracker,
+                                         public Dali::BaseObjectObserver
 {
 public:
   ActorAccessible() = delete;
 
   ActorAccessible(Actor actor);
 
+  // BaseObjectObserver::ObjectDestroyed
+  void ObjectDestroyed() override;
+
   /**
    * @copydoc Dali::Accessibility::Accessible::GetName()
    */
@@ -166,6 +171,7 @@ private:
   Dali::WeakHandle<Dali::Actor> mSelf;
   std::vector<Accessible*>      mChildren;
   bool                          mChildrenDirty;
+  const uint32_t                mActorId;
 };
 
 } // namespace Dali::Accessibility
index aa60a1e..7804164 100644 (file)
@@ -35,7 +35,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;
@@ -524,28 +524,30 @@ public:
   static void SetCurrentlyHighlightedActor(Dali::Actor actor);
 
   /**
-   * @brief Sets ObjectRegistry.
-   *
-   * @param[in] registry ObjectRegistry instance
-   */
-  static void SetObjectRegistry(ObjectRegistry registry);
-
-  /**
    * @brief The method registers functor resposible for converting Actor into Accessible.
    * @param functor The returning Accessible handle from Actor object
    */
-  static void RegisterExternalAccessibleGetter(std::function<Accessible*(Dali::Actor)> functor);
+  static void RegisterExternalAccessibleGetter(std::function<std::pair<std::shared_ptr<Accessible>, bool>(Dali::Actor)> functor);
 
   /**
    * @brief Acquires Accessible object from Actor object.
    *
    * @param[in] actor Actor object
    *
-   * @return The handle to Accessible object
+   * @return The raw pointer to Accessible object
    */
   static Accessible* Get(Dali::Actor actor);
 
   /**
+   * @brief Acquires Accessible object from Actor object.
+   *
+   * @param[in] actor Actor object
+   *
+   * @return The owning pointer to Accessible object
+   */
+  static std::shared_ptr<Accessible> GetOwningPtr(Dali::Actor actor);
+
+  /**
    * @brief Obtains the DBus interface name for the specified AT-SPI interface.
    *
    * @param interface AT-SPI interface identifier (e.g. AtspiInterface::ACCESSIBLE)
index 44b26ba..b3cba19 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_ADAPTOR_ATSPI_APPLICATION_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.
@@ -50,6 +50,20 @@ public:
   virtual std::string GetVersion() const = 0;
 
   /**
+   * @brief Gets include_hidden flag currently set on the application.
+   *
+   * @return true is include_hidden is set; false otherwise.
+   */
+  virtual bool GetIncludeHidden() const = 0;
+
+  /**
+   * @brief Sets include_hidden flag to the application.
+   *
+   * @return true is include_hidden flag is updated; false otherwise.
+   */
+  virtual bool SetIncludeHidden(bool includeHidden) = 0;
+
+  /**
    * @brief Downcasts an Accessible to an Application.
    *
    * @param obj The Accessible
index 5340073..ed8fc1e 100644 (file)
@@ -113,7 +113,7 @@ void Accessible::EmitStateChanged(State state, int newValue, int reserved)
 
     if(shouldEmit)
     {
-      bridgeData->mBridge->EmitStateChanged(this, state, newValue, reserved);
+      bridgeData->mBridge->EmitStateChanged(shared_from_this(), state, newValue, reserved);
     }
   }
 }
@@ -189,7 +189,7 @@ void Accessible::Emit(ObjectPropertyChangeEvent event)
 {
   if(auto bridgeData = GetBridgeData())
   {
-    bridgeData->mBridge->Emit(this, event);
+    bridgeData->mBridge->Emit(shared_from_this(), event);
   }
 }
 
@@ -197,7 +197,7 @@ void Accessible::EmitBoundsChanged(Rect<> rect)
 {
   if(auto bridgeData = GetBridgeData())
   {
-    bridgeData->mBridge->EmitBoundsChanged(this, rect);
+    bridgeData->mBridge->EmitBoundsChanged(shared_from_this(), rect);
   }
 }
 
index 9806bad..c080236 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -28,6 +28,8 @@ void BridgeApplication::RegisterInterfaces()
   DBus::DBusInterfaceDescription desc{Accessible::GetInterfaceName(AtspiInterface::APPLICATION)};
   AddGetPropertyToInterface(desc, "ToolkitName", &BridgeApplication::GetToolkitName);
   AddGetPropertyToInterface(desc, "Version", &BridgeApplication::GetVersion);
+  AddFunctionToInterface(desc, "GetIncludeHidden", &BridgeApplication::GetIncludeHidden);
+  AddFunctionToInterface(desc, "SetIncludeHidden", &BridgeApplication::SetIncludeHidden);
   mDbusServer.addInterface("/", desc, true);
 }
 
@@ -45,3 +47,17 @@ std::string BridgeApplication::GetVersion()
 {
   return FindSelf()->GetVersion();
 }
+
+DBus::ValueOrError<bool> BridgeApplication::GetIncludeHidden()
+{
+  return FindSelf()->GetIncludeHidden();
+}
+
+DBus::ValueOrError<void> BridgeApplication::SetIncludeHidden(bool includeHidden)
+{
+  if(FindSelf()->SetIncludeHidden(includeHidden))
+  {
+    NotifyIncludeHiddenChanged();
+  }
+  return {};
+}
index f4cefc4..299e772 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_APPLICATION_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.
@@ -44,6 +44,9 @@ protected:
    */
   Dali::Accessibility::Application* FindSelf() const;
 
+private:
+  virtual void NotifyIncludeHiddenChanged(){};
+
 public:
   /**
    * @brief Gets name of graphic user interface framework used by an application.
@@ -58,6 +61,18 @@ public:
    * @return String with version
    */
   std::string GetVersion();
+
+  /**
+   * @brief Gets include_hidden flag currently set on the application.
+   *
+   * @return true is include_hidden is set; false otherwise.
+   */
+  DBus::ValueOrError<bool> GetIncludeHidden();
+
+  /**
+   * @brief Sets include_hidden flag to the application.
+   */
+  DBus::ValueOrError<void> SetIncludeHidden(bool includeHidden);
 };
 
 #endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_APPLICATION_H
index 7b24a7f..3bd27ff 100644 (file)
@@ -233,24 +233,25 @@ void BridgeBase::CompressDefaultLabels()
 {
   // Remove entries for objects which no longer exist
   mDefaultLabels.remove_if([](const DefaultLabelType& label) {
-    return !label.first.GetBaseHandle(); // Check window's weak handle
-    // TODO: Once Accessible becomes a handle type, check its weak handle here as well
+    // Check 1) window's weak handle; 2) accessible's ref object
+    return !label.first.GetBaseHandle() || label.second.expired();
   });
 }
 
-void BridgeBase::RegisterDefaultLabel(Accessible* object)
+void BridgeBase::RegisterDefaultLabel(std::shared_ptr<Accessible> object)
 {
   CompressDefaultLabels();
 
-  Dali::WeakHandle<Dali::Window> window = GetWindow(object);
+  Dali::WeakHandle<Dali::Window> window = GetWindow(object.get());
   if(!window.GetBaseHandle()) // true also if `object` is null
   {
     DALI_LOG_ERROR("Cannot register default label: object does not belong to any window");
     return;
   }
 
-  auto it = std::find_if(mDefaultLabels.begin(), mDefaultLabels.end(), [object](const DefaultLabelType& label) {
-    return object == label.second;
+  auto it = std::find_if(mDefaultLabels.begin(), mDefaultLabels.end(), [&object](const DefaultLabelType& label) {
+    auto labelPtr = label.second.lock();
+    return labelPtr && object == labelPtr;
   });
 
   if(it == mDefaultLabels.end())
@@ -269,17 +270,20 @@ void BridgeBase::RegisterDefaultLabel(Accessible* object)
   }
 }
 
-void BridgeBase::UnregisterDefaultLabel(Accessible* object)
+void BridgeBase::UnregisterDefaultLabel(std::shared_ptr<Accessible> object)
 {
   CompressDefaultLabels();
 
-  mDefaultLabels.remove_if([object](const DefaultLabelType& label) {
-    return object == label.second;
+  mDefaultLabels.remove_if([&object](const DefaultLabelType& label) {
+    auto labelPtr = label.second.lock();
+    return labelPtr && object == labelPtr;
   });
 }
 
-Accessible* BridgeBase::GetDefaultLabel(Accessible* root) const
+Accessible* BridgeBase::GetDefaultLabel(Accessible* root)
 {
+  CompressDefaultLabels();
+
   Dali::WeakHandle<Dali::Window> window = GetWindow(root);
   if(!window.GetBaseHandle())
   {
@@ -290,7 +294,16 @@ Accessible* BridgeBase::GetDefaultLabel(Accessible* root) const
     return window == label.first;
   });
 
-  return (it == mDefaultLabels.rend()) ? root : it->second;
+  Accessible* rawPtr = root;
+  if(it != mDefaultLabels.rend())
+  {
+    if(auto labelPtr = it->second.lock())
+    {
+      rawPtr = labelPtr.get();
+    }
+  }
+
+  return rawPtr;
 }
 
 std::string BridgeBase::StripPrefix(const std::string& path)
@@ -314,7 +327,7 @@ Accessible* BridgeBase::Find(const std::string& path) const
   }
 
   auto it = mData->mKnownObjects.find(static_cast<Accessible*>(accessible));
-  if(it == mData->mKnownObjects.end() || (*it)->IsHidden())
+  if(it == mData->mKnownObjects.end() || (!mApplication.mShouldIncludeHidden && (*it)->IsHidden()))
   {
     throw std::domain_error{"unknown object '" + path + "'"};
   }
index eec96fe..c7efdeb 100644 (file)
@@ -50,6 +50,7 @@ public:
   std::string                                   mName;
   std::string                                   mToolkitName{"dali"};
   bool                                          mIsEmbedded{false};
+  bool                                          mShouldIncludeHidden{false};
 
   std::string GetName() const override
   {
@@ -182,6 +183,21 @@ public:
     return std::to_string(Dali::ADAPTOR_MAJOR_VERSION) + "." + std::to_string(Dali::ADAPTOR_MINOR_VERSION);
   }
 
+  bool GetIncludeHidden() const override
+  {
+    return mShouldIncludeHidden;
+  }
+
+  bool SetIncludeHidden(bool includeHidden) override
+  {
+    if(mShouldIncludeHidden != includeHidden)
+    {
+      mShouldIncludeHidden = includeHidden;
+      return true;
+    }
+    return false;
+  }
+
   // Socket
 
   Dali::Accessibility::Address Embed(Dali::Accessibility::Address plug) override
@@ -359,17 +375,17 @@ public:
   /**
    * @copydoc Dali::Accessibility::Bridge::RegisterDefaultLabel()
    */
-  void RegisterDefaultLabel(Dali::Accessibility::Accessible* object) override;
+  void RegisterDefaultLabel(std::shared_ptr<Dali::Accessibility::Accessible> object) override;
 
   /**
    * @copydoc Dali::Accessibility::Bridge::UnregisterDefaultLabel()
    */
-  void UnregisterDefaultLabel(Dali::Accessibility::Accessible* object) override;
+  void UnregisterDefaultLabel(std::shared_ptr<Dali::Accessibility::Accessible> object) override;
 
   /**
    * @copydoc Dali::Accessibility::Bridge::GetDefaultLabel()
    */
-  Dali::Accessibility::Accessible* GetDefaultLabel(Dali::Accessibility::Accessible* root) const override;
+  Dali::Accessibility::Accessible* GetDefaultLabel(Dali::Accessibility::Accessible* root) override;
 
   /**
    * @copydoc Dali::Accessibility::Bridge::GetApplication()
@@ -613,7 +629,7 @@ public:
 
 protected:
   // We use a weak handle in order not to keep a window alive forever if someone forgets to UnregisterDefaultLabel()
-  using DefaultLabelType  = std::pair<Dali::WeakHandle<Dali::Window>, Dali::Accessibility::Accessible*>;
+  using DefaultLabelType  = std::pair<Dali::WeakHandle<Dali::Window>, std::weak_ptr<Dali::Accessibility::Accessible>>;
   using DefaultLabelsType = std::list<DefaultLabelType>;
 
   mutable ApplicationAccessible mApplication;
index 6cafd4a..6d0b630 100644 (file)
@@ -25,6 +25,7 @@
 #include <map>
 
 // INTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/actor-accessible.h>
 #include <dali/devel-api/adaptor-framework/environment-variable.h>
 #include <dali/devel-api/adaptor-framework/window-devel.h>
 #include <dali/internal/accessibility/bridge/accessibility-common.h>
@@ -76,21 +77,22 @@ class BridgeImpl : public virtual BridgeBase,
                    public BridgeTable,
                    public BridgeTableCell
 {
-  DBus::DBusClient                                    mAccessibilityStatusClient;
-  DBus::DBusClient                                    mRegistryClient;
-  DBus::DBusClient                                    mDirectReadingClient;
-  bool                                                mIsScreenReaderEnabled = false;
-  bool                                                mIsEnabled             = false;
-  bool                                                mIsApplicationRunning  = false;
-  std::map<int32_t, std::function<void(std::string)>> mDirectReadingCallbacks;
-  Dali::Actor                                         mHighlightedActor;
-  std::function<void(Dali::Actor)>                    mHighlightClearAction;
-  Dali::CallbackBase*                                 mIdleCallback = NULL;
-  Dali::Timer                                         mInitializeTimer;
-  Dali::Timer                                         mReadIsEnabledTimer;
-  Dali::Timer                                         mReadScreenReaderEnabledTimer;
-  Dali::Timer                                         mForceUpTimer;
-  std::string                                         mPreferredBusName;
+  DBus::DBusClient                                              mAccessibilityStatusClient{};
+  DBus::DBusClient                                              mRegistryClient{};
+  DBus::DBusClient                                              mDirectReadingClient{};
+  bool                                                          mIsScreenReaderEnabled{false};
+  bool                                                          mIsEnabled{false};
+  bool                                                          mIsApplicationRunning{false};
+  std::unordered_map<int32_t, std::function<void(std::string)>> mDirectReadingCallbacks{};
+  Dali::Actor                                                   mHighlightedActor;
+  std::function<void(Dali::Actor)>                              mHighlightClearAction{nullptr};
+  Dali::CallbackBase*                                           mIdleCallback{};
+  Dali::Timer                                                   mInitializeTimer;
+  Dali::Timer                                                   mReadIsEnabledTimer;
+  Dali::Timer                                                   mReadScreenReaderEnabledTimer;
+  Dali::Timer                                                   mForceUpTimer;
+  std::string                                                   mPreferredBusName;
+  std::map<uint32_t, std::shared_ptr<Accessible>>               mAccessibles; // Actor.ID to Accessible map
 
 public:
   BridgeImpl()
@@ -98,36 +100,54 @@ public:
   }
 
   /**
-   * @copydoc Dali::Accessibility::Bridge::Emit()
+   * @copydoc Dali::Accessibility::Bridge::AddAccessible()
    */
-  Consumed Emit(KeyEventType type, unsigned int keyCode, const std::string& keyName, unsigned int timeStamp, bool isText) override
+  bool AddAccessible(uint32_t actorId, std::shared_ptr<Accessible> accessible) override
   {
-    if(!IsUp())
-    {
-      return Consumed::NO;
-    }
+    mAccessibles[actorId] = std::move(accessible);
+    return true;
+  }
+
+  /**
+   * @copydoc Dali::Accessibility::Bridge::RemoveAccessible()
+   */
+  void RemoveAccessible(uint32_t actorId) override
+  {
+    mAccessibles.erase(actorId);
+  }
 
-    unsigned int keyType = 0;
+  /**
+   * @copydoc Dali::Accessibility::Bridge::GetAccessible()
+   */
+  std::shared_ptr<Accessible> GetAccessible(Dali::Actor actor) const override
+  {
+    uint32_t actorId = actor.GetProperty<int>(Dali::Actor::Property::ID);
+    auto     iter    = mAccessibles.find(actorId);
+    return iter != mAccessibles.end() ? iter->second : nullptr;
+  }
 
-    switch(type)
+  /**
+   * @copydoc Dali::Accessibility::Bridge::ShouldIncludeHidden()
+   */
+  bool ShouldIncludeHidden() const override
+  {
+    return mApplication.mShouldIncludeHidden;
+  }
+
+  void NotifyIncludeHiddenChanged() override
+  {
+    for(const auto& iter : mAccessibles)
     {
-      case KeyEventType::KEY_PRESSED:
+      const auto& accessible = iter.second;
+      if(accessible->IsHidden())
       {
-        keyType = 0;
-        break;
-      }
-      case KeyEventType::KEY_RELEASED:
-      {
-        keyType = 1;
-        break;
-      }
-      default:
-      {
-        return Consumed::NO;
+        auto* parent = dynamic_cast<ActorAccessible*>(accessible->GetParent());
+        if(parent)
+        {
+          parent->OnChildrenChanged();
+        }
       }
     }
-
-    return Consumed::NO;
   }
 
   /**
index 2f00293..fa51796 100644 (file)
@@ -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::map<ObjectPropertyChangeEvent, std::string_view> eventMap{
     {ObjectPropertyChangeEvent::NAME, "accessible-name"},
@@ -86,7 +86,7 @@ void BridgeObject::Emit(Accessible* obj, ObjectPropertyChangeEvent event)
   if(eventName != eventMap.end())
   {
     mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
-      GetAccessiblePath(obj),
+      GetAccessiblePath(obj.get()),
       Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
       "PropertyChange",
       std::string{eventName->second},
@@ -143,7 +143,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::map<State, std::string_view> stateMap{
     {State::INVALID, "invalid"},
@@ -204,7 +204,7 @@ void BridgeObject::EmitStateChanged(Accessible* obj, State state, int newValue,
   if(stateName != stateMap.end())
   {
     mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
-      GetAccessiblePath(obj),
+      GetAccessiblePath(obj.get()),
       Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
       "StateChanged",
       std::string{stateName->second},
@@ -215,26 +215,29 @@ void BridgeObject::EmitStateChanged(Accessible* obj, State state, int newValue,
   }
 }
 
-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, 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"});
+  AddCoalescableMessage(CoalescableMessages::BOUNDS_CHANGED, obj.get(), 1.0f, [=, weakObj = std::weak_ptr<Accessible>(obj), rect = std::move(rect)]() {
+    if(auto accessible = 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}};
+
+      mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<std::tuple<int32_t, int32_t, int32_t, int32_t> >, Address>(
+        GetAccessiblePath(accessible.get()),
+        Accessible::GetInterfaceName(AtspiInterface::EVENT_OBJECT),
+        "BoundsChanged",
+        "",
+        0,
+        0,
+        tmp,
+        {"", "root"});
+    }
   });
 }
 
index 2bfd1fb..8b9d850 100644 (file)
@@ -62,7 +62,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()
@@ -72,12 +72,12 @@ 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::EmitMovedOutOfScreen()
index 4cb4f94..1414c38 100644 (file)
@@ -46,15 +46,15 @@ struct DummyBridge : Dali::Accessibility::Bridge
   {
   }
 
-  void RegisterDefaultLabel(Accessibility::Accessible* object) override
+  void RegisterDefaultLabel(std::shared_ptr<Accessibility::Accessible> object) override
   {
   }
 
-  void UnregisterDefaultLabel(Accessibility::Accessible* object) override
+  void UnregisterDefaultLabel(std::shared_ptr<Accessibility::Accessible> object) override
   {
   }
 
-  Dali::Accessibility::Accessible* GetDefaultLabel(Dali::Accessibility::Accessible* root) const override
+  Dali::Accessibility::Accessible* GetDefaultLabel(Dali::Accessibility::Accessible* root) override
   {
     return nullptr;
   }
@@ -142,7 +142,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
   {
   }
 
@@ -150,19 +150,14 @@ 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
   {
   }
 
-  Accessibility::Consumed Emit(Accessibility::KeyEventType type, unsigned int keyCode, const std::string& keyName, unsigned int timeStamp, bool isText) override
-  {
-    return Accessibility::Consumed::YES;
-  }
-
   void Say(const std::string& text, bool discardable, std::function<void(std::string)> callback) override
   {
   }
@@ -213,6 +208,25 @@ struct DummyBridge : Dali::Accessibility::Bridge
   void SetPreferredBusName(std::string_view preferredBusName) override
   {
   }
+
+  bool AddAccessible(uint32_t actorId, std::shared_ptr<Accessible> accessible) override
+  {
+    return false;
+  }
+
+  void RemoveAccessible(uint32_t actorId) override
+  {
+  }
+
+  std::shared_ptr<Accessible> GetAccessible(Actor actor) const override
+  {
+    return nullptr;
+  };
+
+  bool ShouldIncludeHidden() const override
+  {
+    return false;
+  }
 };
 
 } // namespace Dali::Accessibility
index a85d772..56ce105 100644 (file)
@@ -314,24 +314,6 @@ void Adaptor::Initialize(GraphicsFactory& graphicsFactory)
   mConfigurationManager = Utils::MakeUnique<ConfigurationManager>(systemCachePath, mGraphics.get(), mThreadController);
 }
 
-void Adaptor::AccessibilityObserver::OnAccessibleKeyEvent(const Dali::KeyEvent& event)
-{
-  Accessibility::KeyEventType type;
-  if(event.GetState() == Dali::KeyEvent::DOWN)
-  {
-    type = Accessibility::KeyEventType::KEY_PRESSED;
-  }
-  else if(event.GetState() == Dali::KeyEvent::UP)
-  {
-    type = Accessibility::KeyEventType::KEY_RELEASED;
-  }
-  else
-  {
-    return;
-  }
-  Dali::Accessibility::Bridge::GetCurrentBridge()->Emit(type, event.GetKeyCode(), event.GetKeyName(), event.GetTime(), !event.GetKeyString().empty());
-}
-
 Adaptor::~Adaptor()
 {
   Accessibility::Bridge::GetCurrentBridge()->Terminate();
@@ -392,7 +374,6 @@ void Adaptor::Start()
   auto bridge  = Accessibility::Bridge::GetCurrentBridge();
   bridge->SetApplicationName(appName);
   bridge->Initialize();
-  Dali::Stage::GetCurrent().KeyEventSignal().Connect(&mAccessibilityObserver, &AccessibilityObserver::OnAccessibleKeyEvent);
 
   Dali::Internal::Adaptor::SceneHolder* defaultWindow = mWindows.front();
 
index d0f9ed2..1a2ab40 100644 (file)
@@ -700,13 +700,6 @@ private:                                          // Data
 
   std::unique_ptr<Integration::AddOnManager> mAddOnManager; ///< Pointer to the addon manager
 
-  class AccessibilityObserver : public ConnectionTracker
-  {
-  public:
-    void OnAccessibleKeyEvent(const Dali::KeyEvent& event);
-  };
-  AccessibilityObserver mAccessibilityObserver;
-
 public:
   inline static Adaptor& GetImplementation(Dali::Adaptor& adaptor)
   {
index fe9dd7f..540cf60 100644 (file)
@@ -285,7 +285,6 @@ void Application::OnInit()
   DALI_TRACE_BEGIN(gTraceFilter, "DALI_APP_ADAPTOR_START");
   mAdaptor->Start();
   DALI_TRACE_END(gTraceFilter, "DALI_APP_ADAPTOR_START");
-  Accessibility::Accessible::SetObjectRegistry(mAdaptor->GetObjectRegistry());
 
   if(!mStylesheet.empty())
   {
index 40d5891..cf641f7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -19,8 +19,8 @@
 #include <dali/internal/system/tizen-wayland/widget-controller-tizen.h>
 
 // EXTERNAL INCLUDES
-#include <dali/public-api/actors/layer.h>
 #include <bundle.h>
+#include <dali/public-api/actors/layer.h>
 #include <unistd.h>
 #include <widget_base.h>
 
@@ -71,7 +71,7 @@ void WidgetImplTizen::SetUsingKeyEvent(bool flag)
 
 void WidgetImplTizen::SetInformation(Dali::Window window, const std::string& widgetId)
 {
-  mWindow = window;
+  mWindow   = window;
   mWidgetId = widgetId;
 
   auto bridge           = Accessibility::Bridge::GetCurrentBridge();
@@ -83,9 +83,12 @@ void WidgetImplTizen::SetInformation(Dali::Window window, const std::string& wid
   bridge->SetPreferredBusName(preferredBusName);
 
   // Widget should not send window events (which could narrow down the navigation context)
-  auto& suppressedEvents = Accessibility::Accessible::Get(window.GetRootLayer())->GetSuppressedEvents();
-  suppressedEvents[Accessibility::AtspiEvent::STATE_CHANGED] = true;
-  suppressedEvents[Accessibility::AtspiEvent::WINDOW_CHANGED] = true;
+  if(auto accessible = Accessibility::Accessible::Get(window.GetRootLayer()))
+  {
+    auto& suppressedEvents                                      = accessible->GetSuppressedEvents();
+    suppressedEvents[Accessibility::AtspiEvent::STATE_CHANGED]  = true;
+    suppressedEvents[Accessibility::AtspiEvent::WINDOW_CHANGED] = true;
+  }
 }
 
 Dali::Window WidgetImplTizen::GetWindow() const
index 3bc1044..ba4862b 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.
@@ -113,12 +113,14 @@ Window::~Window()
 {
   if(mScene)
   {
-    auto bridge     = Accessibility::Bridge::GetCurrentBridge();
-    auto rootLayer  = mScene.GetRootLayer();
-    auto accessible = Accessibility::Accessible::Get(rootLayer);
-    bridge->RemoveTopLevelWindow(accessible);
-    // Related to multi-window case. This is called for default window and non-default window, but it is effective for non-default window.
-    bridge->Emit(accessible, Accessibility::WindowEvent::DESTROY);
+    auto bridge    = Accessibility::Bridge::GetCurrentBridge();
+    auto rootLayer = mScene.GetRootLayer();
+    if(auto accessible = Accessibility::Accessible::Get(rootLayer))
+    {
+      bridge->RemoveTopLevelWindow(accessible);
+      // Related to multi-window case. This is called for default window and non-default window, but it is effective for non-default window.
+      bridge->Emit(accessible, Accessibility::WindowEvent::DESTROY);
+    }
   }
 
   if(DALI_LIKELY(mAdaptor))
@@ -715,7 +717,10 @@ void Window::SetSize(Dali::Window::WindowSize size)
 
   mSurface->SetFullSwapNextFrame();
 
-  Dali::Accessibility::Accessible::Get(mScene.GetRootLayer())->EmitBoundsChanged(Dali::Rect<>(oldRect.x, oldRect.y, size.GetWidth(), size.GetHeight()));
+  if(auto accessible = Accessibility::Accessible::Get(mScene.GetRootLayer()))
+  {
+    accessible->EmitBoundsChanged(Dali::Rect<>(oldRect.x, oldRect.y, size.GetWidth(), size.GetHeight()));
+  }
 }
 
 Dali::Window::WindowSize Window::GetSize() const
@@ -742,7 +747,10 @@ void Window::SetPosition(Dali::Window::WindowPosition position)
 
   mSurface->SetFullSwapNextFrame();
 
-  Dali::Accessibility::Accessible::Get(mScene.GetRootLayer())->EmitBoundsChanged(Dali::Rect<>(position.GetX(), position.GetY(), oldRect.width, oldRect.height));
+  if(auto accessible = Accessibility::Accessible::Get(mScene.GetRootLayer()))
+  {
+    accessible->EmitBoundsChanged(Dali::Rect<>(position.GetX(), position.GetY(), oldRect.width, oldRect.height));
+  }
 }
 
 Dali::Window::WindowPosition Window::GetPosition() const
@@ -810,7 +818,10 @@ void Window::SetPositionSize(PositionSize positionSize)
 
   mSurface->SetFullSwapNextFrame();
 
-  Dali::Accessibility::Accessible::Get(mScene.GetRootLayer())->EmitBoundsChanged(Dali::Rect<>(positionSize.x, positionSize.y, positionSize.width, positionSize.height));
+  if(auto accessible = Accessibility::Accessible::Get(mScene.GetRootLayer()))
+  {
+    accessible->EmitBoundsChanged(Dali::Rect<>(positionSize.x, positionSize.y, positionSize.width, positionSize.height));
+  }
 }
 
 void Window::SetLayout(unsigned int numCols, unsigned int numRows, unsigned int column, unsigned int row, unsigned int colSpan, unsigned int rowSpan)
@@ -1011,7 +1022,10 @@ void Window::OnUpdatePositionSize(Dali::PositionSize& positionSize)
 
   if(DALI_LIKELY(mScene))
   {
-    Dali::Accessibility::Accessible::Get(mScene.GetRootLayer())->EmitBoundsChanged(Dali::Rect<>(positionSize.x, positionSize.y, positionSize.width, positionSize.height));
+    if(auto accessible = Accessibility::Accessible::Get(mScene.GetRootLayer()))
+    {
+      accessible->EmitBoundsChanged(Dali::Rect<>(positionSize.x, positionSize.y, positionSize.width, positionSize.height));
+    }
   }
 }
 
@@ -1108,11 +1122,12 @@ void Window::OnInsetsChanged(WindowInsetsPartType partType, WindowInsetsPartStat
 
 void Window::OnAccessibilityEnabled()
 {
-  auto bridge     = Accessibility::Bridge::GetCurrentBridge();
-  auto rootLayer  = mScene.GetRootLayer();
-  auto accessible = Accessibility::Accessible::Get(rootLayer);
-  bridge->AddTopLevelWindow(accessible);
-
+  auto bridge    = Accessibility::Bridge::GetCurrentBridge();
+  auto rootLayer = mScene.GetRootLayer();
+  if(auto accessible = Accessibility::Accessible::Get(rootLayer))
+  {
+    bridge->AddTopLevelWindow(accessible);
+  }
   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), Accessibility is enabled\n", this, mNativeWindowId);
 
   Dali::Window handle(this);
@@ -1141,10 +1156,12 @@ void Window::OnAccessibilityEnabled()
 
 void Window::OnAccessibilityDisabled()
 {
-  auto bridge     = Accessibility::Bridge::GetCurrentBridge();
-  auto rootLayer  = mScene.GetRootLayer();
-  auto accessible = Accessibility::Accessible::Get(rootLayer);
-  bridge->RemoveTopLevelWindow(accessible);
+  auto bridge    = Accessibility::Bridge::GetCurrentBridge();
+  auto rootLayer = mScene.GetRootLayer();
+  if(auto accessible = Accessibility::Accessible::Get(rootLayer))
+  {
+    bridge->RemoveTopLevelWindow(accessible);
+  }
   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), Accessibility is disabled\n", this, mNativeWindowId);
 }